diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index d8557ad..761e098 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -26,7 +26,6 @@
     ],
     static_libs: [
         "androidx.annotation_annotation",
-        "netd_aidl_interface-unstable-java",
         "netlink-client",
         // TODO: use networkstack-client instead of just including the AIDL interface
         "networkstack-aidl-interfaces-unstable-java",
@@ -34,6 +33,7 @@
         "android.hardware.tetheroffload.control-V1.0-java",
         "net-utils-framework-common",
         "net-utils-device-common",
+        "netd-client",
     ],
     libs: [
         "framework-statsd.stubs.module_lib",
@@ -60,8 +60,9 @@
         "com.android.tethering",
     ],
     min_sdk_version: "30",
+    header_libs: ["bpf_syscall_wrappers"],
     srcs: [
-        "jni/android_net_util_TetheringUtils.cpp",
+        "jni/*.cpp",
     ],
     shared_libs: [
         "liblog",
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index a1e7fd2..c99121c 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -16,9 +16,17 @@
 
 apex {
     name: "com.android.tethering",
-    updatable: true,
-    min_sdk_version: "30",
-    java_libs: ["framework-tethering"],
+    // TODO: make updatable again once this contains only updatable artifacts (in particular, this
+    // cannot build as updatable unless service-connectivity builds against stable API).
+    // updatable: true,
+    // min_sdk_version: "30",
+    java_libs: [
+        "framework-tethering",
+        "service-connectivity",
+    ],
+    jni_libs: [
+        "libservice-connectivity",
+    ],
     bpfs: ["offload.o"],
     apps: ["Tethering"],
     manifest: "manifest.json",
diff --git a/Tethering/bpf_progs/offload.c b/Tethering/bpf_progs/offload.c
index cc5af31..d8dc60d 100644
--- a/Tethering/bpf_progs/offload.c
+++ b/Tethering/bpf_progs/offload.c
@@ -34,6 +34,10 @@
 // (tethering allowed when stats[iif].rxBytes + stats[iif].txBytes < limit[iif])
 DEFINE_BPF_MAP_GRW(tether_limit_map, HASH, uint32_t, uint64_t, 16, AID_NETWORK_STACK)
 
+// Used only by TetheringPrivilegedTests, not by production code.
+DEFINE_BPF_MAP_GRW(tether_ingress_map_TEST, HASH, TetherIngressKey, TetherIngressValue, 16,
+                   AID_NETWORK_STACK)
+
 static inline __always_inline int do_forward(struct __sk_buff* skb, bool is_ethernet) {
     int l2_header_size = is_ethernet ? sizeof(struct ethhdr) : 0;
     void* data = (void*)(long)skb->data;
diff --git a/Tethering/jarjar-rules.txt b/Tethering/jarjar-rules.txt
index 591861f..d1ad569 100644
--- a/Tethering/jarjar-rules.txt
+++ b/Tethering/jarjar-rules.txt
@@ -8,4 +8,7 @@
 rule android.net.shared.Inet4AddressUtils* com.android.networkstack.tethering.shared.Inet4AddressUtils@1
 
 # Classes from net-utils-framework-common
-rule com.android.net.module.util.** com.android.networkstack.tethering.util.@1
\ No newline at end of file
+rule com.android.net.module.util.** com.android.networkstack.tethering.util.@1
+
+# Classes from net-utils-device-common
+rule com.android.net.module.util.Struct* com.android.networkstack.tethering.util.Struct@1
diff --git a/Tethering/jni/android_net_util_TetheringUtils.cpp b/Tethering/jni/android_net_util_TetheringUtils.cpp
index 7bfb6da..27c84cf 100644
--- a/Tethering/jni/android_net_util_TetheringUtils.cpp
+++ b/Tethering/jni/android_net_util_TetheringUtils.cpp
@@ -28,9 +28,6 @@
 #include <sys/socket.h>
 #include <stdio.h>
 
-#define LOG_TAG "TetheringUtils"
-#include <android/log.h>
-
 namespace android {
 
 static const uint32_t kIPv6NextHeaderOffset = offsetof(ip6_hdr, ip6_nxt);
@@ -184,18 +181,4 @@
             gMethods, NELEM(gMethods));
 }
 
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
-    JNIEnv *env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
-        return JNI_ERR;
-    }
-
-    if (register_android_net_util_TetheringUtils(env) < 0) {
-        return JNI_ERR;
-    }
-
-    return JNI_VERSION_1_6;
-}
-
 }; // namespace android
diff --git a/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp
new file mode 100644
index 0000000..eadc210
--- /dev/null
+++ b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include "nativehelper/scoped_primitive_array.h"
+#include "nativehelper/scoped_utf_chars.h"
+
+#define BPF_FD_JUST_USE_INT
+#include "BpfSyscallWrappers.h"
+
+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);
+
+    return ret;
+}
+
+static jint com_android_networkstack_tethering_BpfMap_bpfFdGet(JNIEnv *env, jobject clazz,
+        jstring path, jint mode) {
+    ScopedUtfChars pathname(env, path);
+
+    jint fd = bpf::bpfFdGet(pathname.c_str(), static_cast<unsigned>(mode));
+
+    return fd;
+}
+
+static void com_android_networkstack_tethering_BpfMap_writeToMapEntry(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key, jbyteArray value, jint flags) {
+    ScopedByteArrayRO keyRO(env, key);
+    ScopedByteArrayRO valueRO(env, value);
+
+    int ret = bpf::writeToMapEntry(static_cast<int>(fd), keyRO.get(), valueRO.get(),
+            static_cast<int>(flags));
+
+    if (ret) throwErrnoException(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);
+    return false;
+}
+
+static jboolean com_android_networkstack_tethering_BpfMap_deleteMapEntry(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key) {
+    ScopedByteArrayRO keyRO(env, key);
+
+    // On success, zero is returned.  If the element is not found, -1 is returned and errno is set
+    // to ENOENT.
+    int ret = bpf::deleteMapEntry(static_cast<int>(fd), keyRO.get());
+
+    return throwIfNotEnoent(env, "deleteMapEntry", ret, errno);
+}
+
+static jboolean com_android_networkstack_tethering_BpfMap_getNextMapKey(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key, jbyteArray nextKey) {
+    // If key is found, the operation returns zero and sets the next key pointer to the key of the
+    // next element.  If key is not found, the operation returns zero and sets the next key pointer
+    // to the key of the first element.  If key is the last element, -1 is returned and errno is
+    // set to ENOENT.  Other possible errno values are ENOMEM, EFAULT, EPERM, and EINVAL.
+    ScopedByteArrayRW nextKeyRW(env, nextKey);
+    int ret;
+    if (key == nullptr) {
+        // Called by getFirstKey. Find the first key in the map.
+        ret = bpf::getNextMapKey(static_cast<int>(fd), nullptr, nextKeyRW.get());
+    } else {
+        ScopedByteArrayRO keyRO(env, key);
+        ret = bpf::getNextMapKey(static_cast<int>(fd), keyRO.get(), nextKeyRW.get());
+    }
+
+    return throwIfNotEnoent(env, "getNextMapKey", ret, errno);
+}
+
+static jboolean com_android_networkstack_tethering_BpfMap_findMapEntry(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key, jbyteArray value) {
+    ScopedByteArrayRO keyRO(env, key);
+    ScopedByteArrayRW valueRW(env, value);
+
+    // If an element is found, the operation returns zero and stores the element's value into
+    // "value".  If no element is found, the operation returns -1 and sets errno to ENOENT.
+    int ret = bpf::findMapEntry(static_cast<int>(fd), keyRO.get(), valueRW.get());
+
+    return throwIfNotEnoent(env, "findMapEntry", ret, errno);
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "closeMap", "(I)I",
+        (void*) com_android_networkstack_tethering_BpfMap_closeMap },
+    { "bpfFdGet", "(Ljava/lang/String;I)I",
+        (void*) com_android_networkstack_tethering_BpfMap_bpfFdGet },
+    { "writeToMapEntry", "(I[B[BI)V",
+        (void*) com_android_networkstack_tethering_BpfMap_writeToMapEntry },
+    { "deleteMapEntry", "(I[B)Z",
+        (void*) com_android_networkstack_tethering_BpfMap_deleteMapEntry },
+    { "getNextMapKey", "(I[B[B)Z",
+        (void*) com_android_networkstack_tethering_BpfMap_getNextMapKey },
+    { "findMapEntry", "(I[B[B)Z",
+        (void*) com_android_networkstack_tethering_BpfMap_findMapEntry },
+
+};
+
+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));
+}
+
+}; // namespace android
diff --git a/Tethering/jni/onload.cpp b/Tethering/jni/onload.cpp
new file mode 100644
index 0000000..3766de9
--- /dev/null
+++ b/Tethering/jni/onload.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+
+#define LOG_TAG "TetheringJni"
+#include <android/log.h>
+
+namespace android {
+
+int register_android_net_util_TetheringUtils(JNIEnv* env);
+int register_com_android_networkstack_tethering_BpfMap(JNIEnv* env);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "ERROR: GetEnv failed");
+        return JNI_ERR;
+    }
+
+    if (register_android_net_util_TetheringUtils(env) < 0) return JNI_ERR;
+
+    if (register_com_android_networkstack_tethering_BpfMap(env) < 0) return JNI_ERR;
+
+    return JNI_VERSION_1_6;
+}
+
+}; // namespace android
diff --git a/Tethering/proguard.flags b/Tethering/proguard.flags
index 86b9033..9ab56c2 100644
--- a/Tethering/proguard.flags
+++ b/Tethering/proguard.flags
@@ -4,6 +4,14 @@
     static final int EVENT_*;
 }
 
+-keep class com.android.networkstack.tethering.BpfMap {
+    native <methods>;
+}
+
+-keepclassmembers public class * extends com.android.networkstack.tethering.util.Struct {
+    public <init>(...);
+}
+
 -keepclassmembers class android.net.ip.IpServer {
     static final int CMD_*;
 }
diff --git a/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java b/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java
deleted file mode 100644
index b1ffdb0..0000000
--- a/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.
- */
-package android.net.util;
-
-import android.net.INetdUnsolicitedEventListener;
-
-import androidx.annotation.NonNull;
-
-/**
- * Base {@link INetdUnsolicitedEventListener} that provides no-op implementations which can be
- * overridden.
- */
-public class BaseNetdUnsolicitedEventListener extends INetdUnsolicitedEventListener.Stub {
-
-    @Override
-    public void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs,
-            int uid) { }
-
-    @Override
-    public void onQuotaLimitReached(@NonNull String alertName, @NonNull String ifName) { }
-
-    @Override
-    public void onInterfaceDnsServerInfo(@NonNull String ifName, long lifetimeS,
-            @NonNull String[] servers) { }
-
-    @Override
-    public void onInterfaceAddressUpdated(@NonNull String addr, String ifName, int flags,
-            int scope) { }
-
-    @Override
-    public void onInterfaceAddressRemoved(@NonNull String addr, @NonNull String ifName, int flags,
-            int scope) { }
-
-    @Override
-    public void onInterfaceAdded(@NonNull String ifName) { }
-
-    @Override
-    public void onInterfaceRemoved(@NonNull String ifName) { }
-
-    @Override
-    public void onInterfaceChanged(@NonNull String ifName, boolean up) { }
-
-    @Override
-    public void onInterfaceLinkStateChanged(@NonNull String ifName, boolean up) { }
-
-    @Override
-    public void onRouteChanged(boolean updated, @NonNull String route, @NonNull String gateway,
-            @NonNull String ifName) { }
-
-    @Override
-    public void onStrictCleartextDetected(int uid, @NonNull String hex) { }
-
-    @Override
-    public int getInterfaceVersion() {
-        return INetdUnsolicitedEventListener.VERSION;
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return INetdUnsolicitedEventListener.HASH;
-    }
-}
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfMap.java b/Tethering/src/com/android/networkstack/tethering/BpfMap.java
new file mode 100644
index 0000000..69ad1b6
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/BpfMap.java
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+package com.android.networkstack.tethering;
+
+import static android.system.OsConstants.EEXIST;
+import static android.system.OsConstants.ENOENT;
+
+import android.system.ErrnoException;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.net.module.util.Struct;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.function.BiConsumer;
+
+/**
+ * BpfMap is a key -> value mapping structure that is designed to maintained the bpf map entries.
+ * This is a wrapper class of in-kernel data structure. The in-kernel data can be read/written by
+ * passing syscalls with map file descriptor.
+ *
+ * @param <K> the key of the map.
+ * @param <V> the value of the map.
+ */
+public class BpfMap<K extends Struct, V extends Struct> implements AutoCloseable {
+    // Following definitions from kernel include/uapi/linux/bpf.h
+    public static final int BPF_F_RDWR = 0;
+    public static final int BPF_F_RDONLY = 1 << 3;
+    public static final int BPF_F_WRONLY = 1 << 4;
+
+    public static final int BPF_MAP_TYPE_HASH = 1;
+
+    private static final int BPF_F_NO_PREALLOC = 1;
+
+    private static final int BPF_ANY = 0;
+    private static final int BPF_NOEXIST = 1;
+    private static final int BPF_EXIST = 2;
+
+    private final int mMapFd;
+    private final Class<K> mKeyClass;
+    private final Class<V> mValueClass;
+    private final int mKeySize;
+    private final int mValueSize;
+
+    /**
+     * Create a BpfMap map wrapper with "path" of filesystem.
+     *
+     * @param flag the access mode, one of BPF_F_RDWR, BPF_F_RDONLY, or BPF_F_WRONLY.
+     * @throws ErrnoException if the BPF map associated with {@code path} cannot be retrieved.
+     * @throws NullPointerException if {@code path} is null.
+     */
+    public BpfMap(@NonNull final String path, final int flag, final Class<K> key,
+            final Class<V> value) throws ErrnoException, NullPointerException {
+        mMapFd = bpfFdGet(path, flag);
+
+        mKeyClass = key;
+        mValueClass = value;
+        mKeySize = Struct.getSize(key);
+        mValueSize = Struct.getSize(value);
+    }
+
+    /**
+     * Update an existing or create a new key -> value entry in an eBbpf map.
+     */
+    public void updateEntry(K key, V value) throws ErrnoException {
+        writeToMapEntry(mMapFd, key.writeToBytes(), value.writeToBytes(), BPF_ANY);
+    }
+
+    /**
+     * If the key does not exist in the map, insert key -> value entry into eBpf map.
+     * Otherwise IllegalStateException will be thrown.
+     */
+    public void insertEntry(K key, V value)
+            throws ErrnoException, IllegalStateException {
+        try {
+            writeToMapEntry(mMapFd, key.writeToBytes(), value.writeToBytes(), BPF_NOEXIST);
+        } catch (ErrnoException e) {
+            if (e.errno == EEXIST) throw new IllegalStateException(key + " already exists");
+
+            throw e;
+        }
+    }
+
+    /**
+     * If the key already exists in the map, replace its value. Otherwise NoSuchElementException
+     * will be thrown.
+     */
+    public void replaceEntry(K key, V value)
+            throws ErrnoException, NoSuchElementException {
+        try {
+            writeToMapEntry(mMapFd, key.writeToBytes(), value.writeToBytes(), BPF_EXIST);
+        } catch (ErrnoException e) {
+            if (e.errno == ENOENT) throw new NoSuchElementException(key + " not found");
+
+            throw e;
+        }
+    }
+
+    /** Remove existing key from eBpf map. Return false if map was not modified. */
+    public boolean deleteEntry(K key) throws ErrnoException {
+        return deleteMapEntry(mMapFd, key.writeToBytes());
+    }
+
+    private K getNextKeyInternal(@Nullable K key) throws ErrnoException {
+        final byte[] rawKey = getNextRawKey(
+                key == null ? null : key.writeToBytes());
+        if (rawKey == null) return null;
+
+        final ByteBuffer buffer = ByteBuffer.wrap(rawKey);
+        buffer.order(ByteOrder.nativeOrder());
+        return Struct.parse(mKeyClass, buffer);
+    }
+
+    /**
+     * Get the next key of the passed-in key. If the passed-in key is not found, return the first
+     * key. If the passed-in key is the last one, return null.
+     *
+     * TODO: consider allowing null passed-in key.
+     */
+    public K getNextKey(@NonNull K key) throws ErrnoException {
+        Objects.requireNonNull(key);
+        return getNextKeyInternal(key);
+    }
+
+    private byte[] getNextRawKey(@Nullable final byte[] key) throws ErrnoException {
+        byte[] nextKey = new byte[mKeySize];
+        if (getNextMapKey(mMapFd, key, nextKey)) return nextKey;
+
+        return null;
+    }
+
+    /** Get the first key of eBpf map. */
+    public K getFirstKey() throws ErrnoException {
+        return getNextKeyInternal(null);
+    }
+
+    /** Check whether a key exists in the map. */
+    public boolean containsKey(@NonNull K key) throws ErrnoException {
+        Objects.requireNonNull(key);
+
+        final byte[] rawValue = getRawValue(key.writeToBytes());
+        return rawValue != null;
+    }
+
+    /** Retrieve a value from the map. Return null if there is no such key. */
+    public V getValue(@NonNull K key) throws ErrnoException {
+        Objects.requireNonNull(key);
+        final byte[] rawValue = getRawValue(key.writeToBytes());
+
+        if (rawValue == null) return null;
+
+        final ByteBuffer buffer = ByteBuffer.wrap(rawValue);
+        buffer.order(ByteOrder.nativeOrder());
+        return Struct.parse(mValueClass, buffer);
+    }
+
+    private byte[] getRawValue(final byte[] key) throws ErrnoException {
+        byte[] value = new byte[mValueSize];
+        if (findMapEntry(mMapFd, key, value)) return value;
+
+        return null;
+    }
+
+    /**
+     * Iterate through the map and handle each key -> value retrieved base on the given BiConsumer.
+     * The given BiConsumer may to delete the passed-in entry, but is not allowed to perform any
+     * other structural modifications to the map, such as adding entries or deleting other entries.
+     * Otherwise, iteration will result in undefined behaviour.
+     */
+    public void forEach(BiConsumer<K, V> action) throws ErrnoException {
+        @Nullable K nextKey = getFirstKey();
+
+        while (nextKey != null) {
+            @NonNull final K curKey = nextKey;
+            @NonNull final V value = getValue(curKey);
+
+            nextKey = getNextKey(curKey);
+            action.accept(curKey, value);
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        closeMap(mMapFd);
+    }
+
+    private static native int closeMap(int fd) throws ErrnoException;
+
+    private native int bpfFdGet(String path, int mode) throws ErrnoException, NullPointerException;
+
+    private native void writeToMapEntry(int fd, byte[] key, byte[] value, int flags)
+            throws ErrnoException;
+
+    private native boolean deleteMapEntry(int fd, byte[] key) throws ErrnoException;
+
+    // If key is found, the operation returns true and the nextKey would reference to the next
+    // element.  If key is not found, the operation returns true and the nextKey would reference to
+    // the first element.  If key is the last element, false is returned.
+    private native boolean getNextMapKey(int fd, byte[] key, byte[] nextKey) throws ErrnoException;
+
+    private native boolean findMapEntry(int fd, byte[] key, byte[] value) throws ErrnoException;
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherIngressKey.java b/Tethering/src/com/android/networkstack/tethering/TetherIngressKey.java
new file mode 100644
index 0000000..78683c5
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherIngressKey.java
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+package com.android.networkstack.tethering;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+/** The key of BpfMap which is used for bpf offload. */
+public class TetherIngressKey extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long iif; // The input interface index.
+
+    @Field(order = 1, type = Type.ByteArray, arraysize = 16)
+    public final byte[] neigh6; // The destination IPv6 address.
+
+    public TetherIngressKey(final long iif, final byte[] neigh6) {
+        try {
+            final Inet6Address unused = (Inet6Address) InetAddress.getByAddress(neigh6);
+        } catch (ClassCastException | UnknownHostException e) {
+            throw new IllegalArgumentException("Invalid IPv6 address: "
+                    + Arrays.toString(neigh6));
+        }
+        this.iif = iif;
+        this.neigh6 = neigh6;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherIngressKey)) return false;
+
+        final TetherIngressKey that = (TetherIngressKey) obj;
+
+        return iif == that.iif && Arrays.equals(neigh6, that.neigh6);
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(iif) ^ Arrays.hashCode(neigh6);
+    }
+
+    @Override
+    public String toString() {
+        try {
+            return String.format("iif: %d, neigh: %s", iif, Inet6Address.getByAddress(neigh6));
+        } catch (UnknownHostException e) {
+            // Should not happen because construtor already verify neigh6.
+            throw new IllegalStateException("Invalid TetherIngressKey");
+        }
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherIngressValue.java b/Tethering/src/com/android/networkstack/tethering/TetherIngressValue.java
new file mode 100644
index 0000000..e2116fc
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherIngressValue.java
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+package com.android.networkstack.tethering;
+
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.util.Objects;
+
+/** The value of BpfMap which is used for bpf offload. */
+public class TetherIngressValue extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long oif; // The output interface index.
+
+    // The ethhdr struct which is defined in uapi/linux/if_ether.h
+    @Field(order = 1, type = Type.EUI48)
+    public final MacAddress ethDstMac; // The destination mac address.
+    @Field(order = 2, type = Type.EUI48)
+    public final MacAddress ethSrcMac; // The source mac address.
+    @Field(order = 3, type = Type.UBE16)
+    public final int ethProto; // Packet type ID field.
+
+    @Field(order = 4, type = Type.U16)
+    public final int pmtu; // The maximum L3 output path/route mtu.
+
+    public TetherIngressValue(final long oif, @NonNull final MacAddress ethDstMac,
+            @NonNull final MacAddress ethSrcMac, final int ethProto, final int pmtu) {
+        Objects.requireNonNull(ethSrcMac);
+        Objects.requireNonNull(ethDstMac);
+
+        this.oif = oif;
+        this.ethDstMac = ethDstMac;
+        this.ethSrcMac = ethSrcMac;
+        this.ethProto = ethProto;
+        this.pmtu = pmtu;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherIngressValue)) return false;
+
+        final TetherIngressValue that = (TetherIngressValue) obj;
+
+        return oif == that.oif && ethDstMac.equals(that.ethDstMac)
+                && ethSrcMac.equals(that.ethSrcMac) && ethProto == that.ethProto
+                && pmtu == that.pmtu;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(oif, ethDstMac, ethSrcMac, ethProto, pmtu);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("oif: %d, dstMac: %s, srcMac: %s, proto: %d, pmtu: %d", oif,
+                ethDstMac, ethSrcMac, ethProto, pmtu);
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 62ae88c..fdd1c40 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -93,7 +93,6 @@
 import android.net.TetheringRequestParcel;
 import android.net.ip.IpServer;
 import android.net.shared.NetdUtils;
-import android.net.util.BaseNetdUnsolicitedEventListener;
 import android.net.util.InterfaceSet;
 import android.net.util.PrefixUtils;
 import android.net.util.SharedLog;
@@ -132,6 +131,7 @@
 import com.android.internal.util.MessageUtils;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
new file mode 100644
index 0000000..1ddbaa9
--- /dev/null
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
@@ -0,0 +1,354 @@
+/*
+ * 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.
+ */
+
+package com.android.networkstack.tethering;
+
+import static android.system.OsConstants.ETH_P_IPV6;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.net.MacAddress;
+import android.os.Build;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import android.util.ArrayMap;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetAddress;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+@RunWith(AndroidJUnit4.class)
+@IgnoreUpTo(Build.VERSION_CODES.R)
+public final class BpfMapTest {
+    // Sync from packages/modules/Connectivity/Tethering/bpf_progs/offload.c.
+    private static final int TEST_MAP_SIZE = 16;
+    private static final String TETHER_INGRESS_FS_PATH =
+            "/sys/fs/bpf/map_offload_tether_ingress_map_TEST";
+
+    private ArrayMap<TetherIngressKey, TetherIngressValue> mTestData;
+
+    @BeforeClass
+    public static void setupOnce() {
+        System.loadLibrary("tetherutilsjni");
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        // TODO: Simply the test map creation and deletion.
+        // - Make the map a class member (mTestMap)
+        // - Open the test map RW in setUp
+        // - Close the test map in tearDown.
+        cleanTestMap();
+
+        mTestData = new ArrayMap<>();
+        mTestData.put(createTetherIngressKey(101, "2001:db8::1"),
+                createTetherIngressValue(11, "00:00:00:00:00:0a", "11:11:11:00:00:0b", ETH_P_IPV6,
+                1280));
+        mTestData.put(createTetherIngressKey(102, "2001:db8::2"),
+                createTetherIngressValue(22, "00:00:00:00:00:0c", "22:22:22:00:00:0d", ETH_P_IPV6,
+                1400));
+        mTestData.put(createTetherIngressKey(103, "2001:db8::3"),
+                createTetherIngressValue(33, "00:00:00:00:00:0e", "33:33:33:00:00:0f", ETH_P_IPV6,
+                1500));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        cleanTestMap();
+    }
+
+    private BpfMap<TetherIngressKey, TetherIngressValue> getTestMap() throws Exception {
+        return new BpfMap<>(
+                TETHER_INGRESS_FS_PATH, BpfMap.BPF_F_RDWR,
+                TetherIngressKey.class, TetherIngressValue.class);
+    }
+
+    private void cleanTestMap() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            bpfMap.forEach((key, value) -> {
+                try {
+                    assertTrue(bpfMap.deleteEntry(key));
+                } catch (ErrnoException e) {
+                    fail("Fail to delete the key " + key + ": " + e);
+                }
+            });
+            assertNull(bpfMap.getFirstKey());
+        }
+    }
+
+    private TetherIngressKey createTetherIngressKey(long iif, String address) throws Exception {
+        final InetAddress ipv6Address = InetAddress.getByName(address);
+
+        return new TetherIngressKey(iif, ipv6Address.getAddress());
+    }
+
+    private TetherIngressValue createTetherIngressValue(long oif, String src, String dst, int proto,
+            int pmtu) throws Exception {
+        final MacAddress srcMac = MacAddress.fromString(src);
+        final MacAddress dstMac = MacAddress.fromString(dst);
+
+        return new TetherIngressValue(oif, dstMac, srcMac, proto, pmtu);
+    }
+
+    @Test
+    public void testGetFd() throws Exception {
+        try (BpfMap readOnlyMap = new BpfMap<>(TETHER_INGRESS_FS_PATH, BpfMap.BPF_F_RDONLY,
+                TetherIngressKey.class, TetherIngressValue.class)) {
+            assertNotNull(readOnlyMap);
+            try {
+                readOnlyMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+                fail("Writing RO map should throw ErrnoException");
+            } catch (ErrnoException expected) {
+                assertEquals(OsConstants.EPERM, expected.errno);
+            }
+        }
+        try (BpfMap writeOnlyMap = new BpfMap<>(TETHER_INGRESS_FS_PATH, BpfMap.BPF_F_WRONLY,
+                TetherIngressKey.class, TetherIngressValue.class)) {
+            assertNotNull(writeOnlyMap);
+            try {
+                writeOnlyMap.getFirstKey();
+                fail("Reading WO map should throw ErrnoException");
+            } catch (ErrnoException expected) {
+                assertEquals(OsConstants.EPERM, expected.errno);
+            }
+        }
+        try (BpfMap readWriteMap = new BpfMap<>(TETHER_INGRESS_FS_PATH, BpfMap.BPF_F_RDWR,
+                TetherIngressKey.class, TetherIngressValue.class)) {
+            assertNotNull(readWriteMap);
+        }
+    }
+
+    @Test
+    public void testGetFirstKey() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            // getFirstKey on an empty map returns null.
+            assertFalse(bpfMap.containsKey(mTestData.keyAt(0)));
+            assertNull(bpfMap.getFirstKey());
+            assertNull(bpfMap.getValue(mTestData.keyAt(0)));
+
+            // getFirstKey on a non-empty map returns the first key.
+            bpfMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+            assertEquals(mTestData.keyAt(0), bpfMap.getFirstKey());
+        }
+    }
+
+    @Test
+    public void testGetNextKey() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            // [1] If the passed-in key is not found on empty map, return null.
+            final TetherIngressKey nonexistentKey = createTetherIngressKey(1234, "2001:db8::10");
+            assertNull(bpfMap.getNextKey(nonexistentKey));
+
+            // [2] If the passed-in key is null on empty map, throw NullPointerException.
+            try {
+                bpfMap.getNextKey(null);
+                fail("Getting next key with null key should throw NullPointerException");
+            } catch (NullPointerException expected) { }
+
+            // The BPF map has one entry now.
+            final ArrayMap<TetherIngressKey, TetherIngressValue> resultMap = new ArrayMap<>();
+            bpfMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+            resultMap.put(mTestData.keyAt(0), mTestData.valueAt(0));
+
+            // [3] If the passed-in key is the last key, return null.
+            // Because there is only one entry in the map, the first key equals the last key.
+            final TetherIngressKey lastKey = bpfMap.getFirstKey();
+            assertNull(bpfMap.getNextKey(lastKey));
+
+            // The BPF map has two entries now.
+            bpfMap.insertEntry(mTestData.keyAt(1), mTestData.valueAt(1));
+            resultMap.put(mTestData.keyAt(1), mTestData.valueAt(1));
+
+            // [4] If the passed-in key is found, return the next key.
+            TetherIngressKey nextKey = bpfMap.getFirstKey();
+            while (nextKey != null) {
+                if (resultMap.remove(nextKey).equals(nextKey)) {
+                    fail("Unexpected result: " + nextKey);
+                }
+                nextKey = bpfMap.getNextKey(nextKey);
+            }
+            assertTrue(resultMap.isEmpty());
+
+            // [5] If the passed-in key is not found on non-empty map, return the first key.
+            assertEquals(bpfMap.getFirstKey(), bpfMap.getNextKey(nonexistentKey));
+
+            // [6] If the passed-in key is null on non-empty map, throw NullPointerException.
+            try {
+                bpfMap.getNextKey(null);
+                fail("Getting next key with null key should throw NullPointerException");
+            } catch (NullPointerException expected) { }
+        }
+    }
+
+    @Test
+    public void testUpdateBpfMap() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+
+            final TetherIngressKey key = mTestData.keyAt(0);
+            final TetherIngressValue value = mTestData.valueAt(0);
+            final TetherIngressValue value2 = mTestData.valueAt(1);
+            assertFalse(bpfMap.deleteEntry(key));
+
+            // updateEntry will create an entry if it does not exist already.
+            bpfMap.updateEntry(key, value);
+            assertTrue(bpfMap.containsKey(key));
+            final TetherIngressValue result = bpfMap.getValue(key);
+            assertEquals(value, result);
+
+            // updateEntry will update an entry that already exists.
+            bpfMap.updateEntry(key, value2);
+            assertTrue(bpfMap.containsKey(key));
+            final TetherIngressValue result2 = bpfMap.getValue(key);
+            assertEquals(value2, result2);
+
+            assertTrue(bpfMap.deleteEntry(key));
+            assertFalse(bpfMap.containsKey(key));
+        }
+    }
+
+    @Test
+    public void testInsertReplaceEntry() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+
+            final TetherIngressKey key = mTestData.keyAt(0);
+            final TetherIngressValue value = mTestData.valueAt(0);
+            final TetherIngressValue value2 = mTestData.valueAt(1);
+
+            try {
+                bpfMap.replaceEntry(key, value);
+                fail("Replacing non-existent key " + key + " should throw NoSuchElementException");
+            } catch (NoSuchElementException expected) { }
+            assertFalse(bpfMap.containsKey(key));
+
+            bpfMap.insertEntry(key, value);
+            assertTrue(bpfMap.containsKey(key));
+            final TetherIngressValue result = bpfMap.getValue(key);
+            assertEquals(value, result);
+            try {
+                bpfMap.insertEntry(key, value);
+                fail("Inserting existing key " + key + " should throw IllegalStateException");
+            } catch (IllegalStateException expected) { }
+
+            bpfMap.replaceEntry(key, value2);
+            assertTrue(bpfMap.containsKey(key));
+            final TetherIngressValue result2 = bpfMap.getValue(key);
+            assertEquals(value2, result2);
+        }
+    }
+
+    @Test
+    public void testIterateBpfMap() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            final ArrayMap<TetherIngressKey, TetherIngressValue> resultMap =
+                    new ArrayMap<>(mTestData);
+
+            for (int i = 0; i < resultMap.size(); i++) {
+                bpfMap.insertEntry(resultMap.keyAt(i), resultMap.valueAt(i));
+            }
+
+            bpfMap.forEach((key, value) -> {
+                if (!value.equals(resultMap.remove(key))) {
+                    fail("Unexpected result: " + key + ", value: " + value);
+                }
+            });
+            assertTrue(resultMap.isEmpty());
+        }
+    }
+
+    @Test
+    public void testIterateEmptyMap() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            // Can't use an int because variables used in a lambda must be final.
+            final AtomicInteger count = new AtomicInteger();
+            bpfMap.forEach((key, value) -> count.incrementAndGet());
+            // Expect that the consumer was never called.
+            assertEquals(0, count.get());
+        }
+    }
+
+    @Test
+    public void testIterateDeletion() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            final ArrayMap<TetherIngressKey, TetherIngressValue> resultMap =
+                    new ArrayMap<>(mTestData);
+
+            for (int i = 0; i < resultMap.size(); i++) {
+                bpfMap.insertEntry(resultMap.keyAt(i), resultMap.valueAt(i));
+            }
+
+            // Can't use an int because variables used in a lambda must be final.
+            final AtomicInteger count = new AtomicInteger();
+            bpfMap.forEach((key, value) -> {
+                try {
+                    assertTrue(bpfMap.deleteEntry(key));
+                } catch (ErrnoException e) {
+                    fail("Fail to delete key " + key + ": " + e);
+                }
+                if (!value.equals(resultMap.remove(key))) {
+                    fail("Unexpected result: " + key + ", value: " + value);
+                }
+                count.incrementAndGet();
+            });
+            assertEquals(3, count.get());
+            assertTrue(resultMap.isEmpty());
+            assertNull(bpfMap.getFirstKey());
+        }
+    }
+
+    @Test
+    public void testInsertOverflow() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            final ArrayMap<TetherIngressKey, TetherIngressValue> testData = new ArrayMap<>();
+
+            // Build test data for TEST_MAP_SIZE + 1 entries.
+            for (int i = 1; i <= TEST_MAP_SIZE + 1; i++) {
+                testData.put(createTetherIngressKey(i, "2001:db8::1"), createTetherIngressValue(
+                        100, "de:ad:be:ef:00:01", "de:ad:be:ef:00:02", ETH_P_IPV6, 1500));
+            }
+
+            // Insert #TEST_MAP_SIZE test entries to the map. The map has reached the limit.
+            for (int i = 0; i < TEST_MAP_SIZE; i++) {
+                bpfMap.insertEntry(testData.keyAt(i), testData.valueAt(i));
+            }
+
+            // The map won't allow inserting any more entries.
+            try {
+                bpfMap.insertEntry(testData.keyAt(TEST_MAP_SIZE), testData.valueAt(TEST_MAP_SIZE));
+                fail("Writing too many entries should throw ErrnoException");
+            } catch (ErrnoException expected) {
+                // Expect that can't insert the entry anymore because the number of elements in the
+                // map reached the limit. See man-pages/bpf.
+                assertEquals(OsConstants.E2BIG, expected.errno);
+            }
+        }
+    }
+}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 71f6f2f..f423503 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -234,12 +234,16 @@
     }
 
     protected void assertForegroundNetworkAccess() throws Exception {
+        assertForegroundNetworkAccess(true);
+    }
+
+    protected void assertForegroundNetworkAccess(boolean expectAllowed) throws Exception {
         assertForegroundState();
         // We verified that app is in foreground state but if the screen turns-off while
         // verifying for network access, the app will go into background state (in case app's
         // foreground status was due to top activity). So, turn the screen on when verifying
         // network connectivity.
-        assertNetworkAccess(true /* expectAvailable */, true /* needScreenOn */);
+        assertNetworkAccess(expectAllowed /* expectAvailable */, true /* needScreenOn */);
     }
 
     protected void assertForegroundServiceNetworkAccess() throws Exception {
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java
new file mode 100644
index 0000000..29d3c6e
--- /dev/null
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+package com.android.cts.net.hostside;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public final class RestrictedModeTest extends AbstractRestrictBackgroundNetworkTestCase {
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        setRestrictedMode(false);
+        super.tearDown();
+    }
+
+    private void setRestrictedMode(boolean enabled) throws Exception {
+        executeSilentShellCommand(
+                "settings put global restricted_networking_mode " + (enabled ? 1 : 0));
+        assertRestrictedModeState(enabled);
+    }
+
+    private void assertRestrictedModeState(boolean enabled) throws Exception {
+        assertDelayedShellCommand("cmd netpolicy get restricted-mode",
+                "Restricted mode status: " + (enabled ? "enabled" : "disabled"));
+    }
+
+    @Test
+    public void testNetworkAccess() throws Exception {
+        setRestrictedMode(false);
+
+        // go to foreground state and enable restricted mode
+        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
+        setRestrictedMode(true);
+        assertForegroundNetworkAccess(false);
+
+        // go to background state
+        finishActivity();
+        assertBackgroundNetworkAccess(false);
+
+        // disable restricted mode and assert network access in foreground and background states
+        setRestrictedMode(false);
+        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
+        assertForegroundNetworkAccess(true);
+
+        // go to background state
+        finishActivity();
+        assertBackgroundNetworkAccess(true);
+    }
+}
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index ac28c7a..a629ccf 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -311,6 +311,14 @@
                 "testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists");
     }
 
+    /**************************
+     * Restricted mode tests. *
+     **************************/
+    public void testRestrictedMode_networkAccess() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".RestrictedModeTest",
+                "testNetworkAccess");
+    }
+
     /*******************
      * Helper methods. *
      *******************/
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 803c9d8..69d90aa 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -126,7 +126,7 @@
 @RunWith(AndroidJUnit4::class)
 class NetworkAgentTest {
     @Rule @JvmField
-    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q)
+    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.R)
 
     private val LOCAL_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1")
     private val REMOTE_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.2")
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/cts/NsdManagerTest.java
new file mode 100644
index 0000000..2bcfdc3
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.java
@@ -0,0 +1,594 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts;
+
+import android.content.Context;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.platform.test.annotations.AppModeFull;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.List;
+import java.util.ArrayList;
+
+@AppModeFull(reason = "Socket cannot bind in instant app mode")
+public class NsdManagerTest extends AndroidTestCase {
+
+    private static final String TAG = "NsdManagerTest";
+    private static final String SERVICE_TYPE = "_nmt._tcp";
+    private static final int TIMEOUT = 2000;
+
+    private static final boolean DBG = false;
+
+    NsdManager mNsdManager;
+
+    NsdManager.RegistrationListener mRegistrationListener;
+    NsdManager.DiscoveryListener mDiscoveryListener;
+    NsdManager.ResolveListener mResolveListener;
+    private NsdServiceInfo mResolvedService;
+
+    public NsdManagerTest() {
+        initRegistrationListener();
+        initDiscoveryListener();
+        initResolveListener();
+    }
+
+    private void initRegistrationListener() {
+        mRegistrationListener = new NsdManager.RegistrationListener() {
+            @Override
+            public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
+                setEvent("onRegistrationFailed", errorCode);
+            }
+
+            @Override
+            public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
+                setEvent("onUnregistrationFailed", errorCode);
+            }
+
+            @Override
+            public void onServiceRegistered(NsdServiceInfo serviceInfo) {
+                setEvent("onServiceRegistered", serviceInfo);
+            }
+
+            @Override
+            public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
+                setEvent("onServiceUnregistered", serviceInfo);
+            }
+        };
+    }
+
+    private void initDiscoveryListener() {
+        mDiscoveryListener = new NsdManager.DiscoveryListener() {
+            @Override
+            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
+                setEvent("onStartDiscoveryFailed", errorCode);
+            }
+
+            @Override
+            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
+                setEvent("onStopDiscoveryFailed", errorCode);
+            }
+
+            @Override
+            public void onDiscoveryStarted(String serviceType) {
+                NsdServiceInfo info = new NsdServiceInfo();
+                info.setServiceType(serviceType);
+                setEvent("onDiscoveryStarted", info);
+            }
+
+            @Override
+            public void onDiscoveryStopped(String serviceType) {
+                NsdServiceInfo info = new NsdServiceInfo();
+                info.setServiceType(serviceType);
+                setEvent("onDiscoveryStopped", info);
+            }
+
+            @Override
+            public void onServiceFound(NsdServiceInfo serviceInfo) {
+                setEvent("onServiceFound", serviceInfo);
+            }
+
+            @Override
+            public void onServiceLost(NsdServiceInfo serviceInfo) {
+                setEvent("onServiceLost", serviceInfo);
+            }
+        };
+    }
+
+    private void initResolveListener() {
+        mResolveListener = new NsdManager.ResolveListener() {
+            @Override
+            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
+                setEvent("onResolveFailed", errorCode);
+            }
+
+            @Override
+            public void onServiceResolved(NsdServiceInfo serviceInfo) {
+                mResolvedService = serviceInfo;
+                setEvent("onServiceResolved", serviceInfo);
+            }
+        };
+    }
+
+
+
+    private final class EventData {
+        EventData(String callbackName, NsdServiceInfo info) {
+            mCallbackName = callbackName;
+            mSucceeded = true;
+            mErrorCode = 0;
+            mInfo = info;
+        }
+        EventData(String callbackName, int errorCode) {
+            mCallbackName = callbackName;
+            mSucceeded = false;
+            mErrorCode = errorCode;
+            mInfo = null;
+        }
+        private final String mCallbackName;
+        private final boolean mSucceeded;
+        private final int mErrorCode;
+        private final NsdServiceInfo mInfo;
+    }
+
+    private final List<EventData> mEventCache = new ArrayList<EventData>();
+
+    private void setEvent(String callbackName, int errorCode) {
+        if (DBG) Log.d(TAG, callbackName + " failed with " + String.valueOf(errorCode));
+        EventData eventData = new EventData(callbackName, errorCode);
+        synchronized (mEventCache) {
+            mEventCache.add(eventData);
+            mEventCache.notify();
+        }
+    }
+
+    private void setEvent(String callbackName, NsdServiceInfo info) {
+        if (DBG) Log.d(TAG, "Received event " + callbackName + " for " + info.getServiceName());
+        EventData eventData = new EventData(callbackName, info);
+        synchronized (mEventCache) {
+            mEventCache.add(eventData);
+            mEventCache.notify();
+        }
+    }
+
+    void clearEventCache() {
+        synchronized(mEventCache) {
+            mEventCache.clear();
+        }
+    }
+
+    int eventCacheSize() {
+        synchronized(mEventCache) {
+            return mEventCache.size();
+        }
+    }
+
+    private int mWaitId = 0;
+    private EventData waitForCallback(String callbackName) {
+
+        synchronized(mEventCache) {
+
+            mWaitId ++;
+            if (DBG) Log.d(TAG, "Waiting for " + callbackName + ", id=" + String.valueOf(mWaitId));
+
+            try {
+                long startTime = android.os.SystemClock.uptimeMillis();
+                long elapsedTime = 0;
+                int index = 0;
+                while (elapsedTime < TIMEOUT ) {
+                    // first check if we've received that event
+                    for (; index < mEventCache.size(); index++) {
+                        EventData e = mEventCache.get(index);
+                        if (e.mCallbackName.equals(callbackName)) {
+                            if (DBG) Log.d(TAG, "exiting wait id=" + String.valueOf(mWaitId));
+                            return e;
+                        }
+                    }
+
+                    // Not yet received, just wait
+                    mEventCache.wait(TIMEOUT - elapsedTime);
+                    elapsedTime = android.os.SystemClock.uptimeMillis() - startTime;
+                }
+                // we exited the loop because of TIMEOUT; fail the call
+                if (DBG) Log.d(TAG, "timed out waiting id=" + String.valueOf(mWaitId));
+                return null;
+            } catch (InterruptedException e) {
+                return null;                       // wait timed out!
+            }
+        }
+    }
+
+    private EventData waitForNewEvents() throws InterruptedException {
+        if (DBG) Log.d(TAG, "Waiting for a bit, id=" + String.valueOf(mWaitId));
+
+        long startTime = android.os.SystemClock.uptimeMillis();
+        long elapsedTime = 0;
+        synchronized (mEventCache) {
+            int index = mEventCache.size();
+            while (elapsedTime < TIMEOUT ) {
+                // first check if we've received that event
+                for (; index < mEventCache.size(); index++) {
+                    EventData e = mEventCache.get(index);
+                    return e;
+                }
+
+                // Not yet received, just wait
+                mEventCache.wait(TIMEOUT - elapsedTime);
+                elapsedTime = android.os.SystemClock.uptimeMillis() - startTime;
+            }
+        }
+
+        return null;
+    }
+
+    private String mServiceName;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        if (DBG) Log.d(TAG, "Setup test ...");
+        mNsdManager = (NsdManager) getContext().getSystemService(Context.NSD_SERVICE);
+
+        Random rand = new Random();
+        mServiceName = new String("NsdTest");
+        for (int i = 0; i < 4; i++) {
+            mServiceName = mServiceName + String.valueOf(rand.nextInt(10));
+        }
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        if (DBG) Log.d(TAG, "Tear down test ...");
+        super.tearDown();
+    }
+
+    public void testNDSManager() throws Exception {
+        EventData lastEvent = null;
+
+        if (DBG) Log.d(TAG, "Starting test ...");
+
+        NsdServiceInfo si = new NsdServiceInfo();
+        si.setServiceType(SERVICE_TYPE);
+        si.setServiceName(mServiceName);
+
+        byte testByteArray[] = new byte[] {-128, 127, 2, 1, 0, 1, 2};
+        String String256 = "1_________2_________3_________4_________5_________6_________" +
+                 "7_________8_________9_________10________11________12________13________" +
+                 "14________15________16________17________18________19________20________" +
+                 "21________22________23________24________25________123456";
+
+        // Illegal attributes
+        try {
+            si.setAttribute(null, (String) null);
+            fail("Could set null key");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("", (String) null);
+            fail("Could set empty key");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute(String256, (String) null);
+            fail("Could set key with 255 characters");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("key", String256.substring(3));
+            fail("Could set key+value combination with more than 255 characters");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("key", String256.substring(4));
+            fail("Could set key+value combination with 255 characters");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute(new String(new byte[]{0x19}), (String) null);
+            fail("Could set key with invalid character");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("=", (String) null);
+            fail("Could set key with invalid character");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute(new String(new byte[]{0x7F}), (String) null);
+            fail("Could set key with invalid character");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        // Allowed attributes
+        si.setAttribute("booleanAttr", (String) null);
+        si.setAttribute("keyValueAttr", "value");
+        si.setAttribute("keyEqualsAttr", "=");
+        si.setAttribute(" whiteSpaceKeyValueAttr ", " value ");
+        si.setAttribute("binaryDataAttr", testByteArray);
+        si.setAttribute("nullBinaryDataAttr", (byte[]) null);
+        si.setAttribute("emptyBinaryDataAttr", new byte[]{});
+        si.setAttribute("longkey", String256.substring(9));
+
+        ServerSocket socket;
+        int localPort;
+
+        try {
+            socket = new ServerSocket(0);
+            localPort = socket.getLocalPort();
+            si.setPort(localPort);
+        } catch (IOException e) {
+            if (DBG) Log.d(TAG, "Could not open a local socket");
+            assertTrue(false);
+            return;
+        }
+
+        if (DBG) Log.d(TAG, "Port = " + String.valueOf(localPort));
+
+        clearEventCache();
+
+        mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
+        lastEvent = waitForCallback("onServiceRegistered");                 // id = 1
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+        assertTrue(eventCacheSize() == 1);
+
+        // We may not always get the name that we tried to register;
+        // This events tells us the name that was registered.
+        String registeredName = lastEvent.mInfo.getServiceName();
+        si.setServiceName(registeredName);
+
+        clearEventCache();
+
+        mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
+                mDiscoveryListener);
+
+        // Expect discovery started
+        lastEvent = waitForCallback("onDiscoveryStarted");                  // id = 2
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        // Remove this event, so accounting becomes easier later
+        synchronized (mEventCache) {
+            mEventCache.remove(lastEvent);
+        }
+
+        // Expect a service record to be discovered (and filter the ones
+        // that are unrelated to this test)
+        boolean found = false;
+        for (int i = 0; i < 32; i++) {
+
+            lastEvent = waitForCallback("onServiceFound");                  // id = 3
+            if (lastEvent == null) {
+                // no more onServiceFound events are being reported!
+                break;
+            }
+
+            assertTrue(lastEvent.mSucceeded);
+
+            if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
+                    lastEvent.mInfo.getServiceName());
+
+            if (lastEvent.mInfo.getServiceName().equals(registeredName)) {
+                // Save it, as it will get overwritten with new serviceFound events
+                si = lastEvent.mInfo;
+                found = true;
+            }
+
+            // Remove this event from the event cache, so it won't be found by subsequent
+            // calls to waitForCallback
+            synchronized (mEventCache) {
+                mEventCache.remove(lastEvent);
+            }
+        }
+
+        assertTrue(found);
+
+        // We've removed all serviceFound events, and we've removed the discoveryStarted
+        // event as well, so now the event cache should be empty!
+        assertTrue(eventCacheSize() == 0);
+
+        // Resolve the service
+        clearEventCache();
+        mNsdManager.resolveService(si, mResolveListener);
+        lastEvent = waitForCallback("onServiceResolved");                   // id = 4
+
+        assertNotNull(mResolvedService);
+
+        // Check Txt attributes
+        assertEquals(8, mResolvedService.getAttributes().size());
+        assertTrue(mResolvedService.getAttributes().containsKey("booleanAttr"));
+        assertNull(mResolvedService.getAttributes().get("booleanAttr"));
+        assertEquals("value", new String(mResolvedService.getAttributes().get("keyValueAttr")));
+        assertEquals("=", new String(mResolvedService.getAttributes().get("keyEqualsAttr")));
+        assertEquals(" value ", new String(mResolvedService.getAttributes()
+                .get(" whiteSpaceKeyValueAttr ")));
+        assertEquals(String256.substring(9), new String(mResolvedService.getAttributes()
+                .get("longkey")));
+        assertTrue(Arrays.equals(testByteArray,
+                mResolvedService.getAttributes().get("binaryDataAttr")));
+        assertTrue(mResolvedService.getAttributes().containsKey("nullBinaryDataAttr"));
+        assertNull(mResolvedService.getAttributes().get("nullBinaryDataAttr"));
+        assertTrue(mResolvedService.getAttributes().containsKey("emptyBinaryDataAttr"));
+        assertNull(mResolvedService.getAttributes().get("emptyBinaryDataAttr"));
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": Port = " +
+                String.valueOf(lastEvent.mInfo.getPort()));
+
+        assertTrue(lastEvent.mInfo.getPort() == localPort);
+        assertTrue(eventCacheSize() == 1);
+
+        checkForAdditionalEvents();
+        clearEventCache();
+
+        // Unregister the service
+        mNsdManager.unregisterService(mRegistrationListener);
+        lastEvent = waitForCallback("onServiceUnregistered");               // id = 5
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        // Expect a callback for service lost
+        lastEvent = waitForCallback("onServiceLost");                       // id = 6
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName));
+
+        // Register service again to see if we discover it
+        checkForAdditionalEvents();
+        clearEventCache();
+
+        si = new NsdServiceInfo();
+        si.setServiceType(SERVICE_TYPE);
+        si.setServiceName(mServiceName);
+        si.setPort(localPort);
+
+        // Create a new registration listener and register same service again
+        initRegistrationListener();
+
+        mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
+
+        lastEvent = waitForCallback("onServiceRegistered");                 // id = 7
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        registeredName = lastEvent.mInfo.getServiceName();
+
+        // Expect a record to be discovered
+        // Expect a service record to be discovered (and filter the ones
+        // that are unrelated to this test)
+        found = false;
+        for (int i = 0; i < 32; i++) {
+
+            lastEvent = waitForCallback("onServiceFound");                  // id = 8
+            if (lastEvent == null) {
+                // no more onServiceFound events are being reported!
+                break;
+            }
+
+            assertTrue(lastEvent.mSucceeded);
+
+            if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
+                    lastEvent.mInfo.getServiceName());
+
+            if (lastEvent.mInfo.getServiceName().equals(registeredName)) {
+                // Save it, as it will get overwritten with new serviceFound events
+                si = lastEvent.mInfo;
+                found = true;
+            }
+
+            // Remove this event from the event cache, so it won't be found by subsequent
+            // calls to waitForCallback
+            synchronized (mEventCache) {
+                mEventCache.remove(lastEvent);
+            }
+        }
+
+        assertTrue(found);
+
+        // Resolve the service
+        clearEventCache();
+        mNsdManager.resolveService(si, mResolveListener);
+        lastEvent = waitForCallback("onServiceResolved");                   // id = 9
+
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+
+        if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
+                lastEvent.mInfo.getServiceName());
+
+        assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName));
+
+        assertNotNull(mResolvedService);
+
+        // Check that we don't have any TXT records
+        assertEquals(0, mResolvedService.getAttributes().size());
+
+        checkForAdditionalEvents();
+        clearEventCache();
+
+        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
+        lastEvent = waitForCallback("onDiscoveryStopped");                  // id = 10
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+        assertTrue(checkCacheSize(1));
+
+        checkForAdditionalEvents();
+        clearEventCache();
+
+        mNsdManager.unregisterService(mRegistrationListener);
+
+        lastEvent =  waitForCallback("onServiceUnregistered");              // id = 11
+        assertTrue(lastEvent != null);
+        assertTrue(lastEvent.mSucceeded);
+        assertTrue(checkCacheSize(1));
+    }
+
+    boolean checkCacheSize(int size) {
+        synchronized (mEventCache) {
+            int cacheSize = mEventCache.size();
+            if (cacheSize != size) {
+                Log.d(TAG, "id = " + mWaitId + ": event cache size = " + cacheSize);
+                for (int i = 0; i < cacheSize; i++) {
+                    EventData e = mEventCache.get(i);
+                    String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : "";
+                    Log.d(TAG, "eventName is " + e.mCallbackName + sname);
+                }
+            }
+            return (cacheSize == size);
+        }
+    }
+
+    boolean checkForAdditionalEvents() {
+        try {
+            EventData e = waitForNewEvents();
+            if (e != null) {
+                String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : "";
+                Log.d(TAG, "ignoring unexpected event " + e.mCallbackName + sname);
+            }
+            return (e == null);
+        }
+        catch (InterruptedException ex) {
+            return false;
+        }
+    }
+}
+
