summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl8
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java281
2 files changed, 288 insertions, 1 deletions
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index a7b4544f3752..faae90bec86f 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -131,6 +131,14 @@ interface IWifiManager
boolean stopSoftAp();
+ WifiConfiguration startLocalOnlyHotspot(in Messenger messenger, in IBinder binder);
+
+ void stopLocalOnlyHotspot();
+
+ void startWatchLocalOnlyHotspot(in Messenger messenger, in IBinder binder);
+
+ void stopWatchLocalOnlyHotspot();
+
int getWifiApEnabledState();
WifiConfiguration getWifiApConfiguration();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ab069f2a83d2..7bf1d60d578b 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -40,10 +40,13 @@ import android.os.WorkSource;
import android.util.Log;
import android.util.SparseArray;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.server.net.NetworkPinner;
+import dalvik.system.CloseGuard;
+
import java.net.InetAddress;
import java.util.Collections;
import java.util.List;
@@ -362,7 +365,7 @@ public class WifiManager {
/**
* The look up key for an int that indicates why softAP started failed
* currently support general and no_channel
- * @see #SAP_START_FAILURE_GENERAL
+ * @see #SAP_START_FAILURE_GENERIC
* @see #SAP_START_FAILURE_NO_CHANNEL
*
* @hide
@@ -1809,6 +1812,131 @@ public class WifiManager {
}
/**
+ * Request a local only hotspot that an application can use to communicate between co-located
+ * devices connected to the created WiFi hotspot. The network created by this method will not
+ * have Internet access. Each application can make a single request for the hotspot, but
+ * multiple applications could be requesting the hotspot at the same time. When multiple
+ * applications have successfully registered concurrently, they will be sharing the underlying
+ * hotspot. {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} is called
+ * when the hotspot is ready for use by the application.
+ * <p>
+ * Each application can make a single active call to this method. The {@link
+ * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the
+ * requestor with a {@link LocalOnlyHotspotReservation} that contains a
+ * {@link WifiConfiguration} with the SSID, security type and credentials needed to connect
+ * to the hotspot. Communicating this information is up to the application.
+ * <p>
+ * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)}
+ * method will be called. Example failures include errors bringing up the network or if
+ * there is an incompatible operating mode. For example, if the user is currently using Wifi
+ * Tethering to provide an upstream to another device, LocalOnlyHotspot will not start due to
+ * an incompatible mode. The possible error codes include:
+ * {@link LocalOnlyHotspotCallback#ERROR_NO_CHANNEL},
+ * {@link LocalOnlyHotspotCallback#ERROR_GENERIC} and
+ * {@link LocalOnlyHotspotCallback#ERROR_INCOMPATIBLE_MODE}.
+ * <p>
+ * Internally, requests will be tracked to prevent the hotspot from being torn down while apps
+ * are still using it. The {@link LocalOnlyHotspotReservation} object passed in the {@link
+ * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call should be closed when
+ * the LocalOnlyHotspot is no longer needed using {@link LocalOnlyHotspotReservation#close()}.
+ * Since the hotspot may be shared among multiple applications, removing the final registered
+ * application request will trigger the hotspot teardown. This means that applications should
+ * not listen to broadcasts containing wifi state to determine if the hotspot was stopped after
+ * they are done using it. Additionally, once {@link LocalOnlyHotspotReservation#close()} is
+ * called, applications will not receive callbacks of any kind.
+ * <p>
+ * Applications should be aware that the user may also stop the LocalOnlyHotspot through the
+ * Settings UI; it is not guaranteed to stay up as long as there is a requesting application.
+ * The requestors will be notified of this case via
+ * {@link LocalOnlyHotspotCallback#onStopped()}. Other cases may arise where the hotspot is
+ * torn down (Emergency mode, etc). Application developers should be aware that it can stop
+ * unexpectedly, but they will receive a notification if they have properly registered.
+ * <p>
+ * Applications should also be aware that this network will be shared with other applications.
+ * Applications are responsible for protecting their data on this network (e.g., TLS).
+ * <p>
+ * Applications need to have the following permissions to start LocalOnlyHotspot: {@link
+ * android.Manifest.permission#CHANGE_WIFI_STATE} and {@link
+ * android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION}. Callers without
+ * the permissions will trigger a {@link java.lang.SecurityException}.
+ * <p>
+ * @param callback LocalOnlyHotspotCallback for the application to receive updates about
+ * operating status.
+ * @param handler Handler to be used for callbacks. If the caller passes a null Handler, the
+ * main thread will be used.
+ *
+ * @hide
+ */
+ public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback,
+ @Nullable Handler handler) {
+ throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
+ }
+
+ /**
+ * Cancels a pending local only hotspot request. This can be used by the calling application to
+ * cancel the existing request if the provided callback has not been triggered. Calling this
+ * method will be equivalent to closing the returned LocalOnlyHotspotReservation, but it is not
+ * explicitly required.
+ * <p>
+ * When cancelling this request, application developers should be aware that there may still be
+ * outstanding local only hotspot requests and the hotspot may still start, or continue running.
+ * Additionally, if a callback was registered, it will no longer be triggered after calling
+ * cancel.
+ *
+ * @hide
+ */
+ public void cancelLocalOnlyHotspotRequest() {
+ throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
+ }
+
+ /**
+ * Method used to inform WifiService that the LocalOnlyHotspot is no longer needed. This
+ * method is used by WifiManager to release LocalOnlyHotspotReservations held by calling
+ * applications and removes the internal tracking for the hotspot request. When all requesting
+ * applications are finished using the hotspot, it will be stopped and WiFi will return to the
+ * previous operational mode.
+ *
+ * This method should not be called by applications. Instead, they should call the close()
+ * method on their LocalOnlyHotspotReservation.
+ */
+ private void stopLocalOnlyHotspot() {
+ throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
+ }
+
+ /**
+ * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes. Callers will
+ * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the
+ * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered
+ * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(WifiConfiguration)} and
+ * {@link LocalOnlyHotspotObserver#onStopped()} callbacks.
+ * <p>
+ * Applications should have the
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION}
+ * permission. Callers without the permission will trigger a
+ * {@link java.lang.SecurityException}.
+ * <p>
+ * @param observer LocalOnlyHotspotObserver callback.
+ * @param handler Handler to use for callbacks
+ *
+ * @hide
+ */
+ public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer,
+ @Nullable Handler handler) {
+ throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
+ }
+
+ /**
+ * Allow callers to stop watching LocalOnlyHotspot state changes. After calling this method,
+ * applications will no longer receive callbacks.
+ *
+ * @hide
+ */
+ public void unregisterLocalOnlyHotspotObserver() {
+ throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
+ }
+
+
+ /**
* Gets the Wi-Fi enabled state.
* @return One of {@link #WIFI_AP_STATE_DISABLED},
* {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
@@ -2064,6 +2192,157 @@ public class WifiManager {
public void onFailure(int reason);
}
+ /**
+ * LocalOnlyHotspotReservation that contains the {@link WifiConfiguration} for the active
+ * LocalOnlyHotspot request.
+ * <p>
+ * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the
+ * LocalOnlyHotspotReservation in the
+ * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call. This
+ * reservation contains the relevant {@link WifiConfiguration}.
+ * When an application is done with the LocalOnlyHotspot, they should call {@link
+ * LocalOnlyHotspotReservation#close()}. Once this happens, the application will not receive
+ * any further callbacks. If the LocalOnlyHotspot is stopped due to a
+ * user triggered mode change, applications will be notified via the {@link
+ * LocalOnlyHotspotCallback#onStopped()} callback.
+ *
+ * @hide
+ */
+ public class LocalOnlyHotspotReservation implements AutoCloseable {
+
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+ private final WifiConfiguration mConfig;
+
+ /** @hide */
+ @VisibleForTesting
+ public LocalOnlyHotspotReservation(WifiConfiguration config) {
+ mConfig = config;
+ mCloseGuard.open("close");
+ }
+
+ public WifiConfiguration getConfig() {
+ return mConfig;
+ }
+
+ @Override
+ public void close() {
+ try {
+ stopLocalOnlyHotspot();
+ mCloseGuard.close();
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to stop Local Only Hotspot.");
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+ }
+
+ /**
+ * Callback class for applications to receive updates about the LocalOnlyHotspot status.
+ *
+ * @hide
+ */
+ public static class LocalOnlyHotspotCallback {
+ public static final int ERROR_NO_CHANNEL = 1;
+ public static final int ERROR_GENERIC = 2;
+ public static final int ERROR_INCOMPATIBLE_MODE = 3;
+
+ /** LocalOnlyHotspot start succeeded. */
+ public void onStarted(LocalOnlyHotspotReservation reservation) {};
+
+ /**
+ * LocalOnlyHotspot stopped.
+ * <p>
+ * The LocalOnlyHotspot can be disabled at any time by the user. When this happens,
+ * applications will be notified that it was stopped. This will not be invoked when an
+ * application calls {@link LocalOnlyHotspotReservation#close()}.
+ */
+ public void onStopped() {};
+
+ /**
+ * LocalOnlyHotspot failed to start.
+ * <p>
+ * Applications can attempt to call
+ * {@link WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)} again at
+ * a later time.
+ * <p>
+ * @param reason The reason for failure could be one of: {@link #ERROR_INCOMPATIBLE_MODE},
+ * {@link #ERROR_NO_CHANNEL}, or {@link #ERROR_GENERIC}.
+ */
+ public void onFailed(int reason) { };
+ }
+
+ /**
+ * LocalOnlyHotspotSubscription that is an AutoCloseable object for tracking applications
+ * watching for LocalOnlyHotspot changes.
+ *
+ * @hide
+ */
+ public class LocalOnlyHotspotSubscription implements AutoCloseable {
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+
+ /** @hide */
+ @VisibleForTesting
+ public LocalOnlyHotspotSubscription() {
+ mCloseGuard.open("close");
+ }
+
+ @Override
+ public void close() {
+ try {
+ unregisterLocalOnlyHotspotObserver();
+ mCloseGuard.close();
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to unregister LocalOnlyHotspotObserver.");
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+ }
+
+ /**
+ * Class to notify calling applications that watch for changes in LocalOnlyHotspot of updates.
+ *
+ * @hide
+ */
+ public static class LocalOnlyHotspotObserver {
+ /**
+ * Confirm registration for LocalOnlyHotspotChanges by returning a
+ * LocalOnlyHotspotSubscription.
+ */
+ public void onRegistered(LocalOnlyHotspotSubscription subscription) {};
+
+ /**
+ * LocalOnlyHotspot started with the supplied config.
+ */
+ public void onStarted(WifiConfiguration config) {};
+
+ /**
+ * LocalOnlyHotspot stopped.
+ */
+ public void onStopped() {};
+ }
+
// Ensure that multiple ServiceHandler threads do not interleave message dispatch.
private static final Object sServiceHandlerDispatchLock = new Object();