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:
*
* - The list of configured networks. The list can be viewed and updated,
* and attributes of individual entries can be modified.
* - 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.
* - Results of access point scans, containing enough information to
* make decisions about what access point to connect to.
* - It defines the names of various Intent actions that are broadcast
* upon any sort of change in Wi-Fi state.
*
* 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.
* Input: Nothing.
*
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.
*
* 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.
*
* 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:
*
* - networkId
* - SSID
* - BSSID
* - priority
* - allowedProtocols
* - allowedKeyManagement
* - allowedAuthAlgorithms
* - allowedPairwiseCiphers
* - allowedGroupCiphers
*
* @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 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.
*
* 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-null
. 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.
*
* 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
* disableOthers
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 getScanResults() {
try {
return mService.getScanResults();
} catch (RemoteException e) {
return null;
}
}
/**
* Tell the supplicant to persist the current list of configured networks.
*
* 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.
*
* 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.
*
* 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.
*
* Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK}
* permission in an {@code } 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 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.
*
* 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)
*
*/
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.,
* XX:XX:XX:XX:XX:XX
where each X
is a hex digit.
*/
public String BSSID;
/**
* Pre-shared key for use with WPA-PSK.
*
* 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}).
*
* 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""
* 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 CREATOR =
new Creator() {
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