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

Side by Side Diff: build/android/pylib/forwarder.py

Issue 10689132: [android] Upstream / sync most of build/android and build/android/pylib. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « build/android/pylib/fake_dns.py ('k') | build/android/pylib/io_stats_parser.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 import logging
6 import os
7 import pexpect
8 import re
9 import sys
10
11 import android_commands
12 from constants import CHROME_DIR
13
14 class Forwarder(object):
15 """Class to manage port forwards from the device to the host."""
16
17 _FORWARDER_PATH = '/data/local/tmp/forwarder'
18 _TIMEOUT_SECS = 30
19
20 def __init__(self, adb, port_pairs, tool, host_name):
21 """Forwards TCP ports on the device back to the host.
22
23 Works like adb forward, but in reverse.
24
25 Args:
26 adb: Instance of AndroidCommands for talking to the device.
27 port_pairs: A list of tuples (device_port, host_port) to forward. Note
28 that you can specify 0 as a device_port, in which case a
29 port will by dynamically assigned on the device. You can
30 get the number of the assigned port using the
31 DevicePortForHostPort method.
32 tool: Tool class to use to get wrapper, if necessary, for executing the
33 forwarder (see valgrind_tools.py).
34 host_name: Optional. Address to forward to, must be addressable from the
35 host machine. Usually this is omitted and loopback is used.
36
37 Raises:
38 Exception on failure to forward the port.
39 """
40 self._adb = adb
41 self._host_to_device_port_map = dict()
42 self._process = None
43 adb.PushIfNeeded(
44 os.path.join(CHROME_DIR, 'out', 'Release', 'forwarder'),
45 Forwarder._FORWARDER_PATH)
46 forward_string = ['%d:%d:%s' %
47 (device, host, host_name) for device, host in port_pairs]
48
49 # Kill off any existing forwarders on conflicting non-dynamically allocated
50 # ports.
51 for device_port, _ in port_pairs:
52 if device_port != 0:
53 self._KillForwardersUsingDevicePort(device_port)
54
55 logging.info('Forwarding ports: %s' % (forward_string))
56 process = pexpect.spawn(
57 'adb', ['-s', adb._adb.GetSerialNumber(),
58 'shell', '%s %s -D %s' % (
59 tool.GetUtilWrapper(), Forwarder._FORWARDER_PATH,
60 ' '.join(forward_string))])
61
62 # Read the output of the command to determine which device ports where
63 # forwarded to which host ports (necessary if
64 success_re = re.compile('Forwarding device port (\d+) to host (\d+):')
65 failure_re = re.compile('Couldn\'t start forwarder server for port spec: '
66 '(\d+):(\d+)')
67 for pair in port_pairs:
68 index = process.expect([success_re, failure_re, pexpect.EOF,
69 pexpect.TIMEOUT],
70 Forwarder._TIMEOUT_SECS)
71 if index == 0:
72 # Success
73 device_port = int(process.match.group(1))
74 host_port = int(process.match.group(2))
75 self._host_to_device_port_map[host_port] = device_port
76 logging.info("Forwarding device port: %d to host port: %d." %
77 (device_port, host_port))
78 elif index == 1:
79 # Failure
80 device_port = int(process.match.group(1))
81 host_port = int(process.match.group(2))
82 process.close()
83 raise Exception('Failed to forward port %d to %d' % (device_port,
84 host_port))
85 elif index == 2:
86 logging.error(process.before)
87 process.close()
88 raise Exception('Unexpected EOF while trying to forward ports %s' %
89 port_pairs)
90 elif index == 3:
91 logging.error(process.before)
92 process.close()
93 raise Exception('Timeout while trying to forward ports %s' % port_pairs)
94
95 self._process = process
96
97 def _KillForwardersUsingDevicePort(self, device_port):
98 """Check if the device port is in use and if it is try to terminate the
99 forwarder process (if any) that may already be forwarding it"""
100 processes = self._adb.ProcessesUsingDevicePort(device_port)
101 for pid, name in processes:
102 if name == 'forwarder':
103 logging.warning(
104 'Killing forwarder process with pid %d using device_port %d' % (
105 pid, device_port))
106 self._adb.RunShellCommand('kill %d' % pid)
107 else:
108 logging.error(
109 'Not killing process with pid %d (%s) using device_port %d' % (
110 pid, name, device_port))
111
112 def DevicePortForHostPort(self, host_port):
113 """Get the device port that corresponds to a given host port."""
114 return self._host_to_device_port_map.get(host_port)
115
116 def Close(self):
117 """Terminate the forwarder process."""
118 if self._process:
119 self._process.close()
120 self._process = None
OLDNEW
« no previous file with comments | « build/android/pylib/fake_dns.py ('k') | build/android/pylib/io_stats_parser.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698