Add reserveNetwork API
reserveNetwork allows a requestor to initiate the creation of a network
that requires the system to preallocate resources which can then be
advertised by the requestor on or off device in order to help create the
network.
For example, this API will be used to reserve a IP over L2cap server
network, which requires the system to first create a
BluetoothServerSocket and reserve a PSM (i.e. port). This information is
passed back to the requestor via onReserved() callback and subsequently
advertised via a BLE advertisement. The network is established as soon
as the client connects to the advertised PSM, which will trigger a call
to onAvailable(), just like a regular NetworkRequest.
onReserved() callbacks are exclusive to the reserveNetwork API and are
sent when an NetworkOffer is registered that matches the reservation ID
of an existing request. A reserved offer always follows the reservation
request as it is created in direct response. onReserved() can only be
called once. If for some reason the reservation gets cancelled by the
system (i.e. the NetworkOffer is retracted) or cannot be fulfilled,
onUnavailable() is called. It is up to the app to file a new
NetworkRequest when this happens.
An onReserved() callback is not queued, because
a) it cannot be called more than once for the same reservation,
b) it must always be the first callback, and
c) it only gets cancelled by onUnavailable().
This change does not handle NetworkOffer migrations, such as updating
the score, properly. This must be addressed before the feature can ship
as the yieldToBadWifi logic can update the score on all NetworkOffers.
API-Coverage-Bug: 372936361
Test: Very basic CSNetworkReservationTest; more to follow.
Change-Id: I9b349d469830bf28e006cf403c605574371db267
diff --git a/framework/api/current.txt b/framework/api/current.txt
index 32dcfd9..797c107 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -103,6 +103,7 @@
method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, int);
method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler, int);
method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.app.PendingIntent);
+ method @FlaggedApi("com.android.net.flags.ipv6_over_ble") public void reserveNetwork(@NonNull android.net.NetworkRequest, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
method @Deprecated public void setNetworkPreference(int);
method @Deprecated public static boolean setProcessDefaultNetwork(@Nullable android.net.Network);
method public void unregisterNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback);
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 33a443e..9016d13 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -21,6 +21,7 @@
import static android.net.NetworkRequest.Type.LISTEN;
import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
import static android.net.NetworkRequest.Type.REQUEST;
+import static android.net.NetworkRequest.Type.RESERVATION;
import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT;
import static android.net.QosCallback.QosCallbackRegistrationException;
@@ -4271,12 +4272,18 @@
private static final int METHOD_ONLOST = 6;
/**
- * Called if no network is found within the timeout time specified in
- * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} call or if the
- * requested network request cannot be fulfilled (whether or not a timeout was
- * specified). When this callback is invoked the associated
- * {@link NetworkRequest} will have already been removed and released, as if
- * {@link #unregisterNetworkCallback(NetworkCallback)} had been called.
+ * If the callback was registered with one of the {@code requestNetwork} methods, this will
+ * be called if no network is found within the timeout specified in {@link
+ * #requestNetwork(NetworkRequest, NetworkCallback, int)} call or if the requested network
+ * request cannot be fulfilled (whether or not a timeout was specified).
+ *
+ * If the callback was registered when reserving a network, this method indicates that the
+ * reservation is removed. It can be called when the reservation is requested, because the
+ * system could not satisfy the reservation, or after the reserved network connects.
+ *
+ * When this callback is invoked the associated {@link NetworkRequest} will have already
+ * been removed and released, as if {@link #unregisterNetworkCallback(NetworkCallback)} had
+ * been called.
*/
@FilteredCallback(methodId = METHOD_ONUNAVAILABLE, calledByCallbackId = CALLBACK_UNAVAIL)
public void onUnavailable() {}
@@ -5008,6 +5015,41 @@
}
/**
+ * Reserve a network to satisfy a set of {@link NetworkCapabilities}.
+ *
+ * Some types of networks require the system to generate (i.e. reserve) some set of information
+ * before a network can be connected. For such networks, {@link #reserveNetwork} can be used
+ * which may lead to a call to {@link NetworkCallback#onReserved(NetworkCapabilities)}
+ * containing the {@link NetworkCapabilities} that were reserved.
+ *
+ * A reservation reserves at most one network. If the network connects, a reservation request
+ * behaves similar to a request filed using {@link #requestNetwork}. The provided {@link
+ * NetworkCallback} will only be called for the reserved network.
+ *
+ * If the system determines that the requested reservation can never be fulfilled, {@link
+ * NetworkCallback#onUnavailable} is called, the reservation is released by the system, and the
+ * provided callback can be reused. Otherwise, the reservation remains in place until the
+ * requested network connects. There is no guarantee that the reserved network will ever
+ * connect.
+ *
+ * @param request {@link NetworkRequest} describing this request.
+ * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
+ * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
+ * the callback must not be shared - it uniquely specifies this request.
+ */
+ // TODO: add executor overloads for all network request methods. Any method that passed an
+ // Executor could process the messages on the singleton ConnectivityThread Handler.
+ @SuppressLint("ExecutorRegistration")
+ @FlaggedApi(Flags.FLAG_IPV6_OVER_BLE)
+ public void reserveNetwork(@NonNull NetworkRequest request,
+ @NonNull Handler handler,
+ @NonNull NetworkCallback networkCallback) {
+ final CallbackHandler cbHandler = new CallbackHandler(handler);
+ final NetworkCapabilities nc = request.networkCapabilities;
+ sendRequestForNetwork(nc, networkCallback, 0, RESERVATION, TYPE_NONE, cbHandler);
+ }
+
+ /**
* Request a network to satisfy a set of {@link NetworkCapabilities}, limited
* by a timeout.
*