From a3d14561d5178d452ad0a7624b5fbb2e678aa4b7 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 12 Mar 2021 22:48:07 +0900 Subject: Support calling registerDefaultNetworkCallback for another UID. This is to be used by privileged components (e.g., JobScheduler) to request callbacks about the state of other UIDs on the system. Bug: 165835257 Test: new unit test coverage Change-Id: I29f155710394e58c14fcef488db6271d8d83033a --- .../src/android/net/ConnectivityManager.java | 49 +++++++++++++++++++--- .../src/android/net/IConnectivityManager.aidl | 2 +- 2 files changed, 45 insertions(+), 6 deletions(-) (limited to 'packages') diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java index a5e9f31a5bf7..1a5299bb0035 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java +++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java @@ -3695,8 +3695,9 @@ public class ConnectivityManager { private static final HashMap sCallbacks = new HashMap<>(); private static CallbackHandler sCallbackHandler; - private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback, - int timeoutMs, NetworkRequest.Type reqType, int legacyType, CallbackHandler handler) { + private NetworkRequest sendRequestForNetwork(int asUid, NetworkCapabilities need, + NetworkCallback callback, int timeoutMs, NetworkRequest.Type reqType, int legacyType, + CallbackHandler handler) { printStackTrace(); checkCallbackNotNull(callback); Preconditions.checkArgument( @@ -3721,8 +3722,8 @@ public class ConnectivityManager { getAttributionTag()); } else { request = mService.requestNetwork( - need, reqType.ordinal(), messenger, timeoutMs, binder, legacyType, - callbackFlags, callingPackageName, getAttributionTag()); + asUid, need, reqType.ordinal(), messenger, timeoutMs, binder, + legacyType, callbackFlags, callingPackageName, getAttributionTag()); } if (request != null) { sCallbacks.put(request, callback); @@ -3737,6 +3738,12 @@ public class ConnectivityManager { return request; } + private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback, + int timeoutMs, NetworkRequest.Type reqType, int legacyType, CallbackHandler handler) { + return sendRequestForNetwork(Process.INVALID_UID, need, callback, timeoutMs, reqType, + legacyType, handler); + } + /** * Helper function to request a network with a particular legacy type. * @@ -4220,8 +4227,40 @@ public class ConnectivityManager { @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback, @NonNull Handler handler) { + registerDefaultNetworkCallbackAsUid(Process.INVALID_UID, networkCallback, handler); + } + + /** + * Registers to receive notifications about changes in the default network for the specified + * UID. This may be a physical network or a virtual network, such as a VPN that applies to the + * UID. The callbacks will continue to be called until either the application exits or + * {@link #unregisterNetworkCallback(NetworkCallback)} is called. + * + *

To avoid performance issues due to apps leaking callbacks, the system will limit the + * number of outstanding requests to 100 per app (identified by their UID), shared with + * all variants of this method, of {@link #requestNetwork} as well as + * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}. + * Requesting a network with this method will count toward this limit. If this limit is + * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, + * make sure to unregister the callbacks with + * {@link #unregisterNetworkCallback(NetworkCallback)}. + * + * @param uid the UID for which to track default network changes. + * @param networkCallback The {@link NetworkCallback} that the system will call as the + * UID's default network changes. + * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. + * @throws RuntimeException if the app already has too many callbacks registered. + * @hide + */ + // TODO: @SystemApi(client=MODULE_LIBRARIES) + @SuppressLint({"ExecutorRegistration", "PairedRegistration"}) + @RequiresPermission(anyOf = { + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + public void registerDefaultNetworkCallbackAsUid(int uid, + @NonNull NetworkCallback networkCallback, @NonNull Handler handler) { CallbackHandler cbHandler = new CallbackHandler(handler); - sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0, + sendRequestForNetwork(uid, null /* need */, networkCallback, 0 /* timeoutMs */, TRACK_DEFAULT, TYPE_NONE, cbHandler); } diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl index 3300fa8fd12a..0826922e2165 100644 --- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl +++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl @@ -142,7 +142,7 @@ interface IConnectivityManager in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config, in int factorySerialNumber); - NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType, + NetworkRequest requestNetwork(int uid, in NetworkCapabilities networkCapabilities, int reqType, in Messenger messenger, int timeoutSec, in IBinder binder, int legacy, int callbackFlags, String callingPackageName, String callingAttributionTag); -- cgit v1.2.3 From ab638c1edcce10d47b24aa1f848502c8d8b1cd22 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Mon, 22 Mar 2021 18:23:21 +0900 Subject: Expose registerDefaultNetworkCallbackAsUid. Bug: 165835257 Test: atest FrameworksNetTests Change-Id: I638ed5cd5273d456919630aba1e22f099df1b36c --- packages/Connectivity/framework/api/module-lib-current.txt | 1 + .../Connectivity/framework/src/android/net/ConnectivityManager.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt index aa7a0ac46598..f32f08daf7c0 100644 --- a/packages/Connectivity/framework/api/module-lib-current.txt +++ b/packages/Connectivity/framework/api/module-lib-current.txt @@ -11,6 +11,7 @@ package android.net { method @Nullable public android.net.ProxyInfo getGlobalProxy(); method @NonNull public static android.util.Range getIpSecNetIdRange(); method @NonNull public static String getPrivateDnsMode(@NonNull android.content.Context); + method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackAsUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptPartialConnectivity(@NonNull android.net.Network, boolean, boolean); diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java index 1a5299bb0035..2e240f947d82 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java +++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java @@ -4252,7 +4252,7 @@ public class ConnectivityManager { * @throws RuntimeException if the app already has too many callbacks registered. * @hide */ - // TODO: @SystemApi(client=MODULE_LIBRARIES) + @SystemApi(client = MODULE_LIBRARIES) @SuppressLint({"ExecutorRegistration", "PairedRegistration"}) @RequiresPermission(anyOf = { NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, -- cgit v1.2.3