Remove AP persist settings Add new netd interface Handle errors Handle AP config change Bug: 2413908 Change-Id: I31a1221ef5479da8d4a2620f0f0ee0b62539bc69
1216 lines
43 KiB
Java
1216 lines
43 KiB
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.net.DhcpInfo;
|
|
import android.os.Binder;
|
|
import android.os.IBinder;
|
|
import android.os.Handler;
|
|
import android.os.RemoteException;
|
|
|
|
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 {
|
|
|
|
// 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
|
|
*/
|
|
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
|
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 = 0;
|
|
/**
|
|
* Wi-Fi AP is disabled.
|
|
*
|
|
* @see #WIFI_AP_STATE_CHANGED_ACTION
|
|
* @see #getWifiState()
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int WIFI_AP_STATE_DISABLED = 1;
|
|
/**
|
|
* 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 = 2;
|
|
/**
|
|
* Wi-Fi AP is enabled.
|
|
*
|
|
* @see #WIFI_AP_STATE_CHANGED_ACTION
|
|
* @see #getWifiApState()
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int WIFI_AP_STATE_ENABLED = 3;
|
|
/**
|
|
* 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 = 4;
|
|
|
|
/**
|
|
* 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, a second extra may provide the BSSID of the access point,
|
|
* as a {@code String}.
|
|
* @see #EXTRA_NETWORK_INFO
|
|
* @see #EXTRA_BSSID
|
|
*/
|
|
@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";
|
|
/**
|
|
* 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";
|
|
|
|
/**
|
|
* 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";
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/** 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;
|
|
|
|
IWifiManager mService;
|
|
Handler mHandler;
|
|
|
|
/* 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;
|
|
|
|
/**
|
|
* 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 service the Binder interface
|
|
* @param handler target for messages
|
|
* @hide - hide this because it takes in a parameter of type IWifiManager, which
|
|
* is a system private class.
|
|
*/
|
|
public WifiManager(IWifiManager service, Handler handler) {
|
|
mService = service;
|
|
mHandler = handler;
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
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 {
|
|
return mService.disconnect();
|
|
} 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 {
|
|
return mService.reconnect();
|
|
} 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 {
|
|
return mService.reassociate();
|
|
} 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 {
|
|
return mService.startScan(false);
|
|
} 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 {
|
|
return mService.startScan(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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return the number of frequency channels that are allowed
|
|
* to be used in the current regulatory domain.
|
|
* @return the number of allowed channels, or {@code -1} if an error occurs
|
|
*
|
|
* @hide pending API council
|
|
*/
|
|
public int getNumAllowedChannels() {
|
|
try {
|
|
return mService.getNumAllowedChannels();
|
|
} catch (RemoteException e) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the number of frequency channels that are allowed to be used
|
|
* in the current regulatory domain. This method should be used only
|
|
* if the correct number of channels cannot be determined automatically
|
|
* for some reason.
|
|
* @param numChannels the number of allowed channels. Must be greater than 0
|
|
* and less than or equal to 16.
|
|
* @param persist {@code true} if you want this remembered
|
|
* @return {@code true} if the operation succeeds, {@code false} otherwise, e.g.,
|
|
* {@code numChannels} is out of range.
|
|
*
|
|
* @hide pending API council
|
|
*/
|
|
public boolean setNumAllowedChannels(int numChannels, boolean persist) {
|
|
try {
|
|
return mService.setNumAllowedChannels(numChannels, persist);
|
|
} catch (RemoteException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return the list of valid values for the number of allowed radio channels
|
|
* for various regulatory domains.
|
|
* @return the list of channel counts, or {@code null} if the operation fails
|
|
*
|
|
* @hide pending API council review
|
|
*/
|
|
public int[] getValidChannelCounts() {
|
|
try {
|
|
return mService.getValidChannelCounts();
|
|
} catch (RemoteException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* 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 {
|
|
int partitionSize = (MAX_RSSI - MIN_RSSI) / (numLevels - 1);
|
|
return (rssi - MIN_RSSI) / partitionSize;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 {
|
|
return mService.setWifiApEnabled(wifiConfig, enabled);
|
|
} 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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
public class WifiLock {
|
|
private String mTag;
|
|
private final IBinder mBinder;
|
|
private int mRefCount;
|
|
int mLockType;
|
|
private boolean mRefCounted;
|
|
private boolean mHeld;
|
|
|
|
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 > 0) : (!mHeld)) {
|
|
try {
|
|
mService.acquireWifiLock(mBinder, mLockType, mTag);
|
|
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 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} 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 > 0) : (!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;
|
|
}
|
|
}
|
|
}
|