Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright (c) 2013 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 | |
| 5 """Manages WiFi connection""" | |
| 6 | |
| 7 import logging | |
| 8 import os | |
| 9 import sys | |
| 10 import time | |
| 11 | |
| 12 sys.path.append(os.path.join(sys.path[0], '..', '..', 'build','android')) | |
| 13 from pylib import constants | |
| 14 from pylib.device import device_utils | |
| 15 from pylib.device import device_errors | |
| 16 from pylib.utils import logging_utils | |
| 17 from pylib.utils import timeout_retry | |
| 18 | |
| 19 _ACTIVITY_RESULT_OK = -1 | |
| 20 _STR_TO_BOOL = {'true': True, 'false': False} | |
| 21 | |
| 22 | |
| 23 class WiFiManager(object): | |
| 24 """A wrapper around WifiUtil.apk to manage wifi settings. | |
| 25 | |
| 26 WifiUtil is available at build/android/apks/WifiUtil.apk, for more | |
|
navabi
2015/06/18 01:04:57
changed this.
| |
| 27 information, see the README in build/android/apks/ | |
| 28 """ | |
| 29 | |
| 30 def __init__(self, device): | |
| 31 """ | |
| 32 Args: | |
| 33 device: A DeviceUtils object to work with. | |
| 34 """ | |
| 35 self._device = device | |
| 36 self._apk_installed = False | |
| 37 | |
| 38 def IsWifiEnabled(self): | |
| 39 """Checks whether or not wifi is enabled on the device.""" | |
| 40 return self._WifiUtilMethod('isWifiEnabled') | |
| 41 | |
| 42 def IsInternetReachable(self, destination='www.google.com', count=2, | |
| 43 timeout=5): | |
| 44 """Checks whether or not internet is reachable from the device. | |
| 45 | |
| 46 Args: | |
| 47 destination: A string with a destination to check for connectivity. | |
| 48 count: Number of ping packets to send. | |
| 49 timeout: Number of seconds to wait for packets to return. | |
| 50 | |
| 51 Return: | |
| 52 True if pings to the destination succeeded, False otherwise. | |
| 53 """ | |
| 54 try: | |
| 55 self._device.RunShellCommand( | |
| 56 ['ping', '-w', str(timeout), '-c', str(count), destination], | |
| 57 check_return=True) | |
| 58 return True | |
| 59 except device_errors.AdbShellCommandFailedError: | |
| 60 return False | |
| 61 | |
| 62 def EnableWifi(self): | |
| 63 """Enables wifi on the device.""" | |
| 64 if not self._WifiUtilMethod('enableWifi'): | |
| 65 raise device_errors.CommandFailedError( | |
| 66 'Failed to enable wifi on the device') | |
| 67 | |
| 68 def DisableWifi(self): | |
| 69 """Disables wifi on the device.""" | |
| 70 if not self._WifiUtilMethod('disableWifi'): | |
| 71 raise device_errors.CommandFailedError( | |
| 72 'Failed to disable wifi on the device') | |
| 73 | |
| 74 def AddOpenNetwork(self, ssid): | |
| 75 """Adds an open wifi network configuarion. | |
| 76 | |
| 77 Args: | |
| 78 ssid: A string with the SSID of a wifi network. | |
| 79 | |
| 80 Return: | |
| 81 The network ID of the new network configuarion as an integer. | |
| 82 """ | |
| 83 return self._WifiUtilMethod('addOpenNetwork', {'ssid': ssid}, type_fn=int) | |
| 84 | |
| 85 def AddSecureNetwork(self, ssid, password_file): | |
| 86 """Adds an wpa/psk wifi network configuarion. | |
| 87 | |
| 88 Args: | |
| 89 ssid: A string with the SSID of a wifi network. | |
| 90 password_file: A file containing the password for the wifi | |
| 91 | |
| 92 Return: | |
| 93 The network ID of the new network configuarion as an integer. | |
| 94 """ | |
| 95 with open(password_file) as f: | |
| 96 password = f.read().rstrip() | |
| 97 with logging_utils.SuppressLogging(): | |
| 98 result = self._WifiUtilMethod('addWpaPskNetwork', | |
| 99 {'ssid': ssid, 'psk': password}, type_fn=int) | |
| 100 return result | |
| 101 | |
| 102 def AssociateNetwork(self, net_id): | |
| 103 """Associates (connects) to a previously configured network. | |
| 104 | |
| 105 Args: | |
| 106 net_id: An integer with the network ID to associate with. | |
| 107 """ | |
| 108 if not self._WifiUtilMethod('associateNetwork', {'id': net_id}): | |
| 109 raise device_errors.CommandFailedError( | |
| 110 'Failed to connect to network id %d.' % net_id) | |
| 111 | |
| 112 def SaveConfiguration(self): | |
| 113 """Persists the current configured networks. | |
| 114 | |
| 115 Note: It is possible for this method to change the network IDs of existing | |
| 116 networks. | |
| 117 """ | |
| 118 if not self._WifiUtilMethod('saveConfiguration'): | |
| 119 raise device_errors.CommandFailedError( | |
| 120 'Failed to save the current network configuration.') | |
| 121 | |
| 122 def ConnectToGoogleGuest(self): | |
| 123 self.ConnectToWifi('GoogleGuest') | |
| 124 | |
| 125 def ConnectToWifi(self, ssid, password_file=None): | |
| 126 """Enables wifi on the device and connects to specified ssid.""" | |
| 127 def wifi_enabled(): | |
| 128 return self.IsWifiEnabled() | |
| 129 | |
| 130 def internet_reachable(): | |
| 131 return self.IsInternetReachable() | |
| 132 | |
| 133 logging.info('Enabling wifi') | |
| 134 self.EnableWifi() | |
| 135 if not timeout_retry.WaitFor(wifi_enabled, max_tries=6): | |
| 136 raise device_errors.CommandFailedError( | |
| 137 'Timed out waiting for wifi to be enabled') | |
| 138 | |
| 139 logging.info('Adding %s', ssid) | |
| 140 if password_file: | |
| 141 net_id = self.AddSecureNetwork(ssid, password_file) | |
| 142 else: | |
| 143 net_id = self.AddOpenNetwork(ssid) | |
| 144 logging.info('Connecting to %s', ssid) | |
| 145 self.AssociateNetwork(net_id) | |
| 146 logging.info('Saving wifi configuration') | |
| 147 self.SaveConfiguration() | |
| 148 | |
| 149 if not timeout_retry.WaitFor(internet_reachable, max_tries=6): | |
| 150 raise device_errors.CommandFailedError( | |
| 151 'Timed out waiting for Internet connectivity: www.google.com is not' | |
| 152 ' responding.') | |
| 153 | |
| 154 def _WifiUtilMethod(self, method, args=None, type_fn=None): | |
|
navabi
2015/06/18 01:04:57
and I changed the name of the type_fn argument. It
perezju
2015/06/18 09:53:33
nit: maybe call it "return_as"? looks a bit nicer
| |
| 155 """Run a WifiUtil.apk instrumentation and return its result. | |
| 156 | |
| 157 Maps each invocation to an instrumentation command of the form: | |
| 158 | |
| 159 am instrument -e method <METHOD> -e <KEY1> <VAL1> ... \ | |
| 160 -w com.android.tradefed.utils.wifi/.WifiUtil | |
| 161 | |
| 162 Args: | |
| 163 method: A string with the name of the WifiUtil.apk method to invoke. | |
| 164 args: A dictionary with extra arguments for the method, values will be | |
| 165 implicitly casted to strings. | |
| 166 type_fn: A function called to interpret the result of the method. The | |
| 167 default expects and returns a boolean value. | |
| 168 | |
| 169 Return: | |
| 170 The result obtained from INSTRUMENTATION_RESULT: result=[value], as | |
| 171 interpreted by the type_fn function. | |
| 172 | |
| 173 Raises: | |
| 174 AssertionError if the instrumentation call is not successful, or the | |
| 175 instrumentation result is missing. | |
| 176 """ | |
| 177 if not self._apk_installed: | |
| 178 self._InstallWifiUtilApk() | |
| 179 | |
| 180 extras = {'method': method} | |
| 181 if args is not None: | |
| 182 extras.update((k, str(v)) for k, v in args.iteritems()) | |
| 183 if type_fn is None: | |
| 184 type_fn = lambda r: _STR_TO_BOOL[r] | |
| 185 | |
| 186 output = self._device.StartInstrumentation( | |
| 187 'com.android.tradefed.utils.wifi/.WifiUtil', | |
| 188 extras=extras) | |
| 189 results = {} | |
| 190 code = None | |
| 191 for line in output: | |
| 192 section, content = line.split(': ', 1) | |
| 193 if section == 'INSTRUMENTATION_RESULT': | |
| 194 key, value = content.split('=', 1) | |
| 195 results[key] = value | |
| 196 elif section == 'INSTRUMENTATION_CODE': | |
| 197 code = int(content) | |
| 198 if code != _ACTIVITY_RESULT_OK or 'result' not in results: | |
| 199 raise device_errors.CommandFailedError('WifiUtil method %s failed (%s): ' | |
| 200 '%s' % (method, code, results)) | |
| 201 | |
| 202 return type_fn(results['result']) | |
| 203 | |
| 204 def _InstallWifiUtilApk(self): | |
| 205 """Install or update the WifiUtil.apk on the device.""" | |
| 206 logging.info('Installing WifiUtil APK') | |
| 207 wifi_util_apk_file_path = os.path.join( | |
| 208 constants.DIR_SOURCE_ROOT, 'build', 'android', 'apks', 'WifiUtil.apk') | |
| 209 self._device.Install(wifi_util_apk_file_path) | |
| 210 self._apk_installed = True | |
| OLD | NEW |