Merge "Migrate away from AsyncChannel in NetworkAgent"
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index d84ee2a..b5962c5 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -16,14 +16,9 @@
package android.net;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.system.ErrnoException;
-import android.system.Os;
import android.util.Log;
import android.util.Pair;
@@ -155,14 +150,6 @@
public static native Network getDnsNetwork() throws ErrnoException;
/**
- * Allow/Disallow creating AF_INET/AF_INET6 sockets and DNS lookups for current process.
- *
- * @param allowNetworking whether to allow or disallow creating AF_INET/AF_INET6 sockets
- * and DNS lookups.
- */
- public static native void setAllowNetworkingForProcess(boolean allowNetworking);
-
- /**
* Get the tcp repair window associated with the {@code fd}.
*
* @param fd the tcp socket's {@link FileDescriptor}.
@@ -437,60 +424,4 @@
return routedIPCount;
}
- private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET, AF_INET6};
-
- /**
- * Returns true if the hostname is weakly validated.
- * @param hostname Name of host to validate.
- * @return True if it's a valid-ish hostname.
- *
- * @hide
- */
- public static boolean isWeaklyValidatedHostname(@NonNull String hostname) {
- // TODO(b/34953048): Use a validation method that permits more accurate,
- // but still inexpensive, checking of likely valid DNS hostnames.
- final String weakHostnameRegex = "^[a-zA-Z0-9_.-]+$";
- if (!hostname.matches(weakHostnameRegex)) {
- return false;
- }
-
- for (int address_family : ADDRESS_FAMILIES) {
- if (Os.inet_pton(address_family, hostname) != null) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Safely multiple a value by a rational.
- * <p>
- * Internally it uses integer-based math whenever possible, but switches
- * over to double-based math if values would overflow.
- * @hide
- */
- public static long multiplySafeByRational(long value, long num, long den) {
- if (den == 0) {
- throw new ArithmeticException("Invalid Denominator");
- }
- long x = value;
- long y = num;
-
- // Logic shamelessly borrowed from Math.multiplyExact()
- long r = x * y;
- long ax = Math.abs(x);
- long ay = Math.abs(y);
- if (((ax | ay) >>> 31 != 0)) {
- // Some bits greater than 2^31 that might cause overflow
- // Check the result using the divide operator
- // and check for the special case of Long.MIN_VALUE * -1
- if (((y != 0) && (r / y != x)) ||
- (x == Long.MIN_VALUE && y == -1)) {
- // Use double math to avoid overflowing
- return (long) (((double) num / den) * value);
- }
- }
- return r / den;
- }
}
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 8d4c4e5..2155246 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2008, The Android Open Source Project
+ * Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@
#include <netinet/udp.h>
#include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS
-#include <android_runtime/AndroidRuntime.h>
#include <cutils/properties.h>
#include <nativehelper/JNIPlatformHelp.h>
#include <nativehelper/ScopedLocalRef.h>
@@ -226,11 +225,6 @@
class_Network, ctor, dnsNetId & ~NETID_USE_LOCAL_NAMESERVERS, privateDnsBypass);
}
-static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jobject thiz,
- jboolean hasConnectivity) {
- setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE);
-}
-
static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
if (javaFd == NULL) {
jniThrowNullPointerException(env, NULL);
@@ -288,7 +282,6 @@
{ "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 },
- { "setAllowNetworkingForProcess", "(Z)V", (void *)android_net_utils_setAllowNetworkingForProcess },
};
// clang-format on
diff --git a/service/Android.bp b/service/Android.bp
new file mode 100644
index 0000000..a26f715
--- /dev/null
+++ b/service/Android.bp
@@ -0,0 +1,79 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_defaults {
+ name: "libservice-connectivity-defaults",
+ // TODO: build against the NDK (sdk_version: "30" for example)
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-parameter",
+ "-Wthread-safety",
+ ],
+ srcs: [
+ "jni/com_android_server_TestNetworkService.cpp",
+ "jni/com_android_server_connectivity_Vpn.cpp",
+ ],
+ 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",
+ ],
+}
+
+cc_library_shared {
+ name: "libservice-connectivity",
+ defaults: ["libservice-connectivity-defaults"],
+ srcs: [
+ "jni/onload.cpp",
+ ],
+ apex_available: [
+ // TODO: move this library to the tethering APEX and remove libservice-connectivity-static
+ // "com.android.tethering",
+ ],
+}
+
+// Static library linked into libservices.core until libservice-connectivity can be loaded from
+// the tethering APEX instead.
+cc_library_static {
+ name: "libservice-connectivity-static",
+ defaults: ["libservice-connectivity-defaults"],
+}
+
+java_library {
+ name: "service-connectivity",
+ srcs: [
+ ":connectivity-service-srcs",
+ ],
+ installable: true,
+ jarjar_rules: "jarjar-rules.txt",
+ libs: [
+ "android.net.ipsec.ike",
+ "services.core",
+ "services.net",
+ "unsupportedappusage",
+ ],
+ static_libs: [
+ "net-utils-device-common",
+ "net-utils-framework-common",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ ],
+}
diff --git a/service/jarjar-rules.txt b/service/jarjar-rules.txt
new file mode 100644
index 0000000..ef53ebb
--- /dev/null
+++ b/service/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.android.net.module.util.** com.android.connectivity.util.@1
\ No newline at end of file
diff --git a/services/core/jni/com_android_server_TestNetworkService.cpp b/service/jni/com_android_server_TestNetworkService.cpp
similarity index 100%
rename from services/core/jni/com_android_server_TestNetworkService.cpp
rename to service/jni/com_android_server_TestNetworkService.cpp
diff --git a/service/jni/com_android_server_connectivity_Vpn.cpp b/service/jni/com_android_server_connectivity_Vpn.cpp
new file mode 100644
index 0000000..ea5e718
--- /dev/null
+++ b/service/jni/com_android_server_connectivity_Vpn.cpp
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+
+#define LOG_TAG "VpnJni"
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <linux/route.h>
+#include <linux/ipv6_route.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <log/log.h>
+#include <android/log.h>
+
+#include "netutils/ifc.h"
+
+#include "jni.h"
+#include <nativehelper/JNIHelp.h>
+
+namespace android
+{
+
+static int inet4 = -1;
+static int inet6 = -1;
+
+static inline in_addr_t *as_in_addr(sockaddr *sa) {
+ return &((sockaddr_in *)sa)->sin_addr.s_addr;
+}
+
+//------------------------------------------------------------------------------
+
+#define SYSTEM_ERROR (-1)
+#define BAD_ARGUMENT (-2)
+
+static int create_interface(int mtu)
+{
+ int tun = open("/dev/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
+
+ ifreq ifr4;
+ memset(&ifr4, 0, sizeof(ifr4));
+
+ // Allocate interface.
+ ifr4.ifr_flags = IFF_TUN | IFF_NO_PI;
+ if (ioctl(tun, TUNSETIFF, &ifr4)) {
+ ALOGE("Cannot allocate TUN: %s", strerror(errno));
+ goto error;
+ }
+
+ // Activate interface.
+ ifr4.ifr_flags = IFF_UP;
+ if (ioctl(inet4, SIOCSIFFLAGS, &ifr4)) {
+ ALOGE("Cannot activate %s: %s", ifr4.ifr_name, strerror(errno));
+ goto error;
+ }
+
+ // Set MTU if it is specified.
+ ifr4.ifr_mtu = mtu;
+ if (mtu > 0 && ioctl(inet4, SIOCSIFMTU, &ifr4)) {
+ ALOGE("Cannot set MTU on %s: %s", ifr4.ifr_name, strerror(errno));
+ goto error;
+ }
+
+ return tun;
+
+error:
+ close(tun);
+ return SYSTEM_ERROR;
+}
+
+static int get_interface_name(char *name, int tun)
+{
+ ifreq ifr4;
+ if (ioctl(tun, TUNGETIFF, &ifr4)) {
+ ALOGE("Cannot get interface name: %s", strerror(errno));
+ return SYSTEM_ERROR;
+ }
+ strncpy(name, ifr4.ifr_name, IFNAMSIZ);
+ return 0;
+}
+
+static int get_interface_index(const char *name)
+{
+ ifreq ifr4;
+ strncpy(ifr4.ifr_name, name, IFNAMSIZ);
+ if (ioctl(inet4, SIOGIFINDEX, &ifr4)) {
+ ALOGE("Cannot get index of %s: %s", name, strerror(errno));
+ return SYSTEM_ERROR;
+ }
+ return ifr4.ifr_ifindex;
+}
+
+static int set_addresses(const char *name, const char *addresses)
+{
+ int index = get_interface_index(name);
+ if (index < 0) {
+ return index;
+ }
+
+ ifreq ifr4;
+ memset(&ifr4, 0, sizeof(ifr4));
+ strncpy(ifr4.ifr_name, name, IFNAMSIZ);
+ ifr4.ifr_addr.sa_family = AF_INET;
+ ifr4.ifr_netmask.sa_family = AF_INET;
+
+ in6_ifreq ifr6;
+ memset(&ifr6, 0, sizeof(ifr6));
+ ifr6.ifr6_ifindex = index;
+
+ char address[65];
+ int prefix;
+ int chars;
+ int count = 0;
+
+ while (sscanf(addresses, " %64[^/]/%d %n", address, &prefix, &chars) == 2) {
+ addresses += chars;
+
+ if (strchr(address, ':')) {
+ // Add an IPv6 address.
+ if (inet_pton(AF_INET6, address, &ifr6.ifr6_addr) != 1 ||
+ prefix < 0 || prefix > 128) {
+ count = BAD_ARGUMENT;
+ break;
+ }
+
+ ifr6.ifr6_prefixlen = prefix;
+ if (ioctl(inet6, SIOCSIFADDR, &ifr6)) {
+ count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
+ break;
+ }
+ } else {
+ // Add an IPv4 address.
+ if (inet_pton(AF_INET, address, as_in_addr(&ifr4.ifr_addr)) != 1 ||
+ prefix < 0 || prefix > 32) {
+ count = BAD_ARGUMENT;
+ break;
+ }
+
+ if (count) {
+ snprintf(ifr4.ifr_name, sizeof(ifr4.ifr_name), "%s:%d", name, count);
+ }
+ if (ioctl(inet4, SIOCSIFADDR, &ifr4)) {
+ count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
+ break;
+ }
+
+ in_addr_t mask = prefix ? (~0 << (32 - prefix)) : 0;
+ *as_in_addr(&ifr4.ifr_netmask) = htonl(mask);
+ if (ioctl(inet4, SIOCSIFNETMASK, &ifr4)) {
+ count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
+ break;
+ }
+ }
+ ALOGD("Address added on %s: %s/%d", name, address, prefix);
+ ++count;
+ }
+
+ if (count == BAD_ARGUMENT) {
+ ALOGE("Invalid address: %s/%d", address, prefix);
+ } else if (count == SYSTEM_ERROR) {
+ ALOGE("Cannot add address: %s/%d: %s", address, prefix, strerror(errno));
+ } else if (*addresses) {
+ ALOGE("Invalid address: %s", addresses);
+ count = BAD_ARGUMENT;
+ }
+
+ return count;
+}
+
+static int reset_interface(const char *name)
+{
+ ifreq ifr4;
+ strncpy(ifr4.ifr_name, name, IFNAMSIZ);
+ ifr4.ifr_flags = 0;
+
+ if (ioctl(inet4, SIOCSIFFLAGS, &ifr4) && errno != ENODEV) {
+ ALOGE("Cannot reset %s: %s", name, strerror(errno));
+ return SYSTEM_ERROR;
+ }
+ return 0;
+}
+
+static int check_interface(const char *name)
+{
+ ifreq ifr4;
+ strncpy(ifr4.ifr_name, name, IFNAMSIZ);
+ ifr4.ifr_flags = 0;
+
+ if (ioctl(inet4, SIOCGIFFLAGS, &ifr4) && errno != ENODEV) {
+ ALOGE("Cannot check %s: %s", name, strerror(errno));
+ }
+ return ifr4.ifr_flags;
+}
+
+static bool modifyAddress(JNIEnv *env, jobject thiz, jstring jName, jstring jAddress,
+ jint jPrefixLength, bool add)
+{
+ int error = SYSTEM_ERROR;
+ const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
+ const char *address = jAddress ? env->GetStringUTFChars(jAddress, NULL) : NULL;
+
+ if (!name) {
+ jniThrowNullPointerException(env, "name");
+ } else if (!address) {
+ jniThrowNullPointerException(env, "address");
+ } else {
+ if (add) {
+ if ((error = ifc_add_address(name, address, jPrefixLength)) != 0) {
+ ALOGE("Cannot add address %s/%d on interface %s (%s)", address, jPrefixLength, name,
+ strerror(-error));
+ }
+ } else {
+ if ((error = ifc_del_address(name, address, jPrefixLength)) != 0) {
+ ALOGE("Cannot del address %s/%d on interface %s (%s)", address, jPrefixLength, name,
+ strerror(-error));
+ }
+ }
+ }
+
+ if (name) {
+ env->ReleaseStringUTFChars(jName, name);
+ }
+ if (address) {
+ env->ReleaseStringUTFChars(jAddress, address);
+ }
+ return !error;
+}
+
+//------------------------------------------------------------------------------
+
+static void throwException(JNIEnv *env, int error, const char *message)
+{
+ if (error == SYSTEM_ERROR) {
+ jniThrowException(env, "java/lang/IllegalStateException", message);
+ } else {
+ jniThrowException(env, "java/lang/IllegalArgumentException", message);
+ }
+}
+
+static jint create(JNIEnv *env, jobject /* thiz */, jint mtu)
+{
+ int tun = create_interface(mtu);
+ if (tun < 0) {
+ throwException(env, tun, "Cannot create interface");
+ return -1;
+ }
+ return tun;
+}
+
+static jstring getName(JNIEnv *env, jobject /* thiz */, jint tun)
+{
+ char name[IFNAMSIZ];
+ if (get_interface_name(name, tun) < 0) {
+ throwException(env, SYSTEM_ERROR, "Cannot get interface name");
+ return NULL;
+ }
+ return env->NewStringUTF(name);
+}
+
+static jint setAddresses(JNIEnv *env, jobject /* thiz */, jstring jName,
+ jstring jAddresses)
+{
+ const char *name = NULL;
+ const char *addresses = NULL;
+ int count = -1;
+
+ name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
+ if (!name) {
+ jniThrowNullPointerException(env, "name");
+ goto error;
+ }
+ addresses = jAddresses ? env->GetStringUTFChars(jAddresses, NULL) : NULL;
+ if (!addresses) {
+ jniThrowNullPointerException(env, "addresses");
+ goto error;
+ }
+ count = set_addresses(name, addresses);
+ if (count < 0) {
+ throwException(env, count, "Cannot set address");
+ count = -1;
+ }
+
+error:
+ if (name) {
+ env->ReleaseStringUTFChars(jName, name);
+ }
+ if (addresses) {
+ env->ReleaseStringUTFChars(jAddresses, addresses);
+ }
+ return count;
+}
+
+static void reset(JNIEnv *env, jobject /* thiz */, jstring jName)
+{
+ const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
+ if (!name) {
+ jniThrowNullPointerException(env, "name");
+ return;
+ }
+ if (reset_interface(name) < 0) {
+ throwException(env, SYSTEM_ERROR, "Cannot reset interface");
+ }
+ env->ReleaseStringUTFChars(jName, name);
+}
+
+static jint check(JNIEnv *env, jobject /* thiz */, jstring jName)
+{
+ const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
+ if (!name) {
+ jniThrowNullPointerException(env, "name");
+ return 0;
+ }
+ int flags = check_interface(name);
+ env->ReleaseStringUTFChars(jName, name);
+ return flags;
+}
+
+static bool addAddress(JNIEnv *env, jobject thiz, jstring jName, jstring jAddress,
+ jint jPrefixLength)
+{
+ return modifyAddress(env, thiz, jName, jAddress, jPrefixLength, true);
+}
+
+static bool delAddress(JNIEnv *env, jobject thiz, jstring jName, jstring jAddress,
+ jint jPrefixLength)
+{
+ return modifyAddress(env, thiz, jName, jAddress, jPrefixLength, false);
+}
+
+//------------------------------------------------------------------------------
+
+static const JNINativeMethod gMethods[] = {
+ {"jniCreate", "(I)I", (void *)create},
+ {"jniGetName", "(I)Ljava/lang/String;", (void *)getName},
+ {"jniSetAddresses", "(Ljava/lang/String;Ljava/lang/String;)I", (void *)setAddresses},
+ {"jniReset", "(Ljava/lang/String;)V", (void *)reset},
+ {"jniCheck", "(Ljava/lang/String;)I", (void *)check},
+ {"jniAddAddress", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)addAddress},
+ {"jniDelAddress", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)delAddress},
+};
+
+int register_android_server_connectivity_Vpn(JNIEnv *env)
+{
+ if (inet4 == -1) {
+ inet4 = socket(AF_INET, SOCK_DGRAM, 0);
+ }
+ if (inet6 == -1) {
+ inet6 = socket(AF_INET6, SOCK_DGRAM, 0);
+ }
+ return jniRegisterNativeMethods(env, "com/android/server/connectivity/Vpn",
+ gMethods, NELEM(gMethods));
+}
+
+};
diff --git a/service/jni/onload.cpp b/service/jni/onload.cpp
new file mode 100644
index 0000000..3afcb0e
--- /dev/null
+++ b/service/jni/onload.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include <log/log.h>
+
+namespace android {
+
+int register_android_server_connectivity_Vpn(JNIEnv* env);
+int register_android_server_TestNetworkService(JNIEnv* env);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+ JNIEnv *env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ ALOGE("GetEnv failed");
+ return JNI_ERR;
+ }
+
+ if (register_android_server_connectivity_Vpn(env) < 0
+ || register_android_server_TestNetworkService(env) < 0) {
+ return JNI_ERR;
+ }
+
+ return JNI_VERSION_1_6;
+}
+
+};
\ No newline at end of file
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 14ef5e6..4e75a9e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -83,6 +83,7 @@
import android.net.ConnectivityDiagnosticsManager.DataStallReport;
import android.net.ConnectivityManager;
import android.net.DataStallReportParcelable;
+import android.net.DnsResolverServiceManager;
import android.net.ICaptivePortal;
import android.net.IConnectivityDiagnosticsCallback;
import android.net.IConnectivityManager;
@@ -202,7 +203,6 @@
import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.LingerMonitor;
import com.android.server.connectivity.MockableSystemProperties;
-import com.android.server.connectivity.MultipathPolicyTracker;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkDiagnostics;
import com.android.server.connectivity.NetworkNotificationManager;
@@ -443,11 +443,6 @@
private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
/**
- * Used internally to indicate the system is ready.
- */
- private static final int EVENT_SYSTEM_READY = 25;
-
- /**
* used to add a network request with a pending intent
* obj = NetworkRequestInfo
*/
@@ -578,9 +573,8 @@
return sMagicDecoderRing.get(what, Integer.toString(what));
}
- private static IDnsResolver getDnsResolver() {
- return IDnsResolver.Stub
- .asInterface(ServiceManager.getService("dnsresolver"));
+ private static IDnsResolver getDnsResolver(Context context) {
+ return IDnsResolver.Stub.asInterface(DnsResolverServiceManager.getService(context));
}
/** Handler thread used for all of the handlers below. */
@@ -662,9 +656,6 @@
final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
@VisibleForTesting
- final MultipathPolicyTracker mMultipathPolicyTracker;
-
- @VisibleForTesting
final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks =
new HashMap<>();
@@ -956,7 +947,7 @@
public ConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
- this(context, netManager, statsService, policyManager, getDnsResolver(),
+ this(context, netManager, statsService, policyManager, getDnsResolver(context),
new IpConnectivityLog(), NetdService.getInstance(), new Dependencies());
}
@@ -1168,8 +1159,6 @@
mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
mMultinetworkPolicyTracker.start();
- mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
-
mDnsManager = new DnsManager(mContext, mDnsResolver);
registerPrivateDnsSettingsCallbacks();
}
@@ -1804,9 +1793,9 @@
private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
@Override
- public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
- int deviceType = Integer.parseInt(label);
- sendDataActivityBroadcast(deviceType, active, tsNanos);
+ public void interfaceClassDataActivityChanged(int networkType, boolean active, long tsNanos,
+ int uid) {
+ sendDataActivityBroadcast(networkType, active, tsNanos);
}
};
@@ -2315,10 +2304,13 @@
*/
@VisibleForTesting
public void systemReadyInternal() {
- // Let PermissionMonitor#startMonitoring() running in the beginning of the systemReady
- // before MultipathPolicyTracker.start(). Since mApps in PermissionMonitor needs to be
- // populated first to ensure that listening network request which is sent by
- // MultipathPolicyTracker won't be added NET_CAPABILITY_FOREGROUND capability.
+ // Since mApps in PermissionMonitor needs to be populated first to ensure that
+ // listening network request which is sent by MultipathPolicyTracker won't be added
+ // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must
+ // be called after PermissionMonitor#startMonitoring().
+ // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the
+ // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady()
+ // to ensure the tracking will be initialized correctly.
mPermissionMonitor.startMonitoring();
mProxyTracker.loadGlobalProxy();
registerNetdEventCallback();
@@ -2337,8 +2329,6 @@
// Create network requests for always-on networks.
mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
-
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY));
}
/**
@@ -2638,7 +2628,6 @@
dumpAvoidBadWifiSettings(pw);
pw.println();
- mMultipathPolicyTracker.dump(pw);
if (ArrayUtils.contains(args, SHORT_ARG) == false) {
pw.println();
@@ -4189,11 +4178,13 @@
return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
}
- Integer networkPreference = mMultipathPolicyTracker.getMultipathPreference(network);
- if (networkPreference != null) {
+ final NetworkPolicyManager netPolicyManager =
+ mContext.getSystemService(NetworkPolicyManager.class);
+
+ final int networkPreference = netPolicyManager.getMultipathPreference(network);
+ if (networkPreference != 0) {
return networkPreference;
}
-
return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
}
@@ -4297,10 +4288,6 @@
mKeepaliveTracker.handleStopKeepalive(nai, slot, reason);
break;
}
- case EVENT_SYSTEM_READY: {
- mMultipathPolicyTracker.start();
- break;
- }
case EVENT_REVALIDATE_NETWORK: {
handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2));
break;
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index 5cb3d94..f6ca152 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -38,7 +38,9 @@
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
+import com.android.net.module.util.ProxyUtils;
+import java.util.Collections;
import java.util.Objects;
/**
@@ -163,9 +165,10 @@
if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
ProxyInfo proxyProperties;
if (!TextUtils.isEmpty(pacFileUrl)) {
- proxyProperties = new ProxyInfo(Uri.parse(pacFileUrl));
+ proxyProperties = ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
} else {
- proxyProperties = new ProxyInfo(host, port, exclList);
+ proxyProperties = ProxyInfo.buildDirectProxy(host, port,
+ ProxyUtils.exclusionStringAsList(exclList));
}
if (!proxyProperties.isValid()) {
if (DBG) Log.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
@@ -204,7 +207,8 @@
return false;
}
}
- final ProxyInfo p = new ProxyInfo(proxyHost, proxyPort, "");
+ final ProxyInfo p = ProxyInfo.buildDirectProxy(proxyHost, proxyPort,
+ Collections.emptyList());
setGlobalProxy(p);
return true;
}
@@ -219,7 +223,8 @@
*/
public void sendProxyBroadcast() {
final ProxyInfo defaultProxy = getDefaultProxy();
- final ProxyInfo proxyInfo = null != defaultProxy ? defaultProxy : new ProxyInfo("", 0, "");
+ final ProxyInfo proxyInfo = null != defaultProxy ?
+ defaultProxy : ProxyInfo.buildDirectProxy("", 0, Collections.emptyList());
if (mPacManager.setCurrentProxyScriptUrl(proxyInfo) == PacManager.DONT_SEND_BROADCAST) {
return;
}
@@ -261,7 +266,7 @@
mGlobalProxy = new ProxyInfo(proxyInfo);
host = mGlobalProxy.getHost();
port = mGlobalProxy.getPort();
- exclList = mGlobalProxy.getExclusionListAsString();
+ exclList = ProxyUtils.exclusionListAsString(mGlobalProxy.getExclusionList());
pacFileUrl = Uri.EMPTY.equals(proxyInfo.getPacFileUrl())
? "" : proxyInfo.getPacFileUrl().toString();
} else {
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt
index 77e9f12..bcc9072 100644
--- a/tests/net/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/net/common/java/android/net/NetworkProviderTest.kt
@@ -29,6 +29,7 @@
import com.android.net.module.util.ArrayTrackRecord
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.isDevSdkInRange
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -173,10 +174,12 @@
@Test
fun testDeclareNetworkRequestUnfulfillable() {
val mockContext = mock(Context::class.java)
- val provider = createNetworkProvider(mockContext)
- // ConnectivityManager not required at creation time
- verifyNoMoreInteractions(mockContext)
doReturn(mCm).`when`(mockContext).getSystemService(Context.CONNECTIVITY_SERVICE)
+ val provider = createNetworkProvider(mockContext)
+ // ConnectivityManager not required at creation time after R
+ if (!isDevSdkInRange(0, Build.VERSION_CODES.R)) {
+ verifyNoMoreInteractions(mockContext)
+ }
mCm.registerNetworkProvider(provider)
diff --git a/tests/net/java/android/net/Ikev2VpnProfileTest.java b/tests/net/java/android/net/Ikev2VpnProfileTest.java
index ada5494..076e41d 100644
--- a/tests/net/java/android/net/Ikev2VpnProfileTest.java
+++ b/tests/net/java/android/net/Ikev2VpnProfileTest.java
@@ -29,6 +29,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.net.VpnProfile;
+import com.android.net.module.util.ProxyUtils;
import com.android.org.bouncycastle.x509.X509V1CertificateGenerator;
import org.junit.Before;
@@ -67,7 +68,8 @@
return "fooPackage";
}
};
- private final ProxyInfo mProxy = new ProxyInfo(SERVER_ADDR_STRING, -1, EXCL_LIST);
+ private final ProxyInfo mProxy = ProxyInfo.buildDirectProxy(
+ SERVER_ADDR_STRING, -1, ProxyUtils.exclusionStringAsList(EXCL_LIST));
private X509Certificate mUserCert;
private X509Certificate mServerRootCa;
diff --git a/tests/net/java/android/net/NetworkUtilsTest.java b/tests/net/java/android/net/NetworkUtilsTest.java
index 3158cc8..7748288 100644
--- a/tests/net/java/android/net/NetworkUtilsTest.java
+++ b/tests/net/java/android/net/NetworkUtilsTest.java
@@ -16,24 +16,10 @@
package android.net;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.AF_UNIX;
-import static android.system.OsConstants.EPERM;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_STREAM;
-
import static junit.framework.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.system.ErrnoException;
-import android.system.Os;
-
import androidx.test.runner.AndroidJUnit4;
-import libcore.io.IoUtils;
-
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -139,50 +125,4 @@
assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536),
NetworkUtils.routedIPv6AddressCount(set));
}
-
- private static void expectSocketSuccess(String msg, int domain, int type) {
- try {
- IoUtils.closeQuietly(Os.socket(domain, type, 0));
- } catch (ErrnoException e) {
- fail(msg + e.getMessage());
- }
- }
-
- private static void expectSocketPemissionError(String msg, int domain, int type) {
- try {
- IoUtils.closeQuietly(Os.socket(domain, type, 0));
- fail(msg);
- } catch (ErrnoException e) {
- assertEquals(msg, e.errno, EPERM);
- }
- }
-
- private static void expectHasNetworking() {
- expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
- AF_UNIX, SOCK_STREAM);
- expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException",
- AF_INET, SOCK_DGRAM);
- expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException",
- AF_INET6, SOCK_DGRAM);
- }
-
- private static void expectNoNetworking() {
- expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
- AF_UNIX, SOCK_STREAM);
- expectSocketPemissionError(
- "Creating a AF_INET socket should have thrown ErrnoException(EPERM)",
- AF_INET, SOCK_DGRAM);
- expectSocketPemissionError(
- "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)",
- AF_INET6, SOCK_DGRAM);
- }
-
- @Test
- public void testSetAllowNetworkingForProcess() {
- expectHasNetworking();
- NetworkUtils.setAllowNetworkingForProcess(false);
- expectNoNetworking();
- NetworkUtils.setAllowNetworkingForProcess(true);
- expectHasNetworking();
- }
}
diff --git a/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java b/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java
new file mode 100644
index 0000000..3cfecd5
--- /dev/null
+++ b/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.net;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.EPERM;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.junit.Assert.fail;
+
+import android.system.ErrnoException;
+import android.system.Os;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import libcore.io.IoUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@androidx.test.filters.SmallTest
+public class NetworkUtilsInternalTest {
+
+ private static void expectSocketSuccess(String msg, int domain, int type) {
+ try {
+ IoUtils.closeQuietly(Os.socket(domain, type, 0));
+ } catch (ErrnoException e) {
+ fail(msg + e.getMessage());
+ }
+ }
+
+ private static void expectSocketPemissionError(String msg, int domain, int type) {
+ try {
+ IoUtils.closeQuietly(Os.socket(domain, type, 0));
+ fail(msg);
+ } catch (ErrnoException e) {
+ assertEquals(msg, e.errno, EPERM);
+ }
+ }
+
+ private static void expectHasNetworking() {
+ expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
+ AF_UNIX, SOCK_STREAM);
+ expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException",
+ AF_INET, SOCK_DGRAM);
+ expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException",
+ AF_INET6, SOCK_DGRAM);
+ }
+
+ private static void expectNoNetworking() {
+ expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
+ AF_UNIX, SOCK_STREAM);
+ expectSocketPemissionError(
+ "Creating a AF_INET socket should have thrown ErrnoException(EPERM)",
+ AF_INET, SOCK_DGRAM);
+ expectSocketPemissionError(
+ "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)",
+ AF_INET6, SOCK_DGRAM);
+ }
+
+ @Test
+ public void testSetAllowNetworkingForProcess() {
+ expectHasNetworking();
+ NetworkUtilsInternal.setAllowNetworkingForProcess(false);
+ expectNoNetworking();
+ NetworkUtilsInternal.setAllowNetworkingForProcess(true);
+ expectHasNetworking();
+ }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index db7ef19e..5b6f637 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -4742,11 +4742,9 @@
@Test
public void testNetworkCallbackMaximum() {
- // We can only have 99 callbacks, because MultipathPolicyTracker is
- // already one of them.
- final int MAX_REQUESTS = 99;
+ final int MAX_REQUESTS = 100;
final int CALLBACKS = 89;
- final int INTENTS = 10;
+ final int INTENTS = 11;
assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS);
NetworkRequest networkRequest = new NetworkRequest.Builder().build();
diff --git a/tests/net/java/com/android/server/NetworkManagementServiceTest.java b/tests/net/java/com/android/server/NetworkManagementServiceTest.java
index ea763d2..13516d7 100644
--- a/tests/net/java/com/android/server/NetworkManagementServiceTest.java
+++ b/tests/net/java/com/android/server/NetworkManagementServiceTest.java
@@ -68,11 +68,12 @@
@SmallTest
public class NetworkManagementServiceTest {
private NetworkManagementService mNMService;
-
@Mock private Context mContext;
@Mock private IBatteryStats.Stub mBatteryStatsService;
@Mock private INetd.Stub mNetdService;
+ private static final int TEST_UID = 111;
+
@NonNull
@Captor
private ArgumentCaptor<INetdUnsolicitedEventListener> mUnsolListenerCaptor;
@@ -165,14 +166,14 @@
/**
* Interface class activity.
*/
- unsolListener.onInterfaceClassActivityChanged(true, 1, 1234, 0);
- expectSoon(observer).interfaceClassDataActivityChanged("1", true, 1234);
+ unsolListener.onInterfaceClassActivityChanged(true, 1, 1234, TEST_UID);
+ expectSoon(observer).interfaceClassDataActivityChanged(1, true, 1234, TEST_UID);
- unsolListener.onInterfaceClassActivityChanged(false, 9, 5678, 0);
- expectSoon(observer).interfaceClassDataActivityChanged("9", false, 5678);
+ unsolListener.onInterfaceClassActivityChanged(false, 9, 5678, TEST_UID);
+ expectSoon(observer).interfaceClassDataActivityChanged(9, false, 5678, TEST_UID);
- unsolListener.onInterfaceClassActivityChanged(false, 9, 4321, 0);
- expectSoon(observer).interfaceClassDataActivityChanged("9", false, 4321);
+ unsolListener.onInterfaceClassActivityChanged(false, 9, 4321, TEST_UID);
+ expectSoon(observer).interfaceClassDataActivityChanged(9, false, 4321, TEST_UID);
/**
* IP address changes.
@@ -222,8 +223,6 @@
assertFalse(mNMService.isFirewallEnabled());
}
- private static final int TEST_UID = 111;
-
@Test
public void testNetworkRestrictedDefault() {
assertFalse(mNMService.isNetworkRestricted(TEST_UID));
@@ -235,23 +234,23 @@
doReturn(true).when(mNetdService).bandwidthEnableDataSaver(anyBoolean());
// Restrict usage of mobile data in background
- mNMService.setUidMeteredNetworkDenylist(TEST_UID, true);
+ mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, true);
assertTrue("Should be true since mobile data usage is restricted",
mNMService.isNetworkRestricted(TEST_UID));
mNMService.setDataSaverModeEnabled(true);
verify(mNetdService).bandwidthEnableDataSaver(true);
- mNMService.setUidMeteredNetworkDenylist(TEST_UID, false);
+ mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, false);
assertTrue("Should be true since data saver is on and the uid is not allowlisted",
mNMService.isNetworkRestricted(TEST_UID));
- mNMService.setUidMeteredNetworkAllowlist(TEST_UID, true);
+ mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, true);
assertFalse("Should be false since data saver is on and the uid is allowlisted",
mNMService.isNetworkRestricted(TEST_UID));
// remove uid from allowlist and turn datasaver off again
- mNMService.setUidMeteredNetworkAllowlist(TEST_UID, false);
+ mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, false);
mNMService.setDataSaverModeEnabled(false);
verify(mNetdService).bandwidthEnableDataSaver(false);
assertFalse("Network should not be restricted when data saver is off",
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index fb0cfc0..89146f9 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -23,11 +23,11 @@
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.NetworkUtils.multiplySafeByRational;
import static android.os.Process.myUid;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static com.android.internal.net.NetworkUtilsInternal.multiplySafeByRational;
import static com.android.testutils.MiscAsserts.assertThrows;
import static org.junit.Assert.assertArrayEquals;
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index cd9406c..c783629 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -23,6 +23,7 @@
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.TYPE_WIMAX;
import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
+import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.INTERFACES_ALL;
@@ -917,7 +918,8 @@
public void testMetered() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState(true /* isMetered */)};
+ NetworkState[] states =
+ new NetworkState[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1146,7 +1148,8 @@
public void testStatsProviderUpdateStats() throws Exception {
// Pretend that network comes online.
expectDefaultSettings();
- final NetworkState[] states = new NetworkState[]{buildWifiState(true /* isMetered */)};
+ final NetworkState[] states =
+ new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1206,7 +1209,8 @@
public void testStatsProviderSetAlert() throws Exception {
// Pretend that network comes online.
expectDefaultSettings();
- NetworkState[] states = new NetworkState[]{buildWifiState(true /* isMetered */)};
+ NetworkState[] states =
+ new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// Register custom provider and retrieve callback.
@@ -1319,6 +1323,47 @@
assertUidTotal(templateAll, UID_RED, 22L + 35L, 26L + 29L, 19L + 7L, 5L + 11L, 1);
}
+ @Test
+ public void testOperationCount_nonDefault_traffic() throws Exception {
+ // Pretend mobile network comes online, but wifi is the default network.
+ expectDefaultSettings();
+ NetworkState[] states = new NetworkState[]{
+ buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)};
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+
+ // Create some traffic on mobile network.
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 2L, 1L, 3L, 4L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_YES, 1L, 3L, 2L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 5L, 4L, 1L, 4L, 0L));
+ // Increment operation count, which must have a specific tag.
+ mService.incrementOperationCount(UID_RED, 0xF00D, 2);
+ forcePollAndWaitForIdle();
+
+ // Verify mobile summary is not changed by the operation count.
+ final NetworkTemplate templateMobile =
+ buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL);
+ final NetworkStats statsMobile = mSession.getSummaryForAllUid(
+ templateMobile, Long.MIN_VALUE, Long.MAX_VALUE, true);
+ assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 3L, 4L, 5L, 5L, 0);
+ assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 5L, 4L, 1L, 4L, 0);
+
+ // Verify the operation count is blamed onto the default network.
+ // TODO: Blame onto the default network is not very reasonable. Consider blame onto the
+ // network that generates the traffic.
+ final NetworkTemplate templateWifi = buildTemplateWifiWildcard();
+ final NetworkStats statsWifi = mSession.getSummaryForAllUid(
+ templateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
+ assertValues(statsWifi, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 2);
+ }
+
private static File getBaseDir(File statsDir) {
File baseDir = new File(statsDir, "netstats");
baseDir.mkdirs();
@@ -1446,14 +1491,14 @@
}
private static NetworkState buildWifiState() {
- return buildWifiState(false);
+ return buildWifiState(false, TEST_IFACE);
}
- private static NetworkState buildWifiState(boolean isMetered) {
+ private static NetworkState buildWifiState(boolean isMetered, @NonNull String iface) {
final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(TEST_IFACE);
+ prop.setInterfaceName(iface);
final NetworkCapabilities capabilities = new NetworkCapabilities();
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered);
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);