diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 3a3c47d860..94d8b2d594 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2513,7 +2513,7 @@ public class ConnectivityManager { * Intent to reserve the network or it will be released shortly after the Intent * is processed. *
- * If there is already an request for this Intent registered (with the equality of + * If there is already a request for this Intent registered (with the equality of * two Intents defined by {@link Intent#filterEquals}), then it will be removed and * replaced by this one, effectively releasing the previous {@link NetworkRequest}. *
@@ -2572,6 +2572,44 @@ public class ConnectivityManager { sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, LISTEN, TYPE_NONE); } + /** + * Registers a PendingIntent to be sent when a network is available which satisfies the given + * {@link NetworkRequest}. + * + * This function behaves identically to the version that takes a NetworkCallback, but instead + * of {@link NetworkCallback} a {@link PendingIntent} is used. This means + * the request may outlive the calling application and get called back when a suitable + * network is found. + *
+ * The operation is an Intent broadcast that goes to a broadcast receiver that + * you registered with {@link Context#registerReceiver} or through the + * <receiver> tag in an AndroidManifest.xml file + *
+ * The operation Intent is delivered with two extras, a {@link Network} typed + * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest} + * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing + * the original requests parameters. + *
+ * If there is already a request for this Intent registered (with the equality of + * two Intents defined by {@link Intent#filterEquals}), then it will be removed and + * replaced by this one, effectively releasing the previous {@link NetworkRequest}. + *
+ * The request may be released normally by calling + * {@link #releaseNetworkRequest(android.app.PendingIntent)}. + *
This method requires the caller to hold the permission + * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}. + * @param request {@link NetworkRequest} describing this request. + * @param operation Action to perform when the network is available (corresponds + * to the {@link NetworkCallback#onAvailable} call. Typically + * comes from {@link PendingIntent#getBroadcast}. Cannot be null. + */ + public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) { + checkPendingIntent(operation); + try { + mService.pendingListenForNetwork(request.networkCapabilities, operation); + } catch (RemoteException e) {} + } + /** * Requests bandwidth update for a given {@link Network} and returns whether the update request * is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 9c6e16f509..f72f0902e8 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -324,7 +324,7 @@ public class ConnectivityService extends IConnectivityManager.Stub /** * used to add a network request with a pending intent - * includes a NetworkRequestInfo + * obj = NetworkRequestInfo */ private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26; @@ -354,6 +354,12 @@ public class ConnectivityService extends IConnectivityManager.Stub */ private static final int EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON = 30; + /** + * used to add a network listener with a pending intent + * obj = NetworkRequestInfo + */ + private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31; + /** Handler used for internal events. */ final private InternalHandler mHandler; /** Handler used for incoming {@link NetworkStateTracker} events. */ @@ -2524,7 +2530,8 @@ public class ConnectivityService extends IConnectivityManager.Stub handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj); break; } - case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: { + case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: + case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: { handleRegisterNetworkRequestWithIntent(msg); break; } @@ -3760,6 +3767,18 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation) { + checkNotNull(operation, "PendingIntent cannot be null."); + if (!hasWifiNetworkListenPermission(networkCapabilities)) { + enforceAccessPermission(); + } + + NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities( + networkCapabilities), TYPE_NONE, nextNetworkRequestId()); + if (DBG) log("pendingListenForNetwork for " + networkRequest + " to trigger " + operation); + NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation, + NetworkRequestInfo.LISTEN); + + mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); } @Override