Merge "Move perUidCounter increment to outside NetworkRequestInfo constructor" into main
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index 19bcff9..e84573b 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -126,7 +126,7 @@
// Due to b/143733063, APK can't access a jni lib that is in APEX (but not in the APK).
cc_library {
name: "libcom_android_networkstack_tethering_util_jni",
- sdk_version: "30",
+ sdk_version: "current",
apex_available: [
"com.android.tethering",
],
diff --git a/netbpfload/loader.cpp b/netbpfload/loader.cpp
index 2b5f5c7..289b4d7 100644
--- a/netbpfload/loader.cpp
+++ b/netbpfload/loader.cpp
@@ -736,15 +736,15 @@
domain selinux_context = getDomainFromSelinuxContext(md[i].selinux_context);
if (specified(selinux_context)) {
ALOGI("map %s selinux_context [%-32s] -> %d -> '%s' (%s)", mapNames[i].c_str(),
- md[i].selinux_context, selinux_context, lookupSelinuxContext(selinux_context),
- lookupPinSubdir(selinux_context));
+ md[i].selinux_context, static_cast<int>(selinux_context),
+ lookupSelinuxContext(selinux_context), lookupPinSubdir(selinux_context));
}
domain pin_subdir = getDomainFromPinSubdir(md[i].pin_subdir);
if (unrecognized(pin_subdir)) return -ENOTDIR;
if (specified(pin_subdir)) {
ALOGI("map %s pin_subdir [%-32s] -> %d -> '%s'", mapNames[i].c_str(), md[i].pin_subdir,
- pin_subdir, lookupPinSubdir(pin_subdir));
+ static_cast<int>(pin_subdir), lookupPinSubdir(pin_subdir));
}
// Format of pin location is /sys/fs/bpf/<pin_subdir|prefix>map_<objName>_<mapName>
@@ -974,13 +974,14 @@
if (specified(selinux_context)) {
ALOGI("prog %s selinux_context [%-32s] -> %d -> '%s' (%s)", name.c_str(),
- cs[i].prog_def->selinux_context, selinux_context,
+ cs[i].prog_def->selinux_context, static_cast<int>(selinux_context),
lookupSelinuxContext(selinux_context), lookupPinSubdir(selinux_context));
}
if (specified(pin_subdir)) {
ALOGI("prog %s pin_subdir [%-32s] -> %d -> '%s'", name.c_str(),
- cs[i].prog_def->pin_subdir, pin_subdir, lookupPinSubdir(pin_subdir));
+ cs[i].prog_def->pin_subdir, static_cast<int>(pin_subdir),
+ lookupPinSubdir(pin_subdir));
}
// strip any potential $foo suffix
diff --git a/netd/Android.bp b/netd/Android.bp
index eedbdae..fe4d999 100644
--- a/netd/Android.bp
+++ b/netd/Android.bp
@@ -72,6 +72,8 @@
"BpfHandlerTest.cpp",
"BpfBaseTest.cpp",
],
+ version_script: ":connectivity_mainline_test_map",
+ stl: "libc++_static",
static_libs: [
"libbase",
"libnetd_updatable",
diff --git a/service-t/native/libs/libnetworkstats/Android.bp b/service-t/native/libs/libnetworkstats/Android.bp
index c620634..b1925bd 100644
--- a/service-t/native/libs/libnetworkstats/Android.bp
+++ b/service-t/native/libs/libnetworkstats/Android.bp
@@ -76,6 +76,8 @@
"-Wno-unused-parameter",
"-Wthread-safety",
],
+ version_script: ":connectivity_mainline_test_map",
+ stl: "libc++_static",
static_libs: [
"libbase",
"libgmock",
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 23af0f8..1047232 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -55,6 +55,7 @@
import android.os.Build;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
+import android.os.UserHandle;
import android.system.ErrnoException;
import android.system.Os;
import android.util.ArraySet;
@@ -815,8 +816,11 @@
*/
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
public int getNetPermForUid(final int uid) {
+ final int appId = UserHandle.getAppId(uid);
try {
- final U8 permissions = sUidPermissionMap.getValue(new S32(uid));
+ // Key of uid permission map is appId
+ // TODO: Rename map name
+ final U8 permissions = sUidPermissionMap.getValue(new S32(appId));
return permissions != null ? permissions.val : PERMISSION_INTERNET;
} catch (ErrnoException e) {
Log.wtf(TAG, "Failed to get permission for uid: " + uid);
diff --git a/service/src/com/android/server/connectivity/MulticastRoutingCoordinatorService.java b/service/src/com/android/server/connectivity/MulticastRoutingCoordinatorService.java
index ac479b8..af4aee5 100644
--- a/service/src/com/android/server/connectivity/MulticastRoutingCoordinatorService.java
+++ b/service/src/com/android/server/connectivity/MulticastRoutingCoordinatorService.java
@@ -168,14 +168,18 @@
public void applyMulticastRoutingConfig(
final String iifName, final String oifName, final MulticastRoutingConfig newConfig) {
checkOnHandlerThread();
+ Objects.requireNonNull(iifName, "IifName can't be null");
+ Objects.requireNonNull(oifName, "OifName can't be null");
if (newConfig.getForwardingMode() != FORWARD_NONE) {
// Make sure iif and oif are added as multicast forwarding interfaces
- try {
- maybeAddAndTrackInterface(iifName);
- maybeAddAndTrackInterface(oifName);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to apply multicast routing config, ", e);
+ if (!maybeAddAndTrackInterface(iifName) || !maybeAddAndTrackInterface(oifName)) {
+ Log.e(
+ TAG,
+ "Failed to apply multicast routing config from "
+ + iifName
+ + " to "
+ + oifName);
return;
}
}
@@ -258,9 +262,14 @@
}
}
+ /**
+ * Returns the next available virtual index for multicast routing, or -1 if the number of
+ * virtual interfaces has reached max value.
+ */
private int getNextAvailableVirtualIndex() {
if (mVirtualInterfaces.size() >= MAX_NUM_OF_MULTICAST_VIRTUAL_INTERFACES) {
- throw new IllegalStateException("Can't allocate new multicast virtual interface");
+ Log.e(TAG, "Can't allocate new multicast virtual interface");
+ return -1;
}
for (int i = 0; i < mVirtualInterfaces.size(); i++) {
if (!mVirtualInterfaces.contains(i)) {
@@ -291,12 +300,23 @@
return mVirtualInterfaces.get(virtualIndex);
}
- private void maybeAddAndTrackInterface(String ifName) {
+ /**
+ * Returns {@code true} if the interfaces is added and tracked, or {@code false} when failed
+ * to add the interface.
+ */
+ private boolean maybeAddAndTrackInterface(String ifName) {
checkOnHandlerThread();
- if (getIndexForValue(mVirtualInterfaces, ifName) >= 0) return;
+ if (getIndexForValue(mVirtualInterfaces, ifName) >= 0) return true;
int nextVirtualIndex = getNextAvailableVirtualIndex();
+ if (nextVirtualIndex < 0) {
+ return false;
+ }
int ifIndex = mDependencies.getInterfaceIndex(ifName);
+ if (ifIndex == 0) {
+ Log.e(TAG, "Can't get interface index for " + ifName);
+ return false;
+ }
final StructMif6ctl mif6ctl =
new StructMif6ctl(
nextVirtualIndex,
@@ -309,10 +329,11 @@
Log.d(TAG, "Added mifi " + nextVirtualIndex + " to MIF");
} catch (ErrnoException e) {
Log.e(TAG, "failed to add multicast virtual interface", e);
- return;
+ return false;
}
mVirtualInterfaces.put(nextVirtualIndex, ifName);
mInterfaces.put(ifIndex, ifName);
+ return true;
}
@VisibleForTesting
@@ -798,13 +819,12 @@
NetworkUtils.setsockoptBytes(fd, IPPROTO_IPV6, MRT6_DEL_MFC, bytes);
}
- public Integer getInterfaceIndex(String ifName) {
- try {
- NetworkInterface ni = NetworkInterface.getByName(ifName);
- return ni.getIndex();
- } catch (NullPointerException | SocketException e) {
- return null;
- }
+ /**
+ * Returns the interface index for an interface name, or 0 if the interface index could
+ * not be found.
+ */
+ public int getInterfaceIndex(String ifName) {
+ return Os.if_nametoindex(ifName);
}
public NetworkInterface getNetworkInterface(int physicalIndex) {
diff --git a/staticlibs/native/bpfmapjni/Android.bp b/staticlibs/native/bpfmapjni/Android.bp
index 7e6b4ec..969ebd4 100644
--- a/staticlibs/native/bpfmapjni/Android.bp
+++ b/staticlibs/native/bpfmapjni/Android.bp
@@ -39,7 +39,7 @@
"-Werror",
"-Wno-unused-parameter",
],
- sdk_version: "30",
+ sdk_version: "current",
min_sdk_version: "30",
apex_available: [
"com.android.tethering",
diff --git a/staticlibs/native/tcutils/Android.bp b/staticlibs/native/tcutils/Android.bp
index 926590d..e4742ce 100644
--- a/staticlibs/native/tcutils/Android.bp
+++ b/staticlibs/native/tcutils/Android.bp
@@ -21,7 +21,10 @@
name: "libtcutils",
srcs: ["tcutils.cpp"],
export_include_dirs: ["include"],
- header_libs: ["bpf_headers"],
+ header_libs: [
+ "bpf_headers",
+ "libbase_headers",
+ ],
shared_libs: [
"liblog",
],
@@ -31,7 +34,7 @@
"-Werror",
"-Wno-unused-parameter",
],
- sdk_version: "30",
+ sdk_version: "current",
min_sdk_version: "30",
apex_available: [
"com.android.tethering",
diff --git a/staticlibs/native/tcutils/scopeguard.h b/staticlibs/native/tcutils/scopeguard.h
deleted file mode 100644
index 76bbb93..0000000
--- a/staticlibs/native/tcutils/scopeguard.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// -----------------------------------------------------------------------------
-// TODO: figure out a way to use libbase_ndk. This is currently not working
-// because of missing apex availability. For now, we can use a copy of
-// ScopeGuard which is very lean compared to unique_fd. This code has been
-// copied verbatim from:
-// https://cs.android.com/android/platform/superproject/+/master:system/libbase/include/android-base/scopeguard.h
-
-#pragma once
-
-#include <utility> // for std::move, std::forward
-
-namespace android {
-namespace base {
-
-// ScopeGuard ensures that the specified functor is executed no matter how the
-// current scope exits.
-template <typename F> class ScopeGuard {
-public:
- ScopeGuard(F &&f) : f_(std::forward<F>(f)), active_(true) {}
-
- ScopeGuard(ScopeGuard &&that) noexcept
- : f_(std::move(that.f_)), active_(that.active_) {
- that.active_ = false;
- }
-
- template <typename Functor>
- ScopeGuard(ScopeGuard<Functor> &&that)
- : f_(std::move(that.f_)), active_(that.active_) {
- that.active_ = false;
- }
-
- ~ScopeGuard() {
- if (active_)
- f_();
- }
-
- ScopeGuard() = delete;
- ScopeGuard(const ScopeGuard &) = delete;
- void operator=(const ScopeGuard &) = delete;
- void operator=(ScopeGuard &&that) = delete;
-
- void Disable() { active_ = false; }
-
- bool active() const { return active_; }
-
-private:
- template <typename Functor> friend class ScopeGuard;
-
- F f_;
- bool active_;
-};
-
-template <typename F> ScopeGuard<F> make_scope_guard(F &&f) {
- return ScopeGuard<F>(std::forward<F>(f));
-}
-
-} // namespace base
-} // namespace android
diff --git a/staticlibs/native/tcutils/tcutils.cpp b/staticlibs/native/tcutils/tcutils.cpp
index c82390f..21e781c 100644
--- a/staticlibs/native/tcutils/tcutils.cpp
+++ b/staticlibs/native/tcutils/tcutils.cpp
@@ -20,8 +20,10 @@
#include "logging.h"
#include "bpf/KernelUtils.h"
-#include "scopeguard.h"
+#include <BpfSyscallWrappers.h>
+#include <android-base/scopeguard.h>
+#include <android-base/unique_fd.h>
#include <arpa/inet.h>
#include <cerrno>
#include <cstring>
@@ -39,10 +41,6 @@
#include <unistd.h>
#include <utility>
-#define BPF_FD_JUST_USE_INT
-#include <BpfSyscallWrappers.h>
-#undef BPF_FD_JUST_USE_INT
-
// The maximum length of TCA_BPF_NAME. Sync from net/sched/cls_bpf.c.
#define CLS_BPF_NAME_LEN 256
@@ -52,6 +50,9 @@
namespace android {
namespace {
+using base::make_scope_guard;
+using base::unique_fd;
+
/**
* IngressPoliceFilterBuilder builds a nlmsg request equivalent to the following
* tc command:
@@ -130,7 +131,7 @@
// class members
const unsigned mBurstInBytes;
const char *mBpfProgPath;
- int mBpfFd;
+ unique_fd mBpfFd;
Request mRequest;
static double getTickInUsec() {
@@ -139,7 +140,7 @@
ALOGE("fopen(\"/proc/net/psched\"): %s", strerror(errno));
return 0.0;
}
- auto scopeGuard = base::make_scope_guard([fp] { fclose(fp); });
+ auto scopeGuard = make_scope_guard([fp] { fclose(fp); });
uint32_t t2us;
uint32_t us2t;
@@ -166,7 +167,6 @@
unsigned burstInBytes, const char* bpfProgPath)
: mBurstInBytes(burstInBytes),
mBpfProgPath(bpfProgPath),
- mBpfFd(-1),
mRequest{
.n = {
.nlmsg_len = sizeof(mRequest),
@@ -298,13 +298,6 @@
}
// clang-format on
- ~IngressPoliceFilterBuilder() {
- // TODO: use unique_fd
- if (mBpfFd != -1) {
- close(mBpfFd);
- }
- }
-
constexpr unsigned getRequestSize() const { return sizeof(Request); }
private:
@@ -332,14 +325,14 @@
}
int initBpfFd() {
- mBpfFd = bpf::retrieveProgram(mBpfProgPath);
- if (mBpfFd == -1) {
+ mBpfFd.reset(bpf::retrieveProgram(mBpfProgPath));
+ if (!mBpfFd.ok()) {
int error = errno;
ALOGE("retrieveProgram failed: %d", error);
return -error;
}
- mRequest.opt.acts.act2.opt.fd.u32 = static_cast<uint32_t>(mBpfFd);
+ mRequest.opt.acts.act2.opt.fd.u32 = static_cast<uint32_t>(mBpfFd.get());
snprintf(mRequest.opt.acts.act2.opt.name.str,
sizeof(mRequest.opt.acts.act2.opt.name.str), "%s:[*fsobj]",
basename(mBpfProgPath));
@@ -370,14 +363,13 @@
int sendAndProcessNetlinkResponse(const void *req, int len) {
// TODO: use unique_fd instead of ScopeGuard
- int fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
- if (fd == -1) {
+ unique_fd fd(socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE));
+ if (!fd.ok()) {
int error = errno;
ALOGE("socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE): %d",
error);
return -error;
}
- auto scopeGuard = base::make_scope_guard([fd] { close(fd); });
static constexpr int on = 1;
if (setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &on, sizeof(on))) {
@@ -460,10 +452,9 @@
}
int hardwareAddressType(const char *interface) {
- int fd = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (fd < 0)
+ unique_fd fd(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+ if (!fd.ok())
return -errno;
- auto scopeGuard = base::make_scope_guard([fd] { close(fd); });
struct ifreq ifr = {};
// We use strncpy() instead of strlcpy() since kernel has to be able
@@ -576,12 +567,11 @@
// /sys/fs/bpf/... direct-action
int tcAddBpfFilter(int ifIndex, bool ingress, uint16_t prio, uint16_t proto,
const char *bpfProgPath) {
- const int bpfFd = bpf::retrieveProgram(bpfProgPath);
- if (bpfFd == -1) {
+ unique_fd bpfFd(bpf::retrieveProgram(bpfProgPath));
+ if (!bpfFd.ok()) {
ALOGE("retrieveProgram failed: %d", errno);
return -errno;
}
- auto scopeGuard = base::make_scope_guard([bpfFd] { close(bpfFd); });
struct {
nlmsghdr n;
diff --git a/staticlibs/netd/Android.bp b/staticlibs/netd/Android.bp
index 59ef20d..44abba2 100644
--- a/staticlibs/netd/Android.bp
+++ b/staticlibs/netd/Android.bp
@@ -22,7 +22,7 @@
sdk_version: "system_current",
min_sdk_version: "30",
static_libs: [
- "netd_aidl_interface-V14-java",
+ "netd_aidl_interface-V15-java",
],
apex_available: [
"//apex_available:platform", // used from services.net
@@ -45,7 +45,7 @@
cc_library_static {
name: "netd_aidl_interface-lateststable-ndk",
whole_static_libs: [
- "netd_aidl_interface-V14-ndk",
+ "netd_aidl_interface-V15-ndk",
],
apex_available: [
"com.android.resolv",
@@ -56,12 +56,12 @@
cc_defaults {
name: "netd_aidl_interface_lateststable_cpp_static",
- static_libs: ["netd_aidl_interface-V14-cpp"],
+ static_libs: ["netd_aidl_interface-V15-cpp"],
}
cc_defaults {
name: "netd_aidl_interface_lateststable_cpp_shared",
- shared_libs: ["netd_aidl_interface-V14-cpp"],
+ shared_libs: ["netd_aidl_interface-V15-cpp"],
}
aidl_interface {
@@ -167,6 +167,10 @@
version: "14",
imports: [],
},
+ {
+ version: "15",
+ imports: [],
+ },
],
frozen: true,
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/.hash b/staticlibs/netd/aidl_api/netd_aidl_interface/15/.hash
new file mode 100644
index 0000000..afdadcc
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/.hash
@@ -0,0 +1 @@
+2be6ff6fb01645cdddb3bb60f6de5727e5733267
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/INetd.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/INetd.aidl
new file mode 100644
index 0000000..80b3b62
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/INetd.aidl
@@ -0,0 +1,260 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetd {
+ boolean isAlive();
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isAllowlist, in int[] uids);
+ boolean bandwidthEnableDataSaver(boolean enable);
+ /**
+ * @deprecated use networkCreate() instead.
+ */
+ void networkCreatePhysical(int netId, int permission);
+ /**
+ * @deprecated use networkCreate() instead.
+ */
+ void networkCreateVpn(int netId, boolean secure);
+ void networkDestroy(int netId);
+ void networkAddInterface(int netId, in @utf8InCpp String iface);
+ void networkRemoveInterface(int netId, in @utf8InCpp String iface);
+ void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
+ void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
+ void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
+ void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
+ boolean tetherApplyDnsInterfaces();
+ android.net.TetherStatsParcel[] tetherGetStats();
+ void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
+ void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
+ @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
+ void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
+ void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
+ int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
+ void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
+ void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
+ void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
+ void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
+ void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
+ void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
+ void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
+ void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
+ void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
+ void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
+ void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
+ void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
+ void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
+ void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
+ void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
+ void strictUidCleartextPenalty(int uid, int policyPenalty);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The clatd control plane moved to the mainline module starting in T. See ClatCoordinator.
+ */
+ @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The clatd control plane moved to the mainline module starting in T. See ClatCoordinator.
+ */
+ void clatdStop(in @utf8InCpp String ifName);
+ boolean ipfwdEnabled();
+ @utf8InCpp String[] ipfwdGetRequesterList();
+ void ipfwdEnableForwarding(in @utf8InCpp String requester);
+ void ipfwdDisableForwarding(in @utf8InCpp String requester);
+ void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
+ void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
+ void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
+ void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
+ void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
+ void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
+ void bandwidthSetGlobalAlert(long bytes);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void bandwidthAddNaughtyApp(int uid);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void bandwidthRemoveNaughtyApp(int uid);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void bandwidthAddNiceApp(int uid);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void bandwidthRemoveNiceApp(int uid);
+ void tetherStart(in @utf8InCpp String[] dhcpRanges);
+ void tetherStop();
+ boolean tetherIsEnabled();
+ void tetherInterfaceAdd(in @utf8InCpp String ifName);
+ void tetherInterfaceRemove(in @utf8InCpp String ifName);
+ @utf8InCpp String[] tetherInterfaceList();
+ void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
+ @utf8InCpp String[] tetherDnsList();
+ void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
+ void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
+ void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
+ void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
+ int networkGetDefault();
+ void networkSetDefault(int netId);
+ void networkClearDefault();
+ void networkSetPermissionForNetwork(int netId, int permission);
+ void networkSetPermissionForUser(int permission, in int[] uids);
+ void networkClearPermissionForUser(in int[] uids);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void trafficSetNetPermForUids(int permission, in int[] uids);
+ void networkSetProtectAllow(int uid);
+ void networkSetProtectDeny(int uid);
+ boolean networkCanProtect(int uid);
+ void firewallSetFirewallType(int firewalltype);
+ void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void firewallSetUidRule(int childChain, int uid, int firewallRule);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void firewallEnableChildChain(int childChain, boolean enable);
+ @utf8InCpp String[] interfaceGetList();
+ android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
+ void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
+ void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
+ void interfaceClearAddrs(in @utf8InCpp String ifName);
+ void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
+ void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
+ void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
+ void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
+ void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
+ void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void firewallRemoveUidInterfaceRules(in int[] uids);
+ /**
+ * @deprecated unimplemented on T+.
+ */
+ void trafficSwapActiveStatsMap();
+ IBinder getOemNetd();
+ void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
+ android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
+ void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+ void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+ void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ android.net.TetherStatsParcel[] tetherOffloadGetStats();
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
+ void networkCreate(in android.net.NativeNetworkConfig config);
+ void networkAddUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
+ void networkRemoveUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
+ void ipSecMigrate(in android.net.IpSecMigrateInfoParcel migrateInfo);
+ void setNetworkAllowlist(in android.net.netd.aidl.NativeUidRangeConfig[] allowedNetworks);
+ void networkAllowBypassVpnOnNetwork(boolean allow, int uid, int netId);
+ const int IPV4 = 4;
+ const int IPV6 = 6;
+ const int CONF = 1;
+ const int NEIGH = 2;
+ const String IPSEC_INTERFACE_PREFIX = "ipsec";
+ const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
+ const int IPV6_ADDR_GEN_MODE_NONE = 1;
+ const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
+ const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
+ const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
+ const int PENALTY_POLICY_ACCEPT = 1;
+ const int PENALTY_POLICY_LOG = 2;
+ const int PENALTY_POLICY_REJECT = 3;
+ const int CLAT_MARK = 0xdeadc1a7;
+ const int LOCAL_NET_ID = 99;
+ const int DUMMY_NET_ID = 51;
+ const int UNREACHABLE_NET_ID = 52;
+ const String NEXTHOP_NONE = "";
+ const String NEXTHOP_UNREACHABLE = "unreachable";
+ const String NEXTHOP_THROW = "throw";
+ const int PERMISSION_NONE = 0;
+ const int PERMISSION_NETWORK = 1;
+ const int PERMISSION_SYSTEM = 2;
+ const int NO_PERMISSIONS = 0;
+ const int PERMISSION_INTERNET = 4;
+ const int PERMISSION_UPDATE_DEVICE_STATS = 8;
+ const int PERMISSION_UNINSTALLED = (-1) /* -1 */;
+ /**
+ * @deprecated use FIREWALL_ALLOWLIST.
+ */
+ const int FIREWALL_WHITELIST = 0;
+ const int FIREWALL_ALLOWLIST = 0;
+ /**
+ * @deprecated use FIREWALL_DENYLIST.
+ */
+ const int FIREWALL_BLACKLIST = 1;
+ const int FIREWALL_DENYLIST = 1;
+ const int FIREWALL_RULE_ALLOW = 1;
+ const int FIREWALL_RULE_DENY = 2;
+ const int FIREWALL_CHAIN_NONE = 0;
+ const int FIREWALL_CHAIN_DOZABLE = 1;
+ const int FIREWALL_CHAIN_STANDBY = 2;
+ const int FIREWALL_CHAIN_POWERSAVE = 3;
+ const int FIREWALL_CHAIN_RESTRICTED = 4;
+ const String IF_STATE_UP = "up";
+ const String IF_STATE_DOWN = "down";
+ const String IF_FLAG_BROADCAST = "broadcast";
+ const String IF_FLAG_LOOPBACK = "loopback";
+ const String IF_FLAG_POINTOPOINT = "point-to-point";
+ const String IF_FLAG_RUNNING = "running";
+ const String IF_FLAG_MULTICAST = "multicast";
+ const int IPSEC_DIRECTION_IN = 0;
+ const int IPSEC_DIRECTION_OUT = 1;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/INetdUnsolicitedEventListener.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/INetdUnsolicitedEventListener.aidl
new file mode 100644
index 0000000..31775df
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/INetdUnsolicitedEventListener.aidl
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetdUnsolicitedEventListener {
+ oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
+ oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
+ oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
+ oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
+ oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
+ oneway void onInterfaceAdded(@utf8InCpp String ifName);
+ oneway void onInterfaceRemoved(@utf8InCpp String ifName);
+ oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
+ oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
+ oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
+ oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/InterfaceConfigurationParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/InterfaceConfigurationParcel.aidl
new file mode 100644
index 0000000..1869d8d
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/InterfaceConfigurationParcel.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable InterfaceConfigurationParcel {
+ @utf8InCpp String ifName;
+ @utf8InCpp String hwAddr;
+ @utf8InCpp String ipv4Addr;
+ int prefixLength;
+ @utf8InCpp String[] flags;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/IpSecMigrateInfoParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/IpSecMigrateInfoParcel.aidl
new file mode 100644
index 0000000..975a261
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/IpSecMigrateInfoParcel.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaOnlyImmutable
+parcelable IpSecMigrateInfoParcel {
+ int requestId;
+ int selAddrFamily;
+ int direction;
+ @utf8InCpp String oldSourceAddress;
+ @utf8InCpp String oldDestinationAddress;
+ @utf8InCpp String newSourceAddress;
+ @utf8InCpp String newDestinationAddress;
+ int interfaceId;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/MarkMaskParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/MarkMaskParcel.aidl
new file mode 100644
index 0000000..8ea20d1
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/MarkMaskParcel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable MarkMaskParcel {
+ int mark;
+ int mask;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/NativeNetworkConfig.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/NativeNetworkConfig.aidl
new file mode 100644
index 0000000..77d814b
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/NativeNetworkConfig.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable NativeNetworkConfig {
+ int netId;
+ android.net.NativeNetworkType networkType = android.net.NativeNetworkType.PHYSICAL;
+ int permission;
+ boolean secure;
+ android.net.NativeVpnType vpnType = android.net.NativeVpnType.PLATFORM;
+ boolean excludeLocalRoutes = false;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/NativeNetworkType.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/NativeNetworkType.aidl
new file mode 100644
index 0000000..e77a143
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/NativeNetworkType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@Backing(type="int")
+enum NativeNetworkType {
+ PHYSICAL = 0,
+ VIRTUAL = 1,
+ PHYSICAL_LOCAL = 2,
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/NativeVpnType.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/NativeVpnType.aidl
new file mode 100644
index 0000000..8a8be83
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/NativeVpnType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@Backing(type="int")
+enum NativeVpnType {
+ SERVICE = 1,
+ PLATFORM = 2,
+ LEGACY = 3,
+ OEM = 4,
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/RouteInfoParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/RouteInfoParcel.aidl
new file mode 100644
index 0000000..5ef95e6
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/RouteInfoParcel.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable RouteInfoParcel {
+ @utf8InCpp String destination;
+ @utf8InCpp String ifName;
+ @utf8InCpp String nextHop;
+ int mtu;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/TetherConfigParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/TetherConfigParcel.aidl
new file mode 100644
index 0000000..7b39c22
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/TetherConfigParcel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherConfigParcel {
+ boolean usingLegacyDnsProxy;
+ @utf8InCpp String[] dhcpRanges;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/TetherOffloadRuleParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/TetherOffloadRuleParcel.aidl
new file mode 100644
index 0000000..983e986
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/TetherOffloadRuleParcel.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherOffloadRuleParcel {
+ int inputInterfaceIndex;
+ int outputInterfaceIndex;
+ byte[] destination;
+ int prefixLength;
+ byte[] srcL2Address;
+ byte[] dstL2Address;
+ int pmtu = 1500;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/TetherStatsParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/TetherStatsParcel.aidl
new file mode 100644
index 0000000..5f1b722
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/TetherStatsParcel.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherStatsParcel {
+ @utf8InCpp String iface;
+ long rxBytes;
+ long rxPackets;
+ long txBytes;
+ long txPackets;
+ int ifIndex = 0;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/UidRangeParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/UidRangeParcel.aidl
new file mode 100644
index 0000000..72e987a
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/UidRangeParcel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable UidRangeParcel {
+ int start;
+ int stop;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/netd/aidl/NativeUidRangeConfig.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/netd/aidl/NativeUidRangeConfig.aidl
new file mode 100644
index 0000000..9bb679f
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/15/android/net/netd/aidl/NativeUidRangeConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.netd.aidl;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable NativeUidRangeConfig {
+ int netId;
+ android.net.UidRangeParcel[] uidRanges;
+ int subPriority;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
index 8ccefb2..80b3b62 100644
--- a/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
@@ -203,6 +203,7 @@
void networkRemoveUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
void ipSecMigrate(in android.net.IpSecMigrateInfoParcel migrateInfo);
void setNetworkAllowlist(in android.net.netd.aidl.NativeUidRangeConfig[] allowedNetworks);
+ void networkAllowBypassVpnOnNetwork(boolean allow, int uid, int netId);
const int IPV4 = 4;
const int IPV6 = 6;
const int CONF = 1;
diff --git a/staticlibs/netd/binder/android/net/INetd.aidl b/staticlibs/netd/binder/android/net/INetd.aidl
index ee27e84..e4c63b9 100644
--- a/staticlibs/netd/binder/android/net/INetd.aidl
+++ b/staticlibs/netd/binder/android/net/INetd.aidl
@@ -1446,4 +1446,27 @@
* - subPriority: unused
*/
void setNetworkAllowlist(in NativeUidRangeConfig[] allowedNetworks);
+
+ /**
+ * Allow the UID to explicitly select the given network even if it is subject to a VPN.
+ *
+ * Throws ServiceSpecificException with error code EEXISTS when trying to add a bypass rule that
+ * already exists, and ENOENT when trying to remove a bypass rule that does not exist.
+ *
+ * netId specific bypass rules can be combined and are allowed to overlap with global VPN
+ * exclusions (by calling networkSetProtectAllow / networkSetProtectDeny, or by setting netId to
+ * 0). Adding or removing global VPN bypass rules does not affect the netId specific rules and
+ * vice versa.
+ *
+ * Note that if netId is set to 0 (NETID_UNSET) this API is equivalent to
+ * networkSetProtectAllow} / #networkSetProtectDeny.
+ *
+ * @param allow whether to allow or disallow the operation.
+ * @param uid the UID
+ * @param netId the netId that the UID is allowed to select.
+ *
+ * @throws ServiceSpecificException in case of failure, with an error code indicating the
+ * cause of the failure.
+ */
+ void networkAllowBypassVpnOnNetwork(boolean allow, int uid, int netId);
}
diff --git a/staticlibs/netd/libnetdutils/InternetAddresses.cpp b/staticlibs/netd/libnetdutils/InternetAddresses.cpp
index 322f1b1..6d98608 100644
--- a/staticlibs/netd/libnetdutils/InternetAddresses.cpp
+++ b/staticlibs/netd/libnetdutils/InternetAddresses.cpp
@@ -16,6 +16,7 @@
#include "netdutils/InternetAddresses.h"
+#include <stdlib.h>
#include <string>
#include <android-base/stringprintf.h>
diff --git a/tests/common/Android.bp b/tests/common/Android.bp
index 6e9d614..e95a81a 100644
--- a/tests/common/Android.bp
+++ b/tests/common/Android.bp
@@ -201,3 +201,8 @@
name: "connectivity-mainline-presubmit-java-defaults",
test_mainline_modules: mainline_presubmit_modules,
}
+
+filegroup {
+ name: "connectivity_mainline_test_map",
+ srcs: ["connectivity_mainline_test.map"],
+}
diff --git a/tests/common/connectivity_mainline_test.map b/tests/common/connectivity_mainline_test.map
new file mode 100644
index 0000000..043312e
--- /dev/null
+++ b/tests/common/connectivity_mainline_test.map
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Some connectivity tests run on older OS versions, and for those tests, many
+# library dependencies (such as libbase and libc++) need to be linked
+# statically. The tests also need to be linked with a version script to ensure
+# that the statically-linked library isn't exported from the executable, where
+# it would override the shared libraries that the OS itself uses. See
+# b/333438055 for an example of what goes wrong when libc++ is partially
+# exported from an executable.
+{
+ local:
+ *;
+};
diff --git a/tests/mts/Android.bp b/tests/mts/Android.bp
index 336be2e..c118d0a 100644
--- a/tests/mts/Android.bp
+++ b/tests/mts/Android.bp
@@ -31,6 +31,8 @@
header_libs: [
"bpf_headers",
],
+ version_script: ":connectivity_mainline_test_map",
+ stl: "libc++_static",
static_libs: [
"libbase",
"libmodules-utils-build",
diff --git a/tests/native/connectivity_native_test/Android.bp b/tests/native/connectivity_native_test/Android.bp
index 2f66d17..c5088c6 100644
--- a/tests/native/connectivity_native_test/Android.bp
+++ b/tests/native/connectivity_native_test/Android.bp
@@ -17,8 +17,9 @@
"connectivity_native_test.cpp",
],
header_libs: ["bpf_connectivity_headers"],
+ version_script: ":connectivity_mainline_test_map",
+ stl: "libc++_static",
shared_libs: [
- "libbase",
"libbinder_ndk",
"liblog",
"libnetutils",
@@ -26,6 +27,7 @@
],
static_libs: [
"connectivity_native_aidl_interface-lateststable-ndk",
+ "libbase",
"libcutils",
"libmodules-utils-build",
"libutils",
diff --git a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
index 0c200fd..afd6e9a 100644
--- a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
+++ b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
@@ -465,6 +465,7 @@
private void setEnabledInternal(
boolean isEnabled, boolean persist, @NonNull OperationReceiverWrapper receiver) {
+ checkOnHandlerThread();
if (isEnabled && isThreadUserRestricted()) {
receiver.onError(
ERROR_FAILED_PRECONDITION,
@@ -960,7 +961,11 @@
private void checkOnHandlerThread() {
if (Looper.myLooper() != mHandler.getLooper()) {
- Log.wtf(TAG, "Must be on the handler thread!");
+ throw new IllegalStateException(
+ "Not running on ThreadNetworkControllerService thread ("
+ + mHandler.getLooper()
+ + ") : "
+ + Looper.myLooper());
}
}
diff --git a/thread/tests/multidevices/AndroidTest.xml b/thread/tests/multidevices/AndroidTest.xml
index a2ea9aa..8b2bed3 100644
--- a/thread/tests/multidevices/AndroidTest.xml
+++ b/thread/tests/multidevices/AndroidTest.xml
@@ -44,7 +44,7 @@
<test class="com.android.tradefed.testtype.mobly.MoblyBinaryHostTest">
<!-- The mobly-par-file-name should match the module name -->
- <option name="mobly-par-file-name" value="ThreadMultiDeviceTestCases" />
+ <option name="mobly-par-file-name" value="ThreadNetworkMultiDeviceTests" />
<!-- Timeout limit in milliseconds for all test cases of the python binary -->
<option name="mobly-test-timeout" value="180000" />
</test>
diff --git a/thread/tests/unit/Android.bp b/thread/tests/unit/Android.bp
index 3365cd0..9404d1b 100644
--- a/thread/tests/unit/Android.bp
+++ b/thread/tests/unit/Android.bp
@@ -33,6 +33,7 @@
"mts-tethering",
],
static_libs: [
+ "androidx.test.rules",
"frameworks-base-testutils",
"framework-connectivity-pre-jarjar",
"framework-connectivity-t-pre-jarjar",
diff --git a/thread/tests/unit/src/com/android/server/thread/ThreadNetworkControllerServiceTest.java b/thread/tests/unit/src/com/android/server/thread/ThreadNetworkControllerServiceTest.java
index 52a9dd9..cf6eb44 100644
--- a/thread/tests/unit/src/com/android/server/thread/ThreadNetworkControllerServiceTest.java
+++ b/thread/tests/unit/src/com/android/server/thread/ThreadNetworkControllerServiceTest.java
@@ -69,6 +69,7 @@
import android.provider.Settings;
import android.util.AtomicFile;
+import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -97,6 +98,12 @@
/** Unit tests for {@link ThreadNetworkControllerService}. */
@SmallTest
@RunWith(AndroidJUnit4.class)
+// This test doesn't really need to run on the UI thread, but @Before and @Test annotated methods
+// need to run in the same thread because there are code in {@code ThreadNetworkControllerService}
+// checking that all its methods are running in the thread of the handler it's using. This is due
+// to a bug in TestLooper that it executes all tasks on the current thread rather than the thread
+// associated to the backed Looper object.
+@UiThreadTest
public final class ThreadNetworkControllerServiceTest {
// A valid Thread Active Operational Dataset generated from OpenThread CLI "dataset new":
// Active Timestamp: 1