Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.tradefed.utils.wifi;
     18 import android.app.Activity;
     19 import android.app.Instrumentation;
     20 import android.content.Context;
     21 import android.net.wifi.WifiInfo;
     22 import android.net.wifi.WifiManager;
     23 import android.os.Bundle;
     24 import android.text.TextUtils;
     25 import android.util.Log;
     26 
     27 import com.android.tradefed.utils.wifi.WifiConnector.WifiException;
     28 
     29 /**
     30  * An instrumentation class to manipulate Wi-Fi services on device.
     31  * <p/>
     32  * adb shell am instrument -e method (method name) -e arg1 val1 -e arg2 val2 -e arg3 val3
     33  * -w com.android.tradefed.utils.wifi/.WifiUtils
     34  */
     35 public class WifiUtil extends Instrumentation {
     36     // FIXME: document exposed API methods and arguments
     37     private static final String TAG = "WifiUtil";
     38 
     39     private static final String DEFAULT_URL_TO_CHECK = "http://www.google.com";
     40 
     41     private Bundle mArguments;
     42 
     43     static class MissingArgException extends Exception {
     44         public MissingArgException(String msg) {
     45             super(msg);
     46         }
     47 
     48         public static MissingArgException fromArg(String arg) {
     49             return new MissingArgException(
     50                     String.format("Error: missing mandatory argument '%s'", arg));
     51         }
     52     }
     53 
     54     @Override
     55     public void onCreate(Bundle arguments) {
     56         super.onCreate(arguments);
     57         mArguments = arguments;
     58         start();
     59     }
     60 
     61     /**
     62      * Fails an instrumentation request.
     63      *
     64      * @param errMsg an error message
     65      */
     66     private void fail(String errMsg) {
     67         Log.e(TAG, errMsg);
     68         Bundle result = new Bundle();
     69         result.putString("error", errMsg);
     70         finish(Activity.RESULT_CANCELED, result);
     71     }
     72 
     73     /**
     74      * Returns the string value of an argument for the specified name, or throws
     75      * {@link MissingArgException} if the argument is not found or empty.
     76      *
     77      * @param arg the name of an argument
     78      * @return the value of an argument
     79      * @throws MissingArgException if the argument is not found
     80      */
     81     private String expectString(String arg) throws MissingArgException {
     82         String val = mArguments.getString(arg);
     83         if (TextUtils.isEmpty(val)) {
     84             throw MissingArgException.fromArg(arg);
     85         }
     86 
     87         return val;
     88     }
     89 
     90     /**
     91      * Returns the value of a string argument for the specified name, or defaultValue if the
     92      * argument is not found or empty.
     93      *
     94      * @param arg the name of an argument
     95      * @param defaultValue a value to return if the argument is not found
     96      * @return the value of an argument
     97      */
     98     private String getString(String arg, String defaultValue) {
     99         String val = mArguments.getString(arg);
    100         if (TextUtils.isEmpty(val)) {
    101             return defaultValue;
    102         }
    103 
    104         return val;
    105     }
    106 
    107     /**
    108      * Returns the integer value of an argument for the specified name, or throws
    109      * {@link MissingArgException} if the argument is not found or cannot be parsed to an integer.
    110      *
    111      * @param arg the name of an argument
    112      * @return the value of an argument
    113      * @throws MissingArgException if the argument is not found
    114      */
    115     private int expectInteger(String arg) throws MissingArgException {
    116         String val = expectString(arg);
    117         int intVal;
    118         try {
    119             intVal = Integer.parseInt(val);
    120         } catch (NumberFormatException e) {
    121             final String msg = String.format("Couldn't parse arg '%s': %s", arg,
    122                     e.getMessage());
    123             throw new MissingArgException(msg);
    124         }
    125 
    126         return intVal;
    127     }
    128 
    129     /**
    130      * Returns the integer value of an argument for the specified name, or defaultValue if the
    131      * argument is not found, empty, or cannot be parsed.
    132      *
    133      * @param arg the name of an argument
    134      * @param defaultValue a value to return if the argument is not found
    135      * @return the value of an argument
    136      */
    137     private int getInteger(String arg, int defaultValue) {
    138         try {
    139             return expectInteger(arg);
    140         } catch (MissingArgException e) {
    141             return defaultValue;
    142         }
    143     }
    144 
    145     private boolean getBoolean(String arg, boolean defaultValue) {
    146         try {
    147             return Boolean.parseBoolean(expectString(arg));
    148         } catch (MissingArgException e) {
    149             return defaultValue;
    150         }
    151     }
    152 
    153     @Override
    154     public void onStart() {
    155         super.onStart();
    156         final Bundle result = new Bundle();
    157 
    158         try {
    159             final String method = expectString("method");
    160 
    161             WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
    162             if (wifiManager == null) {
    163                 fail("Couldn't get WifiManager reference; goodbye!");
    164                 return;
    165             }
    166             WifiConnector connector = new WifiConnector(getContext());
    167 
    168             // As a pattern, method implementations below should gather arguments _first_, and then
    169             // use those arguments so that the system is not left in an inconsistent state if an
    170             // argument is missing in the middle of an implementation.
    171             if ("enableWifi".equals(method)) {
    172                 result.putBoolean("result", wifiManager.setWifiEnabled(true));
    173             } else if ("disableWifi".equals(method)) {
    174                 result.putBoolean("result", wifiManager.setWifiEnabled(false));
    175             } else if ("addOpenNetwork".equals(method)) {
    176                 final String ssid = expectString("ssid");
    177                 final boolean scanSsid = getBoolean("scan_ssid", false);
    178 
    179                 result.putInt("result", connector.addNetwork(ssid, null, scanSsid));
    180 
    181             } else if ("addWpaPskNetwork".equals(method)) {
    182                 final String ssid = expectString("ssid");
    183                 final boolean scanSsid = getBoolean("scan_ssid", false);
    184                 final String psk = expectString("psk");
    185 
    186                 result.putInt("result", connector.addNetwork(ssid, psk, scanSsid));
    187 
    188             } else if ("associateNetwork".equals(method)) {
    189                 final int id = expectInteger("id");
    190 
    191                 result.putBoolean("result",
    192                         wifiManager.enableNetwork(id, true /* disable other networks */));
    193 
    194             } else if ("disconnect".equals(method)) {
    195                 result.putBoolean("result", wifiManager.disconnect());
    196 
    197             } else if ("disableNetwork".equals(method)) {
    198                 final int id = expectInteger("id");
    199 
    200                 result.putBoolean("result", wifiManager.disableNetwork(id));
    201 
    202             } else if ("isWifiEnabled".equals(method)) {
    203                 result.putBoolean("result", wifiManager.isWifiEnabled());
    204 
    205             } else if ("getIpAddress".equals(method)) {
    206                 final WifiInfo info = wifiManager.getConnectionInfo();
    207                 final int addr = info.getIpAddress();
    208 
    209                 // IP address is stored with the first octet in the lowest byte
    210                 final int a = (addr >> 0) & 0xff;
    211                 final int b = (addr >> 8) & 0xff;
    212                 final int c = (addr >> 16) & 0xff;
    213                 final int d = (addr >> 24) & 0xff;
    214 
    215                 result.putString("result", String.format("%s.%s.%s.%s", a, b, c, d));
    216 
    217             } else if ("getSSID".equals(method)) {
    218                 final WifiInfo info = wifiManager.getConnectionInfo();
    219 
    220                 result.putString("result", info.getSSID());
    221 
    222             } else if ("getBSSID".equals(method)) {
    223                 final WifiInfo info = wifiManager.getConnectionInfo();
    224 
    225                 result.putString("result", info.getBSSID());
    226 
    227             } else if ("removeAllNetworks".equals(method)) {
    228                 connector.removeAllNetworks(true);
    229 
    230                 result.putBoolean("result", true);
    231 
    232             } else if ("removeNetwork".equals(method)) {
    233                 final int id = expectInteger("id");
    234 
    235                 result.putBoolean("result", wifiManager.removeNetwork(id));
    236 
    237             } else if ("saveConfiguration".equals(method)) {
    238                 result.putBoolean("result", wifiManager.saveConfiguration());
    239 
    240             } else if ("getSupplicantState".equals(method)) {
    241                 String state = wifiManager.getConnectionInfo().getSupplicantState().name();
    242                 result.putString("result", state);
    243 
    244             } else if ("checkConnectivity".equals(method)) {
    245                 final String url = getString("urlToCheck", DEFAULT_URL_TO_CHECK);
    246 
    247                 result.putBoolean("result", connector.checkConnectivity(url));
    248 
    249             } else if ("connectToNetwork".equals(method)) {
    250                 final String ssid = expectString("ssid");
    251                 final boolean scanSsid = getBoolean("scan_ssid", false);
    252                 final String psk = getString("psk", null);
    253                 final String pingUrl = getString("urlToCheck", DEFAULT_URL_TO_CHECK);
    254                 final long connectTimeout = getInteger("connectTimeout", -1);
    255                 connector.connectToNetwork(ssid, psk, pingUrl, connectTimeout, scanSsid);
    256 
    257                 result.putBoolean("result", true);
    258 
    259             } else if ("disconnectFromNetwork".equals(method)) {
    260                 connector.disconnectFromNetwork();
    261 
    262                 result.putBoolean("result", true);
    263 
    264             } else if ("getWifiInfo".equals(method)) {
    265                 result.putString("result", connector.getWifiInfo().toString());
    266 
    267             } else if ("startMonitor".equals(method)) {
    268                 final int interval = expectInteger("interval");
    269                 final String urlToCheck = getString("urlToCheck", DEFAULT_URL_TO_CHECK);
    270 
    271                 WifiMonitorService.enable(getContext(), interval, urlToCheck);
    272 
    273                 result.putBoolean("result", true);
    274 
    275             } else if ("stopMonitor".equals(method)) {
    276                 final Context context = getContext();
    277                 WifiMonitorService.disable(context);
    278 
    279                 result.putString("result", WifiMonitorService.getData(context));
    280 
    281             } else {
    282                 fail(String.format("Didn't recognize method '%s'", method));
    283                 return;
    284             }
    285         } catch (WifiException | MissingArgException e) {
    286             fail(e.getMessage());
    287             return;
    288         }
    289 
    290         finish(Activity.RESULT_OK, result);
    291     }
    292 }
    293