Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / backends / android_rndis.py
index 89715a3..7136746 100644 (file)
@@ -9,6 +9,7 @@ import struct
 import subprocess
 import sys
 
+from telemetry.core import util
 from telemetry.core.backends import adb_commands
 
 
@@ -31,13 +32,15 @@ class RndisForwarderWithRoot(object):
   """Forwards traffic using RNDIS. Assuming the device has root access.
   """
   _RNDIS_DEVICE = '/sys/class/android_usb/android0'
+  _NETWORK_INTERFACES = '/etc/network/interfaces'
+  _TELEMETRY_MARKER = '# Added by Telemetry #'
 
   def __init__(self, adb):
     """Args:
          adb: an instance of AdbCommands
     """
     is_root_enabled = adb.Adb().EnableAdbRoot()
-    assert is_root_enabled, 'RNDIS forwarding could not enable root'
+    assert is_root_enabled, 'RNDIS forwarding requires a rooted device'
     self._adb = adb.Adb()
 
     self._host_port = 80
@@ -62,6 +65,11 @@ class RndisForwarderWithRoot(object):
   def OverrideDns(self):
     """Overrides DNS on device to point at the host."""
     self._original_dns = self._GetCurrentDns()
+    if not self._original_dns[0]:
+      # No default route. Install one via the host. This is needed because
+      # getaddrinfo in bionic uses routes to determine AI_ADDRCONFIG.
+      self._adb.RunShellCommand('route add default gw %s dev %s' %
+                                (self._host_ip, self._device_iface))
     self._OverrideDns(self._device_iface, self._host_ip, self._host_ip)
 
   def _IsRndisSupported(self):
@@ -100,8 +108,12 @@ class RndisForwarderWithRoot(object):
       elif ether_address in line:
         return interface_name
 
+  def _WriteProtectedFile(self, path, contents):
+    subprocess.check_call(
+        ['sudo', 'bash', '-c', 'echo -e "%s" > %s' % (contents, path)])
+
   def _DisableRndis(self):
-    self._adb.RunShellCommand('setprop sys.usb.config adb')
+    self._adb.system_properties['sys.usb.config'] = 'adb'
     self._WaitForDevice()
 
   def _EnableRndis(self):
@@ -230,14 +242,27 @@ doit &
         if candidate not in used_addresses:
           return candidate
 
-    addresses, host_address = self._GetHostAddresses(host_iface)
+    interfaces = open(self._NETWORK_INTERFACES, 'r').read()
+    if 'auto ' + host_iface not in interfaces:
+      config = ('%(orig)s\n\n'
+                '%(marker)s\n'
+                'auto %(iface)s\n'
+                'iface %(iface)s inet static\n'
+                '  address 192.168.123.1\n'  # Arbitrary IP.
+                '  netmask 255.255.255.0' % {'orig': interfaces,
+                                             'marker': self._TELEMETRY_MARKER,
+                                             'iface': host_iface})
+      self._WriteProtectedFile(self._NETWORK_INTERFACES, config)
+      subprocess.check_call(['sudo', '/etc/init.d/networking', 'restart'])
+
+    def HasHostAddress():
+      _, host_address = self._GetHostAddresses(host_iface)
+      return bool(host_address)
+    logging.info('Waiting for RNDIS connectivity...')
+    util.WaitFor(HasHostAddress, 10)
 
-    assert host_address, ('Interface %(iface)s was not configured.\n'
-      'To configure it automatically, add to /etc/network/interfaces:\n'
-      'auto %(iface)s\n'
-      'iface %(iface)s inet static\n'
-      '  address 192.168.<unique>.1\n'
-      '  netmask 255.255.255.0' % {'iface': host_iface})
+    addresses, host_address = self._GetHostAddresses(host_iface)
+    assert host_address, 'Interface %s could not be configured.' % host_iface
 
     addresses = [_IpPrefix2AddressMask(addr) for addr in addresses]
     host_ip, netmask = _IpPrefix2AddressMask(host_address)
@@ -301,8 +326,8 @@ doit &
     default_routes = [route[0] for route in routes if route[1] == '00000000']
     return (
       default_routes[0] if default_routes else None,
-      self._adb.RunShellCommand('getprop net.dns1')[0],
-      self._adb.RunShellCommand('getprop net.dns2')[0],
+      self._adb.system_properties['net.dns1'],
+      self._adb.system_properties['net.dns2'],
     )
 
   def _OverrideDns(self, iface, dns1, dns2):
@@ -316,12 +341,11 @@ doit &
       return  # If there is no route, then nobody cares about DNS.
     # DNS proxy in older versions of Android is configured via properties.
     # TODO(szym): run via su -c if necessary.
-    self._adb.RunShellCommand('setprop net.dns1 ' + dns1)
-    self._adb.RunShellCommand('setprop net.dns2 ' + dns2)
-    dnschange = self._adb.RunShellCommand('getprop net.dnschange')[0]
+    self._adb.system_properties['net.dns1'] = dns1
+    self._adb.system_properties['net.dns2'] = dns2
+    dnschange = self._adb.system_properties['net.dnschange']
     if dnschange:
-      self._adb.RunShellCommand('setprop net.dnschange %s' %
-                                (int(dnschange) + 1))
+      self._adb.system_properties['net.dnschange'] = int(dnschange) + 1
     # Since commit 8b47b3601f82f299bb8c135af0639b72b67230e6 to frameworks/base
     # the net.dns1 properties have been replaced with explicit commands for netd
     self._adb.RunShellCommand('ndc netd resolver setifdns %s %s %s' %
@@ -341,3 +365,4 @@ doit &
 
   def Close(self):
     self._OverrideDns(*self._original_dns)
+    self._DisableRndis()