Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py

Issue 2540603004: [Android] Redirect std{in,out,err} to sockets for layout tests. (Closed)
Patch Set: Fix server_process_constructor name. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (C) 2012 Google Inc. All rights reserved. 1 # Copyright (C) 2012 Google Inc. All rights reserved.
2 # 2 #
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer 10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the 11 # in the documentation and/or other materials provided with the
12 # distribution. 12 # distribution.
13 # * Neither the name of Google Inc. nor the names of its 13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from 14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission. 15 # this software without specific prior written permission.
16 # 16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 28
29 import itertools
29 import logging 30 import logging
30 import os 31 import os
31 import re 32 import re
32 import sys 33 import sys
33 import threading 34 import threading
34 import time 35 import time
35 36
36 from multiprocessing.pool import ThreadPool 37 from multiprocessing.pool import ThreadPool
37 38
38 from webkitpy.common.system.executive import ScriptError 39 from webkitpy.common.system.executive import ScriptError
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 261
261 BUILD_REQUIREMENTS_URL = 'https://www.chromium.org/developers/how-tos/androi d-build-instructions' 262 BUILD_REQUIREMENTS_URL = 'https://www.chromium.org/developers/how-tos/androi d-build-instructions'
262 263
263 def __init__(self, host, port_name, **kwargs): 264 def __init__(self, host, port_name, **kwargs):
264 super(AndroidPort, self).__init__(host, port_name, **kwargs) 265 super(AndroidPort, self).__init__(host, port_name, **kwargs)
265 266
266 self._operating_system = 'android' 267 self._operating_system = 'android'
267 self._version = 'icecreamsandwich' 268 self._version = 'icecreamsandwich'
268 269
269 self._host_port = factory.PortFactory(host).get(**kwargs) 270 self._host_port = factory.PortFactory(host).get(**kwargs)
270 self._server_process_constructor = self._android_server_process_construc tor 271 self.server_process_constructor = self._android_server_process_construct or
271 272
272 if not self.get_option('disable_breakpad'): 273 if not self.get_option('disable_breakpad'):
273 self._dump_reader = DumpReaderAndroid(host, self._build_path()) 274 self._dump_reader = DumpReaderAndroid(host, self._build_path())
274 275
275 if self.driver_name() != self.CONTENT_SHELL_NAME: 276 if self.driver_name() != self.CONTENT_SHELL_NAME:
276 raise AssertionError('Layout tests on Android only support content_s hell as the driver.') 277 raise AssertionError('Layout tests on Android only support content_s hell as the driver.')
277 278
278 self._driver_details = ContentShellDriverDetails() 279 self._driver_details = ContentShellDriverDetails()
279 280
280 # Initialize the AndroidDevices class which tracks available devices. 281 # Initialize the AndroidDevices class which tracks available devices.
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 603
603 perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_l inux' 604 perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_l inux'
604 _log.debug("To view the full profile, run:") 605 _log.debug("To view the full profile, run:")
605 _log.debug(' '.join([perfhost_display_patch] + perfhost_report_command)) 606 _log.debug(' '.join([perfhost_display_patch] + perfhost_report_command))
606 607
607 608
608 class ChromiumAndroidDriver(driver.Driver): 609 class ChromiumAndroidDriver(driver.Driver):
609 610
610 def __init__(self, port, worker_number, pixel_tests, driver_details, android _devices, no_timeout=False): 611 def __init__(self, port, worker_number, pixel_tests, driver_details, android _devices, no_timeout=False):
611 super(ChromiumAndroidDriver, self).__init__(port, worker_number, pixel_t ests, no_timeout) 612 super(ChromiumAndroidDriver, self).__init__(port, worker_number, pixel_t ests, no_timeout)
612 self._in_fifo_path = driver_details.device_fifo_directory() + 'stdin.fif o' 613 self._write_stdin_process = None
613 self._out_fifo_path = driver_details.device_fifo_directory() + 'test.fif o'
614 self._err_fifo_path = driver_details.device_fifo_directory() + 'stderr.f ifo'
615 self._read_stdout_process = None 614 self._read_stdout_process = None
616 self._read_stderr_process = None 615 self._read_stderr_process = None
617 self._original_kptr_restrict = None 616 self._original_kptr_restrict = None
618 617
619 self._android_devices = android_devices 618 self._android_devices = android_devices
620 self._device = android_devices.get_device(port._executive, worker_number ) # pylint: disable=protected-access 619 self._device = android_devices.get_device(port._executive, worker_number ) # pylint: disable=protected-access
621 self._driver_details = driver_details 620 self._driver_details = driver_details
622 self._debug_logging = self._port._debug_logging 621 self._debug_logging = self._port._debug_logging
623 self._created_cmd_line = False 622 self._created_cmd_line = False
624 self._device_failed = False 623 self._device_failed = False
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 return '' 818 return ''
820 819
821 # Use Android tool vendor/google/tools/stack to convert the raw 820 # Use Android tool vendor/google/tools/stack to convert the raw
822 # stack trace into a human readable format, if needed. 821 # stack trace into a human readable format, if needed.
823 # It takes a long time, so don't do it here. 822 # It takes a long time, so don't do it here.
824 tombstone_contents = self._device.ReadFile( 823 tombstone_contents = self._device.ReadFile(
825 '/data/tombstones/%s' % last_tombstone[6]) 824 '/data/tombstones/%s' % last_tombstone[6])
826 return '%s\n%s' % (' '.join(last_tombstone), tombstone_contents) 825 return '%s\n%s' % (' '.join(last_tombstone), tombstone_contents)
827 826
828 def _get_logcat(self): 827 def _get_logcat(self):
829 return list(self._device.adb.Logcat(dump=True, logcat_format='threadtime ')) 828 return '\n'.join(self._device.adb.Logcat(dump=True, logcat_format='threa dtime'))
830 829
831 def _setup_performance(self): 830 def _setup_performance(self):
832 # Disable CPU scaling and drop ram cache to reduce noise in tests 831 # Disable CPU scaling and drop ram cache to reduce noise in tests
833 perf_control.PerfControl(self._device).SetPerfProfilingMode() 832 perf_control.PerfControl(self._device).SetPerfProfilingMode()
834 833
835 def _teardown_performance(self): 834 def _teardown_performance(self):
836 perf_control.PerfControl(self._device).SetDefaultPerfMode() 835 perf_control.PerfControl(self._device).SetDefaultPerfMode()
837 836
838 def _get_crash_log(self, stdout, stderr, newer_than): 837 def _get_crash_log(self, stdout, stderr, newer_than):
839 if not stdout: 838 if not stdout:
(...skipping 30 matching lines...) Expand all
870 return driver.Driver.cmd_line(self, pixel_tests, per_test_args) 869 return driver.Driver.cmd_line(self, pixel_tests, per_test_args)
871 870
872 @staticmethod 871 @staticmethod
873 def _loop_with_timeout(condition, timeout_secs): 872 def _loop_with_timeout(condition, timeout_secs):
874 deadline = time.time() + timeout_secs 873 deadline = time.time() + timeout_secs
875 while time.time() < deadline: 874 while time.time() < deadline:
876 if condition(): 875 if condition():
877 return True 876 return True
878 return False 877 return False
879 878
880 def _all_pipes_created(self):
881 return self._device.PathExists(
882 [self._in_fifo_path, self._out_fifo_path, self._err_fifo_path])
883
884 def _remove_all_pipes(self):
885 self._device.RunShellCommand(
886 ['rm', '-f', self._in_fifo_path, self._out_fifo_path, self._err_fifo _path],
887 check_return=True)
888 return (not self._device.PathExists(self._in_fifo_path) and
889 not self._device.PathExists(self._out_fifo_path) and
890 not self._device.PathExists(self._err_fifo_path))
891
892 def start(self, pixel_tests, per_test_args, deadline): 879 def start(self, pixel_tests, per_test_args, deadline):
893 # We override the default start() so that we can call _android_driver_cm d_line() 880 # We override the default start() so that we can call _android_driver_cm d_line()
894 # instead of cmd_line(). 881 # instead of cmd_line().
895 new_cmd_line = self._android_driver_cmd_line(pixel_tests, per_test_args) 882 new_cmd_line = self._android_driver_cmd_line(pixel_tests, per_test_args)
896 883
897 # Since _android_driver_cmd_line() is different than cmd_line() we need to provide 884 # Since _android_driver_cmd_line() is different than cmd_line() we need to provide
898 # our own mechanism for detecting when the process should be stopped. 885 # our own mechanism for detecting when the process should be stopped.
899 if self._current_cmd_line is None: 886 if self._current_cmd_line is None:
900 self._current_android_cmd_line = None 887 self._current_android_cmd_line = None
901 if new_cmd_line != self._current_android_cmd_line: 888 if new_cmd_line != self._current_android_cmd_line:
902 self.stop() 889 self.stop()
903 self._current_android_cmd_line = new_cmd_line 890 self._current_android_cmd_line = new_cmd_line
904 891
905 super(ChromiumAndroidDriver, self).start(pixel_tests, per_test_args, dea dline) 892 super(ChromiumAndroidDriver, self).start(pixel_tests, per_test_args, dea dline)
906 893
907 def _start(self, pixel_tests, per_test_args): 894 def _start(self, pixel_tests, per_test_args):
908 if not self._android_devices.is_device_prepared(self._device.serial): 895 if not self._android_devices.is_device_prepared(self._device.serial):
909 raise driver.DeviceFailure("%s is not prepared in _start()" % self._ device.serial) 896 raise driver.DeviceFailure("%s is not prepared in _start()" % self._ device.serial)
910 897
911 for retries in range(3): 898 for retries in range(3):
912 try: 899 try:
913 if self._start_once(pixel_tests, per_test_args): 900 if self._start_once(pixel_tests, per_test_args):
914 return 901 return
915 except ScriptError as e: 902 except ScriptError as e:
916 self._abort('ScriptError("%s") in _start()' % str(e)) 903 self._abort('ScriptError("%s") in _start()' % str(e))
917 904
918 self._log_error('Failed to start the content_shell application. Retr ies=%d. Log:%s' % (retries, self._get_logcat())) 905 self._log_error('Failed to start the content_shell application. Retr ies=%d. Log:\n%s' % (retries, self._get_logcat()))
919 self.stop() 906 self.stop()
920 time.sleep(2) 907 time.sleep(2)
921 self._abort('Failed to start the content_shell application multiple time s. Giving up.') 908 self._abort('Failed to start the content_shell application multiple time s. Giving up.')
922 909
923 def _start_once(self, pixel_tests, per_test_args): 910 def _start_once(self, pixel_tests, per_test_args):
924 super(ChromiumAndroidDriver, self)._start(pixel_tests, per_test_args, wa it_for_ready=False) 911 super(ChromiumAndroidDriver, self)._start(pixel_tests, per_test_args, wa it_for_ready=False)
925 912
913 self._device.adb.Logcat(clear=True)
914
915 self._device.RunShellCommand(
916 ['rm', '-rf', self._driver_details.device_crash_dumps_directory()],
917 check_return=True)
918 self._device.RunShellCommand(
919 ['mkdir', self._driver_details.device_crash_dumps_directory()],
920 check_return=True)
921 self._device.RunShellCommand(
922 ['chmod', '-R', '777', self._driver_details.device_crash_dumps_direc tory()],
923 check_return=True)
924
925 # Read back the shell prompt to ensure adb shell ready.
qyearsley 2016/12/02 23:35:22 s/ensure adb shell ready/ensure adb shell is ready
jbudorick 2016/12/05 14:30:38 Done.
926 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS
927 self._server_process.start()
928 self._read_prompt(deadline)
929 self._log_debug('Interactive shell started')
930
931 # Start a process to read from the stdout fifo of the test driver and pr int to stdout.
932 self._read_stdout_process, stdout_port = self._start_netcat(
933 'ReadStdout', read_from_stdin=False)
934 self._log_debug('Redirecting stdout to port %d' % stdout_port)
935
936 # Start a process to read from the stderr fifo of the test driver and pr int to stdout.
qyearsley 2016/12/02 23:35:22 What is the meaning of fifo in this context?
jbudorick 2016/12/05 14:30:38 It means that I didn't update this comment or the
937 self._read_stderr_process, stderr_port = self._start_netcat(
938 'ReadStderr', first_port=stdout_port + 1, read_from_stdin=False)
939 self._log_debug('Redirecting stderr to port %d' % stderr_port)
940
941 self._write_stdin_process, stdin_port = self._start_netcat(
942 'WriteStdin', first_port=stderr_port + 1)
943 self._log_debug('Redirecting stdin to port %d' % stdin_port)
944
945 # Combine the stdout and stderr pipes into self._server_process.
946 self._replace_server_process_streams()
947
926 # We delay importing forwarder as long as possible because it uses fcntl , 948 # We delay importing forwarder as long as possible because it uses fcntl ,
927 # which isn't available on windows. 949 # which isn't available on windows.
928 from devil.android import forwarder 950 from devil.android import forwarder
929 951
930 self._log_debug('Starting forwarder') 952 self._log_debug('Starting forwarder')
931 forwarder.Forwarder.Map( 953 forwarder.Forwarder.Map(
932 [(p, p) for p in FORWARD_PORTS.split()], 954 [(p, p) for p in FORWARD_PORTS.split()],
933 self._device) 955 self._device)
934 956 forwarder.Forwarder.Map(
935 self._device.adb.Logcat(clear=True) 957 [(0, stdout_port), (0, stderr_port), (0, stdin_port)],
958 self._device)
936 959
937 cmd_line_file_path = self._driver_details.command_line_file() 960 cmd_line_file_path = self._driver_details.command_line_file()
938 original_cmd_line_file_path = cmd_line_file_path + '.orig' 961 original_cmd_line_file_path = cmd_line_file_path + '.orig'
939 if (self._device.PathExists(cmd_line_file_path) 962 if (self._device.PathExists(cmd_line_file_path)
940 and not self._device.PathExists(original_cmd_line_file_path)): 963 and not self._device.PathExists(original_cmd_line_file_path)):
941 # We check for both the normal path and the backup because we do not want to step 964 # We check for both the normal path and the backup because we do not want to step
942 # on the backup. Otherwise, we'd clobber the backup whenever we chan ged the 965 # on the backup. Otherwise, we'd clobber the backup whenever we chan ged the
943 # command line during the run. 966 # command line during the run.
944 self._device.RunShellCommand( 967 self._device.RunShellCommand(
945 ['mv', cmd_line_file_path, original_cmd_line_file_path], 968 ['mv', cmd_line_file_path, original_cmd_line_file_path],
946 check_return=True) 969 check_return=True)
947 970
971 stream_port_args = [
972 '--android-stderr-port=%s' % forwarder.Forwarder.DevicePortForHostPo rt(stderr_port),
973 '--android-stdin-port=%s' % forwarder.Forwarder.DevicePortForHostPor t(stdin_port),
974 '--android-stdout-port=%s' % forwarder.Forwarder.DevicePortForHostPo rt(stdout_port),
975 ]
976 cmd_line_contents = self._android_driver_cmd_line(pixel_tests, per_test_ args + stream_port_args)
948 self._device.WriteFile( 977 self._device.WriteFile(
949 self._driver_details.command_line_file(), 978 self._driver_details.command_line_file(),
950 ' '.join(self._android_driver_cmd_line(pixel_tests, per_test_args))) 979 ' '.join(cmd_line_contents))
980 self._log_debug('Command-line file contents: %s' % ' '.join(cmd_line_con tents))
951 self._created_cmd_line = True 981 self._created_cmd_line = True
952 982
953 self._device.RunShellCommand(
954 ['rm', '-rf', self._driver_details.device_crash_dumps_directory()],
955 check_return=True)
956 self._device.RunShellCommand(
957 ['mkdir', self._driver_details.device_crash_dumps_directory()],
958 check_return=True)
959 self._device.RunShellCommand(
960 ['chmod', '-R', '777', self._driver_details.device_crash_dumps_direc tory()],
961 check_return=True)
962
963 try: 983 try:
964 self._device.StartActivity( 984 self._device.StartActivity(
965 intent.Intent( 985 intent.Intent(
966 component=self._driver_details.activity_name(), 986 component=self._driver_details.activity_name(),
967 extras={'RunInSubThread': None})) 987 extras={'RunInSubThread': None}))
968 except device_errors.CommandFailedError as exc: 988 except device_errors.CommandFailedError as exc:
969 self._log_error('Failed to start the content_shell application. Exce ption:\n' + str(exc)) 989 self._log_error('Failed to start the content_shell application. Exce ption:\n' + str(exc))
970 return False 990 return False
971 991
972 if not ChromiumAndroidDriver._loop_with_timeout(self._all_pipes_created, DRIVER_START_STOP_TIMEOUT_SECS): 992 # The test driver might crash during startup.
973 return False
974
975 # Read back the shell prompt to ensure adb shell ready.
976 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS
977 self._server_process.start()
978 self._read_prompt(deadline)
979 self._log_debug('Interactive shell started')
980
981 # Start a process to read from the stdout fifo of the test driver and pr int to stdout.
982 self._log_debug('Redirecting stdout to ' + self._out_fifo_path)
983 self._read_stdout_process = self._port._server_process_constructor(
984 self._port, 'ReadStdout',
985 [self._device.adb.GetAdbPath(), '-s', self._device.serial, 'shell', 'cat', self._out_fifo_path])
986 self._read_stdout_process.start()
987
988 # Start a process to read from the stderr fifo of the test driver and pr int to stdout.
989 self._log_debug('Redirecting stderr to ' + self._err_fifo_path)
990 self._read_stderr_process = self._port._server_process_constructor(
991 self._port, 'ReadStderr',
992 [self._device.adb.GetAdbPath(), '-s', self._device.serial, 'shell', 'cat', self._err_fifo_path])
993 self._read_stderr_process.start()
994
995 self._log_debug('Redirecting stdin to ' + self._in_fifo_path)
996 self._server_process.write('cat >%s\n' % self._in_fifo_path)
997
998 # Combine the stdout and stderr pipes into self._server_process.
999 self._server_process.replace_outputs(self._read_stdout_process._proc.std out, self._read_stderr_process._proc.stdout)
1000
1001 def deadlock_detector(processes, normal_startup_event):
1002 if not ChromiumAndroidDriver._loop_with_timeout(lambda: normal_start up_event.is_set(), DRIVER_START_STOP_TIMEOUT_SECS):
1003 # If normal_startup_event is not set in time, the main thread mu st be blocked at
1004 # reading/writing the fifo. Kill the fifo reading/writing proces ses to let the
1005 # main thread escape from the deadlocked state. After that, the main thread will
1006 # treat this as a crash.
1007 self._log_error('Deadlock detected. Processes killed.')
1008 for i in processes:
1009 i.kill()
1010
1011 # Start a thread to kill the pipe reading/writing processes on deadlock of the fifos during startup.
1012 normal_startup_event = threading.Event()
1013 threading.Thread(
1014 name='DeadlockDetector',
1015 target=deadlock_detector,
1016 args=([self._server_process, self._read_stdout_process, self._read_s tderr_process], normal_startup_event)).start()
1017
1018 # The test driver might crash during startup or when the deadlock detect or hits
1019 # a deadlock and kills the fifo reading/writing processes.
1020 if not self._wait_for_server_process_output(self._server_process, deadli ne, '#READY'): 993 if not self._wait_for_server_process_output(self._server_process, deadli ne, '#READY'):
1021 return False 994 return False
1022 995
1023 # Inform the deadlock detector that the startup is successful without de adlock.
1024 normal_startup_event.set()
1025 self._log_debug("content_shell is ready") 996 self._log_debug("content_shell is ready")
1026 return True 997 return True
1027 998
999 def _start_netcat(self, server_name, first_port=10201, read_from_stdin=True) :
1000 for i in itertools.count(first_port, 65536):
1001 nc_cmd = ['nc', '-l', str(i)]
1002 if not read_from_stdin:
1003 nc_cmd.append('-d')
1004 proc = self._port.server_process_constructor(self._port, server_name , nc_cmd)
1005 proc.start()
1006 self._port.host.executive.wait_limited(proc.pid(), limit_in_seconds= 1)
1007 if self._port.host.executive.check_running_pid(proc.pid()):
1008 return (proc, i)
1009
1010 def _replace_server_process_streams(self):
1011 # pylint: disable=protected-access
1012 self._server_process.replace_input(
1013 self._write_stdin_process._proc.stdin)
1014 self._server_process.replace_outputs(
1015 self._read_stdout_process._proc.stdout,
1016 self._read_stderr_process._proc.stdout)
1017
1028 def _pid_on_target(self): 1018 def _pid_on_target(self):
1029 pids = self._device.GetPids(self._driver_details.package_name()) 1019 pids = self._device.GetPids(self._driver_details.package_name())
1030 return pids.get(self._driver_details.package_name()) 1020 return pids.get(self._driver_details.package_name())
1031 1021
1032 def stop(self): 1022 def stop(self):
1033 if not self._device_failed: 1023 if not self._device_failed:
1034 # Do not try to stop the application if there's something wrong with the device; adb may hang. 1024 # Do not try to stop the application if there's something wrong with the device; adb may hang.
1035 # FIXME: crbug.com/305040. Figure out if it's really hanging (and wh y). 1025 # FIXME: crbug.com/305040. Figure out if it's really hanging (and wh y).
1036 self._device.ForceStop(self._driver_details.package_name()) 1026 self._device.ForceStop(self._driver_details.package_name())
1037 1027
1028 if self._write_stdin_process:
1029 self._write_stdin_process.kill()
1030 self._write_stdin_process = None
1031
1038 if self._read_stdout_process: 1032 if self._read_stdout_process:
1039 self._read_stdout_process.kill() 1033 self._read_stdout_process.kill()
1040 self._read_stdout_process = None 1034 self._read_stdout_process = None
1041 1035
1042 if self._read_stderr_process: 1036 if self._read_stderr_process:
1043 self._read_stderr_process.kill() 1037 self._read_stderr_process.kill()
1044 self._read_stderr_process = None 1038 self._read_stderr_process = None
1045 1039
1046 # We delay importing forwarder as long as possible because it uses fcntl , 1040 # We delay importing forwarder as long as possible because it uses fcntl ,
1047 # which isn't available on windows. 1041 # which isn't available on windows.
1048 from devil.android import forwarder 1042 from devil.android import forwarder
1049 1043
1050 forwarder.Forwarder.KillDevice(self._device) 1044 forwarder.Forwarder.KillDevice(self._device)
1051 forwarder.Forwarder.KillHost() 1045 forwarder.Forwarder.KillHost()
1052 1046
1053 super(ChromiumAndroidDriver, self).stop() 1047 super(ChromiumAndroidDriver, self).stop()
1054 1048
1055 if self._android_devices.is_device_prepared(self._device.serial):
1056 if not ChromiumAndroidDriver._loop_with_timeout(self._remove_all_pip es, DRIVER_START_STOP_TIMEOUT_SECS):
1057 self._abort('Failed to remove fifo files. May be locked.')
1058
1059 self._clean_up_cmd_line() 1049 self._clean_up_cmd_line()
1060 1050
1061 def _pull_crash_dumps_from_device(self): 1051 def _pull_crash_dumps_from_device(self):
1062 result = [] 1052 result = []
1063 if not self._device.PathExists(self._driver_details.device_crash_dumps_d irectory()): 1053 if not self._device.PathExists(self._driver_details.device_crash_dumps_d irectory()):
1064 return result 1054 return result
1065 dumps = self._device.ListDirectory( 1055 dumps = self._device.ListDirectory(
1066 self._driver_details.device_crash_dumps_directory()) 1056 self._driver_details.device_crash_dumps_directory())
1067 for dump in dumps: 1057 for dump in dumps:
1068 device_dump = '%s/%s' % (self._driver_details.device_crash_dumps_dir ectory(), dump) 1058 device_dump = '%s/%s' % (self._driver_details.device_crash_dumps_dir ectory(), dump)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 return command 1099 return command
1110 1100
1111 def _read_prompt(self, deadline): 1101 def _read_prompt(self, deadline):
1112 last_char = '' 1102 last_char = ''
1113 while True: 1103 while True:
1114 current_char = self._server_process.read_stdout(deadline, 1) 1104 current_char = self._server_process.read_stdout(deadline, 1)
1115 if current_char == ' ': 1105 if current_char == ' ':
1116 if last_char in ('#', '$'): 1106 if last_char in ('#', '$'):
1117 return 1107 return
1118 last_char = current_char 1108 last_char = current_char
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698