alps/frameworks/base/wifi/java/android/net/wifi/WifiManager.java , WifiConfiguration.java [v4.2.2]

来源:互联网 发布:全民公敌里卫星 知乎 编辑:程序博客网 时间:2024/06/10 06:15
alps/frameworks/base/wifi/java/android/net/wifi/WifiManager.java
/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.net.wifi;import android.annotation.SdkConstant;import android.annotation.SdkConstant.SdkConstantType;import android.content.Context;import android.net.DhcpInfo;import android.os.Binder;import android.os.IBinder;import android.os.Handler;import android.os.HandlerThread;import android.os.Looper;import android.os.Message;import android.os.RemoteException;import android.os.WorkSource;import android.os.Messenger;import android.util.Log;import android.util.SparseArray;import java.util.concurrent.CountDownLatch;import com.android.internal.util.AsyncChannel;import com.android.internal.util.Protocol;import java.util.List;/** * This class provides the primary API for managing all aspects of Wi-Fi * connectivity. Get an instance of this class by calling * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.WIFI_SERVICE)}. * It deals with several categories of items: * <ul> * <li>The list of configured networks. The list can be viewed and updated, * and attributes of individual entries can be modified.</li> * <li>The currently active Wi-Fi network, if any. Connectivity can be * established or torn down, and dynamic information about the state of * the network can be queried.</li> * <li>Results of access point scans, containing enough information to * make decisions about what access point to connect to.</li> * <li>It defines the names of various Intent actions that are broadcast * upon any sort of change in Wi-Fi state. * </ul> * This is the API to use when performing Wi-Fi specific operations. To * perform operations that pertain to network connectivity at an abstract * level, use {@link android.net.ConnectivityManager}. */public class WifiManager {    private static final String TAG = "WifiManager";    // Supplicant error codes:    /**     * The error code if there was a problem authenticating.     */    public static final int ERROR_AUTHENTICATING = 1;    /**     * Broadcast intent action indicating that Wi-Fi has been enabled, disabled,     * enabling, disabling, or unknown. One extra provides this state as an int.     * Another extra provides the previous state, if available.     *     * @see #EXTRA_WIFI_STATE     * @see #EXTRA_PREVIOUS_WIFI_STATE     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String WIFI_STATE_CHANGED_ACTION =        "android.net.wifi.WIFI_STATE_CHANGED";    /**     * The lookup key for an int that indicates whether Wi-Fi is enabled,     * disabled, enabling, disabling, or unknown.  Retrieve it with     * {@link android.content.Intent#getIntExtra(String,int)}.     *     * @see #WIFI_STATE_DISABLED     * @see #WIFI_STATE_DISABLING     * @see #WIFI_STATE_ENABLED     * @see #WIFI_STATE_ENABLING     * @see #WIFI_STATE_UNKNOWN     */    public static final String EXTRA_WIFI_STATE = "wifi_state";    /**     * The previous Wi-Fi state.     *     * @see #EXTRA_WIFI_STATE     */    public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";    /**     * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if     * it finishes successfully.     *     * @see #WIFI_STATE_CHANGED_ACTION     * @see #getWifiState()     */    public static final int WIFI_STATE_DISABLING = 0;    /**     * Wi-Fi is disabled.     *     * @see #WIFI_STATE_CHANGED_ACTION     * @see #getWifiState()     */    public static final int WIFI_STATE_DISABLED = 1;    /**     * Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if     * it finishes successfully.     *     * @see #WIFI_STATE_CHANGED_ACTION     * @see #getWifiState()     */    public static final int WIFI_STATE_ENABLING = 2;    /**     * Wi-Fi is enabled.     *     * @see #WIFI_STATE_CHANGED_ACTION     * @see #getWifiState()     */    public static final int WIFI_STATE_ENABLED = 3;    /**     * Wi-Fi is in an unknown state. This state will occur when an error happens while enabling     * or disabling.     *     * @see #WIFI_STATE_CHANGED_ACTION     * @see #getWifiState()     */    public static final int WIFI_STATE_UNKNOWN = 4;    /**     * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled,     * enabling, disabling, or failed.     *     * @hide     */    public static final String WIFI_AP_STATE_CHANGED_ACTION =        "android.net.wifi.WIFI_AP_STATE_CHANGED";    /**     * The lookup key for an int that indicates whether Wi-Fi AP is enabled,     * disabled, enabling, disabling, or failed.  Retrieve it with     * {@link android.content.Intent#getIntExtra(String,int)}.     *     * @see #WIFI_AP_STATE_DISABLED     * @see #WIFI_AP_STATE_DISABLING     * @see #WIFI_AP_STATE_ENABLED     * @see #WIFI_AP_STATE_ENABLING     * @see #WIFI_AP_STATE_FAILED     *     * @hide     */    public static final String EXTRA_WIFI_AP_STATE = "wifi_state";    /**     * The previous Wi-Fi state.     *     * @see #EXTRA_WIFI_AP_STATE     *     * @hide     */    public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";    /**     * Wi-Fi AP is currently being disabled. The state will change to     * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully.     *     * @see #WIFI_AP_STATE_CHANGED_ACTION     * @see #getWifiApState()     *     * @hide     */    public static final int WIFI_AP_STATE_DISABLING = 10;    /**     * Wi-Fi AP is disabled.     *     * @see #WIFI_AP_STATE_CHANGED_ACTION     * @see #getWifiState()     *     * @hide     */    public static final int WIFI_AP_STATE_DISABLED = 11;    /**     * Wi-Fi AP is currently being enabled. The state will change to     * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully.     *     * @see #WIFI_AP_STATE_CHANGED_ACTION     * @see #getWifiApState()     *     * @hide     */    public static final int WIFI_AP_STATE_ENABLING = 12;    /**     * Wi-Fi AP is enabled.     *     * @see #WIFI_AP_STATE_CHANGED_ACTION     * @see #getWifiApState()     *     * @hide     */    public static final int WIFI_AP_STATE_ENABLED = 13;    /**     * Wi-Fi AP is in a failed state. This state will occur when an error occurs during     * enabling or disabling     *     * @see #WIFI_AP_STATE_CHANGED_ACTION     * @see #getWifiApState()     *     * @hide     */    public static final int WIFI_AP_STATE_FAILED = 14;    /**     * Broadcast intent action indicating that a connection to the supplicant has     * been established (and it is now possible     * to perform Wi-Fi operations) or the connection to the supplicant has been     * lost. One extra provides the connection state as a boolean, where {@code true}     * means CONNECTED.     * @see #EXTRA_SUPPLICANT_CONNECTED     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION =        "android.net.wifi.supplicant.CONNECTION_CHANGE";    /**     * The lookup key for a boolean that indicates whether a connection to     * the supplicant daemon has been gained or lost. {@code true} means     * a connection now exists.     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.     */    public static final String EXTRA_SUPPLICANT_CONNECTED = "connected";    /**     * Broadcast intent action indicating that the state of Wi-Fi connectivity     * has changed. One extra provides the new state     * in the form of a {@link android.net.NetworkInfo} object. If the new     * state is CONNECTED, additional extras may provide the BSSID and WifiInfo of     * the access point.     * as a {@code String}.     * @see #EXTRA_NETWORK_INFO     * @see #EXTRA_BSSID     * @see #EXTRA_WIFI_INFO     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";    /**     * The lookup key for a {@link android.net.NetworkInfo} object associated with the     * Wi-Fi network. Retrieve with     * {@link android.content.Intent#getParcelableExtra(String)}.     */    public static final String EXTRA_NETWORK_INFO = "networkInfo";    /**     * The lookup key for a String giving the BSSID of the access point to which     * we are connected. Only present when the new state is CONNECTED.     * Retrieve with     * {@link android.content.Intent#getStringExtra(String)}.     */    public static final String EXTRA_BSSID = "bssid";    /**     * The lookup key for a {@link android.net.wifi.WifiInfo} object giving the     * information about the access point to which we are connected. Only present     * when the new state is CONNECTED.  Retrieve with     * {@link android.content.Intent#getParcelableExtra(String)}.     */    public static final String EXTRA_WIFI_INFO = "wifiInfo";    /**     * Broadcast intent action indicating that the state of establishing a connection to     * an access point has changed.One extra provides the new     * {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and     * is not generally the most useful thing to look at if you are just interested in     * the overall state of connectivity.     * @see #EXTRA_NEW_STATE     * @see #EXTRA_SUPPLICANT_ERROR     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String SUPPLICANT_STATE_CHANGED_ACTION =        "android.net.wifi.supplicant.STATE_CHANGE";    /**     * The lookup key for a {@link SupplicantState} describing the new state     * Retrieve with     * {@link android.content.Intent#getParcelableExtra(String)}.     */    public static final String EXTRA_NEW_STATE = "newState";    /**     * The lookup key for a {@link SupplicantState} describing the supplicant     * error code if any     * Retrieve with     * {@link android.content.Intent#getIntExtra(String, int)}.     * @see #ERROR_AUTHENTICATING     */    public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";    /**     * Broadcast intent action indicating that the configured networks changed.     * This can be as a result of adding/updating/deleting a network. If     * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set to true the new configuration     * can be retreived with the {@link #EXTRA_WIFI_CONFIGURATION} extra. If multiple     * Wi-Fi configurations changed, {@link #EXTRA_WIFI_CONFIGURATION} will not be present.     * @hide     */    public static final String CONFIGURED_NETWORKS_CHANGED_ACTION =        "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";    /**     * The lookup key for a (@link android.net.wifi.WifiConfiguration} object representing     * the changed Wi-Fi configuration when the {@link #CONFIGURED_NETWORKS_CHANGED_ACTION}     * broadcast is sent.     * @hide     */    public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";    /**     * Multiple network configurations have changed.     * @see #CONFIGURED_NETWORKS_CHANGED_ACTION     *     * @hide     */    public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";    /**     * The lookup key for an integer indicating the reason a Wi-Fi network configuration     * has changed. Only present if {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is {@code false}     * @see #CONFIGURED_NETWORKS_CHANGED_ACTION     * @hide     */    public static final String EXTRA_CHANGE_REASON = "changeReason";    /**     * The configuration is new and was added.     * @hide     */    public static final int CHANGE_REASON_ADDED = 0;    /**     * The configuration was removed and is no longer present in the system's list of     * configured networks.     * @hide     */    public static final int CHANGE_REASON_REMOVED = 1;    /**     * The configuration has changed as a result of explicit action or because the system     * took an automated action such as disabling a malfunctioning configuration.     * @hide     */    public static final int CHANGE_REASON_CONFIG_CHANGE = 2;    /**     * An access point scan has completed, and results are available from the supplicant.     * Call {@link #getScanResults()} to obtain the results.     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";    /**     * The RSSI (signal strength) has changed.     * @see #EXTRA_NEW_RSSI     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";    /**     * The lookup key for an {@code int} giving the new RSSI in dBm.     */    public static final String EXTRA_NEW_RSSI = "newRssi";    /**     * Broadcast intent action indicating that the link configuration     * changed on wifi.     * @hide     */    public static final String LINK_CONFIGURATION_CHANGED_ACTION =        "android.net.wifi.LINK_CONFIGURATION_CHANGED";    /**     * The lookup key for a {@link android.net.LinkProperties} object associated with the     * Wi-Fi network. Retrieve with     * {@link android.content.Intent#getParcelableExtra(String)}.     * @hide     */    public static final String EXTRA_LINK_PROPERTIES = "linkProperties";    /**     * The lookup key for a {@link android.net.LinkCapabilities} object associated with the     * Wi-Fi network. Retrieve with     * {@link android.content.Intent#getParcelableExtra(String)}.     * @hide     */    public static final String EXTRA_LINK_CAPABILITIES = "linkCapabilities";    /**     * The network IDs of the configured networks could have changed.     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";    /**     * Activity Action: Pick a Wi-Fi network to connect to.     * <p>Input: Nothing.     * <p>Output: Nothing.     */    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)    public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";    /**     * In this Wi-Fi lock mode, Wi-Fi will be kept active,     * and will behave normally, i.e., it will attempt to automatically     * establish a connection to a remembered access point that is     * within range, and will do periodic scans if there are remembered     * access points but none are in range.     */    public static final int WIFI_MODE_FULL = 1;    /**     * In this Wi-Fi lock mode, Wi-Fi will be kept active,     * but the only operation that will be supported is initiation of     * scans, and the subsequent reporting of scan results. No attempts     * will be made to automatically connect to remembered access points,     * nor will periodic scans be automatically performed looking for     * remembered access points. Scans must be explicitly requested by     * an application in this mode.     */    public static final int WIFI_MODE_SCAN_ONLY = 2;    /**     * In this Wi-Fi lock mode, Wi-Fi will be kept active as in mode     * {@link #WIFI_MODE_FULL} but it operates at high performance     * with minimum packet loss and low packet latency even when     * the device screen is off. This mode will consume more power     * and hence should be used only when there is a need for such     * an active connection.     * <p>     * An example use case is when a voice connection needs to be     * kept active even after the device screen goes off. Holding the     * regular {@link #WIFI_MODE_FULL} lock will keep the wifi     * connection active, but the connection can be lossy.     * Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the     * duration of the voice call will improve the call quality.     * <p>     * When there is no support from the hardware, this lock mode     * will have the same behavior as {@link #WIFI_MODE_FULL}     */    public static final int WIFI_MODE_FULL_HIGH_PERF = 3;    /** Anything worse than or equal to this will show 0 bars. */    private static final int MIN_RSSI = -100;    /** Anything better than or equal to this will show the max bars. */    private static final int MAX_RSSI = -55;    /**     * Number of RSSI levels used in the framework to initiate     * {@link #RSSI_CHANGED_ACTION} broadcast     * @hide     */    public static final int RSSI_LEVELS = 5;    /**     * Auto settings in the driver. The driver could choose to operate on both     * 2.4 GHz and 5 GHz or make a dynamic decision on selecting the band.     * @hide     */    public static final int WIFI_FREQUENCY_BAND_AUTO = 0;    /**     * Operation on 5 GHz alone     * @hide     */    public static final int WIFI_FREQUENCY_BAND_5GHZ = 1;    /**     * Operation on 2.4 GHz alone     * @hide     */    public static final int WIFI_FREQUENCY_BAND_2GHZ = 2;    /** List of asyncronous notifications     * @hide     */    public static final int DATA_ACTIVITY_NOTIFICATION = 1;    //Lowest bit indicates data reception and the second lowest    //bit indicates data transmitted    /** @hide */    public static final int DATA_ACTIVITY_NONE         = 0x00;    /** @hide */    public static final int DATA_ACTIVITY_IN           = 0x01;    /** @hide */    public static final int DATA_ACTIVITY_OUT          = 0x02;    /** @hide */    public static final int DATA_ACTIVITY_INOUT        = 0x03;    /* Maximum number of active locks we allow.     * This limit was added to prevent apps from creating a ridiculous number     * of locks and crashing the system by overflowing the global ref table.     */    private static final int MAX_ACTIVE_LOCKS = 50;    /* Number of currently active WifiLocks and MulticastLocks */    private int mActiveLockCount;    // M: Added constant    /**     * Broadcast intent action indicating that no WAPI certification error.     * @hide     * @internal     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String NO_CERTIFICATION_ACTION = "android.net.wifi.NO_CERTIFICATION";    /**     * Broadcast intent action notifies WifiService to clear the notification show flag     * @hide     * @internal     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String WIFI_CLEAR_NOTIFICATION_SHOW_FLAG_ACTION =         "android.net.wifi.WIFI_CLEAR_NOTIFICATION_SHOW_FLAG_ACTION";    /**     * The lookup key for a boolean that indicates whether the pick network activity     * is triggered by the notification.     * Retrieve with {@link android.content.Intent#getBooleanExtra(String,boolean)}.     * @hide     * @internal     */    public static final String EXTRA_TRIGGERED_BY_NOTIFICATION = "notification";    /**     * Activity Action: Confirm with user if they want to connect to an AP.     * @hide     * @internal     */    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)    public static final String WIFI_NOTIFICATION_ACTION = "android.net.wifi.WIFI_NOTIFICATION";    /**     * The lookup key for a String indicates the SSID of the highest priority network.     * Retrieve with {@link android.content.Intent#getStringExtra(String)}.     * @hide     * @internal     */    public static final String EXTRA_NOTIFICATION_SSID = "ssid";    /**     * The lookup key for an int indicates the networkId of the highest priority network.     * Retrieve with {@link android.content.Intent#getIntExtra(String,int)}.     * @hide     * @internal     */    public static final String EXTRA_NOTIFICATION_NETWORKID = "network_id";    /**     * Broadcast intent action indicating that WPS check pin fails.     * @hide     * @internal     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String WIFI_WPS_CHECK_PIN_FAIL_ACTION = "android.net.wifi.WIFI_WPS_CHECK_PIN_FAIL";    /**     * Broadcast intent action indicating that the hotspot clients changed.     * @hide     * @internal     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String WIFI_HOTSPOT_CLIENTS_CHANGED_ACTION = "android.net.wifi.WIFI_HOTSPOT_CLIENTS_CHANGED";    /**     * Broadcast intent action indicating that the hotspot overlap occurs.     * @hide     * @internal     */    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)    public static final String WIFI_HOTSPOT_OVERLAP_ACTION = "android.net.wifi.WIFI_HOTSPOT_OVERLAP";    private Context mContext;    IWifiManager mService;    private static final int INVALID_KEY = 0;    private static int mListenerKey = 1;    private static final SparseArray mListenerMap = new SparseArray();    private static final Object mListenerMapLock = new Object();    private static AsyncChannel sAsyncChannel;    private static ServiceHandler sHandler;    private Messenger mWifiServiceMessenger;    private static final CountDownLatch sConnected = new CountDownLatch(1);    private static Object sThreadRefLock = new Object();    private static int sThreadRefCount;    private static HandlerThread sHandlerThread;    /**     * Create a new WifiManager instance.     * Applications will almost always want to use     * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve     * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}.     * @param context the application context     * @param service the Binder interface     * @hide - hide this because it takes in a parameter of type IWifiManager, which     * is a system private class.     */    public WifiManager(Context context, IWifiManager service) {        mContext = context;        mService = service;        init();    }    /**     * Return a list of all the networks configured in the supplicant.     * Not all fields of WifiConfiguration are returned. Only the following     * fields are filled in:     * <ul>     * <li>networkId</li>     * <li>SSID</li>     * <li>BSSID</li>     * <li>priority</li>     * <li>allowedProtocols</li>     * <li>allowedKeyManagement</li>     * <li>allowedAuthAlgorithms</li>     * <li>allowedPairwiseCiphers</li>     * <li>allowedGroupCiphers</li>     * </ul>     * @return a list of network configurations in the form of a list     * of {@link WifiConfiguration} objects. Upon failure to fetch or     * when when Wi-Fi is turned off, it can be null.     */    public List<WifiConfiguration> getConfiguredNetworks() {        try {            return mService.getConfiguredNetworks();        } catch (RemoteException e) {            return null;        }    }    /**     * Add a new network description to the set of configured networks.     * The {@code networkId} field of the supplied configuration object     * is ignored.     * <p/>     * The new network will be marked DISABLED by default. To enable it,     * called {@link #enableNetwork}.     *     * @param config the set of variables that describe the configuration,     *            contained in a {@link WifiConfiguration} object.     * @return the ID of the newly created network description. This is used in     *         other operations to specified the network to be acted upon.     *         Returns {@code -1} on failure.     */    public int addNetwork(WifiConfiguration config) {        if (config == null) {            return -1;        }        config.networkId = -1;        return addOrUpdateNetwork(config);    }    /**     * Update the network description of an existing configured network.     *     * @param config the set of variables that describe the configuration,     *            contained in a {@link WifiConfiguration} object. It may     *            be sparse, so that only the items that are being changed     *            are non-<code>null</code>. The {@code networkId} field     *            must be set to the ID of the existing network being updated.     * @return Returns the {@code networkId} of the supplied     *         {@code WifiConfiguration} on success.     *         <br/>     *         Returns {@code -1} on failure, including when the {@code networkId}     *         field of the {@code WifiConfiguration} does not refer to an     *         existing network.     */    public int updateNetwork(WifiConfiguration config) {        if (config == null || config.networkId < 0) {            return -1;        }        return addOrUpdateNetwork(config);    }    /**     * Internal method for doing the RPC that creates a new network description     * or updates an existing one.     *     * @param config The possibly sparse object containing the variables that     *         are to set or updated in the network description.     * @return the ID of the network on success, {@code -1} on failure.     */    private int addOrUpdateNetwork(WifiConfiguration config) {        try {            return mService.addOrUpdateNetwork(config);        } catch (RemoteException e) {            return -1;        }    }    /**     * Remove the specified network from the list of configured networks.     * This may result in the asynchronous delivery of state change     * events.     * @param netId the integer that identifies the network configuration     * to the supplicant     * @return {@code true} if the operation succeeded     */    public boolean removeNetwork(int netId) {        try {            return mService.removeNetwork(netId);        } catch (RemoteException e) {            return false;        }    }    /**     * Allow a previously configured network to be associated with. If     * <code>disableOthers</code> is true, then all other configured     * networks are disabled, and an attempt to connect to the selected     * network is initiated. This may result in the asynchronous delivery     * of state change events.     * @param netId the ID of the network in the list of configured networks     * @param disableOthers if true, disable all other networks. The way to     * select a particular network to connect to is specify {@code true}     * for this parameter.     * @return {@code true} if the operation succeeded     */    public boolean enableNetwork(int netId, boolean disableOthers) {        try {            return mService.enableNetwork(netId, disableOthers);        } catch (RemoteException e) {            return false;        }    }    /**     * Disable a configured network. The specified network will not be     * a candidate for associating. This may result in the asynchronous     * delivery of state change events.     * @param netId the ID of the network as returned by {@link #addNetwork}.     * @return {@code true} if the operation succeeded     */    public boolean disableNetwork(int netId) {        try {            return mService.disableNetwork(netId);        } catch (RemoteException e) {            return false;        }    }    /**     * Disassociate from the currently active access point. This may result     * in the asynchronous delivery of state change events.     * @return {@code true} if the operation succeeded     */    public boolean disconnect() {        try {            mService.disconnect();            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Reconnect to the currently active access point, if we are currently     * disconnected. This may result in the asynchronous delivery of state     * change events.     * @return {@code true} if the operation succeeded     */    public boolean reconnect() {        try {            mService.reconnect();            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Reconnect to the currently active access point, even if we are already     * connected. This may result in the asynchronous delivery of state     * change events.     * @return {@code true} if the operation succeeded     */    public boolean reassociate() {        try {            mService.reassociate();            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Check that the supplicant daemon is responding to requests.     * @return {@code true} if we were able to communicate with the supplicant and     * it returned the expected response to the PING message.     */    public boolean pingSupplicant() {        if (mService == null)            return false;        try {            return mService.pingSupplicant();        } catch (RemoteException e) {            return false;        }    }    /**     * Request a scan for access points. Returns immediately. The availability     * of the results is made known later by means of an asynchronous event sent     * on completion of the scan.     * @return {@code true} if the operation succeeded, i.e., the scan was initiated     */    public boolean startScan() {        try {            mService.startScan(false);            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Request a scan for access points. Returns immediately. The availability     * of the results is made known later by means of an asynchronous event sent     * on completion of the scan.     * This is a variant of startScan that forces an active scan, even if passive     * scans are the current default     * @return {@code true} if the operation succeeded, i.e., the scan was initiated     *     * @hide     */    public boolean startScanActive() {        try {            mService.startScan(true);            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Return dynamic information about the current Wi-Fi connection, if any is active.     * @return the Wi-Fi information, contained in {@link WifiInfo}.     */    public WifiInfo getConnectionInfo() {        try {            return mService.getConnectionInfo();        } catch (RemoteException e) {            return null;        }    }    /**     * Return the results of the latest access point scan.     * @return the list of access points found in the most recent scan.     */    public List<ScanResult> getScanResults() {        try {            return mService.getScanResults();        } catch (RemoteException e) {            return null;        }    }    /**     * Tell the supplicant to persist the current list of configured networks.     * <p>     * Note: It is possible for this method to change the network IDs of     * existing networks. You should assume the network IDs can be different     * after calling this method.     *     * @return {@code true} if the operation succeeded     */    public boolean saveConfiguration() {        try {            return mService.saveConfiguration();        } catch (RemoteException e) {            return false;        }    }    /**     * Set the country code.     * @param countryCode country code in ISO 3166 format.     * @param persist {@code true} if this needs to be remembered     *     * @hide     */    public void setCountryCode(String country, boolean persist) {        try {            mService.setCountryCode(country, persist);        } catch (RemoteException e) { }    }    /**     * Set the operational frequency band.     * @param band  One of     *     {@link #WIFI_FREQUENCY_BAND_AUTO},     *     {@link #WIFI_FREQUENCY_BAND_5GHZ},     *     {@link #WIFI_FREQUENCY_BAND_2GHZ},     * @param persist {@code true} if this needs to be remembered     * @hide     */    public void setFrequencyBand(int band, boolean persist) {        try {            mService.setFrequencyBand(band, persist);        } catch (RemoteException e) { }    }    /**     * Get the operational frequency band.     * @return One of     *     {@link #WIFI_FREQUENCY_BAND_AUTO},     *     {@link #WIFI_FREQUENCY_BAND_5GHZ},     *     {@link #WIFI_FREQUENCY_BAND_2GHZ} or     *     {@code -1} on failure.     * @hide     */    public int getFrequencyBand() {        try {            return mService.getFrequencyBand();        } catch (RemoteException e) {            return -1;        }    }    /**     * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz)     * @return {@code true} if supported, {@code false} otherwise.     * @hide     */    public boolean isDualBandSupported() {        try {            return mService.isDualBandSupported();        } catch (RemoteException e) {            return false;        }    }    /**     * Return the DHCP-assigned addresses from the last successful DHCP request,     * if any.     * @return the DHCP information     */    public DhcpInfo getDhcpInfo() {        try {            return mService.getDhcpInfo();        } catch (RemoteException e) {            return null;        }    }    /**     * Enable or disable Wi-Fi.     * @param enabled {@code true} to enable, {@code false} to disable.     * @return {@code true} if the operation succeeds (or if the existing state     *         is the same as the requested state).     */    public boolean setWifiEnabled(boolean enabled) {        try {            return mService.setWifiEnabled(enabled);        } catch (RemoteException e) {            return false;        }    }    /**     * Gets the Wi-Fi enabled state.     * @return One of {@link #WIFI_STATE_DISABLED},     *         {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED},     *         {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN}     * @see #isWifiEnabled()     */    public int getWifiState() {        try {            return mService.getWifiEnabledState();        } catch (RemoteException e) {            return WIFI_STATE_UNKNOWN;        }    }    /**     * Return whether Wi-Fi is enabled or disabled.     * @return {@code true} if Wi-Fi is enabled     * @see #getWifiState()     */    public boolean isWifiEnabled() {        return getWifiState() == WIFI_STATE_ENABLED;    }    /**     * Return TX packet counter, for CTS test of WiFi watchdog.     * @param listener is the interface to receive result     *     * @hide for CTS test only     */    public void getTxPacketCount(TxPacketCountListener listener) {        validateChannel();        sAsyncChannel.sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener));    }    /**     * Calculates the level of the signal. This should be used any time a signal     * is being shown.     *     * @param rssi The power of the signal measured in RSSI.     * @param numLevels The number of levels to consider in the calculated     *            level.     * @return A level of the signal, given in the range of 0 to numLevels-1     *         (both inclusive).     */    public static int calculateSignalLevel(int rssi, int numLevels) {        if (rssi <= MIN_RSSI) {            return 0;        } else if (rssi >= MAX_RSSI) {            return numLevels - 1;        } else {            float inputRange = (MAX_RSSI - MIN_RSSI);            float outputRange = (numLevels - 1);            return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange);        }    }    /**     * Compares two signal strengths.     *     * @param rssiA The power of the first signal measured in RSSI.     * @param rssiB The power of the second signal measured in RSSI.     * @return Returns <0 if the first signal is weaker than the second signal,     *         0 if the two signals have the same strength, and >0 if the first     *         signal is stronger than the second signal.     */    public static int compareSignalLevel(int rssiA, int rssiB) {        return rssiA - rssiB;    }    /**     * Start AccessPoint mode with the specified     * configuration. If the radio is already running in     * AP mode, update the new configuration     * Note that starting in access point mode disables station     * mode operation     * @param wifiConfig SSID, security and channel details as     *        part of WifiConfiguration     * @return {@code true} if the operation succeeds, {@code false} otherwise     *     * @hide Dont open up yet     */    public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {        try {            mService.setWifiApEnabled(wifiConfig, enabled);            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Gets the Wi-Fi enabled state.     * @return One of {@link #WIFI_AP_STATE_DISABLED},     *         {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},     *         {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}     * @see #isWifiApEnabled()     *     * @hide Dont open yet     */    public int getWifiApState() {        try {            return mService.getWifiApEnabledState();        } catch (RemoteException e) {            return WIFI_AP_STATE_FAILED;        }    }    /**     * Return whether Wi-Fi AP is enabled or disabled.     * @return {@code true} if Wi-Fi AP is enabled     * @see #getWifiApState()     *     * @hide Dont open yet     */    public boolean isWifiApEnabled() {        return getWifiApState() == WIFI_AP_STATE_ENABLED;    }    /**     * Gets the Wi-Fi AP Configuration.     * @return AP details in WifiConfiguration     *     * @hide Dont open yet     */    public WifiConfiguration getWifiApConfiguration() {        try {            return mService.getWifiApConfiguration();        } catch (RemoteException e) {            return null;        }    }    /**     * Sets the Wi-Fi AP Configuration.     * @return {@code true} if the operation succeeded, {@code false} otherwise     *     * @hide Dont open yet     */    public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {        try {            mService.setWifiApConfiguration(wifiConfig);            return true;        } catch (RemoteException e) {            return false;        }    }   /**     * Start the driver and connect to network.     *     * This function will over-ride WifiLock and device idle status. For example,     * even if the device is idle or there is only a scan-only lock held,     * a start wifi would mean that wifi connection is kept active until     * a stopWifi() is sent.     *     * This API is used by WifiStateTracker     *     * @return {@code true} if the operation succeeds else {@code false}     * @hide     */    public boolean startWifi() {        try {            mService.startWifi();            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Disconnect from a network (if any) and stop the driver.     *     * This function will over-ride WifiLock and device idle status. Wi-Fi     * stays inactive until a startWifi() is issued.     *     * This API is used by WifiStateTracker     *     * @return {@code true} if the operation succeeds else {@code false}     * @hide     */    public boolean stopWifi() {        try {            mService.stopWifi();            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Add a bssid to the supplicant blacklist     *     * This API is used by WifiWatchdogService     *     * @return {@code true} if the operation succeeds else {@code false}     * @hide     */    public boolean addToBlacklist(String bssid) {        try {            mService.addToBlacklist(bssid);            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Clear the supplicant blacklist     *     * This API is used by WifiWatchdogService     *     * @return {@code true} if the operation succeeds else {@code false}     * @hide     */    public boolean clearBlacklist() {        try {            mService.clearBlacklist();            return true;        } catch (RemoteException e) {            return false;        }    }    /* TODO: deprecate synchronous API and open up the following API */    private static final int BASE = Protocol.BASE_WIFI_MANAGER;    /* Commands to WifiService */    /** @hide */    public static final int CONNECT_NETWORK                 = BASE + 1;    /** @hide */    public static final int CONNECT_NETWORK_FAILED          = BASE + 2;    /** @hide */    public static final int CONNECT_NETWORK_SUCCEEDED       = BASE + 3;    /** @hide */    public static final int FORGET_NETWORK                  = BASE + 4;    /** @hide */    public static final int FORGET_NETWORK_FAILED           = BASE + 5;    /** @hide */    public static final int FORGET_NETWORK_SUCCEEDED        = BASE + 6;    /** @hide */    public static final int SAVE_NETWORK                    = BASE + 7;    /** @hide */    public static final int SAVE_NETWORK_FAILED             = BASE + 8;    /** @hide */    public static final int SAVE_NETWORK_SUCCEEDED          = BASE + 9;    /** @hide */    public static final int START_WPS                       = BASE + 10;    /** @hide */    public static final int START_WPS_SUCCEEDED             = BASE + 11;    /** @hide */    public static final int WPS_FAILED                      = BASE + 12;    /** @hide */    public static final int WPS_COMPLETED                   = BASE + 13;    /** @hide */    public static final int CANCEL_WPS                      = BASE + 14;    /** @hide */    public static final int CANCEL_WPS_FAILED               = BASE + 15;    /** @hide */    public static final int CANCEL_WPS_SUCCEDED             = BASE + 16;    /** @hide */    public static final int DISABLE_NETWORK                 = BASE + 17;    /** @hide */    public static final int DISABLE_NETWORK_FAILED          = BASE + 18;    /** @hide */    public static final int DISABLE_NETWORK_SUCCEEDED       = BASE + 19;    /** @hide */    public static final int RSSI_PKTCNT_FETCH               = BASE + 20;    /** @hide */    public static final int RSSI_PKTCNT_FETCH_SUCCEEDED     = BASE + 21;    /** @hide */    public static final int RSSI_PKTCNT_FETCH_FAILED        = BASE + 22;    /* For system use only */    /** @hide */    public static final int ENABLE_TRAFFIC_STATS_POLL       = BASE + 31;    /** @hide */    public static final int TRAFFIC_STATS_POLL              = BASE + 32;    /**     * Passed with {@link ActionListener#onFailure}.     * Indicates that the operation failed due to an internal error.     * @hide     */    public static final int ERROR                       = 0;    /**     * Passed with {@link ActionListener#onFailure}.     * Indicates that the operation is already in progress     * @hide     */    public static final int IN_PROGRESS                 = 1;    /**     * Passed with {@link ActionListener#onFailure}.     * Indicates that the operation failed because the framework is busy and     * unable to service the request     * @hide     */    public static final int BUSY                        = 2;    /* WPS specific errors */    /** WPS overlap detected {@hide} */    public static final int WPS_OVERLAP_ERROR           = 3;    /** WEP on WPS is prohibited {@hide} */    public static final int WPS_WEP_PROHIBITED          = 4;    /** TKIP only prohibited {@hide} */    public static final int WPS_TKIP_ONLY_PROHIBITED    = 5;    /** Authentication failure on WPS {@hide} */    public static final int WPS_AUTH_FAILURE            = 6;    /** WPS timed out {@hide} */    public static final int WPS_TIMED_OUT               = 7;    /** Interface for callback invocation on an application action {@hide} */    public interface ActionListener {        /** The operation succeeded */        public void onSuccess();        /**         * The operation failed         * @param reason The reason for failure could be one of         * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY}         */        public void onFailure(int reason);    }    /** Interface for callback invocation on a start WPS action {@hide} */    public interface WpsListener {        /** WPS start succeeded */        public void onStartSuccess(String pin);        /** WPS operation completed succesfully */        public void onCompletion();        /**         * WPS operation failed         * @param reason The reason for failure could be one of         * {@link #IN_PROGRESS}, {@link #WPS_OVERLAP_ERROR},{@link #ERROR} or {@link #BUSY}         */        public void onFailure(int reason);    }    /** Interface for callback invocation on a TX packet count poll action {@hide} */    public interface TxPacketCountListener {        /**         * The operation succeeded         * @param count TX packet counter         */        public void onSuccess(int count);        /**         * The operation failed         * @param reason The reason for failure could be one of         * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY}         */        public void onFailure(int reason);    }    private static class ServiceHandler extends Handler {        ServiceHandler(Looper looper) {            super(looper);        }        @Override        public void handleMessage(Message message) {            Object listener = removeListener(message.arg2);            switch (message.what) {                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {                        sAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);                    } else {                        Log.e(TAG, "Failed to set up channel connection");                        // This will cause all further async API calls on the WifiManager                        // to fail and throw an exception                        if (sAsyncChannel != null) {                            Log.d(TAG, "Disconnect sAsyncChannel for failed to set up!");                            sAsyncChannel.disconnect();                            sAsyncChannel = null;                        } else {                            Log.d(TAG, "sAsyncChannel is null when failed to set up!");                        }                    }                    sConnected.countDown();                    break;                case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:                    // Ignore                    break;                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:                    Log.e(TAG, "Channel connection lost");                    // This will cause all further async API calls on the WifiManager                    // to fail and throw an exception                    if (sAsyncChannel != null) {                        Log.d(TAG, "Disconnect sAsyncChannel for channel connection lost!");                        sAsyncChannel.disconnect();                        sAsyncChannel = null;                    } else {                        Log.d(TAG, "sAsyncChannel is null when channel connection lost!");                    }                    getLooper().quit();                    break;                    /* ActionListeners grouped together */                case WifiManager.CONNECT_NETWORK_FAILED:                case WifiManager.FORGET_NETWORK_FAILED:                case WifiManager.SAVE_NETWORK_FAILED:                case WifiManager.CANCEL_WPS_FAILED:                case WifiManager.DISABLE_NETWORK_FAILED:                    if (listener != null) {                        ((ActionListener) listener).onFailure(message.arg1);                    }                    break;                    /* ActionListeners grouped together */                case WifiManager.CONNECT_NETWORK_SUCCEEDED:                case WifiManager.FORGET_NETWORK_SUCCEEDED:                case WifiManager.SAVE_NETWORK_SUCCEEDED:                case WifiManager.CANCEL_WPS_SUCCEDED:                case WifiManager.DISABLE_NETWORK_SUCCEEDED:                    if (listener != null) {                        ((ActionListener) listener).onSuccess();                    }                    break;                case WifiManager.START_WPS_SUCCEEDED:                    if (listener != null) {                        WpsResult result = (WpsResult) message.obj;                        ((WpsListener) listener).onStartSuccess(result.pin);                        //Listener needs to stay until completion or failure                        synchronized(mListenerMapLock) {                            mListenerMap.put(message.arg2, listener);                        }                    }                    break;                case WifiManager.WPS_COMPLETED:                    if (listener != null) {                        ((WpsListener) listener).onCompletion();                    }                    break;                case WifiManager.WPS_FAILED:                    if (listener != null) {                        ((WpsListener) listener).onFailure(message.arg1);                    }                    break;                case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:                    if (listener != null) {                        RssiPacketCountInfo info = (RssiPacketCountInfo) message.obj;                        if (info != null)                            ((TxPacketCountListener) listener).onSuccess(info.txgood + info.txbad);                        else                            ((TxPacketCountListener) listener).onFailure(ERROR);                    }                    break;                case WifiManager.RSSI_PKTCNT_FETCH_FAILED:                    if (listener != null) {                        ((TxPacketCountListener) listener).onFailure(message.arg1);                    }                    break;                default:                    //ignore                    break;            }        }    }    private static int putListener(Object listener) {        if (listener == null) return INVALID_KEY;        int key;        synchronized (mListenerMapLock) {            do {                key = mListenerKey++;            } while (key == INVALID_KEY);            mListenerMap.put(key, listener);        }        return key;    }    private static Object removeListener(int key) {        if (key == INVALID_KEY) return null;        synchronized (mListenerMapLock) {            Object listener = mListenerMap.get(key);            mListenerMap.remove(key);            return listener;        }    }    private void init() {        Log.d(TAG, "Enter init, sThreadRefCount:" + sThreadRefCount);        mWifiServiceMessenger = getWifiServiceMessenger();        if (mWifiServiceMessenger == null) {            sAsyncChannel = null;            Log.e(TAG, "mWifiServiceMessenger == null");            return;        }        synchronized (sThreadRefLock) {            if (++sThreadRefCount == 1) {                sHandlerThread = new HandlerThread("WifiManager");                Log.d(TAG, "Create WifiManager handlerthread");                sHandlerThread.start();                sHandler = new ServiceHandler(sHandlerThread.getLooper());                sAsyncChannel = new AsyncChannel();                sAsyncChannel.connect(mContext, sHandler, mWifiServiceMessenger);                try {                    sConnected.await();                } catch (InterruptedException e) {                    Log.e(TAG, "interrupted wait at init");                }            }        }    }    private void validateChannel() {        if (sAsyncChannel == null) throw new IllegalStateException(                "No permission to access and change wifi or a bad initialization");    }    /**     * Connect to a network with the given configuration. The network also     * gets added to the supplicant configuration.     *     * For a new network, this function is used instead of a     * sequence of addNetwork(), enableNetwork(), saveConfiguration() and     * reconnect()     *     * @param config the set of variables that describe the configuration,     *            contained in a {@link WifiConfiguration} object.     * @param listener for callbacks on success or failure. Can be null.     * @throws IllegalStateException if the WifiManager instance needs to be     * initialized again     *     * @hide     */    public void connect(WifiConfiguration config, ActionListener listener) {        if (config == null) throw new IllegalArgumentException("config cannot be null");        validateChannel();        // Use INVALID_NETWORK_ID for arg1 when passing a config object        // arg1 is used to pass network id when the network already exists        sAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,                putListener(listener), config);    }    /**     * Connect to a network with the given networkId.     *     * This function is used instead of a enableNetwork(), saveConfiguration() and     * reconnect()     *     * @param networkId the network id identifiying the network in the     *                supplicant configuration list     * @param listener for callbacks on success or failure. Can be null.     * @throws IllegalStateException if the WifiManager instance needs to be     * initialized again     * @hide     */    public void connect(int networkId, ActionListener listener) {        if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");        validateChannel();        sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));    }    /**     * Save the given network in the supplicant config. If the network already     * exists, the configuration is updated. A new network is enabled     * by default.     *     * For a new network, this function is used instead of a     * sequence of addNetwork(), enableNetwork() and saveConfiguration().     *     * For an existing network, it accomplishes the task of updateNetwork()     * and saveConfiguration()     *     * @param config the set of variables that describe the configuration,     *            contained in a {@link WifiConfiguration} object.     * @param listener for callbacks on success or failure. Can be null.     * @throws IllegalStateException if the WifiManager instance needs to be     * initialized again     * @hide     */    public void save(WifiConfiguration config, ActionListener listener) {        if (config == null) throw new IllegalArgumentException("config cannot be null");        validateChannel();        sAsyncChannel.sendMessage(SAVE_NETWORK, 0, putListener(listener), config);    }    /**     * Delete the network in the supplicant config.     *     * This function is used instead of a sequence of removeNetwork()     * and saveConfiguration().     *     * @param config the set of variables that describe the configuration,     *            contained in a {@link WifiConfiguration} object.     * @param listener for callbacks on success or failure. Can be null.     * @throws IllegalStateException if the WifiManager instance needs to be     * initialized again     * @hide     */    public void forget(int netId, ActionListener listener) {        if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");        validateChannel();        sAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener));    }    /**     * Disable network     *     * @param netId is the network Id     * @param listener for callbacks on success or failure. Can be null.     * @throws IllegalStateException if the WifiManager instance needs to be     * initialized again     * @hide     */    public void disable(int netId, ActionListener listener) {        if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");        validateChannel();        sAsyncChannel.sendMessage(DISABLE_NETWORK, netId, putListener(listener));    }    /**     * Start Wi-fi Protected Setup     *     * @param config WPS configuration     * @param listener for callbacks on success or failure. Can be null.     * @throws IllegalStateException if the WifiManager instance needs to be     * initialized again     * @hide     */    public void startWps(WpsInfo config, WpsListener listener) {        if (config == null) throw new IllegalArgumentException("config cannot be null");        validateChannel();        sAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config);    }    /**     * Cancel any ongoing Wi-fi Protected Setup     *     * @param listener for callbacks on success or failure. Can be null.     * @throws IllegalStateException if the WifiManager instance needs to be     * initialized again     * @hide     */    public void cancelWps(ActionListener listener) {        validateChannel();        sAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener));    }    /**     * Get a reference to WifiService handler. This is used by a client to establish     * an AsyncChannel communication with WifiService     *     * @return Messenger pointing to the WifiService handler     * @hide     */    public Messenger getWifiServiceMessenger() {        try {            return mService.getWifiServiceMessenger();        } catch (RemoteException e) {            return null;        } catch (SecurityException e) {            return null;        }    }    /**     * Get a reference to WifiStateMachine handler.     * @return Messenger pointing to the WifiService handler     * @hide     */    public Messenger getWifiStateMachineMessenger() {        try {            return mService.getWifiStateMachineMessenger();        } catch (RemoteException e) {            return null;        }    }    /**     * Returns the file in which IP and proxy configuration data is stored     * @hide     */    public String getConfigFile() {        try {            return mService.getConfigFile();        } catch (RemoteException e) {            return null;        }    }    /**     * Allows an application to keep the Wi-Fi radio awake.     * Normally the Wi-Fi radio may turn off when the user has not used the device in a while.     * Acquiring a WifiLock will keep the radio on until the lock is released.  Multiple     * applications may hold WifiLocks, and the radio will only be allowed to turn off when no     * WifiLocks are held in any application.     * <p>     * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or     * could function over a mobile network, if available.  A program that needs to download large     * files should hold a WifiLock to ensure that the download will complete, but a program whose     * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely     * affecting battery life.     * <p>     * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane     * Mode.  They simply keep the radio from turning off when Wi-Fi is already on but the device     * is idle.     * <p>     * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK}     * permission in an {@code <uses-permission>} element of the application's manifest.     */    public class WifiLock {        private String mTag;        private final IBinder mBinder;        private int mRefCount;        int mLockType;        private boolean mRefCounted;        private boolean mHeld;        private WorkSource mWorkSource;        private WifiLock(int lockType, String tag) {            mTag = tag;            mLockType = lockType;            mBinder = new Binder();            mRefCount = 0;            mRefCounted = true;            mHeld = false;        }        /**         * Locks the Wi-Fi radio on until {@link #release} is called.         *         * If this WifiLock is reference-counted, each call to {@code acquire} will increment the         * reference count, and the radio will remain locked as long as the reference count is         * above zero.         *         * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock         * the radio, but subsequent calls will be ignored.  Only one call to {@link #release}         * will be required, regardless of the number of times that {@code acquire} is called.         */        public void acquire() {            synchronized (mBinder) {                if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {                    try {                        mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource);                        synchronized (WifiManager.this) {                            if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {                                mService.releaseWifiLock(mBinder);                                throw new UnsupportedOperationException(                                            "Exceeded maximum number of wifi locks");                            }                            mActiveLockCount++;                        }                    } catch (RemoteException ignore) {                    }                    mHeld = true;                }            }        }        /**         * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle.         *         * If this WifiLock is reference-counted, each call to {@code release} will decrement the         * reference count, and the radio will be unlocked only when the reference count reaches         * zero.  If the reference count goes below zero (that is, if {@code release} is called         * a greater number of times than {@link #acquire}), an exception is thrown.         *         * If this WifiLock is not reference-counted, the first call to {@code release} (after         * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent         * calls will be ignored.         */        public void release() {            synchronized (mBinder) {                if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {                    try {                        mService.releaseWifiLock(mBinder);                        synchronized (WifiManager.this) {                            mActiveLockCount--;                        }                    } catch (RemoteException ignore) {                    }                    mHeld = false;                }                if (mRefCount < 0) {                    throw new RuntimeException("WifiLock under-locked " + mTag);                }            }        }        /**         * Controls whether this is a reference-counted or non-reference-counted WifiLock.         *         * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and         * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire}         * has been balanced with a call to {@link #release}.  Non-reference-counted WifiLocks         * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the         * radio whenever {@link #release} is called and it is locked.         *         * @param refCounted true if this WifiLock should keep a reference count         */        public void setReferenceCounted(boolean refCounted) {            mRefCounted = refCounted;        }        /**         * Checks whether this WifiLock is currently held.         *         * @return true if this WifiLock is held, false otherwise         */        public boolean isHeld() {            synchronized (mBinder) {                return mHeld;            }        }        public void setWorkSource(WorkSource ws) {            synchronized (mBinder) {                if (ws != null && ws.size() == 0) {                    ws = null;                }                boolean changed = true;                if (ws == null) {                    mWorkSource = null;                } else if (mWorkSource == null) {                    changed = mWorkSource != null;                    mWorkSource = new WorkSource(ws);                } else {                    changed = mWorkSource.diff(ws);                    if (changed) {                        mWorkSource.set(ws);                    }                }                if (changed && mHeld) {                    try {                        mService.updateWifiLockWorkSource(mBinder, mWorkSource);                    } catch (RemoteException e) {                    }                }            }        }        public String toString() {            String s1, s2, s3;            synchronized (mBinder) {                s1 = Integer.toHexString(System.identityHashCode(this));                s2 = mHeld ? "held; " : "";                if (mRefCounted) {                    s3 = "refcounted: refcount = " + mRefCount;                } else {                    s3 = "not refcounted";                }                return "WifiLock{ " + s1 + "; " + s2 + s3 + " }";            }        }        @Override        protected void finalize() throws Throwable {            super.finalize();            synchronized (mBinder) {                if (mHeld) {                    try {                        mService.releaseWifiLock(mBinder);                        synchronized (WifiManager.this) {                            mActiveLockCount--;                        }                    } catch (RemoteException ignore) {                    }                }            }        }    }    /**     * Creates a new WifiLock.     *     * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL},     * {@link #WIFI_MODE_FULL_HIGH_PERF} and {@link #WIFI_MODE_SCAN_ONLY} for     * descriptions of the types of Wi-Fi locks.     * @param tag a tag for the WifiLock to identify it in debugging messages.  This string is     *            never shown to the user under normal conditions, but should be descriptive     *            enough to identify your application and the specific WifiLock within it, if it     *            holds multiple WifiLocks.     *     * @return a new, unacquired WifiLock with the given tag.     *     * @see WifiLock     */    public WifiLock createWifiLock(int lockType, String tag) {        return new WifiLock(lockType, tag);    }    /**     * Creates a new WifiLock.     *     * @param tag a tag for the WifiLock to identify it in debugging messages.  This string is     *            never shown to the user under normal conditions, but should be descriptive     *            enough to identify your application and the specific WifiLock within it, if it     *            holds multiple WifiLocks.     *     * @return a new, unacquired WifiLock with the given tag.     *     * @see WifiLock     */    public WifiLock createWifiLock(String tag) {        return new WifiLock(WIFI_MODE_FULL, tag);    }    /**     * Create a new MulticastLock     *     * @param tag a tag for the MulticastLock to identify it in debugging     *            messages.  This string is never shown to the user under     *            normal conditions, but should be descriptive enough to     *            identify your application and the specific MulticastLock     *            within it, if it holds multiple MulticastLocks.     *     * @return a new, unacquired MulticastLock with the given tag.     *     * @see MulticastLock     */    public MulticastLock createMulticastLock(String tag) {        return new MulticastLock(tag);    }    /**     * Allows an application to receive Wifi Multicast packets.     * Normally the Wifi stack filters out packets not explicitly     * addressed to this device.  Acquring a MulticastLock will     * cause the stack to receive packets addressed to multicast     * addresses.  Processing these extra packets can cause a noticable     * battery drain and should be disabled when not needed.     */    public class MulticastLock {        private String mTag;        private final IBinder mBinder;        private int mRefCount;        private boolean mRefCounted;        private boolean mHeld;        private MulticastLock(String tag) {            mTag = tag;            mBinder = new Binder();            mRefCount = 0;            mRefCounted = true;            mHeld = false;        }        /**         * Locks Wifi Multicast on until {@link #release} is called.         *         * If this MulticastLock is reference-counted each call to         * {@code acquire} will increment the reference count, and the         * wifi interface will receive multicast packets as long as the         * reference count is above zero.         *         * If this MulticastLock is not reference-counted, the first call to         * {@code acquire} will turn on the multicast packets, but subsequent         * calls will be ignored.  Only one call to {@link #release} will         * be required, regardless of the number of times that {@code acquire}         * is called.         *         * Note that other applications may also lock Wifi Multicast on.         * Only they can relinquish their lock.         *         * Also note that applications cannot leave Multicast locked on.         * When an app exits or crashes, any Multicast locks will be released.         */        public void acquire() {            synchronized (mBinder) {                if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {                    try {                        mService.acquireMulticastLock(mBinder, mTag);                        synchronized (WifiManager.this) {                            if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {                                mService.releaseMulticastLock();                                throw new UnsupportedOperationException(                                        "Exceeded maximum number of wifi locks");                            }                            mActiveLockCount++;                        }                    } catch (RemoteException ignore) {                    }                    mHeld = true;                }            }        }        /**         * Unlocks Wifi Multicast, restoring the filter of packets         * not addressed specifically to this device and saving power.         *         * If this MulticastLock is reference-counted, each call to         * {@code release} will decrement the reference count, and the         * multicast packets will only stop being received when the reference         * count reaches zero.  If the reference count goes below zero (that         * is, if {@code release} is called a greater number of times than         * {@link #acquire}), an exception is thrown.         *         * If this MulticastLock is not reference-counted, the first call to         * {@code release} (after the radio was multicast locked using         * {@link #acquire}) will unlock the multicast, and subsequent calls         * will be ignored.         *         * Note that if any other Wifi Multicast Locks are still outstanding         * this {@code release} call will not have an immediate effect.  Only         * when all applications have released all their Multicast Locks will         * the Multicast filter be turned back on.         *         * Also note that when an app exits or crashes all of its Multicast         * Locks will be automatically released.         */        public void release() {            synchronized (mBinder) {                if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {                    try {                        mService.releaseMulticastLock();                        synchronized (WifiManager.this) {                            mActiveLockCount--;                        }                    } catch (RemoteException ignore) {                    }                    mHeld = false;                }                if (mRefCount < 0) {                    throw new RuntimeException("MulticastLock under-locked "                            + mTag);                }            }        }        /**         * Controls whether this is a reference-counted or non-reference-         * counted MulticastLock.         *         * Reference-counted MulticastLocks keep track of the number of calls         * to {@link #acquire} and {@link #release}, and only stop the         * reception of multicast packets when every call to {@link #acquire}         * has been balanced with a call to {@link #release}.  Non-reference-         * counted MulticastLocks allow the reception of multicast packets         * whenever {@link #acquire} is called and stop accepting multicast         * packets whenever {@link #release} is called.         *         * @param refCounted true if this MulticastLock should keep a reference         * count         */        public void setReferenceCounted(boolean refCounted) {            mRefCounted = refCounted;        }        /**         * Checks whether this MulticastLock is currently held.         *         * @return true if this MulticastLock is held, false otherwise         */        public boolean isHeld() {            synchronized (mBinder) {                return mHeld;            }        }        public String toString() {            String s1, s2, s3;            synchronized (mBinder) {                s1 = Integer.toHexString(System.identityHashCode(this));                s2 = mHeld ? "held; " : "";                if (mRefCounted) {                    s3 = "refcounted: refcount = " + mRefCount;                } else {                    s3 = "not refcounted";                }                return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }";            }        }        @Override        protected void finalize() throws Throwable {            super.finalize();            setReferenceCounted(false);            release();        }    }    /**     * Check multicast filter status.     *     * @return true if multicast packets are allowed.     *     * @hide pending API council approval     */    public boolean isMulticastEnabled() {        try {            return mService.isMulticastEnabled();        } catch (RemoteException e) {            return false;        }    }    /**     * Initialize the multicast filtering to 'on'     * @hide no intent to publish     */    public boolean initializeMulticastFiltering() {        try {            mService.initializeMulticastFiltering();            return true;        } catch (RemoteException e) {             return false;        }    }    /** @hide */    public void captivePortalCheckComplete() {        try {            mService.captivePortalCheckComplete();        } catch (RemoteException e) {}    }    protected void finalize() throws Throwable {        Log.d(TAG, "Enter finalize, sThreadRefCount:" + sThreadRefCount);        try {            synchronized (sThreadRefLock) {                if (--sThreadRefCount == 0 && sHandlerThread != null) {                    sHandlerThread.getLooper().quit();                    if (sAsyncChannel != null) {                        Log.d(TAG, "Disconnect sAsyncChannel for finalize!");                        sAsyncChannel.disconnect();                        sAsyncChannel = null;                    } else {                        Log.d(TAG, "sAsyncChannel is null when finalize!");                    }                }            }        } finally {            super.finalize();        }    }    // M: Added functions    /**     * Get hotspot preferred channels     * @return an String array of the hotspot perferred channels     * @hide     * @internal     */    public String[] getAccessPointPreferredChannels() {        try {            return mService.getAccessPointPreferredChannels();        } catch (RemoteException e) {            return null;        }    }    /**     * Enable CTIA test     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean doCtiaTestOn() {        try {            return mService.doCtiaTestOn();        } catch (RemoteException e) {            return false;        }    }    /**     * Disable CTIA test     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean doCtiaTestOff() {        try {            return mService.doCtiaTestOff();        } catch (RemoteException e) {            return false;        }    }    /**     * Set rate     * @param rate The value to be set     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean doCtiaTestRate(int rate) {        try {            return mService.doCtiaTestRate(rate);        } catch (RemoteException e) {            return false;        }    }    /**     * Set the TX power enable or disable     * @param enabled {@code true} to enable, {@code false} to disable.     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean setTxPowerEnabled(boolean enabled) {        try {            return mService.setTxPowerEnabled(enabled);        } catch (RemoteException e) {            return false;        }    }    /**     * Set the TX power offset     * @param offset The offset value to be set     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean setTxPower(int offset) {        try {            return mService.setTxPower(offset);        } catch (RemoteException e) {            return false;        }    }    /**     * Start hotspot WPS function     * @param config WPS configuration     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean startApWps(WpsInfo config) {        try {            mService.startApWps(config);            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Return the hotspot clients     * @return a list of hotspot client in the form of a list     * of {@link HotspotClient} objects.     * @hide     * @internal     */    public List<HotspotClient> getHotspotClients() {        try {            return mService.getHotspotClients();        } catch (RemoteException e) {            return null;        }    }    /**     * Return the IP address of the client     * @param deviceAddress The mac address of the hotspot client     * @hide     * @internal     */    public String getClientIp(String deviceAddress) {        try {            return mService.getClientIp(deviceAddress);        } catch (RemoteException e) {            return null;        }    }    /**     * Block the client     * @param client The hotspot client to be blocked     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean blockClient(HotspotClient client) {        try {            return mService.blockClient(client);        } catch (RemoteException e) {            return false;        }    }    /**     * Unblock the client     * @param client The hotspot client to be unblocked     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean unblockClient(HotspotClient client) {        try {            return mService.unblockClient(client);        } catch (RemoteException e) {            return false;        }    }        /**     * Set hotspot probe request enable or disable     * @param enabled {@code true} to enable, {@code false} to disable.     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean setApProbeRequestEnabled(boolean enabled) {        try {            return mService.setApProbeRequestEnabled(enabled);        } catch (RemoteException e) {            return false;        }    }    /**     * Suspend the WiFi available notification     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean suspendNotification() {        try {            mService.suspendNotification();            return true;        } catch (RemoteException e) {            return false;        }    }    /**     * Save the priority of access point     * @return {@code true} if the operation succeeds else {@code false}     * @hide     * @internal     */    public boolean saveApPriority() {        try {            return mService.saveApPriority();        } catch (RemoteException e) {            return false;        }    }    /**     * Check if there is connectable AP exists     * @return {@code true} if there is connectable AP exists else {@code false}     * @hide     * @internal     */    public boolean hasConnectableAp() {        try {            return mService.hasConnectableAp();        } catch (RemoteException e) {            return false;        }    }}


alps/frameworks/base/wifi/java/android/net/wifi/WifiConfiguration.java
/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.net.wifi;import android.net.LinkProperties;import android.os.Parcelable;import android.os.Parcel;import com.mediatek.common.featureoption.FeatureOption;import java.util.BitSet;/** * A class representing a configured Wi-Fi network, including the * security configuration. Android will not necessarily support * all of these security schemes initially. */public class WifiConfiguration implements Parcelable {    /**     * In old configurations, the "private_key" field was used. However, newer     * configurations use the key_id field with the engine_id set to "keystore".     * If this field is found in the configuration, the migration code is     * triggered.     * @hide     */    public static final String OLD_PRIVATE_KEY_NAME = "private_key";    /**     * String representing the keystore OpenSSL ENGINE's ID.     * @hide     */    public static final String KEYSTORE_ENGINE_ID = "keystore";    /**     * String representing the keystore URI used for wpa_supplicant.     * @hide     */    public static final String KEYSTORE_URI = "keystore://";    /**     * String to set the engine value to when it should be enabled.     * @hide     */    public static final String ENGINE_ENABLE = "1";    /**     * String to set the engine value to when it should be disabled.     * @hide     */    public static final String ENGINE_DISABLE = "0";    /** {@hide} */    public static final String ssidVarName = "ssid";    /** {@hide} */    public static final String bssidVarName = "bssid";    /** {@hide} */    public static final String pskVarName = "psk";    /** {@hide} */    public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" };    /** {@hide} */    public static final String wepTxKeyIdxVarName = "wep_tx_keyidx";    /** {@hide} */    public static final String priorityVarName = "priority";    /** {@hide} */    public static final String hiddenSSIDVarName = "scan_ssid";    /** {@hide} */    public static final int INVALID_NETWORK_ID = -1;    /** {@hide} */    public class EnterpriseField {        private String varName;        private String value;        private EnterpriseField(String varName) {            this.varName = varName;            this.value = null;        }        public void setValue(String value) {            this.value = value;        }        public String varName() {            return varName;        }        public String value() {            return value;        }    }    /** {@hide} */    public EnterpriseField eap = new EnterpriseField("eap");    /** {@hide} */    public EnterpriseField phase2 = new EnterpriseField("phase2");    /** {@hide} */    public EnterpriseField identity = new EnterpriseField("identity");    /** {@hide} */    public EnterpriseField anonymous_identity = new EnterpriseField("anonymous_identity");    /** {@hide} */    public EnterpriseField password = new EnterpriseField("password");    /** {@hide} */    public EnterpriseField client_cert = new EnterpriseField("client_cert");    /** {@hide} */    public EnterpriseField engine = new EnterpriseField("engine");    /** {@hide} */    public EnterpriseField engine_id = new EnterpriseField("engine_id");    /** {@hide} */    public EnterpriseField key_id = new EnterpriseField("key_id");    /** {@hide} */    public EnterpriseField ca_cert = new EnterpriseField("ca_cert");    /**     * @hide     * @internal     */    public EnterpriseField ca_cert2 = new EnterpriseField("ca_cert2");    /** {@hide} */    public EnterpriseField[] enterpriseFields = {            eap, phase2, identity, anonymous_identity, password, client_cert,            engine, engine_id, key_id, ca_cert, ca_cert2 };    /**     * Recognized key management schemes.     */    public static class KeyMgmt {        private KeyMgmt() { }        /** WPA is not used; plaintext or static WEP could be used. */        public static final int NONE = 0;        /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */        public static final int WPA_PSK = 1;        /** WPA using EAP authentication. Generally used with an external authentication server. */        public static final int WPA_EAP = 2;        /** IEEE 802.1X using EAP authentication and (optionally) dynamically         * generated WEP keys. */        public static final int IEEE8021X = 3;        /** WPA2 pre-shared key for use with soft access point          * (requires {@code preSharedKey} to be specified).          * @hide          */        public static final int WPA2_PSK = 4;        /**          * WAPI with pre-shared key.         * @hide         * @internal         */        public static final int WAPI_PSK = 5;        /**          * WAPI with certificate authentication.         * @hide         * @internal         */        public static final int WAPI_CERT = 6;        public static final String varName = "key_mgmt";        public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X",                "WPA2_PSK", "WAPI_PSK", "WAPI_CERT" };    }    /**     * Recognized security protocols.     */    public static class Protocol {        private Protocol() { }        /** WPA/IEEE 802.11i/D3.0 */        public static final int WPA = 0;        /** WPA2/IEEE 802.11i */        public static final int RSN = 1;        /**          * WAPI         * @hide         * @internal         */        public static final int WAPI = 2;        public static final String varName = "proto";        public static final String[] strings = { "WPA", "RSN", "WAPI" };    }    /**     * Recognized IEEE 802.11 authentication algorithms.     */    public static class AuthAlgorithm {        private AuthAlgorithm() { }        /** Open System authentication (required for WPA/WPA2) */        public static final int OPEN = 0;        /** Shared Key authentication (requires static WEP keys) */        public static final int SHARED = 1;        /** LEAP/Network EAP (only used with LEAP) */        public static final int LEAP = 2;        public static final String varName = "auth_alg";        public static final String[] strings = { "OPEN", "SHARED", "LEAP" };    }    /**     * Recognized pairwise ciphers for WPA.     */    public static class PairwiseCipher {        private PairwiseCipher() { }        /** Use only Group keys (deprecated) */        public static final int NONE = 0;        /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */        public static final int TKIP = 1;        /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */        public static final int CCMP = 2;        /**          * SMS4, a block cipher of 128-bit block size and key size for WAPI.         * @hide         * @internal         */        public static final int SMS4 = 3;        public static final String varName = "pairwise";        public static final String[] strings = { "NONE", "TKIP", "CCMP", "SMS4" };    }    /**     * Recognized group ciphers.     * <pre>     * CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]     * TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]     * WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key     * WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)     * </pre>     */    public static class GroupCipher {        private GroupCipher() { }        /** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) */        public static final int WEP40 = 0;        /** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key */        public static final int WEP104 = 1;        /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */        public static final int TKIP = 2;        /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */        public static final int CCMP = 3;        /**          * SMS4, a block cipher of 128-bit block size and key size for WAPI.         * @hide         * @internal         */        public static final int SMS4 = 4;        public static final String varName = "group";        public static final String[] strings = { "WEP40", "WEP104", "TKIP", "CCMP", "SMS4" };    }    /** Possible status of a network configuration. */    public static class Status {        private Status() { }        /** this is the network we are currently connected to */        public static final int CURRENT = 0;        /** supplicant will not attempt to use this network */        public static final int DISABLED = 1;        /** supplicant will consider this network available for association */        public static final int ENABLED = 2;        public static final String[] strings = { "current", "disabled", "enabled" };    }    /** @hide */    public static final int DISABLED_UNKNOWN_REASON                         = 0;    /** @hide */    public static final int DISABLED_DNS_FAILURE                            = 1;    /** @hide */    public static final int DISABLED_DHCP_FAILURE                           = 2;    /** @hide */    public static final int DISABLED_AUTH_FAILURE                           = 3;    /**     * The ID number that the supplicant uses to identify this     * network configuration entry. This must be passed as an argument     * to most calls into the supplicant.     */    public int networkId;    /**     * The current status of this network configuration entry.     * @see Status     */    public int status;    /**     * The code referring to a reason for disabling the network     * Valid when {@link #status} == Status.DISABLED     * @hide     */    public int disableReason;    /**     * The network's SSID. Can either be an ASCII string,     * which must be enclosed in double quotation marks     * (e.g., {@code "MyNetwork"}, or a string of     * hex digits,which are not enclosed in quotes     * (e.g., {@code 01a243f405}).     */    public String SSID;    /**     * When set, this network configuration entry should only be used when     * associating with the AP having the specified BSSID. The value is     * a string in the format of an Ethernet MAC address, e.g.,     * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit.     */    public String BSSID;    /**     * Pre-shared key for use with WPA-PSK.     * <p/>     * When the value of this key is read, the actual key is     * not returned, just a "*" if the key has a value, or the null     * string otherwise.     */    public String preSharedKey;    /**     * Up to four WEP keys. Either an ASCII string enclosed in double     * quotation marks (e.g., {@code "abcdef"} or a string     * of hex digits (e.g., {@code 0102030405}).     * <p/>     * When the value of one of these keys is read, the actual key is     * not returned, just a "*" if the key has a value, or the null     * string otherwise.     */    public String[] wepKeys;    /** Default WEP key index, ranging from 0 to 3. */    public int wepTxKeyIndex;    /**     * Priority determines the preference given to a network by {@code wpa_supplicant}     * when choosing an access point with which to associate.     */    public int priority;    /**     * This is a network that does not broadcast its SSID, so an     * SSID-specific probe request must be used for scans.     */    public boolean hiddenSSID;    /**     * The set of key management protocols supported by this configuration.     * See {@link KeyMgmt} for descriptions of the values.     * Defaults to WPA-PSK WPA-EAP.     */    public BitSet allowedKeyManagement;    /**     * The set of security protocols supported by this configuration.     * See {@link Protocol} for descriptions of the values.     * Defaults to WPA RSN.     */    public BitSet allowedProtocols;    /**     * The set of authentication protocols supported by this configuration.     * See {@link AuthAlgorithm} for descriptions of the values.     * Defaults to automatic selection.     */    public BitSet allowedAuthAlgorithms;    /**     * The set of pairwise ciphers for WPA supported by this configuration.     * See {@link PairwiseCipher} for descriptions of the values.     * Defaults to CCMP TKIP.     */    public BitSet allowedPairwiseCiphers;    /**     * The set of group ciphers supported by this configuration.     * See {@link GroupCipher} for descriptions of the values.     * Defaults to CCMP TKIP WEP104 WEP40.     */    public BitSet allowedGroupCiphers;    /**     * @hide     */    public enum IpAssignment {        /* Use statically configured IP settings. Configuration can be accessed         * with linkProperties */        STATIC,        /* Use dynamically configured IP settigns */        DHCP,        /* no IP details are assigned, this is used to indicate         * that any existing IP settings should be retained */        UNASSIGNED    }    /**     * @hide     */    public IpAssignment ipAssignment;    /**     * @hide     */    public enum ProxySettings {        /* No proxy is to be used. Any existing proxy settings         * should be cleared. */        NONE,        /* Use statically configured proxy. Configuration can be accessed         * with linkProperties */        STATIC,        /* no proxy details are assigned, this is used to indicate         * that any existing proxy settings should be retained */        UNASSIGNED    }    /**     * @hide     */    public ProxySettings proxySettings;    /**     * @hide     */    public LinkProperties linkProperties;    /**     * Variable name used to set/get value from supplicant     * @hide     */    public static final String IMSI_VAR_NAME = "imsi";    /**     * Variable name used to set/get value from supplicant     * @hide     */    public static final String SIMSLOT_VAR_NAME = "sim_slot";    /**     * Variable name used to set/get value from supplicant     * @hide     */    public static final String PCSC_VAR_NAME = "pcsc";    /**     * IMSI for EAP-SIM/EAP-AKA     * @hide     * @internal     */    public String imsi;    /**     * SIM slot for EAP-SIM/EAP-AKA     * @hide     * @internal     */    public String simSlot;    /**     * PCSC for EAP-SIM/EAP-AKA     * @hide     * @internal     */    public String pcsc;    /**     * The preferred channel for AP     * @hide     * @internal     */    public int channel;    /**     * The channel bandwidth for AP. 0: 20MHz only 1: Auto 20/40 Mhz     * @hide     * @internal     */    public int channelWidth;    public WifiConfiguration() {        networkId = INVALID_NETWORK_ID;        SSID = null;        BSSID = null;        priority = 0;        hiddenSSID = false;        disableReason = DISABLED_UNKNOWN_REASON;        allowedKeyManagement = new BitSet();        allowedProtocols = new BitSet();        allowedAuthAlgorithms = new BitSet();        allowedPairwiseCiphers = new BitSet();        allowedGroupCiphers = new BitSet();        wepKeys = new String[4];        for (int i = 0; i < wepKeys.length; i++)            wepKeys[i] = null;        for (EnterpriseField field : enterpriseFields) {            field.setValue(null);        }        ipAssignment = IpAssignment.UNASSIGNED;        proxySettings = ProxySettings.UNASSIGNED;        linkProperties = new LinkProperties();        if (FeatureOption.MTK_EAP_SIM_AKA) {            imsi = null;            simSlot = null;            pcsc = null;        }        channel = 0;        channelWidth = 1;    }    @Override    public String toString() {        StringBuilder sbuf = new StringBuilder();        if (this.status == WifiConfiguration.Status.CURRENT) {            sbuf.append("* ");        } else if (this.status == WifiConfiguration.Status.DISABLED) {            sbuf.append("- DSBLE: ").append(this.disableReason).append(" ");        }        sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID).                append(" BSSID: ").append(this.BSSID).append(" PRIO: ").append(this.priority).                append('\n');        sbuf.append(" KeyMgmt:");        for (int k = 0; k < this.allowedKeyManagement.size(); k++) {            if (this.allowedKeyManagement.get(k)) {                sbuf.append(" ");                if (k < KeyMgmt.strings.length) {                    sbuf.append(KeyMgmt.strings[k]);                } else {                    sbuf.append("??");                }            }        }        sbuf.append(" Protocols:");        for (int p = 0; p < this.allowedProtocols.size(); p++) {            if (this.allowedProtocols.get(p)) {                sbuf.append(" ");                if (p < Protocol.strings.length) {                    sbuf.append(Protocol.strings[p]);                } else {                    sbuf.append("??");                }            }        }        sbuf.append('\n');        sbuf.append(" AuthAlgorithms:");        for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) {            if (this.allowedAuthAlgorithms.get(a)) {                sbuf.append(" ");                if (a < AuthAlgorithm.strings.length) {                    sbuf.append(AuthAlgorithm.strings[a]);                } else {                    sbuf.append("??");                }            }        }        sbuf.append('\n');        sbuf.append(" PairwiseCiphers:");        for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) {            if (this.allowedPairwiseCiphers.get(pc)) {                sbuf.append(" ");                if (pc < PairwiseCipher.strings.length) {                    sbuf.append(PairwiseCipher.strings[pc]);                } else {                    sbuf.append("??");                }            }        }        sbuf.append('\n');        sbuf.append(" GroupCiphers:");        for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) {            if (this.allowedGroupCiphers.get(gc)) {                sbuf.append(" ");                if (gc < GroupCipher.strings.length) {                    sbuf.append(GroupCipher.strings[gc]);                } else {                    sbuf.append("??");                }            }        }        sbuf.append('\n').append(" PSK: ");        if (this.preSharedKey != null) {            sbuf.append('*');        }        for (EnterpriseField field : enterpriseFields) {            sbuf.append('\n').append(" " + field.varName() + ": ");            String value = field.value();            if (value != null) sbuf.append(value);        }        sbuf.append('\n');        sbuf.append("IP assignment: " + ipAssignment.toString());        sbuf.append("\n");        sbuf.append("Proxy settings: " + proxySettings.toString());        sbuf.append("\n");        sbuf.append(linkProperties.toString());        sbuf.append("\n");        if (FeatureOption.MTK_EAP_SIM_AKA) {            sbuf.append(" imsi: ").append(this.imsi);            sbuf.append(" simSlot: ").append(this.simSlot);            sbuf.append(" pcsc: ").append(this.pcsc).append('\n');        }        sbuf.append("Channel: ").append(this.channel).append(" ChannelWidth: ").append(this.channelWidth).append('\n');        return sbuf.toString();    }    /**     * Construct a WifiConfiguration from a scanned network     * @param scannedAP the scan result used to construct the config entry     * TODO: figure out whether this is a useful way to construct a new entry.     *    public WifiConfiguration(ScanResult scannedAP) {        networkId = -1;        SSID = scannedAP.SSID;        BSSID = scannedAP.BSSID;    }    */    /** {@hide} */    public String getPrintableSsid() {        if (SSID == null) return "";        final int length = SSID.length();        if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') {            return SSID.substring(1, length - 1);        }        /** The ascii-encoded string format is P"<ascii-encoded-string>"         * The decoding is implemented in the supplicant for a newly configured         * network.         */        if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') &&                (SSID.charAt(length-1) == '"')) {            WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(                    SSID.substring(2, length - 1));            return wifiSsid.toString();        }        return SSID;    }    private static BitSet readBitSet(Parcel src) {        int cardinality = src.readInt();        BitSet set = new BitSet();        for (int i = 0; i < cardinality; i++)            set.set(src.readInt());        return set;    }    private static void writeBitSet(Parcel dest, BitSet set) {        int nextSetBit = -1;        dest.writeInt(set.cardinality());        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1)            dest.writeInt(nextSetBit);    }    /** @hide */    public int getAuthType() {        if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {            return KeyMgmt.WPA_PSK;        } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) {            return KeyMgmt.WPA2_PSK;        } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {            return KeyMgmt.WPA_EAP;        } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {            return KeyMgmt.IEEE8021X;        }        return KeyMgmt.NONE;    }    /** Implement the Parcelable interface {@hide} */    public int describeContents() {        return 0;    }    /** copy constructor {@hide} */    public WifiConfiguration(WifiConfiguration source) {        if (source != null) {            networkId = source.networkId;            status = source.status;            disableReason = source.disableReason;            SSID = source.SSID;            BSSID = source.BSSID;            preSharedKey = source.preSharedKey;            wepKeys = new String[4];            for (int i = 0; i < wepKeys.length; i++)                wepKeys[i] = source.wepKeys[i];            wepTxKeyIndex = source.wepTxKeyIndex;            priority = source.priority;            hiddenSSID = source.hiddenSSID;            allowedKeyManagement   = (BitSet) source.allowedKeyManagement.clone();            allowedProtocols       = (BitSet) source.allowedProtocols.clone();            allowedAuthAlgorithms  = (BitSet) source.allowedAuthAlgorithms.clone();            allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone();            allowedGroupCiphers    = (BitSet) source.allowedGroupCiphers.clone();            for (int i = 0; i < source.enterpriseFields.length; i++) {                enterpriseFields[i].setValue(source.enterpriseFields[i].value());            }            ipAssignment = source.ipAssignment;            proxySettings = source.proxySettings;            linkProperties = new LinkProperties(source.linkProperties);                        if (FeatureOption.MTK_EAP_SIM_AKA) {                imsi = source.imsi;                simSlot = source.simSlot;                pcsc = source.pcsc;            }            channel = source.channel;            channelWidth = source.channelWidth;        }    }    /** Implement the Parcelable interface {@hide} */    public void writeToParcel(Parcel dest, int flags) {        dest.writeInt(networkId);        dest.writeInt(status);        dest.writeInt(disableReason);        dest.writeString(SSID);        dest.writeString(BSSID);        dest.writeString(preSharedKey);        for (String wepKey : wepKeys)            dest.writeString(wepKey);        dest.writeInt(wepTxKeyIndex);        dest.writeInt(priority);        dest.writeInt(hiddenSSID ? 1 : 0);        writeBitSet(dest, allowedKeyManagement);        writeBitSet(dest, allowedProtocols);        writeBitSet(dest, allowedAuthAlgorithms);        writeBitSet(dest, allowedPairwiseCiphers);        writeBitSet(dest, allowedGroupCiphers);        for (EnterpriseField field : enterpriseFields) {            dest.writeString(field.value());        }        dest.writeString(ipAssignment.name());        dest.writeString(proxySettings.name());        dest.writeParcelable(linkProperties, flags);        if (FeatureOption.MTK_EAP_SIM_AKA) {            dest.writeString(imsi);            dest.writeString(simSlot);            dest.writeString(pcsc);        }        dest.writeInt(channel);        dest.writeInt(channelWidth);    }    /** Implement the Parcelable interface {@hide} */    public static final Creator<WifiConfiguration> CREATOR =        new Creator<WifiConfiguration>() {            public WifiConfiguration createFromParcel(Parcel in) {                WifiConfiguration config = new WifiConfiguration();                config.networkId = in.readInt();                config.status = in.readInt();                config.disableReason = in.readInt();                config.SSID = in.readString();                config.BSSID = in.readString();                config.preSharedKey = in.readString();                for (int i = 0; i < config.wepKeys.length; i++)                    config.wepKeys[i] = in.readString();                config.wepTxKeyIndex = in.readInt();                config.priority = in.readInt();                config.hiddenSSID = in.readInt() != 0;                config.allowedKeyManagement   = readBitSet(in);                config.allowedProtocols       = readBitSet(in);                config.allowedAuthAlgorithms  = readBitSet(in);                config.allowedPairwiseCiphers = readBitSet(in);                config.allowedGroupCiphers    = readBitSet(in);                for (EnterpriseField field : config.enterpriseFields) {                    field.setValue(in.readString());                }                config.ipAssignment = IpAssignment.valueOf(in.readString());                config.proxySettings = ProxySettings.valueOf(in.readString());                config.linkProperties = in.readParcelable(null);                if (FeatureOption.MTK_EAP_SIM_AKA) {                    config.imsi = in.readString();                    config.simSlot = in.readString();                    config.pcsc = in.readString();                }                config.channel = in.readInt();                config.channelWidth = in.readInt();                return config;            }            public WifiConfiguration[] newArray(int size) {                return new WifiConfiguration[size];            }        };}

alps/frameworks/base/wifi/java/android/net/wifi/WifiManager.java

0 1
原创粉丝点击