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

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

Issue 221823011: [Android] Change object types from AndroidCommands to DeviceUtils in build/android/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Frank's comments. Created 6 years, 8 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
OLDNEW
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 # pylint: disable=W0212 5 # pylint: disable=W0212
6 6
7 import fcntl 7 import fcntl
8 import logging 8 import logging
9 import os 9 import os
10 import psutil 10 import psutil
11 11
12 from pylib import cmd_helper 12 from pylib import cmd_helper
13 from pylib import constants 13 from pylib import constants
14 from pylib import valgrind_tools 14 from pylib import valgrind_tools
15 15
16 # TODO(jbudorick) Remove once telemetry gets switched over.
17 import pylib.android_commands
18 import pylib.device.device_utils
19
16 20
17 def _GetProcessStartTime(pid): 21 def _GetProcessStartTime(pid):
18 return psutil.Process(pid).create_time 22 return psutil.Process(pid).create_time
19 23
20 24
21 class _FileLock(object): 25 class _FileLock(object):
22 """With statement-aware implementation of a file lock. 26 """With statement-aware implementation of a file lock.
23 27
24 File locks are needed for cross-process synchronization when the 28 File locks are needed for cross-process synchronization when the
25 multiprocessing Python module is used. 29 multiprocessing Python module is used.
(...skipping 27 matching lines...) Expand all
53 _HOST_FORWARDER_LOG = '/tmp/host_forwarder_log' 57 _HOST_FORWARDER_LOG = '/tmp/host_forwarder_log'
54 58
55 _instance = None 59 _instance = None
56 60
57 @staticmethod 61 @staticmethod
58 def UseMultiprocessing(): 62 def UseMultiprocessing():
59 """Tells the forwarder that multiprocessing is used.""" 63 """Tells the forwarder that multiprocessing is used."""
60 os.environ[Forwarder._MULTIPROCESSING_ENV_VAR] = '1' 64 os.environ[Forwarder._MULTIPROCESSING_ENV_VAR] = '1'
61 65
62 @staticmethod 66 @staticmethod
63 def Map(port_pairs, adb, tool=None): 67 def Map(port_pairs, device, tool=None):
64 """Runs the forwarder. 68 """Runs the forwarder.
65 69
66 Args: 70 Args:
67 port_pairs: A list of tuples (device_port, host_port) to forward. Note 71 port_pairs: A list of tuples (device_port, host_port) to forward. Note
68 that you can specify 0 as a device_port, in which case a 72 that you can specify 0 as a device_port, in which case a
69 port will by dynamically assigned on the device. You can 73 port will by dynamically assigned on the device. You can
70 get the number of the assigned port using the 74 get the number of the assigned port using the
71 DevicePortForHostPort method. 75 DevicePortForHostPort method.
72 adb: An AndroidCommands instance. 76 device: A DeviceUtils instance.
73 tool: Tool class to use to get wrapper, if necessary, for executing the 77 tool: Tool class to use to get wrapper, if necessary, for executing the
74 forwarder (see valgrind_tools.py). 78 forwarder (see valgrind_tools.py).
75 79
76 Raises: 80 Raises:
77 Exception on failure to forward the port. 81 Exception on failure to forward the port.
78 """ 82 """
83 # TODO(jbudorick) Remove once telemetry gets switched over.
84 if isinstance(device, pylib.android_commands.AndroidCommands):
85 device = pylib.device.device_utils.DeviceUtils(device)
79 if not tool: 86 if not tool:
80 tool = valgrind_tools.CreateTool(None, adb) 87 tool = valgrind_tools.CreateTool(None, device)
81 with _FileLock(Forwarder._LOCK_PATH): 88 with _FileLock(Forwarder._LOCK_PATH):
82 instance = Forwarder._GetInstanceLocked(tool) 89 instance = Forwarder._GetInstanceLocked(tool)
83 instance._InitDeviceLocked(adb, tool) 90 instance._InitDeviceLocked(device, tool)
84 91
85 device_serial = adb.Adb().GetSerialNumber() 92 device_serial = device.old_interface.Adb().GetSerialNumber()
86 redirection_commands = [ 93 redirection_commands = [
87 ['--serial-id=' + device_serial, '--map', str(device), 94 ['--serial-id=' + device_serial, '--map', str(device),
88 str(host)] for device, host in port_pairs] 95 str(host)] for device, host in port_pairs]
89 logging.info('Forwarding using commands: %s', redirection_commands) 96 logging.info('Forwarding using commands: %s', redirection_commands)
90 97
91 for redirection_command in redirection_commands: 98 for redirection_command in redirection_commands:
92 try: 99 try:
93 (exit_code, output) = cmd_helper.GetCmdStatusAndOutput( 100 (exit_code, output) = cmd_helper.GetCmdStatusAndOutput(
94 [instance._host_forwarder_path] + redirection_command) 101 [instance._host_forwarder_path] + redirection_command)
95 except OSError as e: 102 except OSError as e:
(...skipping 10 matching lines...) Expand all
106 'expected "device_port:host_port"') % output) 113 'expected "device_port:host_port"') % output)
107 device_port = int(tokens[0]) 114 device_port = int(tokens[0])
108 host_port = int(tokens[1]) 115 host_port = int(tokens[1])
109 serial_with_port = (device_serial, device_port) 116 serial_with_port = (device_serial, device_port)
110 instance._device_to_host_port_map[serial_with_port] = host_port 117 instance._device_to_host_port_map[serial_with_port] = host_port
111 instance._host_to_device_port_map[host_port] = serial_with_port 118 instance._host_to_device_port_map[host_port] = serial_with_port
112 logging.info('Forwarding device port: %d to host port: %d.', 119 logging.info('Forwarding device port: %d to host port: %d.',
113 device_port, host_port) 120 device_port, host_port)
114 121
115 @staticmethod 122 @staticmethod
116 def UnmapDevicePort(device_port, adb): 123 def UnmapDevicePort(device_port, device):
117 """Unmaps a previously forwarded device port. 124 """Unmaps a previously forwarded device port.
118 125
119 Args: 126 Args:
120 adb: An AndroidCommands instance. 127 device: A DeviceUtils instance.
121 device_port: A previously forwarded port (through Map()). 128 device_port: A previously forwarded port (through Map()).
122 """ 129 """
130 # TODO(jbudorick) Remove once telemetry gets switched over.
131 if isinstance(device, pylib.android_commands.AndroidCommands):
132 device = pylib.device.device_utils.DeviceUtils(device)
123 with _FileLock(Forwarder._LOCK_PATH): 133 with _FileLock(Forwarder._LOCK_PATH):
124 Forwarder._UnmapDevicePortLocked(device_port, adb) 134 Forwarder._UnmapDevicePortLocked(device_port, device)
125 135
126 @staticmethod 136 @staticmethod
127 def UnmapAllDevicePorts(adb): 137 def UnmapAllDevicePorts(device):
128 """Unmaps all the previously forwarded ports for the provided device. 138 """Unmaps all the previously forwarded ports for the provided device.
129 139
130 Args: 140 Args:
131 adb: An AndroidCommands instance. 141 device: A DeviceUtils instance.
132 port_pairs: A list of tuples (device_port, host_port) to unmap. 142 port_pairs: A list of tuples (device_port, host_port) to unmap.
133 """ 143 """
134 with _FileLock(Forwarder._LOCK_PATH): 144 with _FileLock(Forwarder._LOCK_PATH):
135 if not Forwarder._instance: 145 if not Forwarder._instance:
136 return 146 return
137 adb_serial = adb.Adb().GetSerialNumber() 147 adb_serial = device.old_interface.Adb().GetSerialNumber()
138 if adb_serial not in Forwarder._instance._initialized_devices: 148 if adb_serial not in Forwarder._instance._initialized_devices:
139 return 149 return
140 port_map = Forwarder._GetInstanceLocked( 150 port_map = Forwarder._GetInstanceLocked(
141 None)._device_to_host_port_map 151 None)._device_to_host_port_map
142 for (device_serial, device_port) in port_map.keys(): 152 for (device_serial, device_port) in port_map.keys():
143 if adb_serial == device_serial: 153 if adb_serial == device_serial:
144 Forwarder._UnmapDevicePortLocked(device_port, adb) 154 Forwarder._UnmapDevicePortLocked(device_port, device)
145 # There are no more ports mapped, kill the device_forwarder. 155 # There are no more ports mapped, kill the device_forwarder.
146 tool = valgrind_tools.CreateTool(None, adb) 156 tool = valgrind_tools.CreateTool(None, device)
147 Forwarder._KillDeviceLocked(adb, tool) 157 Forwarder._KillDeviceLocked(device, tool)
148 Forwarder._instance._initialized_devices.remove(adb_serial) 158 Forwarder._instance._initialized_devices.remove(adb_serial)
149 159
150 160
151 @staticmethod 161 @staticmethod
152 def DevicePortForHostPort(host_port): 162 def DevicePortForHostPort(host_port):
153 """Returns the device port that corresponds to a given host port.""" 163 """Returns the device port that corresponds to a given host port."""
154 with _FileLock(Forwarder._LOCK_PATH): 164 with _FileLock(Forwarder._LOCK_PATH):
155 (_device_serial, device_port) = Forwarder._GetInstanceLocked( 165 (_device_serial, device_port) = Forwarder._GetInstanceLocked(
156 None)._host_to_device_port_map.get(host_port) 166 None)._host_to_device_port_map.get(host_port)
157 return device_port 167 return device_port
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 self._device_to_host_port_map = dict() 208 self._device_to_host_port_map = dict()
199 self._host_to_device_port_map = dict() 209 self._host_to_device_port_map = dict()
200 self._host_forwarder_path = os.path.join( 210 self._host_forwarder_path = os.path.join(
201 constants.GetOutDirectory(), 'host_forwarder') 211 constants.GetOutDirectory(), 'host_forwarder')
202 assert os.path.exists(self._host_forwarder_path), 'Please build forwarder2' 212 assert os.path.exists(self._host_forwarder_path), 'Please build forwarder2'
203 self._device_forwarder_path_on_host = os.path.join( 213 self._device_forwarder_path_on_host = os.path.join(
204 constants.GetOutDirectory(), 'forwarder_dist') 214 constants.GetOutDirectory(), 'forwarder_dist')
205 self._InitHostLocked() 215 self._InitHostLocked()
206 216
207 @staticmethod 217 @staticmethod
208 def _UnmapDevicePortLocked(device_port, adb): 218 def _UnmapDevicePortLocked(device_port, device):
209 """Internal method used by UnmapDevicePort(). 219 """Internal method used by UnmapDevicePort().
210 220
211 Note that the global lock must be acquired before calling this method. 221 Note that the global lock must be acquired before calling this method.
212 """ 222 """
213 instance = Forwarder._GetInstanceLocked(None) 223 instance = Forwarder._GetInstanceLocked(None)
214 serial = adb.Adb().GetSerialNumber() 224 serial = device.old_interface.Adb().GetSerialNumber()
215 serial_with_port = (serial, device_port) 225 serial_with_port = (serial, device_port)
216 if not serial_with_port in instance._device_to_host_port_map: 226 if not serial_with_port in instance._device_to_host_port_map:
217 logging.error('Trying to unmap non-forwarded port %d' % device_port) 227 logging.error('Trying to unmap non-forwarded port %d' % device_port)
218 return 228 return
219 redirection_command = ['--serial-id=' + serial, '--unmap', str(device_port)] 229 redirection_command = ['--serial-id=' + serial, '--unmap', str(device_port)]
220 (exit_code, output) = cmd_helper.GetCmdStatusAndOutput( 230 (exit_code, output) = cmd_helper.GetCmdStatusAndOutput(
221 [instance._host_forwarder_path] + redirection_command) 231 [instance._host_forwarder_path] + redirection_command)
222 if exit_code != 0: 232 if exit_code != 0:
223 logging.error('%s exited with %d:\n%s' % ( 233 logging.error('%s exited with %d:\n%s' % (
224 instance._host_forwarder_path, exit_code, '\n'.join(output))) 234 instance._host_forwarder_path, exit_code, '\n'.join(output)))
(...skipping 28 matching lines...) Expand all
253 if pid_with_start_time: 263 if pid_with_start_time:
254 (pid, process_start_time) = pid_with_start_time.split(':') 264 (pid, process_start_time) = pid_with_start_time.split(':')
255 if pid == str(pid_for_lock): 265 if pid == str(pid_for_lock):
256 if process_start_time == str(_GetProcessStartTime(pid_for_lock)): 266 if process_start_time == str(_GetProcessStartTime(pid_for_lock)):
257 return 267 return
258 self._KillHostLocked() 268 self._KillHostLocked()
259 pid_file.seek(0) 269 pid_file.seek(0)
260 pid_file.write( 270 pid_file.write(
261 '%s:%s' % (pid_for_lock, str(_GetProcessStartTime(pid_for_lock)))) 271 '%s:%s' % (pid_for_lock, str(_GetProcessStartTime(pid_for_lock))))
262 272
263 def _InitDeviceLocked(self, adb, tool): 273 def _InitDeviceLocked(self, device, tool):
264 """Initializes the device_forwarder daemon for a specific device (once). 274 """Initializes the device_forwarder daemon for a specific device (once).
265 275
266 Note that the global lock must be acquired before calling this method. This 276 Note that the global lock must be acquired before calling this method. This
267 method kills any existing device_forwarder daemon on the device that could 277 method kills any existing device_forwarder daemon on the device that could
268 be stale, pushes the latest version of the daemon (to the device) and starts 278 be stale, pushes the latest version of the daemon (to the device) and starts
269 it. 279 it.
270 280
271 Args: 281 Args:
272 adb: An AndroidCommands instance. 282 device: A DeviceUtils instance.
273 tool: Tool class to use to get wrapper, if necessary, for executing the 283 tool: Tool class to use to get wrapper, if necessary, for executing the
274 forwarder (see valgrind_tools.py). 284 forwarder (see valgrind_tools.py).
275 """ 285 """
276 device_serial = adb.Adb().GetSerialNumber() 286 device_serial = device.old_interface.Adb().GetSerialNumber()
277 if device_serial in self._initialized_devices: 287 if device_serial in self._initialized_devices:
278 return 288 return
279 Forwarder._KillDeviceLocked(adb, tool) 289 Forwarder._KillDeviceLocked(device, tool)
280 adb.PushIfNeeded( 290 device.old_interface.PushIfNeeded(
281 self._device_forwarder_path_on_host, 291 self._device_forwarder_path_on_host,
282 Forwarder._DEVICE_FORWARDER_FOLDER) 292 Forwarder._DEVICE_FORWARDER_FOLDER)
283 (exit_code, output) = adb.GetShellCommandStatusAndOutput( 293 (exit_code, output) = device.old_interface.GetShellCommandStatusAndOutput(
284 '%s %s %s' % (Forwarder._LD_LIBRARY_PATH, tool.GetUtilWrapper(), 294 '%s %s %s' % (Forwarder._LD_LIBRARY_PATH, tool.GetUtilWrapper(),
285 Forwarder._DEVICE_FORWARDER_PATH)) 295 Forwarder._DEVICE_FORWARDER_PATH))
286 if exit_code != 0: 296 if exit_code != 0:
287 raise Exception( 297 raise Exception(
288 'Failed to start device forwarder:\n%s' % '\n'.join(output)) 298 'Failed to start device forwarder:\n%s' % '\n'.join(output))
289 self._initialized_devices.add(device_serial) 299 self._initialized_devices.add(device_serial)
290 300
291 def _KillHostLocked(self): 301 def _KillHostLocked(self):
292 """Kills the forwarder process running on the host. 302 """Kills the forwarder process running on the host.
293 303
294 Note that the global lock must be acquired before calling this method. 304 Note that the global lock must be acquired before calling this method.
295 """ 305 """
296 logging.info('Killing host_forwarder.') 306 logging.info('Killing host_forwarder.')
297 (exit_code, output) = cmd_helper.GetCmdStatusAndOutput( 307 (exit_code, output) = cmd_helper.GetCmdStatusAndOutput(
298 [self._host_forwarder_path, '--kill-server']) 308 [self._host_forwarder_path, '--kill-server'])
299 if exit_code != 0: 309 if exit_code != 0:
300 (exit_code, output) = cmd_helper.GetCmdStatusAndOutput( 310 (exit_code, output) = cmd_helper.GetCmdStatusAndOutput(
301 ['pkill', '-9', 'host_forwarder']) 311 ['pkill', '-9', 'host_forwarder'])
302 if exit_code != 0: 312 if exit_code != 0:
303 raise Exception('%s exited with %d:\n%s' % ( 313 raise Exception('%s exited with %d:\n%s' % (
304 self._host_forwarder_path, exit_code, '\n'.join(output))) 314 self._host_forwarder_path, exit_code, '\n'.join(output)))
305 315
306 @staticmethod 316 @staticmethod
307 def _KillDeviceLocked(adb, tool): 317 def _KillDeviceLocked(device, tool):
308 """Kills the forwarder process running on the device. 318 """Kills the forwarder process running on the device.
309 319
310 Note that the global lock must be acquired before calling this method. 320 Note that the global lock must be acquired before calling this method.
311 321
312 Args: 322 Args:
313 adb: Instance of AndroidCommands for talking to the device. 323 device: Instance of DeviceUtils for talking to the device.
314 tool: Wrapper tool (e.g. valgrind) that can be used to execute the device 324 tool: Wrapper tool (e.g. valgrind) that can be used to execute the device
315 forwarder (see valgrind_tools.py). 325 forwarder (see valgrind_tools.py).
316 """ 326 """
317 logging.info('Killing device_forwarder.') 327 logging.info('Killing device_forwarder.')
318 if not adb.FileExistsOnDevice(Forwarder._DEVICE_FORWARDER_PATH): 328 if not device.old_interface.FileExistsOnDevice(
329 Forwarder._DEVICE_FORWARDER_PATH):
319 return 330 return
320 adb.GetShellCommandStatusAndOutput( 331 device.old_interface.GetShellCommandStatusAndOutput(
321 '%s %s --kill-server' % (tool.GetUtilWrapper(), 332 '%s %s --kill-server' % (tool.GetUtilWrapper(),
322 Forwarder._DEVICE_FORWARDER_PATH)) 333 Forwarder._DEVICE_FORWARDER_PATH))
323 # TODO(pliard): Remove the following call to KillAllBlocking() when we are 334 # TODO(pliard): Remove the following call to KillAllBlocking() when we are
324 # sure that the old version of device_forwarder (not supporting 335 # sure that the old version of device_forwarder (not supporting
325 # 'kill-server') is not running on the bots anymore. 336 # 'kill-server') is not running on the bots anymore.
326 timeout_sec = 5 337 timeout_sec = 5
327 processes_killed = adb.KillAllBlocking('device_forwarder', timeout_sec) 338 processes_killed = device.old_interface.KillAllBlocking(
339 'device_forwarder', timeout_sec)
328 if not processes_killed: 340 if not processes_killed:
329 pids = adb.ExtractPid('device_forwarder') 341 pids = device.old_interface.ExtractPid('device_forwarder')
330 if pids: 342 if pids:
331 raise Exception('Timed out while killing device_forwarder') 343 raise Exception('Timed out while killing device_forwarder')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698