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