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
alps/frameworks/base/wifi/java/android/net/wifi/WifiManager.java , WifiConfiguration.java [v4.2.2]