diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 111a8c48a4..5c65238b3e 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3265,42 +3265,77 @@ public class ConnectivityManager { /** * Called when the framework connects and has declared a new network ready for use. - * This callback may be called more than once if the {@link Network} that is - * satisfying the request changes. This will always immediately be followed by a - * call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a - * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}, and a call to - * {@link #onBlockedStatusChanged(Network, boolean)}. + * + *
For callbacks registered with {@link #registerNetworkCallback}, multiple networks may + * be available at the same time, and onAvailable will be called for each of these as they + * appear. + * + *
For callbacks registered with {@link #requestNetwork} and + * {@link #registerDefaultNetworkCallback}, this means the network passed as an argument + * is the new best network for this request and is now tracked by this callback ; this + * callback will no longer receive method calls about other networks that may have been + * passed to this method previously. The previously-best network may have disconnected, or + * it may still be around and the newly-best network may simply be better. + * + *
Starting with {@link android.os.Build.VERSION_CODES#O}, this will always immediately + * be followed by a call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} + * then by a call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}, and a call + * to {@link #onBlockedStatusChanged(Network, boolean)}. + * + *
Do NOT call {@link #getNetworkCapabilities(Network)} or + * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in + * this callback as this is prone to race conditions (there is no guarantee the objects + * returned by these methods will be current). Instead, wait for a call to + * {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} and + * {@link #onLinkPropertiesChanged(Network, LinkProperties)} whose arguments are guaranteed + * to be well-ordered with respect to other callbacks. * * @param network The {@link Network} of the satisfying network. */ public void onAvailable(@NonNull Network network) {} /** - * Called when the network is about to be disconnected. Often paired with an - * {@link NetworkCallback#onAvailable} call with the new replacement network - * for graceful handover. This may not be called if we have a hard loss - * (loss without warning). This may be followed by either a - * {@link NetworkCallback#onLost} call or a - * {@link NetworkCallback#onAvailable} call for this network depending - * on whether we lose or regain it. + * Called when the network is about to be lost, typically because there are no outstanding + * requests left for it. This may be paired with a {@link NetworkCallback#onAvailable} call + * with the new replacement network for graceful handover. This method is not guaranteed + * to be called before {@link NetworkCallback#onLost} is called, for example in case a + * network is suddenly disconnected. * - * @param network The {@link Network} that is about to be disconnected. - * @param maxMsToLive The time in ms the framework will attempt to keep the - * network connected. Note that the network may suffer a - * hard loss at any time. + *
Do NOT call {@link #getNetworkCapabilities(Network)} or + * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in + * this callback as this is prone to race conditions ; calling these methods while in a + * callback may return an outdated or even a null object. + * + * @param network The {@link Network} that is about to be lost. + * @param maxMsToLive The time in milliseconds the system intends to keep the network + * connected for graceful handover; note that the network may still + * suffer a hard loss at any time. */ public void onLosing(@NonNull Network network, int maxMsToLive) {} /** - * Called when the framework has a hard loss of the network or when the - * graceful failure ends. + * Called when a network disconnects or otherwise no longer satisfies this request or + * callback. + * + *
If the callback was registered with requestNetwork() or + * registerDefaultNetworkCallback(), it will only be invoked against the last network + * returned by onAvailable() when that network is lost and no other network satisfies + * the criteria of the request. + * + *
If the callback was registered with registerNetworkCallback() it will be called for + * each network which no longer satisfies the criteria of the callback. + * + *
Do NOT call {@link #getNetworkCapabilities(Network)} or + * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in + * this callback as this is prone to race conditions ; calling these methods while in a + * callback may return an outdated or even a null object. * * @param network The {@link Network} lost. */ public void onLost(@NonNull Network network) {} /** - * Called if no network is found in the timeout time specified in + * 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 @@ -3310,8 +3345,15 @@ public class ConnectivityManager { public void onUnavailable() {} /** - * Called when the network the framework connected to for this request - * changes capabilities but still satisfies the stated need. + * Called when the network corresponding to this request changes capabilities but still + * satisfies the requested criteria. + * + *
Starting with {@link android.os.Build.VERSION_CODES#O} this method is guaranteed + * to be called immediately after {@link #onAvailable}. + * + *
Do NOT call {@link #getLinkProperties(Network)} or other synchronous + * ConnectivityManager methods in this callback as this is prone to race conditions : + * calling these methods while in a callback may return an outdated or even a null object. * * @param network The {@link Network} whose capabilities have changed. * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this @@ -3321,8 +3363,14 @@ public class ConnectivityManager { @NonNull NetworkCapabilities networkCapabilities) {} /** - * Called when the network the framework connected to for this request - * changes {@link LinkProperties}. + * Called when the network corresponding to this request changes {@link LinkProperties}. + * + *
Starting with {@link android.os.Build.VERSION_CODES#O} this method is guaranteed + * to be called immediately after {@link #onAvailable}. + * + *
Do NOT call {@link #getNetworkCapabilities(Network)} or other synchronous + * ConnectivityManager methods in this callback as this is prone to race conditions : + * calling these methods while in a callback may return an outdated or even a null object. * * @param network The {@link Network} whose link properties have changed. * @param linkProperties The new {@link LinkProperties} for this network. @@ -3331,12 +3379,20 @@ public class ConnectivityManager { @NonNull LinkProperties linkProperties) {} /** - * Called when the network the framework connected to for this request - * goes into {@link NetworkInfo.State#SUSPENDED}. - * This generally means that while the TCP connections are still live, - * temporarily network data fails to transfer. Specifically this is used - * on cellular networks to mask temporary outages when driving through - * a tunnel, etc. + * Called when the network the framework connected to for this request suspends data + * transmission temporarily. + * + *
This generally means that while the TCP connections are still live temporarily + * network data fails to transfer. To give a specific example, this is used on cellular + * networks to mask temporary outages when driving through a tunnel, etc. In general this + * means read operations on sockets on this network will block once the buffers are + * drained, and write operations will block once the buffers are full. + * + *
Do NOT call {@link #getNetworkCapabilities(Network)} or + * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in + * this callback as this is prone to race conditions (there is no guarantee the objects + * returned by these methods will be current). + * * @hide */ public void onNetworkSuspended(@NonNull Network network) {} @@ -3345,6 +3401,12 @@ public class ConnectivityManager { * Called when the network the framework connected to for this request * returns from a {@link NetworkInfo.State#SUSPENDED} state. This should always be * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call. + + *
Do NOT call {@link #getNetworkCapabilities(Network)} or + * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in + * this callback as this is prone to race conditions : calling these methods while in a + * callback may return an outdated or even a null object. + * * @hide */ public void onNetworkResumed(@NonNull Network network) {} @@ -3352,6 +3414,11 @@ public class ConnectivityManager { /** * Called when access to the specified network is blocked or unblocked. * + *
Do NOT call {@link #getNetworkCapabilities(Network)} or + * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in + * this callback as this is prone to race conditions : calling these methods while in a + * callback may return an outdated or even a null object. + * * @param network The {@link Network} whose blocked status has changed. * @param blocked The blocked status of this {@link Network}. */ @@ -3588,13 +3655,51 @@ public class ConnectivityManager { /** * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}. * - * This {@link NetworkRequest} will live until released via - * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A - * version of the method which takes a timeout is - * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}. - * Status of the request can be followed by listening to the various - * callbacks described in {@link NetworkCallback}. The {@link Network} - * can be used to direct traffic to the network. + *
This method will attempt to find the best network that matches the passed + * {@link NetworkRequest}, and to bring up one that does if none currently satisfies the + * criteria. The platform will evaluate which network is the best at its own discretion. + * Throughput, latency, cost per byte, policy, user preference and other considerations + * may be factored in the decision of what is considered the best network. + * + *
As long as this request is outstanding, the platform will try to maintain the best network + * matching this request, while always attempting to match the request to a better network if + * possible. If a better match is found, the platform will switch this request to the now-best + * network and inform the app of the newly best network by invoking + * {@link NetworkCallback#onAvailable(Network)} on the provided callback. Note that the platform + * will not try to maintain any other network than the best one currently matching the request: + * a network not matching any network request may be disconnected at any time. + * + *
For example, an application could use this method to obtain a connected cellular network + * even if the device currently has a data connection over Ethernet. This may cause the cellular + * radio to consume additional power. Or, an application could inform the system that it wants + * a network supporting sending MMSes and have the system let it know about the currently best + * MMS-supporting network through the provided {@link NetworkCallback}. + * + *
The status of the request can be followed by listening to the various callbacks described + * in {@link NetworkCallback}. The {@link Network} object passed to the callback methods can be + * used to direct traffic to the network (although accessing some networks may be subject to + * holding specific permissions). Callers will learn about the specific characteristics of the + * network through + * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)} and + * {@link NetworkCallback#onLinkPropertiesChanged(Network, LinkProperties)}. The methods of the + * provided {@link NetworkCallback} will only be invoked due to changes in the best network + * matching the request at any given time; therefore when a better network matching the request + * becomes available, the {@link NetworkCallback#onAvailable(Network)} method is called + * with the new network after which no further updates are given about the previously-best + * network, unless it becomes the best again at some later time. All callbacks are invoked + * in order on the same thread, which by default is a thread created by the framework running + * in the app. + * {@see #requestNetwork(NetworkRequest, NetworkCallback, Handler)} to change where the + * callbacks are invoked. + * + *
This{@link NetworkRequest} will live until released via + * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits, at + * which point the system may let go of the network at any time. + * + *
A version of this method which takes a timeout is + * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}, that an app can use to only + * wait for a limited amount of time for the network to become unavailable. + * *
It is presently unsupported to request a network with mutable * {@link NetworkCapabilities} such as * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or @@ -3602,7 +3707,7 @@ public class ConnectivityManager { * as these {@code NetworkCapabilities} represent states that a particular * network may never attain, and whether a network will attain these states * is unknown prior to bringing up the network so the framework does not - * know how to go about satisfing a request with these capabilities. + * know how to go about satisfying a request with these capabilities. * *
This method requires the caller to hold either the * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission @@ -3625,34 +3730,17 @@ public class ConnectivityManager { /** * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}. * - * This {@link NetworkRequest} will live until released via - * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A - * version of the method which takes a timeout is - * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}. - * Status of the request can be followed by listening to the various - * callbacks described in {@link NetworkCallback}. The {@link Network} - * can be used to direct traffic to the network. - *
It is presently unsupported to request a network with mutable - * {@link NetworkCapabilities} such as - * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or - * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL} - * as these {@code NetworkCapabilities} represent states that a particular - * network may never attain, and whether a network will attain these states - * is unknown prior to bringing up the network so the framework does not - * know how to go about satisfying a request with these capabilities. + * This method behaves identically to {@link #requestNetwork(NetworkRequest, NetworkCallback)} + * but runs all the callbacks on the passed Handler. * - *
This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.
+ *This method has the same permission requirements as + * {@link #requestNetwork(NetworkRequest, NetworkCallback)} and throws the same exceptions in + * the same conditions. * * @param request {@link NetworkRequest} describing this request. * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note * the callback must not be shared - it uniquely specifies this request. * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. - * @throws IllegalArgumentException if {@code request} contains invalid network capabilities. - * @throws SecurityException if missing the appropriate permissions. - * @throws RuntimeException if request limit per UID is exceeded. */ public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, @NonNull Handler handler) { @@ -3677,10 +3765,9 @@ public class ConnectivityManager { * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided * for that purpose. Calling this method will attempt to bring up the requested network. * - *
This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.
+ *This method has the same permission requirements as + * {@link #requestNetwork(NetworkRequest, NetworkCallback)} and throws the same exceptions in + * the same conditions. * * @param request {@link NetworkRequest} describing this request. * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note @@ -3688,9 +3775,6 @@ public class ConnectivityManager { * @param timeoutMs The time in milliseconds to attempt looking for a suitable network * before {@link NetworkCallback#onUnavailable()} is called. The timeout must * be a positive value (i.e. >0). - * @throws IllegalArgumentException if {@code request} contains invalid network capabilities. - * @throws SecurityException if missing the appropriate permissions. - * @throws RuntimeException if request limit per UID is exceeded. */ public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, int timeoutMs) { @@ -3703,21 +3787,13 @@ public class ConnectivityManager { * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited * by a timeout. * - * This function behaves identically to the version without timeout, but if a suitable - * network is not found within the given time (in milliseconds) the - * {@link NetworkCallback#onUnavailable} callback is called. The request can still be - * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does - * not have to be released if timed-out (it is automatically released). Unregistering a - * request that timed out is not an error. + * This method behaves identically to + * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} but runs all the callbacks + * on the passed Handler. * - *
Do not use this method to poll for the existence of specific networks (e.g. with a small - * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided - * for that purpose. Calling this method will attempt to bring up the requested network. - * - *
This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.
+ *This method has the same permission requirements as + * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} and throws the same exceptions + * in the same conditions. * * @param request {@link NetworkRequest} describing this request. * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note @@ -3725,9 +3801,6 @@ public class ConnectivityManager { * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. * @param timeoutMs The time in milliseconds to attempt looking for a suitable network * before {@link NetworkCallback#onUnavailable} is called. - * @throws IllegalArgumentException if {@code request} contains invalid network capabilities. - * @throws SecurityException if missing the appropriate permissions. - * @throws RuntimeException if request limit per UID is exceeded. */ public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) {