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: mojo/devtools/common/devtoolslib/android_shell.py

Issue 1253273003: Unify casing of function names in devtools. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Rebase. Created 5 years, 4 months 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
« no previous file with comments | « no previous file | mojo/devtools/common/devtoolslib/http_server.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 import atexit 5 import atexit
6 import hashlib 6 import hashlib
7 import json 7 import json
8 import logging 8 import logging
9 import os 9 import os
10 import os.path 10 import os.path
11 import random 11 import random
12 import re 12 import re
13 import subprocess 13 import subprocess
14 import sys 14 import sys
15 import tempfile 15 import tempfile
16 import threading 16 import threading
17 import time 17 import time
18 18
19 from devtoolslib.http_server import StartHttpServer 19 from devtoolslib.http_server import start_http_server
20 from devtoolslib.shell import Shell 20 from devtoolslib.shell import Shell
21 21
22 22
23 # Tags used by mojo shell Java logging. 23 # Tags used by mojo shell Java logging.
24 _LOGCAT_JAVA_TAGS = [ 24 _LOGCAT_JAVA_TAGS = [
25 'AndroidHandler', 25 'AndroidHandler',
26 'MojoFileHelper', 26 'MojoFileHelper',
27 'MojoMain', 27 'MojoMain',
28 'MojoShellActivity', 28 'MojoShellActivity',
29 'MojoShellApplication', 29 'MojoShellApplication',
30 ] 30 ]
31 31
32 # Tags used by native logging reflected in the logcat. 32 # Tags used by native logging reflected in the logcat.
33 _LOGCAT_NATIVE_TAGS = [ 33 _LOGCAT_NATIVE_TAGS = [
34 'chromium', 34 'chromium',
35 'sky', 35 'sky',
36 ] 36 ]
37 37
38 _MOJO_SHELL_PACKAGE_NAME = 'org.chromium.mojo.shell' 38 _MOJO_SHELL_PACKAGE_NAME = 'org.chromium.mojo.shell'
39 39
40 40
41 _logger = logging.getLogger() 41 _logger = logging.getLogger()
42 42
43 43
44 def _ExitIfNeeded(process): 44 def _exit_if_needed(process):
45 """Exits |process| if it is still alive.""" 45 """Exits |process| if it is still alive."""
46 if process.poll() is None: 46 if process.poll() is None:
47 process.kill() 47 process.kill()
48 48
49 49
50 def _FindAvailablePort(netstat_output, max_attempts=10000): 50 def _find_available_port(netstat_output, max_attempts=10000):
51 opened = [int(x.strip().split()[3].split(':')[1]) 51 opened = [int(x.strip().split()[3].split(':')[1])
52 for x in netstat_output if x.startswith(' tcp')] 52 for x in netstat_output if x.startswith(' tcp')]
53 for _ in xrange(max_attempts): 53 for _ in xrange(max_attempts):
54 port = random.randint(4096, 16384) 54 port = random.randint(4096, 16384)
55 if port not in opened: 55 if port not in opened:
56 return port 56 return port
57 else: 57 else:
58 raise Exception('Failed to identify an available port.') 58 raise Exception('Failed to identify an available port.')
59 59
60 60
61 def _FindAvailableHostPort(): 61 def _find_available_host_port():
62 netstat_output = subprocess.check_output(['netstat']) 62 netstat_output = subprocess.check_output(['netstat'])
63 return _FindAvailablePort(netstat_output) 63 return _find_available_port(netstat_output)
64 64
65 65
66 class AndroidShell(Shell): 66 class AndroidShell(Shell):
67 """Wrapper around Mojo shell running on an Android device. 67 """Wrapper around Mojo shell running on an Android device.
68 68
69 Args: 69 Args:
70 adb_path: Path to adb, optional if adb is in PATH. 70 adb_path: Path to adb, optional if adb is in PATH.
71 target_device: Device to run on, if multiple devices are connected. 71 target_device: Device to run on, if multiple devices are connected.
72 logcat_tags: Comma-separated list of additional logcat tags to use. 72 logcat_tags: Comma-separated list of additional logcat tags to use.
73 """ 73 """
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 for _ in xrange(max_attempts): 106 for _ in xrange(max_attempts):
107 if subprocess.check_output(fifo_command)[0] == '0': 107 if subprocess.check_output(fifo_command)[0] == '0':
108 return 108 return
109 time.sleep(1) 109 time.sleep(1)
110 if on_fifo_closed: 110 if on_fifo_closed:
111 on_fifo_closed() 111 on_fifo_closed()
112 raise Exception("Unable to find fifo.") 112 raise Exception("Unable to find fifo.")
113 _WaitForFifo() 113 _WaitForFifo()
114 stdout_cat = subprocess.Popen( 114 stdout_cat = subprocess.Popen(
115 self._AdbCommand(['shell', 'cat', fifo_path]), stdout=pipe) 115 self._AdbCommand(['shell', 'cat', fifo_path]), stdout=pipe)
116 atexit.register(_ExitIfNeeded, stdout_cat) 116 atexit.register(_exit_if_needed, stdout_cat)
117 stdout_cat.wait() 117 stdout_cat.wait()
118 if on_fifo_closed: 118 if on_fifo_closed:
119 on_fifo_closed() 119 on_fifo_closed()
120 120
121 thread = threading.Thread(target=Run, name="StdoutRedirector") 121 thread = threading.Thread(target=Run, name="StdoutRedirector")
122 thread.start() 122 thread.start()
123 123
124 def _FindAvailableDevicePort(self): 124 def _FindAvailableDevicePort(self):
125 netstat_output = subprocess.check_output( 125 netstat_output = subprocess.check_output(
126 self._AdbCommand(['shell', 'netstat'])) 126 self._AdbCommand(['shell', 'netstat']))
127 return _FindAvailablePort(netstat_output) 127 return _find_available_port(netstat_output)
128 128
129 def _ForwardDevicePortToHost(self, device_port, host_port): 129 def _ForwardDevicePortToHost(self, device_port, host_port):
130 """Maps the device port to the host port. If |device_port| is 0, a random 130 """Maps the device port to the host port. If |device_port| is 0, a random
131 available port is chosen. 131 available port is chosen.
132 132
133 Returns: 133 Returns:
134 The device port. 134 The device port.
135 """ 135 """
136 assert host_port 136 assert host_port
137 # Root is not required for `adb forward` (hence we don't check the return 137 # Root is not required for `adb forward` (hence we don't check the return
(...skipping 20 matching lines...) Expand all
158 available port is chosen. 158 available port is chosen.
159 159
160 Returns: 160 Returns:
161 The host port. 161 The host port.
162 """ 162 """
163 assert device_port 163 assert device_port
164 self._RunAdbAsRoot() 164 self._RunAdbAsRoot()
165 165
166 if host_port == 0: 166 if host_port == 0:
167 # TODO(ppi): Should we have a retry loop to handle the unlikely races? 167 # TODO(ppi): Should we have a retry loop to handle the unlikely races?
168 host_port = _FindAvailableHostPort() 168 host_port = _find_available_host_port()
169 subprocess.check_call(self._AdbCommand([ 169 subprocess.check_call(self._AdbCommand([
170 "forward", 'tcp:%d' % host_port, 'tcp:%d' % device_port])) 170 "forward", 'tcp:%d' % host_port, 'tcp:%d' % device_port]))
171 171
172 def _UnmapPort(): 172 def _UnmapPort():
173 unmap_command = self._AdbCommand([ 173 unmap_command = self._AdbCommand([
174 "forward", "--remove", "tcp:%d" % device_port]) 174 "forward", "--remove", "tcp:%d" % device_port])
175 subprocess.Popen(unmap_command) 175 subprocess.Popen(unmap_command)
176 atexit.register(_UnmapPort) 176 atexit.register(_UnmapPort)
177 return host_port 177 return host_port
178 178
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 self.StopShell() 272 self.StopShell()
273 273
274 def StartShell(self, 274 def StartShell(self,
275 arguments, 275 arguments,
276 stdout=None, 276 stdout=None,
277 on_application_stop=None): 277 on_application_stop=None):
278 """Starts the mojo shell, passing it the given arguments. 278 """Starts the mojo shell, passing it the given arguments.
279 279
280 Args: 280 Args:
281 arguments: List of arguments for the shell. It must contain the 281 arguments: List of arguments for the shell. It must contain the
282 "--origin=" arg. shell_arguments.ConfigureLocalOrigin() can be used 282 "--origin=" arg. shell_arguments.configure_local_origin() can be used
283 to set up a local directory on the host machine as origin. 283 to set up a local directory on the host machine as origin.
284 stdout: Valid argument for subprocess.Popen() or None. 284 stdout: Valid argument for subprocess.Popen() or None.
285 """ 285 """
286 if not self.stop_shell_registered: 286 if not self.stop_shell_registered:
287 atexit.register(self.StopShell) 287 atexit.register(self.StopShell)
288 self.stop_shell_registered = True 288 self.stop_shell_registered = True
289 289
290 STDOUT_PIPE = "/data/data/%s/stdout.fifo" % _MOJO_SHELL_PACKAGE_NAME 290 STDOUT_PIPE = "/data/data/%s/stdout.fifo" % _MOJO_SHELL_PACKAGE_NAME
291 291
292 cmd = self._AdbCommand(['shell', 'am', 'start', 292 cmd = self._AdbCommand(['shell', 'am', 'start',
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 The process responsible for reading the logs. 337 The process responsible for reading the logs.
338 """ 338 """
339 tags = _LOGCAT_JAVA_TAGS 339 tags = _LOGCAT_JAVA_TAGS
340 if include_native_logs: 340 if include_native_logs:
341 tags.extend(_LOGCAT_NATIVE_TAGS) 341 tags.extend(_LOGCAT_NATIVE_TAGS)
342 if self.additional_logcat_tags is not None: 342 if self.additional_logcat_tags is not None:
343 tags.extend(self.additional_logcat_tags.split(",")) 343 tags.extend(self.additional_logcat_tags.split(","))
344 logcat = subprocess.Popen( 344 logcat = subprocess.Popen(
345 self._AdbCommand(['logcat', '-s', ' '.join(tags)]), 345 self._AdbCommand(['logcat', '-s', ' '.join(tags)]),
346 stdout=sys.stdout) 346 stdout=sys.stdout)
347 atexit.register(_ExitIfNeeded, logcat) 347 atexit.register(_exit_if_needed, logcat)
348 return logcat 348 return logcat
349 349
350 def ForwardObservatoryPorts(self): 350 def ForwardObservatoryPorts(self):
351 """Forwards the ports used by the dart observatories to the host machine. 351 """Forwards the ports used by the dart observatories to the host machine.
352 """ 352 """
353 logcat = subprocess.Popen(self._AdbCommand(['logcat']), 353 logcat = subprocess.Popen(self._AdbCommand(['logcat']),
354 stdout=subprocess.PIPE) 354 stdout=subprocess.PIPE)
355 atexit.register(_ExitIfNeeded, logcat) 355 atexit.register(_exit_if_needed, logcat)
356 356
357 def _ForwardObservatoriesAsNeeded(): 357 def _ForwardObservatoriesAsNeeded():
358 while True: 358 while True:
359 line = logcat.stdout.readline() 359 line = logcat.stdout.readline()
360 if not line: 360 if not line:
361 break 361 break
362 match = re.search(r'Observatory listening on http://127.0.0.1:(\d+)', 362 match = re.search(r'Observatory listening on http://127.0.0.1:(\d+)',
363 line) 363 line)
364 if match: 364 if match:
365 device_port = int(match.group(1)) 365 device_port = int(match.group(1))
(...skipping 16 matching lines...) Expand all
382 local_dir_path: path to the directory to be served 382 local_dir_path: path to the directory to be served
383 port: port at which the server will be available to the shell 383 port: port at which the server will be available to the shell
384 additional_mappings: List of tuples (prefix, local_base_path) mapping 384 additional_mappings: List of tuples (prefix, local_base_path) mapping
385 URLs that start with |prefix| to local directory at |local_base_path|. 385 URLs that start with |prefix| to local directory at |local_base_path|.
386 The prefixes should skip the leading slash. 386 The prefixes should skip the leading slash.
387 387
388 Returns: 388 Returns:
389 The url that the shell can use to access the content of |local_dir_path|. 389 The url that the shell can use to access the content of |local_dir_path|.
390 """ 390 """
391 assert local_dir_path 391 assert local_dir_path
392 server_address = StartHttpServer(local_dir_path, host_port=port, 392 server_address = start_http_server(local_dir_path, host_port=port,
393 additional_mappings=additional_mappings) 393 additional_mappings=additional_mappings)
394 394
395 return 'http://127.0.0.1:%d/' % self._ForwardDevicePortToHost( 395 return 'http://127.0.0.1:%d/' % self._ForwardDevicePortToHost(
396 port, server_address[1]) 396 port, server_address[1])
397 397
398 def ForwardHostPortToShell(self, host_port): 398 def ForwardHostPortToShell(self, host_port):
399 """Forwards a port on the host machine to the same port wherever the shell 399 """Forwards a port on the host machine to the same port wherever the shell
400 is running. 400 is running.
401 401
402 This is a no-op if the shell is running locally. 402 This is a no-op if the shell is running locally.
403 """ 403 """
(...skipping 27 matching lines...) Expand all
431 A tuple of (return_code, output). |return_code| is the exit code returned 431 A tuple of (return_code, output). |return_code| is the exit code returned
432 by the shell or None if the exit code cannot be retrieved. |output| is the 432 by the shell or None if the exit code cannot be retrieved. |output| is the
433 stdout mingled with the stderr produced by the shell. 433 stdout mingled with the stderr produced by the shell.
434 """ 434 """
435 (r, w) = os.pipe() 435 (r, w) = os.pipe()
436 with os.fdopen(r, "r") as rf: 436 with os.fdopen(r, "r") as rf:
437 with os.fdopen(w, "w") as wf: 437 with os.fdopen(w, "w") as wf:
438 self.StartShell(arguments, wf, wf.close) 438 self.StartShell(arguments, wf, wf.close)
439 output = rf.read() 439 output = rf.read()
440 return None, output 440 return None, output
OLDNEW
« no previous file with comments | « no previous file | mojo/devtools/common/devtoolslib/http_server.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698