diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index d04a5bee51..0976b753e6 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.BACKGROUND_REQUEST; import static android.net.NetworkRequest.Type.LISTEN; import static android.net.NetworkRequest.Type.REQUEST; import static android.net.NetworkRequest.Type.TRACK_DEFAULT; +import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT; import static android.net.QosCallback.QosCallbackRegistrationException; import android.annotation.CallbackExecutor; @@ -3721,7 +3722,8 @@ public class ConnectivityManager { printStackTrace(); checkCallbackNotNull(callback); Preconditions.checkArgument( - reqType == TRACK_DEFAULT || need != null, "null NetworkCapabilities"); + reqType == TRACK_DEFAULT || reqType == TRACK_SYSTEM_DEFAULT || need != null, + "null NetworkCapabilities"); final NetworkRequest request; final String callingPackageName = mContext.getOpPackageName(); try { @@ -4192,8 +4194,9 @@ public class ConnectivityManager { } /** - * Registers to receive notifications about changes in the system default network. The callbacks - * will continue to be called until either the application exits or + * Registers to receive notifications about changes in the application's default network. This + * may be a physical network or a virtual network, such as a VPN that applies to the + * application. 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 @@ -4206,7 +4209,7 @@ public class ConnectivityManager { * {@link #unregisterNetworkCallback(NetworkCallback)}. * * @param networkCallback The {@link NetworkCallback} that the system will call as the - * system default network changes. + * application's default network changes. * The callback is invoked on the default internal Handler. * @throws RuntimeException if the app already has too many callbacks registered. */ @@ -4215,11 +4218,47 @@ public class ConnectivityManager { registerDefaultNetworkCallback(networkCallback, getDefaultHandler()); } + /** + * Registers to receive notifications about changes in the application's default network. This + * may be a physical network or a virtual network, such as a VPN that applies to the + * application. 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 networkCallback The {@link NetworkCallback} that the system will call as the + * application'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. + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback, + @NonNull Handler handler) { + CallbackHandler cbHandler = new CallbackHandler(handler); + sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0, + TRACK_DEFAULT, TYPE_NONE, cbHandler); + } + /** * Registers to receive notifications about changes in the system default network. The callbacks * will continue to be called until either the application exits or * {@link #unregisterNetworkCallback(NetworkCallback)} is called. * + * This method should not be used to determine networking state seen by applications, because in + * many cases, most or even all application traffic may not use the default network directly, + * and traffic from different applications may go on different networks by default. As an + * example, if a VPN is connected, traffic from all applications might be sent through the VPN + * and not onto the system default network. Applications or system components desiring to do + * determine network state as seen by applications should use other methods such as + * {@link #registerDefaultNetworkCallback(NetworkCallback, Handler)}. + * *
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
@@ -4233,20 +4272,19 @@ public class ConnectivityManager {
* system 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
*/
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
+ @SystemApi(client = MODULE_LIBRARIES)
+ @SuppressLint({"ExecutorRegistration", "PairedRegistration"})
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_SETTINGS})
+ public void registerSystemDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
@NonNull Handler handler) {
- // This works because if the NetworkCapabilities are null,
- // ConnectivityService takes them from the default request.
- //
- // Since the capabilities are exactly the same as the default request's
- // capabilities, this request is guaranteed, at all times, to be
- // satisfied by the same network, if any, that satisfies the default
- // request, i.e., the system default network.
CallbackHandler cbHandler = new CallbackHandler(handler);
sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0,
- TRACK_DEFAULT, TYPE_NONE, cbHandler);
+ TRACK_SYSTEM_DEFAULT, TYPE_NONE, cbHandler);
}
/**
diff --git a/framework/src/android/net/NetworkRequest.java b/framework/src/android/net/NetworkRequest.java
index 6540397d62..b4a651c060 100644
--- a/framework/src/android/net/NetworkRequest.java
+++ b/framework/src/android/net/NetworkRequest.java
@@ -104,17 +104,14 @@ public class NetworkRequest implements Parcelable {
* callbacks about the single, highest scoring current network
* (if any) that matches the specified NetworkCapabilities, or
*
- * - TRACK_DEFAULT, a hybrid of the two designed such that the
- * framework will issue callbacks for the single, highest scoring
- * current network (if any) that matches the capabilities of the
- * default Internet request (mDefaultRequest), but which cannot cause
- * the framework to either create or retain the existence of any
- * specific network. Note that from the point of view of the request
- * matching code, TRACK_DEFAULT is identical to REQUEST: its special
- * behaviour is not due to different semantics, but to the fact that
- * the system will only ever create a TRACK_DEFAULT with capabilities
- * that are identical to the default request's capabilities, thus
- * causing it to share fate in every way with the default request.
+ * - TRACK_DEFAULT, which causes the framework to issue callbacks for
+ * the single, highest scoring current network (if any) that will
+ * be chosen for an app, but which cannot cause the framework to
+ * either create or retain the existence of any specific network.
+ *
+ * - TRACK_SYSTEM_DEFAULT, which causes the framework to send callbacks
+ * for the network (if any) that satisfies the default Internet
+ * request.
*
* - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
* to retain the NET_CAPABILITY_FOREGROUND capability. A network with
@@ -137,6 +134,7 @@ public class NetworkRequest implements Parcelable {
TRACK_DEFAULT,
REQUEST,
BACKGROUND_REQUEST,
+ TRACK_SYSTEM_DEFAULT,
};
/**
@@ -601,6 +599,8 @@ public class NetworkRequest implements Parcelable {
return NetworkRequestProto.TYPE_REQUEST;
case BACKGROUND_REQUEST:
return NetworkRequestProto.TYPE_BACKGROUND_REQUEST;
+ case TRACK_SYSTEM_DEFAULT:
+ return NetworkRequestProto.TYPE_TRACK_SYSTEM_DEFAULT;
default:
return NetworkRequestProto.TYPE_UNKNOWN;
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 06f935833d..5164437b68 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5746,6 +5746,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
throw new SecurityException("Insufficient permissions to specify legacy type");
}
}
+ final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities;
final int callingUid = mDeps.getCallingUid();
final NetworkRequest.Type reqType;
try {
@@ -5756,11 +5757,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
switch (reqType) {
case TRACK_DEFAULT:
// If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities}
- // is unused and will be replaced by the one from the default network request.
- // This allows callers to keep track of the system default network.
+ // is unused and will be replaced by ones appropriate for the caller.
+ // This allows callers to keep track of the default network for their app.
networkCapabilities = createDefaultNetworkCapabilitiesForUid(callingUid);
enforceAccessPermission();
break;
+ case TRACK_SYSTEM_DEFAULT:
+ enforceSettingsPermission();
+ networkCapabilities = new NetworkCapabilities(defaultNc);
+ break;
case BACKGROUND_REQUEST:
enforceNetworkStackOrSettingsPermission();
// Fall-through since other checks are the same with normal requests.
@@ -5779,6 +5784,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
ensureRequestableCapabilities(networkCapabilities);
ensureSufficientPermissionsForRequest(networkCapabilities,
Binder.getCallingPid(), callingUid, callingPackageName);
+
// Set the UID range for this request to the single UID of the requester, or to an empty
// set of UIDs if the caller has the appropriate permission and UIDs have not been set.
// This will overwrite any allowed UIDs in the requested capabilities. Though there
@@ -5798,6 +5804,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
new NetworkRequestInfo(messenger, networkRequest, binder, callingAttributionTag);
if (DBG) log("requestNetwork for " + nri);
+ // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
+ // copied from the default request above. (This is necessary to ensure, for example, that
+ // the callback does not leak sensitive information to unprivileged apps.) Check that the
+ // changes don't alter request matching.
+ if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT &&
+ (!networkCapabilities.equalRequestableCapabilities(defaultNc))) {
+ Log.wtf(TAG, "TRACK_SYSTEM_DEFAULT capabilities don't match default request: "
+ + networkCapabilities + " vs. " + defaultNc);
+ }
+
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
if (timeoutMs > 0) {
mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index bff1a5c99d..c05e25367d 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -717,8 +717,9 @@ public class NetworkAgentInfo implements Comparable