Merge "WifiManager: add APIs for LOHS" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4bac2d2fd7
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -1808,6 +1811,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},
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user