• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3# found in the LICENSE file.
4
5from telemetry.internal.util import atexit_with_log
6import logging
7import subprocess
8
9from telemetry.internal import forwarders
10
11try:
12  from devil.android import forwarder
13except ImportError:
14  forwarder = None
15
16
17class AndroidForwarderFactory(forwarders.ForwarderFactory):
18
19  def __init__(self, device):
20    super(AndroidForwarderFactory, self).__init__()
21    self._device = device
22
23  def Create(self, port_pair):
24    try:
25      return AndroidForwarder(self._device, port_pair)
26    except Exception:
27      try:
28        logging.warning('Failed to create forwarder. '
29                        'Currently forwarded connections:')
30        for line in self._device.adb.ForwardList().splitlines():
31          logging.warning('  %s', line)
32      except Exception:
33        logging.warning('Exception raised while listing forwarded connections.')
34
35      logging.warning('Relevant device tcp sockets in use:')
36      try:
37        proc_net_tcp_target = ':%s ' % hex(port_pair.remote_port)[2:]
38        for line in self._device.ReadFile('/proc/net/tcp', as_root=True,
39                                          force_pull=True).splitlines():
40          if proc_net_tcp_target in line:
41            logging.warning('  %s', line)
42      except Exception:
43        logging.warning('Exception raised while listing tcp sockets.')
44
45      logging.warning('Possibly relevant lsof entries:')
46      try:
47        lsof_output = self._device.RunShellCommand(
48            ['lsof'], as_root=True, check_return=True)
49        lsof_target = str(port_pair.remote_port)
50        for line in lsof_output:
51          if lsof_target in line:
52            logging.warning('  %s', line)
53      except Exception:
54        logging.warning('Exception raised running lsof.')
55
56      logging.warning('Alive webpagereplay instances:')
57      try:
58        for line in subprocess.check_output(['ps', '-ef']).splitlines():
59          if 'webpagereplay' in line:
60            logging.warning('  %s', line)
61      except Exception:
62        logging.warning('Exception raised while listing WPR intances.')
63
64      raise
65
66
67class AndroidForwarder(forwarders.Forwarder):
68
69  def __init__(self, device, port_pair):
70    super(AndroidForwarder, self).__init__(port_pair)
71    self._device = device
72    forwarder.Forwarder.Map(
73        [(port_pair.remote_port, port_pair.local_port)], self._device)
74    self._port_pair = (
75        forwarders.PortPair(
76            port_pair.local_port,
77            forwarder.Forwarder.DevicePortForHostPort(port_pair.local_port)))
78    atexit_with_log.Register(self.Close)
79    # TODO(tonyg): Verify that each port can connect to host.
80
81  def Close(self):
82    if self._forwarding:
83      forwarder.Forwarder.UnmapDevicePort(
84          self._port_pair.remote_port, self._device)
85    super(AndroidForwarder, self).Close()
86