Merge "Prevent NPEs when registering/unregistering ConnDiags CBs."
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 0ce43cc..be0e040 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,5 +1,8 @@
{
"presubmit": [
+ {
+ "name": "ConnectivityCoverageTests"
+ },
// Run in addition to mainline-presubmit as mainline-presubmit is not
// supported in every branch.
// CtsNetTestCasesLatestSdk uses stable API shims, so does not exercise
@@ -21,7 +24,7 @@
],
"postsubmit": [
{
- "name": "ConnectivityCoverageTests"
+ "name": "TetheringPrivilegedTests"
}
],
"mainline-presubmit": [
@@ -32,6 +35,9 @@
"exclude-annotation": "com.android.testutils.SkipPresubmit"
}
]
+ },
+ {
+ "name": "ConnectivityCoverageTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
}
],
"mainline-postsubmit": [
@@ -42,9 +48,6 @@
},
{
"name": "TetheringCoverageTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
- },
- {
- "name": "ConnectivityCoverageTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
}
],
"imports": [
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index 6031646..60c1f2b 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -33,13 +33,13 @@
"NetworkStackApiStableShims",
"androidx.annotation_annotation",
"modules-utils-build",
- "netlink-client",
"networkstack-client",
"android.hardware.tetheroffload.config-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
"android.hardware.tetheroffload.control-V1.1-java",
"net-utils-framework-common",
"net-utils-device-common",
+ "net-utils-device-common-netlink",
"netd-client",
],
libs: [
diff --git a/Tethering/apex/AndroidManifest.xml b/Tethering/apex/AndroidManifest.xml
index 4aae3cc..dbc8ec8 100644
--- a/Tethering/apex/AndroidManifest.xml
+++ b/Tethering/apex/AndroidManifest.xml
@@ -18,12 +18,4 @@
package="com.android.tethering">
<!-- APEX does not have classes.dex -->
<application android:hasCode="false" />
- <!-- b/145383354: Current minSdk is locked to Q for development cycle, lock it to next version
- before ship. -->
- <!-- TODO: Uncomment this when the R API level is fixed. b/148281152 -->
- <!--uses-sdk
- android:minSdkVersion="29"
- android:targetSdkVersion="29"
- />
- -->
</manifest>
diff --git a/Tethering/apex/manifest.json b/Tethering/apex/manifest.json
index 8836c4e..88f13b2 100644
--- a/Tethering/apex/manifest.json
+++ b/Tethering/apex/manifest.json
@@ -1,4 +1,4 @@
{
"name": "com.android.tethering",
- "version": 300900700
+ "version": 319999900
}
diff --git a/Tethering/jni/android_net_util_TetheringUtils.cpp b/Tethering/jni/android_net_util_TetheringUtils.cpp
index 27c84cf..2e76501 100644
--- a/Tethering/jni/android_net_util_TetheringUtils.cpp
+++ b/Tethering/jni/android_net_util_TetheringUtils.cpp
@@ -34,6 +34,10 @@
static const uint32_t kIPv6PayloadStart = sizeof(ip6_hdr);
static const uint32_t kICMPv6TypeOffset = kIPv6PayloadStart + offsetof(icmp6_hdr, icmp6_type);
+static void throwSocketException(JNIEnv *env, const char* msg, int error) {
+ jniThrowExceptionFmt(env, "java/net/SocketException", "%s: %s", msg, strerror(error));
+}
+
static void android_net_util_setupIcmpFilter(JNIEnv *env, jobject javaFd, uint32_t type) {
sock_filter filter_code[] = {
// Check header is ICMPv6.
@@ -56,8 +60,7 @@
int fd = netjniutils::GetNativeFileDescriptor(env, javaFd);
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
+ throwSocketException(env, "setsockopt(SO_ATTACH_FILTER)", errno);
}
}
@@ -84,8 +87,7 @@
ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &rs_only);
socklen_t len = sizeof(rs_only);
if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &rs_only, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(ICMP6_FILTER): %s", strerror(errno));
+ throwSocketException(env, "setsockopt(ICMP6_FILTER)", errno);
return;
}
@@ -97,8 +99,7 @@
int hops = kLinkLocalHopLimit;
len = sizeof(hops);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errno));
+ throwSocketException(env, "setsockopt(IPV6_MULTICAST_HOPS)", errno);
return;
}
@@ -106,8 +107,7 @@
hops = kLinkLocalHopLimit;
len = sizeof(hops);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_UNICAST_HOPS): %s", strerror(errno));
+ throwSocketException(env, "setsockopt(IPV6_UNICAST_HOPS)", errno);
return;
}
@@ -115,16 +115,14 @@
int off = 0;
len = sizeof(off);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_MULTICAST_LOOP): %s", strerror(errno));
+ throwSocketException(env, "setsockopt(IPV6_MULTICAST_LOOP)", errno);
return;
}
// Specify the IPv6 interface to use for outbound multicast.
len = sizeof(ifIndex);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_MULTICAST_IF): %s", strerror(errno));
+ throwSocketException(env, "setsockopt(IPV6_MULTICAST_IF)", errno);
return;
}
@@ -144,8 +142,7 @@
auto sa = reinterpret_cast<const struct sockaddr *>(&sin6);
len = sizeof(sin6);
if (bind(fd, sa, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "bind(IN6ADDR_ANY): %s", strerror(errno));
+ throwSocketException(env, "bind(IN6ADDR_ANY)", errno);
return;
}
@@ -156,8 +153,7 @@
};
len = sizeof(all_rtrs);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &all_rtrs, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_JOIN_GROUP): %s", strerror(errno));
+ throwSocketException(env, "setsockopt(IPV6_JOIN_GROUP)", errno);
return;
}
}
diff --git a/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp
index eadc210..260dbc1 100644
--- a/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp
+++ b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp
@@ -27,40 +27,11 @@
namespace android {
-static jclass sErrnoExceptionClass;
-static jmethodID sErrnoExceptionCtor2;
-static jmethodID sErrnoExceptionCtor3;
-
-static void throwErrnoException(JNIEnv* env, const char* functionName, int error) {
- if (sErrnoExceptionClass == nullptr || sErrnoExceptionClass == nullptr) return;
-
- jthrowable cause = nullptr;
- if (env->ExceptionCheck()) {
- cause = env->ExceptionOccurred();
- env->ExceptionClear();
- }
-
- ScopedLocalRef<jstring> msg(env, env->NewStringUTF(functionName));
-
- // Not really much we can do here if msg is null, let's try to stumble on...
- if (msg.get() == nullptr) env->ExceptionClear();
-
- jobject errnoException;
- if (cause != nullptr) {
- errnoException = env->NewObject(sErrnoExceptionClass, sErrnoExceptionCtor3, msg.get(),
- error, cause);
- } else {
- errnoException = env->NewObject(sErrnoExceptionClass, sErrnoExceptionCtor2, msg.get(),
- error);
- }
- env->Throw(static_cast<jthrowable>(errnoException));
-}
-
static jint com_android_networkstack_tethering_BpfMap_closeMap(JNIEnv *env, jobject clazz,
jint fd) {
int ret = close(fd);
- if (ret) throwErrnoException(env, "closeMap", errno);
+ if (ret) jniThrowErrnoException(env, "closeMap", errno);
return ret;
}
@@ -71,6 +42,8 @@
jint fd = bpf::bpfFdGet(pathname.c_str(), static_cast<unsigned>(mode));
+ if (fd < 0) jniThrowErrnoException(env, "bpfFdGet", errno);
+
return fd;
}
@@ -82,13 +55,13 @@
int ret = bpf::writeToMapEntry(static_cast<int>(fd), keyRO.get(), valueRO.get(),
static_cast<int>(flags));
- if (ret) throwErrnoException(env, "writeToMapEntry", errno);
+ if (ret) jniThrowErrnoException(env, "writeToMapEntry", errno);
}
static jboolean throwIfNotEnoent(JNIEnv *env, const char* functionName, int ret, int err) {
if (ret == 0) return true;
- if (err != ENOENT) throwErrnoException(env, functionName, err);
+ if (err != ENOENT) jniThrowErrnoException(env, functionName, err);
return false;
}
@@ -155,18 +128,6 @@
};
int register_com_android_networkstack_tethering_BpfMap(JNIEnv* env) {
- sErrnoExceptionClass = static_cast<jclass>(env->NewGlobalRef(
- env->FindClass("android/system/ErrnoException")));
- if (sErrnoExceptionClass == nullptr) return JNI_ERR;
-
- sErrnoExceptionCtor2 = env->GetMethodID(sErrnoExceptionClass, "<init>",
- "(Ljava/lang/String;I)V");
- if (sErrnoExceptionCtor2 == nullptr) return JNI_ERR;
-
- sErrnoExceptionCtor3 = env->GetMethodID(sErrnoExceptionClass, "<init>",
- "(Ljava/lang/String;ILjava/lang/Throwable;)V");
- if (sErrnoExceptionCtor3 == nullptr) return JNI_ERR;
-
return jniRegisterNativeMethods(env,
"com/android/networkstack/tethering/BpfMap",
gMethods, NELEM(gMethods));
diff --git a/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp b/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp
index 2fb5985..2d679a8 100644
--- a/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp
+++ b/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp
@@ -44,37 +44,36 @@
const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK;
const sockaddr_nl KERNEL_NLADDR = {AF_NETLINK, 0, 0, 0};
+static void throwIOException(JNIEnv *env, const char* msg, int error) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "%s: %s", msg, strerror(error));
+}
+
// TODO: move to frameworks/libs/net/common/native for sharing with
// system/netd/server/OffloadUtils.{c, h}.
static void sendAndProcessNetlinkResponse(JNIEnv* env, const void* req, int len) {
int fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); // TODO: use unique_fd
if (fd == -1) {
- jniThrowExceptionFmt(env, "java/io/IOException",
- "socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE): %s",
- strerror(errno));
+ throwIOException(env, "socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE)", errno);
return;
}
static constexpr int on = 1;
if (setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &on, sizeof(on))) {
- jniThrowExceptionFmt(env, "java/io/IOException",
- "setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, %d)", on);
+ throwIOException(env, "setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, 1)", errno);
close(fd);
return;
}
// this is needed to get valid strace netlink parsing, it allocates the pid
if (bind(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR))) {
- jniThrowExceptionFmt(env, "java/io/IOException", "bind(fd, {AF_NETLINK, 0, 0}): %s",
- strerror(errno));
+ throwIOException(env, "bind(fd, {AF_NETLINK, 0, 0})", errno);
close(fd);
return;
}
// we do not want to receive messages from anyone besides the kernel
if (connect(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR))) {
- jniThrowExceptionFmt(env, "java/io/IOException", "connect(fd, {AF_NETLINK, 0, 0}): %s",
- strerror(errno));
+ throwIOException(env, "connect(fd, {AF_NETLINK, 0, 0})", errno);
close(fd);
return;
}
@@ -82,15 +81,13 @@
int rv = send(fd, req, len, 0);
if (rv == -1) {
- jniThrowExceptionFmt(env, "java/io/IOException", "send(fd, req, len, 0): %s",
- strerror(errno));
+ throwIOException(env, "send(fd, req, len, 0)", errno);
close(fd);
return;
}
if (rv != len) {
- jniThrowExceptionFmt(env, "java/io/IOException", "send(fd, req, len, 0): %s",
- strerror(EMSGSIZE));
+ throwIOException(env, "send(fd, req, len, 0)", EMSGSIZE);
close(fd);
return;
}
@@ -104,7 +101,7 @@
rv = recv(fd, &resp, sizeof(resp), MSG_TRUNC);
if (rv == -1) {
- jniThrowExceptionFmt(env, "java/io/IOException", "recv() failed: %s", strerror(errno));
+ throwIOException(env, "recv() failed", errno);
close(fd);
return;
}
@@ -131,8 +128,7 @@
}
if (resp.e.error) { // returns 0 on success
- jniThrowExceptionFmt(env, "java/io/IOException", "NLMSG_ERROR message return error: %s",
- strerror(-resp.e.error));
+ throwIOException(env, "NLMSG_ERROR message return error", -resp.e.error);
}
close(fd);
return;
@@ -198,8 +194,7 @@
const int bpfFd = bpf::retrieveProgram(pathname.c_str());
if (bpfFd == -1) {
- jniThrowExceptionFmt(env, "java/io/IOException", "retrieveProgram failed %s",
- strerror(errno));
+ throwIOException(env, "retrieveProgram failed", errno);
return;
}
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 822bdf6..cf49683 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -26,6 +26,7 @@
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.networkstack.tethering.UpstreamNetworkState.isVcnInterface;
import android.net.INetd;
import android.net.INetworkStackStatusCallback;
@@ -51,7 +52,6 @@
import android.net.util.InterfaceSet;
import android.net.util.PrefixUtils;
import android.net.util.SharedLog;
-import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -66,6 +66,7 @@
import com.android.internal.util.MessageUtils;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
+import com.android.modules.utils.build.SdkLevel;
import com.android.networkstack.tethering.BpfCoordinator;
import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
@@ -675,9 +676,7 @@
return false;
}
- // TODO: use ShimUtils instead of explicitly checking the version here.
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R || "S".equals(Build.VERSION.CODENAME)
- || "T".equals(Build.VERSION.CODENAME)) {
+ if (SdkLevel.isAtLeastS()) {
// DAD Proxy starts forwarding packets after IPv6 upstream is present.
mDadProxy = mDeps.getDadProxy(getHandler(), mInterfaceParams);
}
@@ -755,6 +754,9 @@
// deprecation of any existing RA data.
setRaParams(params);
+ // Be aware that updateIpv6ForwardingRules use mLastIPv6LinkProperties, so this line should
+ // be eariler than updateIpv6ForwardingRules.
+ // TODO: avoid this dependencies and move this logic into BpfCoordinator.
mLastIPv6LinkProperties = v6only;
updateIpv6ForwardingRules(mLastIPv6UpstreamIfindex, upstreamIfIndex, null);
@@ -892,12 +894,20 @@
mBpfCoordinator.tetherOffloadRuleUpdate(this, newIfindex);
}
+ private boolean isIpv6VcnNetworkInterface() {
+ if (mLastIPv6LinkProperties == null) return false;
+
+ return isVcnInterface(mLastIPv6LinkProperties.getInterfaceName());
+ }
+
// Handles all updates to IPv6 forwarding rules. These can currently change only if the upstream
// changes or if a neighbor event is received.
private void updateIpv6ForwardingRules(int prevUpstreamIfindex, int upstreamIfindex,
NeighborEvent e) {
- // If we no longer have an upstream, clear forwarding rules and do nothing else.
- if (upstreamIfindex == 0) {
+ // If no longer have an upstream or it is virtual network, clear forwarding rules and do
+ // nothing else.
+ // TODO: Rather than always clear rules, ensure whether ipv6 ever enable first.
+ if (upstreamIfindex == 0 || isIpv6VcnNetworkInterface()) {
clearIpv6ForwardingRules();
return;
}
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 2c1fd29..5b39a23 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -31,6 +31,7 @@
import static com.android.networkstack.tethering.BpfUtils.DOWNSTREAM;
import static com.android.networkstack.tethering.BpfUtils.UPSTREAM;
import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
+import static com.android.networkstack.tethering.UpstreamNetworkState.isVcnInterface;
import android.app.usage.NetworkStatsManager;
import android.net.INetd;
@@ -41,9 +42,6 @@
import android.net.ip.ConntrackMonitor;
import android.net.ip.ConntrackMonitor.ConntrackEventConsumer;
import android.net.ip.IpServer;
-import android.net.netlink.ConntrackMessage;
-import android.net.netlink.NetlinkConstants;
-import android.net.netlink.NetlinkSocket;
import android.net.netstats.provider.NetworkStatsProvider;
import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
@@ -65,6 +63,9 @@
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.Struct;
+import com.android.net.module.util.netlink.ConntrackMessage;
+import com.android.net.module.util.netlink.NetlinkConstants;
+import com.android.net.module.util.netlink.NetlinkSocket;
import com.android.networkstack.tethering.apishim.common.BpfCoordinatorShim;
import java.net.Inet4Address;
@@ -124,9 +125,9 @@
}
@VisibleForTesting
- static final int POLLING_CONNTRACK_TIMEOUT_MS = 60_000;
+ static final int CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS = 60_000;
@VisibleForTesting
- static final int NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED = 432000;
+ static final int NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED = 432_000;
@VisibleForTesting
static final int NF_CONNTRACK_UDP_TIMEOUT_STREAM = 180;
@@ -249,10 +250,10 @@
maybeSchedulePollingStats();
};
- // Runnable that used by scheduling next polling of conntrack timeout.
- private final Runnable mScheduledPollingConntrackTimeout = () -> {
- maybeRefreshConntrackTimeout();
- maybeSchedulePollingConntrackTimeout();
+ // Runnable that used by scheduling next refreshing of conntrack timeout.
+ private final Runnable mScheduledConntrackTimeoutUpdate = () -> {
+ refreshAllConntrackTimeouts();
+ maybeScheduleConntrackTimeoutUpdate();
};
// TODO: add BpfMap<TetherDownstream64Key, TetherDownstream64Value> retrieving function.
@@ -434,7 +435,7 @@
mPollingStarted = true;
maybeSchedulePollingStats();
- maybeSchedulePollingConntrackTimeout();
+ maybeScheduleConntrackTimeoutUpdate();
mLog.i("Polling started");
}
@@ -451,8 +452,8 @@
if (!mPollingStarted) return;
// Stop scheduled polling conntrack timeout.
- if (mHandler.hasCallbacks(mScheduledPollingConntrackTimeout)) {
- mHandler.removeCallbacks(mScheduledPollingConntrackTimeout);
+ if (mHandler.hasCallbacks(mScheduledConntrackTimeoutUpdate)) {
+ mHandler.removeCallbacks(mScheduledConntrackTimeoutUpdate);
}
// Stop scheduled polling stats and poll the latest stats from BPF maps.
if (mHandler.hasCallbacks(mScheduledPollingStats)) {
@@ -666,6 +667,8 @@
if (upstreamIfindex == 0 || TextUtils.isEmpty(upstreamIface)) return;
+ if (isVcnInterface(upstreamIface)) return;
+
// The same interface index to name mapping may be added by different IpServer objects or
// re-added by reconnection on the same upstream interface. Ignore the duplicate one.
final String iface = mInterfaceNames.get(upstreamIfindex);
@@ -833,9 +836,10 @@
// TODO: need to consider 464xlat.
if (ns != null && ns.linkProperties != null && ns.linkProperties.hasIpv4Address()) {
// TODO: support ether ip upstream interface.
- final InterfaceParams params = mDeps.getInterfaceParams(
- ns.linkProperties.getInterfaceName());
- if (params != null && !params.hasMacAddress /* raw ip upstream only */) {
+ final String ifaceName = ns.linkProperties.getInterfaceName();
+ final InterfaceParams params = mDeps.getInterfaceParams(ifaceName);
+ final boolean isVcn = isVcnInterface(ifaceName);
+ if (!isVcn && params != null && !params.hasMacAddress /* raw ip upstream only */) {
upstreamIndex = params.index;
}
}
@@ -879,6 +883,8 @@
* TODO: consider error handling if the attach program failed.
*/
public void maybeAttachProgram(@NonNull String intIface, @NonNull String extIface) {
+ if (isVcnInterface(extIface)) return;
+
if (forwardingPairExists(intIface, extIface)) return;
boolean firstDownstreamForThisUpstream = !isAnyForwardingPairOnUpstream(extIface);
@@ -1051,6 +1057,15 @@
}
}
+ private String l4protoToString(int proto) {
+ if (proto == OsConstants.IPPROTO_TCP) {
+ return "tcp";
+ } else if (proto == OsConstants.IPPROTO_UDP) {
+ return "udp";
+ }
+ return String.format("unknown(%d)", proto);
+ }
+
private String ipv4RuleToString(long now, boolean downstream,
Tether4Key key, Tether4Value value) {
final String src4, public4, dst4;
@@ -1069,12 +1084,11 @@
throw new AssertionError("IP address array not valid IPv4 address!");
}
- final String protoStr = (key.l4proto == OsConstants.IPPROTO_TCP) ? "tcp" : "udp";
final String ageStr = (value.lastUsed == 0) ? "-"
: String.format("%dms", (now - value.lastUsed) / 1_000_000);
return String.format("%s [%s] %d(%s) %s:%d -> %d(%s) %s:%d -> %s:%d [%s] %s",
- protoStr, key.dstMac, key.iif, getIfName(key.iif), src4, key.srcPort,
- value.oif, getIfName(value.oif),
+ l4protoToString(key.l4proto), key.dstMac, key.iif, getIfName(key.iif),
+ src4, key.srcPort, value.oif, getIfName(value.oif),
public4, publicPort, dst4, value.dstPort, value.ethDstMac, ageStr);
}
@@ -1443,25 +1457,6 @@
return addr6;
}
- @Nullable
- private Inet4Address ipv4MappedAddressBytesToIpv4Address(final byte[] addr46) {
- if (addr46.length != 16) return null;
- if (addr46[0] != 0 || addr46[1] != 0 || addr46[2] != 0 || addr46[3] != 0
- || addr46[4] != 0 || addr46[5] != 0 || addr46[6] != 0 || addr46[7] != 0
- || addr46[8] != 0 && addr46[9] != 0 || (addr46[10] & 0xff) != 0xff
- || (addr46[11] & 0xff) != 0xff) {
- return null;
- }
-
- final byte[] addr4 = new byte[4];
- addr4[0] = addr46[12];
- addr4[1] = addr46[13];
- addr4[2] = addr46[14];
- addr4[3] = addr46[15];
-
- return parseIPv4Address(addr4);
- }
-
// TODO: parse CTA_PROTOINFO of conntrack event in ConntrackMonitor. For TCP, only add rules
// while TCP status is established.
@VisibleForTesting
@@ -1861,7 +1856,7 @@
try {
final InetAddress ia = Inet4Address.getByAddress(addrBytes);
if (ia instanceof Inet4Address) return (Inet4Address) ia;
- } catch (UnknownHostException | IllegalArgumentException e) {
+ } catch (UnknownHostException e) {
mLog.e("Failed to parse IPv4 address: " + e);
}
return null;
@@ -1871,7 +1866,15 @@
// coming a conntrack event to notify updated timeout.
private void updateConntrackTimeout(byte proto, Inet4Address src4, short srcPort,
Inet4Address dst4, short dstPort) {
- if (src4 == null || dst4 == null) return;
+ if (src4 == null || dst4 == null) {
+ mLog.e("Either source or destination IPv4 address is invalid ("
+ + "proto: " + proto + ", "
+ + "src4: " + src4 + ", "
+ + "srcPort: " + Short.toUnsignedInt(srcPort) + ", "
+ + "dst4: " + dst4 + ", "
+ + "dstPort: " + Short.toUnsignedInt(dstPort) + ")");
+ return;
+ }
// TODO: consider acquiring the timeout setting from nf_conntrack_* variables.
// - proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
@@ -1885,38 +1888,50 @@
try {
NetlinkSocket.sendOneShotKernelMessage(OsConstants.NETLINK_NETFILTER, msg);
} catch (ErrnoException e) {
- mLog.e("Error updating conntrack entry ("
+ // Lower the log level for the entry not existing. The conntrack entry may have been
+ // deleted and not handled by the conntrack event monitor yet. In other words, the
+ // rule has not been deleted from the BPF map yet. Deleting a non-existent entry may
+ // happen during the conntrack timeout refreshing iteration. Note that ENOENT may be
+ // a real error but is hard to distinguish.
+ // TODO: Figure out a better way to handle this.
+ final String errMsg = "Failed to update conntrack entry ("
+ "proto: " + proto + ", "
+ "src4: " + src4 + ", "
+ "srcPort: " + Short.toUnsignedInt(srcPort) + ", "
+ "dst4: " + dst4 + ", "
+ "dstPort: " + Short.toUnsignedInt(dstPort) + "), "
+ "msg: " + NetlinkConstants.hexify(msg) + ", "
- + "e: " + e);
+ + "e: " + e;
+ if (OsConstants.ENOENT == e.errno) {
+ mLog.w(errMsg);
+ } else {
+ mLog.e(errMsg);
+ }
}
}
- private void maybeRefreshConntrackTimeout() {
+ private void refreshAllConntrackTimeouts() {
final long now = mDeps.elapsedRealtimeNanos();
- // Reverse the source and destination {address, port} from downstream value because
- // #updateConntrackTimeout refresh the timeout of netlink attribute CTA_TUPLE_ORIG
- // which is opposite direction for downstream map value.
- mBpfCoordinatorShim.tetherOffloadRuleForEach(DOWNSTREAM, (k, v) -> {
- if ((now - v.lastUsed) / 1_000_000 < POLLING_CONNTRACK_TIMEOUT_MS) {
- updateConntrackTimeout((byte) k.l4proto,
- ipv4MappedAddressBytesToIpv4Address(v.dst46), (short) v.dstPort,
- ipv4MappedAddressBytesToIpv4Address(v.src46), (short) v.srcPort);
- }
- });
-
// TODO: Consider ignoring TCP traffic on upstream and monitor on downstream only
// because TCP is a bidirectional traffic. Probably don't need to extend timeout by
// both directions for TCP.
mBpfCoordinatorShim.tetherOffloadRuleForEach(UPSTREAM, (k, v) -> {
- if ((now - v.lastUsed) / 1_000_000 < POLLING_CONNTRACK_TIMEOUT_MS) {
- updateConntrackTimeout((byte) k.l4proto, parseIPv4Address(k.src4),
- (short) k.srcPort, parseIPv4Address(k.dst4), (short) k.dstPort);
+ if ((now - v.lastUsed) / 1_000_000 < CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS) {
+ updateConntrackTimeout((byte) k.l4proto,
+ parseIPv4Address(k.src4), (short) k.srcPort,
+ parseIPv4Address(k.dst4), (short) k.dstPort);
+ }
+ });
+
+ // Reverse the source and destination {address, port} from downstream value because
+ // #updateConntrackTimeout refresh the timeout of netlink attribute CTA_TUPLE_ORIG
+ // which is opposite direction for downstream map value.
+ mBpfCoordinatorShim.tetherOffloadRuleForEach(DOWNSTREAM, (k, v) -> {
+ if ((now - v.lastUsed) / 1_000_000 < CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS) {
+ updateConntrackTimeout((byte) k.l4proto,
+ parseIPv4Address(v.dst46), (short) v.dstPort,
+ parseIPv4Address(v.src46), (short) v.srcPort);
}
});
}
@@ -1931,14 +1946,15 @@
mHandler.postDelayed(mScheduledPollingStats, getPollingInterval());
}
- private void maybeSchedulePollingConntrackTimeout() {
+ private void maybeScheduleConntrackTimeoutUpdate() {
if (!mPollingStarted) return;
- if (mHandler.hasCallbacks(mScheduledPollingConntrackTimeout)) {
- mHandler.removeCallbacks(mScheduledPollingConntrackTimeout);
+ if (mHandler.hasCallbacks(mScheduledConntrackTimeoutUpdate)) {
+ mHandler.removeCallbacks(mScheduledConntrackTimeoutUpdate);
}
- mHandler.postDelayed(mScheduledPollingConntrackTimeout, POLLING_CONNTRACK_TIMEOUT_MS);
+ mHandler.postDelayed(mScheduledConntrackTimeoutUpdate,
+ CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS);
}
// Return forwarding rule map. This is used for testing only.
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadController.java b/Tethering/src/com/android/networkstack/tethering/OffloadController.java
index beb1821..d60c21d 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadController.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadController.java
@@ -42,9 +42,6 @@
import android.net.NetworkStats;
import android.net.NetworkStats.Entry;
import android.net.RouteInfo;
-import android.net.netlink.ConntrackMessage;
-import android.net.netlink.NetlinkConstants;
-import android.net.netlink.NetlinkSocket;
import android.net.netstats.provider.NetworkStatsProvider;
import android.net.util.SharedLog;
import android.os.Handler;
@@ -56,6 +53,9 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.net.module.util.netlink.ConntrackMessage;
+import com.android.net.module.util.netlink.NetlinkConstants;
+import com.android.net.module.util.netlink.NetlinkSocket;
import com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
import java.net.Inet4Address;
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index e3ac660..f336d9b 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -16,10 +16,11 @@
package com.android.networkstack.tethering;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
import static android.net.util.TetheringUtils.uint16;
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_DUMP;
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
@@ -28,9 +29,6 @@
import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
import android.hardware.tetheroffload.control.V1_1.ITetheringOffloadCallback;
-import android.net.netlink.NetlinkSocket;
-import android.net.netlink.StructNfGenMsg;
-import android.net.netlink.StructNlMsgHdr;
import android.net.util.SharedLog;
import android.net.util.SocketUtils;
import android.os.Handler;
@@ -43,6 +41,9 @@
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.netlink.NetlinkSocket;
+import com.android.net.module.util.netlink.StructNfGenMsg;
+import com.android.net.module.util.netlink.StructNlMsgHdr;
import java.io.FileDescriptor;
import java.io.IOException;
diff --git a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
index 69471a1..5584db2 100644
--- a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
+++ b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
@@ -49,7 +49,6 @@
import com.android.internal.util.StateMachine;
import com.android.networkstack.apishim.ConnectivityManagerShimImpl;
import com.android.networkstack.apishim.common.ConnectivityManagerShim;
-import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
import java.util.HashMap;
import java.util.HashSet;
@@ -162,12 +161,7 @@
}
ConnectivityManagerShim mCmShim = ConnectivityManagerShimImpl.newInstance(mContext);
mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_DEFAULT_INTERNET);
- try {
- mCmShim.registerSystemDefaultNetworkCallback(mDefaultNetworkCallback, mHandler);
- } catch (UnsupportedApiLevelException e) {
- Log.wtf(TAG, "registerSystemDefaultNetworkCallback is not supported");
- return;
- }
+ mCmShim.registerSystemDefaultNetworkCallback(mDefaultNetworkCallback, mHandler);
if (mEntitlementMgr == null) {
mEntitlementMgr = entitle;
}
diff --git a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkState.java b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkState.java
index bab9f84..986c3f7 100644
--- a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkState.java
+++ b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkState.java
@@ -15,6 +15,8 @@
*/
package com.android.networkstack.tethering;
+import static android.net.INetd.IPSEC_INTERFACE_PREFIX;
+
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
@@ -48,4 +50,9 @@
networkCapabilities == null ? "null" : networkCapabilities,
linkProperties == null ? "null" : linkProperties);
}
+
+ /** Check whether the interface is VCN. */
+ public static boolean isVcnInterface(@NonNull String iface) {
+ return iface.startsWith(IPSEC_INTERFACE_PREFIX);
+ }
}
diff --git a/Tethering/tests/integration/Android.bp b/Tethering/tests/integration/Android.bp
index b93a969..2593b1b 100644
--- a/Tethering/tests/integration/Android.bp
+++ b/Tethering/tests/integration/Android.bp
@@ -41,9 +41,10 @@
"libdexmakerjvmtiagent",
"libstaticjvmtiagent",
],
- jarjar_rules: ":NetworkStackJarJarRules",
}
+// Library including tethering integration tests targeting the latest stable SDK.
+// Use with NetworkStackJarJarRules.
android_library {
name: "TetheringIntegrationTestsLatestSdkLib",
target_sdk_version: "30",
@@ -56,6 +57,8 @@
]
}
+// Library including tethering integration tests targeting current development SDK.
+// Use with NetworkStackJarJarRules.
android_library {
name: "TetheringIntegrationTestsLib",
target_sdk_version: "current",
@@ -76,6 +79,7 @@
"mts",
],
compile_multilib: "both",
+ jarjar_rules: ":NetworkStackJarJarRules",
}
android_library {
@@ -88,13 +92,33 @@
"TetheringTestsLatestSdkLib",
"TetheringIntegrationTestsLatestSdkLib",
],
- jarjar_rules: ":TetheringTestsJarJarRules",
+ // Jarjar rules should normally be applied on final artifacts and not intermediate libraries as
+ // applying different rules on intermediate libraries can cause conflicts when combining them
+ // (the resulting artifact can end up with multiple incompatible implementations of the same
+ // classes). But this library is used to combine tethering coverage tests with connectivity
+ // coverage tests into a single coverage target. The tests need to use the same jarjar rules as
+ // covered production code for coverage to be calculated properly, so jarjar is applied
+ // separately on each set of tests.
+ jarjar_rules: ":TetheringCoverageJarJarRules",
manifest: "AndroidManifest_coverage.xml",
visibility: [
"//packages/modules/Connectivity/tests:__subpackages__"
],
}
+// Combine NetworkStack and Tethering jarjar rules for coverage target. The jarjar files are
+// simply concatenated in the order specified in srcs.
+genrule {
+ name: "TetheringCoverageJarJarRules",
+ srcs: [
+ ":TetheringTestsJarJarRules",
+ ":NetworkStackJarJarRules",
+ ],
+ out: ["jarjar-rules-tethering-coverage.txt"],
+ cmd: "cat $(in) > $(out)",
+ visibility: ["//visibility:private"],
+}
+
// Special version of the tethering tests that includes all tests necessary for code coverage
// purposes. This is currently the union of TetheringTests, TetheringIntegrationTests and
// NetworkStackTests.
diff --git a/Tethering/tests/jarjar-rules.txt b/Tethering/tests/jarjar-rules.txt
index 9cb143e..23d3f56 100644
--- a/Tethering/tests/jarjar-rules.txt
+++ b/Tethering/tests/jarjar-rules.txt
@@ -17,3 +17,8 @@
# TestableLooper from "testables" can be used instead of TestLooper from frameworks-base-testutils.
zap android.os.test.TestLooperTest*
zap com.android.test.filters.SelectTestTests*
+
+# When used in combined test suites like ConnectivityCoverageTests, these test jarjar rules are
+# combined with the jarjar-rules.txt of other included modules (like NetworkStack jarjar rules).
+# They will effectively be added after the following line break. Note that jarjar stops at the first
+# matching rule, so any rule in this file takes precedence over rules in the following ones.
diff --git a/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java b/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java
index a933e1b..23d9055 100644
--- a/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java
+++ b/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java
@@ -31,6 +31,7 @@
import android.net.MacAddress;
import android.net.util.InterfaceParams;
import android.net.util.TetheringUtils;
+import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -38,8 +39,9 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DevSdkIgnoreRunner;
import com.android.testutils.TapPacketReader;
import com.android.testutils.TapPacketReaderRule;
@@ -54,7 +56,8 @@
import java.io.IOException;
import java.nio.ByteBuffer;
-@RunWith(AndroidJUnit4.class)
+@RunWith(DevSdkIgnoreRunner.class)
+@IgnoreUpTo(Build.VERSION_CODES.R)
@SmallTest
public class DadProxyTest {
private static final int DATA_BUFFER_LEN = 4096;
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
index 830729d..f97270c 100644
--- a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
@@ -31,9 +31,8 @@
import android.system.OsConstants;
import android.util.ArrayMap;
-import androidx.test.runner.AndroidJUnit4;
-
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -45,7 +44,7 @@
import java.util.concurrent.atomic.AtomicInteger;
-@RunWith(AndroidJUnit4.class)
+@RunWith(DevSdkIgnoreRunner.class)
@IgnoreUpTo(Build.VERSION_CODES.R)
public final class BpfMapTest {
// Sync from packages/modules/Connectivity/Tethering/bpf_progs/offload.c.
@@ -389,4 +388,15 @@
assertEquals(OsConstants.E2BIG, expected.errno);
}
}
+
+ @Test
+ public void testOpenNonexistentMap() throws Exception {
+ try {
+ final BpfMap<TetherDownstream6Key, Tether6Value> nonexistentMap = new BpfMap<>(
+ "/sys/fs/bpf/tethering/nonexistent", BpfMap.BPF_F_RDWR,
+ TetherDownstream6Key.class, Tether6Value.class);
+ } catch (ErrnoException expected) {
+ assertEquals(OsConstants.ENOENT, expected.errno);
+ }
+ }
}
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
index 57c28fc..7ee69b2 100644
--- a/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
@@ -16,10 +16,9 @@
package com.android.networkstack.tethering;
-import static android.net.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-
+import static com.android.net.module.util.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_DUMP;
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
import static com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_GET;
import static com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_NEW;
import static com.android.networkstack.tethering.OffloadHardwareInterface.NFNL_SUBSYS_CTNETLINK;
@@ -29,7 +28,6 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import android.net.netlink.StructNlMsgHdr;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.HandlerThread;
@@ -40,6 +38,8 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.net.module.util.netlink.StructNlMsgHdr;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 378a21c..ef4330a 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -31,14 +31,14 @@
import static android.net.ip.IpServer.STATE_LOCAL_ONLY;
import static android.net.ip.IpServer.STATE_TETHERED;
import static android.net.ip.IpServer.STATE_UNAVAILABLE;
-import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH;
-import static android.net.netlink.NetlinkConstants.RTM_NEWNEIGH;
-import static android.net.netlink.StructNdMsg.NUD_FAILED;
-import static android.net.netlink.StructNdMsg.NUD_REACHABLE;
-import static android.net.netlink.StructNdMsg.NUD_STALE;
import static android.system.OsConstants.ETH_P_IPV6;
import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELNEIGH;
+import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWNEIGH;
+import static com.android.net.module.util.netlink.StructNdMsg.NUD_FAILED;
+import static com.android.net.module.util.netlink.StructNdMsg.NUD_REACHABLE;
+import static com.android.net.module.util.netlink.StructNdMsg.NUD_STALE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -146,8 +146,10 @@
private static final String IFACE_NAME = "testnet1";
private static final String UPSTREAM_IFACE = "upstream0";
private static final String UPSTREAM_IFACE2 = "upstream1";
+ private static final String IPSEC_IFACE = "ipsec0";
private static final int UPSTREAM_IFINDEX = 101;
private static final int UPSTREAM_IFINDEX2 = 102;
+ private static final int IPSEC_IFINDEX = 103;
private static final String BLUETOOTH_IFACE_ADDR = "192.168.44.1";
private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24;
private static final int DHCP_LEASE_TIME_SECS = 3600;
@@ -160,6 +162,8 @@
private static final InterfaceParams UPSTREAM_IFACE_PARAMS2 = new InterfaceParams(
UPSTREAM_IFACE2, UPSTREAM_IFINDEX2, MacAddress.ALL_ZEROS_ADDRESS,
1500 /* defaultMtu */);
+ private static final InterfaceParams IPSEC_IFACE_PARAMS = new InterfaceParams(
+ IPSEC_IFACE, IPSEC_IFINDEX, MacAddress.ALL_ZEROS_ADDRESS, 1500 /* defaultMtu */);
private static final int MAKE_DHCPSERVER_TIMEOUT_MS = 1000;
@@ -208,6 +212,7 @@
when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS);
when(mDependencies.getInterfaceParams(UPSTREAM_IFACE)).thenReturn(UPSTREAM_IFACE_PARAMS);
when(mDependencies.getInterfaceParams(UPSTREAM_IFACE2)).thenReturn(UPSTREAM_IFACE_PARAMS2);
+ when(mDependencies.getInterfaceParams(IPSEC_IFACE)).thenReturn(IPSEC_IFACE_PARAMS);
mInterfaceConfiguration = new InterfaceConfigurationParcel();
mInterfaceConfiguration.flags = new String[0];
@@ -1453,4 +1458,23 @@
public void testDadProxyUpdates_EnabledAfterR() throws Exception {
checkDadProxyEnabled(true);
}
+
+ @Test
+ public void testSkipVirtualNetworkInBpf() throws Exception {
+ initTetheredStateMachine(TETHERING_BLUETOOTH, null);
+ final LinkProperties v6Only = new LinkProperties();
+ v6Only.setInterfaceName(IPSEC_IFACE);
+ dispatchTetherConnectionChanged(IPSEC_IFACE, v6Only, 0);
+
+ verify(mBpfCoordinator).maybeAttachProgram(IFACE_NAME, IPSEC_IFACE);
+ verify(mNetd).tetherAddForward(IFACE_NAME, IPSEC_IFACE);
+ verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, IPSEC_IFACE);
+
+ final int myIfindex = TEST_IFACE_PARAMS.index;
+ final InetAddress neigh = InetAddresses.parseNumericAddress("2001:db8::1");
+ final MacAddress mac = MacAddress.fromString("00:00:00:00:00:0a");
+ recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, mac);
+ verify(mBpfCoordinator, never()).tetherOffloadRuleAdd(
+ mIpServer, makeForwardingRule(IPSEC_IFINDEX, neigh, mac));
+ }
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 914e0d4..6e96085 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -24,13 +24,6 @@
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStats.UID_TETHERING;
import static android.net.ip.ConntrackMonitor.ConntrackEvent;
-import static android.net.netlink.ConntrackMessage.DYING_MASK;
-import static android.net.netlink.ConntrackMessage.ESTABLISHED_MASK;
-import static android.net.netlink.ConntrackMessage.Tuple;
-import static android.net.netlink.ConntrackMessage.TupleIpv4;
-import static android.net.netlink.ConntrackMessage.TupleProto;
-import static android.net.netlink.NetlinkConstants.IPCTNL_MSG_CT_DELETE;
-import static android.net.netlink.NetlinkConstants.IPCTNL_MSG_CT_NEW;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
import static android.system.OsConstants.ETH_P_IP;
import static android.system.OsConstants.ETH_P_IPV6;
@@ -40,9 +33,16 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker;
+import static com.android.net.module.util.netlink.ConntrackMessage.DYING_MASK;
+import static com.android.net.module.util.netlink.ConntrackMessage.ESTABLISHED_MASK;
+import static com.android.net.module.util.netlink.ConntrackMessage.Tuple;
+import static com.android.net.module.util.netlink.ConntrackMessage.TupleIpv4;
+import static com.android.net.module.util.netlink.ConntrackMessage.TupleProto;
+import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_DELETE;
+import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_NEW;
+import static com.android.networkstack.tethering.BpfCoordinator.CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS;
import static com.android.networkstack.tethering.BpfCoordinator.NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED;
import static com.android.networkstack.tethering.BpfCoordinator.NF_CONNTRACK_UDP_TIMEOUT_STREAM;
-import static com.android.networkstack.tethering.BpfCoordinator.POLLING_CONNTRACK_TIMEOUT_MS;
import static com.android.networkstack.tethering.BpfCoordinator.StatsType;
import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_IFACE;
import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_UID;
@@ -82,9 +82,6 @@
import android.net.ip.ConntrackMonitor;
import android.net.ip.ConntrackMonitor.ConntrackEventConsumer;
import android.net.ip.IpServer;
-import android.net.netlink.ConntrackMessage;
-import android.net.netlink.NetlinkConstants;
-import android.net.netlink.NetlinkSocket;
import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.Build;
@@ -100,6 +97,9 @@
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.Struct;
+import com.android.net.module.util.netlink.ConntrackMessage;
+import com.android.net.module.util.netlink.NetlinkConstants;
+import com.android.net.module.util.netlink.NetlinkSocket;
import com.android.networkstack.tethering.BpfCoordinator.BpfConntrackEventConsumer;
import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
@@ -1128,6 +1128,7 @@
final String intIface1 = "wlan1";
final String intIface2 = "rndis0";
final String extIface = "rmnet_data0";
+ final String virtualIface = "ipsec0";
final BpfUtils mockMarkerBpfUtils = staticMockMarker(BpfUtils.class);
final BpfCoordinator coordinator = makeBpfCoordinator();
@@ -1163,6 +1164,14 @@
ExtendedMockito.verify(() -> BpfUtils.detachProgram(intIface1));
ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
+
+ // [6] Skip attaching if upstream is virtual interface.
+ coordinator.maybeAttachProgram(intIface1, virtualIface);
+ ExtendedMockito.verify(() -> BpfUtils.attachProgram(extIface, DOWNSTREAM), never());
+ ExtendedMockito.verify(() -> BpfUtils.attachProgram(intIface1, UPSTREAM), never());
+ ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
+ ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
+
} finally {
mockSession.finishMocking();
}
@@ -1535,14 +1544,14 @@
// Timeline:
// 0 60 (seconds)
// +---+---+---+---+--...--+---+---+---+---+---+- ..
- // | POLLING_CONNTRACK_TIMEOUT_MS |
+ // | CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS |
// +---+---+---+---+--...--+---+---+---+---+---+- ..
// |<- valid diff ->|
// |<- expired diff ->|
// ^ ^ ^
// last used time elapsed time (valid) elapsed time (expired)
- final long validTime = (POLLING_CONNTRACK_TIMEOUT_MS - 1) * 1_000_000L;
- final long expiredTime = (POLLING_CONNTRACK_TIMEOUT_MS + 1) * 1_000_000L;
+ final long validTime = (CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS - 1) * 1_000_000L;
+ final long expiredTime = (CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS + 1) * 1_000_000L;
// Static mocking for NetlinkSocket.
MockitoSession mockSession = ExtendedMockito.mockitoSession()
@@ -1556,14 +1565,14 @@
// [1] Don't refresh contrack timeout.
setElapsedRealtimeNanos(expiredTime);
- mTestLooper.moveTimeForward(POLLING_CONNTRACK_TIMEOUT_MS);
+ mTestLooper.moveTimeForward(CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS);
waitForIdle();
ExtendedMockito.verifyNoMoreInteractions(staticMockMarker(NetlinkSocket.class));
ExtendedMockito.clearInvocations(staticMockMarker(NetlinkSocket.class));
// [2] Refresh contrack timeout.
setElapsedRealtimeNanos(validTime);
- mTestLooper.moveTimeForward(POLLING_CONNTRACK_TIMEOUT_MS);
+ mTestLooper.moveTimeForward(CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS);
waitForIdle();
final byte[] expectedNetlinkTcp = ConntrackMessage.newIPv4TimeoutUpdateRequest(
IPPROTO_TCP, PRIVATE_ADDR, (int) PRIVATE_PORT, REMOTE_ADDR,
@@ -1580,7 +1589,7 @@
// [3] Don't refresh contrack timeout if polling stopped.
coordinator.stopPolling();
- mTestLooper.moveTimeForward(POLLING_CONNTRACK_TIMEOUT_MS);
+ mTestLooper.moveTimeForward(CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS);
waitForIdle();
ExtendedMockito.verifyNoMoreInteractions(staticMockMarker(NetlinkSocket.class));
ExtendedMockito.clearInvocations(staticMockMarker(NetlinkSocket.class));
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
index a8b3b92..24716b2 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
@@ -43,8 +43,6 @@
import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
import android.hardware.tetheroffload.control.V1_1.ITetheringOffloadCallback;
import android.hardware.tetheroffload.control.V1_1.OffloadCallbackEvent;
-import android.net.netlink.StructNfGenMsg;
-import android.net.netlink.StructNlMsgHdr;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.NativeHandle;
@@ -57,6 +55,9 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.net.module.util.netlink.StructNfGenMsg;
+import com.android.net.module.util.netlink.StructNlMsgHdr;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index f999dfa..f45768f 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -178,10 +178,10 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.StateMachine;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.net.module.util.CollectionUtils;
import com.android.networkstack.tethering.TestConnectivityManager.TestNetworkAgent;
import com.android.testutils.MiscAsserts;
@@ -365,7 +365,8 @@
final String[] ifaces = new String[] {
TEST_RNDIS_IFNAME, TEST_WLAN_IFNAME, TEST_WIFI_IFNAME, TEST_MOBILE_IFNAME,
TEST_DUN_IFNAME, TEST_P2P_IFNAME, TEST_NCM_IFNAME, TEST_ETH_IFNAME};
- return new InterfaceParams(ifName, ArrayUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET,
+ return new InterfaceParams(ifName,
+ CollectionUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET,
MacAddress.ALL_ZEROS_ADDRESS);
}
diff --git a/framework/api/current.txt b/framework/api/current.txt
index 715a532..13ecb12 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -68,7 +68,6 @@
method public boolean bindProcessToNetwork(@Nullable android.net.Network);
method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network getActiveNetwork();
- method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public android.net.Network getActiveNetworkForUid(int);
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 14ec608..eecd12c 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -1187,7 +1187,8 @@
*
* @return a {@link Network} object for the current default network for the
* given UID or {@code null} if no default network is currently active
- * TODO: b/183465229 Cleanup getActiveNetworkForUid once b/165835257 is fixed
+ *
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.NETWORK_STACK)
@Nullable
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index ec71d3d..5bd0af8 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -818,7 +818,7 @@
* restrictions.
* @hide
*/
- public void restrictCapabilitesForTestNetwork(int creatorUid) {
+ public void restrictCapabilitiesForTestNetwork(int creatorUid) {
final long originalCapabilities = mNetworkCapabilities;
final long originalTransportTypes = mTransportTypes;
final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
@@ -828,7 +828,7 @@
final TransportInfo originalTransportInfo = getTransportInfo();
final Set<Integer> originalSubIds = getSubscriptionIds();
clearAll();
- if (0 != (originalCapabilities & NET_CAPABILITY_NOT_RESTRICTED)) {
+ if (0 != (originalCapabilities & (1 << NET_CAPABILITY_NOT_RESTRICTED))) {
// If the test network is not restricted, then it is only allowed to declare some
// specific transports. This is to minimize impact on running apps in case an app
// run from the shell creates a test a network.
diff --git a/framework/src/android/net/util/MultinetworkPolicyTracker.java b/framework/src/android/net/util/MultinetworkPolicyTracker.java
index 9791cbf..3e7cb80 100644
--- a/framework/src/android/net/util/MultinetworkPolicyTracker.java
+++ b/framework/src/android/net/util/MultinetworkPolicyTracker.java
@@ -180,7 +180,7 @@
* The value works when the time set is more than {@link System.currentTimeMillis()}.
*/
public void setTestAllowBadWifiUntil(long timeMs) {
- Log.d(TAG, "setTestAllowBadWifiUntil: " + mTestAllowBadWifiUntilMs);
+ Log.d(TAG, "setTestAllowBadWifiUntil: " + timeMs);
mTestAllowBadWifiUntilMs = timeMs;
reevaluateInternal();
}
diff --git a/service/Android.bp b/service/Android.bp
index 7fe0e2b..911d67f 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -53,8 +53,8 @@
"src/**/*.java",
":framework-connectivity-shared-srcs",
":services-connectivity-shared-srcs",
- // TODO: move to net-utils-device-common, enable shrink optimization to avoid extra classes
- ":net-module-utils-srcs",
+ // TODO: move to net-utils-device-common
+ ":connectivity-module-utils-srcs",
],
libs: [
"framework-annotations-lib",
@@ -65,12 +65,13 @@
"ServiceConnectivityResources",
],
static_libs: [
- "dnsresolver_aidl_interface-V8-java",
+ "dnsresolver_aidl_interface-V9-java",
+ "modules-utils-build",
"modules-utils-os",
"net-utils-device-common",
+ "net-utils-device-common-netlink",
"net-utils-framework-common",
"netd-client",
- "netlink-client",
"networkstack-client",
"PlatformProperties",
"service-connectivity-protos",
diff --git a/service/ServiceConnectivityResources/res/values/config.xml b/service/ServiceConnectivityResources/res/values/config.xml
index bf32ad5..b22457a 100644
--- a/service/ServiceConnectivityResources/res/values/config.xml
+++ b/service/ServiceConnectivityResources/res/values/config.xml
@@ -114,4 +114,15 @@
<!-- Whether to cancel network notifications automatically when tapped -->
<bool name="config_autoCancelNetworkNotifications">true</bool>
+ <!-- When no internet or partial connectivity is detected on a network, and a high priority
+ (heads up) notification would be shown due to the network being explicitly selected,
+ directly show the dialog that would normally be shown when tapping the notification
+ instead of showing the notification. -->
+ <bool name="config_notifyNoInternetAsDialogWhenHighPriority">false</bool>
+
+ <!-- When showing notifications indicating partial connectivity, display the same notifications
+ as no connectivity instead. This may be easier to understand for users but offers less
+ details on what is happening. -->
+ <bool name="config_partialConnectivityNotifiedAsNoInternet">false</bool>
+
</resources>
diff --git a/service/ServiceConnectivityResources/res/values/overlayable.xml b/service/ServiceConnectivityResources/res/values/overlayable.xml
index 6ac6a0e..5af13d7 100644
--- a/service/ServiceConnectivityResources/res/values/overlayable.xml
+++ b/service/ServiceConnectivityResources/res/values/overlayable.xml
@@ -32,6 +32,8 @@
<item type="array" name="config_networkNotifySwitches"/>
<item type="bool" name="config_ongoingSignInNotification"/>
<item type="bool" name="config_autoCancelNetworkNotifications"/>
+ <item type="bool" name="config_notifyNoInternetAsDialogWhenHighPriority"/>
+ <item type="bool" name="config_partialConnectivityNotifiedAsNoInternet"/>
<item type="drawable" name="stat_notify_wifi_in_range"/>
<item type="drawable" name="stat_notify_rssi_in_range"/>
</policy>
diff --git a/service/jarjar-rules.txt b/service/jarjar-rules.txt
index 5caa11b..4ba6837 100644
--- a/service/jarjar-rules.txt
+++ b/service/jarjar-rules.txt
@@ -1,17 +1,97 @@
-rule android.sysprop.** com.android.connectivity.sysprop.@1
-rule com.android.net.module.util.** com.android.connectivity.net-utils.@1
-rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1
+rule android.sysprop.** com.android.connectivity.@0
+rule com.android.net.module.util.** com.android.connectivity.@0
+rule com.android.modules.utils.** com.android.connectivity.@0
-# internal util classes
-# Exclude AsyncChannel. TODO: remove AsyncChannel usage in ConnectivityService
-rule com.android.internal.util.AsyncChannel* @0
-# Exclude LocationPermissionChecker. This is going to be moved to libs/net
-rule com.android.internal.util.LocationPermissionChecker* @0
-rule android.util.LocalLog* com.android.connectivity.util.LocalLog@1
+# internal util classes from framework-connectivity-shared-srcs
+rule android.util.LocalLog* com.android.connectivity.@0
# android.util.IndentingPrintWriter* should use a different package name from
# the one in com.android.internal.util
-rule android.util.IndentingPrintWriter* android.connectivity.util.IndentingPrintWriter@1
-rule com.android.internal.util.** com.android.connectivity.util.@1
+rule android.util.IndentingPrintWriter* com.android.connectivity.@0
+rule com.android.internal.util.IndentingPrintWriter* com.android.connectivity.@0
+rule com.android.internal.util.IState* com.android.connectivity.@0
+rule com.android.internal.util.MessageUtils* com.android.connectivity.@0
+rule com.android.internal.util.State* com.android.connectivity.@0
+rule com.android.internal.util.StateMachine* com.android.connectivity.@0
+rule com.android.internal.util.WakeupMessage* com.android.connectivity.@0
-rule com.android.internal.messages.** com.android.connectivity.messages.@1
-rule com.google.protobuf.** com.android.connectivity.protobuf.@1
+rule com.android.internal.messages.** com.android.connectivity.@0
+rule com.google.protobuf.** com.android.connectivity.@0
+
+# From dnsresolver_aidl_interface (newer AIDLs should go to android.net.resolv.aidl)
+rule android.net.resolv.aidl.** com.android.connectivity.@0
+rule android.net.IDnsResolver* com.android.connectivity.@0
+rule android.net.ResolverHostsParcel* com.android.connectivity.@0
+rule android.net.ResolverOptionsParcel* com.android.connectivity.@0
+rule android.net.ResolverParamsParcel* com.android.connectivity.@0
+rule android.net.ResolverParamsParcel* com.android.connectivity.@0
+# Also includes netd event listener AIDL, but this is handled by netd-client rules
+
+# From net-utils-device-common
+rule android.net.NetworkFactory* com.android.connectivity.@0
+
+# From netd-client (newer AIDLs should go to android.net.netd.aidl)
+rule android.net.netd.aidl.** com.android.connectivity.@0
+# Avoid including android.net.INetdEventCallback, used in tests but not part of the module
+rule android.net.INetd com.android.connectivity.@0
+rule android.net.INetd$* com.android.connectivity.@0
+rule android.net.INetdUnsolicitedEventListener* com.android.connectivity.@0
+rule android.net.InterfaceConfigurationParcel* com.android.connectivity.@0
+rule android.net.MarkMaskParcel* com.android.connectivity.@0
+rule android.net.NativeNetworkConfig* com.android.connectivity.@0
+rule android.net.NativeNetworkType* com.android.connectivity.@0
+rule android.net.NativeVpnType* com.android.connectivity.@0
+rule android.net.RouteInfoParcel* com.android.connectivity.@0
+rule android.net.TetherConfigParcel* com.android.connectivity.@0
+rule android.net.TetherOffloadRuleParcel* com.android.connectivity.@0
+rule android.net.TetherStatsParcel* com.android.connectivity.@0
+rule android.net.UidRangeParcel* com.android.connectivity.@0
+rule android.net.metrics.INetdEventListener* com.android.connectivity.@0
+
+# From netlink-client
+rule android.net.netlink.** com.android.connectivity.@0
+
+# From networkstack-client (newer AIDLs should go to android.net.[networkstack|ipmemorystore].aidl)
+rule android.net.networkstack.aidl.** com.android.connectivity.@0
+rule android.net.ipmemorystore.aidl.** com.android.connectivity.@0
+rule android.net.ipmemorystore.aidl.** com.android.connectivity.@0
+rule android.net.DataStallReportParcelable* com.android.connectivity.@0
+rule android.net.DhcpResultsParcelable* com.android.connectivity.@0
+rule android.net.IIpMemoryStore* com.android.connectivity.@0
+rule android.net.INetworkMonitor* com.android.connectivity.@0
+rule android.net.INetworkStackConnector* com.android.connectivity.@0
+rule android.net.INetworkStackStatusCallback* com.android.connectivity.@0
+rule android.net.InformationElementParcelable* com.android.connectivity.@0
+rule android.net.InitialConfigurationParcelable* com.android.connectivity.@0
+rule android.net.IpMemoryStore* com.android.connectivity.@0
+rule android.net.Layer2InformationParcelable* com.android.connectivity.@0
+rule android.net.Layer2PacketParcelable* com.android.connectivity.@0
+rule android.net.NattKeepalivePacketDataParcelable* com.android.connectivity.@0
+rule android.net.NetworkMonitorManager* com.android.connectivity.@0
+rule android.net.NetworkTestResultParcelable* com.android.connectivity.@0
+rule android.net.PrivateDnsConfigParcel* com.android.connectivity.@0
+rule android.net.ProvisioningConfigurationParcelable* com.android.connectivity.@0
+rule android.net.ScanResultInfoParcelable* com.android.connectivity.@0
+rule android.net.TcpKeepalivePacketDataParcelable* com.android.connectivity.@0
+rule android.net.dhcp.DhcpLeaseParcelable* com.android.connectivity.@0
+rule android.net.dhcp.DhcpServingParamsParcel* com.android.connectivity.@0
+rule android.net.dhcp.IDhcpEventCallbacks* com.android.connectivity.@0
+rule android.net.dhcp.IDhcpServer* com.android.connectivity.@0
+rule android.net.ip.IIpClient* com.android.connectivity.@0
+rule android.net.ip.IpClientCallbacks* com.android.connectivity.@0
+rule android.net.ip.IpClientManager* com.android.connectivity.@0
+rule android.net.ip.IpClientUtil* com.android.connectivity.@0
+rule android.net.ipmemorystore.** com.android.connectivity.@0
+rule android.net.networkstack.** com.android.connectivity.@0
+rule android.net.shared.** com.android.connectivity.@0
+rule android.net.util.KeepalivePacketDataUtil* com.android.connectivity.@0
+
+# From connectivity-module-utils
+rule android.net.util.InterfaceParams* com.android.connectivity.@0
+rule android.net.util.SharedLog* com.android.connectivity.@0
+rule android.net.shared.** com.android.connectivity.@0
+
+# From services-connectivity-shared-srcs
+rule android.net.util.NetworkConstants* com.android.connectivity.@0
+
+# Remaining are connectivity sources in com.android.server and com.android.server.connectivity:
+# TODO: move to a subpackage of com.android.connectivity (such as com.android.connectivity.server)
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 50fb2cf..47bde72 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -179,7 +179,6 @@
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.netd.aidl.NativeUidRangeConfig;
-import android.net.netlink.InetDiagMessage;
import android.net.networkstack.ModuleNetworkStackClient;
import android.net.networkstack.NetworkStackClientBase;
import android.net.resolv.aidl.DnsHealthEventParcel;
@@ -235,6 +234,7 @@
import com.android.net.module.util.LocationPermissionChecker;
import com.android.net.module.util.NetworkCapabilitiesUtils;
import com.android.net.module.util.PermissionUtils;
+import com.android.net.module.util.netlink.InetDiagMessage;
import com.android.server.connectivity.AutodestructReference;
import com.android.server.connectivity.DnsManager;
import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
@@ -324,7 +324,8 @@
private static final int DEFAULT_NASCENT_DELAY_MS = 5_000;
// The maximum number of network request allowed per uid before an exception is thrown.
- private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
+ @VisibleForTesting
+ static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
// The maximum number of network request allowed for system UIDs before an exception is thrown.
@VisibleForTesting
@@ -344,7 +345,8 @@
@VisibleForTesting
protected final PermissionMonitor mPermissionMonitor;
- private final PerUidCounter mNetworkRequestCounter;
+ @VisibleForTesting
+ final PerUidCounter mNetworkRequestCounter;
@VisibleForTesting
final PerUidCounter mSystemNetworkRequestCounter;
@@ -403,44 +405,44 @@
/**
* For per-app preferences, requests contain an int to signify which request
- * should have priority. The priority is passed to netd which will use it
- * together with UID ranges to generate the corresponding IP rule. This serves
- * to direct device-originated data traffic of the specific UIDs to the correct
+ * should have priority. The order is passed to netd which will use it together
+ * with UID ranges to generate the corresponding IP rule. This serves to
+ * direct device-originated data traffic of the specific UIDs to the correct
* default network for each app.
- * Priorities passed to netd must be in the 0~999 range. Larger values code for
+ * Order ints passed to netd must be in the 0~999 range. Larger values code for
* a lower priority, {@see NativeUidRangeConfig}
*
- * Requests that don't code for a per-app preference use PREFERENCE_PRIORITY_INVALID.
- * The default request uses PREFERENCE_PRIORITY_DEFAULT.
+ * Requests that don't code for a per-app preference use PREFERENCE_ORDER_INVALID.
+ * The default request uses PREFERENCE_ORDER_DEFAULT.
*/
- // Bound for the lowest valid priority.
- static final int PREFERENCE_PRIORITY_LOWEST = 999;
- // Used when sending to netd to code for "no priority".
- static final int PREFERENCE_PRIORITY_NONE = 0;
- // Priority for requests that don't code for a per-app preference. As it is
- // out of the valid range, the corresponding priority should be
- // PREFERENCE_PRIORITY_NONE when sending to netd.
+ // Bound for the lowest valid preference order.
+ static final int PREFERENCE_ORDER_LOWEST = 999;
+ // Used when sending to netd to code for "no order".
+ static final int PREFERENCE_ORDER_NONE = 0;
+ // Order for requests that don't code for a per-app preference. As it is
+ // out of the valid range, the corresponding order should be
+ // PREFERENCE_ORDER_NONE when sending to netd.
@VisibleForTesting
- static final int PREFERENCE_PRIORITY_INVALID = Integer.MAX_VALUE;
- // Priority for the default internet request. Since this must always have the
+ static final int PREFERENCE_ORDER_INVALID = Integer.MAX_VALUE;
+ // Order for the default internet request. Since this must always have the
// lowest priority, its value is larger than the largest acceptable value. As
- // it is out of the valid range, the corresponding priority should be
- // PREFERENCE_PRIORITY_NONE when sending to netd.
- static final int PREFERENCE_PRIORITY_DEFAULT = 1000;
+ // it is out of the valid range, the corresponding order should be
+ // PREFERENCE_ORDER_NONE when sending to netd.
+ static final int PREFERENCE_ORDER_DEFAULT = 1000;
// As a security feature, VPNs have the top priority.
- static final int PREFERENCE_PRIORITY_VPN = 1;
- // Priority of per-app OEM preference. See {@link #setOemNetworkPreference}.
+ static final int PREFERENCE_ORDER_VPN = 0; // Netd supports only 0 for VPN.
+ // Order of per-app OEM preference. See {@link #setOemNetworkPreference}.
@VisibleForTesting
- static final int PREFERENCE_PRIORITY_OEM = 10;
- // Priority of per-profile preference, such as used by enterprise networks.
+ static final int PREFERENCE_ORDER_OEM = 10;
+ // Order of per-profile preference, such as used by enterprise networks.
// See {@link #setProfileNetworkPreference}.
@VisibleForTesting
- static final int PREFERENCE_PRIORITY_PROFILE = 20;
- // Priority of user setting to prefer mobile data even when networks with
+ static final int PREFERENCE_ORDER_PROFILE = 20;
+ // Order of user setting to prefer mobile data even when networks with
// better scores are connected.
// See {@link ConnectivitySettingsManager#setMobileDataPreferredUids}
@VisibleForTesting
- static final int PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED = 30;
+ static final int PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED = 30;
/**
* used internally to clear a wakelock when transitioning
@@ -1154,9 +1156,20 @@
private void incrementCountOrThrow(final int uid, final int numToIncrement) {
final int newRequestCount =
mUidToNetworkRequestCount.get(uid, 0) + numToIncrement;
- if (newRequestCount >= mMaxCountPerUid) {
+ if (newRequestCount >= mMaxCountPerUid
+ // HACK : the system server is allowed to go over the request count limit
+ // when it is creating requests on behalf of another app (but not itself,
+ // so it can still detect its own request leaks). This only happens in the
+ // per-app API flows in which case the old requests for that particular
+ // UID will be removed soon.
+ // TODO : instead of this hack, addPerAppDefaultNetworkRequests and other
+ // users of transact() should unregister the requests to decrease the count
+ // before they increase it again by creating a new NRI. Then remove the
+ // transact() method.
+ && (Process.myUid() == uid || Process.myUid() != Binder.getCallingUid())) {
throw new ServiceSpecificException(
- ConnectivityManager.Errors.TOO_MANY_REQUESTS);
+ ConnectivityManager.Errors.TOO_MANY_REQUESTS,
+ "Uid " + uid + " exceeded its allotted requests limit");
}
mUidToNetworkRequestCount.put(uid, newRequestCount);
}
@@ -3162,7 +3175,18 @@
}
private void dumpNetworkRequests(IndentingPrintWriter pw) {
- for (NetworkRequestInfo nri : requestsSortedById()) {
+ NetworkRequestInfo[] infos = null;
+ while (infos == null) {
+ try {
+ infos = requestsSortedById();
+ } catch (ConcurrentModificationException e) {
+ // mNetworkRequests should only be accessed from handler thread, except dump().
+ // As dump() is never called in normal usage, it would be needlessly expensive
+ // to lock the collection only for its benefit. Instead, retry getting the
+ // requests if ConcurrentModificationException is thrown during dump().
+ }
+ }
+ for (NetworkRequestInfo nri : infos) {
pw.println(nri.toString());
}
}
@@ -3231,7 +3255,7 @@
// the Messenger, but if this ever changes, not making a defensive copy
// here will give attack vectors to clients using this code path.
networkCapabilities = new NetworkCapabilities(networkCapabilities);
- networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid);
+ networkCapabilities.restrictCapabilitiesForTestNetwork(nai.creatorUid);
}
processCapabilitiesFromAgent(nai, networkCapabilities);
updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
@@ -4245,7 +4269,7 @@
mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
satisfier.network.getNetId(),
toUidRangeStableParcels(nri.getUids()),
- nri.getPriorityForNetd()));
+ nri.getPreferenceOrderForNetd()));
} catch (RemoteException e) {
loge("Exception setting network preference default network", e);
}
@@ -5083,10 +5107,8 @@
private void handleReportNetworkConnectivity(
@Nullable NetworkAgentInfo nai, int uid, boolean hasConnectivity) {
- // TODO(b/192611346): remove NetworkInfo.State.DISCONNECTING as it's not used
if (nai == null
|| nai != getNetworkAgentInfoForNetwork(nai.network)
- || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING
|| nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
return;
}
@@ -5714,8 +5736,8 @@
// maximum limit of registered callbacks per UID.
final int mAsUid;
- // Default network priority of this request.
- final int mPreferencePriority;
+ // Preference order of this request.
+ final int mPreferenceOrder;
// In order to preserve the mapping of NetworkRequest-to-callback when apps register
// callbacks using a returned NetworkRequest, the original NetworkRequest needs to be
@@ -5747,12 +5769,12 @@
NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r,
@Nullable final PendingIntent pi, @Nullable String callingAttributionTag) {
this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag,
- PREFERENCE_PRIORITY_INVALID);
+ PREFERENCE_ORDER_INVALID);
}
NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
@NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi,
- @Nullable String callingAttributionTag, final int preferencePriority) {
+ @Nullable String callingAttributionTag, final int preferenceOrder) {
ensureAllNetworkRequestsHaveType(r);
mRequests = initializeRequests(r);
mNetworkRequestForCallback = requestForCallback;
@@ -5770,7 +5792,7 @@
*/
mCallbackFlags = NetworkCallback.FLAG_NONE;
mCallingAttributionTag = callingAttributionTag;
- mPreferencePriority = preferencePriority;
+ mPreferenceOrder = preferenceOrder;
}
NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m,
@@ -5800,7 +5822,7 @@
mPerUidCounter.incrementCountOrThrow(mUid);
mCallbackFlags = callbackFlags;
mCallingAttributionTag = callingAttributionTag;
- mPreferencePriority = PREFERENCE_PRIORITY_INVALID;
+ mPreferenceOrder = PREFERENCE_ORDER_INVALID;
linkDeathRecipient();
}
@@ -5836,22 +5858,22 @@
mUid = nri.mUid;
mAsUid = nri.mAsUid;
mPendingIntent = nri.mPendingIntent;
- mPerUidCounter = getRequestCounter(this);
+ mPerUidCounter = nri.mPerUidCounter;
mPerUidCounter.incrementCountOrThrow(mUid);
mCallbackFlags = nri.mCallbackFlags;
mCallingAttributionTag = nri.mCallingAttributionTag;
- mPreferencePriority = PREFERENCE_PRIORITY_INVALID;
+ mPreferenceOrder = PREFERENCE_ORDER_INVALID;
linkDeathRecipient();
}
NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) {
- this(asUid, Collections.singletonList(r), PREFERENCE_PRIORITY_INVALID);
+ this(asUid, Collections.singletonList(r), PREFERENCE_ORDER_INVALID);
}
NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
- final int preferencePriority) {
+ final int preferenceOrder) {
this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */,
- preferencePriority);
+ preferenceOrder);
}
// True if this NRI is being satisfied. It also accounts for if the nri has its satisifer
@@ -5892,24 +5914,30 @@
}
}
- boolean hasHigherPriorityThan(@NonNull final NetworkRequestInfo target) {
- // Compare two priorities, larger value means lower priority.
- return mPreferencePriority < target.mPreferencePriority;
+ boolean hasHigherOrderThan(@NonNull final NetworkRequestInfo target) {
+ // Compare two preference orders.
+ return mPreferenceOrder < target.mPreferenceOrder;
}
- int getPriorityForNetd() {
- if (mPreferencePriority >= PREFERENCE_PRIORITY_NONE
- && mPreferencePriority <= PREFERENCE_PRIORITY_LOWEST) {
- return mPreferencePriority;
+ int getPreferenceOrderForNetd() {
+ if (mPreferenceOrder >= PREFERENCE_ORDER_NONE
+ && mPreferenceOrder <= PREFERENCE_ORDER_LOWEST) {
+ return mPreferenceOrder;
}
- return PREFERENCE_PRIORITY_NONE;
+ return PREFERENCE_ORDER_NONE;
}
@Override
public void binderDied() {
log("ConnectivityService NetworkRequestInfo binderDied(" +
"uid/pid:" + mUid + "/" + mPid + ", " + mBinder + ")");
- mHandler.post(() -> handleRemoveNetworkRequest(this));
+ // As an immutable collection, mRequests cannot change by the time the
+ // lambda is evaluated on the handler thread so calling .get() from a binder thread
+ // is acceptable. Use handleReleaseNetworkRequest and not directly
+ // handleRemoveNetworkRequest so as to force a lookup in the requests map, in case
+ // the app already unregistered the request.
+ mHandler.post(() -> handleReleaseNetworkRequest(mRequests.get(0),
+ mUid, false /* callOnUnavailable */));
}
@Override
@@ -5922,7 +5950,7 @@
+ " " + mRequests
+ (mPendingIntent == null ? "" : " to trigger " + mPendingIntent)
+ " callback flags: " + mCallbackFlags
- + " priority: " + mPreferencePriority;
+ + " order: " + mPreferenceOrder;
}
}
@@ -6514,7 +6542,7 @@
// than one request and for multilayer, all requests will track the same uids.
if (nri.mRequests.get(0).networkCapabilities.appliesToUid(uid)) {
// Find out the highest priority request.
- if (nri.hasHigherPriorityThan(highestPriorityNri)) {
+ if (nri.hasHigherOrderThan(highestPriorityNri)) {
highestPriorityNri = nri;
}
}
@@ -6659,7 +6687,7 @@
}
for (final UidRange range : uids) {
if (range.contains(uid)) {
- if (nri.hasHigherPriorityThan(highestPriorityNri)) {
+ if (nri.hasHigherOrderThan(highestPriorityNri)) {
highestPriorityNri = nri;
}
}
@@ -6736,7 +6764,7 @@
// the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
// sees capabilities that may be malicious, which might prevent mistakes in the future.
networkCapabilities = new NetworkCapabilities(networkCapabilities);
- networkCapabilities.restrictCapabilitesForTestNetwork(uid);
+ networkCapabilities.restrictCapabilitiesForTestNetwork(uid);
}
LinkProperties lp = new LinkProperties(linkProperties);
@@ -7524,10 +7552,10 @@
try {
if (add) {
mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(
- nai.network.netId, ranges, PREFERENCE_PRIORITY_VPN));
+ nai.network.netId, ranges, PREFERENCE_ORDER_VPN));
} else {
mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
- nai.network.netId, ranges, PREFERENCE_PRIORITY_VPN));
+ nai.network.netId, ranges, PREFERENCE_ORDER_VPN));
}
} catch (Exception e) {
loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges +
@@ -7872,13 +7900,13 @@
mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(
newDefaultNetwork.network.getNetId(),
toUidRangeStableParcels(nri.getUids()),
- nri.getPriorityForNetd()));
+ nri.getPreferenceOrderForNetd()));
}
if (null != oldDefaultNetwork) {
mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
oldDefaultNetwork.network.getNetId(),
toUidRangeStableParcels(nri.getUids()),
- nri.getPriorityForNetd()));
+ nri.getPreferenceOrderForNetd()));
}
} catch (RemoteException | ServiceSpecificException e) {
loge("Exception setting app default network", e);
@@ -9985,7 +10013,7 @@
TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs,
- PREFERENCE_PRIORITY_PROFILE);
+ PREFERENCE_ORDER_PROFILE);
result.add(nri);
}
return result;
@@ -10002,7 +10030,7 @@
() -> {
final ArraySet<NetworkRequestInfo> nris =
createNrisFromProfileNetworkPreferences(mProfileNetworkPreferences);
- replaceDefaultNetworkRequestsForPreference(nris, PREFERENCE_PRIORITY_PROFILE);
+ replaceDefaultNetworkRequestsForPreference(nris, PREFERENCE_ORDER_PROFILE);
});
// Finally, rematch.
rematchAllNetworksAndRequests();
@@ -10042,7 +10070,7 @@
}
setNetworkRequestUids(requests, ranges);
nris.add(new NetworkRequestInfo(Process.myUid(), requests,
- PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED));
+ PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED));
return nris;
}
@@ -10054,7 +10082,7 @@
final ArraySet<NetworkRequestInfo> nris =
createNrisFromMobileDataPreferredUids(mMobileDataPreferredUids);
replaceDefaultNetworkRequestsForPreference(nris,
- PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED);
+ PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
});
// Finally, rematch.
rematchAllNetworksAndRequests();
@@ -10152,7 +10180,7 @@
final ArraySet<NetworkRequestInfo> nris =
new OemNetworkRequestFactory()
.createNrisFromOemNetworkPreferences(preference);
- replaceDefaultNetworkRequestsForPreference(nris, PREFERENCE_PRIORITY_OEM);
+ replaceDefaultNetworkRequestsForPreference(nris, PREFERENCE_ORDER_OEM);
});
mOemNetworkPreferences = preference;
@@ -10166,11 +10194,11 @@
}
private void replaceDefaultNetworkRequestsForPreference(
- @NonNull final Set<NetworkRequestInfo> nris, final int preferencePriority) {
+ @NonNull final Set<NetworkRequestInfo> nris, final int preferenceOrder) {
// Skip the requests which are set by other network preference. Because the uid range rules
// should stay in netd.
final Set<NetworkRequestInfo> requests = new ArraySet<>(mDefaultNetworkRequests);
- requests.removeIf(request -> request.mPreferencePriority != preferencePriority);
+ requests.removeIf(request -> request.mPreferenceOrder != preferenceOrder);
handleRemoveNetworkRequests(requests);
addPerAppDefaultNetworkRequests(nris);
}
@@ -10240,7 +10268,7 @@
final NetworkRequestInfo trackingNri =
getDefaultRequestTrackingUid(callbackRequest.mAsUid);
- // If this nri is not being tracked, the change it back to an untracked nri.
+ // If this nri is not being tracked, then change it back to an untracked nri.
if (trackingNri == mDefaultRequest) {
callbackRequestsToRegister.add(new NetworkRequestInfo(
callbackRequest,
@@ -10365,7 +10393,7 @@
ranges.add(new UidRange(uid, uid));
}
setNetworkRequestUids(requests, ranges);
- return new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_PRIORITY_OEM);
+ return new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_OEM);
}
private NetworkRequest createUnmeteredNetworkRequest() {
diff --git a/service/src/com/android/server/connectivity/DnsManager.java b/service/src/com/android/server/connectivity/DnsManager.java
index 05b12ba..1493cae 100644
--- a/service/src/com/android/server/connectivity/DnsManager.java
+++ b/service/src/com/android/server/connectivity/DnsManager.java
@@ -38,7 +38,6 @@
import android.net.InetAddresses;
import android.net.LinkProperties;
import android.net.Network;
-import android.net.ResolverOptionsParcel;
import android.net.ResolverParamsParcel;
import android.net.Uri;
import android.net.shared.PrivateDnsConfig;
@@ -384,7 +383,6 @@
.collect(Collectors.toList()))
: useTls ? paramsParcel.servers // Opportunistic
: new String[0]; // Off
- paramsParcel.resolverOptions = new ResolverOptionsParcel();
paramsParcel.transportTypes = transportTypes;
// Prepare to track the validation status of the DNS servers in the
// resolver config when private DNS is in opportunistic or strict mode.
diff --git a/service/src/com/android/server/connectivity/NetworkNotificationManager.java b/service/src/com/android/server/connectivity/NetworkNotificationManager.java
index ae98d92..155f6c4 100644
--- a/service/src/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/service/src/com/android/server/connectivity/NetworkNotificationManager.java
@@ -198,11 +198,22 @@
}
final Resources r = mResources.get();
+ if (highPriority && maybeNotifyViaDialog(r, notifyType, intent)) {
+ Log.d(TAG, "Notified via dialog for event " + nameOf(eventId));
+ return;
+ }
+
final CharSequence title;
final CharSequence details;
Icon icon = Icon.createWithResource(
mResources.getResourcesContext(), getIcon(transportType));
- if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
+ final boolean showAsNoInternet = notifyType == NotificationType.PARTIAL_CONNECTIVITY
+ && r.getBoolean(R.bool.config_partialConnectivityNotifiedAsNoInternet);
+ if (showAsNoInternet) {
+ Log.d(TAG, "Showing partial connectivity as NO_INTERNET");
+ }
+ if ((notifyType == NotificationType.NO_INTERNET || showAsNoInternet)
+ && transportType == TRANSPORT_WIFI) {
title = r.getString(R.string.wifi_no_internet, name);
details = r.getString(R.string.wifi_no_internet_detailed);
} else if (notifyType == NotificationType.PRIVATE_DNS_BROKEN) {
@@ -306,6 +317,24 @@
}
}
+ private boolean maybeNotifyViaDialog(Resources res, NotificationType notifyType,
+ PendingIntent intent) {
+ if (notifyType != NotificationType.NO_INTERNET
+ && notifyType != NotificationType.PARTIAL_CONNECTIVITY) {
+ return false;
+ }
+ if (!res.getBoolean(R.bool.config_notifyNoInternetAsDialogWhenHighPriority)) {
+ return false;
+ }
+
+ try {
+ intent.send();
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG, "Error sending dialog PendingIntent", e);
+ }
+ return true;
+ }
+
/**
* Clear the notification with the given id, only if it matches the given type.
*/
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index 512d767..7c0fb91 100755
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -25,6 +25,12 @@
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.net.ConnectivitySettingsManager.UIDS_ALLOWED_ON_RESTRICTED_NETWORKS;
+import static android.net.INetd.PERMISSION_INTERNET;
+import static android.net.INetd.PERMISSION_NETWORK;
+import static android.net.INetd.PERMISSION_NONE;
+import static android.net.INetd.PERMISSION_SYSTEM;
+import static android.net.INetd.PERMISSION_UNINSTALLED;
+import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID;
@@ -153,7 +159,7 @@
* Get device first sdk version.
*/
public int getDeviceFirstSdkInt() {
- return Build.VERSION.FIRST_SDK_INT;
+ return Build.VERSION.DEVICE_INITIAL_SDK_INT;
}
/**
@@ -261,8 +267,8 @@
mUsers.addAll(mUserManager.getUserHandles(true /* excludeDying */));
final SparseArray<String> netdPermToSystemPerm = new SparseArray<>();
- netdPermToSystemPerm.put(INetd.PERMISSION_INTERNET, INTERNET);
- netdPermToSystemPerm.put(INetd.PERMISSION_UPDATE_DEVICE_STATS, UPDATE_DEVICE_STATS);
+ netdPermToSystemPerm.put(PERMISSION_INTERNET, INTERNET);
+ netdPermToSystemPerm.put(PERMISSION_UPDATE_DEVICE_STATS, UPDATE_DEVICE_STATS);
for (int i = 0; i < netdPermToSystemPerm.size(); i++) {
final int netdPermission = netdPermToSystemPerm.keyAt(i);
final String systemPermission = netdPermToSystemPerm.valueAt(i);
@@ -281,7 +287,14 @@
@VisibleForTesting
synchronized void updateUidsAllowedOnRestrictedNetworks(final Set<Integer> uids) {
mUidsAllowedOnRestrictedNetworks.clear();
- mUidsAllowedOnRestrictedNetworks.addAll(uids);
+ // This is necessary for the app id to match in isUidAllowedOnRestrictedNetworks, and will
+ // grant the permission to all uids associated with the app ID. This is safe even if the app
+ // is only installed on some users because the uid cannot match some other app – this uid is
+ // in effect not installed and can't be run.
+ // TODO (b/192431153): Change appIds back to uids.
+ for (int uid : uids) {
+ mUidsAllowedOnRestrictedNetworks.add(UserHandle.getAppId(uid));
+ }
}
@VisibleForTesting
@@ -303,7 +316,7 @@
if (appInfo == null) return false;
// Check whether package's uid is in allowed on restricted networks uid list. If so, this
// uid can have netd system permission.
- return mUidsAllowedOnRestrictedNetworks.contains(appInfo.uid);
+ return mUidsAllowedOnRestrictedNetworks.contains(UserHandle.getAppId(appInfo.uid));
}
@VisibleForTesting
@@ -362,8 +375,8 @@
}
try {
if (add) {
- mNetd.networkSetPermissionForUser(INetd.PERMISSION_NETWORK, toIntArray(network));
- mNetd.networkSetPermissionForUser(INetd.PERMISSION_SYSTEM, toIntArray(system));
+ mNetd.networkSetPermissionForUser(PERMISSION_NETWORK, toIntArray(network));
+ mNetd.networkSetPermissionForUser(PERMISSION_SYSTEM, toIntArray(system));
} else {
mNetd.networkClearPermissionForUser(toIntArray(network));
mNetd.networkClearPermissionForUser(toIntArray(system));
@@ -432,7 +445,7 @@
}
private int getPermissionForUid(final int uid) {
- int permission = INetd.PERMISSION_NONE;
+ int permission = PERMISSION_NONE;
// Check all the packages for this UID. The UID has the permission if any of the
// packages in it has the permission.
final String[] packages = mPackageManager.getPackagesForUid(uid);
@@ -446,7 +459,7 @@
}
} else {
// The last package of this uid is removed from device. Clean the package up.
- permission = INetd.PERMISSION_UNINSTALLED;
+ permission = PERMISSION_UNINSTALLED;
}
return permission;
}
@@ -566,11 +579,11 @@
for (int i = 0; i < requestedPermissions.length; i++) {
if (requestedPermissions[i].equals(INTERNET)
&& ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
- permissions |= INetd.PERMISSION_INTERNET;
+ permissions |= PERMISSION_INTERNET;
}
if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS)
&& ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
- permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
+ permissions |= PERMISSION_UPDATE_DEVICE_STATS;
}
}
return permissions;
@@ -743,19 +756,19 @@
for (int i = 0; i < netdPermissionsAppIds.size(); i++) {
int permissions = netdPermissionsAppIds.valueAt(i);
switch(permissions) {
- case (INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS):
+ case (PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS):
allPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
break;
- case INetd.PERMISSION_INTERNET:
+ case PERMISSION_INTERNET:
internetPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
break;
- case INetd.PERMISSION_UPDATE_DEVICE_STATS:
+ case PERMISSION_UPDATE_DEVICE_STATS:
updateStatsPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
break;
- case INetd.PERMISSION_NONE:
+ case PERMISSION_NONE:
noPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
break;
- case INetd.PERMISSION_UNINSTALLED:
+ case PERMISSION_UNINSTALLED:
uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i));
break;
default:
@@ -767,23 +780,22 @@
// TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids()
if (allPermissionAppIds.size() != 0) {
mNetd.trafficSetNetPermForUids(
- INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
+ PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS,
toIntArray(allPermissionAppIds));
}
if (internetPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(INetd.PERMISSION_INTERNET,
+ mNetd.trafficSetNetPermForUids(PERMISSION_INTERNET,
toIntArray(internetPermissionAppIds));
}
if (updateStatsPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UPDATE_DEVICE_STATS,
+ mNetd.trafficSetNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS,
toIntArray(updateStatsPermissionAppIds));
}
if (noPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(INetd.PERMISSION_NONE,
- toIntArray(noPermissionAppIds));
+ mNetd.trafficSetNetPermForUids(PERMISSION_NONE, toIntArray(noPermissionAppIds));
}
if (uninstalledAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UNINSTALLED,
+ mNetd.trafficSetNetPermForUids(PERMISSION_UNINSTALLED,
toIntArray(uninstalledAppIds));
}
} catch (RemoteException e) {
diff --git a/tests/common/java/android/net/NetworkCapabilitiesTest.java b/tests/common/java/android/net/NetworkCapabilitiesTest.java
index a30d4f1..3d0cb92 100644
--- a/tests/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/common/java/android/net/NetworkCapabilitiesTest.java
@@ -42,6 +42,7 @@
import static android.net.NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
+import static android.net.NetworkCapabilities.TRANSPORT_USB;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
@@ -973,6 +974,11 @@
assertNotEquals(512, nc.getLinkUpstreamBandwidthKbps());
}
+ private int getMaxTransport() {
+ if (!isAtLeastS() && MAX_TRANSPORT == TRANSPORT_USB) return MAX_TRANSPORT - 1;
+ return MAX_TRANSPORT;
+ }
+
@Test
public void testSignalStrength() {
final NetworkCapabilities nc = new NetworkCapabilities();
@@ -984,7 +990,7 @@
}
private void assertNoTransport(NetworkCapabilities nc) {
- for (int i = MIN_TRANSPORT; i <= MAX_TRANSPORT; i++) {
+ for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) {
assertFalse(nc.hasTransport(i));
}
}
@@ -1001,7 +1007,7 @@
assertFalse(nc.hasTransport(i));
}
}
- for (int i = MAX_TRANSPORT; i > maxTransportType; i--) {
+ for (int i = getMaxTransport(); i > maxTransportType; i--) {
if (positiveSequence) {
assertFalse(nc.hasTransport(i));
} else {
@@ -1015,12 +1021,12 @@
final NetworkCapabilities nc = new NetworkCapabilities();
assertNoTransport(nc);
// Test adding multiple transport types.
- for (int i = MIN_TRANSPORT; i <= MAX_TRANSPORT; i++) {
+ for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) {
nc.addTransportType(i);
checkCurrentTransportTypes(nc, i, true /* positiveSequence */);
}
// Test removing multiple transport types.
- for (int i = MIN_TRANSPORT; i <= MAX_TRANSPORT; i++) {
+ for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) {
nc.removeTransportType(i);
checkCurrentTransportTypes(nc, i, false /* positiveSequence */);
}
@@ -1161,4 +1167,48 @@
// Ensure test case fails if new net cap is added into default cap but no update here.
assertEquals(0, nc.getCapabilities().length);
}
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testRestrictCapabilitiesForTestNetwork() {
+ final int ownerUid = 1234;
+ final int[] administratorUids = {1001, ownerUid};
+ final NetworkCapabilities nonRestrictedNc = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .addTransportType(TRANSPORT_VPN)
+ .addCapability(NET_CAPABILITY_MMS)
+ .addCapability(NET_CAPABILITY_NOT_METERED)
+ .setAdministratorUids(administratorUids)
+ .setOwnerUid(ownerUid)
+ .setSubscriptionIds(Set.of(TEST_SUBID1)).build();
+
+ nonRestrictedNc.restrictCapabilitiesForTestNetwork(ownerUid);
+ // TRANSPORT_TEST will be appended
+ assertTrue(nonRestrictedNc.hasTransport(TRANSPORT_TEST));
+ assertEquals(Set.of(TEST_SUBID1), nonRestrictedNc.getSubscriptionIds());
+ // Non-UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS will be removed
+ assertFalse(nonRestrictedNc.hasTransport(TRANSPORT_CELLULAR));
+ assertTrue(nonRestrictedNc.hasTransport(TRANSPORT_VPN));
+ // Only TEST_NETWORKS_ALLOWED_CAPABILITIES will be kept
+ assertFalse(nonRestrictedNc.hasCapability(NET_CAPABILITY_MMS));
+ assertTrue(nonRestrictedNc.hasCapability(NET_CAPABILITY_NOT_METERED));
+
+ final NetworkCapabilities restrictedNc = new NetworkCapabilities.Builder(nonRestrictedNc)
+ .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ .addTransportType(TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_MMS).build();
+ restrictedNc.restrictCapabilitiesForTestNetwork(ownerUid);
+ // It may declare any transport if the net cap is restricted
+ assertTrue(restrictedNc.hasTransport(TRANSPORT_CELLULAR));
+ // SubIds will be cleared.
+ assertEquals(new ArraySet<>(), restrictedNc.getSubscriptionIds());
+ // Only retain the owner and administrator UIDs if they match the app registering the remote
+ // caller that registered the network.
+ assertEquals(ownerUid, restrictedNc.getOwnerUid());
+ assertArrayEquals(new int[] {ownerUid}, restrictedNc.getAdministratorUids());
+ // The creator UID does not match the owner and administrator UIDs will clear the owner and
+ // administrator UIDs.
+ restrictedNc.restrictCapabilitiesForTestNetwork(5678);
+ assertEquals(INVALID_UID, restrictedNc.getOwnerUid());
+ assertArrayEquals(new int[0], restrictedNc.getAdministratorUids());
+ }
}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
index 62aa493..215f129 100755
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -1213,7 +1213,8 @@
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
// Enqueue a request and check only one download.
- final long id = dm.enqueue(new Request(Uri.parse("https://www.google.com")));
+ final long id = dm.enqueue(new Request(
+ Uri.parse("https://google-ipv6test.appspot.com/ip.js?fmt=text")));
assertEquals(1, getTotalNumberDownloads(dm, new Query()));
assertEquals(1, getTotalNumberDownloads(dm, new Query().setFilterById(id)));
diff --git a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java
index cdb66e3..8d68c5f 100644
--- a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java
+++ b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java
@@ -57,7 +57,8 @@
/**
* Tests reporting of connectivity changed.
*/
- public void testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent() {
+ public void testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent()
+ throws Exception {
if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
Log.i(TAG, "testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent cannot execute unless device supports WiFi");
return;
@@ -75,7 +76,7 @@
}
public void testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent()
- throws InterruptedException {
+ throws Exception {
if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot"
+ "execute unless device supports WiFi");
@@ -94,7 +95,7 @@
getConnectivityCount, SEND_BROADCAST_TIMEOUT));
}
- public void testConnectivityChanged_whenRegistered_shouldReceiveIntent() {
+ public void testConnectivityChanged_whenRegistered_shouldReceiveIntent() throws Exception {
if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
Log.i(TAG, "testConnectivityChanged_whenRegistered_shouldReceiveIntent cannot execute unless device supports WiFi");
return;
diff --git a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
index 86642ea..4d60279 100644
--- a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
@@ -38,6 +38,7 @@
import android.platform.test.annotations.AppModeFull;
import android.util.Log;
+import androidx.test.filters.SdkSuppress;
import androidx.test.runner.AndroidJUnit4;
import com.android.testutils.DevSdkIgnoreRule;
@@ -58,6 +59,7 @@
* Test for BatteryStatsManager.
*/
@RunWith(AndroidJUnit4.class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.R) // BatteryStatsManager did not exist on Q
public class BatteryStatsManagerTest{
@Rule
public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
@@ -85,21 +87,36 @@
@SkipPresubmit(reason = "Virtual hardware does not support wifi battery stats")
public void testReportNetworkInterfaceForTransports() throws Exception {
try {
- final Network cellNetwork = mCtsNetUtils.connectToCell();
- final URL url = new URL(TEST_URL);
+ // Simulate the device being unplugged from charging.
+ executeShellCommand("cmd battery unplug");
+ executeShellCommand("cmd battery set status " + BATTERY_STATUS_DISCHARGING);
+ // Reset all current stats before starting test.
+ executeShellCommand("dumpsys batterystats --reset");
+ // Do not automatically reset the stats when the devices are unplugging after the
+ // battery was last full or the level is 100, or have gone through a significant
+ // charge.
+ executeShellCommand("dumpsys batterystats enable no-auto-reset");
+ // Upon calling "cmd battery unplug" a task is scheduled on the battery
+ // stats worker thread. Because network battery stats are only recorded
+ // when the device is on battery, this test needs to wait until the
+ // battery status is recorded because causing traffic.
+ // Writing stats to disk is unnecessary, but --write waits for the worker
+ // thread to finish processing the enqueued tasks as a side effect. This
+ // side effect is the point of using --write here.
+ executeShellCommand("dumpsys batterystats --write");
// Make sure wifi is disabled.
mCtsNetUtils.ensureWifiDisconnected(null /* wifiNetworkToCheck */);
- // Simulate the device being unplugged from charging.
- executeShellCommand("dumpsys battery unplug");
- executeShellCommand("dumpsys battery set status " + BATTERY_STATUS_DISCHARGING);
- executeShellCommand("dumpsys batterystats enable pretend-screen-off");
+
+ final Network cellNetwork = mCtsNetUtils.connectToCell();
+ final URL url = new URL(TEST_URL);
// Get cellular battery stats
CellularBatteryStats cellularStatsBefore = runAsShell(UPDATE_DEVICE_STATS,
mBsm::getCellularBatteryStats);
// Generate traffic on cellular network.
+ Log.d(TAG, "Generate traffic on cellular network.");
generateNetworkTraffic(cellNetwork, url);
// The mobile battery stats are updated when a network stops being the default network.
@@ -117,6 +134,7 @@
mBsm::getWifiBatteryStats);
// Generate traffic on wifi network.
+ Log.d(TAG, "Generate traffic on wifi network.");
generateNetworkTraffic(wifiNetwork, url);
// Wifi battery stats are updated when wifi on.
mCtsNetUtils.toggleWifi();
@@ -128,8 +146,8 @@
wifiStatsAfter)));
} finally {
// Reset battery settings.
- executeShellCommand("dumpsys battery reset");
- executeShellCommand("dumpsys batterystats disable pretend-screen-off");
+ executeShellCommand("dumpsys batterystats disable no-auto-reset");
+ executeShellCommand("cmd battery reset");
}
}
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index e45aa98..65dffbd 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -159,6 +159,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.ArrayUtils;
+import com.android.modules.utils.build.SdkLevel;
import com.android.networkstack.apishim.ConnectivityManagerShimImpl;
import com.android.networkstack.apishim.ConstantsShim;
import com.android.networkstack.apishim.NetworkInformationShimImpl;
@@ -281,7 +282,8 @@
private final ArraySet<Integer> mNetworkTypes = new ArraySet<>();
private UiAutomation mUiAutomation;
private CtsNetUtils mCtsNetUtils;
-
+ // The registered callbacks.
+ private List<NetworkCallback> mRegisteredCallbacks = new ArrayList<>();
// Used for cleanup purposes.
private final List<Range<Integer>> mVpnRequiredUidRanges = new ArrayList<>();
@@ -376,11 +378,12 @@
// All tests in this class require a working Internet connection as they start. Make
// sure there is still one as they end that's ready to use for the next test to use.
final TestNetworkCallback callback = new TestNetworkCallback();
- mCm.registerDefaultNetworkCallback(callback);
+ registerDefaultNetworkCallback(callback);
try {
assertNotNull("Couldn't restore Internet connectivity", callback.waitForAvailable());
} finally {
- mCm.unregisterNetworkCallback(callback);
+ // Unregister all registered callbacks.
+ unregisterRegisteredCallbacks();
}
}
@@ -715,7 +718,7 @@
final String goodPrivateDnsServer = "dns.google";
mCtsNetUtils.storePrivateDnsSetting();
final TestableNetworkCallback cb = new TestableNetworkCallback();
- mCm.registerNetworkCallback(makeWifiNetworkRequest(), cb);
+ registerNetworkCallback(makeWifiNetworkRequest(), cb);
try {
// Verifying the good private DNS sever
mCtsNetUtils.setPrivateDnsStrictMode(goodPrivateDnsServer);
@@ -747,15 +750,15 @@
*/
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@Test
- public void testRegisterNetworkCallback() {
+ public void testRegisterNetworkCallback() throws Exception {
assumeTrue(mPackageManager.hasSystemFeature(FEATURE_WIFI));
// We will register for a WIFI network being available or lost.
final TestNetworkCallback callback = new TestNetworkCallback();
- mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
+ registerNetworkCallback(makeWifiNetworkRequest(), callback);
final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback();
- mCm.registerDefaultNetworkCallback(defaultTrackingCallback);
+ registerDefaultNetworkCallback(defaultTrackingCallback);
final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback();
final TestNetworkCallback perUidCallback = new TestNetworkCallback();
@@ -763,51 +766,37 @@
final Handler h = new Handler(Looper.getMainLooper());
if (TestUtils.shouldTestSApis()) {
runWithShellPermissionIdentity(() -> {
- mCmShim.registerSystemDefaultNetworkCallback(systemDefaultCallback, h);
- mCmShim.registerDefaultNetworkCallbackForUid(Process.myUid(), perUidCallback, h);
+ registerSystemDefaultNetworkCallback(systemDefaultCallback, h);
+ registerDefaultNetworkCallbackForUid(Process.myUid(), perUidCallback, h);
}, NETWORK_SETTINGS);
- mCm.registerBestMatchingNetworkCallback(makeDefaultRequest(), bestMatchingCallback, h);
+ registerBestMatchingNetworkCallback(makeDefaultRequest(), bestMatchingCallback, h);
}
Network wifiNetwork = null;
+ mCtsNetUtils.ensureWifiConnected();
- try {
- mCtsNetUtils.ensureWifiConnected();
+ // Now we should expect to get a network callback about availability of the wifi
+ // network even if it was already connected as a state-based action when the callback
+ // is registered.
+ wifiNetwork = callback.waitForAvailable();
+ assertNotNull("Did not receive onAvailable for TRANSPORT_WIFI request",
+ wifiNetwork);
- // Now we should expect to get a network callback about availability of the wifi
- // network even if it was already connected as a state-based action when the callback
- // is registered.
- wifiNetwork = callback.waitForAvailable();
- assertNotNull("Did not receive onAvailable for TRANSPORT_WIFI request",
- wifiNetwork);
+ final Network defaultNetwork = defaultTrackingCallback.waitForAvailable();
+ assertNotNull("Did not receive onAvailable on default network callback",
+ defaultNetwork);
- final Network defaultNetwork = defaultTrackingCallback.waitForAvailable();
- assertNotNull("Did not receive onAvailable on default network callback",
- defaultNetwork);
-
- if (TestUtils.shouldTestSApis()) {
- assertNotNull("Did not receive onAvailable on system default network callback",
- systemDefaultCallback.waitForAvailable());
- final Network perUidNetwork = perUidCallback.waitForAvailable();
- assertNotNull("Did not receive onAvailable on per-UID default network callback",
- perUidNetwork);
- assertEquals(defaultNetwork, perUidNetwork);
- final Network bestMatchingNetwork = bestMatchingCallback.waitForAvailable();
- assertNotNull("Did not receive onAvailable on best matching network callback",
- bestMatchingNetwork);
- assertEquals(defaultNetwork, bestMatchingNetwork);
- }
-
- } catch (InterruptedException e) {
- fail("Broadcast receiver or NetworkCallback wait was interrupted.");
- } finally {
- mCm.unregisterNetworkCallback(callback);
- mCm.unregisterNetworkCallback(defaultTrackingCallback);
- if (TestUtils.shouldTestSApis()) {
- mCm.unregisterNetworkCallback(systemDefaultCallback);
- mCm.unregisterNetworkCallback(perUidCallback);
- mCm.unregisterNetworkCallback(bestMatchingCallback);
- }
+ if (TestUtils.shouldTestSApis()) {
+ assertNotNull("Did not receive onAvailable on system default network callback",
+ systemDefaultCallback.waitForAvailable());
+ final Network perUidNetwork = perUidCallback.waitForAvailable();
+ assertNotNull("Did not receive onAvailable on per-UID default network callback",
+ perUidNetwork);
+ assertEquals(defaultNetwork, perUidNetwork);
+ final Network bestMatchingNetwork = bestMatchingCallback.waitForAvailable();
+ assertNotNull("Did not receive onAvailable on best matching network callback",
+ bestMatchingNetwork);
+ assertEquals(defaultNetwork, bestMatchingNetwork);
}
}
@@ -978,22 +967,15 @@
*/
@AppModeFull(reason = "CHANGE_NETWORK_STATE permission can't be granted to instant apps")
@Test
- public void testRequestNetworkCallback() {
+ public void testRequestNetworkCallback() throws Exception {
final TestNetworkCallback callback = new TestNetworkCallback();
- mCm.requestNetwork(new NetworkRequest.Builder()
+ requestNetwork(new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), callback);
- try {
- // Wait to get callback for availability of internet
- Network internetNetwork = callback.waitForAvailable();
- assertNotNull("Did not receive NetworkCallback#onAvailable for INTERNET",
- internetNetwork);
- } catch (InterruptedException e) {
- fail("NetworkCallback wait was interrupted.");
- } finally {
- mCm.unregisterNetworkCallback(callback);
- }
+ // Wait to get callback for availability of internet
+ Network internetNetwork = callback.waitForAvailable();
+ assertNotNull("Did not receive NetworkCallback#onAvailable for INTERNET", internetNetwork);
}
/**
@@ -1009,9 +991,8 @@
}
final TestNetworkCallback callback = new TestNetworkCallback();
- mCm.requestNetwork(new NetworkRequest.Builder()
- .addTransportType(TRANSPORT_WIFI)
- .build(), callback, 100);
+ requestNetwork(new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(),
+ callback, 100);
try {
// Wait to get callback for unavailability of requested network
@@ -1020,7 +1001,6 @@
} catch (InterruptedException e) {
fail("NetworkCallback wait was interrupted.");
} finally {
- mCm.unregisterNetworkCallback(callback);
if (previousWifiEnabledState) {
mCtsNetUtils.connectToWifi();
}
@@ -1042,7 +1022,7 @@
*/
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@Test
- public void testToggleWifiConnectivityAction() {
+ public void testToggleWifiConnectivityAction() throws Exception {
// toggleWifi calls connectToWifi and disconnectFromWifi, which both wait for
// CONNECTIVITY_ACTION broadcasts.
mCtsNetUtils.toggleWifi();
@@ -1123,11 +1103,11 @@
// this method will return right away, and if not, it'll wait for the setting to change.
if (useSystemDefault) {
runWithShellPermissionIdentity(() ->
- mCmShim.registerSystemDefaultNetworkCallback(networkCallback,
+ registerSystemDefaultNetworkCallback(networkCallback,
new Handler(Looper.getMainLooper())),
NETWORK_SETTINGS);
} else {
- mCm.registerDefaultNetworkCallback(networkCallback);
+ registerDefaultNetworkCallback(networkCallback);
}
// Changing meteredness on wifi involves reconnecting, which can take several seconds
@@ -1137,8 +1117,6 @@
throw new AssertionError("Timed out waiting for active network metered status to "
+ "change to " + requestedMeteredness + " ; network = "
+ mCm.getActiveNetwork(), e);
- } finally {
- mCm.unregisterNetworkCallback(networkCallback);
}
}
@@ -1698,7 +1676,10 @@
return;
}
- final int firstSdk = Build.VERSION.FIRST_SDK_INT;
+ final int firstSdk = SdkLevel.isAtLeastS()
+ ? Build.VERSION.DEVICE_INITIAL_SDK_INT
+ // FIRST_SDK_INT was a @TestApi field renamed to DEVICE_INITIAL_SDK_INT in S
+ : Build.VERSION.class.getField("FIRST_SDK_INT").getInt(null);
if (firstSdk < Build.VERSION_CODES.Q) {
Log.i(TAG, "testSocketKeepaliveLimitTelephony: skip test for devices launching"
+ " before Q: " + firstSdk);
@@ -1821,8 +1802,15 @@
// Verify that networks are available as expected if wifi or cell is supported. Continue the
// test if none of them are supported since test should still able to verify the permission
// mechanism.
- if (supportWifi) requestAndWaitForAvailable(makeWifiNetworkRequest(), wifiCb);
- if (supportTelephony) requestAndWaitForAvailable(makeCellNetworkRequest(), telephonyCb);
+ if (supportWifi) {
+ mCtsNetUtils.ensureWifiConnected();
+ registerCallbackAndWaitForAvailable(makeWifiNetworkRequest(), wifiCb);
+ }
+ if (supportTelephony) {
+ // connectToCell needs to be followed by disconnectFromCell, which is called in tearDown
+ mCtsNetUtils.connectToCell();
+ registerCallbackAndWaitForAvailable(makeCellNetworkRequest(), telephonyCb);
+ }
try {
// Verify we cannot set Airplane Mode without correct permission:
@@ -1859,11 +1847,11 @@
+ "called whilst holding the NETWORK_AIRPLANE_MODE permission.");
}
// Verify that turning airplane mode off takes effect as expected.
+ // connectToCell only registers a request, it cannot / does not need to be called twice
+ mCtsNetUtils.ensureWifiConnected();
if (supportWifi) waitForAvailable(wifiCb);
if (supportTelephony) waitForAvailable(telephonyCb);
} finally {
- if (supportWifi) mCm.unregisterNetworkCallback(wifiCb);
- if (supportTelephony) mCm.unregisterNetworkCallback(telephonyCb);
// Restore the previous state of airplane mode and permissions:
runShellCommand("cmd connectivity airplane-mode "
+ (isAirplaneModeEnabled ? "enable" : "disable"));
@@ -1871,9 +1859,9 @@
}
}
- private void requestAndWaitForAvailable(@NonNull final NetworkRequest request,
+ private void registerCallbackAndWaitForAvailable(@NonNull final NetworkRequest request,
@NonNull final TestableNetworkCallback cb) {
- mCm.registerNetworkCallback(request, cb);
+ registerNetworkCallback(request, cb);
waitForAvailable(cb);
}
@@ -1991,18 +1979,15 @@
foundNc.complete(nc);
}
};
- try {
- mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
- // Registering a callback here guarantees onCapabilitiesChanged is called immediately
- // because WiFi network should be connected.
- final NetworkCapabilities nc =
- foundNc.get(NETWORK_CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- // Verify if ssid is contained in the NetworkCapabilities received from callback.
- assertNotNull("NetworkCapabilities of the network is null", nc);
- assertEquals(hasSsid, Pattern.compile(ssid).matcher(nc.toString()).find());
- } finally {
- mCm.unregisterNetworkCallback(callback);
- }
+
+ registerNetworkCallback(makeWifiNetworkRequest(), callback);
+ // Registering a callback here guarantees onCapabilitiesChanged is called immediately
+ // because WiFi network should be connected.
+ final NetworkCapabilities nc =
+ foundNc.get(NETWORK_CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ // Verify if ssid is contained in the NetworkCapabilities received from callback.
+ assertNotNull("NetworkCapabilities of the network is null", nc);
+ assertEquals(hasSsid, Pattern.compile(ssid).matcher(nc.toString()).find());
}
/**
@@ -2040,14 +2025,14 @@
final TestableNetworkCallback callback = new TestableNetworkCallback();
final Handler handler = new Handler(Looper.getMainLooper());
assertThrows(SecurityException.class,
- () -> mCmShim.requestBackgroundNetwork(testRequest, callback, handler));
+ () -> requestBackgroundNetwork(testRequest, callback, handler));
Network testNetwork = null;
try {
// Request background test network via Shell identity which has NETWORK_SETTINGS
// permission granted.
runWithShellPermissionIdentity(
- () -> mCmShim.requestBackgroundNetwork(testRequest, callback, handler),
+ () -> requestBackgroundNetwork(testRequest, callback, handler),
new String[] { android.Manifest.permission.NETWORK_SETTINGS });
// Register the test network agent which has no foreground request associated to it.
@@ -2084,7 +2069,6 @@
}
testNetworkInterface.getFileDescriptor().close();
}, new String[] { android.Manifest.permission.MANAGE_TEST_NETWORKS });
- mCm.unregisterNetworkCallback(callback);
}
}
@@ -2099,6 +2083,10 @@
public void onBlockedStatusChanged(Network network, int blockedReasons) {
getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons));
}
+ private void assertNoBlockedStatusCallback() {
+ super.assertNoCallbackThat(NO_CALLBACK_TIMEOUT_MS,
+ c -> c instanceof CallbackEntry.BlockedStatus);
+ }
}
private void setRequireVpnForUids(boolean requireVpn, Collection<Range<Integer>> ranges)
@@ -2120,8 +2108,9 @@
final int myUid = Process.myUid();
final int otherUid = UserHandle.getUid(5, Process.FIRST_APPLICATION_UID);
final Handler handler = new Handler(Looper.getMainLooper());
- mCm.registerDefaultNetworkCallback(myUidCallback, handler);
- mCmShim.registerDefaultNetworkCallbackForUid(otherUid, otherUidCallback, handler);
+
+ registerDefaultNetworkCallback(myUidCallback, handler);
+ registerDefaultNetworkCallbackForUid(otherUid, otherUidCallback, handler);
final Network defaultNetwork = mCm.getActiveNetwork();
final List<DetailedBlockedStatusCallback> allCallbacks =
@@ -2135,24 +2124,24 @@
setRequireVpnForUids(true, List.of(myUidRange));
myUidCallback.expectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_LOCKDOWN_VPN);
- otherUidCallback.assertNoCallback(NO_CALLBACK_TIMEOUT_MS);
+ otherUidCallback.assertNoBlockedStatusCallback();
setRequireVpnForUids(true, List.of(myUidRange, otherUidRange));
- myUidCallback.assertNoCallback(NO_CALLBACK_TIMEOUT_MS);
+ myUidCallback.assertNoBlockedStatusCallback();
otherUidCallback.expectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_LOCKDOWN_VPN);
// setRequireVpnForUids does no deduplication or refcounting. Removing myUidRange does not
// unblock myUid because it was added to the blocked ranges twice.
setRequireVpnForUids(false, List.of(myUidRange));
- myUidCallback.assertNoCallback(NO_CALLBACK_TIMEOUT_MS);
- otherUidCallback.assertNoCallback(NO_CALLBACK_TIMEOUT_MS);
+ myUidCallback.assertNoBlockedStatusCallback();
+ otherUidCallback.assertNoBlockedStatusCallback();
setRequireVpnForUids(false, List.of(myUidRange, otherUidRange));
myUidCallback.expectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_NONE);
otherUidCallback.expectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_NONE);
- myUidCallback.assertNoCallback(NO_CALLBACK_TIMEOUT_MS);
- otherUidCallback.assertNoCallback(NO_CALLBACK_TIMEOUT_MS);
+ myUidCallback.assertNoBlockedStatusCallback();
+ otherUidCallback.assertNoBlockedStatusCallback();
}
@Test
@@ -2168,16 +2157,15 @@
assertNotNull(info);
assertEquals(DetailedState.CONNECTED, info.getDetailedState());
+ final TestableNetworkCallback callback = new TestableNetworkCallback();
try {
mCmShim.setLegacyLockdownVpnEnabled(true);
// setLegacyLockdownVpnEnabled is asynchronous and only takes effect when the
// ConnectivityService handler thread processes it. Ensure it has taken effect by doing
// something that blocks until the handler thread is idle.
- final TestableNetworkCallback callback = new TestableNetworkCallback();
- mCm.registerDefaultNetworkCallback(callback);
+ registerDefaultNetworkCallback(callback);
waitForAvailable(callback);
- mCm.unregisterNetworkCallback(callback);
// Test one of the effects of setLegacyLockdownVpnEnabled: the fact that any NetworkInfo
// in state CONNECTED is degraded to CONNECTING if the legacy VPN is not connected.
@@ -2366,7 +2354,6 @@
// Cleanup any prior test state from setOemNetworkPreference
clearOemNetworkPreference();
- unregisterTestOemNetworkPreferenceCallbacks(defaultCallback, systemDefaultCallback);
}
}
@@ -2410,23 +2397,15 @@
// The default (non-test) network should be available as the network pref was cleared.
waitForAvailable(defaultCallback);
- unregisterTestOemNetworkPreferenceCallbacks(defaultCallback, systemDefaultCallback);
}
}
- private void unregisterTestOemNetworkPreferenceCallbacks(
- @NonNull final TestableNetworkCallback defaultCallback,
- @NonNull final TestableNetworkCallback systemDefaultCallback) {
- mCm.unregisterNetworkCallback(defaultCallback);
- mCm.unregisterNetworkCallback(systemDefaultCallback);
- }
-
private void registerTestOemNetworkPreferenceCallbacks(
@NonNull final TestableNetworkCallback defaultCallback,
@NonNull final TestableNetworkCallback systemDefaultCallback) {
- mCm.registerDefaultNetworkCallback(defaultCallback);
+ registerDefaultNetworkCallback(defaultCallback);
runWithShellPermissionIdentity(() ->
- mCmShim.registerSystemDefaultNetworkCallback(systemDefaultCallback,
+ registerSystemDefaultNetworkCallback(systemDefaultCallback,
new Handler(Looper.getMainLooper())), NETWORK_SETTINGS);
}
@@ -2527,7 +2506,7 @@
// Wait for partial connectivity to be detected on the network
final Network network = preparePartialConnectivity();
- mCm.requestNetwork(makeWifiNetworkRequest(), cb);
+ requestNetwork(makeWifiNetworkRequest(), cb);
runAsShell(NETWORK_SETTINGS, () -> {
// The always bit is verified in NetworkAgentTest
mCm.setAcceptPartialConnectivity(network, false /* accept */, false /* always */);
@@ -2535,7 +2514,6 @@
// Reject partial connectivity network should cause the network being torn down
assertEquals(network, cb.waitForLost());
} finally {
- mCm.unregisterNetworkCallback(cb);
resetValidationConfig();
// Wifi will not automatically reconnect to the network. ensureWifiDisconnected cannot
// apply here. Thus, turn off wifi first and restart to restore.
@@ -2570,13 +2548,12 @@
// guarantee that it won't become the default in the future.
assertNotEquals(wifiNetwork, mCm.getActiveNetwork());
- mCm.registerNetworkCallback(makeWifiNetworkRequest(), wifiCb);
+ registerNetworkCallback(makeWifiNetworkRequest(), wifiCb);
runAsShell(NETWORK_SETTINGS, () -> {
mCm.setAcceptUnvalidated(wifiNetwork, false /* accept */, false /* always */);
});
waitForLost(wifiCb);
} finally {
- mCm.unregisterNetworkCallback(wifiCb);
resetValidationConfig();
/// Wifi will not automatically reconnect to the network. ensureWifiDisconnected cannot
// apply here. Thus, turn off wifi first and restart to restore.
@@ -2606,8 +2583,8 @@
final Network cellNetwork = mCtsNetUtils.connectToCell();
final Network wifiNetwork = prepareValidatedNetwork();
- mCm.registerDefaultNetworkCallback(defaultCb);
- mCm.registerNetworkCallback(makeWifiNetworkRequest(), wifiCb);
+ registerDefaultNetworkCallback(defaultCb);
+ registerNetworkCallback(makeWifiNetworkRequest(), wifiCb);
try {
// Verify wifi is the default network.
@@ -2637,11 +2614,10 @@
// Default network should be updated to validated cellular network.
defaultCb.eventuallyExpect(CallbackEntry.AVAILABLE, NETWORK_CALLBACK_TIMEOUT_MS,
entry -> cellNetwork.equals(entry.getNetwork()));
- // No update on wifi callback.
- wifiCb.assertNoCallback();
+ // No callback except LinkPropertiesChanged which may be triggered randomly from network
+ wifiCb.assertNoCallbackThat(NO_CALLBACK_TIMEOUT_MS,
+ c -> !(c instanceof CallbackEntry.LinkPropertiesChanged));
} finally {
- mCm.unregisterNetworkCallback(wifiCb);
- mCm.unregisterNetworkCallback(defaultCb);
resetAvoidBadWifi(previousAvoidBadWifi);
resetValidationConfig();
// Reconnect wifi to reset the wifi status
@@ -2679,12 +2655,8 @@
}
};
- try {
- mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), cb);
- return future.get(timeout, TimeUnit.MILLISECONDS);
- } finally {
- mCm.unregisterNetworkCallback(cb);
- }
+ registerNetworkCallback(new NetworkRequest.Builder().build(), cb);
+ return future.get(timeout, TimeUnit.MILLISECONDS);
}
private void resetValidationConfig() {
@@ -2794,9 +2766,9 @@
final TestableNetworkCallback defaultTrackingCb = new TestableNetworkCallback();
final TestableNetworkCallback systemDefaultCb = new TestableNetworkCallback();
final Handler h = new Handler(Looper.getMainLooper());
- runWithShellPermissionIdentity(() -> mCm.registerSystemDefaultNetworkCallback(
+ runWithShellPermissionIdentity(() -> registerSystemDefaultNetworkCallback(
systemDefaultCb, h), NETWORK_SETTINGS);
- mCm.registerDefaultNetworkCallback(defaultTrackingCb);
+ registerDefaultNetworkCallback(defaultTrackingCb);
try {
// CtsNetTestCases uid is not listed in MOBILE_DATA_PREFERRED_UIDS setting, so the
@@ -2832,31 +2804,19 @@
// Active network for CtsNetTestCases uid should change back to wifi.
assertEquals(wifiNetwork, mCm.getActiveNetwork());
} finally {
- mCm.unregisterNetworkCallback(systemDefaultCb);
- mCm.unregisterNetworkCallback(defaultTrackingCb);
-
// Restore setting.
ConnectivitySettingsManager.setMobileDataPreferredUids(
mContext, mobileDataPreferredUids);
}
}
- /** Wait for assigned time. */
- private void waitForMs(long ms) {
- try {
- Thread.sleep(ms);
- } catch (InterruptedException e) {
- fail("Thread was interrupted");
- }
- }
-
private void assertBindSocketToNetworkSuccess(final Network network) throws Exception {
final CompletableFuture<Boolean> future = new CompletableFuture<>();
final ExecutorService executor = Executors.newSingleThreadExecutor();
try {
executor.execute(() -> {
- for (int i = 0; i < 30; i++) {
- waitForMs(100);
+ for (int i = 0; i < 300; i++) {
+ SystemClock.sleep(10);
try (Socket socket = new Socket()) {
network.bindSocket(socket);
@@ -2894,7 +2854,7 @@
final Handler h = new Handler(Looper.getMainLooper());
final TestableNetworkCallback testNetworkCb = new TestableNetworkCallback();
- mCm.registerBestMatchingNetworkCallback(new NetworkRequest.Builder().clearCapabilities()
+ registerBestMatchingNetworkCallback(new NetworkRequest.Builder().clearCapabilities()
.addTransportType(NetworkCapabilities.TRANSPORT_TEST).build(), testNetworkCb, h);
// Create test network agent with restricted network.
@@ -2944,7 +2904,6 @@
// TODD: Have a significant signal to know the uids has been send to netd.
assertBindSocketToNetworkSuccess(network);
} finally {
- mCm.unregisterNetworkCallback(testNetworkCb);
agent.unregister();
// Restore setting.
@@ -2953,4 +2912,58 @@
mContext, originalUidsAllowedOnRestrictedNetworks), NETWORK_SETTINGS);
}
}
+
+ private void unregisterRegisteredCallbacks() {
+ for (NetworkCallback callback: mRegisteredCallbacks) {
+ mCm.unregisterNetworkCallback(callback);
+ }
+ }
+
+ private void registerDefaultNetworkCallback(NetworkCallback callback) {
+ mCm.registerDefaultNetworkCallback(callback);
+ mRegisteredCallbacks.add(callback);
+ }
+
+ private void registerDefaultNetworkCallback(NetworkCallback callback, Handler handler) {
+ mCm.registerDefaultNetworkCallback(callback, handler);
+ mRegisteredCallbacks.add(callback);
+ }
+
+ private void registerNetworkCallback(NetworkRequest request, NetworkCallback callback) {
+ mCm.registerNetworkCallback(request, callback);
+ mRegisteredCallbacks.add(callback);
+ }
+
+ private void registerSystemDefaultNetworkCallback(NetworkCallback callback, Handler handler) {
+ mCmShim.registerSystemDefaultNetworkCallback(callback, handler);
+ mRegisteredCallbacks.add(callback);
+ }
+
+ private void registerDefaultNetworkCallbackForUid(int uid, NetworkCallback callback,
+ Handler handler) throws Exception {
+ mCmShim.registerDefaultNetworkCallbackForUid(uid, callback, handler);
+ mRegisteredCallbacks.add(callback);
+ }
+
+ private void requestNetwork(NetworkRequest request, NetworkCallback callback) {
+ mCm.requestNetwork(request, callback);
+ mRegisteredCallbacks.add(callback);
+ }
+
+ private void requestNetwork(NetworkRequest request, NetworkCallback callback, int timeoutSec) {
+ mCm.requestNetwork(request, callback, timeoutSec);
+ mRegisteredCallbacks.add(callback);
+ }
+
+ private void registerBestMatchingNetworkCallback(NetworkRequest request,
+ NetworkCallback callback, Handler handler) {
+ mCm.registerBestMatchingNetworkCallback(request, callback, handler);
+ mRegisteredCallbacks.add(callback);
+ }
+
+ private void requestBackgroundNetwork(NetworkRequest request, NetworkCallback callback,
+ Handler handler) throws Exception {
+ mCmShim.requestBackgroundNetwork(request, callback, handler);
+ mRegisteredCallbacks.add(callback);
+ }
}
diff --git a/tests/cts/net/src/android/net/cts/PacProxyManagerTest.java b/tests/cts/net/src/android/net/cts/PacProxyManagerTest.java
index a20f1cc..f0c87673 100644
--- a/tests/cts/net/src/android/net/cts/PacProxyManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/PacProxyManagerTest.java
@@ -16,6 +16,7 @@
package android.net.cts;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static com.android.testutils.TestPermissionUtil.runAsShell;
@@ -168,7 +169,9 @@
mContext.registerReceiver(receiver, new IntentFilter(Proxy.PROXY_CHANGE_ACTION));
// Call setCurrentProxyScriptUrl with the URL of the pac file.
- runAsShell(NETWORK_SETTINGS, () -> {
+ // Note that the proxy script is global to device, and setting it from a different user
+ // should require INTERACT_ACROSS_USERS_FULL permission which the Settings app has.
+ runAsShell(NETWORK_SETTINGS, INTERACT_ACROSS_USERS_FULL, () -> {
mPacProxyManager.setCurrentProxyScriptUrl(proxy);
});
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
index 103906a..fd0cd18 100644
--- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -54,6 +54,7 @@
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Build;
+import android.os.ConditionVariable;
import android.os.IBinder;
import android.os.SystemClock;
import android.system.Os;
@@ -168,18 +169,44 @@
}
// Toggle WiFi twice, leaving it in the state it started in
- public void toggleWifi() {
+ public void toggleWifi() throws Exception {
if (mWifiManager.isWifiEnabled()) {
Network wifiNetwork = getWifiNetwork();
+ // Ensure system default network is WIFI because it's expected in disconnectFromWifi()
+ expectNetworkIsSystemDefault(wifiNetwork);
disconnectFromWifi(wifiNetwork);
connectToWifi();
} else {
connectToWifi();
Network wifiNetwork = getWifiNetwork();
+ // Ensure system default network is WIFI because it's expected in disconnectFromWifi()
+ expectNetworkIsSystemDefault(wifiNetwork);
disconnectFromWifi(wifiNetwork);
}
}
+ private Network expectNetworkIsSystemDefault(Network network)
+ throws Exception {
+ final CompletableFuture<Network> future = new CompletableFuture();
+ final NetworkCallback cb = new NetworkCallback() {
+ @Override
+ public void onAvailable(Network n) {
+ if (n.equals(network)) future.complete(network);
+ }
+ };
+
+ try {
+ mCm.registerDefaultNetworkCallback(cb);
+ return future.get(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ throw new AssertionError("Timed out waiting for system default network to switch"
+ + " to network " + network + ". Current default network is network "
+ + mCm.getActiveNetwork(), e);
+ } finally {
+ mCm.unregisterNetworkCallback(cb);
+ }
+ }
+
/**
* Enable WiFi and wait for it to become connected to a network.
*
@@ -264,6 +291,9 @@
Log.w(TAG, "connect failed with " + error + "; waiting before retry");
SystemClock.sleep(WIFI_CONNECT_INTERVAL_MS);
}
+
+ fail("Failed to connect to " + config.SSID
+ + " after " + MAX_WIFI_CONNECT_RETRIES + "retries");
}
private static class ConnectWifiListener implements WifiManager.ActionListener {
@@ -696,16 +726,28 @@
* {@code onAvailable}.
*/
public static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
- private final CountDownLatch mAvailableLatch = new CountDownLatch(1);
+ private final ConditionVariable mAvailableCv = new ConditionVariable(false);
private final CountDownLatch mLostLatch = new CountDownLatch(1);
private final CountDownLatch mUnavailableLatch = new CountDownLatch(1);
public Network currentNetwork;
public Network lastLostNetwork;
+ /**
+ * Wait for a network to be available.
+ *
+ * If onAvailable was previously called but was followed by onLost, this will wait for the
+ * next available network.
+ */
public Network waitForAvailable() throws InterruptedException {
- return mAvailableLatch.await(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS)
- ? currentNetwork : null;
+ final long timeoutMs = TimeUnit.SECONDS.toMillis(CONNECTIVITY_CHANGE_TIMEOUT_SECS);
+ while (mAvailableCv.block(timeoutMs)) {
+ final Network n = currentNetwork;
+ if (n != null) return n;
+ Log.w(TAG, "onAvailable called but network was lost before it could be returned."
+ + " Waiting for the next call to onAvailable.");
+ }
+ return null;
}
public Network waitForLost() throws InterruptedException {
@@ -717,17 +759,17 @@
return mUnavailableLatch.await(2, TimeUnit.SECONDS);
}
-
@Override
public void onAvailable(Network network) {
currentNetwork = network;
- mAvailableLatch.countDown();
+ mAvailableCv.open();
}
@Override
public void onLost(Network network) {
lastLostNetwork = network;
if (network.equals(currentNetwork)) {
+ mAvailableCv.close();
currentNetwork = null;
}
mLostLatch.countDown();
diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp
index 52ce83a..e9c4e5a 100644
--- a/tests/cts/tethering/Android.bp
+++ b/tests/cts/tethering/Android.bp
@@ -71,6 +71,7 @@
// Include both the 32 and 64 bit versions
compile_multilib: "both",
+ jarjar_rules: ":NetworkStackJarJarRules",
}
// Tethering CTS tests for development and release. These tests always target the platform SDK
@@ -95,4 +96,5 @@
// Include both the 32 and 64 bit versions
compile_multilib: "both",
+ jarjar_rules: ":NetworkStackJarJarRules",
}
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index 5fe478f..2bc985a 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -29,6 +29,7 @@
],
libs: [
"android.test.mock",
+ "ServiceConnectivityResources",
],
static_libs: [
"NetworkStackApiStableLib",
@@ -37,7 +38,7 @@
"kotlin-reflect",
"mockito-target-extended-minus-junit4",
"net-tests-utils",
- "service-connectivity",
+ "service-connectivity-pre-jarjar",
"services.core",
"services.net",
"testables",
@@ -52,6 +53,7 @@
"libnativehelper_compat_libc++",
"libnetworkstackutilsjni",
],
+ jarjar_rules: ":connectivity-jarjar-rules",
}
// Utilities for testing framework code both in integration and unit tests.
diff --git a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index e039ef0..80338aa 100644
--- a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -23,7 +23,9 @@
import android.content.Context.BIND_IMPORTANT
import android.content.Intent
import android.content.ServiceConnection
+import android.content.res.Resources
import android.net.ConnectivityManager
+import android.net.ConnectivityResources
import android.net.IDnsResolver
import android.net.INetd
import android.net.LinkProperties
@@ -35,6 +37,7 @@
import android.net.TestNetworkStackClient
import android.net.Uri
import android.net.metrics.IpConnectivityLog
+import android.net.util.MultinetworkPolicyTracker
import android.os.ConditionVariable
import android.os.IBinder
import android.os.SystemConfigManager
@@ -43,6 +46,7 @@
import android.util.Log
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
+import com.android.connectivity.resources.R
import com.android.server.ConnectivityService
import com.android.server.NetworkAgentWrapper
import com.android.server.TestNetIdManager
@@ -59,6 +63,7 @@
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.doNothing
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.eq
@@ -93,6 +98,10 @@
private lateinit var dnsResolver: IDnsResolver
@Mock
private lateinit var systemConfigManager: SystemConfigManager
+ @Mock
+ private lateinit var resources: Resources
+ @Mock
+ private lateinit var resourcesContext: Context
@Spy
private var context = TestableContext(realContext)
@@ -110,9 +119,11 @@
private val realContext get() = InstrumentationRegistry.getInstrumentation().context
private val httpProbeUrl get() =
- realContext.getResources().getString(R.string.config_captive_portal_http_url)
+ realContext.getResources().getString(com.android.server.net.integrationtests.R.string
+ .config_captive_portal_http_url)
private val httpsProbeUrl get() =
- realContext.getResources().getString(R.string.config_captive_portal_https_url)
+ realContext.getResources().getString(com.android.server.net.integrationtests.R.string
+ .config_captive_portal_https_url)
private class InstrumentationServiceConnection : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
@@ -156,6 +167,27 @@
.getSystemService(Context.SYSTEM_CONFIG_SERVICE)
doReturn(IntArray(0)).`when`(systemConfigManager).getSystemPermissionUids(anyString())
+ doReturn(60000).`when`(resources).getInteger(R.integer.config_networkTransitionTimeout)
+ doReturn("").`when`(resources).getString(R.string.config_networkCaptivePortalServerUrl)
+ doReturn(arrayOf<String>("test_wlan_wol")).`when`(resources)
+ .getStringArray(R.array.config_wakeonlan_supported_interfaces)
+ doReturn(arrayOf("0,1", "1,3")).`when`(resources)
+ .getStringArray(R.array.config_networkSupportedKeepaliveCount)
+ doReturn(emptyArray<String>()).`when`(resources)
+ .getStringArray(R.array.config_networkNotifySwitches)
+ doReturn(intArrayOf(10, 11, 12, 14, 15)).`when`(resources)
+ .getIntArray(R.array.config_protectedNetworks)
+ // We don't test the actual notification value strings, so just return an empty array.
+ // It doesn't matter what the values are as long as it's not null.
+ doReturn(emptyArray<String>()).`when`(resources).getStringArray(
+ R.array.network_switch_type_name)
+ doReturn(1).`when`(resources).getInteger(R.integer.config_networkAvoidBadWifi)
+ doReturn(R.array.config_networkSupportedKeepaliveCount).`when`(resources)
+ .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any())
+
+ doReturn(resources).`when`(resourcesContext).getResources()
+ ConnectivityResources.setResourcesContextForTest(resourcesContext)
+
networkStackClient = TestNetworkStackClient(realContext)
networkStackClient.start()
@@ -176,12 +208,19 @@
doReturn(mock(ProxyTracker::class.java)).`when`(deps).makeProxyTracker(any(), any())
doReturn(mock(MockableSystemProperties::class.java)).`when`(deps).systemProperties
doReturn(TestNetIdManager()).`when`(deps).makeNetIdManager()
+ doAnswer { inv ->
+ object : MultinetworkPolicyTracker(inv.getArgument(0), inv.getArgument(1),
+ inv.getArgument(2)) {
+ override fun getResourcesForActiveSubId() = resources
+ }
+ }.`when`(deps).makeMultinetworkPolicyTracker(any(), any(), any())
return deps
}
@After
fun tearDown() {
nsInstrumentation.clearAllState()
+ ConnectivityResources.setResourcesContextForTest(null)
}
@Test
diff --git a/tests/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/tests/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
index eff6658..c7cf040 100644
--- a/tests/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
+++ b/tests/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
@@ -36,7 +36,6 @@
import java.io.ByteArrayInputStream
import java.net.HttpURLConnection
import java.net.URL
-import java.net.URLConnection
import java.nio.charset.StandardCharsets
private const val TEST_NETID = 42
@@ -63,6 +62,28 @@
override fun getPrivateDnsBypassNetwork(network: Network?) = privateDnsBypassNetwork
}
+ /**
+ * Mock [HttpURLConnection] to simulate reply from a server.
+ */
+ private class MockConnection(
+ url: URL,
+ private val response: HttpResponse
+ ) : HttpURLConnection(url) {
+ private val responseBytes = response.content.toByteArray(StandardCharsets.UTF_8)
+ override fun getResponseCode() = response.responseCode
+ override fun getContentLengthLong() = responseBytes.size.toLong()
+ override fun getHeaderField(field: String): String? {
+ return when (field) {
+ "location" -> response.redirectUrl
+ else -> null
+ }
+ }
+ override fun getInputStream() = ByteArrayInputStream(responseBytes)
+ override fun connect() = Unit
+ override fun disconnect() = Unit
+ override fun usingProxy() = false
+ }
+
private inner class TestNetworkStackConnector(context: Context) : NetworkStackConnector(
context, TestPermissionChecker(), NetworkStackService.Dependencies()) {
@@ -70,17 +91,8 @@
private val privateDnsBypassNetwork = TestNetwork(TEST_NETID)
private inner class TestNetwork(netId: Int) : Network(netId) {
- override fun openConnection(url: URL): URLConnection {
- val response = InstrumentationConnector.processRequest(url)
- val responseBytes = response.content.toByteArray(StandardCharsets.UTF_8)
-
- val connection = mock(HttpURLConnection::class.java)
- doReturn(response.responseCode).`when`(connection).responseCode
- doReturn(responseBytes.size.toLong()).`when`(connection).contentLengthLong
- doReturn(response.redirectUrl).`when`(connection).getHeaderField("location")
- doReturn(ByteArrayInputStream(responseBytes)).`when`(connection).inputStream
- return connection
- }
+ override fun openConnection(url: URL) = MockConnection(
+ url, InstrumentationConnector.processRequest(url))
}
override fun makeNetworkMonitor(
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index a7f57e8..96ea761 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -58,6 +58,7 @@
jarjar_rules: "jarjar-rules.txt",
static_libs: [
"androidx.test.rules",
+ "androidx.test.uiautomator",
"bouncycastle-repackaged-unbundled",
"core-tests-support",
"FrameworksNetCommonTests",
diff --git a/tests/unit/AndroidManifest.xml b/tests/unit/AndroidManifest.xml
index 4c60ccf..887f171 100644
--- a/tests/unit/AndroidManifest.xml
+++ b/tests/unit/AndroidManifest.xml
@@ -53,6 +53,8 @@
<application>
<uses-library android:name="android.test.runner" />
<uses-library android:name="android.net.ipsec.ike" />
+ <activity
+ android:name="com.android.server.connectivity.NetworkNotificationManagerTest$TestDialogActivity"/>
</application>
<instrumentation
diff --git a/tests/unit/java/android/net/IpSecAlgorithmTest.java b/tests/unit/java/android/net/IpSecAlgorithmTest.java
index cac8c2d..c2a759b 100644
--- a/tests/unit/java/android/net/IpSecAlgorithmTest.java
+++ b/tests/unit/java/android/net/IpSecAlgorithmTest.java
@@ -123,7 +123,7 @@
@Test
public void testValidationForAlgosAddedInS() throws Exception {
- if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.R) {
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.R) {
return;
}
@@ -196,13 +196,13 @@
private static Set<String> getMandatoryAlgos() {
return CollectionUtils.filter(
ALGO_TO_REQUIRED_FIRST_SDK.keySet(),
- i -> Build.VERSION.FIRST_SDK_INT >= ALGO_TO_REQUIRED_FIRST_SDK.get(i));
+ i -> Build.VERSION.DEVICE_INITIAL_SDK_INT >= ALGO_TO_REQUIRED_FIRST_SDK.get(i));
}
private static Set<String> getOptionalAlgos() {
return CollectionUtils.filter(
ALGO_TO_REQUIRED_FIRST_SDK.keySet(),
- i -> Build.VERSION.FIRST_SDK_INT < ALGO_TO_REQUIRED_FIRST_SDK.get(i));
+ i -> Build.VERSION.DEVICE_INITIAL_SDK_INT < ALGO_TO_REQUIRED_FIRST_SDK.get(i));
}
@Test
diff --git a/tests/unit/java/android/net/KeepalivePacketDataUtilTest.java b/tests/unit/java/android/net/KeepalivePacketDataUtilTest.java
index ed4f61d..8498b6f 100644
--- a/tests/unit/java/android/net/KeepalivePacketDataUtilTest.java
+++ b/tests/unit/java/android/net/KeepalivePacketDataUtilTest.java
@@ -168,8 +168,8 @@
assertEquals(resultData.tos, tos);
assertEquals(resultData.ttl, ttl);
- final String expected = ""
- + "android.net.TcpKeepalivePacketDataParcelable{srcAddress: [10, 0, 0, 1],"
+ final String expected = TcpKeepalivePacketDataParcelable.class.getName()
+ + "{srcAddress: [10, 0, 0, 1],"
+ " srcPort: 1234, dstAddress: [10, 0, 0, 5], dstPort: 4321, seq: 286331153,"
+ " ack: 572662306, rcvWnd: 48000, rcvWndScale: 2, tos: 4, ttl: 64}";
assertEquals(expected, resultData.toString());
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 772b968..c19ed61 100644
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -125,10 +125,11 @@
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.IPPROTO_TCP;
-import static com.android.server.ConnectivityService.PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED;
-import static com.android.server.ConnectivityService.PREFERENCE_PRIORITY_OEM;
-import static com.android.server.ConnectivityService.PREFERENCE_PRIORITY_PROFILE;
-import static com.android.server.ConnectivityService.PREFERENCE_PRIORITY_VPN;
+import static com.android.server.ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID;
+import static com.android.server.ConnectivityService.PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED;
+import static com.android.server.ConnectivityService.PREFERENCE_ORDER_OEM;
+import static com.android.server.ConnectivityService.PREFERENCE_ORDER_PROFILE;
+import static com.android.server.ConnectivityService.PREFERENCE_ORDER_VPN;
import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType;
import static com.android.testutils.ConcurrentUtils.await;
import static com.android.testutils.ConcurrentUtils.durationOf;
@@ -176,6 +177,8 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import static java.util.Arrays.asList;
+
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -279,6 +282,7 @@
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Looper;
+import android.os.Messenger;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -311,7 +315,6 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnProfile;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.WakeupMessage;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider;
@@ -540,6 +543,9 @@
private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();
// Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
+ // For permissions granted across the board, the key is only the permission name.
+ // For permissions only granted to a combination of uid/pid, the key
+ // is "<permission name>,<pid>,<uid>". PID+UID permissons have priority over generic ones.
private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
MockContext(Context base, ContentProvider settingsProvider) {
@@ -641,30 +647,40 @@
return mPackageManager;
}
- private int checkMockedPermission(String permission, Supplier<Integer> ifAbsent) {
- final Integer granted = mMockedPermissions.get(permission);
- return granted != null ? granted : ifAbsent.get();
+ private int checkMockedPermission(String permission, int pid, int uid,
+ Supplier<Integer> ifAbsent) {
+ final Integer granted = mMockedPermissions.get(permission + "," + pid + "," + uid);
+ if (null != granted) {
+ return granted;
+ }
+ final Integer allGranted = mMockedPermissions.get(permission);
+ if (null != allGranted) {
+ return allGranted;
+ }
+ return ifAbsent.get();
}
@Override
public int checkPermission(String permission, int pid, int uid) {
- return checkMockedPermission(
- permission, () -> super.checkPermission(permission, pid, uid));
+ return checkMockedPermission(permission, pid, uid,
+ () -> super.checkPermission(permission, pid, uid));
}
@Override
public int checkCallingOrSelfPermission(String permission) {
- return checkMockedPermission(
- permission, () -> super.checkCallingOrSelfPermission(permission));
+ return checkMockedPermission(permission, Process.myPid(), Process.myUid(),
+ () -> super.checkCallingOrSelfPermission(permission));
}
@Override
public void enforceCallingOrSelfPermission(String permission, String message) {
- final Integer granted = mMockedPermissions.get(permission);
- if (granted == null) {
- super.enforceCallingOrSelfPermission(permission, message);
- return;
- }
+ final Integer granted = checkMockedPermission(permission,
+ Process.myPid(), Process.myUid(),
+ () -> {
+ super.enforceCallingOrSelfPermission(permission, message);
+ // enforce will crash if the permission is not granted
+ return PERMISSION_GRANTED;
+ });
if (!granted.equals(PERMISSION_GRANTED)) {
throw new SecurityException("[Test] permission denied: " + permission);
@@ -674,6 +690,8 @@
/**
* Mock checks for the specified permission, and have them behave as per {@code granted}.
*
+ * This will apply across the board no matter what the checked UID and PID are.
+ *
* <p>Passing null reverts to default behavior, which does a real permission check on the
* test package.
* @param granted One of {@link PackageManager#PERMISSION_GRANTED} or
@@ -683,6 +701,21 @@
mMockedPermissions.put(permission, granted);
}
+ /**
+ * Mock checks for the specified permission, and have them behave as per {@code granted}.
+ *
+ * This will only apply to the passed UID and PID.
+ *
+ * <p>Passing null reverts to default behavior, which does a real permission check on the
+ * test package.
+ * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or
+ * {@link PackageManager#PERMISSION_DENIED}.
+ */
+ public void setPermission(String permission, int pid, int uid, Integer granted) {
+ final String key = permission + "," + pid + "," + uid;
+ mMockedPermissions.put(key, granted);
+ }
+
@Override
public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver,
@NonNull IntentFilter filter, @Nullable String broadcastPermission,
@@ -1298,10 +1331,10 @@
verify(mMockNetd, times(1)).networkAddUidRangesParcel(
new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(),
- toUidRangeStableParcels(uids), PREFERENCE_PRIORITY_VPN));
+ toUidRangeStableParcels(uids), PREFERENCE_ORDER_VPN));
verify(mMockNetd, never()).networkRemoveUidRangesParcel(argThat(config ->
mMockVpn.getNetwork().getNetId() == config.netId
- && PREFERENCE_PRIORITY_VPN == config.subPriority));
+ && PREFERENCE_ORDER_VPN == config.subPriority));
mAgentRegistered = true;
verify(mMockNetd).networkCreate(nativeNetworkConfigVpn(getNetwork().netId,
!mMockNetworkAgent.isBypassableVpn(), mVpnType));
@@ -1530,7 +1563,7 @@
}
private <T> T doAsUid(final int uid, @NonNull final Supplier<T> what) {
- when(mDeps.getCallingUid()).thenReturn(uid);
+ doReturn(uid).when(mDeps).getCallingUid();
try {
return what.get();
} finally {
@@ -1564,15 +1597,21 @@
}
private void withPermission(String permission, ExceptionalRunnable r) throws Exception {
- if (mServiceContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
- r.run();
- return;
- }
try {
mServiceContext.setPermission(permission, PERMISSION_GRANTED);
r.run();
} finally {
- mServiceContext.setPermission(permission, PERMISSION_DENIED);
+ mServiceContext.setPermission(permission, null);
+ }
+ }
+
+ private void withPermission(String permission, int pid, int uid, ExceptionalRunnable r)
+ throws Exception {
+ try {
+ mServiceContext.setPermission(permission, pid, uid, PERMISSION_GRANTED);
+ r.run();
+ } finally {
+ mServiceContext.setPermission(permission, pid, uid, null);
}
}
@@ -1605,9 +1644,8 @@
MockitoAnnotations.initMocks(this);
- when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO));
- when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
- Arrays.asList(PRIMARY_USER_HANDLE));
+ when(mUserManager.getAliveUsers()).thenReturn(asList(PRIMARY_USER_INFO));
+ when(mUserManager.getUserHandles(anyBoolean())).thenReturn(asList(PRIMARY_USER_HANDLE));
when(mUserManager.getUserInfo(PRIMARY_USER)).thenReturn(PRIMARY_USER_INFO);
// canHaveRestrictedProfile does not take a userId. It applies to the userId of the context
// it was started from, i.e., PRIMARY_USER.
@@ -1815,7 +1853,7 @@
eq(UserHandle.getCallingUserId()))).thenReturn(myPackageInfo);
when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
- Arrays.asList(new PackageInfo[] {
+ asList(new PackageInfo[] {
buildPackageInfo(/* SYSTEM */ false, APP1_UID),
buildPackageInfo(/* SYSTEM */ false, APP2_UID),
buildPackageInfo(/* SYSTEM */ false, VPN_UID)
@@ -1832,7 +1870,7 @@
ResolveInfo rInfo = new ResolveInfo();
rInfo.serviceInfo = new ServiceInfo();
rInfo.serviceInfo.metaData = new Bundle();
- final List<ResolveInfo> services = Arrays.asList(new ResolveInfo[]{rInfo});
+ final List<ResolveInfo> services = asList(new ResolveInfo[]{rInfo});
when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA),
eq(userId))).thenReturn(services);
when(mPackageManager.getPackageUidAsUser(TEST_PACKAGE_NAME, userId))
@@ -2171,6 +2209,46 @@
}
@Test
+ public void testBinderDeathAfterUnregister() throws Exception {
+ final NetworkCapabilities caps = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .build();
+ final Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
+ final Messenger messenger = new Messenger(handler);
+ final CompletableFuture<Binder.DeathRecipient> deathRecipient = new CompletableFuture<>();
+ final Binder binder = new Binder() {
+ private DeathRecipient mDeathRecipient;
+ @Override
+ public void linkToDeath(@NonNull final DeathRecipient recipient, final int flags) {
+ synchronized (this) {
+ mDeathRecipient = recipient;
+ }
+ super.linkToDeath(recipient, flags);
+ deathRecipient.complete(recipient);
+ }
+
+ @Override
+ public boolean unlinkToDeath(@NonNull final DeathRecipient recipient, final int flags) {
+ synchronized (this) {
+ if (null == mDeathRecipient) {
+ throw new IllegalStateException();
+ }
+ mDeathRecipient = null;
+ }
+ return super.unlinkToDeath(recipient, flags);
+ }
+ };
+ final NetworkRequest request = mService.listenForNetwork(caps, messenger, binder,
+ NetworkCallback.FLAG_NONE, mContext.getOpPackageName(),
+ mContext.getAttributionTag());
+ mService.releaseNetworkRequest(request);
+ deathRecipient.get().binderDied();
+ // Wait for the release message to be processed.
+ waitForIdle();
+ // After waitForIdle(), the message was processed and the service didn't crash.
+ }
+
+ @Test
public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
// Test bringing up unvalidated WiFi
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
@@ -4719,7 +4797,6 @@
testAvoidBadWifiConfig_controlledBySettings();
}
- @Ignore("Refactoring in progress b/178071397")
@Test
public void testAvoidBadWifi() throws Exception {
final ContentResolver cr = mServiceContext.getContentResolver();
@@ -4849,8 +4926,8 @@
final ContentResolver cr = mServiceContext.getContentResolver();
final String settingName = ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE;
- for (int config : Arrays.asList(0, 3, 2)) {
- for (String setting: Arrays.asList(null, "0", "2", "1")) {
+ for (int config : asList(0, 3, 2)) {
+ for (String setting: asList(null, "0", "2", "1")) {
mPolicyTracker.mConfigMeteredMultipathPreference = config;
Settings.Global.putString(cr, settingName, setting);
mPolicyTracker.reevaluate();
@@ -6009,10 +6086,10 @@
networkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, networkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent);
networkCallback.assertNoCallback();
- checkDirectlyConnectedRoutes(cbi.getLp(), Arrays.asList(myIpv4Address),
- Arrays.asList(myIpv4DefaultRoute));
+ checkDirectlyConnectedRoutes(cbi.getLp(), asList(myIpv4Address),
+ asList(myIpv4DefaultRoute));
checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()),
- Arrays.asList(myIpv4Address), Arrays.asList(myIpv4DefaultRoute));
+ asList(myIpv4Address), asList(myIpv4DefaultRoute));
// Verify direct routes are added during subsequent link properties updates.
LinkProperties newLp = new LinkProperties(lp);
@@ -6024,8 +6101,8 @@
cbi = networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, networkAgent);
networkCallback.assertNoCallback();
checkDirectlyConnectedRoutes(cbi.getLp(),
- Arrays.asList(myIpv4Address, myIpv6Address1, myIpv6Address2),
- Arrays.asList(myIpv4DefaultRoute));
+ asList(myIpv4Address, myIpv6Address1, myIpv6Address2),
+ asList(myIpv4DefaultRoute));
mCm.unregisterNetworkCallback(networkCallback);
}
@@ -6353,9 +6430,9 @@
mResolverParamsParcelCaptor.capture());
ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
assertEquals(1, resolvrParams.servers.length);
- assertTrue(ArrayUtils.contains(resolvrParams.servers, "2001:db8::1"));
+ assertTrue(CollectionUtils.contains(resolvrParams.servers, "2001:db8::1"));
// Opportunistic mode.
- assertTrue(ArrayUtils.contains(resolvrParams.tlsServers, "2001:db8::1"));
+ assertTrue(CollectionUtils.contains(resolvrParams.tlsServers, "2001:db8::1"));
reset(mMockDnsResolver);
cellLp.addDnsServer(InetAddress.getByName("192.0.2.1"));
@@ -6365,12 +6442,12 @@
mResolverParamsParcelCaptor.capture());
resolvrParams = mResolverParamsParcelCaptor.getValue();
assertEquals(2, resolvrParams.servers.length);
- assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
- new String[]{"2001:db8::1", "192.0.2.1"}));
+ assertTrue(new ArraySet<>(resolvrParams.servers).containsAll(
+ asList("2001:db8::1", "192.0.2.1")));
// Opportunistic mode.
assertEquals(2, resolvrParams.tlsServers.length);
- assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
- new String[]{"2001:db8::1", "192.0.2.1"}));
+ assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll(
+ asList("2001:db8::1", "192.0.2.1")));
reset(mMockDnsResolver);
final String TLS_SPECIFIER = "tls.example.com";
@@ -6385,8 +6462,8 @@
mResolverParamsParcelCaptor.capture());
resolvrParams = mResolverParamsParcelCaptor.getValue();
assertEquals(2, resolvrParams.servers.length);
- assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
- new String[]{"2001:db8::1", "192.0.2.1"}));
+ assertTrue(new ArraySet<>(resolvrParams.servers).containsAll(
+ asList("2001:db8::1", "192.0.2.1")));
reset(mMockDnsResolver);
}
@@ -6493,12 +6570,12 @@
mResolverParamsParcelCaptor.capture());
ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
assertEquals(2, resolvrParams.tlsServers.length);
- assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
- new String[] { "2001:db8::1", "192.0.2.1" }));
+ assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll(
+ asList("2001:db8::1", "192.0.2.1")));
// Opportunistic mode.
assertEquals(2, resolvrParams.tlsServers.length);
- assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
- new String[] { "2001:db8::1", "192.0.2.1" }));
+ assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll(
+ asList("2001:db8::1", "192.0.2.1")));
reset(mMockDnsResolver);
cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED,
@@ -6515,8 +6592,8 @@
mResolverParamsParcelCaptor.capture());
resolvrParams = mResolverParamsParcelCaptor.getValue();
assertEquals(2, resolvrParams.servers.length);
- assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
- new String[] { "2001:db8::1", "192.0.2.1" }));
+ assertTrue(new ArraySet<>(resolvrParams.servers).containsAll(
+ asList("2001:db8::1", "192.0.2.1")));
reset(mMockDnsResolver);
cellNetworkCallback.assertNoCallback();
@@ -6525,11 +6602,11 @@
mResolverParamsParcelCaptor.capture());
resolvrParams = mResolverParamsParcelCaptor.getValue();
assertEquals(2, resolvrParams.servers.length);
- assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
- new String[] { "2001:db8::1", "192.0.2.1" }));
+ assertTrue(new ArraySet<>(resolvrParams.servers).containsAll(
+ asList("2001:db8::1", "192.0.2.1")));
assertEquals(2, resolvrParams.tlsServers.length);
- assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
- new String[] { "2001:db8::1", "192.0.2.1" }));
+ assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll(
+ asList("2001:db8::1", "192.0.2.1")));
reset(mMockDnsResolver);
cellNetworkCallback.assertNoCallback();
@@ -7565,7 +7642,7 @@
// Start the restricted profile, and check that the UID within it loses network access.
when(mPackageManager.getPackageUidAsUser(ALWAYS_ON_PACKAGE, RESTRICTED_USER))
.thenReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID));
- when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO,
+ when(mUserManager.getAliveUsers()).thenReturn(asList(PRIMARY_USER_INFO,
RESTRICTED_USER_INFO));
// TODO: check that VPN app within restricted profile still has access, etc.
final Intent addedIntent = new Intent(ACTION_USER_ADDED);
@@ -7576,7 +7653,7 @@
assertNull(mCm.getActiveNetworkForUid(restrictedUid));
// Stop the restricted profile, and check that the UID within it has network access again.
- when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO));
+ when(mUserManager.getAliveUsers()).thenReturn(asList(PRIMARY_USER_INFO));
// Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
@@ -8001,7 +8078,7 @@
// networks, ConnectivityService does not guarantee the order in which callbacks are fired.
private void assertBlockedCallbackInAnyOrder(TestNetworkCallback callback, boolean blocked,
TestNetworkAgentWrapper... agents) {
- final List<Network> expectedNetworks = Arrays.asList(agents).stream()
+ final List<Network> expectedNetworks = asList(agents).stream()
.map((agent) -> agent.getNetwork())
.collect(Collectors.toList());
@@ -8697,7 +8774,7 @@
mResolverParamsParcelCaptor.capture());
ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
assertEquals(1, resolvrParams.servers.length);
- assertTrue(ArrayUtils.contains(resolvrParams.servers, "8.8.8.8"));
+ assertTrue(CollectionUtils.contains(resolvrParams.servers, "8.8.8.8"));
for (final LinkProperties stackedLp : stackedLpsAfterChange) {
verify(mDeps).reportNetworkInterfaceForTransports(
@@ -9370,7 +9447,7 @@
InOrder inOrder = inOrder(mMockNetd);
// Update to new range which is old range minus APP1, i.e. only APP2
- final Set<UidRange> newRanges = new HashSet<>(Arrays.asList(
+ final Set<UidRange> newRanges = new HashSet<>(asList(
new UidRange(vpnRange.start, APP1_UID - 1),
new UidRange(APP1_UID + 1, vpnRange.stop)));
mMockVpn.setUids(newRanges);
@@ -9862,9 +9939,9 @@
assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
final UnderlyingNetworkInfo underlyingNetworkInfo =
- new UnderlyingNetworkInfo(vpnOwnerUid, VPN_IFNAME, new ArrayList<String>());
+ new UnderlyingNetworkInfo(vpnOwnerUid, VPN_IFNAME, new ArrayList<>());
mMockVpn.setUnderlyingNetworkInfo(underlyingNetworkInfo);
- when(mDeps.getConnectionOwnerUid(anyInt(), any(), any())).thenReturn(42);
+ doReturn(42).when(mDeps).getConnectionOwnerUid(anyInt(), any(), any());
}
private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
@@ -10285,13 +10362,13 @@
}
private boolean areConnDiagCapsRedacted(NetworkCapabilities nc) {
- TestTransportInfo ti = (TestTransportInfo) nc.getTransportInfo();
+ TestTransportInfo ti = getTestTransportInfo(nc);
return nc.getUids() == null
&& nc.getAdministratorUids().length == 0
&& nc.getOwnerUid() == Process.INVALID_UID
- && getTestTransportInfo(nc).locationRedacted
- && getTestTransportInfo(nc).localMacAddressRedacted
- && getTestTransportInfo(nc).settingsRedacted;
+ && ti.locationRedacted
+ && ti.localMacAddressRedacted
+ && ti.settingsRedacted;
}
@Test
@@ -10527,11 +10604,11 @@
if (add) {
inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(
new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(),
- toUidRangeStableParcels(vpnRanges), PREFERENCE_PRIORITY_VPN));
+ toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN));
} else {
inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(
new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(),
- toUidRangeStableParcels(vpnRanges), PREFERENCE_PRIORITY_VPN));
+ toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN));
}
inOrder.verify(mMockNetd, times(1)).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)),
@@ -10559,7 +10636,7 @@
verify(mProxyTracker, never()).sendProxyBroadcast();
// Update to new range which is old range minus APP1, i.e. only APP2
- final Set<UidRange> newRanges = new HashSet<>(Arrays.asList(
+ final Set<UidRange> newRanges = new HashSet<>(asList(
new UidRange(vpnRange.start, APP1_UID - 1),
new UidRange(APP1_UID + 1, vpnRange.stop)));
mMockVpn.setUids(newRanges);
@@ -11005,7 +11082,7 @@
.createNrisFromOemNetworkPreferences(
createDefaultOemNetworkPreferences(prefToTest));
final NetworkRequestInfo nri = nris.iterator().next();
- assertEquals(PREFERENCE_PRIORITY_OEM, nri.mPreferencePriority);
+ assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder);
final List<NetworkRequest> mRequests = nri.mRequests;
assertEquals(expectedNumOfNris, nris.size());
assertEquals(expectedNumOfRequests, mRequests.size());
@@ -11035,7 +11112,7 @@
.createNrisFromOemNetworkPreferences(
createDefaultOemNetworkPreferences(prefToTest));
final NetworkRequestInfo nri = nris.iterator().next();
- assertEquals(PREFERENCE_PRIORITY_OEM, nri.mPreferencePriority);
+ assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder);
final List<NetworkRequest> mRequests = nri.mRequests;
assertEquals(expectedNumOfNris, nris.size());
assertEquals(expectedNumOfRequests, mRequests.size());
@@ -11062,7 +11139,7 @@
.createNrisFromOemNetworkPreferences(
createDefaultOemNetworkPreferences(prefToTest));
final NetworkRequestInfo nri = nris.iterator().next();
- assertEquals(PREFERENCE_PRIORITY_OEM, nri.mPreferencePriority);
+ assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder);
final List<NetworkRequest> mRequests = nri.mRequests;
assertEquals(expectedNumOfNris, nris.size());
assertEquals(expectedNumOfRequests, mRequests.size());
@@ -11086,7 +11163,7 @@
.createNrisFromOemNetworkPreferences(
createDefaultOemNetworkPreferences(prefToTest));
final NetworkRequestInfo nri = nris.iterator().next();
- assertEquals(PREFERENCE_PRIORITY_OEM, nri.mPreferencePriority);
+ assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder);
final List<NetworkRequest> mRequests = nri.mRequests;
assertEquals(expectedNumOfNris, nris.size());
assertEquals(expectedNumOfRequests, mRequests.size());
@@ -11160,7 +11237,7 @@
final int secondUserTestPackageUid = UserHandle.getUid(SECONDARY_USER, TEST_PACKAGE_UID);
final int thirdUserTestPackageUid = UserHandle.getUid(TERTIARY_USER, TEST_PACKAGE_UID);
when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
- Arrays.asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE, TERTIARY_USER_HANDLE));
+ asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE, TERTIARY_USER_HANDLE));
// Arrange PackageManager mocks testing for users who have and don't have a package.
mockGetApplicationInfoThrowsNameNotFound(TEST_PACKAGE_NAME, PRIMARY_USER_HANDLE);
@@ -11777,11 +11854,11 @@
verify(mMockNetd, times(addUidRangesTimes)).networkAddUidRangesParcel(argThat(config ->
(useAnyIdForAdd ? true : addUidRangesNetId == config.netId)
&& Arrays.equals(addedUidRanges, config.uidRanges)
- && PREFERENCE_PRIORITY_OEM == config.subPriority));
+ && PREFERENCE_ORDER_OEM == config.subPriority));
verify(mMockNetd, times(removeUidRangesTimes)).networkRemoveUidRangesParcel(
argThat(config -> (useAnyIdForRemove ? true : removeUidRangesNetId == config.netId)
&& Arrays.equals(removedUidRanges, config.uidRanges)
- && PREFERENCE_PRIORITY_OEM == config.subPriority));
+ && PREFERENCE_ORDER_OEM == config.subPriority));
if (shouldDestroyNetwork) {
verify(mMockNetd, times(1))
.networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId)));
@@ -12107,7 +12184,7 @@
final int secondUser = 10;
final UserHandle secondUserHandle = new UserHandle(secondUser);
when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
- Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle));
+ asList(PRIMARY_USER_HANDLE, secondUserHandle));
// Arrange PackageManager mocks
final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
@@ -12148,7 +12225,7 @@
final int secondUser = 10;
final UserHandle secondUserHandle = new UserHandle(secondUser);
when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
- Arrays.asList(PRIMARY_USER_HANDLE));
+ asList(PRIMARY_USER_HANDLE));
// Arrange PackageManager mocks
final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
@@ -12176,7 +12253,7 @@
// Send a broadcast indicating a user was added.
when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
- Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle));
+ asList(PRIMARY_USER_HANDLE, secondUserHandle));
final Intent addedIntent = new Intent(ACTION_USER_ADDED);
addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser));
processBroadcast(addedIntent);
@@ -12189,7 +12266,7 @@
// Send a broadcast indicating a user was removed.
when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
- Arrays.asList(PRIMARY_USER_HANDLE));
+ asList(PRIMARY_USER_HANDLE));
final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser));
processBroadcast(removedIntent);
@@ -12936,7 +13013,7 @@
// is not handled specially, the rules are always active as long as a preference is set.
inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle),
- PREFERENCE_PRIORITY_PROFILE));
+ PREFERENCE_ORDER_PROFILE));
// The enterprise network is not ready yet.
assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback,
@@ -12951,11 +13028,10 @@
inOrder.verify(mMockNetd).networkCreate(
nativeNetworkConfigPhysical(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM));
inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
- workAgent.getNetwork().netId, uidRangeFor(testHandle),
- PREFERENCE_PRIORITY_PROFILE));
+ workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE));
inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig(
mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle),
- PREFERENCE_PRIORITY_PROFILE));
+ PREFERENCE_ORDER_PROFILE));
// Make sure changes to the work agent send callbacks to the app in the work profile, but
// not to the other apps.
@@ -13005,7 +13081,7 @@
assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback);
inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle),
- PREFERENCE_PRIORITY_PROFILE));
+ PREFERENCE_ORDER_PROFILE));
inOrder.verify(mMockNetd).networkDestroy(workAgent.getNetwork().netId);
mCellNetworkAgent.disconnect();
@@ -13029,8 +13105,7 @@
inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical(
workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM));
inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
- workAgent2.getNetwork().netId, uidRangeFor(testHandle),
- PREFERENCE_PRIORITY_PROFILE));
+ workAgent2.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE));
workAgent2.setNetworkValid(true /* isStrictMode */);
workAgent2.mNetworkMonitor.forceReevaluation(Process.myUid());
@@ -13076,8 +13151,7 @@
inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical(
mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE));
inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
- workAgent.getNetwork().netId, uidRangeFor(testHandle),
- PREFERENCE_PRIORITY_PROFILE));
+ workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE));
registerDefaultNetworkCallbacks();
@@ -13092,8 +13166,7 @@
mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback);
inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig(
- workAgent.getNetwork().netId, uidRangeFor(testHandle),
- PREFERENCE_PRIORITY_PROFILE));
+ workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE));
workAgent.disconnect();
mCellNetworkAgent.disconnect();
@@ -13138,8 +13211,7 @@
r -> r.run(), listener);
listener.expectOnComplete();
inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
- workAgent.getNetwork().netId, uidRangeFor(testHandle2),
- PREFERENCE_PRIORITY_PROFILE));
+ workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE));
mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent);
assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback,
@@ -13149,8 +13221,7 @@
r -> r.run(), listener);
listener.expectOnComplete();
inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
- workAgent.getNetwork().netId, uidRangeFor(testHandle4),
- PREFERENCE_PRIORITY_PROFILE));
+ workAgent.getNetwork().netId, uidRangeFor(testHandle4), PREFERENCE_ORDER_PROFILE));
app4Cb.expectAvailableCallbacksValidated(workAgent);
assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback,
@@ -13160,8 +13231,7 @@
r -> r.run(), listener);
listener.expectOnComplete();
inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig(
- workAgent.getNetwork().netId, uidRangeFor(testHandle2),
- PREFERENCE_PRIORITY_PROFILE));
+ workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE));
mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback,
@@ -13190,7 +13260,7 @@
mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE));
inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle),
- PREFERENCE_PRIORITY_PROFILE));
+ PREFERENCE_ORDER_PROFILE));
final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
removedIntent.putExtra(Intent.EXTRA_USER, testHandle);
@@ -13198,7 +13268,7 @@
inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig(
mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle),
- PREFERENCE_PRIORITY_PROFILE));
+ PREFERENCE_ORDER_PROFILE));
}
/**
@@ -13298,17 +13368,45 @@
@Test
public void testProfileNetworkPrefCountsRequestsCorrectlyOnSet() throws Exception {
final UserHandle testHandle = setupEnterpriseNetwork();
- testRequestCountLimits(() -> {
- // Set initially to test the limit prior to having existing requests.
- final TestOnCompleteListener listener = new TestOnCompleteListener();
- mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE,
- Runnable::run, listener);
+ final TestOnCompleteListener listener = new TestOnCompleteListener();
+ // Leave one request available so the profile preference can be set.
+ testRequestCountLimits(1 /* countToLeaveAvailable */, () -> {
+ withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ Process.myPid(), Process.myUid(), () -> {
+ // Set initially to test the limit prior to having existing requests.
+ mCm.setProfileNetworkPreference(testHandle,
+ PROFILE_NETWORK_PREFERENCE_ENTERPRISE,
+ Runnable::run, listener);
+ });
listener.expectOnComplete();
- // re-set so as to test the limit as part of replacing existing requests.
- mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE,
- Runnable::run, listener);
+ // Simulate filing requests as some app on the work profile
+ final int otherAppUid = UserHandle.getUid(TEST_WORK_PROFILE_USER_ID,
+ UserHandle.getAppId(Process.myUid() + 1));
+ final int remainingCount = ConnectivityService.MAX_NETWORK_REQUESTS_PER_UID
+ - mService.mNetworkRequestCounter.mUidToNetworkRequestCount.get(otherAppUid)
+ - 1;
+ final NetworkCallback[] callbacks = new NetworkCallback[remainingCount];
+ doAsUid(otherAppUid, () -> {
+ for (int i = 0; i < remainingCount; ++i) {
+ callbacks[i] = new TestableNetworkCallback();
+ mCm.registerDefaultNetworkCallback(callbacks[i]);
+ }
+ });
+
+ withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ Process.myPid(), Process.myUid(), () -> {
+ // re-set so as to test the limit as part of replacing existing requests.
+ mCm.setProfileNetworkPreference(testHandle,
+ PROFILE_NETWORK_PREFERENCE_ENTERPRISE, Runnable::run, listener);
+ });
listener.expectOnComplete();
+
+ doAsUid(otherAppUid, () -> {
+ for (final NetworkCallback callback : callbacks) {
+ mCm.unregisterNetworkCallback(callback);
+ }
+ });
});
}
@@ -13320,39 +13418,45 @@
mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true);
@OemNetworkPreferences.OemNetworkPreference final int networkPref =
OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
- testRequestCountLimits(() -> {
- // Set initially to test the limit prior to having existing requests.
- final TestOemListenerCallback listener = new TestOemListenerCallback();
- mService.setOemNetworkPreference(
- createDefaultOemNetworkPreferences(networkPref), listener);
- listener.expectOnComplete();
+ // Leave one request available so the OEM preference can be set.
+ testRequestCountLimits(1 /* countToLeaveAvailable */, () ->
+ withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> {
+ // Set initially to test the limit prior to having existing requests.
+ final TestOemListenerCallback listener = new TestOemListenerCallback();
+ mService.setOemNetworkPreference(
+ createDefaultOemNetworkPreferences(networkPref), listener);
+ listener.expectOnComplete();
- // re-set so as to test the limit as part of replacing existing requests.
- mService.setOemNetworkPreference(
- createDefaultOemNetworkPreferences(networkPref), listener);
- listener.expectOnComplete();
- });
+ // re-set so as to test the limit as part of replacing existing requests.
+ mService.setOemNetworkPreference(
+ createDefaultOemNetworkPreferences(networkPref), listener);
+ listener.expectOnComplete();
+ }));
}
- private void testRequestCountLimits(@NonNull final Runnable r) throws Exception {
+ private void testRequestCountLimits(final int countToLeaveAvailable,
+ @NonNull final ExceptionalRunnable r) throws Exception {
final ArraySet<TestNetworkCallback> callbacks = new ArraySet<>();
try {
final int requestCount = mService.mSystemNetworkRequestCounter
.mUidToNetworkRequestCount.get(Process.myUid());
- // The limit is hit when total requests <= limit.
- final int maxCount =
- ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - requestCount;
+ // The limit is hit when total requests = limit - 1, and exceeded with a crash when
+ // total requests >= limit.
+ final int countToFile =
+ MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - requestCount - countToLeaveAvailable;
// Need permission so registerDefaultNetworkCallback uses mSystemNetworkRequestCounter
withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> {
- for (int i = 1; i < maxCount - 1; i++) {
+ for (int i = 1; i < countToFile; i++) {
final TestNetworkCallback cb = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(cb);
callbacks.add(cb);
}
-
- // Code to run to check if it triggers a max request count limit error.
- r.run();
+ assertEquals(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1 - countToLeaveAvailable,
+ mService.mSystemNetworkRequestCounter
+ .mUidToNetworkRequestCount.get(Process.myUid()));
});
+ // Code to run to check if it triggers a max request count limit error.
+ r.run();
} finally {
for (final TestNetworkCallback cb : callbacks) {
mCm.unregisterNetworkCallback(cb);
@@ -13369,7 +13473,7 @@
assertEquals(1, nris.size());
assertTrue(nri.isMultilayerRequest());
assertEquals(nri.getUids(), uidRangesForUids(uids));
- assertEquals(PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED, nri.mPreferencePriority);
+ assertEquals(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED, nri.mPreferenceOrder);
}
/**
@@ -13421,7 +13525,7 @@
final Set<Integer> uids1 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID));
final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1));
final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1,
- PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED);
+ PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
setAndUpdateMobileDataPreferredUids(uids1);
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1);
inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any());
@@ -13433,7 +13537,7 @@
SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID));
final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2));
final NativeUidRangeConfig config2 = new NativeUidRangeConfig(cellNetId, uidRanges2,
- PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED);
+ PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
setAndUpdateMobileDataPreferredUids(uids2);
inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1);
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config2);
@@ -13481,7 +13585,7 @@
final Set<Integer> uids = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID));
final UidRangeParcel[] uidRanges = toUidRangeStableParcels(uidRangesForUids(uids));
final NativeUidRangeConfig wifiConfig = new NativeUidRangeConfig(wifiNetId, uidRanges,
- PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED);
+ PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
setAndUpdateMobileDataPreferredUids(uids);
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig);
inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any());
@@ -13497,7 +13601,7 @@
final int cellNetId = mCellNetworkAgent.getNetwork().netId;
final NativeUidRangeConfig cellConfig = new NativeUidRangeConfig(cellNetId, uidRanges,
- PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED);
+ PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(
cellNetId, INetd.PERMISSION_NONE));
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig);
@@ -13526,7 +13630,7 @@
final int cellNetId2 = mCellNetworkAgent.getNetwork().netId;
final NativeUidRangeConfig cellConfig2 = new NativeUidRangeConfig(cellNetId2, uidRanges,
- PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED);
+ PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(
cellNetId2, INetd.PERMISSION_NONE));
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig2);
@@ -13597,15 +13701,18 @@
public void testMobileDataPreferredUidsChangedCountsRequestsCorrectlyOnSet() throws Exception {
ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext,
Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)));
- testRequestCountLimits(() -> {
- // Set initially to test the limit prior to having existing requests.
- mService.updateMobileDataPreferredUids();
- waitForIdle();
+ // Leave one request available so MDO preference set up above can be set.
+ testRequestCountLimits(1 /* countToLeaveAvailable */, () ->
+ withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ Process.myPid(), Process.myUid(), () -> {
+ // Set initially to test the limit prior to having existing requests.
+ mService.updateMobileDataPreferredUids();
+ waitForIdle();
- // re-set so as to test the limit as part of replacing existing requests.
- mService.updateMobileDataPreferredUids();
- waitForIdle();
- });
+ // re-set so as to test the limit as part of replacing existing requests
+ mService.updateMobileDataPreferredUids();
+ waitForIdle();
+ }));
}
@Test
@@ -13625,7 +13732,7 @@
final int[] uids1 = new int[] { PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) };
final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1));
final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1,
- PREFERENCE_PRIORITY_OEM);
+ PREFERENCE_ORDER_OEM);
setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME);
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1);
inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any());
@@ -13639,7 +13746,7 @@
r -> r.run(), listener);
listener.expectOnComplete();
final NativeUidRangeConfig config2 = new NativeUidRangeConfig(workAgent.getNetwork().netId,
- uidRangeFor(testHandle), PREFERENCE_PRIORITY_PROFILE);
+ uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE);
inorder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical(
workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM));
inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any());
@@ -13649,7 +13756,7 @@
final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2));
final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2));
final NativeUidRangeConfig config3 = new NativeUidRangeConfig(cellNetId, uidRanges2,
- PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED);
+ PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
setAndUpdateMobileDataPreferredUids(uids2);
inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any());
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config3);
@@ -13658,7 +13765,7 @@
final Set<Integer> uids3 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID3));
final UidRangeParcel[] uidRanges3 = toUidRangeStableParcels(uidRangesForUids(uids3));
final NativeUidRangeConfig config4 = new NativeUidRangeConfig(cellNetId, uidRanges3,
- PREFERENCE_PRIORITY_OEM);
+ PREFERENCE_ORDER_OEM);
setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges3, "com.android.test");
inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1);
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config4);
@@ -13672,7 +13779,7 @@
// Set MOBILE_DATA_PREFERRED_UIDS setting again with same uid as oem network preference.
final NativeUidRangeConfig config6 = new NativeUidRangeConfig(cellNetId, uidRanges3,
- PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED);
+ PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
setAndUpdateMobileDataPreferredUids(uids3);
inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config3);
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config6);
diff --git a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
index 9ef558f..24aecdb 100644
--- a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
@@ -43,6 +43,7 @@
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.net.ConnectivitySettingsManager;
import android.net.IDnsResolver;
@@ -106,8 +107,14 @@
@Mock IDnsResolver mMockDnsResolver;
private void assertResolverOptionsEquals(
- @NonNull ResolverOptionsParcel actual,
- @NonNull ResolverOptionsParcel expected) {
+ @Nullable ResolverOptionsParcel actual,
+ @Nullable ResolverOptionsParcel expected) {
+ if (actual == null) {
+ assertNull(expected);
+ return;
+ } else {
+ assertNotNull(expected);
+ }
assertEquals(actual.hosts, expected.hosts);
assertEquals(actual.tcMode, expected.tcMode);
assertEquals(actual.enforceDnsUid, expected.enforceDnsUid);
@@ -365,7 +372,7 @@
expectedParams.tlsName = "";
expectedParams.tlsServers = new String[]{"3.3.3.3", "4.4.4.4"};
expectedParams.transportTypes = TEST_TRANSPORT_TYPES;
- expectedParams.resolverOptions = new ResolverOptionsParcel();
+ expectedParams.resolverOptions = null;
assertResolverParamsEquals(actualParams, expectedParams);
}
diff --git a/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index 07deeef..2cf5d8e 100644
--- a/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -27,6 +27,7 @@
import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.SIGN_IN;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.clearInvocations;
@@ -39,9 +40,14 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
@@ -49,10 +55,19 @@
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.Build;
+import android.os.Bundle;
import android.os.UserHandle;
import android.telephony.TelephonyManager;
+import android.util.DisplayMetrics;
+import android.widget.TextView;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject;
+import androidx.test.uiautomator.UiSelector;
import com.android.connectivity.resources.R;
import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
@@ -83,6 +98,7 @@
private static final String TEST_EXTRA_INFO = "extra";
private static final int TEST_NOTIF_ID = 101;
private static final String TEST_NOTIF_TAG = NetworkNotificationManager.tagFor(TEST_NOTIF_ID);
+ private static final long TEST_TIMEOUT_MS = 10_000L;
static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities();
static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities();
static final NetworkCapabilities VPN_CAPABILITIES = new NetworkCapabilities();
@@ -101,8 +117,28 @@
VPN_CAPABILITIES.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
}
+ /**
+ * Test activity that shows the action it was started with on screen, and dismisses when the
+ * text is tapped.
+ */
+ public static class TestDialogActivity extends Activity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setTurnScreenOn(true);
+ getSystemService(KeyguardManager.class).requestDismissKeyguard(
+ this, null /* callback */);
+
+ final TextView txt = new TextView(this);
+ txt.setText(getIntent().getAction());
+ txt.setOnClickListener(e -> finish());
+ setContentView(txt);
+ }
+ }
+
@Mock Context mCtx;
@Mock Resources mResources;
+ @Mock DisplayMetrics mDisplayMetrics;
@Mock PackageManager mPm;
@Mock TelephonyManager mTelephonyManager;
@Mock NotificationManager mNotificationManager;
@@ -124,6 +160,7 @@
mCellNai.networkInfo = mNetworkInfo;
mVpnNai.networkCapabilities = VPN_CAPABILITIES;
mVpnNai.networkInfo = mNetworkInfo;
+ mDisplayMetrics.density = 2.275f;
doReturn(true).when(mVpnNai).isVPN();
when(mCtx.getResources()).thenReturn(mResources);
when(mCtx.getPackageManager()).thenReturn(mPm);
@@ -136,6 +173,7 @@
when(mNetworkInfo.getExtraInfo()).thenReturn(TEST_EXTRA_INFO);
ConnectivityResources.setResourcesContextForTest(mCtx);
when(mResources.getColor(anyInt(), any())).thenReturn(0xFF607D8B);
+ when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
// Come up with some credible-looking transport names. The actual values do not matter.
String[] transportNames = new String[NetworkCapabilities.MAX_TRANSPORT + 1];
@@ -341,4 +379,82 @@
mManager.clearNotification(id, PARTIAL_CONNECTIVITY);
verify(mNotificationManager, never()).cancel(eq(tag), eq(PARTIAL_CONNECTIVITY.eventId));
}
+
+ @Test
+ public void testNotifyNoInternetAsDialogWhenHighPriority() throws Exception {
+ doReturn(true).when(mResources).getBoolean(
+ R.bool.config_notifyNoInternetAsDialogWhenHighPriority);
+
+ mManager.showNotification(TEST_NOTIF_ID, NETWORK_SWITCH, mWifiNai, mCellNai, null, false);
+ // Non-"no internet" notifications are not affected
+ verify(mNotificationManager).notify(eq(TEST_NOTIF_TAG), eq(NETWORK_SWITCH.eventId), any());
+
+ final Instrumentation instr = InstrumentationRegistry.getInstrumentation();
+ final Context ctx = instr.getContext();
+ final String testAction = "com.android.connectivity.coverage.TEST_DIALOG";
+ final Intent intent = new Intent(testAction)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .setClassName(ctx.getPackageName(), TestDialogActivity.class.getName());
+ final PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0 /* requestCode */,
+ intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+
+ mManager.showNotification(TEST_NOTIF_ID, NO_INTERNET, mWifiNai, null /* switchToNai */,
+ pendingIntent, true /* highPriority */);
+
+ // Previous notifications are still dismissed
+ verify(mNotificationManager).cancel(TEST_NOTIF_TAG, NETWORK_SWITCH.eventId);
+
+ // Verify that the activity is shown (the activity shows the action on screen)
+ final UiObject actionText = UiDevice.getInstance(instr).findObject(
+ new UiSelector().text(testAction));
+ assertTrue("Activity not shown", actionText.waitForExists(TEST_TIMEOUT_MS));
+
+ // Tapping the text should dismiss the dialog
+ actionText.click();
+ assertTrue("Activity not dismissed", actionText.waitUntilGone(TEST_TIMEOUT_MS));
+
+ // Verify no NO_INTERNET notification was posted
+ verify(mNotificationManager, never()).notify(any(), eq(NO_INTERNET.eventId), any());
+ }
+
+ private void doNotificationTextTest(NotificationType type, @StringRes int expectedTitleRes,
+ String expectedTitleArg, @StringRes int expectedContentRes) {
+ final String expectedTitle = "title " + expectedTitleArg;
+ final String expectedContent = "expected content";
+ doReturn(expectedTitle).when(mResources).getString(expectedTitleRes, expectedTitleArg);
+ doReturn(expectedContent).when(mResources).getString(expectedContentRes);
+
+ mManager.showNotification(TEST_NOTIF_ID, type, mWifiNai, mCellNai, null, false);
+ final ArgumentCaptor<Notification> notifCap = ArgumentCaptor.forClass(Notification.class);
+
+ verify(mNotificationManager).notify(eq(TEST_NOTIF_TAG), eq(type.eventId),
+ notifCap.capture());
+ final Notification notif = notifCap.getValue();
+
+ assertEquals(expectedTitle, notif.extras.getString(Notification.EXTRA_TITLE));
+ assertEquals(expectedContent, notif.extras.getString(Notification.EXTRA_TEXT));
+ }
+
+ @Test
+ public void testNotificationText_NoInternet() {
+ doNotificationTextTest(NO_INTERNET,
+ R.string.wifi_no_internet, TEST_EXTRA_INFO,
+ R.string.wifi_no_internet_detailed);
+ }
+
+ @Test
+ public void testNotificationText_Partial() {
+ doNotificationTextTest(PARTIAL_CONNECTIVITY,
+ R.string.network_partial_connectivity, TEST_EXTRA_INFO,
+ R.string.network_partial_connectivity_detailed);
+ }
+
+ @Test
+ public void testNotificationText_PartialAsNoInternet() {
+ doReturn(true).when(mResources).getBoolean(
+ R.bool.config_partialConnectivityNotifiedAsNoInternet);
+ doNotificationTextTest(PARTIAL_CONNECTIVITY,
+ R.string.wifi_no_internet, TEST_EXTRA_INFO,
+ R.string.wifi_no_internet_detailed);
+ }
}
diff --git a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
index 8f46508..a9749c4 100644
--- a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -31,6 +31,11 @@
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.net.ConnectivitySettingsManager.UIDS_ALLOWED_ON_RESTRICTED_NETWORKS;
+import static android.net.INetd.PERMISSION_INTERNET;
+import static android.net.INetd.PERMISSION_NONE;
+import static android.net.INetd.PERMISSION_SYSTEM;
+import static android.net.INetd.PERMISSION_UNINSTALLED;
+import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.Process.SYSTEM_UID;
@@ -123,6 +128,8 @@
private static final String PARTITION_VENDOR = "vendor";
private static final int VERSION_P = Build.VERSION_CODES.P;
private static final int VERSION_Q = Build.VERSION_CODES.Q;
+ private static final int PERMISSION_TRAFFIC_ALL =
+ PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS;
@Mock private Context mContext;
@Mock private PackageManager mPackageManager;
@@ -132,6 +139,7 @@
@Mock private SystemConfigManager mSystemConfigManager;
private PermissionMonitor mPermissionMonitor;
+ private NetdMonitor mNetdMonitor;
@Before
public void setUp() throws Exception {
@@ -155,6 +163,7 @@
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
+ mNetdMonitor = new NetdMonitor(mNetdService);
when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(/* empty app list */ null);
mPermissionMonitor.startMonitoring();
@@ -460,25 +469,26 @@
}
private class NetdMonitor {
- private final HashMap<Integer, Boolean> mApps = new HashMap<>();
+ private final HashMap<Integer, Boolean> mUidsNetworkPermission = new HashMap<>();
+ private final HashMap<Integer, Integer> mAppIdsTrafficPermission = new HashMap<>();
NetdMonitor(INetd mockNetd) throws Exception {
- // Add hook to verify and track result of setPermission.
+ // Add hook to verify and track result of networkSetPermission.
doAnswer((InvocationOnMock invocation) -> {
final Object[] args = invocation.getArguments();
- final Boolean isSystem = args[0].equals(INetd.PERMISSION_SYSTEM);
+ final Boolean isSystem = args[0].equals(PERMISSION_SYSTEM);
for (final int uid : (int[]) args[1]) {
// TODO: Currently, permission monitor will send duplicate commands for each uid
// corresponding to each user. Need to fix that and uncomment below test.
// if (mApps.containsKey(uid) && mApps.get(uid) == isSystem) {
// fail("uid " + uid + " is already set to " + isSystem);
// }
- mApps.put(uid, isSystem);
+ mUidsNetworkPermission.put(uid, isSystem);
}
return null;
}).when(mockNetd).networkSetPermissionForUser(anyInt(), any(int[].class));
- // Add hook to verify and track result of clearPermission.
+ // Add hook to verify and track result of networkClearPermission.
doAnswer((InvocationOnMock invocation) -> {
final Object[] args = invocation.getArguments();
for (final int uid : (int[]) args[0]) {
@@ -487,42 +497,62 @@
// if (!mApps.containsKey(uid)) {
// fail("uid " + uid + " does not exist.");
// }
- mApps.remove(uid);
+ mUidsNetworkPermission.remove(uid);
}
return null;
}).when(mockNetd).networkClearPermissionForUser(any(int[].class));
+
+ // Add hook to verify and track result of trafficSetNetPerm.
+ doAnswer((InvocationOnMock invocation) -> {
+ final Object[] args = invocation.getArguments();
+ final int permission = (int) args[0];
+ for (final int appId : (int[]) args[1]) {
+ mAppIdsTrafficPermission.put(appId, permission);
+ }
+ return null;
+ }).when(mockNetd).trafficSetNetPermForUids(anyInt(), any(int[].class));
}
- public void expectPermission(Boolean permission, UserHandle[] users, int[] apps) {
+ public void expectNetworkPerm(Boolean permission, UserHandle[] users, int... appIds) {
for (final UserHandle user : users) {
- for (final int app : apps) {
- final int uid = user.getUid(app);
- if (!mApps.containsKey(uid)) {
+ for (final int appId : appIds) {
+ final int uid = user.getUid(appId);
+ if (!mUidsNetworkPermission.containsKey(uid)) {
fail("uid " + uid + " does not exist.");
}
- if (mApps.get(uid) != permission) {
+ if (mUidsNetworkPermission.get(uid) != permission) {
fail("uid " + uid + " has wrong permission: " + permission);
}
}
}
}
- public void expectNoPermission(UserHandle[] users, int[] apps) {
+ public void expectNoNetworkPerm(UserHandle[] users, int... appIds) {
for (final UserHandle user : users) {
- for (final int app : apps) {
- final int uid = user.getUid(app);
- if (mApps.containsKey(uid)) {
+ for (final int appId : appIds) {
+ final int uid = user.getUid(appId);
+ if (mUidsNetworkPermission.containsKey(uid)) {
fail("uid " + uid + " has listed permissions, expected none.");
}
}
}
}
+
+ public void expectTrafficPerm(int permission, int... appIds) {
+ for (final int appId : appIds) {
+ if (!mAppIdsTrafficPermission.containsKey(appId)) {
+ fail("appId " + appId + " does not exist.");
+ }
+ if (mAppIdsTrafficPermission.get(appId) != permission) {
+ fail("appId " + appId + " has wrong permission: "
+ + mAppIdsTrafficPermission.get(appId));
+ }
+ }
+ }
}
@Test
public void testUserAndPackageAddRemove() throws Exception {
- final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
-
// MOCK_UID1: MOCK_PACKAGE1 only has network permission.
// SYSTEM_UID: SYSTEM_PACKAGE1 has system permission.
// SYSTEM_UID: SYSTEM_PACKAGE2 only has network permission.
@@ -537,15 +567,15 @@
// Add SYSTEM_PACKAGE2, expect only have network permission.
mPermissionMonitor.onUserAdded(MOCK_USER1);
addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE2, SYSTEM_UID);
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID});
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER1}, SYSTEM_UID);
// Add SYSTEM_PACKAGE1, expect permission escalate.
addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE1, SYSTEM_UID);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1}, SYSTEM_UID);
mPermissionMonitor.onUserAdded(MOCK_USER2);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
- new int[]{SYSTEM_UID});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ SYSTEM_UID);
// Remove SYSTEM_PACKAGE2, expect keep system permission.
when(mPackageManager.getPackagesForUid(MOCK_USER1.getUid(SYSTEM_UID)))
@@ -554,19 +584,19 @@
.thenReturn(new String[]{SYSTEM_PACKAGE1});
removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2},
SYSTEM_PACKAGE2, SYSTEM_UID);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
- new int[]{SYSTEM_UID});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ SYSTEM_UID);
// Add SYSTEM_PACKAGE2, expect keep system permission.
addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_PACKAGE2, SYSTEM_UID);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
- new int[]{SYSTEM_UID});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ SYSTEM_UID);
addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
- new int[]{SYSTEM_UID});
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
- new int[]{MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ SYSTEM_UID);
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ MOCK_UID1);
// Remove MOCK_UID1, expect no permission left for all user.
when(mPackageManager.getPackagesForUid(MOCK_USER1.getUid(MOCK_UID1)))
@@ -575,29 +605,28 @@
.thenReturn(new String[]{});
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
- netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
- new int[]{MOCK_UID1});
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_UID1);
// Remove SYSTEM_PACKAGE1, expect permission downgrade.
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{SYSTEM_PACKAGE2});
removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2},
SYSTEM_PACKAGE1, SYSTEM_UID);
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
- new int[]{SYSTEM_UID});
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ SYSTEM_UID);
mPermissionMonitor.onUserRemoved(MOCK_USER1);
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER2}, new int[]{SYSTEM_UID});
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER2}, SYSTEM_UID);
// Remove all packages, expect no permission left.
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{});
removePackageForUsers(new UserHandle[]{MOCK_USER2}, SYSTEM_PACKAGE2, SYSTEM_UID);
- netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
- new int[]{SYSTEM_UID, MOCK_UID1});
+ mNetdMonitor.expectNoNetworkPerm(
+ new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_UID, MOCK_UID1);
// Remove last user, expect no redundant clearPermission is invoked.
mPermissionMonitor.onUserRemoved(MOCK_USER2);
- netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
- new int[]{SYSTEM_UID, MOCK_UID1});
+ mNetdMonitor.expectNoNetworkPerm(
+ new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_UID, MOCK_UID1);
}
@Test
@@ -688,74 +717,38 @@
}
}
- private class NetdServiceMonitor {
- private final HashMap<Integer, Integer> mPermissions = new HashMap<>();
-
- NetdServiceMonitor(INetd mockNetdService) throws Exception {
- // Add hook to verify and track result of setPermission.
- doAnswer((InvocationOnMock invocation) -> {
- final Object[] args = invocation.getArguments();
- final int permission = (int) args[0];
- for (final int uid : (int[]) args[1]) {
- mPermissions.put(uid, permission);
- }
- return null;
- }).when(mockNetdService).trafficSetNetPermForUids(anyInt(), any(int[].class));
- }
-
- public void expectPermission(int permission, int[] apps) {
- for (final int app : apps) {
- if (!mPermissions.containsKey(app)) {
- fail("uid " + app + " does not exist.");
- }
- if (mPermissions.get(app) != permission) {
- fail("uid " + app + " has wrong permission: " + mPermissions.get(app));
- }
- }
- }
- }
-
@Test
public void testPackagePermissionUpdate() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
// MOCK_UID1: MOCK_PACKAGE1 only has internet permission.
// MOCK_UID2: MOCK_PACKAGE2 does not have any permission.
// SYSTEM_UID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission.
// SYSTEM_UID2: SYSTEM_PACKAGE2 has only update device stats permission.
-
SparseIntArray netdPermissionsAppIds = new SparseIntArray();
- netdPermissionsAppIds.put(MOCK_UID1, INetd.PERMISSION_INTERNET);
- netdPermissionsAppIds.put(MOCK_UID2, INetd.PERMISSION_NONE);
- netdPermissionsAppIds.put(SYSTEM_UID1, INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS);
- netdPermissionsAppIds.put(SYSTEM_UID2, INetd.PERMISSION_UPDATE_DEVICE_STATS);
+ netdPermissionsAppIds.put(MOCK_UID1, PERMISSION_INTERNET);
+ netdPermissionsAppIds.put(MOCK_UID2, PERMISSION_NONE);
+ netdPermissionsAppIds.put(SYSTEM_UID1, PERMISSION_TRAFFIC_ALL);
+ netdPermissionsAppIds.put(SYSTEM_UID2, PERMISSION_UPDATE_DEVICE_STATS);
// Send the permission information to netd, expect permission updated.
mPermissionMonitor.sendPackagePermissionsToNetd(netdPermissionsAppIds);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET,
- new int[]{MOCK_UID1});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID2});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{SYSTEM_UID1});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_UPDATE_DEVICE_STATS,
- new int[]{SYSTEM_UID2});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_UID1);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_UID2);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, SYSTEM_UID1);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_UPDATE_DEVICE_STATS, SYSTEM_UID2);
// Update permission of MOCK_UID1, expect new permission show up.
- mPermissionMonitor.sendPackagePermissionsForUid(MOCK_UID1,
- INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mPermissionMonitor.sendPackagePermissionsForUid(MOCK_UID1, PERMISSION_TRAFFIC_ALL);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1);
// Change permissions of SYSTEM_UID2, expect new permission show up and old permission
// revoked.
- mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID2,
- INetd.PERMISSION_INTERNET);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{SYSTEM_UID2});
+ mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID2, PERMISSION_INTERNET);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, SYSTEM_UID2);
// Revoke permission from SYSTEM_UID1, expect no permission stored.
- mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID1, INetd.PERMISSION_NONE);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{SYSTEM_UID1});
+ mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID1, PERMISSION_NONE);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_NONE, SYSTEM_UID1);
}
private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions)
@@ -776,24 +769,18 @@
@Test
public void testPackageInstall() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
-
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1);
addPackage(MOCK_PACKAGE2, MOCK_UID2, new String[] {INTERNET});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID2});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_UID2);
}
@Test
public void testPackageInstallSharedUid() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
-
PackageInfo packageInfo1 = addPackage(MOCK_PACKAGE1, MOCK_UID1,
new String[] {INTERNET, UPDATE_DEVICE_STATS});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1);
// Install another package with the same uid and no permissions should not cause the UID to
// lose permissions.
@@ -802,57 +789,45 @@
when(mPackageManager.getPackagesForUid(MOCK_UID1))
.thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
mPermissionMonitor.onPackageAdded(MOCK_PACKAGE2, MOCK_UID1);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1);
}
@Test
public void testPackageUninstallBasic() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
-
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1);
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_UID1);
}
@Test
public void testPackageRemoveThenAdd() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
-
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1);
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_UID1);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_UID1);
}
@Test
public void testPackageUpdate() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
-
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_UID1);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_UID1);
}
@Test
public void testPackageUninstallWithMultiplePackages() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
-
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1);
// Mock another package with the same uid but different permissions.
PackageInfo packageInfo2 = systemPackageInfoWithPermissions(INTERNET);
@@ -861,7 +836,7 @@
MOCK_PACKAGE2});
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_UID1);
}
@Test
@@ -878,7 +853,6 @@
@Test
public void testUpdateUidPermissionsFromSystemConfig() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(new ArrayList<>());
when(mSystemConfigManager.getSystemPermissionUids(eq(INTERNET)))
.thenReturn(new int[]{ MOCK_UID1, MOCK_UID2 });
@@ -886,10 +860,8 @@
.thenReturn(new int[]{ MOCK_UID2 });
mPermissionMonitor.startMonitoring();
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{ MOCK_UID1 });
- netdServiceMonitor.expectPermission(
- INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
- new int[]{ MOCK_UID2 });
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_UID1);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID2);
}
private BroadcastReceiver expectBroadcastReceiver(String... actions) {
@@ -909,7 +881,6 @@
@Test
public void testIntentReceiver() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
final BroadcastReceiver receiver = expectBroadcastReceiver(
Intent.ACTION_PACKAGE_ADDED, Intent.ACTION_PACKAGE_REMOVED);
@@ -920,8 +891,7 @@
setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1,
new String[] { INTERNET, UPDATE_DEVICE_STATS });
receiver.onReceive(mContext, addedIntent);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[] { MOCK_UID1 });
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1);
// Verify receiving PACKAGE_REMOVED intent.
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(null);
@@ -929,7 +899,7 @@
Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
removedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1);
receiver.onReceive(mContext, removedIntent);
- netdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[] { MOCK_UID1 });
+ mNetdMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_UID1);
}
private ContentObserver expectRegisterContentObserver(Uri expectedUri) {
@@ -949,7 +919,6 @@
@Test
public void testUidsAllowedOnRestrictedNetworksChanged() throws Exception {
- final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
final ContentObserver contentObserver = expectRegisterContentObserver(
Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS));
@@ -963,27 +932,25 @@
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new Integer[] { MOCK_UID1 }));
contentObserver.onChange(true /* selfChange */);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_UID2);
// MOCK_UID2 is listed in setting that allow to use restricted networks, MOCK_UID2
// should have SYSTEM permission but MOCK_UID1 should revoke permission.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new Integer[] { MOCK_UID2 }));
contentObserver.onChange(true /* selfChange */);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
- netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_UID2);
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_UID1);
// No uid lists in setting, should revoke permission from all uids.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
contentObserver.onChange(true /* selfChange */);
- netdMonitor.expectNoPermission(
- new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1, MOCK_UID2});
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_UID1, MOCK_UID2);
}
@Test
public void testUidsAllowedOnRestrictedNetworksChangedWithSharedUid() throws Exception {
- final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
final ContentObserver contentObserver = expectRegisterContentObserver(
Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS));
@@ -995,29 +962,28 @@
// MOCK_PACKAGE1 have CHANGE_NETWORK_STATE, MOCK_UID1 should have NETWORK permission.
addPackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_UID1);
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
// MOCK_UID1 is listed in setting that allow to use restricted networks, MOCK_UID1
// should upgrade to SYSTEM permission.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new Integer[] { MOCK_UID1 }));
contentObserver.onChange(true /* selfChange */);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
// No app lists in setting, MOCK_UID1 should downgrade to NETWORK permission.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
contentObserver.onChange(true /* selfChange */);
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
// MOCK_PACKAGE1 removed, should revoke permission from MOCK_UID1.
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{MOCK_PACKAGE2});
removePackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_UID1);
- netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_UID1);
}
@Test
public void testUidsAllowedOnRestrictedNetworksChangedWithMultipleUsers() throws Exception {
- final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
final ContentObserver contentObserver = expectRegisterContentObserver(
Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS));
@@ -1032,44 +998,37 @@
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new Integer[] { MOCK_UID1 }));
contentObserver.onChange(true /* selfChange */);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_UID2);
// Add user MOCK_USER2.
mPermissionMonitor.onUserAdded(MOCK_USER2);
// MOCK_UID1 in both users should all have SYSTEM permission and MOCK_UID2 has no
// permissions in either user.
- netdMonitor.expectPermission(
- SYSTEM, new UserHandle[] { MOCK_USER1, MOCK_USER2 }, new int[]{MOCK_UID1});
- netdMonitor.expectNoPermission(
- new UserHandle[] { MOCK_USER1, MOCK_USER2 }, new int[]{MOCK_UID2});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_UID1);
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_UID2);
// MOCK_UID2 is listed in setting that allow to use restricted networks, MOCK_UID2
// in both users should have SYSTEM permission and MOCK_UID1 has no permissions.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new Integer[] { MOCK_UID2 }));
contentObserver.onChange(true /* selfChange */);
- netdMonitor.expectPermission(
- SYSTEM, new UserHandle[] { MOCK_USER1, MOCK_USER2 }, new int[]{MOCK_UID2});
- netdMonitor.expectNoPermission(
- new UserHandle[] { MOCK_USER1, MOCK_USER2 }, new int[]{MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_UID2);
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_UID1);
// Remove user MOCK_USER1
mPermissionMonitor.onUserRemoved(MOCK_USER1);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[] {MOCK_USER2}, new int[]{MOCK_UID2});
- netdMonitor.expectNoPermission(new UserHandle[] {MOCK_USER2}, new int[]{MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER2}, MOCK_UID2);
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER2}, MOCK_UID1);
// No uid lists in setting, should revoke permission from all uids.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
contentObserver.onChange(true /* selfChange */);
- netdMonitor.expectNoPermission(
- new UserHandle[]{MOCK_USER2}, new int[]{ MOCK_UID1, MOCK_UID2 });
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER2}, MOCK_UID1, MOCK_UID2);
}
@Test
public void testOnExternalApplicationsAvailable() throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
- final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
final BroadcastReceiver receiver = expectBroadcastReceiver(
Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
@@ -1080,10 +1039,8 @@
List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID1),
buildPackageInfo(MOCK_PACKAGE2, MOCK_UID2)));
mPermissionMonitor.startMonitoring();
- netdMonitor.expectNoPermission(
- new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1, MOCK_UID2});
- netdServiceMonitor.expectPermission(
- INetd.PERMISSION_NONE, new int[]{MOCK_UID1, MOCK_UID2});
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_UID1, MOCK_UID2);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_UID1, MOCK_UID2);
// Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd.
final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
@@ -1094,18 +1051,15 @@
buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID2, CHANGE_NETWORK_STATE,
UPDATE_DEVICE_STATS);
receiver.onReceive(mContext, externalIntent);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[] { MOCK_UID1 });
- netdServiceMonitor.expectPermission(
- INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID2});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_UID2);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_UID1);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_UPDATE_DEVICE_STATS, MOCK_UID2);
}
@Test
public void testOnExternalApplicationsAvailable_AppsNotRegisteredOnStartMonitoring()
throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
- final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
final BroadcastReceiver receiver = expectBroadcastReceiver(
Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
@@ -1124,18 +1078,15 @@
externalIntent.putExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST,
new String[] { MOCK_PACKAGE1 , MOCK_PACKAGE2});
receiver.onReceive(mContext, externalIntent);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[] { MOCK_UID1 });
- netdServiceMonitor.expectPermission(
- INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID2});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_UID2);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_UID1);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_UPDATE_DEVICE_STATS, MOCK_UID2);
}
@Test
public void testOnExternalApplicationsAvailableWithSharedUid()
throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
- final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
final BroadcastReceiver receiver = expectBroadcastReceiver(
Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
@@ -1146,8 +1097,8 @@
List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID1),
buildPackageInfo(MOCK_PACKAGE2, MOCK_UID1)));
mPermissionMonitor.startMonitoring();
- netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[] {MOCK_UID1});
+ mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_UID1);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_UID1);
// Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd.
final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
@@ -1157,16 +1108,13 @@
when(mPackageManager.getPackagesForUid(MOCK_UID1))
.thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
receiver.onReceive(mContext, externalIntent);
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- netdServiceMonitor.expectPermission(
- INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[] {MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_UPDATE_DEVICE_STATS, MOCK_UID1);
}
@Test
public void testOnExternalApplicationsAvailableWithSharedUid_DifferentStorage()
throws Exception {
- final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
- final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
final BroadcastReceiver receiver = expectBroadcastReceiver(
Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
@@ -1179,8 +1127,8 @@
buildPackageInfo(MOCK_PACKAGE2, MOCK_UID1, CHANGE_NETWORK_STATE,
INTERNET)));
mPermissionMonitor.startMonitoring();
- netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[] {MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_UID1);
// Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd.
final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
@@ -1192,9 +1140,7 @@
when(mPackageManager.getPackagesForUid(MOCK_UID1))
.thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
receiver.onReceive(mContext, externalIntent);
- netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- netdServiceMonitor.expectPermission(
- INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
- new int[] {MOCK_UID1});
+ mNetdMonitor.expectNetworkPerm(SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_UID1);
+ mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1);
}
}