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 5import atexit 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_pairs): 24 try: 25 return AndroidForwarder(self._device, port_pairs) 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('Device tcp sockets in use:') 36 try: 37 for line in self._device.ReadFile('/proc/net/tcp', as_root=True, 38 force_pull=True).splitlines(): 39 logging.warning(' %s', line) 40 except Exception: 41 logging.warning('Exception raised while listing tcp sockets.') 42 43 logging.warning('Alive webpagereplay instances:') 44 try: 45 for line in subprocess.check_output(['ps', '-ef']).splitlines(): 46 if 'webpagereplay' in line: 47 logging.warning(' %s', line) 48 except Exception: 49 logging.warning('Exception raised while listing WPR intances.') 50 51 raise 52 53 54class AndroidForwarder(forwarders.Forwarder): 55 56 def __init__(self, device, port_pairs): 57 super(AndroidForwarder, self).__init__(port_pairs) 58 self._device = device 59 forwarder.Forwarder.Map([(p.remote_port, p.local_port) 60 for p in port_pairs if p], self._device) 61 self._port_pairs = forwarders.PortPairs(*[ 62 forwarders.PortPair( 63 p.local_port, 64 forwarder.Forwarder.DevicePortForHostPort(p.local_port)) 65 if p else None for p in port_pairs]) 66 atexit.register(self.Close) 67 # TODO(tonyg): Verify that each port can connect to host. 68 69 def Close(self): 70 if self._forwarding: 71 for port_pair in self._port_pairs: 72 if port_pair: 73 forwarder.Forwarder.UnmapDevicePort( 74 port_pair.remote_port, self._device) 75 super(AndroidForwarder, self).Close() 76