Roll android_tools support library to 25.1.0
[android_tools.git] / sdk / sources / android-23 / android / net / wifi / WifiManager.java
blobcf88df42f8d34248945881d6ff767be9eee311d6
1 /*
2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package android.net.wifi;
19 import android.annotation.SdkConstant;
20 import android.annotation.SdkConstant.SdkConstantType;
21 import android.annotation.SystemApi;
22 import android.content.Context;
23 import android.net.ConnectivityManager;
24 import android.net.ConnectivityManager.NetworkCallback;
25 import android.net.DhcpInfo;
26 import android.net.Network;
27 import android.net.NetworkCapabilities;
28 import android.net.NetworkRequest;
29 import android.net.wifi.ScanSettings;
30 import android.net.wifi.WifiChannel;
31 import android.os.Binder;
32 import android.os.Build;
33 import android.os.IBinder;
34 import android.os.Handler;
35 import android.os.HandlerThread;
36 import android.os.Looper;
37 import android.os.Message;
38 import android.os.RemoteException;
39 import android.os.WorkSource;
40 import android.os.Messenger;
41 import android.util.Log;
42 import android.util.SparseArray;
44 import java.net.InetAddress;
45 import java.util.concurrent.CountDownLatch;
47 import com.android.internal.annotations.GuardedBy;
48 import com.android.internal.util.AsyncChannel;
49 import com.android.internal.util.Protocol;
51 import java.util.List;
53 /**
54 * This class provides the primary API for managing all aspects of Wi-Fi
55 * connectivity. Get an instance of this class by calling
56 * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.WIFI_SERVICE)}.
58 * It deals with several categories of items:
59 * <ul>
60 * <li>The list of configured networks. The list can be viewed and updated,
61 * and attributes of individual entries can be modified.</li>
62 * <li>The currently active Wi-Fi network, if any. Connectivity can be
63 * established or torn down, and dynamic information about the state of
64 * the network can be queried.</li>
65 * <li>Results of access point scans, containing enough information to
66 * make decisions about what access point to connect to.</li>
67 * <li>It defines the names of various Intent actions that are broadcast
68 * upon any sort of change in Wi-Fi state.
69 * </ul>
70 * This is the API to use when performing Wi-Fi specific operations. To
71 * perform operations that pertain to network connectivity at an abstract
72 * level, use {@link android.net.ConnectivityManager}.
74 public class WifiManager {
76 private static final String TAG = "WifiManager";
77 // Supplicant error codes:
78 /**
79 * The error code if there was a problem authenticating.
81 public static final int ERROR_AUTHENTICATING = 1;
83 /**
84 * Broadcast intent action indicating whether Wi-Fi scanning is allowed currently
85 * @hide
87 public static final String WIFI_SCAN_AVAILABLE = "wifi_scan_available";
89 /**
90 * Extra int indicating scan availability, WIFI_STATE_ENABLED and WIFI_STATE_DISABLED
91 * @hide
93 public static final String EXTRA_SCAN_AVAILABLE = "scan_enabled";
95 /**
96 * Broadcast intent action indicating that the credential of a Wi-Fi network
97 * has been changed. One extra provides the ssid of the network. Another
98 * extra provides the event type, whether the credential is saved or forgot.
99 * @hide
101 @SystemApi
102 public static final String WIFI_CREDENTIAL_CHANGED_ACTION =
103 "android.net.wifi.WIFI_CREDENTIAL_CHANGED";
104 /** @hide */
105 @SystemApi
106 public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
107 /** @hide */
108 @SystemApi
109 public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid";
110 /** @hide */
111 @SystemApi
112 public static final int WIFI_CREDENTIAL_SAVED = 0;
113 /** @hide */
114 @SystemApi
115 public static final int WIFI_CREDENTIAL_FORGOT = 1;
118 * Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
119 * enabling, disabling, or unknown. One extra provides this state as an int.
120 * Another extra provides the previous state, if available.
122 * @see #EXTRA_WIFI_STATE
123 * @see #EXTRA_PREVIOUS_WIFI_STATE
125 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
126 public static final String WIFI_STATE_CHANGED_ACTION =
127 "android.net.wifi.WIFI_STATE_CHANGED";
129 * The lookup key for an int that indicates whether Wi-Fi is enabled,
130 * disabled, enabling, disabling, or unknown. Retrieve it with
131 * {@link android.content.Intent#getIntExtra(String,int)}.
133 * @see #WIFI_STATE_DISABLED
134 * @see #WIFI_STATE_DISABLING
135 * @see #WIFI_STATE_ENABLED
136 * @see #WIFI_STATE_ENABLING
137 * @see #WIFI_STATE_UNKNOWN
139 public static final String EXTRA_WIFI_STATE = "wifi_state";
141 * The previous Wi-Fi state.
143 * @see #EXTRA_WIFI_STATE
145 public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
148 * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if
149 * it finishes successfully.
151 * @see #WIFI_STATE_CHANGED_ACTION
152 * @see #getWifiState()
154 public static final int WIFI_STATE_DISABLING = 0;
156 * Wi-Fi is disabled.
158 * @see #WIFI_STATE_CHANGED_ACTION
159 * @see #getWifiState()
161 public static final int WIFI_STATE_DISABLED = 1;
163 * Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if
164 * it finishes successfully.
166 * @see #WIFI_STATE_CHANGED_ACTION
167 * @see #getWifiState()
169 public static final int WIFI_STATE_ENABLING = 2;
171 * Wi-Fi is enabled.
173 * @see #WIFI_STATE_CHANGED_ACTION
174 * @see #getWifiState()
176 public static final int WIFI_STATE_ENABLED = 3;
178 * Wi-Fi is in an unknown state. This state will occur when an error happens while enabling
179 * or disabling.
181 * @see #WIFI_STATE_CHANGED_ACTION
182 * @see #getWifiState()
184 public static final int WIFI_STATE_UNKNOWN = 4;
187 * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled,
188 * enabling, disabling, or failed.
190 * @hide
192 public static final String WIFI_AP_STATE_CHANGED_ACTION =
193 "android.net.wifi.WIFI_AP_STATE_CHANGED";
196 * The lookup key for an int that indicates whether Wi-Fi AP is enabled,
197 * disabled, enabling, disabling, or failed. Retrieve it with
198 * {@link android.content.Intent#getIntExtra(String,int)}.
200 * @see #WIFI_AP_STATE_DISABLED
201 * @see #WIFI_AP_STATE_DISABLING
202 * @see #WIFI_AP_STATE_ENABLED
203 * @see #WIFI_AP_STATE_ENABLING
204 * @see #WIFI_AP_STATE_FAILED
206 * @hide
208 public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
211 * The look up key for an int that indicates why softAP started failed
212 * currently support general and no_channel
213 * @see #SAP_START_FAILURE_GENERAL
214 * @see #SAP_START_FAILURE_NO_CHANNEL
216 * @hide
218 public static final String EXTRA_WIFI_AP_FAILURE_REASON = "wifi_ap_error_code";
220 * The previous Wi-Fi state.
222 * @see #EXTRA_WIFI_AP_STATE
224 * @hide
226 public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
228 * Wi-Fi AP is currently being disabled. The state will change to
229 * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully.
231 * @see #WIFI_AP_STATE_CHANGED_ACTION
232 * @see #getWifiApState()
234 * @hide
236 public static final int WIFI_AP_STATE_DISABLING = 10;
238 * Wi-Fi AP is disabled.
240 * @see #WIFI_AP_STATE_CHANGED_ACTION
241 * @see #getWifiState()
243 * @hide
245 public static final int WIFI_AP_STATE_DISABLED = 11;
247 * Wi-Fi AP is currently being enabled. The state will change to
248 * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully.
250 * @see #WIFI_AP_STATE_CHANGED_ACTION
251 * @see #getWifiApState()
253 * @hide
255 public static final int WIFI_AP_STATE_ENABLING = 12;
257 * Wi-Fi AP is enabled.
259 * @see #WIFI_AP_STATE_CHANGED_ACTION
260 * @see #getWifiApState()
262 * @hide
264 public static final int WIFI_AP_STATE_ENABLED = 13;
266 * Wi-Fi AP is in a failed state. This state will occur when an error occurs during
267 * enabling or disabling
269 * @see #WIFI_AP_STATE_CHANGED_ACTION
270 * @see #getWifiApState()
272 * @hide
274 public static final int WIFI_AP_STATE_FAILED = 14;
277 * If WIFI AP start failed, this reason code means there is no legal channel exists on
278 * user selected band by regulatory
280 * @hide
282 public static final int SAP_START_FAILURE_GENERAL= 0;
285 * All other reason for AP start failed besides SAP_START_FAILURE_GENERAL
287 * @hide
289 public static final int SAP_START_FAILURE_NO_CHANNEL = 1;
291 * Broadcast intent action indicating that a connection to the supplicant has
292 * been established (and it is now possible
293 * to perform Wi-Fi operations) or the connection to the supplicant has been
294 * lost. One extra provides the connection state as a boolean, where {@code true}
295 * means CONNECTED.
296 * @see #EXTRA_SUPPLICANT_CONNECTED
298 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
299 public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION =
300 "android.net.wifi.supplicant.CONNECTION_CHANGE";
302 * The lookup key for a boolean that indicates whether a connection to
303 * the supplicant daemon has been gained or lost. {@code true} means
304 * a connection now exists.
305 * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
307 public static final String EXTRA_SUPPLICANT_CONNECTED = "connected";
309 * Broadcast intent action indicating that the state of Wi-Fi connectivity
310 * has changed. One extra provides the new state
311 * in the form of a {@link android.net.NetworkInfo} object. If the new
312 * state is CONNECTED, additional extras may provide the BSSID and WifiInfo of
313 * the access point.
314 * as a {@code String}.
315 * @see #EXTRA_NETWORK_INFO
316 * @see #EXTRA_BSSID
317 * @see #EXTRA_WIFI_INFO
319 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
320 public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
322 * The lookup key for a {@link android.net.NetworkInfo} object associated with the
323 * Wi-Fi network. Retrieve with
324 * {@link android.content.Intent#getParcelableExtra(String)}.
326 public static final String EXTRA_NETWORK_INFO = "networkInfo";
328 * The lookup key for a String giving the BSSID of the access point to which
329 * we are connected. Only present when the new state is CONNECTED.
330 * Retrieve with
331 * {@link android.content.Intent#getStringExtra(String)}.
333 public static final String EXTRA_BSSID = "bssid";
335 * The lookup key for a {@link android.net.wifi.WifiInfo} object giving the
336 * information about the access point to which we are connected. Only present
337 * when the new state is CONNECTED. Retrieve with
338 * {@link android.content.Intent#getParcelableExtra(String)}.
340 public static final String EXTRA_WIFI_INFO = "wifiInfo";
342 * Broadcast intent action indicating that the state of establishing a connection to
343 * an access point has changed.One extra provides the new
344 * {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and
345 * is not generally the most useful thing to look at if you are just interested in
346 * the overall state of connectivity.
347 * @see #EXTRA_NEW_STATE
348 * @see #EXTRA_SUPPLICANT_ERROR
350 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
351 public static final String SUPPLICANT_STATE_CHANGED_ACTION =
352 "android.net.wifi.supplicant.STATE_CHANGE";
354 * The lookup key for a {@link SupplicantState} describing the new state
355 * Retrieve with
356 * {@link android.content.Intent#getParcelableExtra(String)}.
358 public static final String EXTRA_NEW_STATE = "newState";
361 * The lookup key for a {@link SupplicantState} describing the supplicant
362 * error code if any
363 * Retrieve with
364 * {@link android.content.Intent#getIntExtra(String, int)}.
365 * @see #ERROR_AUTHENTICATING
367 public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
370 * Broadcast intent action indicating that the configured networks changed.
371 * This can be as a result of adding/updating/deleting a network. If
372 * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set to true the new configuration
373 * can be retreived with the {@link #EXTRA_WIFI_CONFIGURATION} extra. If multiple
374 * Wi-Fi configurations changed, {@link #EXTRA_WIFI_CONFIGURATION} will not be present.
375 * @hide
377 @SystemApi
378 public static final String CONFIGURED_NETWORKS_CHANGED_ACTION =
379 "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
381 * The lookup key for a (@link android.net.wifi.WifiConfiguration} object representing
382 * the changed Wi-Fi configuration when the {@link #CONFIGURED_NETWORKS_CHANGED_ACTION}
383 * broadcast is sent.
384 * @hide
386 @SystemApi
387 public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
389 * Multiple network configurations have changed.
390 * @see #CONFIGURED_NETWORKS_CHANGED_ACTION
392 * @hide
394 @SystemApi
395 public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
397 * The lookup key for an integer indicating the reason a Wi-Fi network configuration
398 * has changed. Only present if {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is {@code false}
399 * @see #CONFIGURED_NETWORKS_CHANGED_ACTION
400 * @hide
402 @SystemApi
403 public static final String EXTRA_CHANGE_REASON = "changeReason";
405 * The configuration is new and was added.
406 * @hide
408 @SystemApi
409 public static final int CHANGE_REASON_ADDED = 0;
411 * The configuration was removed and is no longer present in the system's list of
412 * configured networks.
413 * @hide
415 @SystemApi
416 public static final int CHANGE_REASON_REMOVED = 1;
418 * The configuration has changed as a result of explicit action or because the system
419 * took an automated action such as disabling a malfunctioning configuration.
420 * @hide
422 @SystemApi
423 public static final int CHANGE_REASON_CONFIG_CHANGE = 2;
425 * An access point scan has completed, and results are available from the supplicant.
426 * Call {@link #getScanResults()} to obtain the results. {@link #EXTRA_RESULTS_UPDATED}
427 * indicates if the scan was completed successfully.
429 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
430 public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
433 * Lookup key for a {@code boolean} representing the result of previous {@link #startScan}
434 * operation, reported with {@link #SCAN_RESULTS_AVAILABLE_ACTION}.
435 * @return true scan was successful, results are updated
436 * @return false scan was not successful, results haven't been updated since previous scan
438 public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated";
441 * A batch of access point scans has been completed and the results areavailable.
442 * Call {@link #getBatchedScanResults()} to obtain the results.
443 * @hide pending review
445 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
446 public static final String BATCHED_SCAN_RESULTS_AVAILABLE_ACTION =
447 "android.net.wifi.BATCHED_RESULTS";
449 * The RSSI (signal strength) has changed.
450 * @see #EXTRA_NEW_RSSI
452 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
453 public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
455 * The lookup key for an {@code int} giving the new RSSI in dBm.
457 public static final String EXTRA_NEW_RSSI = "newRssi";
460 * Broadcast intent action indicating that the link configuration
461 * changed on wifi.
462 * @hide
464 public static final String LINK_CONFIGURATION_CHANGED_ACTION =
465 "android.net.wifi.LINK_CONFIGURATION_CHANGED";
468 * The lookup key for a {@link android.net.LinkProperties} object associated with the
469 * Wi-Fi network. Retrieve with
470 * {@link android.content.Intent#getParcelableExtra(String)}.
471 * @hide
473 public static final String EXTRA_LINK_PROPERTIES = "linkProperties";
476 * The lookup key for a {@link android.net.NetworkCapabilities} object associated with the
477 * Wi-Fi network. Retrieve with
478 * {@link android.content.Intent#getParcelableExtra(String)}.
479 * @hide
481 public static final String EXTRA_NETWORK_CAPABILITIES = "networkCapabilities";
484 * The network IDs of the configured networks could have changed.
486 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
487 public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
490 * Activity Action: Show a system activity that allows the user to enable
491 * scans to be available even with Wi-Fi turned off.
493 * <p>Notification of the result of this activity is posted using the
494 * {@link android.app.Activity#onActivityResult} callback. The
495 * <code>resultCode</code>
496 * will be {@link android.app.Activity#RESULT_OK} if scan always mode has
497 * been turned on or {@link android.app.Activity#RESULT_CANCELED} if the user
498 * has rejected the request or an error has occurred.
500 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
501 public static final String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE =
502 "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
505 * Activity Action: Pick a Wi-Fi network to connect to.
506 * <p>Input: Nothing.
507 * <p>Output: Nothing.
509 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
510 public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
513 * In this Wi-Fi lock mode, Wi-Fi will be kept active,
514 * and will behave normally, i.e., it will attempt to automatically
515 * establish a connection to a remembered access point that is
516 * within range, and will do periodic scans if there are remembered
517 * access points but none are in range.
519 public static final int WIFI_MODE_FULL = 1;
521 * In this Wi-Fi lock mode, Wi-Fi will be kept active,
522 * but the only operation that will be supported is initiation of
523 * scans, and the subsequent reporting of scan results. No attempts
524 * will be made to automatically connect to remembered access points,
525 * nor will periodic scans be automatically performed looking for
526 * remembered access points. Scans must be explicitly requested by
527 * an application in this mode.
529 public static final int WIFI_MODE_SCAN_ONLY = 2;
531 * In this Wi-Fi lock mode, Wi-Fi will be kept active as in mode
532 * {@link #WIFI_MODE_FULL} but it operates at high performance
533 * with minimum packet loss and low packet latency even when
534 * the device screen is off. This mode will consume more power
535 * and hence should be used only when there is a need for such
536 * an active connection.
537 * <p>
538 * An example use case is when a voice connection needs to be
539 * kept active even after the device screen goes off. Holding the
540 * regular {@link #WIFI_MODE_FULL} lock will keep the wifi
541 * connection active, but the connection can be lossy.
542 * Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the
543 * duration of the voice call will improve the call quality.
544 * <p>
545 * When there is no support from the hardware, this lock mode
546 * will have the same behavior as {@link #WIFI_MODE_FULL}
548 public static final int WIFI_MODE_FULL_HIGH_PERF = 3;
550 /** Anything worse than or equal to this will show 0 bars. */
551 private static final int MIN_RSSI = -100;
553 /** Anything better than or equal to this will show the max bars. */
554 private static final int MAX_RSSI = -55;
557 * Number of RSSI levels used in the framework to initiate
558 * {@link #RSSI_CHANGED_ACTION} broadcast
559 * @hide
561 public static final int RSSI_LEVELS = 5;
564 * Auto settings in the driver. The driver could choose to operate on both
565 * 2.4 GHz and 5 GHz or make a dynamic decision on selecting the band.
566 * @hide
568 public static final int WIFI_FREQUENCY_BAND_AUTO = 0;
571 * Operation on 5 GHz alone
572 * @hide
574 public static final int WIFI_FREQUENCY_BAND_5GHZ = 1;
577 * Operation on 2.4 GHz alone
578 * @hide
580 public static final int WIFI_FREQUENCY_BAND_2GHZ = 2;
582 /** List of asyncronous notifications
583 * @hide
585 public static final int DATA_ACTIVITY_NOTIFICATION = 1;
587 //Lowest bit indicates data reception and the second lowest
588 //bit indicates data transmitted
589 /** @hide */
590 public static final int DATA_ACTIVITY_NONE = 0x00;
591 /** @hide */
592 public static final int DATA_ACTIVITY_IN = 0x01;
593 /** @hide */
594 public static final int DATA_ACTIVITY_OUT = 0x02;
595 /** @hide */
596 public static final int DATA_ACTIVITY_INOUT = 0x03;
598 /** @hide */
599 public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false;
601 /* Maximum number of active locks we allow.
602 * This limit was added to prevent apps from creating a ridiculous number
603 * of locks and crashing the system by overflowing the global ref table.
605 private static final int MAX_ACTIVE_LOCKS = 50;
607 /* Number of currently active WifiLocks and MulticastLocks */
608 private int mActiveLockCount;
610 private Context mContext;
611 IWifiManager mService;
612 private final int mTargetSdkVersion;
614 private static final int INVALID_KEY = 0;
615 private static int sListenerKey = 1;
616 private static final SparseArray sListenerMap = new SparseArray();
617 private static final Object sListenerMapLock = new Object();
619 private static AsyncChannel sAsyncChannel;
620 private static CountDownLatch sConnected;
621 private static ConnectivityManager sCM;
623 private static final Object sThreadRefLock = new Object();
624 private static int sThreadRefCount;
625 private static HandlerThread sHandlerThread;
627 @GuardedBy("sCM")
628 // TODO: Introduce refcounting and make this a per-process static callback, instead of a
629 // per-WifiManager callback.
630 private PinningNetworkCallback mNetworkCallback;
633 * Create a new WifiManager instance.
634 * Applications will almost always want to use
635 * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
636 * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}.
637 * @param context the application context
638 * @param service the Binder interface
639 * @hide - hide this because it takes in a parameter of type IWifiManager, which
640 * is a system private class.
642 public WifiManager(Context context, IWifiManager service) {
643 mContext = context;
644 mService = service;
645 mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
646 init();
650 * Return a list of all the networks configured in the supplicant.
651 * Not all fields of WifiConfiguration are returned. Only the following
652 * fields are filled in:
653 * <ul>
654 * <li>networkId</li>
655 * <li>SSID</li>
656 * <li>BSSID</li>
657 * <li>priority</li>
658 * <li>allowedProtocols</li>
659 * <li>allowedKeyManagement</li>
660 * <li>allowedAuthAlgorithms</li>
661 * <li>allowedPairwiseCiphers</li>
662 * <li>allowedGroupCiphers</li>
663 * </ul>
664 * @return a list of network configurations in the form of a list
665 * of {@link WifiConfiguration} objects. Upon failure to fetch or
666 * when when Wi-Fi is turned off, it can be null.
668 public List<WifiConfiguration> getConfiguredNetworks() {
669 try {
670 return mService.getConfiguredNetworks();
671 } catch (RemoteException e) {
672 Log.w(TAG, "Caught RemoteException trying to get configured networks: " + e);
673 return null;
677 /** @hide */
678 @SystemApi
679 public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
680 try {
681 return mService.getPrivilegedConfiguredNetworks();
682 } catch (RemoteException e) {
683 return null;
687 /** @hide */
688 @SystemApi
689 public WifiConnectionStatistics getConnectionStatistics() {
690 try {
691 return mService.getConnectionStatistics();
692 } catch (RemoteException e) {
693 return null;
698 * Returns a WifiConfiguration matching this ScanResult
699 * @param scanResult scanResult that represents the BSSID
700 * @return {@link WifiConfiguration} that matches this BSSID or null
701 * @hide
703 public WifiConfiguration getMatchingWifiConfig(ScanResult scanResult) {
704 try {
705 return mService.getMatchingWifiConfig(scanResult);
706 } catch (RemoteException e) {
707 return null;
712 * Add a new network description to the set of configured networks.
713 * The {@code networkId} field of the supplied configuration object
714 * is ignored.
715 * <p/>
716 * The new network will be marked DISABLED by default. To enable it,
717 * called {@link #enableNetwork}.
719 * @param config the set of variables that describe the configuration,
720 * contained in a {@link WifiConfiguration} object.
721 * @return the ID of the newly created network description. This is used in
722 * other operations to specified the network to be acted upon.
723 * Returns {@code -1} on failure.
725 public int addNetwork(WifiConfiguration config) {
726 if (config == null) {
727 return -1;
729 config.networkId = -1;
730 return addOrUpdateNetwork(config);
734 * Update the network description of an existing configured network.
736 * @param config the set of variables that describe the configuration,
737 * contained in a {@link WifiConfiguration} object. It may
738 * be sparse, so that only the items that are being changed
739 * are non-<code>null</code>. The {@code networkId} field
740 * must be set to the ID of the existing network being updated.
741 * @return Returns the {@code networkId} of the supplied
742 * {@code WifiConfiguration} on success.
743 * <br/>
744 * Returns {@code -1} on failure, including when the {@code networkId}
745 * field of the {@code WifiConfiguration} does not refer to an
746 * existing network.
748 public int updateNetwork(WifiConfiguration config) {
749 if (config == null || config.networkId < 0) {
750 return -1;
752 return addOrUpdateNetwork(config);
756 * Internal method for doing the RPC that creates a new network description
757 * or updates an existing one.
759 * @param config The possibly sparse object containing the variables that
760 * are to set or updated in the network description.
761 * @return the ID of the network on success, {@code -1} on failure.
763 private int addOrUpdateNetwork(WifiConfiguration config) {
764 try {
765 return mService.addOrUpdateNetwork(config);
766 } catch (RemoteException e) {
767 return -1;
772 * Remove the specified network from the list of configured networks.
773 * This may result in the asynchronous delivery of state change
774 * events.
775 * @param netId the integer that identifies the network configuration
776 * to the supplicant
777 * @return {@code true} if the operation succeeded
779 public boolean removeNetwork(int netId) {
780 try {
781 return mService.removeNetwork(netId);
782 } catch (RemoteException e) {
783 return false;
788 * Allow a previously configured network to be associated with. If
789 * <code>disableOthers</code> is true, then all other configured
790 * networks are disabled, and an attempt to connect to the selected
791 * network is initiated. This may result in the asynchronous delivery
792 * of state change events.
793 * <p>
794 * <b>Note:</b> If an application's target SDK version is
795 * {@link android.os.Build.VERSION_CODES#LOLLIPOP} or newer, network
796 * communication may not use Wi-Fi even if Wi-Fi is connected; traffic may
797 * instead be sent through another network, such as cellular data,
798 * Bluetooth tethering, or Ethernet. For example, traffic will never use a
799 * Wi-Fi network that does not provide Internet access (e.g. a wireless
800 * printer), if another network that does offer Internet access (e.g.
801 * cellular data) is available. Applications that need to ensure that their
802 * network traffic uses Wi-Fi should use APIs such as
803 * {@link Network#bindSocket(java.net.Socket)},
804 * {@link Network#openConnection(java.net.URL)}, or
805 * {@link ConnectivityManager#bindProcessToNetwork} to do so.
807 * @param netId the ID of the network in the list of configured networks
808 * @param disableOthers if true, disable all other networks. The way to
809 * select a particular network to connect to is specify {@code true}
810 * for this parameter.
811 * @return {@code true} if the operation succeeded
813 public boolean enableNetwork(int netId, boolean disableOthers) {
814 final boolean pin = disableOthers && mTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP;
815 if (pin) {
816 registerPinningNetworkCallback();
819 boolean success;
820 try {
821 success = mService.enableNetwork(netId, disableOthers);
822 } catch (RemoteException e) {
823 success = false;
826 if (pin && !success) {
827 unregisterPinningNetworkCallback();
830 return success;
834 * Disable a configured network. The specified network will not be
835 * a candidate for associating. This may result in the asynchronous
836 * delivery of state change events.
837 * @param netId the ID of the network as returned by {@link #addNetwork}.
838 * @return {@code true} if the operation succeeded
840 public boolean disableNetwork(int netId) {
841 try {
842 return mService.disableNetwork(netId);
843 } catch (RemoteException e) {
844 return false;
849 * Disassociate from the currently active access point. This may result
850 * in the asynchronous delivery of state change events.
851 * @return {@code true} if the operation succeeded
853 public boolean disconnect() {
854 try {
855 mService.disconnect();
856 return true;
857 } catch (RemoteException e) {
858 return false;
863 * Reconnect to the currently active access point, if we are currently
864 * disconnected. This may result in the asynchronous delivery of state
865 * change events.
866 * @return {@code true} if the operation succeeded
868 public boolean reconnect() {
869 try {
870 mService.reconnect();
871 return true;
872 } catch (RemoteException e) {
873 return false;
878 * Reconnect to the currently active access point, even if we are already
879 * connected. This may result in the asynchronous delivery of state
880 * change events.
881 * @return {@code true} if the operation succeeded
883 public boolean reassociate() {
884 try {
885 mService.reassociate();
886 return true;
887 } catch (RemoteException e) {
888 return false;
893 * Check that the supplicant daemon is responding to requests.
894 * @return {@code true} if we were able to communicate with the supplicant and
895 * it returned the expected response to the PING message.
897 public boolean pingSupplicant() {
898 if (mService == null)
899 return false;
900 try {
901 return mService.pingSupplicant();
902 } catch (RemoteException e) {
903 return false;
908 * Get a list of available channels for customized scan.
910 * @see {@link WifiChannel}
912 * @return the channel list, or null if not available
913 * @hide
915 public List<WifiChannel> getChannelList() {
916 try {
917 return mService.getChannelList();
918 } catch (RemoteException e) {
919 return null;
923 /* Keep this list in sync with wifi_hal.h */
924 /** @hide */
925 public static final int WIFI_FEATURE_INFRA = 0x0001; // Basic infrastructure mode
926 /** @hide */
927 public static final int WIFI_FEATURE_INFRA_5G = 0x0002; // Support for 5 GHz Band
928 /** @hide */
929 public static final int WIFI_FEATURE_PASSPOINT = 0x0004; // Support for GAS/ANQP
930 /** @hide */
931 public static final int WIFI_FEATURE_P2P = 0x0008; // Wifi-Direct
932 /** @hide */
933 public static final int WIFI_FEATURE_MOBILE_HOTSPOT = 0x0010; // Soft AP
934 /** @hide */
935 public static final int WIFI_FEATURE_SCANNER = 0x0020; // WifiScanner APIs
936 /** @hide */
937 public static final int WIFI_FEATURE_NAN = 0x0040; // Neighbor Awareness Networking
938 /** @hide */
939 public static final int WIFI_FEATURE_D2D_RTT = 0x0080; // Device-to-device RTT
940 /** @hide */
941 public static final int WIFI_FEATURE_D2AP_RTT = 0x0100; // Device-to-AP RTT
942 /** @hide */
943 public static final int WIFI_FEATURE_BATCH_SCAN = 0x0200; // Batched Scan (deprecated)
944 /** @hide */
945 public static final int WIFI_FEATURE_PNO = 0x0400; // Preferred network offload
946 /** @hide */
947 public static final int WIFI_FEATURE_ADDITIONAL_STA = 0x0800; // Support for two STAs
948 /** @hide */
949 public static final int WIFI_FEATURE_TDLS = 0x1000; // Tunnel directed link setup
950 /** @hide */
951 public static final int WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000; // Support for TDLS off channel
952 /** @hide */
953 public static final int WIFI_FEATURE_EPR = 0x4000; // Enhanced power reporting
954 /** @hide */
955 public static final int WIFI_FEATURE_AP_STA = 0x8000; // Support for AP STA Concurrency
956 /** @hide */
957 public static final int WIFI_FEATURE_LINK_LAYER_STATS = 0x10000; // Link layer stats collection
958 /** @hide */
959 public static final int WIFI_FEATURE_LOGGER = 0x20000; // WiFi Logger
960 /** @hide */
961 public static final int WIFI_FEATURE_HAL_EPNO = 0x40000; // WiFi PNO enhanced
963 private int getSupportedFeatures() {
964 try {
965 return mService.getSupportedFeatures();
966 } catch (RemoteException e) {
967 return 0;
971 private boolean isFeatureSupported(int feature) {
972 return (getSupportedFeatures() & feature) == feature;
975 * @return true if this adapter supports 5 GHz band
977 public boolean is5GHzBandSupported() {
978 return isFeatureSupported(WIFI_FEATURE_INFRA_5G);
982 * @return true if this adapter supports passpoint
983 * @hide
985 public boolean isPasspointSupported() {
986 return isFeatureSupported(WIFI_FEATURE_PASSPOINT);
990 * @return true if this adapter supports WifiP2pManager (Wi-Fi Direct)
992 public boolean isP2pSupported() {
993 return isFeatureSupported(WIFI_FEATURE_P2P);
997 * @return true if this adapter supports portable Wi-Fi hotspot
998 * @hide
1000 @SystemApi
1001 public boolean isPortableHotspotSupported() {
1002 return isFeatureSupported(WIFI_FEATURE_MOBILE_HOTSPOT);
1006 * @return true if this adapter supports WifiScanner APIs
1007 * @hide
1009 @SystemApi
1010 public boolean isWifiScannerSupported() {
1011 return isFeatureSupported(WIFI_FEATURE_SCANNER);
1015 * @return true if this adapter supports Neighbour Awareness Network APIs
1016 * @hide
1018 public boolean isNanSupported() {
1019 return isFeatureSupported(WIFI_FEATURE_NAN);
1023 * @return true if this adapter supports Device-to-device RTT
1024 * @hide
1026 @SystemApi
1027 public boolean isDeviceToDeviceRttSupported() {
1028 return isFeatureSupported(WIFI_FEATURE_D2D_RTT);
1032 * @return true if this adapter supports Device-to-AP RTT
1034 @SystemApi
1035 public boolean isDeviceToApRttSupported() {
1036 return isFeatureSupported(WIFI_FEATURE_D2AP_RTT);
1040 * @return true if this adapter supports offloaded connectivity scan
1042 public boolean isPreferredNetworkOffloadSupported() {
1043 return isFeatureSupported(WIFI_FEATURE_PNO);
1047 * @return true if this adapter supports multiple simultaneous connections
1048 * @hide
1050 public boolean isAdditionalStaSupported() {
1051 return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA);
1055 * @return true if this adapter supports Tunnel Directed Link Setup
1057 public boolean isTdlsSupported() {
1058 return isFeatureSupported(WIFI_FEATURE_TDLS);
1062 * @return true if this adapter supports Off Channel Tunnel Directed Link Setup
1063 * @hide
1065 public boolean isOffChannelTdlsSupported() {
1066 return isFeatureSupported(WIFI_FEATURE_TDLS_OFFCHANNEL);
1070 * @return true if this adapter supports advanced power/performance counters
1072 public boolean isEnhancedPowerReportingSupported() {
1073 return isFeatureSupported(WIFI_FEATURE_LINK_LAYER_STATS);
1077 * Return the record of {@link WifiActivityEnergyInfo} object that
1078 * has the activity and energy info. This can be used to ascertain what
1079 * the controller has been up to, since the last sample.
1080 * @param updateType Type of info, cached vs refreshed.
1082 * @return a record with {@link WifiActivityEnergyInfo} or null if
1083 * report is unavailable or unsupported
1084 * @hide
1086 public WifiActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
1087 if (mService == null) return null;
1088 try {
1089 WifiActivityEnergyInfo record;
1090 if (!isEnhancedPowerReportingSupported()) {
1091 return null;
1093 synchronized(this) {
1094 record = mService.reportActivityInfo();
1095 if (record != null && record.isValid()) {
1096 return record;
1097 } else {
1098 return null;
1101 } catch (RemoteException e) {
1102 Log.e(TAG, "getControllerActivityEnergyInfo: " + e);
1104 return null;
1108 * Request a scan for access points. Returns immediately. The availability
1109 * of the results is made known later by means of an asynchronous event sent
1110 * on completion of the scan.
1111 * @return {@code true} if the operation succeeded, i.e., the scan was initiated
1113 public boolean startScan() {
1114 try {
1115 mService.startScan(null, null);
1116 return true;
1117 } catch (RemoteException e) {
1118 return false;
1122 /** @hide */
1123 @SystemApi
1124 public boolean startScan(WorkSource workSource) {
1125 try {
1126 mService.startScan(null, workSource);
1127 return true;
1128 } catch (RemoteException e) {
1129 return false;
1134 * startLocationRestrictedScan()
1135 * Trigger a scan which will not make use of DFS channels and is thus not suitable for
1136 * establishing wifi connection.
1137 * @hide
1139 @SystemApi
1140 public boolean startLocationRestrictedScan(WorkSource workSource) {
1141 try {
1142 mService.startLocationRestrictedScan(workSource);
1143 return true;
1144 } catch (RemoteException e) {
1145 return false;
1150 * Request a scan for access points in specified channel list. Each channel is specified by its
1151 * frequency in MHz, e.g. "5500" (do NOT include "DFS" even though it is). The availability of
1152 * the results is made known later in the same way as {@link #startScan}.
1154 * Note:
1156 * 1. Customized scan is for non-connection purposes, i.e. it won't trigger a wifi connection
1157 * even though it finds some known networks.
1159 * 2. Customized scan result may include access points that is not specified in the channel
1160 * list. An app will need to do frequency filtering if it wants to get pure results for the
1161 * channel list it specified.
1163 * @hide
1165 public boolean startCustomizedScan(ScanSettings requested) {
1166 try {
1167 mService.startScan(requested, null);
1168 return true;
1169 } catch (RemoteException e) {
1170 return false;
1174 /** @hide */
1175 public boolean startCustomizedScan(ScanSettings requested, WorkSource workSource) {
1176 try {
1177 mService.startScan(requested, workSource);
1178 return true;
1179 } catch (RemoteException e) {
1180 return false;
1185 * Request a batched scan for access points. To end your requested batched scan,
1186 * call stopBatchedScan with the same Settings.
1188 * If there are mulitple requests for batched scans, the more demanding settings will
1189 * take precidence.
1191 * @param requested {@link BatchedScanSettings} the scan settings requested.
1192 * @return false on known error
1193 * @hide
1195 public boolean requestBatchedScan(BatchedScanSettings requested) {
1196 try {
1197 return mService.requestBatchedScan(requested, new Binder(), null);
1198 } catch (RemoteException e) { return false; }
1200 /** @hide */
1201 public boolean requestBatchedScan(BatchedScanSettings requested, WorkSource workSource) {
1202 try {
1203 return mService.requestBatchedScan(requested, new Binder(), workSource);
1204 } catch (RemoteException e) { return false; }
1208 * Check if the Batched Scan feature is supported.
1210 * @return false if not supported.
1211 * @hide
1213 @SystemApi
1214 public boolean isBatchedScanSupported() {
1215 try {
1216 return mService.isBatchedScanSupported();
1217 } catch (RemoteException e) { return false; }
1221 * End a requested batch scan for this applicaiton. Note that batched scan may
1222 * still occur if other apps are using them.
1224 * @param requested {@link BatchedScanSettings} the scan settings you previously requested
1225 * and now wish to stop. A value of null here will stop all scans requested by the
1226 * calling App.
1227 * @hide
1229 public void stopBatchedScan(BatchedScanSettings requested) {
1230 try {
1231 mService.stopBatchedScan(requested);
1232 } catch (RemoteException e) {}
1236 * Retrieve the latest batched scan result. This should be called immediately after
1237 * {@link BATCHED_SCAN_RESULTS_AVAILABLE_ACTION} is received.
1238 * @hide
1240 @SystemApi
1241 public List<BatchedScanResult> getBatchedScanResults() {
1242 try {
1243 return mService.getBatchedScanResults(mContext.getOpPackageName());
1244 } catch (RemoteException e) {
1245 return null;
1250 * Force a re-reading of batched scan results. This will attempt
1251 * to read more information from the chip, but will do so at the expense
1252 * of previous data. Rate limited to the current scan frequency.
1254 * pollBatchedScan will always wait 1 period from the start of the batch
1255 * before trying to read from the chip, so if your #scans/batch == 1 this will
1256 * have no effect.
1258 * If you had already waited 1 period before calling, this should have
1259 * immediate (though async) effect.
1261 * If you call before that 1 period is up this will set up a timer and fetch
1262 * results when the 1 period is up.
1264 * Servicing a pollBatchedScan request (immediate or after timed delay) starts a
1265 * new batch, so if you were doing 10 scans/batch and called in the 4th scan, you
1266 * would get data in the 4th and then again 10 scans later.
1267 * @hide
1269 public void pollBatchedScan() {
1270 try {
1271 mService.pollBatchedScan();
1272 } catch (RemoteException e) { }
1276 * Creates a configuration token describing the network referenced by {@code netId}
1277 * of MIME type application/vnd.wfa.wsc. Can be used to configure WiFi networks via NFC.
1279 * @return hex-string encoded configuration token
1280 * @hide
1282 public String getWpsNfcConfigurationToken(int netId) {
1283 try {
1284 return mService.getWpsNfcConfigurationToken(netId);
1285 } catch (RemoteException e) {
1286 return null;
1291 * Return dynamic information about the current Wi-Fi connection, if any is active.
1292 * @return the Wi-Fi information, contained in {@link WifiInfo}.
1294 public WifiInfo getConnectionInfo() {
1295 try {
1296 return mService.getConnectionInfo();
1297 } catch (RemoteException e) {
1298 return null;
1303 * Return the results of the latest access point scan.
1304 * @return the list of access points found in the most recent scan. An app must hold
1305 * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
1306 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
1307 * in order to get valid results.
1309 public List<ScanResult> getScanResults() {
1310 try {
1311 return mService.getScanResults(mContext.getOpPackageName());
1312 } catch (RemoteException e) {
1313 return null;
1318 * Check if scanning is always available.
1320 * If this return {@code true}, apps can issue {@link #startScan} and fetch scan results
1321 * even when Wi-Fi is turned off.
1323 * To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}.
1325 public boolean isScanAlwaysAvailable() {
1326 try {
1327 return mService.isScanAlwaysAvailable();
1328 } catch (RemoteException e) {
1329 return false;
1334 * Tell the supplicant to persist the current list of configured networks.
1335 * <p>
1336 * Note: It is possible for this method to change the network IDs of
1337 * existing networks. You should assume the network IDs can be different
1338 * after calling this method.
1340 * @return {@code true} if the operation succeeded
1342 public boolean saveConfiguration() {
1343 try {
1344 return mService.saveConfiguration();
1345 } catch (RemoteException e) {
1346 return false;
1351 * Set the country code.
1352 * @param countryCode country code in ISO 3166 format.
1353 * @param persist {@code true} if this needs to be remembered
1355 * @hide
1357 public void setCountryCode(String country, boolean persist) {
1358 try {
1359 mService.setCountryCode(country, persist);
1360 } catch (RemoteException e) { }
1364 * get the country code.
1365 * @return the country code in ISO 3166 format.
1367 * @hide
1369 public String getCountryCode() {
1370 try {
1371 String country = mService.getCountryCode();
1372 return(country);
1373 } catch (RemoteException e) {
1374 return null;
1379 * Set the operational frequency band.
1380 * @param band One of
1381 * {@link #WIFI_FREQUENCY_BAND_AUTO},
1382 * {@link #WIFI_FREQUENCY_BAND_5GHZ},
1383 * {@link #WIFI_FREQUENCY_BAND_2GHZ},
1384 * @param persist {@code true} if this needs to be remembered
1385 * @hide
1387 public void setFrequencyBand(int band, boolean persist) {
1388 try {
1389 mService.setFrequencyBand(band, persist);
1390 } catch (RemoteException e) { }
1394 * Get the operational frequency band.
1395 * @return One of
1396 * {@link #WIFI_FREQUENCY_BAND_AUTO},
1397 * {@link #WIFI_FREQUENCY_BAND_5GHZ},
1398 * {@link #WIFI_FREQUENCY_BAND_2GHZ} or
1399 * {@code -1} on failure.
1400 * @hide
1402 public int getFrequencyBand() {
1403 try {
1404 return mService.getFrequencyBand();
1405 } catch (RemoteException e) {
1406 return -1;
1411 * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz)
1412 * @return {@code true} if supported, {@code false} otherwise.
1413 * @hide
1415 public boolean isDualBandSupported() {
1416 try {
1417 return mService.isDualBandSupported();
1418 } catch (RemoteException e) {
1419 return false;
1424 * Return the DHCP-assigned addresses from the last successful DHCP request,
1425 * if any.
1426 * @return the DHCP information
1428 public DhcpInfo getDhcpInfo() {
1429 try {
1430 return mService.getDhcpInfo();
1431 } catch (RemoteException e) {
1432 return null;
1437 * Enable or disable Wi-Fi.
1438 * @param enabled {@code true} to enable, {@code false} to disable.
1439 * @return {@code true} if the operation succeeds (or if the existing state
1440 * is the same as the requested state).
1442 public boolean setWifiEnabled(boolean enabled) {
1443 try {
1444 return mService.setWifiEnabled(enabled);
1445 } catch (RemoteException e) {
1446 return false;
1451 * Gets the Wi-Fi enabled state.
1452 * @return One of {@link #WIFI_STATE_DISABLED},
1453 * {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED},
1454 * {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN}
1455 * @see #isWifiEnabled()
1457 public int getWifiState() {
1458 try {
1459 return mService.getWifiEnabledState();
1460 } catch (RemoteException e) {
1461 return WIFI_STATE_UNKNOWN;
1466 * Return whether Wi-Fi is enabled or disabled.
1467 * @return {@code true} if Wi-Fi is enabled
1468 * @see #getWifiState()
1470 public boolean isWifiEnabled() {
1471 return getWifiState() == WIFI_STATE_ENABLED;
1475 * Return TX packet counter, for CTS test of WiFi watchdog.
1476 * @param listener is the interface to receive result
1478 * @hide for CTS test only
1480 public void getTxPacketCount(TxPacketCountListener listener) {
1481 validateChannel();
1482 sAsyncChannel.sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener));
1486 * Calculates the level of the signal. This should be used any time a signal
1487 * is being shown.
1489 * @param rssi The power of the signal measured in RSSI.
1490 * @param numLevels The number of levels to consider in the calculated
1491 * level.
1492 * @return A level of the signal, given in the range of 0 to numLevels-1
1493 * (both inclusive).
1495 public static int calculateSignalLevel(int rssi, int numLevels) {
1496 if (rssi <= MIN_RSSI) {
1497 return 0;
1498 } else if (rssi >= MAX_RSSI) {
1499 return numLevels - 1;
1500 } else {
1501 float inputRange = (MAX_RSSI - MIN_RSSI);
1502 float outputRange = (numLevels - 1);
1503 return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange);
1508 * Compares two signal strengths.
1510 * @param rssiA The power of the first signal measured in RSSI.
1511 * @param rssiB The power of the second signal measured in RSSI.
1512 * @return Returns <0 if the first signal is weaker than the second signal,
1513 * 0 if the two signals have the same strength, and >0 if the first
1514 * signal is stronger than the second signal.
1516 public static int compareSignalLevel(int rssiA, int rssiB) {
1517 return rssiA - rssiB;
1521 * Start AccessPoint mode with the specified
1522 * configuration. If the radio is already running in
1523 * AP mode, update the new configuration
1524 * Note that starting in access point mode disables station
1525 * mode operation
1526 * @param wifiConfig SSID, security and channel details as
1527 * part of WifiConfiguration
1528 * @return {@code true} if the operation succeeds, {@code false} otherwise
1530 * @hide Dont open up yet
1532 public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
1533 try {
1534 mService.setWifiApEnabled(wifiConfig, enabled);
1535 return true;
1536 } catch (RemoteException e) {
1537 return false;
1542 * Gets the Wi-Fi enabled state.
1543 * @return One of {@link #WIFI_AP_STATE_DISABLED},
1544 * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
1545 * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
1546 * @see #isWifiApEnabled()
1548 * @hide Dont open yet
1550 public int getWifiApState() {
1551 try {
1552 return mService.getWifiApEnabledState();
1553 } catch (RemoteException e) {
1554 return WIFI_AP_STATE_FAILED;
1559 * Return whether Wi-Fi AP is enabled or disabled.
1560 * @return {@code true} if Wi-Fi AP is enabled
1561 * @see #getWifiApState()
1563 * @hide Dont open yet
1565 public boolean isWifiApEnabled() {
1566 return getWifiApState() == WIFI_AP_STATE_ENABLED;
1570 * Gets the Wi-Fi AP Configuration.
1571 * @return AP details in WifiConfiguration
1573 * @hide Dont open yet
1575 public WifiConfiguration getWifiApConfiguration() {
1576 try {
1577 return mService.getWifiApConfiguration();
1578 } catch (RemoteException e) {
1579 return null;
1584 * Builds a WifiConfiguration from Hotspot 2.0 MIME file.
1585 * @return AP details in WifiConfiguration
1587 * @hide Dont open yet
1589 public WifiConfiguration buildWifiConfig(String uriString, String mimeType, byte[] data) {
1590 try {
1591 return mService.buildWifiConfig(uriString, mimeType, data);
1592 } catch (RemoteException e) {
1593 Log.w(TAG, "Caught RemoteException trying to build wifi config: " + e);
1594 return null;
1599 * Sets the Wi-Fi AP Configuration.
1600 * @return {@code true} if the operation succeeded, {@code false} otherwise
1602 * @hide Dont open yet
1604 public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
1605 try {
1606 mService.setWifiApConfiguration(wifiConfig);
1607 return true;
1608 } catch (RemoteException e) {
1609 return false;
1614 * Start the driver and connect to network.
1616 * This function will over-ride WifiLock and device idle status. For example,
1617 * even if the device is idle or there is only a scan-only lock held,
1618 * a start wifi would mean that wifi connection is kept active until
1619 * a stopWifi() is sent.
1621 * This API is used by WifiStateTracker
1623 * @return {@code true} if the operation succeeds else {@code false}
1624 * @hide
1626 public boolean startWifi() {
1627 try {
1628 mService.startWifi();
1629 return true;
1630 } catch (RemoteException e) {
1631 return false;
1636 * Disconnect from a network (if any) and stop the driver.
1638 * This function will over-ride WifiLock and device idle status. Wi-Fi
1639 * stays inactive until a startWifi() is issued.
1641 * This API is used by WifiStateTracker
1643 * @return {@code true} if the operation succeeds else {@code false}
1644 * @hide
1646 public boolean stopWifi() {
1647 try {
1648 mService.stopWifi();
1649 return true;
1650 } catch (RemoteException e) {
1651 return false;
1656 * Add a bssid to the supplicant blacklist
1658 * This API is used by WifiWatchdogService
1660 * @return {@code true} if the operation succeeds else {@code false}
1661 * @hide
1663 public boolean addToBlacklist(String bssid) {
1664 try {
1665 mService.addToBlacklist(bssid);
1666 return true;
1667 } catch (RemoteException e) {
1668 return false;
1673 * Clear the supplicant blacklist
1675 * This API is used by WifiWatchdogService
1677 * @return {@code true} if the operation succeeds else {@code false}
1678 * @hide
1680 public boolean clearBlacklist() {
1681 try {
1682 mService.clearBlacklist();
1683 return true;
1684 } catch (RemoteException e) {
1685 return false;
1691 * Enable/Disable TDLS on a specific local route.
1693 * <p>
1694 * TDLS enables two wireless endpoints to talk to each other directly
1695 * without going through the access point that is managing the local
1696 * network. It saves bandwidth and improves quality of the link.
1697 * </p>
1698 * <p>
1699 * This API enables/disables the option of using TDLS. If enabled, the
1700 * underlying hardware is free to use TDLS or a hop through the access
1701 * point. If disabled, existing TDLS session is torn down and
1702 * hardware is restricted to use access point for transferring wireless
1703 * packets. Default value for all routes is 'disabled', meaning restricted
1704 * to use access point for transferring packets.
1705 * </p>
1707 * @param remoteIPAddress IP address of the endpoint to setup TDLS with
1708 * @param enable true = setup and false = tear down TDLS
1710 public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) {
1711 try {
1712 mService.enableTdls(remoteIPAddress.getHostAddress(), enable);
1713 } catch (RemoteException e) {
1714 // Just ignore the exception
1719 * Similar to {@link #setTdlsEnabled(InetAddress, boolean) }, except
1720 * this version allows you to specify remote endpoint with a MAC address.
1721 * @param remoteMacAddress MAC address of the remote endpoint such as 00:00:0c:9f:f2:ab
1722 * @param enable true = setup and false = tear down TDLS
1724 public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) {
1725 try {
1726 mService.enableTdlsWithMacAddress(remoteMacAddress, enable);
1727 } catch (RemoteException e) {
1728 // Just ignore the exception
1732 /* TODO: deprecate synchronous API and open up the following API */
1734 private static final int BASE = Protocol.BASE_WIFI_MANAGER;
1736 /* Commands to WifiService */
1737 /** @hide */
1738 public static final int CONNECT_NETWORK = BASE + 1;
1739 /** @hide */
1740 public static final int CONNECT_NETWORK_FAILED = BASE + 2;
1741 /** @hide */
1742 public static final int CONNECT_NETWORK_SUCCEEDED = BASE + 3;
1744 /** @hide */
1745 public static final int FORGET_NETWORK = BASE + 4;
1746 /** @hide */
1747 public static final int FORGET_NETWORK_FAILED = BASE + 5;
1748 /** @hide */
1749 public static final int FORGET_NETWORK_SUCCEEDED = BASE + 6;
1751 /** @hide */
1752 public static final int SAVE_NETWORK = BASE + 7;
1753 /** @hide */
1754 public static final int SAVE_NETWORK_FAILED = BASE + 8;
1755 /** @hide */
1756 public static final int SAVE_NETWORK_SUCCEEDED = BASE + 9;
1758 /** @hide */
1759 public static final int START_WPS = BASE + 10;
1760 /** @hide */
1761 public static final int START_WPS_SUCCEEDED = BASE + 11;
1762 /** @hide */
1763 public static final int WPS_FAILED = BASE + 12;
1764 /** @hide */
1765 public static final int WPS_COMPLETED = BASE + 13;
1767 /** @hide */
1768 public static final int CANCEL_WPS = BASE + 14;
1769 /** @hide */
1770 public static final int CANCEL_WPS_FAILED = BASE + 15;
1771 /** @hide */
1772 public static final int CANCEL_WPS_SUCCEDED = BASE + 16;
1774 /** @hide */
1775 public static final int DISABLE_NETWORK = BASE + 17;
1776 /** @hide */
1777 public static final int DISABLE_NETWORK_FAILED = BASE + 18;
1778 /** @hide */
1779 public static final int DISABLE_NETWORK_SUCCEEDED = BASE + 19;
1781 /** @hide */
1782 public static final int RSSI_PKTCNT_FETCH = BASE + 20;
1783 /** @hide */
1784 public static final int RSSI_PKTCNT_FETCH_SUCCEEDED = BASE + 21;
1785 /** @hide */
1786 public static final int RSSI_PKTCNT_FETCH_FAILED = BASE + 22;
1789 * Passed with {@link ActionListener#onFailure}.
1790 * Indicates that the operation failed due to an internal error.
1791 * @hide
1793 public static final int ERROR = 0;
1796 * Passed with {@link ActionListener#onFailure}.
1797 * Indicates that the operation is already in progress
1798 * @hide
1800 public static final int IN_PROGRESS = 1;
1803 * Passed with {@link ActionListener#onFailure}.
1804 * Indicates that the operation failed because the framework is busy and
1805 * unable to service the request
1806 * @hide
1808 public static final int BUSY = 2;
1810 /* WPS specific errors */
1811 /** WPS overlap detected */
1812 public static final int WPS_OVERLAP_ERROR = 3;
1813 /** WEP on WPS is prohibited */
1814 public static final int WPS_WEP_PROHIBITED = 4;
1815 /** TKIP only prohibited */
1816 public static final int WPS_TKIP_ONLY_PROHIBITED = 5;
1817 /** Authentication failure on WPS */
1818 public static final int WPS_AUTH_FAILURE = 6;
1819 /** WPS timed out */
1820 public static final int WPS_TIMED_OUT = 7;
1823 * Passed with {@link ActionListener#onFailure}.
1824 * Indicates that the operation failed due to invalid inputs
1825 * @hide
1827 public static final int INVALID_ARGS = 8;
1830 * Passed with {@link ActionListener#onFailure}.
1831 * Indicates that the operation failed due to user permissions.
1832 * @hide
1834 public static final int NOT_AUTHORIZED = 9;
1837 * Interface for callback invocation on an application action
1838 * @hide
1840 public interface ActionListener {
1841 /** The operation succeeded */
1842 public void onSuccess();
1844 * The operation failed
1845 * @param reason The reason for failure could be one of
1846 * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY}
1848 public void onFailure(int reason);
1851 /** Interface for callback invocation on a start WPS action */
1852 public static abstract class WpsCallback {
1853 /** WPS start succeeded */
1854 public abstract void onStarted(String pin);
1856 /** WPS operation completed succesfully */
1857 public abstract void onSucceeded();
1860 * WPS operation failed
1861 * @param reason The reason for failure could be one of
1862 * {@link #WPS_TKIP_ONLY_PROHIBITED}, {@link #WPS_OVERLAP_ERROR},
1863 * {@link #WPS_WEP_PROHIBITED}, {@link #WPS_TIMED_OUT} or {@link #WPS_AUTH_FAILURE}
1864 * and some generic errors.
1866 public abstract void onFailed(int reason);
1869 /** Interface for callback invocation on a TX packet count poll action {@hide} */
1870 public interface TxPacketCountListener {
1872 * The operation succeeded
1873 * @param count TX packet counter
1875 public void onSuccess(int count);
1877 * The operation failed
1878 * @param reason The reason for failure could be one of
1879 * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY}
1881 public void onFailure(int reason);
1884 private static class ServiceHandler extends Handler {
1885 ServiceHandler(Looper looper) {
1886 super(looper);
1889 @Override
1890 public void handleMessage(Message message) {
1891 Object listener = removeListener(message.arg2);
1892 switch (message.what) {
1893 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
1894 if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
1895 sAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
1896 } else {
1897 Log.e(TAG, "Failed to set up channel connection");
1898 // This will cause all further async API calls on the WifiManager
1899 // to fail and throw an exception
1900 sAsyncChannel = null;
1902 sConnected.countDown();
1903 break;
1904 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
1905 // Ignore
1906 break;
1907 case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
1908 Log.e(TAG, "Channel connection lost");
1909 // This will cause all further async API calls on the WifiManager
1910 // to fail and throw an exception
1911 sAsyncChannel = null;
1912 getLooper().quit();
1913 break;
1914 /* ActionListeners grouped together */
1915 case WifiManager.CONNECT_NETWORK_FAILED:
1916 case WifiManager.FORGET_NETWORK_FAILED:
1917 case WifiManager.SAVE_NETWORK_FAILED:
1918 case WifiManager.DISABLE_NETWORK_FAILED:
1919 if (listener != null) {
1920 ((ActionListener) listener).onFailure(message.arg1);
1922 break;
1923 /* ActionListeners grouped together */
1924 case WifiManager.CONNECT_NETWORK_SUCCEEDED:
1925 case WifiManager.FORGET_NETWORK_SUCCEEDED:
1926 case WifiManager.SAVE_NETWORK_SUCCEEDED:
1927 case WifiManager.DISABLE_NETWORK_SUCCEEDED:
1928 if (listener != null) {
1929 ((ActionListener) listener).onSuccess();
1931 break;
1932 case WifiManager.START_WPS_SUCCEEDED:
1933 if (listener != null) {
1934 WpsResult result = (WpsResult) message.obj;
1935 ((WpsCallback) listener).onStarted(result.pin);
1936 //Listener needs to stay until completion or failure
1937 synchronized(sListenerMapLock) {
1938 sListenerMap.put(message.arg2, listener);
1941 break;
1942 case WifiManager.WPS_COMPLETED:
1943 if (listener != null) {
1944 ((WpsCallback) listener).onSucceeded();
1946 break;
1947 case WifiManager.WPS_FAILED:
1948 if (listener != null) {
1949 ((WpsCallback) listener).onFailed(message.arg1);
1951 break;
1952 case WifiManager.CANCEL_WPS_SUCCEDED:
1953 if (listener != null) {
1954 ((WpsCallback) listener).onSucceeded();
1956 break;
1957 case WifiManager.CANCEL_WPS_FAILED:
1958 if (listener != null) {
1959 ((WpsCallback) listener).onFailed(message.arg1);
1961 break;
1962 case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
1963 if (listener != null) {
1964 RssiPacketCountInfo info = (RssiPacketCountInfo) message.obj;
1965 if (info != null)
1966 ((TxPacketCountListener) listener).onSuccess(info.txgood + info.txbad);
1967 else
1968 ((TxPacketCountListener) listener).onFailure(ERROR);
1970 break;
1971 case WifiManager.RSSI_PKTCNT_FETCH_FAILED:
1972 if (listener != null) {
1973 ((TxPacketCountListener) listener).onFailure(message.arg1);
1975 break;
1976 default:
1977 //ignore
1978 break;
1983 private static int putListener(Object listener) {
1984 if (listener == null) return INVALID_KEY;
1985 int key;
1986 synchronized (sListenerMapLock) {
1987 do {
1988 key = sListenerKey++;
1989 } while (key == INVALID_KEY);
1990 sListenerMap.put(key, listener);
1992 return key;
1995 private static Object removeListener(int key) {
1996 if (key == INVALID_KEY) return null;
1997 synchronized (sListenerMapLock) {
1998 Object listener = sListenerMap.get(key);
1999 sListenerMap.remove(key);
2000 return listener;
2004 private void init() {
2005 synchronized (sThreadRefLock) {
2006 if (++sThreadRefCount == 1) {
2007 Messenger messenger = getWifiServiceMessenger();
2008 if (messenger == null) {
2009 sAsyncChannel = null;
2010 return;
2013 sHandlerThread = new HandlerThread("WifiManager");
2014 sAsyncChannel = new AsyncChannel();
2015 sConnected = new CountDownLatch(1);
2017 sHandlerThread.start();
2018 Handler handler = new ServiceHandler(sHandlerThread.getLooper());
2019 sAsyncChannel.connect(mContext, handler, messenger);
2020 try {
2021 sConnected.await();
2022 } catch (InterruptedException e) {
2023 Log.e(TAG, "interrupted wait at init");
2029 private void validateChannel() {
2030 if (sAsyncChannel == null) throw new IllegalStateException(
2031 "No permission to access and change wifi or a bad initialization");
2034 private void initConnectivityManager() {
2035 // TODO: what happens if an app calls a WifiManager API before ConnectivityManager is
2036 // registered? Can we fix this by starting ConnectivityService before WifiService?
2037 if (sCM == null) {
2038 sCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
2039 if (sCM == null) {
2040 throw new IllegalStateException("Bad luck, ConnectivityService not started.");
2046 * A NetworkCallback that pins the process to the first wifi network to connect.
2048 * We use this to maintain compatibility with pre-M apps that call WifiManager.enableNetwork()
2049 * to connect to a Wi-Fi network that has no Internet access, and then assume that they will be
2050 * able to use that network because it's the system default.
2052 * In order to maintain compatibility with apps that call setProcessDefaultNetwork themselves,
2053 * we try not to set the default network unless they have already done so, and we try not to
2054 * clear the default network unless we set it ourselves.
2056 * This should maintain behaviour that's compatible with L, which would pin the whole system to
2057 * any wifi network that was created via enableNetwork(..., true) until that network
2058 * disconnected.
2060 * Note that while this hack allows network traffic to flow, it is quite limited. For example:
2062 * 1. setProcessDefaultNetwork only affects this process, so:
2063 * - Any subprocesses spawned by this process will not be pinned to Wi-Fi.
2064 * - If this app relies on any other apps on the device also being on Wi-Fi, that won't work
2065 * either, because other apps on the device will not be pinned.
2066 * 2. The behaviour of other APIs is not modified. For example:
2067 * - getActiveNetworkInfo will return the system default network, not Wi-Fi.
2068 * - There will be no CONNECTIVITY_ACTION broadcasts about TYPE_WIFI.
2069 * - getProcessDefaultNetwork will not return null, so if any apps are relying on that, they
2070 * will be surprised as well.
2072 private class PinningNetworkCallback extends NetworkCallback {
2073 private Network mPinnedNetwork;
2075 @Override
2076 public void onPreCheck(Network network) {
2077 if (sCM.getProcessDefaultNetwork() == null && mPinnedNetwork == null) {
2078 sCM.setProcessDefaultNetwork(network);
2079 mPinnedNetwork = network;
2080 Log.d(TAG, "Wifi alternate reality enabled on network " + network);
2084 @Override
2085 public void onLost(Network network) {
2086 if (network.equals(mPinnedNetwork) && network.equals(sCM.getProcessDefaultNetwork())) {
2087 sCM.setProcessDefaultNetwork(null);
2088 Log.d(TAG, "Wifi alternate reality disabled on network " + network);
2089 mPinnedNetwork = null;
2090 unregisterPinningNetworkCallback();
2095 private void registerPinningNetworkCallback() {
2096 initConnectivityManager();
2097 synchronized (sCM) {
2098 if (mNetworkCallback == null) {
2099 // TODO: clear all capabilities.
2100 NetworkRequest request = new NetworkRequest.Builder()
2101 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
2102 .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
2103 .build();
2104 mNetworkCallback = new PinningNetworkCallback();
2105 try {
2106 sCM.registerNetworkCallback(request, mNetworkCallback);
2107 } catch (SecurityException e) {
2108 Log.d(TAG, "Failed to register network callback", e);
2114 private void unregisterPinningNetworkCallback() {
2115 initConnectivityManager();
2116 synchronized (sCM) {
2117 if (mNetworkCallback != null) {
2118 try {
2119 sCM.unregisterNetworkCallback(mNetworkCallback);
2120 } catch (SecurityException e) {
2121 Log.d(TAG, "Failed to unregister network callback", e);
2123 mNetworkCallback = null;
2129 * Connect to a network with the given configuration. The network also
2130 * gets added to the supplicant configuration.
2132 * For a new network, this function is used instead of a
2133 * sequence of addNetwork(), enableNetwork(), saveConfiguration() and
2134 * reconnect()
2136 * @param config the set of variables that describe the configuration,
2137 * contained in a {@link WifiConfiguration} object.
2138 * @param listener for callbacks on success or failure. Can be null.
2139 * @throws IllegalStateException if the WifiManager instance needs to be
2140 * initialized again
2142 * @hide
2144 public void connect(WifiConfiguration config, ActionListener listener) {
2145 if (config == null) throw new IllegalArgumentException("config cannot be null");
2146 validateChannel();
2147 // Use INVALID_NETWORK_ID for arg1 when passing a config object
2148 // arg1 is used to pass network id when the network already exists
2149 sAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
2150 putListener(listener), config);
2154 * Connect to a network with the given networkId.
2156 * This function is used instead of a enableNetwork(), saveConfiguration() and
2157 * reconnect()
2159 * @param networkId the network id identifiying the network in the
2160 * supplicant configuration list
2161 * @param listener for callbacks on success or failure. Can be null.
2162 * @throws IllegalStateException if the WifiManager instance needs to be
2163 * initialized again
2164 * @hide
2166 public void connect(int networkId, ActionListener listener) {
2167 if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
2168 validateChannel();
2169 sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));
2173 * Save the given network in the supplicant config. If the network already
2174 * exists, the configuration is updated. A new network is enabled
2175 * by default.
2177 * For a new network, this function is used instead of a
2178 * sequence of addNetwork(), enableNetwork() and saveConfiguration().
2180 * For an existing network, it accomplishes the task of updateNetwork()
2181 * and saveConfiguration()
2183 * @param config the set of variables that describe the configuration,
2184 * contained in a {@link WifiConfiguration} object.
2185 * @param listener for callbacks on success or failure. Can be null.
2186 * @throws IllegalStateException if the WifiManager instance needs to be
2187 * initialized again
2188 * @hide
2190 public void save(WifiConfiguration config, ActionListener listener) {
2191 if (config == null) throw new IllegalArgumentException("config cannot be null");
2192 validateChannel();
2193 sAsyncChannel.sendMessage(SAVE_NETWORK, 0, putListener(listener), config);
2197 * Delete the network in the supplicant config.
2199 * This function is used instead of a sequence of removeNetwork()
2200 * and saveConfiguration().
2202 * @param config the set of variables that describe the configuration,
2203 * contained in a {@link WifiConfiguration} object.
2204 * @param listener for callbacks on success or failure. Can be null.
2205 * @throws IllegalStateException if the WifiManager instance needs to be
2206 * initialized again
2207 * @hide
2209 public void forget(int netId, ActionListener listener) {
2210 if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
2211 validateChannel();
2212 sAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener));
2216 * Disable network
2218 * @param netId is the network Id
2219 * @param listener for callbacks on success or failure. Can be null.
2220 * @throws IllegalStateException if the WifiManager instance needs to be
2221 * initialized again
2222 * @hide
2224 public void disable(int netId, ActionListener listener) {
2225 if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
2226 validateChannel();
2227 sAsyncChannel.sendMessage(DISABLE_NETWORK, netId, putListener(listener));
2231 * Disable ephemeral Network
2233 * @param SSID, in the format of WifiConfiguration's SSID.
2234 * @hide
2236 public void disableEphemeralNetwork(String SSID) {
2237 if (SSID == null) throw new IllegalArgumentException("SSID cannot be null");
2238 try {
2239 mService.disableEphemeralNetwork(SSID);
2240 } catch (RemoteException e) {
2245 * Start Wi-fi Protected Setup
2247 * @param config WPS configuration (does not support {@link WpsInfo#LABEL})
2248 * @param listener for callbacks on success or failure. Can be null.
2249 * @throws IllegalStateException if the WifiManager instance needs to be
2250 * initialized again
2252 public void startWps(WpsInfo config, WpsCallback listener) {
2253 if (config == null) throw new IllegalArgumentException("config cannot be null");
2254 validateChannel();
2255 sAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config);
2259 * Cancel any ongoing Wi-fi Protected Setup
2261 * @param listener for callbacks on success or failure. Can be null.
2262 * @throws IllegalStateException if the WifiManager instance needs to be
2263 * initialized again
2265 public void cancelWps(WpsCallback listener) {
2266 validateChannel();
2267 sAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener));
2271 * Get a reference to WifiService handler. This is used by a client to establish
2272 * an AsyncChannel communication with WifiService
2274 * @return Messenger pointing to the WifiService handler
2275 * @hide
2277 public Messenger getWifiServiceMessenger() {
2278 try {
2279 return mService.getWifiServiceMessenger();
2280 } catch (RemoteException e) {
2281 return null;
2282 } catch (SecurityException e) {
2283 return null;
2289 * Returns the file in which IP and proxy configuration data is stored
2290 * @hide
2292 public String getConfigFile() {
2293 try {
2294 return mService.getConfigFile();
2295 } catch (RemoteException e) {
2296 return null;
2301 * Allows an application to keep the Wi-Fi radio awake.
2302 * Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
2303 * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple
2304 * applications may hold WifiLocks, and the radio will only be allowed to turn off when no
2305 * WifiLocks are held in any application.
2306 * <p>
2307 * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or
2308 * could function over a mobile network, if available. A program that needs to download large
2309 * files should hold a WifiLock to ensure that the download will complete, but a program whose
2310 * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely
2311 * affecting battery life.
2312 * <p>
2313 * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane
2314 * Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device
2315 * is idle.
2316 * <p>
2317 * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK}
2318 * permission in an {@code &lt;uses-permission&gt;} element of the application's manifest.
2320 public class WifiLock {
2321 private String mTag;
2322 private final IBinder mBinder;
2323 private int mRefCount;
2324 int mLockType;
2325 private boolean mRefCounted;
2326 private boolean mHeld;
2327 private WorkSource mWorkSource;
2329 private WifiLock(int lockType, String tag) {
2330 mTag = tag;
2331 mLockType = lockType;
2332 mBinder = new Binder();
2333 mRefCount = 0;
2334 mRefCounted = true;
2335 mHeld = false;
2339 * Locks the Wi-Fi radio on until {@link #release} is called.
2341 * If this WifiLock is reference-counted, each call to {@code acquire} will increment the
2342 * reference count, and the radio will remain locked as long as the reference count is
2343 * above zero.
2345 * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock
2346 * the radio, but subsequent calls will be ignored. Only one call to {@link #release}
2347 * will be required, regardless of the number of times that {@code acquire} is called.
2349 public void acquire() {
2350 synchronized (mBinder) {
2351 if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
2352 try {
2353 mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource);
2354 synchronized (WifiManager.this) {
2355 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
2356 mService.releaseWifiLock(mBinder);
2357 throw new UnsupportedOperationException(
2358 "Exceeded maximum number of wifi locks");
2360 mActiveLockCount++;
2362 } catch (RemoteException ignore) {
2364 mHeld = true;
2370 * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle.
2372 * If this WifiLock is reference-counted, each call to {@code release} will decrement the
2373 * reference count, and the radio will be unlocked only when the reference count reaches
2374 * zero. If the reference count goes below zero (that is, if {@code release} is called
2375 * a greater number of times than {@link #acquire}), an exception is thrown.
2377 * If this WifiLock is not reference-counted, the first call to {@code release} (after
2378 * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent
2379 * calls will be ignored.
2381 public void release() {
2382 synchronized (mBinder) {
2383 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
2384 try {
2385 mService.releaseWifiLock(mBinder);
2386 synchronized (WifiManager.this) {
2387 mActiveLockCount--;
2389 } catch (RemoteException ignore) {
2391 mHeld = false;
2393 if (mRefCount < 0) {
2394 throw new RuntimeException("WifiLock under-locked " + mTag);
2400 * Controls whether this is a reference-counted or non-reference-counted WifiLock.
2402 * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and
2403 * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire}
2404 * has been balanced with a call to {@link #release}. Non-reference-counted WifiLocks
2405 * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the
2406 * radio whenever {@link #release} is called and it is locked.
2408 * @param refCounted true if this WifiLock should keep a reference count
2410 public void setReferenceCounted(boolean refCounted) {
2411 mRefCounted = refCounted;
2415 * Checks whether this WifiLock is currently held.
2417 * @return true if this WifiLock is held, false otherwise
2419 public boolean isHeld() {
2420 synchronized (mBinder) {
2421 return mHeld;
2425 public void setWorkSource(WorkSource ws) {
2426 synchronized (mBinder) {
2427 if (ws != null && ws.size() == 0) {
2428 ws = null;
2430 boolean changed = true;
2431 if (ws == null) {
2432 mWorkSource = null;
2433 } else {
2434 ws.clearNames();
2435 if (mWorkSource == null) {
2436 changed = mWorkSource != null;
2437 mWorkSource = new WorkSource(ws);
2438 } else {
2439 changed = mWorkSource.diff(ws);
2440 if (changed) {
2441 mWorkSource.set(ws);
2445 if (changed && mHeld) {
2446 try {
2447 mService.updateWifiLockWorkSource(mBinder, mWorkSource);
2448 } catch (RemoteException e) {
2454 public String toString() {
2455 String s1, s2, s3;
2456 synchronized (mBinder) {
2457 s1 = Integer.toHexString(System.identityHashCode(this));
2458 s2 = mHeld ? "held; " : "";
2459 if (mRefCounted) {
2460 s3 = "refcounted: refcount = " + mRefCount;
2461 } else {
2462 s3 = "not refcounted";
2464 return "WifiLock{ " + s1 + "; " + s2 + s3 + " }";
2468 @Override
2469 protected void finalize() throws Throwable {
2470 super.finalize();
2471 synchronized (mBinder) {
2472 if (mHeld) {
2473 try {
2474 mService.releaseWifiLock(mBinder);
2475 synchronized (WifiManager.this) {
2476 mActiveLockCount--;
2478 } catch (RemoteException ignore) {
2486 * Creates a new WifiLock.
2488 * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL},
2489 * {@link #WIFI_MODE_FULL_HIGH_PERF} and {@link #WIFI_MODE_SCAN_ONLY} for
2490 * descriptions of the types of Wi-Fi locks.
2491 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is
2492 * never shown to the user under normal conditions, but should be descriptive
2493 * enough to identify your application and the specific WifiLock within it, if it
2494 * holds multiple WifiLocks.
2496 * @return a new, unacquired WifiLock with the given tag.
2498 * @see WifiLock
2500 public WifiLock createWifiLock(int lockType, String tag) {
2501 return new WifiLock(lockType, tag);
2505 * Creates a new WifiLock.
2507 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is
2508 * never shown to the user under normal conditions, but should be descriptive
2509 * enough to identify your application and the specific WifiLock within it, if it
2510 * holds multiple WifiLocks.
2512 * @return a new, unacquired WifiLock with the given tag.
2514 * @see WifiLock
2516 public WifiLock createWifiLock(String tag) {
2517 return new WifiLock(WIFI_MODE_FULL, tag);
2522 * Create a new MulticastLock
2524 * @param tag a tag for the MulticastLock to identify it in debugging
2525 * messages. This string is never shown to the user under
2526 * normal conditions, but should be descriptive enough to
2527 * identify your application and the specific MulticastLock
2528 * within it, if it holds multiple MulticastLocks.
2530 * @return a new, unacquired MulticastLock with the given tag.
2532 * @see MulticastLock
2534 public MulticastLock createMulticastLock(String tag) {
2535 return new MulticastLock(tag);
2539 * Allows an application to receive Wifi Multicast packets.
2540 * Normally the Wifi stack filters out packets not explicitly
2541 * addressed to this device. Acquring a MulticastLock will
2542 * cause the stack to receive packets addressed to multicast
2543 * addresses. Processing these extra packets can cause a noticable
2544 * battery drain and should be disabled when not needed.
2546 public class MulticastLock {
2547 private String mTag;
2548 private final IBinder mBinder;
2549 private int mRefCount;
2550 private boolean mRefCounted;
2551 private boolean mHeld;
2553 private MulticastLock(String tag) {
2554 mTag = tag;
2555 mBinder = new Binder();
2556 mRefCount = 0;
2557 mRefCounted = true;
2558 mHeld = false;
2562 * Locks Wifi Multicast on until {@link #release} is called.
2564 * If this MulticastLock is reference-counted each call to
2565 * {@code acquire} will increment the reference count, and the
2566 * wifi interface will receive multicast packets as long as the
2567 * reference count is above zero.
2569 * If this MulticastLock is not reference-counted, the first call to
2570 * {@code acquire} will turn on the multicast packets, but subsequent
2571 * calls will be ignored. Only one call to {@link #release} will
2572 * be required, regardless of the number of times that {@code acquire}
2573 * is called.
2575 * Note that other applications may also lock Wifi Multicast on.
2576 * Only they can relinquish their lock.
2578 * Also note that applications cannot leave Multicast locked on.
2579 * When an app exits or crashes, any Multicast locks will be released.
2581 public void acquire() {
2582 synchronized (mBinder) {
2583 if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
2584 try {
2585 mService.acquireMulticastLock(mBinder, mTag);
2586 synchronized (WifiManager.this) {
2587 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
2588 mService.releaseMulticastLock();
2589 throw new UnsupportedOperationException(
2590 "Exceeded maximum number of wifi locks");
2592 mActiveLockCount++;
2594 } catch (RemoteException ignore) {
2596 mHeld = true;
2602 * Unlocks Wifi Multicast, restoring the filter of packets
2603 * not addressed specifically to this device and saving power.
2605 * If this MulticastLock is reference-counted, each call to
2606 * {@code release} will decrement the reference count, and the
2607 * multicast packets will only stop being received when the reference
2608 * count reaches zero. If the reference count goes below zero (that
2609 * is, if {@code release} is called a greater number of times than
2610 * {@link #acquire}), an exception is thrown.
2612 * If this MulticastLock is not reference-counted, the first call to
2613 * {@code release} (after the radio was multicast locked using
2614 * {@link #acquire}) will unlock the multicast, and subsequent calls
2615 * will be ignored.
2617 * Note that if any other Wifi Multicast Locks are still outstanding
2618 * this {@code release} call will not have an immediate effect. Only
2619 * when all applications have released all their Multicast Locks will
2620 * the Multicast filter be turned back on.
2622 * Also note that when an app exits or crashes all of its Multicast
2623 * Locks will be automatically released.
2625 public void release() {
2626 synchronized (mBinder) {
2627 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
2628 try {
2629 mService.releaseMulticastLock();
2630 synchronized (WifiManager.this) {
2631 mActiveLockCount--;
2633 } catch (RemoteException ignore) {
2635 mHeld = false;
2637 if (mRefCount < 0) {
2638 throw new RuntimeException("MulticastLock under-locked "
2639 + mTag);
2645 * Controls whether this is a reference-counted or non-reference-
2646 * counted MulticastLock.
2648 * Reference-counted MulticastLocks keep track of the number of calls
2649 * to {@link #acquire} and {@link #release}, and only stop the
2650 * reception of multicast packets when every call to {@link #acquire}
2651 * has been balanced with a call to {@link #release}. Non-reference-
2652 * counted MulticastLocks allow the reception of multicast packets
2653 * whenever {@link #acquire} is called and stop accepting multicast
2654 * packets whenever {@link #release} is called.
2656 * @param refCounted true if this MulticastLock should keep a reference
2657 * count
2659 public void setReferenceCounted(boolean refCounted) {
2660 mRefCounted = refCounted;
2664 * Checks whether this MulticastLock is currently held.
2666 * @return true if this MulticastLock is held, false otherwise
2668 public boolean isHeld() {
2669 synchronized (mBinder) {
2670 return mHeld;
2674 public String toString() {
2675 String s1, s2, s3;
2676 synchronized (mBinder) {
2677 s1 = Integer.toHexString(System.identityHashCode(this));
2678 s2 = mHeld ? "held; " : "";
2679 if (mRefCounted) {
2680 s3 = "refcounted: refcount = " + mRefCount;
2681 } else {
2682 s3 = "not refcounted";
2684 return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }";
2688 @Override
2689 protected void finalize() throws Throwable {
2690 super.finalize();
2691 setReferenceCounted(false);
2692 release();
2697 * Check multicast filter status.
2699 * @return true if multicast packets are allowed.
2701 * @hide pending API council approval
2703 public boolean isMulticastEnabled() {
2704 try {
2705 return mService.isMulticastEnabled();
2706 } catch (RemoteException e) {
2707 return false;
2712 * Initialize the multicast filtering to 'on'
2713 * @hide no intent to publish
2715 public boolean initializeMulticastFiltering() {
2716 try {
2717 mService.initializeMulticastFiltering();
2718 return true;
2719 } catch (RemoteException e) {
2720 return false;
2724 protected void finalize() throws Throwable {
2725 try {
2726 synchronized (sThreadRefLock) {
2727 if (--sThreadRefCount == 0 && sAsyncChannel != null) {
2728 sAsyncChannel.disconnect();
2731 } finally {
2732 super.finalize();
2737 * Set wifi verbose log. Called from developer settings.
2738 * @hide
2740 public void enableVerboseLogging (int verbose) {
2741 try {
2742 mService.enableVerboseLogging(verbose);
2743 } catch (Exception e) {
2744 //ignore any failure here
2745 Log.e(TAG, "enableVerboseLogging " + e.toString());
2750 * Get the WiFi verbose logging level.This is used by settings
2751 * to decide what to show within the picker.
2752 * @hide
2754 public int getVerboseLoggingLevel() {
2755 try {
2756 return mService.getVerboseLoggingLevel();
2757 } catch (RemoteException e) {
2758 return 0;
2763 * Set wifi Aggressive Handover. Called from developer settings.
2764 * @hide
2766 public void enableAggressiveHandover(int enabled) {
2767 try {
2768 mService.enableAggressiveHandover(enabled);
2769 } catch (RemoteException e) {
2775 * Get the WiFi Handover aggressiveness.This is used by settings
2776 * to decide what to show within the picker.
2777 * @hide
2779 public int getAggressiveHandover() {
2780 try {
2781 return mService.getAggressiveHandover();
2782 } catch (RemoteException e) {
2783 return 0;
2788 * Set setting for allowing Scans when traffic is ongoing.
2789 * @hide
2791 public void setAllowScansWithTraffic(int enabled) {
2792 try {
2793 mService.setAllowScansWithTraffic(enabled);
2794 } catch (RemoteException e) {
2800 * Get setting for allowing Scans when traffic is ongoing.
2801 * @hide
2803 public int getAllowScansWithTraffic() {
2804 try {
2805 return mService.getAllowScansWithTraffic();
2806 } catch (RemoteException e) {
2807 return 0;
2812 * Resets all wifi manager settings back to factory defaults.
2814 * @hide
2816 public void factoryReset() {
2817 try {
2818 mService.factoryReset();
2819 } catch (RemoteException e) {
2824 * Get Network object of current wifi network
2825 * @return Get Network object of current wifi network
2826 * @hide
2828 public Network getCurrentNetwork() {
2829 try {
2830 return mService.getCurrentNetwork();
2831 } catch (RemoteException e) {
2832 return null;
2837 * Framework layer autojoin enable/disable when device is associated
2838 * this will enable/disable autojoin scan and switch network when connected
2839 * @return true -- if set successful false -- if set failed
2840 * @hide
2842 public boolean enableAutoJoinWhenAssociated(boolean enabled) {
2843 try {
2844 return mService.enableAutoJoinWhenAssociated(enabled);
2845 } catch (RemoteException e) {
2846 return false;
2851 * Get setting for Framework layer autojoin enable status
2852 * @hide
2854 public boolean getEnableAutoJoinWhenAssociated() {
2855 try {
2856 return mService.getEnableAutoJoinWhenAssociated();
2857 } catch (RemoteException e) {
2858 return false;
2862 * Set setting for enabling autojoin Offload thru Wifi HAL layer
2863 * @hide
2865 public void setHalBasedAutojoinOffload(int enabled) {
2866 try {
2867 mService.setHalBasedAutojoinOffload(enabled);
2868 } catch (RemoteException e) {
2874 * Get setting for enabling autojoin Offload thru Wifi HAL layer
2875 * @hide
2877 public int getHalBasedAutojoinOffload() {
2878 try {
2879 return mService.getHalBasedAutojoinOffload();
2880 } catch (RemoteException e) {
2882 return 0;