Merge "Expose ConnectivitySettingsManager as module-lib API" into sc-dev
diff --git a/framework/Android.bp b/framework/Android.bp
index 3553c1f..fdfb108 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -26,6 +26,7 @@
java_library {
name: "framework-connectivity-protos",
sdk_version: "module_current",
+ min_sdk_version: "30",
proto: {
type: "nano",
},
@@ -81,11 +82,13 @@
java_sdk_library {
name: "framework-connectivity",
- api_only: true,
+ sdk_version: "module_current",
+ min_sdk_version: "30",
defaults: ["framework-module-defaults"],
installable: true,
srcs: [
":framework-connectivity-sources",
+ ":net-utils-framework-common-srcs",
],
aidl: {
include_dirs: [
@@ -97,10 +100,34 @@
"frameworks/native/aidl/binder", // For PersistableBundle.aidl
],
},
+ impl_only_libs: [
+ // TODO (b/183097033) remove once module_current includes core_platform
+ "stable.core.platform.api.stubs",
+ "framework-tethering.stubs.module_lib",
+ "framework-wifi.stubs.module_lib",
+ "net-utils-device-common",
+ ],
libs: [
"unsupportedappusage",
],
+ static_libs: [
+ "framework-connectivity-protos",
+ ],
+ jarjar_rules: "jarjar-rules.txt",
permitted_packages: ["android.net"],
+ impl_library_visibility: [
+ "//packages/modules/Connectivity/Tethering/apex",
+ // In preparation for future move
+ "//packages/modules/Connectivity/apex",
+ "//packages/modules/Connectivity/service",
+ "//frameworks/base/packages/Connectivity/service",
+ "//frameworks/base",
+ "//packages/modules/Connectivity/Tethering/tests/unit",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.tethering",
+ ],
}
cc_defaults {
@@ -109,13 +136,15 @@
"-Wall",
"-Werror",
"-Wno-unused-parameter",
+ // Don't warn about S API usage even with
+ // min_sdk 30: the library is only loaded
+ // on S+ devices
+ "-Wno-unguarded-availability",
"-Wthread-safety",
],
shared_libs: [
- "libbase",
"liblog",
"libnativehelper",
- "libnetd_client",
],
header_libs: [
"dnsproxyd_protocol_headers",
@@ -137,43 +166,15 @@
cc_library_shared {
name: "libframework-connectivity-jni",
+ min_sdk_version: "30",
defaults: ["libframework-connectivity-defaults"],
srcs: [
+ "jni/android_net_NetworkUtils.cpp",
"jni/onload.cpp",
],
shared_libs: ["libandroid"],
- static_libs: ["libconnectivityframeworkutils"],
+ stl: "libc++_static",
apex_available: [
- "//apex_available:platform",
"com.android.tethering",
],
}
-
-java_library {
- name: "framework-connectivity.impl",
- sdk_version: "module_current",
- srcs: [
- ":framework-connectivity-sources",
- ],
- aidl: {
- include_dirs: [
- "frameworks/base/core/java", // For framework parcelables
- "frameworks/native/aidl/binder", // For PersistableBundle.aidl
- ],
- },
- libs: [
- // TODO (b/183097033) remove once module_current includes core_current
- "stable.core.platform.api.stubs",
- "framework-tethering",
- "framework-wifi",
- "unsupportedappusage",
- ],
- static_libs: [
- "framework-connectivity-protos",
- "net-utils-device-common",
- ],
- jarjar_rules: "jarjar-rules.txt",
- apex_available: ["com.android.tethering"],
- installable: true,
- permitted_packages: ["android.net"],
-}
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index 4a03c15..41c5609 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -28,6 +28,14 @@
field public static final String ACTION_PROMPT_LOST_VALIDATION = "android.net.action.PROMPT_LOST_VALIDATION";
field public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = "android.net.action.PROMPT_PARTIAL_CONNECTIVITY";
field public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED";
+ field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
+ field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
+ field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
+ field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
+ field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
+ field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
+ field public static final int BLOCKED_REASON_NONE = 0; // 0x0
+ field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
field public static final String PRIVATE_DNS_MODE_OFF = "off";
field public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
field public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 9dcc391..593698e 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -218,6 +218,8 @@
method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
method public void onAutomaticReconnectDisabled();
method public void onBandwidthUpdateRequested();
+ method public void onNetworkCreated();
+ method public void onNetworkDisconnected();
method public void onNetworkUnwanted();
method public void onQosCallbackRegistered(int, @NonNull android.net.QosFilter);
method public void onQosCallbackUnregistered(int);
@@ -232,8 +234,8 @@
method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
method public final void sendNetworkScore(@IntRange(from=0, to=99) int);
method public final void sendQosCallbackError(int, int);
- method public final void sendQosSessionAvailable(int, int, @NonNull android.telephony.data.EpsBearerQosSessionAttributes);
- method public final void sendQosSessionLost(int, int);
+ method public final void sendQosSessionAvailable(int, int, @NonNull android.net.QosSessionAttributes);
+ method public final void sendQosSessionLost(int, int, int);
method public final void sendSocketKeepaliveEvent(int, int);
method @Deprecated public void setLegacySubtype(int, @NonNull String);
method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
@@ -385,6 +387,7 @@
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
field public static final int TYPE_EPS_BEARER = 1; // 0x1
+ field public static final int TYPE_NR_BEARER = 2; // 0x2
}
public interface QosSessionAttributes {
diff --git a/framework/jni/android_net_NetworkUtils.cpp b/framework/jni/android_net_NetworkUtils.cpp
index fd4d9db..e8bb42d 100644
--- a/framework/jni/android_net_NetworkUtils.cpp
+++ b/framework/jni/android_net_NetworkUtils.cpp
@@ -37,7 +37,6 @@
#include <utils/Log.h>
#include <utils/misc.h>
-#include "NetdClient.h"
#include "jni.h"
extern "C" {
@@ -113,14 +112,14 @@
}
static jboolean android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz,
- jint netId)
+ jint netId, jlong netHandle)
{
- return (jboolean) !setNetworkForResolv(netId);
+ return (jboolean) !android_setprocdns(netHandle);
}
-static jint android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, jobject javaFd,
- jint netId) {
- return setNetworkForSocket(netId, AFileDescriptor_getFD(env, javaFd));
+static jint android_net_utils_bindSocketToNetworkHandle(JNIEnv *env, jobject thiz, jobject javaFd,
+ jlong netHandle) {
+ return android_setsocknetwork(netHandle, AFileDescriptor_getFD(env, javaFd));
}
static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst)
@@ -132,7 +131,7 @@
return true;
}
-static jobject android_net_utils_resNetworkQuery(JNIEnv *env, jobject thiz, jint netId,
+static jobject android_net_utils_resNetworkQuery(JNIEnv *env, jobject thiz, jlong netHandle,
jstring dname, jint ns_class, jint ns_type, jint flags) {
const jsize javaCharsCount = env->GetStringLength(dname);
const jsize byteCountUTF8 = env->GetStringUTFLength(dname);
@@ -142,7 +141,8 @@
std::vector<char> queryname(byteCountUTF8 + 1, 0);
env->GetStringUTFRegion(dname, 0, javaCharsCount, queryname.data());
- int fd = resNetworkQuery(netId, queryname.data(), ns_class, ns_type, flags);
+
+ int fd = android_res_nquery(netHandle, queryname.data(), ns_class, ns_type, flags);
if (fd < 0) {
jniThrowErrnoException(env, "resNetworkQuery", -fd);
@@ -152,12 +152,12 @@
return jniCreateFileDescriptor(env, fd);
}
-static jobject android_net_utils_resNetworkSend(JNIEnv *env, jobject thiz, jint netId,
+static jobject android_net_utils_resNetworkSend(JNIEnv *env, jobject thiz, jlong netHandle,
jbyteArray msg, jint msgLen, jint flags) {
uint8_t data[MAXCMDSIZE];
checkLenAndCopy(env, msg, msgLen, data);
- int fd = resNetworkSend(netId, data, msgLen, flags);
+ int fd = android_res_nsend(netHandle, data, msgLen, flags);
if (fd < 0) {
jniThrowErrnoException(env, "resNetworkSend", -fd);
@@ -172,7 +172,7 @@
int rcode;
std::vector<uint8_t> buf(MAXPACKETSIZE, 0);
- int res = resNetworkResult(fd, &rcode, buf.data(), MAXPACKETSIZE);
+ int res = android_res_nresult(fd, &rcode, buf.data(), MAXPACKETSIZE);
jniSetFileDescriptorOfFD(env, javaFd, -1);
if (res < 0) {
jniThrowErrnoException(env, "resNetworkResult", -res);
@@ -196,23 +196,22 @@
static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) {
int fd = AFileDescriptor_getFD(env, javaFd);
- resNetworkCancel(fd);
+ android_res_cancel(fd);
jniSetFileDescriptorOfFD(env, javaFd, -1);
}
static jobject android_net_utils_getDnsNetwork(JNIEnv *env, jobject thiz) {
- unsigned dnsNetId = 0;
- if (int res = getNetworkForDns(&dnsNetId) < 0) {
- jniThrowErrnoException(env, "getDnsNetId", -res);
+ net_handle_t dnsNetHandle = NETWORK_UNSPECIFIED;
+ if (int res = android_getprocdns(&dnsNetHandle) < 0) {
+ jniThrowErrnoException(env, "getDnsNetwork", -res);
return nullptr;
}
- bool privateDnsBypass = dnsNetId & NETID_USE_LOCAL_NAMESERVERS;
static jclass class_Network = MakeGlobalRefOrDie(
env, FindClassOrDie(env, "android/net/Network"));
- static jmethodID ctor = env->GetMethodID(class_Network, "<init>", "(IZ)V");
- return env->NewObject(
- class_Network, ctor, dnsNetId & ~NETID_USE_LOCAL_NAMESERVERS, privateDnsBypass);
+ static jmethodID method = env->GetStaticMethodID(class_Network, "fromNetworkHandle",
+ "(J)Landroid/net/Network;");
+ return env->CallStaticObjectMethod(class_Network, method, static_cast<jlong>(dnsNetHandle));
}
static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
@@ -261,12 +260,12 @@
{ "bindProcessToNetworkHandle", "(J)Z", (void*) android_net_utils_bindProcessToNetworkHandle },
{ "getBoundNetworkHandleForProcess", "()J", (void*) android_net_utils_getBoundNetworkHandleForProcess },
{ "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
- { "bindSocketToNetwork", "(Ljava/io/FileDescriptor;I)I", (void*) android_net_utils_bindSocketToNetwork },
+ { "bindSocketToNetworkHandle", "(Ljava/io/FileDescriptor;J)I", (void*) android_net_utils_bindSocketToNetworkHandle },
{ "attachDropAllBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDropAllBPFFilter },
{ "detachBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_detachBPFFilter },
{ "getTcpRepairWindow", "(Ljava/io/FileDescriptor;)Landroid/net/TcpRepairWindow;", (void*) android_net_utils_getTcpRepairWindow },
- { "resNetworkSend", "(I[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend },
- { "resNetworkQuery", "(ILjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery },
+ { "resNetworkSend", "(J[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend },
+ { "resNetworkQuery", "(JLjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery },
{ "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult },
{ "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel },
{ "getDnsNetwork", "()Landroid/net/Network;", (void*) android_net_utils_getDnsNetwork },
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 8c93676..c8bc662 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -829,6 +829,94 @@
})
public @interface PrivateDnsMode {}
+ /**
+ * Flag to indicate that an app is not subject to any restrictions that could result in its
+ * network access blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_NONE = 0;
+
+ /**
+ * Flag to indicate that an app is subject to Battery saver restrictions that would
+ * result in its network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_BATTERY_SAVER = 1 << 0;
+
+ /**
+ * Flag to indicate that an app is subject to Doze restrictions that would
+ * result in its network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_DOZE = 1 << 1;
+
+ /**
+ * Flag to indicate that an app is subject to App Standby restrictions that would
+ * result in its network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_APP_STANDBY = 1 << 2;
+
+ /**
+ * Flag to indicate that an app is subject to Restricted mode restrictions that would
+ * result in its network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;
+
+ /**
+ * Flag to indicate that an app is subject to Data saver restrictions that would
+ * result in its metered network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_METERED_REASON_DATA_SAVER = 1 << 16;
+
+ /**
+ * Flag to indicate that an app is subject to user restrictions that would
+ * result in its metered network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 1 << 17;
+
+ /**
+ * Flag to indicate that an app is subject to Device admin restrictions that would
+ * result in its metered network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 1 << 18;
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = {"BLOCKED_"}, value = {
+ BLOCKED_REASON_NONE,
+ BLOCKED_REASON_BATTERY_SAVER,
+ BLOCKED_REASON_DOZE,
+ BLOCKED_REASON_APP_STANDBY,
+ BLOCKED_REASON_RESTRICTED_MODE,
+ BLOCKED_METERED_REASON_DATA_SAVER,
+ BLOCKED_METERED_REASON_USER_RESTRICTED,
+ BLOCKED_METERED_REASON_ADMIN_DISABLED,
+ })
+ public @interface BlockedReason {}
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
private final IConnectivityManager mService;
@@ -3238,9 +3326,10 @@
* Register or update a network offer with ConnectivityService.
*
* ConnectivityService keeps track of offers made by the various providers and matches
- * them to networking requests made by apps or the system. The provider supplies a score
- * and the capabilities of the network it might be able to bring up ; these act as filters
- * used by ConnectivityService to only send those requests that can be fulfilled by the
+ * them to networking requests made by apps or the system. A callback identifies an offer
+ * uniquely, and later calls with the same callback update the offer. The provider supplies a
+ * score and the capabilities of the network it might be able to bring up ; these act as
+ * filters used by ConnectivityService to only send those requests that can be fulfilled by the
* provider.
*
* The provider is under no obligation to be able to bring up the network it offers at any
diff --git a/framework/src/android/net/INetworkAgent.aidl b/framework/src/android/net/INetworkAgent.aidl
index 1f66e18..f9d3994 100644
--- a/framework/src/android/net/INetworkAgent.aidl
+++ b/framework/src/android/net/INetworkAgent.aidl
@@ -46,4 +46,6 @@
void onRemoveKeepalivePacketFilter(int slot);
void onQosFilterCallbackRegistered(int qosCallbackId, in QosFilterParcelable filterParcel);
void onQosCallbackUnregistered(int qosCallbackId);
+ void onNetworkCreated();
+ void onNetworkDisconnected();
}
diff --git a/framework/src/android/net/INetworkAgentRegistry.aidl b/framework/src/android/net/INetworkAgentRegistry.aidl
index c5464d3..cbd6193 100644
--- a/framework/src/android/net/INetworkAgentRegistry.aidl
+++ b/framework/src/android/net/INetworkAgentRegistry.aidl
@@ -22,6 +22,7 @@
import android.net.NetworkScore;
import android.net.QosSession;
import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
/**
* Interface for NetworkAgents to send network properties.
@@ -37,6 +38,7 @@
void sendSocketKeepaliveEvent(int slot, int reason);
void sendUnderlyingNetworks(in @nullable List<Network> networks);
void sendEpsQosSessionAvailable(int callbackId, in QosSession session, in EpsBearerQosSessionAttributes attributes);
+ void sendNrQosSessionAvailable(int callbackId, in QosSession session, in NrQosSessionAttributes attributes);
void sendQosSessionLost(int qosCallbackId, in QosSession session);
void sendQosCallbackError(int qosCallbackId, int exceptionType);
}
diff --git a/framework/src/android/net/INetworkOfferCallback.aidl b/framework/src/android/net/INetworkOfferCallback.aidl
index 67d2d40..a6de173 100644
--- a/framework/src/android/net/INetworkOfferCallback.aidl
+++ b/framework/src/android/net/INetworkOfferCallback.aidl
@@ -22,15 +22,16 @@
* A callback registered with connectivity by network providers together with
* a NetworkOffer.
*
- * When the offer is needed to satisfy some application or system component,
- * connectivity will call onOfferNeeded on this callback. When this happens,
- * the provider should try and bring up the network.
+ * When the network for this offer is needed to satisfy some application or
+ * system component, connectivity will call onNetworkNeeded on this callback.
+ * When this happens, the provider should try and bring up the network.
*
- * When the offer is no longer needed, for example because the application has
- * withdrawn the request or if the request is being satisfied by a network
- * that this offer will never be able to beat, connectivity calls
- * onOfferUnneeded. When this happens, the provider should stop trying to
- * bring up the network, or tear it down if it has already been brought up.
+ * When the network for this offer is no longer needed, for example because
+ * the application has withdrawn the request or if the request is being
+ * satisfied by a network that this offer will never be able to beat,
+ * connectivity calls onNetworkUnneeded. When this happens, the provider
+ * should stop trying to bring up the network, or tear it down if it has
+ * already been brought up.
*
* When NetworkProvider#offerNetwork is called, the provider can expect to
* immediately receive all requests that can be fulfilled by that offer and
@@ -38,25 +39,25 @@
* request is currently outstanding, because no requests have been made that
* can be satisfied by this offer, or because all such requests are already
* satisfied by a better network.
- * onOfferNeeded can be called at any time after registration and until the
+ * onNetworkNeeded can be called at any time after registration and until the
* offer is withdrawn with NetworkProvider#unofferNetwork is called. This
* typically happens when a new network request is filed by an application,
* or when the network satisfying a request disconnects and this offer now
- * stands a chance to be the best network for it.
+ * stands a chance to supply the best network for it.
*
* @hide
*/
oneway interface INetworkOfferCallback {
/**
- * Informs the registrant that the offer is needed to fulfill this request.
+ * Called when a network for this offer is needed to fulfill this request.
* @param networkRequest the request to satisfy
* @param providerId the ID of the provider currently satisfying
* this request, or NetworkProvider.ID_NONE if none.
*/
- void onOfferNeeded(in NetworkRequest networkRequest, int providerId);
+ void onNetworkNeeded(in NetworkRequest networkRequest, int providerId);
/**
- * Informs the registrant that the offer is no longer needed to fulfill this request.
+ * Informs the registrant that the offer is no longer valuable to fulfill this request.
*/
- void onOfferUnneeded(in NetworkRequest networkRequest);
+ void onNetworkUnneeded(in NetworkRequest networkRequest);
}
diff --git a/framework/src/android/net/IQosCallback.aidl b/framework/src/android/net/IQosCallback.aidl
index 91c7575..c973541 100644
--- a/framework/src/android/net/IQosCallback.aidl
+++ b/framework/src/android/net/IQosCallback.aidl
@@ -19,6 +19,7 @@
import android.os.Bundle;
import android.net.QosSession;
import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
/**
* AIDL interface for QosCallback
@@ -29,6 +30,8 @@
{
void onQosEpsBearerSessionAvailable(in QosSession session,
in EpsBearerQosSessionAttributes attributes);
+ void onNrQosSessionAvailable(in QosSession session,
+ in NrQosSessionAttributes attributes);
void onQosSessionLost(in QosSession session);
void onError(in int type);
}
diff --git a/framework/src/android/net/Network.java b/framework/src/android/net/Network.java
index 41fad63..1f49033 100644
--- a/framework/src/android/net/Network.java
+++ b/framework/src/android/net/Network.java
@@ -92,6 +92,7 @@
// value in the native/android/net.c NDK implementation.
private static final long HANDLE_MAGIC = 0xcafed00dL;
private static final int HANDLE_MAGIC_SIZE = 32;
+ private static final int USE_LOCAL_NAMESERVERS_FLAG = 0x80000000;
// A boolean to control how getAllByName()/getByName() behaves in the face
// of Private DNS.
@@ -189,7 +190,7 @@
*/
public int getNetIdForResolv() {
return mPrivateDnsBypass
- ? (int) (0x80000000L | (long) netId) // Non-portable DNS resolution flag.
+ ? (USE_LOCAL_NAMESERVERS_FLAG | netId) // Non-portable DNS resolution flag.
: netId;
}
@@ -452,12 +453,13 @@
throw new IllegalArgumentException(
"Network.fromNetworkHandle refusing to instantiate NETID_UNSET Network.");
}
- if ((networkHandle & ((1L << HANDLE_MAGIC_SIZE) - 1)) != HANDLE_MAGIC
- || networkHandle < 0) {
+ if ((networkHandle & ((1L << HANDLE_MAGIC_SIZE) - 1)) != HANDLE_MAGIC) {
throw new IllegalArgumentException(
"Value passed to fromNetworkHandle() is not a network handle.");
}
- return new Network((int) (networkHandle >> HANDLE_MAGIC_SIZE));
+ final int netIdForResolv = (int) (networkHandle >>> HANDLE_MAGIC_SIZE);
+ return new Network((netIdForResolv & ~USE_LOCAL_NAMESERVERS_FLAG),
+ ((netIdForResolv & USE_LOCAL_NAMESERVERS_FLAG) != 0) /* privateDnsBypass */);
}
/**
@@ -485,7 +487,7 @@
if (netId == 0) {
return 0L; // make this zero condition obvious for debugging
}
- return (((long) netId) << HANDLE_MAGIC_SIZE) | HANDLE_MAGIC;
+ return (((long) getNetIdForResolv()) << HANDLE_MAGIC_SIZE) | HANDLE_MAGIC;
}
// implement the Parcelable interface
diff --git a/framework/src/android/net/NetworkAgent.java b/framework/src/android/net/NetworkAgent.java
index b3d9616..6b55bb7 100644
--- a/framework/src/android/net/NetworkAgent.java
+++ b/framework/src/android/net/NetworkAgent.java
@@ -32,6 +32,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -361,6 +362,22 @@
*/
public static final int CMD_UNREGISTER_QOS_CALLBACK = BASE + 21;
+ /**
+ * Sent by ConnectivityService to {@link NetworkAgent} to inform the agent that its native
+ * network was created and the Network object is now valid.
+ *
+ * @hide
+ */
+ public static final int CMD_NETWORK_CREATED = BASE + 22;
+
+ /**
+ * Sent by ConnectivityService to {@link NetworkAgent} to inform the agent that its native
+ * network was destroyed.
+ *
+ * @hide
+ */
+ public static final int CMD_NETWORK_DISCONNECTED = BASE + 23;
+
private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacySubType,
config.legacyTypeName, config.legacySubTypeName);
@@ -560,6 +577,14 @@
msg.arg1 /* QoS callback id */);
break;
}
+ case CMD_NETWORK_CREATED: {
+ onNetworkCreated();
+ break;
+ }
+ case CMD_NETWORK_DISCONNECTED: {
+ onNetworkDisconnected();
+ break;
+ }
}
}
}
@@ -700,6 +725,16 @@
mHandler.sendMessage(mHandler.obtainMessage(
CMD_UNREGISTER_QOS_CALLBACK, qosCallbackId, 0, null));
}
+
+ @Override
+ public void onNetworkCreated() {
+ mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_CREATED));
+ }
+
+ @Override
+ public void onNetworkDisconnected() {
+ mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_DISCONNECTED));
+ }
}
/**
@@ -1010,6 +1045,17 @@
}
/**
+ * Called when ConnectivityService has successfully created this NetworkAgent's native network.
+ */
+ public void onNetworkCreated() {}
+
+
+ /**
+ * Called when ConnectivityService has successfully destroy this NetworkAgent's native network.
+ */
+ public void onNetworkDisconnected() {}
+
+ /**
* Requests that the network hardware send the specified packet at the specified interval.
*
* @param slot the hardware slot on which to start the keepalive.
@@ -1160,29 +1206,37 @@
/**
- * Sends the attributes of Eps Bearer Qos Session back to the Application
+ * Sends the attributes of Qos Session back to the Application
*
* @param qosCallbackId the callback id that the session belongs to
- * @param sessionId the unique session id across all Eps Bearer Qos Sessions
- * @param attributes the attributes of the Eps Qos Session
+ * @param sessionId the unique session id across all Qos Sessions
+ * @param attributes the attributes of the Qos Session
*/
public final void sendQosSessionAvailable(final int qosCallbackId, final int sessionId,
- @NonNull final EpsBearerQosSessionAttributes attributes) {
+ @NonNull final QosSessionAttributes attributes) {
Objects.requireNonNull(attributes, "The attributes must be non-null");
- queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId,
- new QosSession(sessionId, QosSession.TYPE_EPS_BEARER),
- attributes));
+ if (attributes instanceof EpsBearerQosSessionAttributes) {
+ queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId,
+ new QosSession(sessionId, QosSession.TYPE_EPS_BEARER),
+ (EpsBearerQosSessionAttributes)attributes));
+ } else if (attributes instanceof NrQosSessionAttributes) {
+ queueOrSendMessage(ra -> ra.sendNrQosSessionAvailable(qosCallbackId,
+ new QosSession(sessionId, QosSession.TYPE_NR_BEARER),
+ (NrQosSessionAttributes)attributes));
+ }
}
/**
- * Sends event that the Eps Qos Session was lost.
+ * Sends event that the Qos Session was lost.
*
* @param qosCallbackId the callback id that the session belongs to
- * @param sessionId the unique session id across all Eps Bearer Qos Sessions
+ * @param sessionId the unique session id across all Qos Sessions
+ * @param qosSessionType the session type {@code QosSesson#QosSessionType}
*/
- public final void sendQosSessionLost(final int qosCallbackId, final int sessionId) {
+ public final void sendQosSessionLost(final int qosCallbackId,
+ final int sessionId, final int qosSessionType) {
queueOrSendMessage(ra -> ra.sendQosSessionLost(qosCallbackId,
- new QosSession(sessionId, QosSession.TYPE_EPS_BEARER)));
+ new QosSession(sessionId, qosSessionType)));
}
/**
diff --git a/framework/src/android/net/NetworkProvider.java b/framework/src/android/net/NetworkProvider.java
index d5b5c9b..d859022 100644
--- a/framework/src/android/net/NetworkProvider.java
+++ b/framework/src/android/net/NetworkProvider.java
@@ -170,10 +170,11 @@
/** @hide */
// TODO : make @SystemApi when the impl is complete
public interface NetworkOfferCallback {
- /** Called by the system when this offer is needed to satisfy some networking request. */
- void onOfferNeeded(@NonNull NetworkRequest request, int providerId);
- /** Called by the system when this offer is no longer needed. */
- void onOfferUnneeded(@NonNull NetworkRequest request);
+ /** Called by the system when a network for this offer is needed to satisfy some
+ * networking request. */
+ void onNetworkNeeded(@NonNull NetworkRequest request, int providerId);
+ /** Called by the system when this offer is no longer valuable for this request. */
+ void onNetworkUnneeded(@NonNull NetworkRequest request);
}
private class NetworkOfferCallbackProxy extends INetworkOfferCallback.Stub {
@@ -187,14 +188,14 @@
}
@Override
- public void onOfferNeeded(final @NonNull NetworkRequest request,
+ public void onNetworkNeeded(final @NonNull NetworkRequest request,
final int providerId) {
- mExecutor.execute(() -> callback.onOfferNeeded(request, providerId));
+ mExecutor.execute(() -> callback.onNetworkNeeded(request, providerId));
}
@Override
- public void onOfferUnneeded(final @NonNull NetworkRequest request) {
- mExecutor.execute(() -> callback.onOfferUnneeded(request));
+ public void onNetworkUnneeded(final @NonNull NetworkRequest request) {
+ mExecutor.execute(() -> callback.onNetworkUnneeded(request));
}
}
@@ -213,41 +214,41 @@
}
/**
- * Register or update an offer for network with the passed caps and score.
+ * Register or update an offer for network with the passed capabilities and score.
*
- * A NetworkProvider's job is to provide networks. This function is how a provider tells the
+ * A NetworkProvider's role is to provide networks. This method is how a provider tells the
* connectivity stack what kind of network it may provide. The score and caps arguments act
- * as filters that the connectivity stack uses to tell when the offer is necessary. When an
- * offer might be advantageous over existing networks, the provider will receive a call to
- * the associated callback's {@link NetworkOfferCallback#onOfferNeeded} method. The provider
- * should then try to bring up this network. When an offer is no longer needed, the stack
- * will inform the provider by calling {@link NetworkOfferCallback#onOfferUnneeded}. The
+ * as filters that the connectivity stack uses to tell when the offer is valuable. When an
+ * offer might be preferred over existing networks, the provider will receive a call to
+ * the associated callback's {@link NetworkOfferCallback#onNetworkNeeded} method. The provider
+ * should then try to bring up this network. When an offer is no longer useful, the stack
+ * will inform the provider by calling {@link NetworkOfferCallback#onNetworkUnneeded}. The
* provider should stop trying to bring up such a network, or disconnect it if it already has
* one.
*
- * The stack determines what offers are needed according to what networks are currently
+ * The stack determines what offers are valuable according to what networks are currently
* available to the system, and what networking requests are made by applications. If an
- * offer looks like it could be a better choice than any existing network for any particular
- * request, that's when the stack decides the offer is needed. If the current networking
- * requests are all satisfied by networks that this offer can't possibly be a better match
- * for, that's when the offer is unneeded. An offer starts off as unneeded ; the provider
- * should not try to bring up the network until {@link NetworkOfferCallback#onOfferNeeded}
- * is called.
+ * offer looks like it could connect a better network than any existing network for any
+ * particular request, that's when the stack decides the network is needed. If the current
+ * networking requests are all satisfied by networks that this offer couldn't possibly be a
+ * better match for, that's when the offer is no longer valuable. An offer starts out as
+ * unneeded ; the provider should not try to bring up the network until
+ * {@link NetworkOfferCallback#onNetworkNeeded} is called.
*
* Note that the offers are non-binding to the providers, in particular because providers
* often don't know if they will be able to bring up such a network at any given time. For
- * example, no wireless network may be in range when the offer is needed. This is fine and
- * expected ; the provider should simply continue to try to bring up the network and do so
+ * example, no wireless network may be in range when the offer would be valuable. This is fine
+ * and expected ; the provider should simply continue to try to bring up the network and do so
* if/when it becomes possible. In the mean time, the stack will continue to satisfy requests
* with the best network currently available, or if none, keep the apps informed that no
* network can currently satisfy this request. When/if the provider can bring up the network,
* the connectivity stack will match it against requests, and inform interested apps of the
* availability of this network. This may, in turn, render the offer of some other provider
- * unneeded if all requests it used to satisfy are now better served by this network.
+ * low-value if all requests it used to satisfy are now better served by this network.
*
* A network can become unneeded for a reason like the above : whether the provider managed
* to bring up the offered network after it became needed or not, some other provider may
- * bring up a better network than this one, making this offer unneeded. A network may also
+ * bring up a better network than this one, making this network unneeded. A network may also
* become unneeded if the application making the request withdrew it (for example, after it
* is done transferring data, or if the user canceled an operation).
*
diff --git a/framework/src/android/net/NetworkUtils.java b/framework/src/android/net/NetworkUtils.java
index f524859..16a49bc 100644
--- a/framework/src/android/net/NetworkUtils.java
+++ b/framework/src/android/net/NetworkUtils.java
@@ -92,12 +92,16 @@
@Deprecated
public native static boolean bindProcessToNetworkForHostResolution(int netId);
+ private static native int bindSocketToNetworkHandle(FileDescriptor fd, long netHandle);
+
/**
* Explicitly binds {@code fd} to the network designated by {@code netId}. This
* overrides any binding via {@link #bindProcessToNetwork}.
* @return 0 on success or negative errno on failure.
*/
- public static native int bindSocketToNetwork(FileDescriptor fd, int netId);
+ public static int bindSocketToNetwork(FileDescriptor fd, int netId) {
+ return bindSocketToNetworkHandle(fd, new Network(netId).getNetworkHandle());
+ }
/**
* Determine if {@code uid} can access network designated by {@code netId}.
@@ -108,14 +112,22 @@
return false;
}
+ private static native FileDescriptor resNetworkSend(
+ long netHandle, byte[] msg, int msglen, int flags) throws ErrnoException;
+
/**
* DNS resolver series jni method.
* Issue the query {@code msg} on the network designated by {@code netId}.
* {@code flags} is an additional config to control actual querying behavior.
* @return a file descriptor to watch for read events
*/
- public static native FileDescriptor resNetworkSend(
- int netId, byte[] msg, int msglen, int flags) throws ErrnoException;
+ public static FileDescriptor resNetworkSend(
+ int netId, byte[] msg, int msglen, int flags) throws ErrnoException {
+ return resNetworkSend(new Network(netId).getNetworkHandle(), msg, msglen, flags);
+ }
+
+ private static native FileDescriptor resNetworkQuery(
+ long netHandle, String dname, int nsClass, int nsType, int flags) throws ErrnoException;
/**
* DNS resolver series jni method.
@@ -124,8 +136,11 @@
* {@code flags} is an additional config to control actual querying behavior.
* @return a file descriptor to watch for read events
*/
- public static native FileDescriptor resNetworkQuery(
- int netId, String dname, int nsClass, int nsType, int flags) throws ErrnoException;
+ public static FileDescriptor resNetworkQuery(
+ int netId, String dname, int nsClass, int nsType, int flags) throws ErrnoException {
+ return resNetworkQuery(new Network(netId).getNetworkHandle(), dname, nsClass, nsType,
+ flags);
+ }
/**
* DNS resolver series jni method.
diff --git a/framework/src/android/net/QosCallbackConnection.java b/framework/src/android/net/QosCallbackConnection.java
index bdb4ad6..de0fc24 100644
--- a/framework/src/android/net/QosCallbackConnection.java
+++ b/framework/src/android/net/QosCallbackConnection.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
import com.android.internal.annotations.VisibleForTesting;
@@ -84,6 +85,25 @@
}
/**
+ * Called when either the {@link NrQosSessionAttributes} has changed or on the first time
+ * the attributes have become available.
+ *
+ * @param session the session that is now available
+ * @param attributes the corresponding attributes of session
+ */
+ @Override
+ public void onNrQosSessionAvailable(@NonNull final QosSession session,
+ @NonNull final NrQosSessionAttributes attributes) {
+
+ mExecutor.execute(() -> {
+ final QosCallback callback = mCallback;
+ if (callback != null) {
+ callback.onQosSessionAvailable(session, attributes);
+ }
+ });
+ }
+
+ /**
* Called when the session is lost.
*
* @param session the session that was lost
diff --git a/framework/src/android/net/QosSession.java b/framework/src/android/net/QosSession.java
index 4f3bb77..93f2ff2 100644
--- a/framework/src/android/net/QosSession.java
+++ b/framework/src/android/net/QosSession.java
@@ -36,6 +36,11 @@
*/
public static final int TYPE_EPS_BEARER = 1;
+ /**
+ * The {@link QosSession} is a NR Session.
+ */
+ public static final int TYPE_NR_BEARER = 2;
+
private final int mSessionId;
private final int mSessionType;
@@ -100,6 +105,7 @@
*/
@IntDef(value = {
TYPE_EPS_BEARER,
+ TYPE_NR_BEARER,
})
@interface QosSessionType {}
diff --git a/service/Android.bp b/service/Android.bp
index 37dd9ff..b44128b 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -25,7 +25,7 @@
cc_library_shared {
name: "libservice-connectivity",
- // TODO: build against the NDK (sdk_version: "30" for example)
+ min_sdk_version: "30",
cflags: [
"-Wall",
"-Werror",
@@ -36,13 +36,13 @@
"jni/com_android_server_TestNetworkService.cpp",
"jni/onload.cpp",
],
+ stl: "libc++_static",
+ header_libs: [
+ "libbase_headers",
+ ],
shared_libs: [
- "libbase",
"liblog",
"libnativehelper",
- // TODO: remove dependency on ifc_[add/del]_address by having Java code to add/delete
- // addresses, and remove dependency on libnetutils.
- "libnetutils",
],
apex_available: [
"com.android.tethering",
@@ -52,6 +52,7 @@
java_library {
name: "service-connectivity-pre-jarjar",
sdk_version: "system_server_current",
+ min_sdk_version: "30",
srcs: [
":connectivity-service-srcs",
":framework-connectivity-shared-srcs",
@@ -82,7 +83,6 @@
"service-connectivity-protos",
],
apex_available: [
- "//apex_available:platform",
"com.android.tethering",
],
}
@@ -90,6 +90,7 @@
java_library {
name: "service-connectivity-protos",
sdk_version: "system_current",
+ min_sdk_version: "30",
proto: {
type: "nano",
},
@@ -98,7 +99,6 @@
],
libs: ["libprotobuf-java-nano"],
apex_available: [
- "//apex_available:platform",
"com.android.tethering",
],
}
@@ -106,13 +106,14 @@
java_library {
name: "service-connectivity",
sdk_version: "system_server_current",
+ min_sdk_version: "30",
installable: true,
static_libs: [
"service-connectivity-pre-jarjar",
],
jarjar_rules: "jarjar-rules.txt",
apex_available: [
- "//apex_available:platform",
+ "//apex_available:platform", // For arc-services
"com.android.tethering",
],
}
diff --git a/service/ServiceConnectivityResources/Android.bp b/service/ServiceConnectivityResources/Android.bp
index fa4501a..d783738 100644
--- a/service/ServiceConnectivityResources/Android.bp
+++ b/service/ServiceConnectivityResources/Android.bp
@@ -22,6 +22,7 @@
android_app {
name: "ServiceConnectivityResources",
sdk_version: "module_current",
+ min_sdk_version: "30",
resource_dirs: [
"res",
],
diff --git a/service/jni/com_android_server_TestNetworkService.cpp b/service/jni/com_android_server_TestNetworkService.cpp
index 36a6fde..e7a40e5 100644
--- a/service/jni/com_android_server_TestNetworkService.cpp
+++ b/service/jni/com_android_server_TestNetworkService.cpp
@@ -35,8 +35,6 @@
#include <log/log.h>
-#include "netutils/ifc.h"
-
#include "jni.h"
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
@@ -48,9 +46,8 @@
//------------------------------------------------------------------------------
static void throwException(JNIEnv* env, int error, const char* action, const char* iface) {
- const std::string& msg =
- android::base::StringPrintf("Error %s %s: %s", action, iface, strerror(error));
-
+ const std::string& msg = "Error: " + std::string(action) + " " + std::string(iface) + ": "
+ + std::string(strerror(error));
jniThrowException(env, "java/lang/IllegalStateException", msg.c_str());
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 4c6e06f..8bb9ce9 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -29,6 +29,7 @@
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
+import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
@@ -74,7 +75,6 @@
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
import static android.net.NetworkPolicyManager.blockedReasonsToString;
import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
@@ -3716,6 +3716,7 @@
mDnsManager.removeNetwork(nai.network);
}
mNetIdManager.releaseNetId(nai.network.getNetId());
+ nai.onNetworkDisconnected();
}
private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
@@ -6467,6 +6468,13 @@
}
}
+ private boolean isNetworkProviderWithIdRegistered(final int providerId) {
+ for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
+ if (npi.providerId == providerId) return true;
+ }
+ return false;
+ }
+
/**
* Register or update a network offer.
* @param newOffer The new offer. If the callback member is the same as an existing
@@ -6474,7 +6482,13 @@
*/
private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) {
ensureRunningOnConnectivityServiceThread();
-
+ if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) {
+ // This may actually happen if a provider updates its score or registers and then
+ // immediately unregisters. The offer would still be in the handler queue, but the
+ // provider would have been removed.
+ if (DBG) log("Received offer from an unregistered provider");
+ return;
+ }
final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback);
if (null != existingOffer) {
handleUnregisterNetworkOffer(existingOffer);
@@ -8113,6 +8127,7 @@
updateCapabilitiesForNetwork(networkAgent);
}
networkAgent.created = true;
+ networkAgent.onNetworkCreated();
}
if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 103ab95..97df5bf 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -49,6 +49,7 @@
import android.os.RemoteException;
import android.os.SystemClock;
import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
@@ -576,6 +577,28 @@
}
}
+ /**
+ * Notify the NetworkAgent that the network is successfully connected.
+ */
+ public void onNetworkCreated() {
+ try {
+ networkAgent.onNetworkCreated();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error sending network created event", e);
+ }
+ }
+
+ /**
+ * Notify the NetworkAgent that the network is disconnected and destroyed.
+ */
+ public void onNetworkDisconnected() {
+ try {
+ networkAgent.onNetworkDisconnected();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error sending network disconnected event", e);
+ }
+ }
+
// TODO: consider moving out of NetworkAgentInfo into its own class
private class NetworkAgentMessageHandler extends INetworkAgentRegistry.Stub {
private final Handler mHandler;
@@ -633,7 +656,13 @@
@Override
public void sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session,
final EpsBearerQosSessionAttributes attributes) {
- mQosCallbackTracker.sendEventQosSessionAvailable(qosCallbackId, session, attributes);
+ mQosCallbackTracker.sendEventEpsQosSessionAvailable(qosCallbackId, session, attributes);
+ }
+
+ @Override
+ public void sendNrQosSessionAvailable(final int qosCallbackId, final QosSession session,
+ final NrQosSessionAttributes attributes) {
+ mQosCallbackTracker.sendEventNrQosSessionAvailable(qosCallbackId, session, attributes);
}
@Override
diff --git a/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java b/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java
index 0f5400d..534dbe7 100644
--- a/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java
+++ b/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java
@@ -27,6 +27,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
import android.util.Log;
import java.util.Objects;
@@ -146,13 +147,23 @@
mNetworkAgentInfo.onQosCallbackUnregistered(mAgentCallbackId);
}
- void sendEventQosSessionAvailable(final QosSession session,
+ void sendEventEpsQosSessionAvailable(final QosSession session,
final EpsBearerQosSessionAttributes attributes) {
try {
- if (DBG) log("sendEventQosSessionAvailable: sending...");
+ if (DBG) log("sendEventEpsQosSessionAvailable: sending...");
mCallback.onQosEpsBearerSessionAvailable(session, attributes);
} catch (final RemoteException e) {
- loge("sendEventQosSessionAvailable: remote exception", e);
+ loge("sendEventEpsQosSessionAvailable: remote exception", e);
+ }
+ }
+
+ void sendEventNrQosSessionAvailable(final QosSession session,
+ final NrQosSessionAttributes attributes) {
+ try {
+ if (DBG) log("sendEventNrQosSessionAvailable: sending...");
+ mCallback.onNrQosSessionAvailable(session, attributes);
+ } catch (final RemoteException e) {
+ loge("sendEventNrQosSessionAvailable: remote exception", e);
}
}
diff --git a/services/core/java/com/android/server/connectivity/QosCallbackTracker.java b/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
index 8bda532..b6ab47b 100644
--- a/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
+++ b/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
@@ -27,6 +27,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
import android.util.Log;
import com.android.net.module.util.CollectionUtils;
@@ -179,17 +180,31 @@
}
/**
- * Called when the NetworkAgent sends the qos session available event
+ * Called when the NetworkAgent sends the qos session available event for EPS
*
* @param qosCallbackId the callback id that the qos session is now available to
* @param session the qos session that is now available
* @param attributes the qos attributes that are now available on the qos session
*/
- public void sendEventQosSessionAvailable(final int qosCallbackId,
+ public void sendEventEpsQosSessionAvailable(final int qosCallbackId,
final QosSession session,
final EpsBearerQosSessionAttributes attributes) {
- runOnAgentConnection(qosCallbackId, "sendEventQosSessionAvailable: ",
- ac -> ac.sendEventQosSessionAvailable(session, attributes));
+ runOnAgentConnection(qosCallbackId, "sendEventEpsQosSessionAvailable: ",
+ ac -> ac.sendEventEpsQosSessionAvailable(session, attributes));
+ }
+
+ /**
+ * Called when the NetworkAgent sends the qos session available event for NR
+ *
+ * @param qosCallbackId the callback id that the qos session is now available to
+ * @param session the qos session that is now available
+ * @param attributes the qos attributes that are now available on the qos session
+ */
+ public void sendEventNrQosSessionAvailable(final int qosCallbackId,
+ final QosSession session,
+ final NrQosSessionAttributes attributes) {
+ runOnAgentConnection(qosCallbackId, "sendEventNrQosSessionAvailable: ",
+ ac -> ac.sendEventNrQosSessionAvailable(session, attributes));
}
/**
diff --git a/tests/net/common/java/android/net/NetworkTest.java b/tests/net/common/java/android/net/NetworkTest.java
index 11d44b8..cd9da8e 100644
--- a/tests/net/common/java/android/net/NetworkTest.java
+++ b/tests/net/common/java/android/net/NetworkTest.java
@@ -22,11 +22,16 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import android.os.Build;
import android.platform.test.annotations.AppModeFull;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -43,6 +48,9 @@
public class NetworkTest {
final Network mNetwork = new Network(99);
+ @Rule
+ public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
+
@Test
public void testBindSocketOfInvalidFdThrows() throws Exception {
@@ -151,6 +159,23 @@
}
@Test
+ public void testFromNetworkHandle() {
+ final Network network = new Network(1234);
+ assertEquals(network.getNetId(),
+ Network.fromNetworkHandle(network.getNetworkHandle()).getNetId());
+ }
+
+ // Parsing private DNS bypassing handle was not supported until S
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testFromNetworkHandle_S() {
+ final Network network = new Network(1234, true);
+
+ final Network recreatedNetwork = Network.fromNetworkHandle(network.getNetworkHandle());
+ assertEquals(network.netId, recreatedNetwork.netId);
+ assertEquals(network.getNetIdForResolv(), recreatedNetwork.getNetIdForResolv());
+ }
+
+ @Test
public void testGetPrivateDnsBypassingCopy() {
final Network copy = mNetwork.getPrivateDnsBypassingCopy();
assertEquals(mNetwork.netId, copy.netId);
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 14dddcb..e039ef0 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -73,7 +73,7 @@
import kotlin.test.fail
const val SERVICE_BIND_TIMEOUT_MS = 5_000L
-const val TEST_TIMEOUT_MS = 1_000L
+const val TEST_TIMEOUT_MS = 10_000L
/**
* Test that exercises an instrumented version of ConnectivityService against an instrumented
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index d82565a..44298d4 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -30,6 +30,10 @@
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
+import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
+import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE;
@@ -90,10 +94,6 @@
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
-import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_DATA_SAVER;
-import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_BATTERY_SAVER;
-import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
@@ -265,6 +265,7 @@
import android.system.Os;
import android.telephony.TelephonyManager;
import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
import android.test.mock.MockContentResolver;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -9963,7 +9964,7 @@
&& session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes));
mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
- .sendQosSessionLost(qosCallbackId, sessionId);
+ .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER);
waitForIdle();
verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session ->
session.getSessionId() == sessionId
@@ -9971,6 +9972,36 @@
}
@Test
+ public void testNrQosCallbackAvailableAndLost() throws Exception {
+ mQosCallbackMockHelper = new QosCallbackMockHelper();
+ final int sessionId = 10;
+ final int qosCallbackId = 1;
+
+ when(mQosCallbackMockHelper.mFilter.validate())
+ .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE);
+ mQosCallbackMockHelper.registerQosCallback(
+ mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback);
+ waitForIdle();
+
+ final NrQosSessionAttributes attributes = new NrQosSessionAttributes(
+ 1, 2, 3, 4, 5, 6, 7, new ArrayList<>());
+ mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
+ .sendQosSessionAvailable(qosCallbackId, sessionId, attributes);
+ waitForIdle();
+
+ verify(mQosCallbackMockHelper.mCallback).onNrQosSessionAvailable(argThat(session ->
+ session.getSessionId() == sessionId
+ && session.getSessionType() == QosSession.TYPE_NR_BEARER), eq(attributes));
+
+ mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
+ .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_NR_BEARER);
+ waitForIdle();
+ verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session ->
+ session.getSessionId() == sessionId
+ && session.getSessionType() == QosSession.TYPE_NR_BEARER));
+ }
+
+ @Test
public void testQosCallbackTooManyRequests() throws Exception {
mQosCallbackMockHelper = new QosCallbackMockHelper();
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 97c65eb..8b072c4 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -83,10 +83,10 @@
IpConnectivityMetrics mService;
NetdEventListenerService mNetdListener;
- final NetworkCapabilities mNcWifi = new NetworkCapabilities.Builder()
+ private static final NetworkCapabilities CAPABILITIES_WIFI = new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
- final NetworkCapabilities mNcCell = new NetworkCapabilities.Builder()
+ private static final NetworkCapabilities CAPABILITIES_CELL = new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.build();
@@ -590,7 +590,7 @@
ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
verify(mCm).registerNetworkCallback(any(), networkCallback.capture());
networkCallback.getValue().onCapabilitiesChanged(new Network(netId),
- netId == 100 ? mNcWifi : mNcCell);
+ netId == 100 ? CAPABILITIES_WIFI : CAPABILITIES_CELL);
}
void connectEvent(int netId, int error, int latencyMs, String ipAddr) throws Exception {
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index 52975e4..50aaaee 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -63,10 +63,10 @@
NetdEventListenerService mService;
ConnectivityManager mCm;
- final NetworkCapabilities mNcWifi = new NetworkCapabilities.Builder()
+ private static final NetworkCapabilities CAPABILITIES_WIFI = new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
- final NetworkCapabilities mNcCell = new NetworkCapabilities.Builder()
+ private static final NetworkCapabilities CAPABILITIES_CELL = new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.build();
@@ -475,7 +475,7 @@
ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
verify(mCm).registerNetworkCallback(any(), networkCallback.capture());
networkCallback.getValue().onCapabilitiesChanged(new Network(netId),
- netId == 100 ? mNcWifi : mNcCell);
+ netId == 100 ? CAPABILITIES_WIFI : CAPABILITIES_CELL);
}
Thread connectEventAction(int netId, int error, int latencyMs, String ipAddr) {