diff --git a/Tethering/AndroidManifest.xml b/Tethering/AndroidManifest.xml
index 6deb345..b832e16 100644
--- a/Tethering/AndroidManifest.xml
+++ b/Tethering/AndroidManifest.xml
@@ -41,6 +41,7 @@
     <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
     <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
 
     <protected-broadcast android:name="com.android.server.connectivity.tethering.DISABLE_TETHERING" />
 
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 4c4368f..b709693 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -22,16 +22,16 @@
 // different value depending on the branch.
 java_defaults {
     name: "ConnectivityNextEnableDefaults",
-    enabled: false,
+    enabled: true,
 }
 apex_defaults {
     name: "ConnectivityApexDefaults",
     // Tethering app to include in the AOSP apex. Branches that disable the "next" targets may use
     // a stable tethering app instead, but will generally override the AOSP apex to use updatable
     // package names and keys, so that apex will be unused anyway.
-    apps: ["Tethering"], // Replace to "Tethering" if ConnectivityNextEnableDefaults is false.
+    apps: ["TetheringNext"], // Replace to "Tethering" if ConnectivityNextEnableDefaults is false.
 }
-enable_tethering_next_apex = false
+enable_tethering_next_apex = true
 // This is a placeholder comment to avoid merge conflicts
 // as the above target may have different "enabled" values
 // depending on the branch
@@ -60,8 +60,7 @@
         both: {
             jni_libs: [
                 "libframework-connectivity-jni",
-                // Changed in sc-mainline-prod only: no framework-connectivity-t
-                // "libframework-connectivity-tiramisu-jni"
+                "libframework-connectivity-tiramisu-jni"
             ],
         },
     },
@@ -78,6 +77,7 @@
     ],
     apps: [
         "ServiceConnectivityResources",
+        "HalfSheetUX",
     ],
     prebuilts: [
         "current_sdkinfo",
@@ -108,7 +108,7 @@
     name: "com.android.tethering-bootclasspath-fragment",
     contents: [
         "framework-connectivity",
-        // Changed in sc-mainline-prod only: no framework-connectivity-t
+        "framework-connectivity-t",
         "framework-tethering",
     ],
     apex_available: ["com.android.tethering"],
@@ -131,18 +131,15 @@
     // modified by the Soong or platform compat team.
     hidden_api: {
         max_target_r_low_priority: [
-            // Changed in sc-mainline-prod only: no list for
-            // framework-connectivity-t APIs as it is not in the APEX
+            "hiddenapi/hiddenapi-max-target-r-loprio.txt",
 	],
         max_target_o_low_priority: [
             "hiddenapi/hiddenapi-max-target-o-low-priority.txt",
-            // Changed in sc-mainline-prod only: no list for
-            // framework-connectivity-t APIs as it is not in the APEX
+            "hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt",
 	],
         unsupported: [
             "hiddenapi/hiddenapi-unsupported.txt",
-            // Changed in sc-mainline-prod only: no framework-connectivity-t
-            // "hiddenapi/hiddenapi-unsupported-tiramisu.txt",
+            "hiddenapi/hiddenapi-unsupported-tiramisu.txt",
         ],
     },
 }
diff --git a/Tethering/common/TetheringLib/Android.bp b/Tethering/common/TetheringLib/Android.bp
index 25489ff..9ca3f14 100644
--- a/Tethering/common/TetheringLib/Android.bp
+++ b/Tethering/common/TetheringLib/Android.bp
@@ -21,7 +21,6 @@
     name: "framework-tethering",
     defaults: ["framework-module-defaults"],
     impl_library_visibility: [
-        "//frameworks/base/packages/Tethering:__subpackages__",
         "//packages/modules/Connectivity/Tethering:__subpackages__",
 
         // Using for test only
diff --git a/Tethering/tests/unit/Android.bp b/Tethering/tests/unit/Android.bp
index d1b8380..37b1bc8 100644
--- a/Tethering/tests/unit/Android.bp
+++ b/Tethering/tests/unit/Android.bp
@@ -67,6 +67,7 @@
         "ext",
         "framework-minus-apex",
         "framework-res",
+        "framework-bluetooth.stubs.module_lib",
         "framework-connectivity.impl",
         "framework-connectivity-t.impl",
         "framework-tethering.impl",
diff --git a/buildstubs-t/Android.bp b/buildstubs-t/Android.bp
deleted file mode 100644
index 9ca3fd2..0000000
--- a/buildstubs-t/Android.bp
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// 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 {
-    // See: http://go/android-license-faq
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-// Placeholder empty filegroups to avoid merge conflicts on build rules
-// on a branch that does not have the filegroups
-
-filegroup {
-    name: "framework-connectivity-tiramisu-updatable-sources",
-    srcs: [],
-}
-
-filegroup {
-    name: "services.connectivity-tiramisu-updatable-sources",
-    srcs: ["stubs-src/**/*.java"],
-}
-
-filegroup {
-    name: "framework-connectivity-api-shared-srcs",
-    srcs: [],
-}
-
-filegroup {
-    name: "ethernet-service-updatable-sources",
-    srcs: [],
-}
-
-filegroup {
-    name: "services.connectivity-netstats-jni-sources",
-    srcs: [
-        "stubs-src-jni/mock_com_android_server_net_NetworkStatsFactory.cpp",
-        "stubs-src-jni/mock_com_android_server_net_NetworkStatsService.cpp",
-    ],
-    visibility: [
-        "//packages/modules/Connectivity:__subpackages__",
-    ],
-}
-
-filegroup {
-    name: "framework-connectivity-tiramisu-jni-sources",
-    srcs: [
-        "stubs-src-jni/mock_android_net_TrafficStats.cpp",
-    ],
-    visibility: [
-        "//packages/modules/Connectivity:__subpackages__",
-    ],
-}
-
-// Empty replacement for framework-connectivity-t.impl and stubs,
-// as framework-connectivity is disabled in the branch
-java_library {
-    name: "framework-connectivity-t.impl",
-    min_sdk_version: "Tiramisu",
-    sdk_version: "module_current",
-    srcs: [],
-}
-
-java_library {
-    name: "framework-connectivity-t.stubs.module_lib",
-    min_sdk_version: "Tiramisu",
-    sdk_version: "module_current",
-    srcs: [],
-}
diff --git a/buildstubs-t/stubs-src-jni/mock_android_net_TrafficStats.cpp b/buildstubs-t/stubs-src-jni/mock_android_net_TrafficStats.cpp
deleted file mode 100644
index ef5d874..0000000
--- a/buildstubs-t/stubs-src-jni/mock_android_net_TrafficStats.cpp
+++ /dev/null
@@ -1,25 +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.
- */
-
-#include <nativehelper/JNIHelp.h>
-
-namespace android {
-
-int register_android_net_TrafficStats(JNIEnv* env) {
-    return JNI_ERR;
-}
-
-};  // namespace android
diff --git a/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsFactory.cpp b/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsFactory.cpp
deleted file mode 100644
index 594a174..0000000
--- a/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsFactory.cpp
+++ /dev/null
@@ -1,25 +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.
- */
-
-#include <nativehelper/JNIHelp.h>
-
-namespace android {
-
-int register_android_server_net_NetworkStatsFactory(JNIEnv* env) {
-    return JNI_ERR;
-}
-
-};  // namespace android
diff --git a/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsService.cpp b/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsService.cpp
deleted file mode 100644
index b0c42b0..0000000
--- a/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsService.cpp
+++ /dev/null
@@ -1,25 +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.
- */
-
-#include <nativehelper/JNIHelp.h>
-
-namespace android {
-
-int register_android_server_net_NetworkStatsService(JNIEnv* env) {
-    return JNI_ERR;
-}
-
-};  // namespace android
diff --git a/buildstubs-t/stubs-src/android/net/TrafficStats.java b/buildstubs-t/stubs-src/android/net/TrafficStats.java
deleted file mode 100644
index 0b208ac..0000000
--- a/buildstubs-t/stubs-src/android/net/TrafficStats.java
+++ /dev/null
@@ -1,31 +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.
- */
-
-package android.net;
-
-import android.content.Context;
-
-/**
- * Fake TrafficStats class for sc-mainline-prod,
- * to allow building the T service-connectivity before sources
- * are moved to the branch.
- */
-public final class TrafficStats {
-    /** Init */
-    public static void init(Context context) {
-        throw new RuntimeException("This is a stub class");
-    }
-}
diff --git a/buildstubs-t/stubs-src/com/android/server/EthernetService.java b/buildstubs-t/stubs-src/com/android/server/EthernetService.java
deleted file mode 100644
index 4a06e1e..0000000
--- a/buildstubs-t/stubs-src/com/android/server/EthernetService.java
+++ /dev/null
@@ -1,31 +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.
- */
-
-package com.android.server.ethernet;
-
-import android.content.Context;
-
-/**
- * Fake EthernetService class for branches that do not have the updatable EthernetService yet,
- * to allow building the T service-connectivity before sources are moved to the branch.
- */
-public final class EthernetService {
-    /** Create instance */
-    public static EthernetServiceImpl create(Context ctx) {
-        throw new RuntimeException("This is a stub class");
-    }
-}
-
diff --git a/buildstubs-t/stubs-src/com/android/server/EthernetServiceImpl.java b/buildstubs-t/stubs-src/com/android/server/EthernetServiceImpl.java
deleted file mode 100644
index eb3bfa0..0000000
--- a/buildstubs-t/stubs-src/com/android/server/EthernetServiceImpl.java
+++ /dev/null
@@ -1,28 +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.
- */
-
-package com.android.server.ethernet;
-
-import android.os.Binder;
-
-/** Stub class for EthernetServiceImpl */
-public class EthernetServiceImpl extends Binder {
-    /** Start service */
-    public void start() {
-        throw new RuntimeException("This is a stub class");
-    }
-}
-
diff --git a/buildstubs-t/stubs-src/com/android/server/IpSecService.java b/buildstubs-t/stubs-src/com/android/server/IpSecService.java
deleted file mode 100644
index bb48c14..0000000
--- a/buildstubs-t/stubs-src/com/android/server/IpSecService.java
+++ /dev/null
@@ -1,31 +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.
- */
-
-package com.android.server;
-
-import android.content.Context;
-import android.os.Binder;
-
-/**
- * Fake IpSecManager class for sc-mainline-prod,
- * to allow building the T service-connectivity before sources
- * are moved to the branch
- */
-public final class IpSecService extends Binder {
-    public IpSecService(Context ctx) {
-        throw new RuntimeException("This is a stub class");
-    }
-}
diff --git a/buildstubs-t/stubs-src/com/android/server/NsdService.java b/buildstubs-t/stubs-src/com/android/server/NsdService.java
deleted file mode 100644
index 4a3ba90..0000000
--- a/buildstubs-t/stubs-src/com/android/server/NsdService.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.server;
-
-import android.content.Context;
-import android.os.Binder;
-
-/**
- * Fake NsdService class for sc-mainline-prod,
- * to allow building the T service-connectivity before sources
- * are moved to the branch
- */
-public final class NsdService extends Binder {
-    /** Create instance */
-    public static NsdService create(Context ctx) throws InterruptedException {
-        throw new RuntimeException("This is a stub class");
-    }
-}
diff --git a/buildstubs-t/stubs-src/com/android/server/net/NetworkStatsService.java b/buildstubs-t/stubs-src/com/android/server/net/NetworkStatsService.java
deleted file mode 100644
index 8568e2a..0000000
--- a/buildstubs-t/stubs-src/com/android/server/net/NetworkStatsService.java
+++ /dev/null
@@ -1,37 +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.
- */
-
-package com.android.server.net;
-
-import android.content.Context;
-import android.os.Binder;
-
-/**
- * Fake NetworkStatsService class for sc-mainline-prod,
- * to allow building the T service-connectivity before sources
- * are moved to the branch
- */
-public final class NetworkStatsService extends Binder {
-    /** Create instance */
-    public static NetworkStatsService create(Context ctx) {
-        throw new RuntimeException("This is a stub class");
-    }
-
-    /** System Ready */
-    public void systemReady() {
-        throw new RuntimeException("This is a stub class");
-    }
-}
diff --git a/framework-t/Android.bp b/framework-t/Android.bp
index 292dc3c..9c8b359 100644
--- a/framework-t/Android.bp
+++ b/framework-t/Android.bp
@@ -19,9 +19,12 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+// Include build rules from Sources.bp
+build = ["Sources.bp"]
+
 java_defaults {
     name: "enable-framework-connectivity-t-targets",
-    enabled: false,
+    enabled: true,
 }
 // The above defaults can be used to disable framework-connectivity t
 // targets while minimizing merge conflicts in the build rules.
@@ -114,7 +117,7 @@
         // In preparation for future move
         "//packages/modules/Connectivity/apex",
         "//packages/modules/Connectivity/service-t",
-        "//packages/modules/Nearby/service",
+        "//packages/modules/Connectivity/nearby/service",
         "//frameworks/base",
 
         // Tests using hidden APIs
@@ -131,10 +134,10 @@
         "//frameworks/opt/telephony/tests/telephonytests",
         "//packages/modules/CaptivePortalLogin/tests",
         "//packages/modules/Connectivity/Tethering/tests:__subpackages__",
+        "//packages/modules/Connectivity/nearby/tests:__subpackages__",
         "//packages/modules/Connectivity/tests:__subpackages__",
         "//packages/modules/IPsec/tests/iketests",
         "//packages/modules/NetworkStack/tests:__subpackages__",
-        "//packages/modules/Nearby/tests:__subpackages__",
         "//packages/modules/Wifi/service/tests/wifitests",
     ],
 }
diff --git a/framework-t/Sources.bp b/framework-t/Sources.bp
new file mode 100644
index 0000000..53b4163
--- /dev/null
+++ b/framework-t/Sources.bp
@@ -0,0 +1,175 @@
+//
+// 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.
+//
+
+// NetworkStats related libraries.
+
+filegroup {
+    name: "framework-connectivity-netstats-internal-sources",
+    srcs: [
+        "src/android/app/usage/*.java",
+        "src/android/net/DataUsageRequest.*",
+        "src/android/net/INetworkStatsService.aidl",
+        "src/android/net/INetworkStatsSession.aidl",
+        "src/android/net/NetworkIdentity.java",
+        "src/android/net/NetworkIdentitySet.java",
+        "src/android/net/NetworkStateSnapshot.*",
+        "src/android/net/NetworkStats.*",
+        "src/android/net/NetworkStatsAccess.*",
+        "src/android/net/NetworkStatsCollection.*",
+        "src/android/net/NetworkStatsHistory.*",
+        "src/android/net/NetworkTemplate.*",
+        "src/android/net/TrafficStats.java",
+        "src/android/net/UnderlyingNetworkInfo.*",
+        "src/android/net/netstats/**/*.*",
+    ],
+    path: "src",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+filegroup {
+    name: "framework-connectivity-netstats-sources",
+    srcs: [
+        ":framework-connectivity-netstats-internal-sources",
+    ],
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+// Nsd related libraries.
+
+filegroup {
+    name: "framework-connectivity-nsd-internal-sources",
+    srcs: [
+        "src/android/net/nsd/*.aidl",
+        "src/android/net/nsd/*.java",
+    ],
+    path: "src",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+filegroup {
+    name: "framework-connectivity-nsd-sources",
+    srcs: [
+        ":framework-connectivity-nsd-internal-sources",
+    ],
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+// IpSec related libraries.
+
+filegroup {
+    name: "framework-connectivity-ipsec-sources",
+    srcs: [
+        "src/android/net/IIpSecService.aidl",
+        "src/android/net/IpSec*.*",
+    ],
+    path: "src",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+// Ethernet related libraries.
+
+filegroup {
+    name: "framework-connectivity-ethernet-sources",
+    srcs: [
+        "src/android/net/EthernetManager.java",
+        "src/android/net/EthernetNetworkManagementException.java",
+        "src/android/net/EthernetNetworkManagementException.aidl",
+        "src/android/net/EthernetNetworkSpecifier.java",
+        "src/android/net/EthernetNetworkUpdateRequest.java",
+        "src/android/net/EthernetNetworkUpdateRequest.aidl",
+        "src/android/net/IEthernetManager.aidl",
+        "src/android/net/IEthernetServiceListener.aidl",
+        "src/android/net/INetworkInterfaceOutcomeReceiver.aidl",
+        "src/android/net/ITetheredInterfaceCallback.aidl",
+    ],
+    path: "src",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+// Connectivity-T common libraries.
+
+filegroup {
+    name: "framework-connectivity-tiramisu-internal-sources",
+    srcs: [
+        "src/android/net/ConnectivityFrameworkInitializerTiramisu.java",
+    ],
+    path: "src",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+// TODO: remove this empty filegroup.
+filegroup {
+    name: "framework-connectivity-tiramisu-sources",
+    srcs: [],
+    visibility: ["//frameworks/base"],
+}
+
+filegroup {
+    name: "framework-connectivity-tiramisu-updatable-sources",
+    srcs: [
+        ":framework-connectivity-ethernet-sources",
+        ":framework-connectivity-ipsec-sources",
+        ":framework-connectivity-netstats-sources",
+        ":framework-connectivity-nsd-sources",
+        ":framework-connectivity-tiramisu-internal-sources",
+    ],
+    visibility: [
+        "//frameworks/base",
+        "//packages/modules/Connectivity:__subpackages__",
+    ],
+}
+
+cc_library_shared {
+    name: "libframework-connectivity-tiramisu-jni",
+    min_sdk_version: "30",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-parameter",
+        // Don't warn about S API usage even with
+        // min_sdk 30: the library is only loaded
+        // on S+ devices
+        "-Wno-unguarded-availability",
+        "-Wthread-safety",
+    ],
+    srcs: [
+        "jni/android_net_TrafficStats.cpp",
+        "jni/onload.cpp",
+    ],
+    shared_libs: [
+        "libandroid",
+        "liblog",
+        "libnativehelper",
+    ],
+    stl: "none",
+    apex_available: [
+        "com.android.tethering",
+    ],
+}
diff --git a/framework-t/api/current.txt b/framework-t/api/current.txt
index 1b47481..eb77288 100644
--- a/framework-t/api/current.txt
+++ b/framework-t/api/current.txt
@@ -3,7 +3,7 @@
 
   public final class NetworkStats implements java.lang.AutoCloseable {
     method public void close();
-    method public boolean getNextBucket(android.app.usage.NetworkStats.Bucket);
+    method public boolean getNextBucket(@Nullable android.app.usage.NetworkStats.Bucket);
     method public boolean hasNextBucket();
   }
 
@@ -40,21 +40,21 @@
   }
 
   public class NetworkStatsManager {
-    method @WorkerThread public android.app.usage.NetworkStats queryDetails(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats queryDetailsForUid(int, String, long, long, int) throws java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTag(int, String, long, long, int, int) throws java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTagState(int, String, long, long, int, int, int) throws java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats querySummary(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
-    method public void registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback);
-    method public void registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback, @Nullable android.os.Handler);
-    method public void unregisterUsageCallback(android.app.usage.NetworkStatsManager.UsageCallback);
+    method @WorkerThread public android.app.usage.NetworkStats queryDetails(int, @Nullable String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+    method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForUid(int, @Nullable String, long, long, int) throws java.lang.SecurityException;
+    method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTag(int, @Nullable String, long, long, int, int) throws java.lang.SecurityException;
+    method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTagState(int, @Nullable String, long, long, int, int, int) throws java.lang.SecurityException;
+    method @WorkerThread public android.app.usage.NetworkStats querySummary(int, @Nullable String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+    method @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, @Nullable String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+    method @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, @Nullable String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+    method public void registerUsageCallback(int, @Nullable String, long, @NonNull android.app.usage.NetworkStatsManager.UsageCallback);
+    method public void registerUsageCallback(int, @Nullable String, long, @NonNull android.app.usage.NetworkStatsManager.UsageCallback, @Nullable android.os.Handler);
+    method public void unregisterUsageCallback(@NonNull android.app.usage.NetworkStatsManager.UsageCallback);
   }
 
   public abstract static class NetworkStatsManager.UsageCallback {
     ctor public NetworkStatsManager.UsageCallback();
-    method public abstract void onThresholdReached(int, String);
+    method public abstract void onThresholdReached(int, @Nullable String);
   }
 
 }
@@ -173,12 +173,12 @@
     method public static void incrementOperationCount(int, int);
     method public static void setThreadStatsTag(int);
     method public static void setThreadStatsUid(int);
-    method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
-    method public static void tagFileDescriptor(java.io.FileDescriptor) throws java.io.IOException;
-    method public static void tagSocket(java.net.Socket) throws java.net.SocketException;
-    method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
-    method public static void untagFileDescriptor(java.io.FileDescriptor) throws java.io.IOException;
-    method public static void untagSocket(java.net.Socket) throws java.net.SocketException;
+    method public static void tagDatagramSocket(@NonNull java.net.DatagramSocket) throws java.net.SocketException;
+    method public static void tagFileDescriptor(@NonNull java.io.FileDescriptor) throws java.io.IOException;
+    method public static void tagSocket(@NonNull java.net.Socket) throws java.net.SocketException;
+    method public static void untagDatagramSocket(@NonNull java.net.DatagramSocket) throws java.net.SocketException;
+    method public static void untagFileDescriptor(@NonNull java.io.FileDescriptor) throws java.io.IOException;
+    method public static void untagSocket(@NonNull java.net.Socket) throws java.net.SocketException;
     field public static final int UNSUPPORTED = -1; // 0xffffffff
   }
 
diff --git a/framework-t/api/lint-baseline.txt b/framework-t/api/lint-baseline.txt
index 53e1beb..2996a3e 100644
--- a/framework-t/api/lint-baseline.txt
+++ b/framework-t/api/lint-baseline.txt
@@ -41,86 +41,18 @@
     android.net.IpSecTransform.Builder does not declare a `build()` method, but builder classes are expected to
 
 
-MissingNullability: android.app.usage.NetworkStats#getNextBucket(android.app.usage.NetworkStats.Bucket) parameter #0:
-    Missing nullability on parameter `bucketOut` in method `getNextBucket`
 MissingNullability: android.app.usage.NetworkStatsManager#queryDetails(int, String, long, long):
     Missing nullability on method `queryDetails` return
-MissingNullability: android.app.usage.NetworkStatsManager#queryDetails(int, String, long, long) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `queryDetails`
-MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUid(int, String, long, long, int):
-    Missing nullability on method `queryDetailsForUid` return
-MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUid(int, String, long, long, int) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `queryDetailsForUid`
-MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUidTag(int, String, long, long, int, int):
-    Missing nullability on method `queryDetailsForUidTag` return
-MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUidTag(int, String, long, long, int, int) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `queryDetailsForUidTag`
-MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUidTagState(int, String, long, long, int, int, int):
-    Missing nullability on method `queryDetailsForUidTagState` return
-MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUidTagState(int, String, long, long, int, int, int) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `queryDetailsForUidTagState`
 MissingNullability: android.app.usage.NetworkStatsManager#querySummary(int, String, long, long):
     Missing nullability on method `querySummary` return
-MissingNullability: android.app.usage.NetworkStatsManager#querySummary(int, String, long, long) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `querySummary`
 MissingNullability: android.app.usage.NetworkStatsManager#querySummaryForDevice(int, String, long, long):
     Missing nullability on method `querySummaryForDevice` return
-MissingNullability: android.app.usage.NetworkStatsManager#querySummaryForDevice(int, String, long, long) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `querySummaryForDevice`
 MissingNullability: android.app.usage.NetworkStatsManager#querySummaryForUser(int, String, long, long):
     Missing nullability on method `querySummaryForUser` return
-MissingNullability: android.app.usage.NetworkStatsManager#querySummaryForUser(int, String, long, long) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `querySummaryForUser`
-MissingNullability: android.app.usage.NetworkStatsManager#registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `registerUsageCallback`
-MissingNullability: android.app.usage.NetworkStatsManager#registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback) parameter #3:
-    Missing nullability on parameter `callback` in method `registerUsageCallback`
-MissingNullability: android.app.usage.NetworkStatsManager#registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `registerUsageCallback`
-MissingNullability: android.app.usage.NetworkStatsManager#registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler) parameter #3:
-    Missing nullability on parameter `callback` in method `registerUsageCallback`
-MissingNullability: android.app.usage.NetworkStatsManager#unregisterUsageCallback(android.app.usage.NetworkStatsManager.UsageCallback) parameter #0:
-    Missing nullability on parameter `callback` in method `unregisterUsageCallback`
-MissingNullability: android.app.usage.NetworkStatsManager.UsageCallback#onThresholdReached(int, String) parameter #1:
-    Missing nullability on parameter `subscriberId` in method `onThresholdReached`
 MissingNullability: android.net.IpSecAlgorithm#writeToParcel(android.os.Parcel, int) parameter #0:
     Missing nullability on parameter `out` in method `writeToParcel`
 MissingNullability: android.net.IpSecManager.UdpEncapsulationSocket#getFileDescriptor():
     Missing nullability on method `getFileDescriptor` return
-MissingNullability: android.net.TrafficStats#tagDatagramSocket(java.net.DatagramSocket) parameter #0:
-    Missing nullability on parameter `socket` in method `tagDatagramSocket`
-MissingNullability: android.net.TrafficStats#tagFileDescriptor(java.io.FileDescriptor) parameter #0:
-    Missing nullability on parameter `fd` in method `tagFileDescriptor`
-MissingNullability: android.net.TrafficStats#tagSocket(java.net.Socket) parameter #0:
-    Missing nullability on parameter `socket` in method `tagSocket`
-MissingNullability: android.net.TrafficStats#untagDatagramSocket(java.net.DatagramSocket) parameter #0:
-    Missing nullability on parameter `socket` in method `untagDatagramSocket`
-MissingNullability: android.net.TrafficStats#untagFileDescriptor(java.io.FileDescriptor) parameter #0:
-    Missing nullability on parameter `fd` in method `untagFileDescriptor`
-MissingNullability: android.net.TrafficStats#untagSocket(java.net.Socket) parameter #0:
-    Missing nullability on parameter `socket` in method `untagSocket`
-MissingNullability: com.android.internal.util.FileRotator#FileRotator(java.io.File, String, long, long) parameter #0:
-    Missing nullability on parameter `basePath` in method `FileRotator`
-MissingNullability: com.android.internal.util.FileRotator#FileRotator(java.io.File, String, long, long) parameter #1:
-    Missing nullability on parameter `prefix` in method `FileRotator`
-MissingNullability: com.android.internal.util.FileRotator#dumpAll(java.io.OutputStream) parameter #0:
-    Missing nullability on parameter `os` in method `dumpAll`
-MissingNullability: com.android.internal.util.FileRotator#readMatching(com.android.internal.util.FileRotator.Reader, long, long) parameter #0:
-    Missing nullability on parameter `reader` in method `readMatching`
-MissingNullability: com.android.internal.util.FileRotator#rewriteActive(com.android.internal.util.FileRotator.Rewriter, long) parameter #0:
-    Missing nullability on parameter `rewriter` in method `rewriteActive`
-MissingNullability: com.android.internal.util.FileRotator#rewriteAll(com.android.internal.util.FileRotator.Rewriter) parameter #0:
-    Missing nullability on parameter `rewriter` in method `rewriteAll`
-MissingNullability: com.android.internal.util.FileRotator.Reader#read(java.io.InputStream) parameter #0:
-    Missing nullability on parameter `in` in method `read`
-MissingNullability: com.android.internal.util.FileRotator.Writer#write(java.io.OutputStream) parameter #0:
-    Missing nullability on parameter `out` in method `write`
-MissingNullability: com.android.server.NetworkManagementSocketTagger#kernelToTag(String) parameter #0:
-    Missing nullability on parameter `string` in method `kernelToTag`
-MissingNullability: com.android.server.NetworkManagementSocketTagger#tag(java.io.FileDescriptor) parameter #0:
-    Missing nullability on parameter `fd` in method `tag`
-MissingNullability: com.android.server.NetworkManagementSocketTagger#untag(java.io.FileDescriptor) parameter #0:
-    Missing nullability on parameter `fd` in method `untag`
 
 
 RethrowRemoteException: android.app.usage.NetworkStatsManager#queryDetails(int, String, long, long):
diff --git a/framework-t/api/module-lib-current.txt b/framework-t/api/module-lib-current.txt
index 658c625..216081a 100644
--- a/framework-t/api/module-lib-current.txt
+++ b/framework-t/api/module-lib-current.txt
@@ -4,6 +4,8 @@
   public class NetworkStatsManager {
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void forceUpdate();
     method public static int getCollapsedRatType(int);
+    method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public android.net.NetworkStats getMobileUidStats();
+    method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public android.net.NetworkStats getWifiUidStats();
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void noteUidForeground(int, boolean);
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void notifyNetworkStatus(@NonNull java.util.List<android.net.Network>, @NonNull java.util.List<android.net.NetworkStateSnapshot>, @Nullable String, @NonNull java.util.List<android.net.UnderlyingNetworkInfo>);
     method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForDevice(@NonNull android.net.NetworkTemplate, long, long);
@@ -25,6 +27,14 @@
 
 }
 
+package android.nearby {
+
+  public final class NearbyFrameworkInitializer {
+    method public static void registerServiceWrappers();
+  }
+
+}
+
 package android.net {
 
   public final class ConnectivityFrameworkInitializerTiramisu {
@@ -102,6 +112,24 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStateSnapshot> CREATOR;
   }
 
+  public final class NetworkStats implements java.lang.Iterable<android.net.NetworkStats.Entry> android.os.Parcelable {
+    method @NonNull public java.util.Iterator<android.net.NetworkStats.Entry> iterator();
+  }
+
+  public static class NetworkStats.Entry {
+    method public int getDefaultNetwork();
+    method public int getMetered();
+    method public long getOperations();
+    method public int getRoaming();
+    method public long getRxBytes();
+    method public long getRxPackets();
+    method public int getSet();
+    method public int getTag();
+    method public long getTxBytes();
+    method public long getTxPackets();
+    method public int getUid();
+  }
+
   public class NetworkStatsCollection {
     method @NonNull public java.util.Map<android.net.NetworkStatsCollection.Key,android.net.NetworkStatsHistory> getEntries();
   }
@@ -182,6 +210,7 @@
   public class TrafficStats {
     method public static void attachSocketTagger();
     method public static void init(@NonNull android.content.Context);
+    method public static void setThreadStatsTagDownload();
   }
 
   public final class UnderlyingNetworkInfo implements android.os.Parcelable {
diff --git a/framework-t/api/system-current.txt b/framework-t/api/system-current.txt
index 0f37b6f..03f9c8e 100644
--- a/framework-t/api/system-current.txt
+++ b/framework-t/api/system-current.txt
@@ -2,10 +2,463 @@
 package android.app.usage {
 
   public class NetworkStatsManager {
-    method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public android.net.NetworkStats getMobileUidStats();
-    method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public android.net.NetworkStats getWifiUidStats();
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider);
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider);
+  }
+
+}
+
+package android.nearby {
+
+  public interface BroadcastCallback {
+    method public void onStatusChanged(int);
+    field public static final int STATUS_FAILURE = 1; // 0x1
+    field public static final int STATUS_FAILURE_ALREADY_REGISTERED = 2; // 0x2
+    field public static final int STATUS_FAILURE_MISSING_PERMISSIONS = 4; // 0x4
+    field public static final int STATUS_FAILURE_SIZE_EXCEED_LIMIT = 3; // 0x3
+    field public static final int STATUS_OK = 0; // 0x0
+  }
+
+  public abstract class BroadcastRequest {
+    method @NonNull public java.util.List<java.lang.Integer> getMediums();
+    method @IntRange(from=0xffffff81, to=126) public int getTxPower();
+    method public int getType();
+    method public int getVersion();
+    field public static final int BROADCAST_TYPE_NEARBY_PRESENCE = 3; // 0x3
+    field public static final int BROADCAST_TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final int PRESENCE_VERSION_UNKNOWN = -1; // 0xffffffff
+    field public static final int PRESENCE_VERSION_V0 = 0; // 0x0
+    field public static final int PRESENCE_VERSION_V1 = 1; // 0x1
+    field public static final int UNKNOWN_TX_POWER = -127; // 0xffffff81
+  }
+
+  public final class CredentialElement implements android.os.Parcelable {
+    ctor public CredentialElement(@NonNull String, @NonNull byte[]);
+    method public int describeContents();
+    method @NonNull public String getKey();
+    method @NonNull public byte[] getValue();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nearby.CredentialElement> CREATOR;
+  }
+
+  public final class DataElement implements android.os.Parcelable {
+    ctor public DataElement(int, @NonNull byte[]);
+    method public int describeContents();
+    method public int getKey();
+    method @NonNull public byte[] getValue();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nearby.DataElement> CREATOR;
+  }
+
+  public class FastPairAccountKeyDeviceMetadata {
+    method @Nullable public byte[] getDeviceAccountKey();
+    method @Nullable public android.nearby.FastPairDeviceMetadata getFastPairDeviceMetadata();
+    method @Nullable public android.nearby.FastPairDiscoveryItem getFastPairDiscoveryItem();
+    method @Nullable public byte[] getSha256DeviceAccountKeyPublicAddress();
+  }
+
+  public static final class FastPairAccountKeyDeviceMetadata.Builder {
+    ctor public FastPairAccountKeyDeviceMetadata.Builder();
+    method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata build();
+    method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata.Builder setDeviceAccountKey(@Nullable byte[]);
+    method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata.Builder setFastPairDeviceMetadata(@Nullable android.nearby.FastPairDeviceMetadata);
+    method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata.Builder setFastPairDiscoveryItem(@Nullable android.nearby.FastPairDiscoveryItem);
+    method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata.Builder setSha256DeviceAccountKeyPublicAddress(@Nullable byte[]);
+  }
+
+  public class FastPairAntispoofKeyDeviceMetadata {
+    method @Nullable public byte[] getAntispoofPublicKey();
+    method @Nullable public android.nearby.FastPairDeviceMetadata getFastPairDeviceMetadata();
+  }
+
+  public static final class FastPairAntispoofKeyDeviceMetadata.Builder {
+    ctor public FastPairAntispoofKeyDeviceMetadata.Builder();
+    method @NonNull public android.nearby.FastPairAntispoofKeyDeviceMetadata build();
+    method @NonNull public android.nearby.FastPairAntispoofKeyDeviceMetadata.Builder setAntispoofPublicKey(@Nullable byte[]);
+    method @NonNull public android.nearby.FastPairAntispoofKeyDeviceMetadata.Builder setFastPairDeviceMetadata(@Nullable android.nearby.FastPairDeviceMetadata);
+  }
+
+  public abstract class FastPairDataProviderService extends android.app.Service {
+    ctor public FastPairDataProviderService(@NonNull String);
+    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public abstract void onLoadFastPairAccountDevicesMetadata(@NonNull android.nearby.FastPairDataProviderService.FastPairAccountDevicesMetadataRequest, @NonNull android.nearby.FastPairDataProviderService.FastPairAccountDevicesMetadataCallback);
+    method public abstract void onLoadFastPairAntispoofKeyDeviceMetadata(@NonNull android.nearby.FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataRequest, @NonNull android.nearby.FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataCallback);
+    method public abstract void onLoadFastPairEligibleAccounts(@NonNull android.nearby.FastPairDataProviderService.FastPairEligibleAccountsRequest, @NonNull android.nearby.FastPairDataProviderService.FastPairEligibleAccountsCallback);
+    method public abstract void onManageFastPairAccount(@NonNull android.nearby.FastPairDataProviderService.FastPairManageAccountRequest, @NonNull android.nearby.FastPairDataProviderService.FastPairManageActionCallback);
+    method public abstract void onManageFastPairAccountDevice(@NonNull android.nearby.FastPairDataProviderService.FastPairManageAccountDeviceRequest, @NonNull android.nearby.FastPairDataProviderService.FastPairManageActionCallback);
+    field public static final String ACTION_FAST_PAIR_DATA_PROVIDER = "android.nearby.action.FAST_PAIR_DATA_PROVIDER";
+    field public static final int ERROR_CODE_BAD_REQUEST = 0; // 0x0
+    field public static final int ERROR_CODE_INTERNAL_ERROR = 1; // 0x1
+    field public static final int MANAGE_REQUEST_ADD = 0; // 0x0
+    field public static final int MANAGE_REQUEST_REMOVE = 1; // 0x1
+  }
+
+  public static interface FastPairDataProviderService.FastPairAccountDevicesMetadataCallback {
+    method public void onError(int, @Nullable String);
+    method public void onFastPairAccountDevicesMetadataReceived(@NonNull java.util.Collection<android.nearby.FastPairAccountKeyDeviceMetadata>);
+  }
+
+  public static class FastPairDataProviderService.FastPairAccountDevicesMetadataRequest {
+    method @NonNull public android.accounts.Account getAccount();
+    method @NonNull public java.util.Collection<byte[]> getDeviceAccountKeys();
+  }
+
+  public static interface FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataCallback {
+    method public void onError(int, @Nullable String);
+    method public void onFastPairAntispoofKeyDeviceMetadataReceived(@NonNull android.nearby.FastPairAntispoofKeyDeviceMetadata);
+  }
+
+  public static class FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataRequest {
+    method @NonNull public byte[] getModelId();
+  }
+
+  public static interface FastPairDataProviderService.FastPairEligibleAccountsCallback {
+    method public void onError(int, @Nullable String);
+    method public void onFastPairEligibleAccountsReceived(@NonNull java.util.Collection<android.nearby.FastPairEligibleAccount>);
+  }
+
+  public static class FastPairDataProviderService.FastPairEligibleAccountsRequest {
+  }
+
+  public static class FastPairDataProviderService.FastPairManageAccountDeviceRequest {
+    method @NonNull public android.accounts.Account getAccount();
+    method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata getAccountKeyDeviceMetadata();
+    method @Nullable public String getBleAddress();
+    method public int getRequestType();
+  }
+
+  public static class FastPairDataProviderService.FastPairManageAccountRequest {
+    method @NonNull public android.accounts.Account getAccount();
+    method public int getRequestType();
+  }
+
+  public static interface FastPairDataProviderService.FastPairManageActionCallback {
+    method public void onError(int, @Nullable String);
+    method public void onSuccess();
+  }
+
+  public class FastPairDeviceMetadata {
+    method @Nullable public String getAssistantSetupHalfSheet();
+    method @Nullable public String getAssistantSetupNotification();
+    method public int getBleTxPower();
+    method @Nullable public String getConfirmPinDescription();
+    method @Nullable public String getConfirmPinTitle();
+    method @Nullable public String getConnectSuccessCompanionAppInstalled();
+    method @Nullable public String getConnectSuccessCompanionAppNotInstalled();
+    method public int getDeviceType();
+    method @Nullable public String getDownloadCompanionAppDescription();
+    method @Nullable public String getFailConnectGoToSettingsDescription();
+    method @Nullable public String getFastPairTvConnectDeviceNoAccountDescription();
+    method @Nullable public byte[] getImage();
+    method @Nullable public String getImageUrl();
+    method @Nullable public String getInitialNotificationDescription();
+    method @Nullable public String getInitialNotificationDescriptionNoAccount();
+    method @Nullable public String getInitialPairingDescription();
+    method @Nullable public String getIntentUri();
+    method @Nullable public String getLocale();
+    method @Nullable public String getName();
+    method @Nullable public String getOpenCompanionAppDescription();
+    method @Nullable public String getRetroactivePairingDescription();
+    method @Nullable public String getSubsequentPairingDescription();
+    method @Nullable public String getSyncContactsDescription();
+    method @Nullable public String getSyncContactsTitle();
+    method @Nullable public String getSyncSmsDescription();
+    method @Nullable public String getSyncSmsTitle();
+    method public float getTriggerDistance();
+    method @Nullable public String getTrueWirelessImageUrlCase();
+    method @Nullable public String getTrueWirelessImageUrlLeftBud();
+    method @Nullable public String getTrueWirelessImageUrlRightBud();
+    method @Nullable public String getUnableToConnectDescription();
+    method @Nullable public String getUnableToConnectTitle();
+    method @Nullable public String getUpdateCompanionAppDescription();
+    method @Nullable public String getWaitLaunchCompanionAppDescription();
+  }
+
+  public static final class FastPairDeviceMetadata.Builder {
+    ctor public FastPairDeviceMetadata.Builder();
+    method @NonNull public android.nearby.FastPairDeviceMetadata build();
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setAssistantSetupHalfSheet(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setAssistantSetupNotification(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setBleTxPower(int);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setConfirmPinDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setConfirmPinTitle(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setConnectSuccessCompanionAppInstalled(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setConnectSuccessCompanionAppNotInstalled(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setDeviceType(int);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setDownloadCompanionAppDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setFailConnectGoToSettingsDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setFastPairTvConnectDeviceNoAccountDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setImage(@Nullable byte[]);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setImageUrl(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setInitialNotificationDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setInitialNotificationDescriptionNoAccount(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setInitialPairingDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setIntentUri(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setLocale(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setName(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setOpenCompanionAppDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setRetroactivePairingDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSubsequentPairingDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSyncContactsDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSyncContactsTitle(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSyncSmsDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSyncSmsTitle(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setTriggerDistance(float);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setTrueWirelessImageUrlCase(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setTrueWirelessImageUrlLeftBud(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setTrueWirelessImageUrlRightBud(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setUnableToConnectDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setUnableToConnectTitle(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setUpdateCompanionAppDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setWaitLaunchCompanionAppDescription(@Nullable String);
+  }
+
+  public class FastPairDiscoveryItem {
+    method @Nullable public String getActionUrl();
+    method public int getActionUrlType();
+    method @Nullable public String getAppName();
+    method public int getAttachmentType();
+    method @Nullable public byte[] getAuthenticationPublicKeySecp256r1();
+    method @Nullable public byte[] getBleRecordBytes();
+    method public int getDebugCategory();
+    method @Nullable public String getDebugMessage();
+    method @Nullable public String getDescription();
+    method @Nullable public String getDeviceName();
+    method @Nullable public String getDisplayUrl();
+    method @Nullable public String getEntityId();
+    method @Nullable public String getFeatureGraphicUrl();
+    method public long getFirstObservationTimestampMillis();
+    method @Nullable public String getGroupId();
+    method @Nullable public String getIconFfeUrl();
+    method @Nullable public byte[] getIconPng();
+    method @Nullable public String getId();
+    method public long getLastObservationTimestampMillis();
+    method public int getLastUserExperience();
+    method public long getLostMillis();
+    method @Nullable public String getMacAddress();
+    method @Nullable public String getPackageName();
+    method public long getPendingAppInstallTimestampMillis();
+    method public int getRssi();
+    method public int getState();
+    method @Nullable public String getTitle();
+    method @Nullable public String getTriggerId();
+    method public int getTxPower();
+    method public int getType();
+  }
+
+  public static final class FastPairDiscoveryItem.Builder {
+    ctor public FastPairDiscoveryItem.Builder();
+    method @NonNull public android.nearby.FastPairDiscoveryItem build();
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setActionUrl(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setActionUrlType(int);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setAppName(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setAttachmentType(int);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setAuthenticationPublicKeySecp256r1(@Nullable byte[]);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setBleRecordBytes(@Nullable byte[]);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDebugCategory(int);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDebugMessage(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDescription(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDeviceName(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDisplayUrl(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setEntityId(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setFeatureGraphicUrl(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setFirstObservationTimestampMillis(long);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setGroupId(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setIconFfeUrl(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setIconPng(@Nullable byte[]);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setId(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setLastObservationTimestampMillis(long);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setLastUserExperience(int);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setLostMillis(long);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setMacAddress(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setPackageName(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setPendingAppInstallTimestampMillis(long);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setRssi(int);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setState(int);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setTitle(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setTriggerId(@Nullable String);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setTxPower(int);
+    method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setType(int);
+  }
+
+  public class FastPairEligibleAccount {
+    method @Nullable public android.accounts.Account getAccount();
+    method public boolean isOptIn();
+  }
+
+  public static final class FastPairEligibleAccount.Builder {
+    ctor public FastPairEligibleAccount.Builder();
+    method @NonNull public android.nearby.FastPairEligibleAccount build();
+    method @NonNull public android.nearby.FastPairEligibleAccount.Builder setAccount(@Nullable android.accounts.Account);
+    method @NonNull public android.nearby.FastPairEligibleAccount.Builder setOptIn(boolean);
+  }
+
+  public abstract class NearbyDevice {
+    method @NonNull public java.util.List<java.lang.Integer> getMediums();
+    method @Nullable public String getName();
+    method @IntRange(from=0xffffff81, to=126) public int getRssi();
+    method public static boolean isValidMedium(int);
+  }
+
+  public class NearbyManager {
+    method public static boolean getFastPairScanEnabled(@NonNull android.content.Context);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static void setFastPairScanEnabled(@NonNull android.content.Context, boolean);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void startBroadcast(@NonNull android.nearby.BroadcastRequest, @NonNull java.util.concurrent.Executor, @NonNull android.nearby.BroadcastCallback);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int startScan(@NonNull android.nearby.ScanRequest, @NonNull java.util.concurrent.Executor, @NonNull android.nearby.ScanCallback);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void stopBroadcast(@NonNull android.nearby.BroadcastCallback);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void stopScan(@NonNull android.nearby.ScanCallback);
+  }
+
+  public final class PresenceBroadcastRequest extends android.nearby.BroadcastRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<java.lang.Integer> getActions();
+    method @NonNull public android.nearby.PrivateCredential getCredential();
+    method @NonNull public java.util.List<android.nearby.DataElement> getExtendedProperties();
+    method @NonNull public byte[] getSalt();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PresenceBroadcastRequest> CREATOR;
+  }
+
+  public static final class PresenceBroadcastRequest.Builder {
+    ctor public PresenceBroadcastRequest.Builder(@NonNull java.util.List<java.lang.Integer>, @NonNull byte[], @NonNull android.nearby.PrivateCredential);
+    method @NonNull public android.nearby.PresenceBroadcastRequest.Builder addAction(@IntRange(from=1, to=255) int);
+    method @NonNull public android.nearby.PresenceBroadcastRequest.Builder addExtendedProperty(@NonNull android.nearby.DataElement);
+    method @NonNull public android.nearby.PresenceBroadcastRequest build();
+    method @NonNull public android.nearby.PresenceBroadcastRequest.Builder setTxPower(@IntRange(from=0xffffff81, to=126) int);
+    method @NonNull public android.nearby.PresenceBroadcastRequest.Builder setVersion(int);
+  }
+
+  public abstract class PresenceCredential {
+    method @NonNull public byte[] getAuthenticityKey();
+    method @NonNull public java.util.List<android.nearby.CredentialElement> getCredentialElements();
+    method public int getIdentityType();
+    method @NonNull public byte[] getSecretId();
+    method public int getType();
+    field public static final int CREDENTIAL_TYPE_PRIVATE = 0; // 0x0
+    field public static final int CREDENTIAL_TYPE_PUBLIC = 1; // 0x1
+    field public static final int IDENTITY_TYPE_PRIVATE = 1; // 0x1
+    field public static final int IDENTITY_TYPE_PROVISIONED = 2; // 0x2
+    field public static final int IDENTITY_TYPE_PUBLIC = 4; // 0x4
+    field public static final int IDENTITY_TYPE_TRUSTED = 3; // 0x3
+    field public static final int IDENTITY_TYPE_UNKNOWN = 0; // 0x0
+  }
+
+  public final class PresenceDevice extends android.nearby.NearbyDevice implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public String getDeviceId();
+    method @Nullable public String getDeviceImageUrl();
+    method public int getDeviceType();
+    method public long getDiscoveryTimestampMillis();
+    method @NonNull public byte[] getEncryptedIdentity();
+    method @NonNull public java.util.List<android.nearby.DataElement> getExtendedProperties();
+    method @NonNull public byte[] getSalt();
+    method @NonNull public byte[] getSecretId();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PresenceDevice> CREATOR;
+  }
+
+  public static final class PresenceDevice.Builder {
+    ctor public PresenceDevice.Builder(@NonNull String, @NonNull byte[], @NonNull byte[], @NonNull byte[]);
+    method @NonNull public android.nearby.PresenceDevice.Builder addExtendedProperty(@NonNull android.nearby.DataElement);
+    method @NonNull public android.nearby.PresenceDevice.Builder addMedium(int);
+    method @NonNull public android.nearby.PresenceDevice build();
+    method @NonNull public android.nearby.PresenceDevice.Builder setDeviceImageUrl(@Nullable String);
+    method @NonNull public android.nearby.PresenceDevice.Builder setDeviceType(int);
+    method @NonNull public android.nearby.PresenceDevice.Builder setDiscoveryTimestampMillis(long);
+    method @NonNull public android.nearby.PresenceDevice.Builder setName(@Nullable String);
+    method @NonNull public android.nearby.PresenceDevice.Builder setRssi(int);
+  }
+
+  public final class PresenceScanFilter extends android.nearby.ScanFilter implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.nearby.PublicCredential> getCredentials();
+    method @NonNull public java.util.List<android.nearby.DataElement> getExtendedProperties();
+    method @NonNull public java.util.List<java.lang.Integer> getPresenceActions();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PresenceScanFilter> CREATOR;
+  }
+
+  public static final class PresenceScanFilter.Builder {
+    ctor public PresenceScanFilter.Builder();
+    method @NonNull public android.nearby.PresenceScanFilter.Builder addCredential(@NonNull android.nearby.PublicCredential);
+    method @NonNull public android.nearby.PresenceScanFilter.Builder addExtendedProperty(@NonNull android.nearby.DataElement);
+    method @NonNull public android.nearby.PresenceScanFilter.Builder addPresenceAction(@IntRange(from=1, to=255) int);
+    method @NonNull public android.nearby.PresenceScanFilter build();
+    method @NonNull public android.nearby.PresenceScanFilter.Builder setMaxPathLoss(@IntRange(from=0, to=127) int);
+  }
+
+  public final class PrivateCredential extends android.nearby.PresenceCredential implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public String getDeviceName();
+    method @NonNull public byte[] getMetadataEncryptionKey();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PrivateCredential> CREATOR;
+  }
+
+  public static final class PrivateCredential.Builder {
+    ctor public PrivateCredential.Builder(@NonNull byte[], @NonNull byte[], @NonNull byte[], @NonNull String);
+    method @NonNull public android.nearby.PrivateCredential.Builder addCredentialElement(@NonNull android.nearby.CredentialElement);
+    method @NonNull public android.nearby.PrivateCredential build();
+    method @NonNull public android.nearby.PrivateCredential.Builder setIdentityType(int);
+  }
+
+  public final class PublicCredential extends android.nearby.PresenceCredential implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public byte[] getEncryptedMetadata();
+    method @NonNull public byte[] getEncryptedMetadataKeyTag();
+    method @NonNull public byte[] getPublicKey();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PublicCredential> CREATOR;
+  }
+
+  public static final class PublicCredential.Builder {
+    ctor public PublicCredential.Builder(@NonNull byte[], @NonNull byte[], @NonNull byte[], @NonNull byte[], @NonNull byte[]);
+    method @NonNull public android.nearby.PublicCredential.Builder addCredentialElement(@NonNull android.nearby.CredentialElement);
+    method @NonNull public android.nearby.PublicCredential build();
+    method @NonNull public android.nearby.PublicCredential.Builder setIdentityType(int);
+  }
+
+  public interface ScanCallback {
+    method public void onDiscovered(@NonNull android.nearby.NearbyDevice);
+    method public void onLost(@NonNull android.nearby.NearbyDevice);
+    method public void onUpdated(@NonNull android.nearby.NearbyDevice);
+  }
+
+  public abstract class ScanFilter {
+    method @IntRange(from=0, to=127) public int getMaxPathLoss();
+    method public int getType();
+  }
+
+  public final class ScanRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.nearby.ScanFilter> getScanFilters();
+    method public int getScanMode();
+    method public int getScanType();
+    method @NonNull public android.os.WorkSource getWorkSource();
+    method public boolean isBleEnabled();
+    method public static boolean isValidScanMode(int);
+    method public static boolean isValidScanType(int);
+    method @NonNull public static String scanModeToString(int);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nearby.ScanRequest> CREATOR;
+    field public static final int SCAN_MODE_BALANCED = 1; // 0x1
+    field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
+    field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
+    field public static final int SCAN_MODE_NO_POWER = -1; // 0xffffffff
+    field public static final int SCAN_TYPE_EXPOSURE_NOTIFICATION = 4; // 0x4
+    field public static final int SCAN_TYPE_FAST_PAIR = 1; // 0x1
+    field public static final int SCAN_TYPE_NEARBY_PRESENCE = 3; // 0x3
+    field public static final int SCAN_TYPE_NEARBY_SHARE = 2; // 0x2
+  }
+
+  public static final class ScanRequest.Builder {
+    ctor public ScanRequest.Builder();
+    method @NonNull public android.nearby.ScanRequest.Builder addScanFilter(@NonNull android.nearby.ScanFilter);
+    method @NonNull public android.nearby.ScanRequest build();
+    method @NonNull public android.nearby.ScanRequest.Builder setBleEnabled(boolean);
+    method @NonNull public android.nearby.ScanRequest.Builder setScanMode(int);
+    method @NonNull public android.nearby.ScanRequest.Builder setScanType(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.nearby.ScanRequest.Builder setWorkSource(@Nullable android.os.WorkSource);
   }
 
 }
@@ -73,7 +526,6 @@
     method @NonNull public android.net.NetworkStats add(@NonNull android.net.NetworkStats);
     method @NonNull public android.net.NetworkStats addEntry(@NonNull android.net.NetworkStats.Entry);
     method public int describeContents();
-    method @NonNull public java.util.Iterator<android.net.NetworkStats.Entry> iterator();
     method @NonNull public android.net.NetworkStats subtract(@NonNull android.net.NetworkStats);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStats> CREATOR;
@@ -97,23 +549,11 @@
 
   public static class NetworkStats.Entry {
     ctor public NetworkStats.Entry(@Nullable String, int, int, int, int, int, int, long, long, long, long, long);
-    method public int getDefaultNetwork();
-    method public int getMetered();
-    method public long getOperations();
-    method public int getRoaming();
-    method public long getRxBytes();
-    method public long getRxPackets();
-    method public int getSet();
-    method public int getTag();
-    method public long getTxBytes();
-    method public long getTxPackets();
-    method public int getUid();
   }
 
   public class TrafficStats {
     method public static void setThreadStatsTagApp();
     method public static void setThreadStatsTagBackup();
-    method public static void setThreadStatsTagDownload();
     method public static void setThreadStatsTagRestore();
     field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_END = -113; // 0xffffff8f
     field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_START = -128; // 0xffffff80
diff --git a/framework-t/jni/android_net_TrafficStats.cpp b/framework-t/jni/android_net_TrafficStats.cpp
new file mode 100644
index 0000000..f3c58b1
--- /dev/null
+++ b/framework-t/jni/android_net_TrafficStats.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#include <android/file_descriptor_jni.h>
+#include <android/multinetwork.h>
+#include <nativehelper/JNIHelp.h>
+
+namespace android {
+
+static jint tagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor, jint tag, jint uid) {
+  int fd = AFileDescriptor_getFd(env, fileDescriptor);
+  if (fd == -1) return -EBADF;
+  return android_tag_socket_with_uid(fd, tag, uid);
+}
+
+static jint untagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor) {
+  int fd = AFileDescriptor_getFd(env, fileDescriptor);
+  if (fd == -1) return -EBADF;
+  return android_untag_socket(fd);
+}
+
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*) tagSocketFd },
+    { "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*) untagSocketFd },
+};
+
+int register_android_net_TrafficStats(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "android/net/TrafficStats", gMethods, NELEM(gMethods));
+}
+
+};  // namespace android
+
diff --git a/framework-t/jni/onload.cpp b/framework-t/jni/onload.cpp
new file mode 100644
index 0000000..1fb42c6
--- /dev/null
+++ b/framework-t/jni/onload.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "FrameworkConnectivityJNI"
+
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+
+namespace android {
+
+int register_android_net_TrafficStats(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_ERROR, LOG_TAG, "ERROR: GetEnv failed");
+        return JNI_ERR;
+    }
+
+    if (register_android_net_TrafficStats(env) < 0) return JNI_ERR;
+
+    return JNI_VERSION_1_6;
+}
+
+};  // namespace android
+
diff --git a/framework-t/src/android/app/usage/NetworkStats.java b/framework-t/src/android/app/usage/NetworkStats.java
new file mode 100644
index 0000000..74fe4bd
--- /dev/null
+++ b/framework-t/src/android/app/usage/NetworkStats.java
@@ -0,0 +1,744 @@
+/**
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package android.app.usage;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.net.INetworkStatsService;
+import android.net.INetworkStatsSession;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.TrafficStats;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.net.module.util.CollectionUtils;
+
+import dalvik.system.CloseGuard;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+
+/**
+ * Class providing enumeration over buckets of network usage statistics. {@link NetworkStats} objects
+ * are returned as results to various queries in {@link NetworkStatsManager}.
+ */
+public final class NetworkStats implements AutoCloseable {
+    private final static String TAG = "NetworkStats";
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    /**
+     * Start timestamp of stats collected
+     */
+    private final long mStartTimeStamp;
+
+    /**
+     * End timestamp of stats collected
+     */
+    private final long mEndTimeStamp;
+
+    /**
+     * Non-null array indicates the query enumerates over uids.
+     */
+    private int[] mUids;
+
+    /**
+     * Index of the current uid in mUids when doing uid enumeration or a single uid value,
+     * depending on query type.
+     */
+    private int mUidOrUidIndex;
+
+    /**
+     * Tag id in case if was specified in the query.
+     */
+    private int mTag = android.net.NetworkStats.TAG_NONE;
+
+    /**
+     * State in case it was not specified in the query.
+     */
+    private int mState = Bucket.STATE_ALL;
+
+    /**
+     * The session while the query requires it, null if all the stats have been collected or close()
+     * has been called.
+     */
+    private INetworkStatsSession mSession;
+    private NetworkTemplate mTemplate;
+
+    /**
+     * Results of a summary query.
+     */
+    private android.net.NetworkStats mSummary = null;
+
+    /**
+     * Results of detail queries.
+     */
+    private NetworkStatsHistory mHistory = null;
+
+    /**
+     * Where we are in enumerating over the current result.
+     */
+    private int mEnumerationIndex = 0;
+
+    /**
+     * Recycling entry objects to prevent heap fragmentation.
+     */
+    private android.net.NetworkStats.Entry mRecycledSummaryEntry = null;
+    private NetworkStatsHistory.Entry mRecycledHistoryEntry = null;
+
+    /** @hide */
+    NetworkStats(Context context, NetworkTemplate template, int flags, long startTimestamp,
+            long endTimestamp, INetworkStatsService statsService)
+            throws RemoteException, SecurityException {
+        // Open network stats session
+        mSession = statsService.openSessionForUsageStats(flags, context.getOpPackageName());
+        mCloseGuard.open("close");
+        mTemplate = template;
+        mStartTimeStamp = startTimestamp;
+        mEndTimeStamp = endTimestamp;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    // -------------------------BEGINNING OF PUBLIC API-----------------------------------
+
+    /**
+     * Buckets are the smallest elements of a query result. As some dimensions of a result may be
+     * aggregated (e.g. time or state) some values may be equal across all buckets.
+     */
+    public static class Bucket {
+        /** @hide */
+        @IntDef(prefix = { "STATE_" }, value = {
+                STATE_ALL,
+                STATE_DEFAULT,
+                STATE_FOREGROUND
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface State {}
+
+        /**
+         * Combined usage across all states.
+         */
+        public static final int STATE_ALL = -1;
+
+        /**
+         * Usage not accounted for in any other state.
+         */
+        public static final int STATE_DEFAULT = 0x1;
+
+        /**
+         * Foreground usage.
+         */
+        public static final int STATE_FOREGROUND = 0x2;
+
+        /**
+         * Special UID value for aggregate/unspecified.
+         */
+        public static final int UID_ALL = android.net.NetworkStats.UID_ALL;
+
+        /**
+         * Special UID value for removed apps.
+         */
+        public static final int UID_REMOVED = TrafficStats.UID_REMOVED;
+
+        /**
+         * Special UID value for data usage by tethering.
+         */
+        public static final int UID_TETHERING = TrafficStats.UID_TETHERING;
+
+        /** @hide */
+        @IntDef(prefix = { "METERED_" }, value = {
+                METERED_ALL,
+                METERED_NO,
+                METERED_YES
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Metered {}
+
+        /**
+         * Combined usage across all metered states. Covers metered and unmetered usage.
+         */
+        public static final int METERED_ALL = -1;
+
+        /**
+         * Usage that occurs on an unmetered network.
+         */
+        public static final int METERED_NO = 0x1;
+
+        /**
+         * Usage that occurs on a metered network.
+         *
+         * <p>A network is classified as metered when the user is sensitive to heavy data usage on
+         * that connection.
+         */
+        public static final int METERED_YES = 0x2;
+
+        /** @hide */
+        @IntDef(prefix = { "ROAMING_" }, value = {
+                ROAMING_ALL,
+                ROAMING_NO,
+                ROAMING_YES
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Roaming {}
+
+        /**
+         * Combined usage across all roaming states. Covers both roaming and non-roaming usage.
+         */
+        public static final int ROAMING_ALL = -1;
+
+        /**
+         * Usage that occurs on a home, non-roaming network.
+         *
+         * <p>Any cellular usage in this bucket was incurred while the device was connected to a
+         * tower owned or operated by the user's wireless carrier, or a tower that the user's
+         * wireless carrier has indicated should be treated as a home network regardless.
+         *
+         * <p>This is also the default value for network types that do not support roaming.
+         */
+        public static final int ROAMING_NO = 0x1;
+
+        /**
+         * Usage that occurs on a roaming network.
+         *
+         * <p>Any cellular usage in this bucket as incurred while the device was roaming on another
+         * carrier's network, for which additional charges may apply.
+         */
+        public static final int ROAMING_YES = 0x2;
+
+        /** @hide */
+        @IntDef(prefix = { "DEFAULT_NETWORK_" }, value = {
+                DEFAULT_NETWORK_ALL,
+                DEFAULT_NETWORK_NO,
+                DEFAULT_NETWORK_YES
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface DefaultNetworkStatus {}
+
+        /**
+         * Combined usage for this network regardless of default network status.
+         */
+        public static final int DEFAULT_NETWORK_ALL = -1;
+
+        /**
+         * Usage that occurs while this network is not a default network.
+         *
+         * <p>This implies that the app responsible for this usage requested that it occur on a
+         * specific network different from the one(s) the system would have selected for it.
+         */
+        public static final int DEFAULT_NETWORK_NO = 0x1;
+
+        /**
+         * Usage that occurs while this network is a default network.
+         *
+         * <p>This implies that the app either did not select a specific network for this usage,
+         * or it selected a network that the system could have selected for app traffic.
+         */
+        public static final int DEFAULT_NETWORK_YES = 0x2;
+
+        /**
+         * Special TAG value for total data across all tags
+         */
+        public static final int TAG_NONE = android.net.NetworkStats.TAG_NONE;
+
+        private int mUid;
+        private int mTag;
+        private int mState;
+        private int mDefaultNetworkStatus;
+        private int mMetered;
+        private int mRoaming;
+        private long mBeginTimeStamp;
+        private long mEndTimeStamp;
+        private long mRxBytes;
+        private long mRxPackets;
+        private long mTxBytes;
+        private long mTxPackets;
+
+        private static int convertSet(@State int state) {
+            switch (state) {
+                case STATE_ALL: return android.net.NetworkStats.SET_ALL;
+                case STATE_DEFAULT: return android.net.NetworkStats.SET_DEFAULT;
+                case STATE_FOREGROUND: return android.net.NetworkStats.SET_FOREGROUND;
+            }
+            return 0;
+        }
+
+        private static @State int convertState(int networkStatsSet) {
+            switch (networkStatsSet) {
+                case android.net.NetworkStats.SET_ALL : return STATE_ALL;
+                case android.net.NetworkStats.SET_DEFAULT : return STATE_DEFAULT;
+                case android.net.NetworkStats.SET_FOREGROUND : return STATE_FOREGROUND;
+            }
+            return 0;
+        }
+
+        private static int convertUid(int uid) {
+            switch (uid) {
+                case TrafficStats.UID_REMOVED: return UID_REMOVED;
+                case TrafficStats.UID_TETHERING: return UID_TETHERING;
+            }
+            return uid;
+        }
+
+        private static int convertTag(int tag) {
+            switch (tag) {
+                case android.net.NetworkStats.TAG_NONE: return TAG_NONE;
+            }
+            return tag;
+        }
+
+        private static @Metered int convertMetered(int metered) {
+            switch (metered) {
+                case android.net.NetworkStats.METERED_ALL : return METERED_ALL;
+                case android.net.NetworkStats.METERED_NO: return METERED_NO;
+                case android.net.NetworkStats.METERED_YES: return METERED_YES;
+            }
+            return 0;
+        }
+
+        private static @Roaming int convertRoaming(int roaming) {
+            switch (roaming) {
+                case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL;
+                case android.net.NetworkStats.ROAMING_NO: return ROAMING_NO;
+                case android.net.NetworkStats.ROAMING_YES: return ROAMING_YES;
+            }
+            return 0;
+        }
+
+        private static @DefaultNetworkStatus int convertDefaultNetworkStatus(
+                int defaultNetworkStatus) {
+            switch (defaultNetworkStatus) {
+                case android.net.NetworkStats.DEFAULT_NETWORK_ALL : return DEFAULT_NETWORK_ALL;
+                case android.net.NetworkStats.DEFAULT_NETWORK_NO: return DEFAULT_NETWORK_NO;
+                case android.net.NetworkStats.DEFAULT_NETWORK_YES: return DEFAULT_NETWORK_YES;
+            }
+            return 0;
+        }
+
+        public Bucket() {
+        }
+
+        /**
+         * Key of the bucket. Usually an app uid or one of the following special values:<p />
+         * <ul>
+         * <li>{@link #UID_REMOVED}</li>
+         * <li>{@link #UID_TETHERING}</li>
+         * <li>{@link android.os.Process#SYSTEM_UID}</li>
+         * </ul>
+         * @return Bucket key.
+         */
+        public int getUid() {
+            return mUid;
+        }
+
+        /**
+         * Tag of the bucket.<p />
+         * @return Bucket tag.
+         */
+        public int getTag() {
+            return mTag;
+        }
+
+        /**
+         * Usage state. One of the following values:<p/>
+         * <ul>
+         * <li>{@link #STATE_ALL}</li>
+         * <li>{@link #STATE_DEFAULT}</li>
+         * <li>{@link #STATE_FOREGROUND}</li>
+         * </ul>
+         * @return Usage state.
+         */
+        public @State int getState() {
+            return mState;
+        }
+
+        /**
+         * Metered state. One of the following values:<p/>
+         * <ul>
+         * <li>{@link #METERED_ALL}</li>
+         * <li>{@link #METERED_NO}</li>
+         * <li>{@link #METERED_YES}</li>
+         * </ul>
+         * <p>A network is classified as metered when the user is sensitive to heavy data usage on
+         * that connection. Apps may warn before using these networks for large downloads. The
+         * metered state can be set by the user within data usage network restrictions.
+         */
+        public @Metered int getMetered() {
+            return mMetered;
+        }
+
+        /**
+         * Roaming state. One of the following values:<p/>
+         * <ul>
+         * <li>{@link #ROAMING_ALL}</li>
+         * <li>{@link #ROAMING_NO}</li>
+         * <li>{@link #ROAMING_YES}</li>
+         * </ul>
+         */
+        public @Roaming int getRoaming() {
+            return mRoaming;
+        }
+
+        /**
+         * Default network status. One of the following values:<p/>
+         * <ul>
+         * <li>{@link #DEFAULT_NETWORK_ALL}</li>
+         * <li>{@link #DEFAULT_NETWORK_NO}</li>
+         * <li>{@link #DEFAULT_NETWORK_YES}</li>
+         * </ul>
+         */
+        public @DefaultNetworkStatus int getDefaultNetworkStatus() {
+            return mDefaultNetworkStatus;
+        }
+
+        /**
+         * Start timestamp of the bucket's time interval. Defined in terms of "Unix time", see
+         * {@link java.lang.System#currentTimeMillis}.
+         * @return Start of interval.
+         */
+        public long getStartTimeStamp() {
+            return mBeginTimeStamp;
+        }
+
+        /**
+         * End timestamp of the bucket's time interval. Defined in terms of "Unix time", see
+         * {@link java.lang.System#currentTimeMillis}.
+         * @return End of interval.
+         */
+        public long getEndTimeStamp() {
+            return mEndTimeStamp;
+        }
+
+        /**
+         * Number of bytes received during the bucket's time interval. Statistics are measured at
+         * the network layer, so they include both TCP and UDP usage.
+         * @return Number of bytes.
+         */
+        public long getRxBytes() {
+            return mRxBytes;
+        }
+
+        /**
+         * Number of bytes transmitted during the bucket's time interval. Statistics are measured at
+         * the network layer, so they include both TCP and UDP usage.
+         * @return Number of bytes.
+         */
+        public long getTxBytes() {
+            return mTxBytes;
+        }
+
+        /**
+         * Number of packets received during the bucket's time interval. Statistics are measured at
+         * the network layer, so they include both TCP and UDP usage.
+         * @return Number of packets.
+         */
+        public long getRxPackets() {
+            return mRxPackets;
+        }
+
+        /**
+         * Number of packets transmitted during the bucket's time interval. Statistics are measured
+         * at the network layer, so they include both TCP and UDP usage.
+         * @return Number of packets.
+         */
+        public long getTxPackets() {
+            return mTxPackets;
+        }
+    }
+
+    /**
+     * Fills the recycled bucket with data of the next bin in the enumeration.
+     * @param bucketOut Bucket to be filled with data. If null, the method does
+     *                  nothing and returning false.
+     * @return true if successfully filled the bucket, false otherwise.
+     */
+    public boolean getNextBucket(@Nullable Bucket bucketOut) {
+        if (mSummary != null) {
+            return getNextSummaryBucket(bucketOut);
+        } else {
+            return getNextHistoryBucket(bucketOut);
+        }
+    }
+
+    /**
+     * Check if it is possible to ask for a next bucket in the enumeration.
+     * @return true if there is at least one more bucket.
+     */
+    public boolean hasNextBucket() {
+        if (mSummary != null) {
+            return mEnumerationIndex < mSummary.size();
+        } else if (mHistory != null) {
+            return mEnumerationIndex < mHistory.size()
+                    || hasNextUid();
+        }
+        return false;
+    }
+
+    /**
+     * Closes the enumeration. Call this method before this object gets out of scope.
+     */
+    @Override
+    public void close() {
+        if (mSession != null) {
+            try {
+                mSession.close();
+            } catch (RemoteException e) {
+                Log.w(TAG, e);
+                // Otherwise, meh
+            }
+        }
+        mSession = null;
+        if (mCloseGuard != null) {
+            mCloseGuard.close();
+        }
+    }
+
+    // -------------------------END OF PUBLIC API-----------------------------------
+
+    /**
+     * Collects device summary results into a Bucket.
+     * @throws RemoteException
+     */
+    Bucket getDeviceSummaryForNetwork() throws RemoteException {
+        mSummary = mSession.getDeviceSummaryForNetwork(mTemplate, mStartTimeStamp, mEndTimeStamp);
+
+        // Setting enumeration index beyond end to avoid accidental enumeration over data that does
+        // not belong to the calling user.
+        mEnumerationIndex = mSummary.size();
+
+        return getSummaryAggregate();
+    }
+
+    /**
+     * Collects summary results and sets summary enumeration mode.
+     * @throws RemoteException
+     */
+    void startSummaryEnumeration() throws RemoteException {
+        mSummary = mSession.getSummaryForAllUid(mTemplate, mStartTimeStamp, mEndTimeStamp,
+                false /* includeTags */);
+        mEnumerationIndex = 0;
+    }
+
+    /**
+     * Collects tagged summary results and sets summary enumeration mode.
+     * @throws RemoteException
+     */
+    void startTaggedSummaryEnumeration() throws RemoteException {
+        mSummary = mSession.getTaggedSummaryForAllUid(mTemplate, mStartTimeStamp, mEndTimeStamp);
+        mEnumerationIndex = 0;
+    }
+
+    /**
+     * Collects history results for uid and resets history enumeration index.
+     */
+    void startHistoryUidEnumeration(int uid, int tag, int state) {
+        mHistory = null;
+        try {
+            mHistory = mSession.getHistoryIntervalForUid(mTemplate, uid,
+                    Bucket.convertSet(state), tag, NetworkStatsHistory.FIELD_ALL,
+                    mStartTimeStamp, mEndTimeStamp);
+            setSingleUidTagState(uid, tag, state);
+        } catch (RemoteException e) {
+            Log.w(TAG, e);
+            // Leaving mHistory null
+        }
+        mEnumerationIndex = 0;
+    }
+
+    /**
+     * Collects history results for network and resets history enumeration index.
+     */
+    void startHistoryDeviceEnumeration() {
+        try {
+            mHistory = mSession.getHistoryIntervalForNetwork(
+                    mTemplate, NetworkStatsHistory.FIELD_ALL, mStartTimeStamp, mEndTimeStamp);
+        } catch (RemoteException e) {
+            Log.w(TAG, e);
+            mHistory = null;
+        }
+        mEnumerationIndex = 0;
+    }
+
+    /**
+     * Starts uid enumeration for current user.
+     * @throws RemoteException
+     */
+    void startUserUidEnumeration() throws RemoteException {
+        // TODO: getRelevantUids should be sensitive to time interval. When that's done,
+        //       the filtering logic below can be removed.
+        int[] uids = mSession.getRelevantUids();
+        // Filtering of uids with empty history.
+        final ArrayList<Integer> filteredUids = new ArrayList<>();
+        for (int uid : uids) {
+            try {
+                NetworkStatsHistory history = mSession.getHistoryIntervalForUid(mTemplate, uid,
+                        android.net.NetworkStats.SET_ALL, android.net.NetworkStats.TAG_NONE,
+                        NetworkStatsHistory.FIELD_ALL, mStartTimeStamp, mEndTimeStamp);
+                if (history != null && history.size() > 0) {
+                    filteredUids.add(uid);
+                }
+            } catch (RemoteException e) {
+                Log.w(TAG, "Error while getting history of uid " + uid, e);
+            }
+        }
+        mUids = CollectionUtils.toIntArray(filteredUids);
+        mUidOrUidIndex = -1;
+        stepHistory();
+    }
+
+    /**
+     * Steps to next uid in enumeration and collects history for that.
+     */
+    private void stepHistory(){
+        if (hasNextUid()) {
+            stepUid();
+            mHistory = null;
+            try {
+                mHistory = mSession.getHistoryIntervalForUid(mTemplate, getUid(),
+                        android.net.NetworkStats.SET_ALL, android.net.NetworkStats.TAG_NONE,
+                        NetworkStatsHistory.FIELD_ALL, mStartTimeStamp, mEndTimeStamp);
+            } catch (RemoteException e) {
+                Log.w(TAG, e);
+                // Leaving mHistory null
+            }
+            mEnumerationIndex = 0;
+        }
+    }
+
+    private void fillBucketFromSummaryEntry(Bucket bucketOut) {
+        bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid);
+        bucketOut.mTag = Bucket.convertTag(mRecycledSummaryEntry.tag);
+        bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set);
+        bucketOut.mDefaultNetworkStatus = Bucket.convertDefaultNetworkStatus(
+                mRecycledSummaryEntry.defaultNetwork);
+        bucketOut.mMetered = Bucket.convertMetered(mRecycledSummaryEntry.metered);
+        bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming);
+        bucketOut.mBeginTimeStamp = mStartTimeStamp;
+        bucketOut.mEndTimeStamp = mEndTimeStamp;
+        bucketOut.mRxBytes = mRecycledSummaryEntry.rxBytes;
+        bucketOut.mRxPackets = mRecycledSummaryEntry.rxPackets;
+        bucketOut.mTxBytes = mRecycledSummaryEntry.txBytes;
+        bucketOut.mTxPackets = mRecycledSummaryEntry.txPackets;
+    }
+
+    /**
+     * Getting the next item in summary enumeration.
+     * @param bucketOut Next item will be set here.
+     * @return true if a next item could be set.
+     */
+    private boolean getNextSummaryBucket(@Nullable Bucket bucketOut) {
+        if (bucketOut != null && mEnumerationIndex < mSummary.size()) {
+            mRecycledSummaryEntry = mSummary.getValues(mEnumerationIndex++, mRecycledSummaryEntry);
+            fillBucketFromSummaryEntry(bucketOut);
+            return true;
+        }
+        return false;
+    }
+
+    Bucket getSummaryAggregate() {
+        if (mSummary == null) {
+            return null;
+        }
+        Bucket bucket = new Bucket();
+        if (mRecycledSummaryEntry == null) {
+            mRecycledSummaryEntry = new android.net.NetworkStats.Entry();
+        }
+        mSummary.getTotal(mRecycledSummaryEntry);
+        fillBucketFromSummaryEntry(bucket);
+        return bucket;
+    }
+
+    /**
+     * Getting the next item in a history enumeration.
+     * @param bucketOut Next item will be set here.
+     * @return true if a next item could be set.
+     */
+    private boolean getNextHistoryBucket(@Nullable Bucket bucketOut) {
+        if (bucketOut != null && mHistory != null) {
+            if (mEnumerationIndex < mHistory.size()) {
+                mRecycledHistoryEntry = mHistory.getValues(mEnumerationIndex++,
+                        mRecycledHistoryEntry);
+                bucketOut.mUid = Bucket.convertUid(getUid());
+                bucketOut.mTag = Bucket.convertTag(mTag);
+                bucketOut.mState = mState;
+                bucketOut.mDefaultNetworkStatus = Bucket.DEFAULT_NETWORK_ALL;
+                bucketOut.mMetered = Bucket.METERED_ALL;
+                bucketOut.mRoaming = Bucket.ROAMING_ALL;
+                bucketOut.mBeginTimeStamp = mRecycledHistoryEntry.bucketStart;
+                bucketOut.mEndTimeStamp = mRecycledHistoryEntry.bucketStart +
+                        mRecycledHistoryEntry.bucketDuration;
+                bucketOut.mRxBytes = mRecycledHistoryEntry.rxBytes;
+                bucketOut.mRxPackets = mRecycledHistoryEntry.rxPackets;
+                bucketOut.mTxBytes = mRecycledHistoryEntry.txBytes;
+                bucketOut.mTxPackets = mRecycledHistoryEntry.txPackets;
+                return true;
+            } else if (hasNextUid()) {
+                stepHistory();
+                return getNextHistoryBucket(bucketOut);
+            }
+        }
+        return false;
+    }
+
+    // ------------------ UID LOGIC------------------------
+
+    private boolean isUidEnumeration() {
+        return mUids != null;
+    }
+
+    private boolean hasNextUid() {
+        return isUidEnumeration() && (mUidOrUidIndex + 1) < mUids.length;
+    }
+
+    private int getUid() {
+        // Check if uid enumeration.
+        if (isUidEnumeration()) {
+            if (mUidOrUidIndex < 0 || mUidOrUidIndex >= mUids.length) {
+                throw new IndexOutOfBoundsException(
+                        "Index=" + mUidOrUidIndex + " mUids.length=" + mUids.length);
+            }
+            return mUids[mUidOrUidIndex];
+        }
+        // Single uid mode.
+        return mUidOrUidIndex;
+    }
+
+    private void setSingleUidTagState(int uid, int tag, int state) {
+        mUidOrUidIndex = uid;
+        mTag = tag;
+        mState = state;
+    }
+
+    private void stepUid() {
+        if (mUids != null) {
+            ++mUidOrUidIndex;
+        }
+    }
+}
diff --git a/framework-t/src/android/app/usage/NetworkStatsManager.java b/framework-t/src/android/app/usage/NetworkStatsManager.java
new file mode 100644
index 0000000..f41475b
--- /dev/null
+++ b/framework-t/src/android/app/usage/NetworkStatsManager.java
@@ -0,0 +1,1238 @@
+/**
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package android.app.usage;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.annotation.WorkerThread;
+import android.app.usage.NetworkStats.Bucket;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.DataUsageRequest;
+import android.net.INetworkStatsService;
+import android.net.Network;
+import android.net.NetworkStack;
+import android.net.NetworkStateSnapshot;
+import android.net.NetworkTemplate;
+import android.net.UnderlyingNetworkInfo;
+import android.net.netstats.IUsageCallback;
+import android.net.netstats.NetworkStatsDataMigrationUtils;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
+import android.os.Build;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.NetworkIdentityUtils;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * Provides access to network usage history and statistics. Usage data is collected in
+ * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details.
+ * <p />
+ * Queries can define a time interval in the form of start and end timestamps (Long.MIN_VALUE and
+ * Long.MAX_VALUE can be used to simulate open ended intervals). By default, apps can only obtain
+ * data about themselves. See the below note for special cases in which apps can obtain data about
+ * other applications.
+ * <h3>
+ * Summary queries
+ * </h3>
+ * {@link #querySummaryForDevice} <p />
+ * {@link #querySummaryForUser} <p />
+ * {@link #querySummary} <p />
+ * These queries aggregate network usage across the whole interval. Therefore there will be only one
+ * bucket for a particular key, state, metered and roaming combination. In case of the user-wide
+ * and device-wide summaries a single bucket containing the totalised network usage is returned.
+ * <h3>
+ * History queries
+ * </h3>
+ * {@link #queryDetailsForUid} <p />
+ * {@link #queryDetails} <p />
+ * These queries do not aggregate over time but do aggregate over state, metered and roaming.
+ * Therefore there can be multiple buckets for a particular key. However, all Buckets will have
+ * {@code state} {@link NetworkStats.Bucket#STATE_ALL},
+ * {@code defaultNetwork} {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
+ * {@code metered } {@link NetworkStats.Bucket#METERED_ALL},
+ * {@code roaming} {@link NetworkStats.Bucket#ROAMING_ALL}.
+ * <p />
+ * <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the
+ * calling app requires the permission {@link android.Manifest.permission#PACKAGE_USAGE_STATS},
+ * which is a system-level permission and will not be granted to third-party apps. However,
+ * declaring the permission implies intention to use the API and the user of the device can grant
+ * permission through the Settings application.
+ * <p />
+ * Profile owner apps are automatically granted permission to query data on the profile they manage
+ * (that is, for any query except {@link #querySummaryForDevice}). Device owner apps and carrier-
+ * privileged apps likewise get access to usage data for all users on the device.
+ * <p />
+ * In addition to tethering usage, usage by removed users and apps, and usage by the system
+ * is also included in the results for callers with one of these higher levels of access.
+ * <p />
+ * <b>NOTE:</b> Prior to API level {@value android.os.Build.VERSION_CODES#N}, all calls to these APIs required
+ * the above permission, even to access an app's own data usage, and carrier-privileged apps were
+ * not included.
+ */
+@SystemService(Context.NETWORK_STATS_SERVICE)
+public class NetworkStatsManager {
+    private static final String TAG = "NetworkStatsManager";
+    private static final boolean DBG = false;
+
+    /** @hide */
+    public static final int CALLBACK_LIMIT_REACHED = 0;
+    /** @hide */
+    public static final int CALLBACK_RELEASED = 1;
+
+    /**
+     * Minimum data usage threshold for registering usage callbacks.
+     *
+     * Requests registered with a threshold lower than this will only be triggered once this minimum
+     * is reached.
+     * @hide
+     */
+    public static final long MIN_THRESHOLD_BYTES = 2 * 1_048_576L; // 2MiB
+
+    private final Context mContext;
+    private final INetworkStatsService mService;
+
+    /**
+     * @deprecated Use {@link NetworkStatsDataMigrationUtils#PREFIX_XT}
+     * instead.
+     * @hide
+     */
+    @Deprecated
+    public static final String PREFIX_DEV = "dev";
+
+    /** @hide */
+    public static final int FLAG_POLL_ON_OPEN = 1 << 0;
+    /** @hide */
+    public static final int FLAG_POLL_FORCE = 1 << 1;
+    /** @hide */
+    public static final int FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN = 1 << 2;
+
+    /**
+     * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is
+     * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along
+     * with NR state as connected. This is a concept added by NetworkStats on top of the telephony
+     * constants for backward compatibility of metrics so this should not be overlapped with any of
+     * the {@code TelephonyManager.NETWORK_TYPE_*} constants.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int NETWORK_TYPE_5G_NSA = -2;
+
+    private int mFlags;
+
+    /** @hide */
+    @VisibleForTesting
+    public NetworkStatsManager(Context context, INetworkStatsService service) {
+        mContext = context;
+        mService = service;
+        setPollOnOpen(true);
+        setAugmentWithSubscriptionPlan(true);
+    }
+
+    /** @hide */
+    public INetworkStatsService getBinder() {
+        return mService;
+    }
+
+    /**
+     * Set poll on open flag to indicate the poll is needed before service gets statistics
+     * result. This is default enabled. However, for any non-privileged caller, the poll might
+     * be omitted in case of rate limiting.
+     *
+     * @param pollOnOpen true if poll is needed.
+     * @hide
+     */
+    // The system will ignore any non-default values for non-privileged
+    // processes, so processes that don't hold the appropriate permissions
+    // can make no use of this API.
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public void setPollOnOpen(boolean pollOnOpen) {
+        if (pollOnOpen) {
+            mFlags |= FLAG_POLL_ON_OPEN;
+        } else {
+            mFlags &= ~FLAG_POLL_ON_OPEN;
+        }
+    }
+
+    /**
+     * Set poll force flag to indicate that calling any subsequent query method will force a stats
+     * poll.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public void setPollForce(boolean pollForce) {
+        if (pollForce) {
+            mFlags |= FLAG_POLL_FORCE;
+        } else {
+            mFlags &= ~FLAG_POLL_FORCE;
+        }
+    }
+
+    /** @hide */
+    public void setAugmentWithSubscriptionPlan(boolean augmentWithSubscriptionPlan) {
+        if (augmentWithSubscriptionPlan) {
+            mFlags |= FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
+        } else {
+            mFlags &= ~FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
+        }
+    }
+
+    /**
+     * Query network usage statistics summaries.
+     *
+     * Result is summarised data usage for the whole
+     * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and
+     * roaming. This means the bucket's start and end timestamp will be the same as the
+     * 'startTime' and 'endTime' arguments. State is going to be
+     * {@link NetworkStats.Bucket#STATE_ALL}, uid {@link NetworkStats.Bucket#UID_ALL},
+     * tag {@link NetworkStats.Bucket#TAG_NONE},
+     * default network {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
+     * metered {@link NetworkStats.Bucket#METERED_ALL},
+     * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param startTime Start of period, in milliseconds since the Unix epoch, see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period, in milliseconds since the Unix epoch, see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @return Bucket Summarised data usage.
+     *
+     * @hide
+     */
+    @NonNull
+    @WorkerThread
+    @SystemApi(client = MODULE_LIBRARIES)
+    public Bucket querySummaryForDevice(@NonNull NetworkTemplate template,
+            long startTime, long endTime) {
+        Objects.requireNonNull(template);
+        try {
+            NetworkStats stats =
+                    new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
+            Bucket bucket = stats.getDeviceSummaryForNetwork();
+            stats.close();
+            return bucket;
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return null; // To make the compiler happy.
+    }
+
+    /**
+     * Query network usage statistics summaries. Result is summarised data usage for the whole
+     * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and
+     * roaming. This means the bucket's start and end timestamp are going to be the same as the
+     * 'startTime' and 'endTime' parameters. State is going to be
+     * {@link NetworkStats.Bucket#STATE_ALL}, uid {@link NetworkStats.Bucket#UID_ALL},
+     * tag {@link NetworkStats.Bucket#TAG_NONE},
+     * default network {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
+     * metered {@link NetworkStats.Bucket#METERED_ALL},
+     * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param networkType As defined in {@link ConnectivityManager}, e.g.
+     *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+     *            etc.
+     * @param subscriberId If applicable, the subscriber id of the network interface.
+     *                     <p>Starting with API level 29, the {@code subscriberId} is guarded by
+     *                     additional restrictions. Calling apps that do not meet the new
+     *                     requirements to access the {@code subscriberId} can provide a {@code
+     *                     null} value when querying for the mobile network type to receive usage
+     *                     for all mobile networks. For additional details see {@link
+     *                     TelephonyManager#getSubscriberId()}.
+     *                     <p>Starting with API level 31, calling apps can provide a
+     *                     {@code subscriberId} with wifi network type to receive usage for
+     *                     wifi networks which is under the given subscription if applicable.
+     *                     Otherwise, pass {@code null} when querying all wifi networks.
+     * @param startTime Start of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @return Bucket object or null if permissions are insufficient or error happened during
+     *         statistics collection.
+     */
+    @WorkerThread
+    public Bucket querySummaryForDevice(int networkType, @Nullable String subscriberId,
+            long startTime, long endTime) throws SecurityException, RemoteException {
+        NetworkTemplate template;
+        try {
+            template = createTemplate(networkType, subscriberId);
+        } catch (IllegalArgumentException e) {
+            if (DBG) Log.e(TAG, "Cannot create template", e);
+            return null;
+        }
+
+        return querySummaryForDevice(template, startTime, endTime);
+    }
+
+    /**
+     * Query network usage statistics summaries. Result is summarised data usage for all uids
+     * belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
+     * This means the bucket's start and end timestamp are going to be the same as the 'startTime'
+     * and 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL},
+     * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE},
+     * metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming
+     * {@link NetworkStats.Bucket#ROAMING_ALL}.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param networkType As defined in {@link ConnectivityManager}, e.g.
+     *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+     *            etc.
+     * @param subscriberId If applicable, the subscriber id of the network interface.
+     *                     <p>Starting with API level 29, the {@code subscriberId} is guarded by
+     *                     additional restrictions. Calling apps that do not meet the new
+     *                     requirements to access the {@code subscriberId} can provide a {@code
+     *                     null} value when querying for the mobile network type to receive usage
+     *                     for all mobile networks. For additional details see {@link
+     *                     TelephonyManager#getSubscriberId()}.
+     *                     <p>Starting with API level 31, calling apps can provide a
+     *                     {@code subscriberId} with wifi network type to receive usage for
+     *                     wifi networks which is under the given subscription if applicable.
+     *                     Otherwise, pass {@code null} when querying all wifi networks.
+     * @param startTime Start of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @return Bucket object or null if permissions are insufficient or error happened during
+     *         statistics collection.
+     */
+    @WorkerThread
+    public Bucket querySummaryForUser(int networkType, @Nullable String subscriberId,
+            long startTime, long endTime) throws SecurityException, RemoteException {
+        NetworkTemplate template;
+        try {
+            template = createTemplate(networkType, subscriberId);
+        } catch (IllegalArgumentException e) {
+            if (DBG) Log.e(TAG, "Cannot create template", e);
+            return null;
+        }
+
+        NetworkStats stats;
+        stats = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
+        stats.startSummaryEnumeration();
+
+        stats.close();
+        return stats.getSummaryAggregate();
+    }
+
+    /**
+     * Query network usage statistics summaries. Result filtered to include only uids belonging to
+     * calling user. Result is aggregated over time, hence all buckets will have the same start and
+     * end timestamps. Not aggregated over state, uid, default network, metered, or roaming. This
+     * means buckets' start and end timestamps are going to be the same as the 'startTime' and
+     * 'endTime' parameters. State, uid, metered, and roaming are going to vary, and tag is going to
+     * be the same.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param networkType As defined in {@link ConnectivityManager}, e.g.
+     *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+     *            etc.
+     * @param subscriberId If applicable, the subscriber id of the network interface.
+     *                     <p>Starting with API level 29, the {@code subscriberId} is guarded by
+     *                     additional restrictions. Calling apps that do not meet the new
+     *                     requirements to access the {@code subscriberId} can provide a {@code
+     *                     null} value when querying for the mobile network type to receive usage
+     *                     for all mobile networks. For additional details see {@link
+     *                     TelephonyManager#getSubscriberId()}.
+     *                     <p>Starting with API level 31, calling apps can provide a
+     *                     {@code subscriberId} with wifi network type to receive usage for
+     *                     wifi networks which is under the given subscription if applicable.
+     *                     Otherwise, pass {@code null} when querying all wifi networks.
+     * @param startTime Start of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @return Statistics object or null if permissions are insufficient or error happened during
+     *         statistics collection.
+     */
+    @WorkerThread
+    public NetworkStats querySummary(int networkType, @Nullable String subscriberId, long startTime,
+            long endTime) throws SecurityException, RemoteException {
+        NetworkTemplate template;
+        try {
+            template = createTemplate(networkType, subscriberId);
+        } catch (IllegalArgumentException e) {
+            if (DBG) Log.e(TAG, "Cannot create template", e);
+            return null;
+        }
+
+        return querySummary(template, startTime, endTime);
+    }
+
+    /**
+     * Query network usage statistics summaries.
+     *
+     * The results will only include traffic made by UIDs belonging to the calling user profile.
+     * The results are aggregated over time, so that all buckets will have the same start and
+     * end timestamps as the passed arguments. Not aggregated over state, uid, default network,
+     * metered, or roaming.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param startTime Start of period, in milliseconds since the Unix epoch, see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period, in milliseconds since the Unix epoch, see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @return Statistics which is described above.
+     * @hide
+     */
+    @NonNull
+    @SystemApi(client = MODULE_LIBRARIES)
+    @WorkerThread
+    public NetworkStats querySummary(@NonNull NetworkTemplate template, long startTime,
+            long endTime) throws SecurityException {
+        Objects.requireNonNull(template);
+        try {
+            NetworkStats result =
+                    new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
+            result.startSummaryEnumeration();
+            return result;
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return null; // To make the compiler happy.
+    }
+
+    /**
+     * Query tagged network usage statistics summaries.
+     *
+     * The results will only include tagged traffic made by UIDs belonging to the calling user
+     * profile. The results are aggregated over time, so that all buckets will have the same
+     * start and end timestamps as the passed arguments. Not aggregated over state, uid,
+     * default network, metered, or roaming.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param startTime Start of period, in milliseconds since the Unix epoch, see
+     *            {@link System#currentTimeMillis}.
+     * @param endTime End of period, in milliseconds since the Unix epoch, see
+     *            {@link System#currentTimeMillis}.
+     * @return Statistics which is described above.
+     * @hide
+     */
+    @NonNull
+    @SystemApi(client = MODULE_LIBRARIES)
+    @WorkerThread
+    public NetworkStats queryTaggedSummary(@NonNull NetworkTemplate template, long startTime,
+            long endTime) throws SecurityException {
+        Objects.requireNonNull(template);
+        try {
+            NetworkStats result =
+                    new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
+            result.startTaggedSummaryEnumeration();
+            return result;
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return null; // To make the compiler happy.
+    }
+
+    /**
+     * Query usage statistics details for networks matching a given {@link NetworkTemplate}.
+     *
+     * Result is not aggregated over time. This means buckets' start and
+     * end timestamps will be between 'startTime' and 'endTime' parameters.
+     * <p>Only includes buckets whose entire time period is included between
+     * startTime and endTime. Doesn't interpolate or return partial buckets.
+     * Since bucket length is in the order of hours, this
+     * method cannot be used to measure data usage on a fine grained time scale.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param startTime Start of period, in milliseconds since the Unix epoch, see
+     *                  {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period, in milliseconds since the Unix epoch, see
+     *                {@link java.lang.System#currentTimeMillis}.
+     * @return Statistics which is described above.
+     * @hide
+     */
+    @NonNull
+    @SystemApi(client = MODULE_LIBRARIES)
+    @WorkerThread
+    public NetworkStats queryDetailsForDevice(@NonNull NetworkTemplate template,
+            long startTime, long endTime) {
+        Objects.requireNonNull(template);
+        try {
+            final NetworkStats result =
+                    new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
+            result.startHistoryDeviceEnumeration();
+            return result;
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        return null; // To make the compiler happy.
+    }
+
+    /**
+     * Query network usage statistics details for a given uid.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @see #queryDetailsForUidTagState(int, String, long, long, int, int, int)
+     */
+    @NonNull
+    @WorkerThread
+    public NetworkStats queryDetailsForUid(int networkType, @Nullable String subscriberId,
+            long startTime, long endTime, int uid) throws SecurityException {
+        return queryDetailsForUidTagState(networkType, subscriberId, startTime, endTime, uid,
+            NetworkStats.Bucket.TAG_NONE, NetworkStats.Bucket.STATE_ALL);
+    }
+
+    /** @hide */
+    @NonNull
+    public NetworkStats queryDetailsForUid(@NonNull NetworkTemplate template,
+            long startTime, long endTime, int uid) throws SecurityException {
+        return queryDetailsForUidTagState(template, startTime, endTime, uid,
+                NetworkStats.Bucket.TAG_NONE, NetworkStats.Bucket.STATE_ALL);
+    }
+
+    /**
+     * Query network usage statistics details for a given uid and tag.
+     *
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     * Only usable for uids belonging to calling user. Result is not aggregated over time.
+     * This means buckets' start and end timestamps are going to be between 'startTime' and
+     * 'endTime' parameters. The uid is going to be the same as the 'uid' parameter, the tag
+     * the same as the 'tag' parameter, and the state the same as the 'state' parameter.
+     * defaultNetwork is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
+     * metered is going to be {@link NetworkStats.Bucket#METERED_ALL}, and
+     * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
+     * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
+     * interpolate across partial buckets. Since bucket length is in the order of hours, this
+     * method cannot be used to measure data usage on a fine grained time scale.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param networkType As defined in {@link ConnectivityManager}, e.g.
+     *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+     *            etc.
+     * @param subscriberId If applicable, the subscriber id of the network interface.
+     *                     <p>Starting with API level 29, the {@code subscriberId} is guarded by
+     *                     additional restrictions. Calling apps that do not meet the new
+     *                     requirements to access the {@code subscriberId} can provide a {@code
+     *                     null} value when querying for the mobile network type to receive usage
+     *                     for all mobile networks. For additional details see {@link
+     *                     TelephonyManager#getSubscriberId()}.
+     *                     <p>Starting with API level 31, calling apps can provide a
+     *                     {@code subscriberId} with wifi network type to receive usage for
+     *                     wifi networks which is under the given subscription if applicable.
+     *                     Otherwise, pass {@code null} when querying all wifi networks.
+     * @param startTime Start of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param uid UID of app
+     * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for aggregated data
+     *            across all the tags.
+     * @return Statistics which is described above.
+     * @throws SecurityException if permissions are insufficient to read network statistics.
+     */
+    @NonNull
+    @WorkerThread
+    public NetworkStats queryDetailsForUidTag(int networkType, @Nullable String subscriberId,
+            long startTime, long endTime, int uid, int tag) throws SecurityException {
+        return queryDetailsForUidTagState(networkType, subscriberId, startTime, endTime, uid,
+            tag, NetworkStats.Bucket.STATE_ALL);
+    }
+
+    /**
+     * Query network usage statistics details for a given uid, tag, and state.
+     *
+     * Only usable for uids belonging to calling user. Result is not aggregated over time.
+     * This means buckets' start and end timestamps are going to be between 'startTime' and
+     * 'endTime' parameters. The uid is going to be the same as the 'uid' parameter, the tag
+     * the same as the 'tag' parameter, and the state the same as the 'state' parameter.
+     * defaultNetwork is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
+     * metered is going to be {@link NetworkStats.Bucket#METERED_ALL}, and
+     * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
+     * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
+     * interpolate across partial buckets. Since bucket length is in the order of hours, this
+     * method cannot be used to measure data usage on a fine grained time scale.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param networkType As defined in {@link ConnectivityManager}, e.g.
+     *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+     *            etc.
+     * @param subscriberId If applicable, the subscriber id of the network interface.
+     *                     <p>Starting with API level 29, the {@code subscriberId} is guarded by
+     *                     additional restrictions. Calling apps that do not meet the new
+     *                     requirements to access the {@code subscriberId} can provide a {@code
+     *                     null} value when querying for the mobile network type to receive usage
+     *                     for all mobile networks. For additional details see {@link
+     *                     TelephonyManager#getSubscriberId()}.
+     *                     <p>Starting with API level 31, calling apps can provide a
+     *                     {@code subscriberId} with wifi network type to receive usage for
+     *                     wifi networks which is under the given subscription if applicable.
+     *                     Otherwise, pass {@code null} when querying all wifi networks.
+     * @param startTime Start of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param uid UID of app
+     * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for aggregated data
+     *            across all the tags.
+     * @param state state of interest. Use {@link NetworkStats.Bucket#STATE_ALL} to aggregate
+     *            traffic from all states.
+     * @return Statistics which is described above.
+     * @throws SecurityException if permissions are insufficient to read network statistics.
+     */
+    @NonNull
+    @WorkerThread
+    public NetworkStats queryDetailsForUidTagState(int networkType, @Nullable String subscriberId,
+            long startTime, long endTime, int uid, int tag, int state) throws SecurityException {
+        NetworkTemplate template;
+        template = createTemplate(networkType, subscriberId);
+
+        return queryDetailsForUidTagState(template, startTime, endTime, uid, tag, state);
+    }
+
+    /**
+     * Query network usage statistics details for a given template, uid, tag, and state.
+     *
+     * Only usable for uids belonging to calling user. Result is not aggregated over time.
+     * This means buckets' start and end timestamps are going to be between 'startTime' and
+     * 'endTime' parameters. The uid is going to be the same as the 'uid' parameter, the tag
+     * the same as the 'tag' parameter, and the state the same as the 'state' parameter.
+     * defaultNetwork is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
+     * metered is going to be {@link NetworkStats.Bucket#METERED_ALL}, and
+     * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
+     * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
+     * interpolate across partial buckets. Since bucket length is in the order of hours, this
+     * method cannot be used to measure data usage on a fine grained time scale.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param startTime Start of period, in milliseconds since the Unix epoch, see
+     *                  {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period, in milliseconds since the Unix epoch, see
+     *                {@link java.lang.System#currentTimeMillis}.
+     * @param uid UID of app
+     * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for aggregated data
+     *            across all the tags.
+     * @param state state of interest. Use {@link NetworkStats.Bucket#STATE_ALL} to aggregate
+     *            traffic from all states.
+     * @return Statistics which is described above.
+     * @hide
+     */
+    @NonNull
+    @SystemApi(client = MODULE_LIBRARIES)
+    @WorkerThread
+    public NetworkStats queryDetailsForUidTagState(@NonNull NetworkTemplate template,
+            long startTime, long endTime, int uid, int tag, int state) throws SecurityException {
+        Objects.requireNonNull(template);
+        try {
+            final NetworkStats result = new NetworkStats(
+                    mContext, template, mFlags, startTime, endTime, mService);
+            result.startHistoryUidEnumeration(uid, tag, state);
+            return result;
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error while querying stats for uid=" + uid + " tag=" + tag
+                    + " state=" + state, e);
+            e.rethrowFromSystemServer();
+        }
+
+        return null; // To make the compiler happy.
+    }
+
+    /**
+     * Query network usage statistics details. Result filtered to include only uids belonging to
+     * calling user. Result is aggregated over state but not aggregated over time, uid, tag,
+     * metered, nor roaming. This means buckets' start and end timestamps are going to be between
+     * 'startTime' and 'endTime' parameters. State is going to be
+     * {@link NetworkStats.Bucket#STATE_ALL}, uid will vary,
+     * tag {@link NetworkStats.Bucket#TAG_NONE},
+     * default network is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
+     * metered is going to be {@link NetworkStats.Bucket#METERED_ALL},
+     * and roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
+     * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
+     * interpolate across partial buckets. Since bucket length is in the order of hours, this
+     * method cannot be used to measure data usage on a fine grained time scale.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param networkType As defined in {@link ConnectivityManager}, e.g.
+     *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+     *            etc.
+     * @param subscriberId If applicable, the subscriber id of the network interface.
+     *                     <p>Starting with API level 29, the {@code subscriberId} is guarded by
+     *                     additional restrictions. Calling apps that do not meet the new
+     *                     requirements to access the {@code subscriberId} can provide a {@code
+     *                     null} value when querying for the mobile network type to receive usage
+     *                     for all mobile networks. For additional details see {@link
+     *                     TelephonyManager#getSubscriberId()}.
+     *                     <p>Starting with API level 31, calling apps can provide a
+     *                     {@code subscriberId} with wifi network type to receive usage for
+     *                     wifi networks which is under the given subscription if applicable.
+     *                     Otherwise, pass {@code null} when querying all wifi networks.
+     * @param startTime Start of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period. Defined in terms of "Unix time", see
+     *            {@link java.lang.System#currentTimeMillis}.
+     * @return Statistics object or null if permissions are insufficient or error happened during
+     *         statistics collection.
+     */
+    @WorkerThread
+    public NetworkStats queryDetails(int networkType, @Nullable String subscriberId, long startTime,
+            long endTime) throws SecurityException, RemoteException {
+        NetworkTemplate template;
+        try {
+            template = createTemplate(networkType, subscriberId);
+        } catch (IllegalArgumentException e) {
+            if (DBG) Log.e(TAG, "Cannot create template", e);
+            return null;
+        }
+
+        NetworkStats result;
+        result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
+        result.startUserUidEnumeration();
+        return result;
+    }
+
+    /**
+     * Query realtime mobile network usage statistics.
+     *
+     * Return a snapshot of current UID network statistics, as it applies
+     * to the mobile radios of the device. The snapshot will include any
+     * tethering traffic, video calling data usage and count of
+     * network operations set by {@link TrafficStats#incrementOperationCount}
+     * made over a mobile radio.
+     * The snapshot will not include any statistics that cannot be seen by
+     * the kernel, e.g. statistics reported by {@link NetworkStatsProvider}s.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    @NonNull public android.net.NetworkStats getMobileUidStats() {
+        try {
+            return mService.getUidStatsForTransport(TRANSPORT_CELLULAR);
+        } catch (RemoteException e) {
+            if (DBG) Log.d(TAG, "Remote exception when get Mobile uid stats");
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Query realtime Wi-Fi network usage statistics.
+     *
+     * Return a snapshot of current UID network statistics, as it applies
+     * to the Wi-Fi radios of the device. The snapshot will include any
+     * tethering traffic, video calling data usage and count of
+     * network operations set by {@link TrafficStats#incrementOperationCount}
+     * made over a Wi-Fi radio.
+     * The snapshot will not include any statistics that cannot be seen by
+     * the kernel, e.g. statistics reported by {@link NetworkStatsProvider}s.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    @NonNull public android.net.NetworkStats getWifiUidStats() {
+        try {
+            return mService.getUidStatsForTransport(TRANSPORT_WIFI);
+        } catch (RemoteException e) {
+            if (DBG) Log.d(TAG, "Remote exception when get WiFi uid stats");
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Registers to receive notifications about data usage on specified networks.
+     *
+     * <p>The callbacks will continue to be called as long as the process is alive or
+     * {@link #unregisterUsageCallback} is called.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param thresholdBytes Threshold in bytes to be notified on. Provided values lower than 2MiB
+     *                       will be clamped for callers except callers with the NETWORK_STACK
+     *                       permission.
+     * @param executor The executor on which callback will be invoked. The provided {@link Executor}
+     *                 must run callback sequentially, otherwise the order of callbacks cannot be
+     *                 guaranteed.
+     * @param callback The {@link UsageCallback} that the system will call when data usage
+     *                 has exceeded the specified threshold.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK}, conditional = true)
+    public void registerUsageCallback(@NonNull NetworkTemplate template, long thresholdBytes,
+            @NonNull @CallbackExecutor Executor executor, @NonNull UsageCallback callback) {
+        Objects.requireNonNull(template, "NetworkTemplate cannot be null");
+        Objects.requireNonNull(callback, "UsageCallback cannot be null");
+        Objects.requireNonNull(executor, "Executor cannot be null");
+
+        final DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET,
+                template, thresholdBytes);
+        try {
+            final UsageCallbackWrapper callbackWrapper =
+                    new UsageCallbackWrapper(executor, callback);
+            callback.request = mService.registerUsageCallback(
+                    mContext.getOpPackageName(), request, callbackWrapper);
+            if (DBG) Log.d(TAG, "registerUsageCallback returned " + callback.request);
+
+            if (callback.request == null) {
+                Log.e(TAG, "Request from callback is null; should not happen");
+            }
+        } catch (RemoteException e) {
+            if (DBG) Log.d(TAG, "Remote exception when registering callback");
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Registers to receive notifications about data usage on specified networks.
+     *
+     * <p>The callbacks will continue to be called as long as the process is live or
+     * {@link #unregisterUsageCallback} is called.
+     *
+     * @param networkType Type of network to monitor. Either
+    {@link ConnectivityManager#TYPE_MOBILE} or {@link ConnectivityManager#TYPE_WIFI}.
+     * @param subscriberId If applicable, the subscriber id of the network interface.
+     *                     <p>Starting with API level 29, the {@code subscriberId} is guarded by
+     *                     additional restrictions. Calling apps that do not meet the new
+     *                     requirements to access the {@code subscriberId} can provide a {@code
+     *                     null} value when registering for the mobile network type to receive
+     *                     notifications for all mobile networks. For additional details see {@link
+     *                     TelephonyManager#getSubscriberId()}.
+     *                     <p>Starting with API level 31, calling apps can provide a
+     *                     {@code subscriberId} with wifi network type to receive usage for
+     *                     wifi networks which is under the given subscription if applicable.
+     *                     Otherwise, pass {@code null} when querying all wifi networks.
+     * @param thresholdBytes Threshold in bytes to be notified on.
+     * @param callback The {@link UsageCallback} that the system will call when data usage
+     *            has exceeded the specified threshold.
+     */
+    public void registerUsageCallback(int networkType, @Nullable String subscriberId,
+            long thresholdBytes, @NonNull UsageCallback callback) {
+        registerUsageCallback(networkType, subscriberId, thresholdBytes, callback,
+                null /* handler */);
+    }
+
+    /**
+     * Registers to receive notifications about data usage on specified networks.
+     *
+     * <p>The callbacks will continue to be called as long as the process is live or
+     * {@link #unregisterUsageCallback} is called.
+     *
+     * @param networkType Type of network to monitor. Either
+                  {@link ConnectivityManager#TYPE_MOBILE} or {@link ConnectivityManager#TYPE_WIFI}.
+     * @param subscriberId If applicable, the subscriber id of the network interface.
+     *                     <p>Starting with API level 29, the {@code subscriberId} is guarded by
+     *                     additional restrictions. Calling apps that do not meet the new
+     *                     requirements to access the {@code subscriberId} can provide a {@code
+     *                     null} value when registering for the mobile network type to receive
+     *                     notifications for all mobile networks. For additional details see {@link
+     *                     TelephonyManager#getSubscriberId()}.
+     *                     <p>Starting with API level 31, calling apps can provide a
+     *                     {@code subscriberId} with wifi network type to receive usage for
+     *                     wifi networks which is under the given subscription if applicable.
+     *                     Otherwise, pass {@code null} when querying all wifi networks.
+     * @param thresholdBytes Threshold in bytes to be notified on.
+     * @param callback The {@link UsageCallback} that the system will call when data usage
+     *            has exceeded the specified threshold.
+     * @param handler to dispatch callback events through, otherwise if {@code null} it uses
+     *            the calling thread.
+     */
+    public void registerUsageCallback(int networkType, @Nullable String subscriberId,
+            long thresholdBytes, @NonNull UsageCallback callback, @Nullable Handler handler) {
+        NetworkTemplate template = createTemplate(networkType, subscriberId);
+        if (DBG) {
+            Log.d(TAG, "registerUsageCallback called with: {"
+                    + " networkType=" + networkType
+                    + " subscriberId=" + subscriberId
+                    + " thresholdBytes=" + thresholdBytes
+                    + " }");
+        }
+
+        final Executor executor = handler == null ? r -> r.run() : r -> handler.post(r);
+
+        registerUsageCallback(template, thresholdBytes, executor, callback);
+    }
+
+    /**
+     * Unregisters callbacks on data usage.
+     *
+     * @param callback The {@link UsageCallback} used when registering.
+     */
+    public void unregisterUsageCallback(@NonNull UsageCallback callback) {
+        if (callback == null || callback.request == null
+                || callback.request.requestId == DataUsageRequest.REQUEST_ID_UNSET) {
+            throw new IllegalArgumentException("Invalid UsageCallback");
+        }
+        try {
+            mService.unregisterUsageRequest(callback.request);
+        } catch (RemoteException e) {
+            if (DBG) Log.d(TAG, "Remote exception when unregistering callback");
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Base class for usage callbacks. Should be extended by applications wanting notifications.
+     */
+    public static abstract class UsageCallback {
+        /**
+         * Called when data usage has reached the given threshold.
+         *
+         * Called by {@code NetworkStatsService} when the registered threshold is reached.
+         * If a caller implements {@link #onThresholdReached(NetworkTemplate)}, the system
+         * will not call {@link #onThresholdReached(int, String)}.
+         *
+         * @param template The {@link NetworkTemplate} that associated with this callback.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public void onThresholdReached(@NonNull NetworkTemplate template) {
+            // Backward compatibility for those who didn't override this function.
+            final int networkType = networkTypeForTemplate(template);
+            if (networkType != ConnectivityManager.TYPE_NONE) {
+                final String subscriberId = template.getSubscriberIds().isEmpty() ? null
+                        : template.getSubscriberIds().iterator().next();
+                onThresholdReached(networkType, subscriberId);
+            }
+        }
+
+        /**
+         * Called when data usage has reached the given threshold.
+         */
+        public abstract void onThresholdReached(int networkType, @Nullable String subscriberId);
+
+        /**
+         * @hide used for internal bookkeeping
+         */
+        private DataUsageRequest request;
+
+        /**
+         * Get network type from a template if feasible.
+         *
+         * @param template the target {@link NetworkTemplate}.
+         * @return legacy network type, only supports for the types which is already supported in
+         *         {@link #registerUsageCallback(int, String, long, UsageCallback, Handler)}.
+         *         {@link ConnectivityManager#TYPE_NONE} for other types.
+         */
+        private static int networkTypeForTemplate(@NonNull NetworkTemplate template) {
+            switch (template.getMatchRule()) {
+                case NetworkTemplate.MATCH_MOBILE:
+                    return ConnectivityManager.TYPE_MOBILE;
+                case NetworkTemplate.MATCH_WIFI:
+                    return ConnectivityManager.TYPE_WIFI;
+                default:
+                    return ConnectivityManager.TYPE_NONE;
+            }
+        }
+    }
+
+    /**
+     * Registers a custom provider of {@link android.net.NetworkStats} to provide network statistics
+     * to the system. To unregister, invoke {@link #unregisterNetworkStatsProvider}.
+     * Note that no de-duplication of statistics between providers is performed, so each provider
+     * must only report network traffic that is not being reported by any other provider. Also note
+     * that the provider cannot be re-registered after unregistering.
+     *
+     * @param tag a human readable identifier of the custom network stats provider. This is only
+     *            used for debugging.
+     * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
+     *                 registered to the system.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_STATS_PROVIDER,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
+    public void registerNetworkStatsProvider(
+            @NonNull String tag,
+            @NonNull NetworkStatsProvider provider) {
+        try {
+            if (provider.getProviderCallbackBinder() != null) {
+                throw new IllegalArgumentException("provider is already registered");
+            }
+            final INetworkStatsProviderCallback cbBinder =
+                    mService.registerNetworkStatsProvider(tag, provider.getProviderBinder());
+            provider.setProviderCallbackBinder(cbBinder);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Unregisters an instance of {@link NetworkStatsProvider}.
+     *
+     * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
+     *                 unregistered to the system.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_STATS_PROVIDER,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
+    public void unregisterNetworkStatsProvider(@NonNull NetworkStatsProvider provider) {
+        try {
+            provider.getProviderCallbackBinderOrThrow().unregister();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    private static NetworkTemplate createTemplate(int networkType, @Nullable String subscriberId) {
+        final NetworkTemplate template;
+        switch (networkType) {
+            case ConnectivityManager.TYPE_MOBILE:
+                template = subscriberId == null
+                        ? NetworkTemplate.buildTemplateMobileWildcard()
+                        : NetworkTemplate.buildTemplateMobileAll(subscriberId);
+                break;
+            case ConnectivityManager.TYPE_WIFI:
+                template = TextUtils.isEmpty(subscriberId)
+                        ? NetworkTemplate.buildTemplateWifiWildcard()
+                        : NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
+                                subscriberId);
+                break;
+            default:
+                throw new IllegalArgumentException("Cannot create template for network type "
+                        + networkType + ", subscriberId '"
+                        + NetworkIdentityUtils.scrubSubscriberId(subscriberId) + "'.");
+        }
+        return template;
+    }
+
+    /**
+     * Notify {@code NetworkStatsService} about network status changed.
+     *
+     * Notifies NetworkStatsService of network state changes for data usage accounting purposes.
+     *
+     * To avoid races that attribute data usage to wrong network, such as new network with
+     * the same interface after SIM hot-swap, this function will not return until
+     * {@code NetworkStatsService} finishes its work of retrieving traffic statistics from
+     * all data sources.
+     *
+     * @param defaultNetworks the list of all networks that could be used by network traffic that
+     *                        does not explicitly select a network.
+     * @param networkStateSnapshots a list of {@link NetworkStateSnapshot}s, one for
+     *                              each network that is currently connected.
+     * @param activeIface the active (i.e., connected) default network interface for the calling
+     *                    uid. Used to determine on which network future calls to
+     *                    {@link android.net.TrafficStats#incrementOperationCount} applies to.
+     * @param underlyingNetworkInfos the list of underlying network information for all
+     *                               currently-connected VPNs.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public void notifyNetworkStatus(
+            @NonNull List<Network> defaultNetworks,
+            @NonNull List<NetworkStateSnapshot> networkStateSnapshots,
+            @Nullable String activeIface,
+            @NonNull List<UnderlyingNetworkInfo> underlyingNetworkInfos) {
+        try {
+            Objects.requireNonNull(defaultNetworks);
+            Objects.requireNonNull(networkStateSnapshots);
+            Objects.requireNonNull(underlyingNetworkInfos);
+            mService.notifyNetworkStatus(defaultNetworks.toArray(new Network[0]),
+                    networkStateSnapshots.toArray(new NetworkStateSnapshot[0]), activeIface,
+                    underlyingNetworkInfos.toArray(new UnderlyingNetworkInfo[0]));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private static class UsageCallbackWrapper extends IUsageCallback.Stub {
+        // Null if unregistered.
+        private volatile UsageCallback mCallback;
+
+        private final Executor mExecutor;
+
+        UsageCallbackWrapper(@NonNull Executor executor, @NonNull UsageCallback callback) {
+            mCallback = callback;
+            mExecutor = executor;
+        }
+
+        @Override
+        public void onThresholdReached(DataUsageRequest request) {
+            // Copy it to a local variable in case mCallback changed inside the if condition.
+            final UsageCallback callback = mCallback;
+            if (callback != null) {
+                mExecutor.execute(() -> callback.onThresholdReached(request.template));
+            } else {
+                Log.e(TAG, "onThresholdReached with released callback for " + request);
+            }
+        }
+
+        @Override
+        public void onCallbackReleased(DataUsageRequest request) {
+            if (DBG) Log.d(TAG, "callback released for " + request);
+            mCallback = null;
+        }
+    }
+
+    /**
+     * Mark given UID as being in foreground for stats purposes.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public void noteUidForeground(int uid, boolean uidForeground) {
+        try {
+            mService.noteUidForeground(uid, uidForeground);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set default value of global alert bytes, the value will be clamped to [128kB, 2MB].
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            Manifest.permission.NETWORK_STACK})
+    public void setDefaultGlobalAlert(long alertBytes) {
+        try {
+            // TODO: Sync internal naming with the API surface.
+            mService.advisePersistThreshold(alertBytes);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Force update of statistics.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public void forceUpdate() {
+        try {
+            mService.forceUpdate();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set the warning and limit to all registered custom network stats providers.
+     * Note that invocation of any interface will be sent to all providers.
+     *
+     * Asynchronicity notes : because traffic may be happening on the device at the same time, it
+     * doesn't make sense to wait for the warning and limit to be set – a caller still wouldn't
+     * know when exactly it was effective. All that can matter is that it's done quickly. Also,
+     * this method can't fail, so there is no status to return. All providers will see the new
+     * values soon.
+     * As such, this method returns immediately and sends the warning and limit to all providers
+     * as soon as possible through a one-way binder call.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public void setStatsProviderWarningAndLimitAsync(@NonNull String iface, long warning,
+            long limit) {
+        try {
+            mService.setStatsProviderWarningAndLimitAsync(iface, warning, limit);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get a RAT type representative of a group of RAT types for network statistics.
+     *
+     * Collapse the given Radio Access Technology (RAT) type into a bucket that
+     * is representative of the original RAT type for network statistics. The
+     * mapping mostly corresponds to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*}
+     * but with adaptations specific to the virtual types introduced by
+     * networks stats.
+     *
+     * @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static int getCollapsedRatType(int ratType) {
+        switch (ratType) {
+            case TelephonyManager.NETWORK_TYPE_GPRS:
+            case TelephonyManager.NETWORK_TYPE_GSM:
+            case TelephonyManager.NETWORK_TYPE_EDGE:
+            case TelephonyManager.NETWORK_TYPE_IDEN:
+            case TelephonyManager.NETWORK_TYPE_CDMA:
+            case TelephonyManager.NETWORK_TYPE_1xRTT:
+                return TelephonyManager.NETWORK_TYPE_GSM;
+            case TelephonyManager.NETWORK_TYPE_EVDO_0:
+            case TelephonyManager.NETWORK_TYPE_EVDO_A:
+            case TelephonyManager.NETWORK_TYPE_EVDO_B:
+            case TelephonyManager.NETWORK_TYPE_EHRPD:
+            case TelephonyManager.NETWORK_TYPE_UMTS:
+            case TelephonyManager.NETWORK_TYPE_HSDPA:
+            case TelephonyManager.NETWORK_TYPE_HSUPA:
+            case TelephonyManager.NETWORK_TYPE_HSPA:
+            case TelephonyManager.NETWORK_TYPE_HSPAP:
+            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
+                return TelephonyManager.NETWORK_TYPE_UMTS;
+            case TelephonyManager.NETWORK_TYPE_LTE:
+            case TelephonyManager.NETWORK_TYPE_IWLAN:
+                return TelephonyManager.NETWORK_TYPE_LTE;
+            case TelephonyManager.NETWORK_TYPE_NR:
+                return TelephonyManager.NETWORK_TYPE_NR;
+            // Virtual RAT type for 5G NSA mode, see
+            // {@link NetworkStatsManager#NETWORK_TYPE_5G_NSA}.
+            case NetworkStatsManager.NETWORK_TYPE_5G_NSA:
+                return NetworkStatsManager.NETWORK_TYPE_5G_NSA;
+            default:
+                return TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        }
+    }
+}
diff --git a/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java b/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
new file mode 100644
index 0000000..61b34d0
--- /dev/null
+++ b/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
@@ -0,0 +1,82 @@
+/*
+ * 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 android.net;
+
+import android.annotation.SystemApi;
+import android.app.SystemServiceRegistry;
+import android.app.usage.NetworkStatsManager;
+import android.content.Context;
+import android.net.nsd.INsdManager;
+import android.net.nsd.NsdManager;
+
+/**
+ * Class for performing registration for Connectivity services which are exposed via updatable APIs
+ * since Android T.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class ConnectivityFrameworkInitializerTiramisu {
+    private ConnectivityFrameworkInitializerTiramisu() {}
+
+    /**
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers NetworkStats, nsd,
+     * ipsec and ethernet services to {@link Context}, so that {@link Context#getSystemService} can
+     * return them.
+     *
+     * @throws IllegalStateException if this is called anywhere besides
+     * {@link SystemServiceRegistry}.
+     */
+    public static void registerServiceWrappers() {
+        SystemServiceRegistry.registerContextAwareService(
+                Context.NSD_SERVICE,
+                NsdManager.class,
+                (context, serviceBinder) -> {
+                    INsdManager service = INsdManager.Stub.asInterface(serviceBinder);
+                    return new NsdManager(context, service);
+                }
+        );
+
+        SystemServiceRegistry.registerContextAwareService(
+                Context.IPSEC_SERVICE,
+                IpSecManager.class,
+                (context, serviceBinder) -> {
+                    IIpSecService service = IIpSecService.Stub.asInterface(serviceBinder);
+                    return new IpSecManager(context, service);
+                }
+        );
+
+        SystemServiceRegistry.registerContextAwareService(
+                Context.NETWORK_STATS_SERVICE,
+                NetworkStatsManager.class,
+                (context, serviceBinder) -> {
+                    INetworkStatsService service =
+                            INetworkStatsService.Stub.asInterface(serviceBinder);
+                    return new NetworkStatsManager(context, service);
+                }
+        );
+
+        SystemServiceRegistry.registerContextAwareService(
+                Context.ETHERNET_SERVICE,
+                EthernetManager.class,
+                (context, serviceBinder) -> {
+                    IEthernetManager service = IEthernetManager.Stub.asInterface(serviceBinder);
+                    return new EthernetManager(context, service);
+                }
+        );
+    }
+}
diff --git a/framework-t/src/android/net/DataUsageRequest.aidl b/framework-t/src/android/net/DataUsageRequest.aidl
new file mode 100644
index 0000000..d1937c7
--- /dev/null
+++ b/framework-t/src/android/net/DataUsageRequest.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.
+ */
+
+package android.net;
+
+parcelable DataUsageRequest;
diff --git a/framework-t/src/android/net/DataUsageRequest.java b/framework-t/src/android/net/DataUsageRequest.java
new file mode 100644
index 0000000..f0ff465
--- /dev/null
+++ b/framework-t/src/android/net/DataUsageRequest.java
@@ -0,0 +1,112 @@
+/**
+ * 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.
+ */
+
+package android.net;
+
+import android.annotation.Nullable;
+import android.net.NetworkTemplate;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Defines a request to register a callbacks. Used to be notified on data usage via
+ * {@link android.app.usage.NetworkStatsManager#registerDataUsageCallback}.
+ * If no {@code uid}s are set, callbacks are restricted to device-owners,
+ * carrier-privileged apps, or system apps.
+ *
+ * @hide
+ */
+public final class DataUsageRequest implements Parcelable {
+
+    public static final String PARCELABLE_KEY = "DataUsageRequest";
+    public static final int REQUEST_ID_UNSET = 0;
+
+    /**
+     * Identifies the request.  {@link DataUsageRequest}s should only be constructed by
+     * the Framework and it is used internally to identify the request.
+     */
+    public final int requestId;
+
+    /**
+     * {@link NetworkTemplate} describing the network to monitor.
+     */
+    public final NetworkTemplate template;
+
+    /**
+     * Threshold in bytes to be notified on.
+     */
+    public final long thresholdInBytes;
+
+    public DataUsageRequest(int requestId, NetworkTemplate template, long thresholdInBytes) {
+        this.requestId = requestId;
+        this.template = template;
+        this.thresholdInBytes = thresholdInBytes;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(requestId);
+        dest.writeParcelable(template, flags);
+        dest.writeLong(thresholdInBytes);
+    }
+
+    public static final @android.annotation.NonNull Creator<DataUsageRequest> CREATOR =
+            new Creator<DataUsageRequest>() {
+                @Override
+                public DataUsageRequest createFromParcel(Parcel in) {
+                    int requestId = in.readInt();
+                    NetworkTemplate template = in.readParcelable(null, android.net.NetworkTemplate.class);
+                    long thresholdInBytes = in.readLong();
+                    DataUsageRequest result = new DataUsageRequest(requestId, template,
+                            thresholdInBytes);
+                    return result;
+                }
+
+                @Override
+                public DataUsageRequest[] newArray(int size) {
+                    return new DataUsageRequest[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        return "DataUsageRequest [ requestId=" + requestId
+                + ", networkTemplate=" + template
+                + ", thresholdInBytes=" + thresholdInBytes + " ]";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj instanceof DataUsageRequest == false) return false;
+        DataUsageRequest that = (DataUsageRequest) obj;
+        return that.requestId == this.requestId
+                && Objects.equals(that.template, this.template)
+                && that.thresholdInBytes == this.thresholdInBytes;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(requestId, template, thresholdInBytes);
+   }
+
+}
diff --git a/framework-t/src/android/net/EthernetManager.java b/framework-t/src/android/net/EthernetManager.java
new file mode 100644
index 0000000..e02ea89
--- /dev/null
+++ b/framework-t/src/android/net/EthernetManager.java
@@ -0,0 +1,729 @@
+/*
+ * Copyright (C) 2014 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;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.OutcomeReceiver;
+import android.os.RemoteException;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.modules.utils.BackgroundThread;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.function.IntConsumer;
+
+/**
+ * A class that manages and configures Ethernet interfaces.
+ *
+ * @hide
+ */
+@SystemApi
+@SystemService(Context.ETHERNET_SERVICE)
+public class EthernetManager {
+    private static final String TAG = "EthernetManager";
+
+    private final IEthernetManager mService;
+    @GuardedBy("mListenerLock")
+    private final ArrayList<ListenerInfo<InterfaceStateListener>> mIfaceListeners =
+            new ArrayList<>();
+    @GuardedBy("mListenerLock")
+    private final ArrayList<ListenerInfo<IntConsumer>> mEthernetStateListeners =
+            new ArrayList<>();
+    final Object mListenerLock = new Object();
+    private final IEthernetServiceListener.Stub mServiceListener =
+            new IEthernetServiceListener.Stub() {
+                @Override
+                public void onEthernetStateChanged(int state) {
+                    synchronized (mListenerLock) {
+                        for (ListenerInfo<IntConsumer> li : mEthernetStateListeners) {
+                            li.executor.execute(() -> {
+                                li.listener.accept(state);
+                            });
+                        }
+                    }
+                }
+
+                @Override
+                public void onInterfaceStateChanged(String iface, int state, int role,
+                        IpConfiguration configuration) {
+                    synchronized (mListenerLock) {
+                        for (ListenerInfo<InterfaceStateListener> li : mIfaceListeners) {
+                            li.executor.execute(() ->
+                                    li.listener.onInterfaceStateChanged(iface, state, role,
+                                            configuration));
+                        }
+                    }
+                }
+            };
+
+    /**
+     * Indicates that Ethernet is disabled.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int ETHERNET_STATE_DISABLED = 0;
+
+    /**
+     * Indicates that Ethernet is enabled.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int ETHERNET_STATE_ENABLED  = 1;
+
+    private static class ListenerInfo<T> {
+        @NonNull
+        public final Executor executor;
+        @NonNull
+        public final T listener;
+
+        private ListenerInfo(@NonNull Executor executor, @NonNull T listener) {
+            this.executor = executor;
+            this.listener = listener;
+        }
+    }
+
+    /**
+     * The interface is absent.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int STATE_ABSENT = 0;
+
+    /**
+     * The interface is present but link is down.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int STATE_LINK_DOWN = 1;
+
+    /**
+     * The interface is present and link is up.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int STATE_LINK_UP = 2;
+
+    /** @hide */
+    @IntDef(prefix = "STATE_", value = {STATE_ABSENT, STATE_LINK_DOWN, STATE_LINK_UP})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InterfaceState {}
+
+    /**
+     * The interface currently does not have any specific role.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int ROLE_NONE = 0;
+
+    /**
+     * The interface is in client mode (e.g., connected to the Internet).
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int ROLE_CLIENT = 1;
+
+    /**
+     * Ethernet interface is in server mode (e.g., providing Internet access to tethered devices).
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int ROLE_SERVER = 2;
+
+    /** @hide */
+    @IntDef(prefix = "ROLE_", value = {ROLE_NONE, ROLE_CLIENT, ROLE_SERVER})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Role {}
+
+    /**
+     * A listener that receives notifications about the state of Ethernet interfaces on the system.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public interface InterfaceStateListener {
+        /**
+         * Called when an Ethernet interface changes state.
+         *
+         * @param iface the name of the interface.
+         * @param state the current state of the interface, or {@link #STATE_ABSENT} if the
+         *              interface was removed.
+         * @param role whether the interface is in client mode or server mode.
+         * @param configuration the current IP configuration of the interface.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        void onInterfaceStateChanged(@NonNull String iface, @InterfaceState int state,
+                @Role int role, @Nullable IpConfiguration configuration);
+    }
+
+    /**
+     * A listener interface to receive notification on changes in Ethernet.
+     * This has never been a supported API. Use {@link InterfaceStateListener} instead.
+     * @hide
+     */
+    public interface Listener extends InterfaceStateListener {
+        /**
+         * Called when Ethernet port's availability is changed.
+         * @param iface Ethernet interface name
+         * @param isAvailable {@code true} if Ethernet port exists.
+         * @hide
+         */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        void onAvailabilityChanged(String iface, boolean isAvailable);
+
+        /** Default implementation for backwards compatibility. Only calls the legacy listener. */
+        default void onInterfaceStateChanged(@NonNull String iface, @InterfaceState int state,
+                @Role int role, @Nullable IpConfiguration configuration) {
+            onAvailabilityChanged(iface, (state >= STATE_LINK_UP));
+        }
+
+    }
+
+    /**
+     * Create a new EthernetManager instance.
+     * Applications will almost always want to use
+     * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
+     * the standard {@link android.content.Context#ETHERNET_SERVICE Context.ETHERNET_SERVICE}.
+     * @hide
+     */
+    public EthernetManager(Context context, IEthernetManager service) {
+        mService = service;
+    }
+
+    /**
+     * Get Ethernet configuration.
+     * @return the Ethernet Configuration, contained in {@link IpConfiguration}.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public IpConfiguration getConfiguration(String iface) {
+        try {
+            return mService.getConfiguration(iface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set Ethernet configuration.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) {
+        try {
+            mService.setConfiguration(iface, config);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Indicates whether the system currently has one or more Ethernet interfaces.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public boolean isAvailable() {
+        return getAvailableInterfaces().length > 0;
+    }
+
+    /**
+     * Indicates whether the system has given interface.
+     *
+     * @param iface Ethernet interface name
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public boolean isAvailable(String iface) {
+        try {
+            return mService.isAvailable(iface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Adds a listener.
+     * This has never been a supported API. Use {@link #addInterfaceStateListener} instead.
+     *
+     * @param listener A {@link Listener} to add.
+     * @throws IllegalArgumentException If the listener is null.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void addListener(@NonNull Listener listener) {
+        addListener(listener, BackgroundThread.getExecutor());
+    }
+
+    /**
+     * Adds a listener.
+     * This has never been a supported API. Use {@link #addInterfaceStateListener} instead.
+     *
+     * @param listener A {@link Listener} to add.
+     * @param executor Executor to run callbacks on.
+     * @throws IllegalArgumentException If the listener or executor is null.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void addListener(@NonNull Listener listener, @NonNull Executor executor) {
+        addInterfaceStateListener(executor, listener);
+    }
+
+    /**
+     * Listen to changes in the state of Ethernet interfaces.
+     *
+     * Adds a listener to receive notification for any state change of all existing Ethernet
+     * interfaces.
+     * <p>{@link Listener#onInterfaceStateChanged} will be triggered immediately for all
+     * existing interfaces upon adding a listener. The same method will be called on the
+     * listener every time any of the interface changes state. In particular, if an
+     * interface is removed, it will be called with state {@link #STATE_ABSENT}.
+     * <p>Use {@link #removeInterfaceStateListener} with the same object to stop listening.
+     *
+     * @param executor Executor to run callbacks on.
+     * @param listener A {@link Listener} to add.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public void addInterfaceStateListener(@NonNull Executor executor,
+            @NonNull InterfaceStateListener listener) {
+        if (listener == null || executor == null) {
+            throw new NullPointerException("listener and executor must not be null");
+        }
+        synchronized (mListenerLock) {
+            maybeAddServiceListener();
+            mIfaceListeners.add(new ListenerInfo<InterfaceStateListener>(executor, listener));
+        }
+    }
+
+    @GuardedBy("mListenerLock")
+    private void maybeAddServiceListener() {
+        if (!mIfaceListeners.isEmpty() || !mEthernetStateListeners.isEmpty()) return;
+
+        try {
+            mService.addListener(mServiceListener);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+    }
+
+    /**
+     * Returns an array of available Ethernet interface names.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public String[] getAvailableInterfaces() {
+        try {
+            return mService.getAvailableInterfaces();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Removes a listener.
+     *
+     * @param listener A {@link Listener} to remove.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) {
+        Objects.requireNonNull(listener);
+        synchronized (mListenerLock) {
+            mIfaceListeners.removeIf(l -> l.listener == listener);
+            maybeRemoveServiceListener();
+        }
+    }
+
+    @GuardedBy("mListenerLock")
+    private void maybeRemoveServiceListener() {
+        if (!mIfaceListeners.isEmpty() || !mEthernetStateListeners.isEmpty()) return;
+
+        try {
+            mService.removeListener(mServiceListener);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes a listener.
+     * This has never been a supported API. Use {@link #removeInterfaceStateListener} instead.
+     * @param listener A {@link Listener} to remove.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void removeListener(@NonNull Listener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+        removeInterfaceStateListener(listener);
+    }
+
+    /**
+     * Whether to treat interfaces created by {@link TestNetworkManager#createTapInterface}
+     * as Ethernet interfaces. The effects of this method apply to any test interfaces that are
+     * already present on the system.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public void setIncludeTestInterfaces(boolean include) {
+        try {
+            mService.setIncludeTestInterfaces(include);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * A request for a tethered interface.
+     */
+    public static class TetheredInterfaceRequest {
+        private final IEthernetManager mService;
+        private final ITetheredInterfaceCallback mCb;
+
+        private TetheredInterfaceRequest(@NonNull IEthernetManager service,
+                @NonNull ITetheredInterfaceCallback cb) {
+            this.mService = service;
+            this.mCb = cb;
+        }
+
+        /**
+         * Release the request, causing the interface to revert back from tethering mode if there
+         * is no other requestor.
+         */
+        public void release() {
+            try {
+                mService.releaseTetheredInterface(mCb);
+            } catch (RemoteException e) {
+                e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Callback for {@link #requestTetheredInterface(TetheredInterfaceCallback)}.
+     */
+    public interface TetheredInterfaceCallback {
+        /**
+         * Called when the tethered interface is available.
+         * @param iface The name of the interface.
+         */
+        void onAvailable(@NonNull String iface);
+
+        /**
+         * Called when the tethered interface is now unavailable.
+         */
+        void onUnavailable();
+    }
+
+    /**
+     * Request a tethered interface in tethering mode.
+     *
+     * <p>When this method is called and there is at least one ethernet interface available, the
+     * system will designate one to act as a tethered interface. If there is already a tethered
+     * interface, the existing interface will be used.
+     * @param callback A callback to be called once the request has been fulfilled.
+     */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_STACK,
+            android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
+    })
+    @NonNull
+    public TetheredInterfaceRequest requestTetheredInterface(@NonNull final Executor executor,
+            @NonNull final TetheredInterfaceCallback callback) {
+        Objects.requireNonNull(callback, "Callback must be non-null");
+        Objects.requireNonNull(executor, "Executor must be non-null");
+        final ITetheredInterfaceCallback cbInternal = new ITetheredInterfaceCallback.Stub() {
+            @Override
+            public void onAvailable(String iface) {
+                executor.execute(() -> callback.onAvailable(iface));
+            }
+
+            @Override
+            public void onUnavailable() {
+                executor.execute(() -> callback.onUnavailable());
+            }
+        };
+
+        try {
+            mService.requestTetheredInterface(cbInternal);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return new TetheredInterfaceRequest(mService, cbInternal);
+    }
+
+    private static final class NetworkInterfaceOutcomeReceiver
+            extends INetworkInterfaceOutcomeReceiver.Stub {
+        @NonNull
+        private final Executor mExecutor;
+        @NonNull
+        private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback;
+
+        NetworkInterfaceOutcomeReceiver(
+                @NonNull final Executor executor,
+                @NonNull final OutcomeReceiver<String, EthernetNetworkManagementException>
+                        callback) {
+            Objects.requireNonNull(executor, "Pass a non-null executor");
+            Objects.requireNonNull(callback, "Pass a non-null callback");
+            mExecutor = executor;
+            mCallback = callback;
+        }
+
+        @Override
+        public void onResult(@NonNull String iface) {
+            mExecutor.execute(() -> mCallback.onResult(iface));
+        }
+
+        @Override
+        public void onError(@NonNull EthernetNetworkManagementException e) {
+            mExecutor.execute(() -> mCallback.onError(e));
+        }
+    }
+
+    private NetworkInterfaceOutcomeReceiver makeNetworkInterfaceOutcomeReceiver(
+            @Nullable final Executor executor,
+            @Nullable final OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
+        if (null != callback) {
+            Objects.requireNonNull(executor, "Pass a non-null executor, or a null callback");
+        }
+        final NetworkInterfaceOutcomeReceiver proxy;
+        if (null == callback) {
+            proxy = null;
+        } else {
+            proxy = new NetworkInterfaceOutcomeReceiver(executor, callback);
+        }
+        return proxy;
+    }
+
+    /**
+     * Updates the configuration of an automotive device's ethernet network.
+     *
+     * The {@link EthernetNetworkUpdateRequest} {@code request} argument describes how to update the
+     * configuration for this network.
+     * Use {@link StaticIpConfiguration.Builder} to build a {@code StaticIpConfiguration} object for
+     * this network to put inside the {@code request}.
+     * Similarly, use {@link NetworkCapabilities.Builder} to build a {@code NetworkCapabilities}
+     * object for this network to put inside the {@code request}.
+     *
+     * This function accepts an {@link OutcomeReceiver} that is called once the operation has
+     * finished execution.
+     *
+     * @param iface the name of the interface to act upon.
+     * @param request the {@link EthernetNetworkUpdateRequest} used to set an ethernet network's
+     *                {@link StaticIpConfiguration} and {@link NetworkCapabilities} values.
+     * @param executor an {@link Executor} to execute the callback on. Optional if callback is null.
+     * @param callback an optional {@link OutcomeReceiver} to listen for completion of the
+     *                 operation. On success, {@link OutcomeReceiver#onResult} is called with the
+     *                 interface name. On error, {@link OutcomeReceiver#onError} is called with more
+     *                 information about the error.
+     * @throws SecurityException if the process doesn't hold
+     *                          {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
+     * @throws UnsupportedOperationException if called on a non-automotive device or on an
+     *                                       unsupported interface.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK,
+            android.Manifest.permission.MANAGE_ETHERNET_NETWORKS})
+    public void updateConfiguration(
+            @NonNull String iface,
+            @NonNull EthernetNetworkUpdateRequest request,
+            @Nullable @CallbackExecutor Executor executor,
+            @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
+        Objects.requireNonNull(iface, "iface must be non-null");
+        Objects.requireNonNull(request, "request must be non-null");
+        final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
+                executor, callback);
+        try {
+            mService.updateConfiguration(iface, request, proxy);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Enable a network interface.
+     *
+     * Enables a previously disabled network interface.
+     * This function accepts an {@link OutcomeReceiver} that is called once the operation has
+     * finished execution.
+     *
+     * @param iface the name of the interface to enable.
+     * @param executor an {@link Executor} to execute the callback on. Optional if callback is null.
+     * @param callback an optional {@link OutcomeReceiver} to listen for completion of the
+     *                 operation. On success, {@link OutcomeReceiver#onResult} is called with the
+     *                 interface name. On error, {@link OutcomeReceiver#onError} is called with more
+     *                 information about the error.
+     * @throws SecurityException if the process doesn't hold
+     *                          {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK,
+            android.Manifest.permission.MANAGE_ETHERNET_NETWORKS})
+    @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
+    public void enableInterface(
+            @NonNull String iface,
+            @Nullable @CallbackExecutor Executor executor,
+            @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
+        Objects.requireNonNull(iface, "iface must be non-null");
+        final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
+                executor, callback);
+        try {
+            mService.connectNetwork(iface, proxy);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Disable a network interface.
+     *
+     * Disables the use of a network interface to fulfill network requests. If the interface
+     * currently serves a request, the network will be torn down.
+     * This function accepts an {@link OutcomeReceiver} that is called once the operation has
+     * finished execution.
+     *
+     * @param iface the name of the interface to disable.
+     * @param executor an {@link Executor} to execute the callback on. Optional if callback is null.
+     * @param callback an optional {@link OutcomeReceiver} to listen for completion of the
+     *                 operation. On success, {@link OutcomeReceiver#onResult} is called with the
+     *                 interface name. On error, {@link OutcomeReceiver#onError} is called with more
+     *                 information about the error.
+     * @throws SecurityException if the process doesn't hold
+     *                          {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK,
+            android.Manifest.permission.MANAGE_ETHERNET_NETWORKS})
+    @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
+    public void disableInterface(
+            @NonNull String iface,
+            @Nullable @CallbackExecutor Executor executor,
+            @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
+        Objects.requireNonNull(iface, "iface must be non-null");
+        final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
+                executor, callback);
+        try {
+            mService.disconnectNetwork(iface, proxy);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Change ethernet setting.
+     *
+     * @param enabled enable or disable ethernet settings.
+     *
+     * @hide
+     */
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK,
+            android.Manifest.permission.NETWORK_SETTINGS})
+    @SystemApi(client = MODULE_LIBRARIES)
+    public void setEthernetEnabled(boolean enabled) {
+        try {
+            mService.setEthernetEnabled(enabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Listen to changes in the state of ethernet.
+     *
+     * @param executor to run callbacks on.
+     * @param listener to listen ethernet state changed.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public void addEthernetStateListener(@NonNull Executor executor,
+            @NonNull IntConsumer listener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        synchronized (mListenerLock) {
+            maybeAddServiceListener();
+            mEthernetStateListeners.add(new ListenerInfo<IntConsumer>(executor, listener));
+        }
+    }
+
+    /**
+     * Removes a listener.
+     *
+     * @param listener to listen ethernet state changed.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public void removeEthernetStateListener(@NonNull IntConsumer listener) {
+        Objects.requireNonNull(listener);
+        synchronized (mListenerLock) {
+            mEthernetStateListeners.removeIf(l -> l.listener == listener);
+            maybeRemoveServiceListener();
+        }
+    }
+
+    /**
+     * Returns an array of existing Ethernet interface names regardless whether the interface
+     * is available or not currently.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    public List<String> getInterfaceList() {
+        try {
+            return mService.getInterfaceList();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+}
diff --git a/framework-t/src/android/net/EthernetNetworkManagementException.aidl b/framework-t/src/android/net/EthernetNetworkManagementException.aidl
new file mode 100644
index 0000000..adf9e5a
--- /dev/null
+++ b/framework-t/src/android/net/EthernetNetworkManagementException.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 android.net;
+
+ parcelable EthernetNetworkManagementException;
\ No newline at end of file
diff --git a/framework-t/src/android/net/EthernetNetworkManagementException.java b/framework-t/src/android/net/EthernetNetworkManagementException.java
new file mode 100644
index 0000000..a69cc55
--- /dev/null
+++ b/framework-t/src/android/net/EthernetNetworkManagementException.java
@@ -0,0 +1,73 @@
+/*
+ * 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 android.net;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/** @hide */
+@SystemApi
+public final class EthernetNetworkManagementException
+        extends RuntimeException implements Parcelable {
+
+    /* @hide */
+    public EthernetNetworkManagementException(@NonNull final String errorMessage) {
+        super(errorMessage);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getMessage());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null || getClass() != obj.getClass()) return false;
+        final EthernetNetworkManagementException that = (EthernetNetworkManagementException) obj;
+
+        return Objects.equals(getMessage(), that.getMessage());
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(getMessage());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<EthernetNetworkManagementException> CREATOR =
+            new Parcelable.Creator<EthernetNetworkManagementException>() {
+                @Override
+                public EthernetNetworkManagementException[] newArray(int size) {
+                    return new EthernetNetworkManagementException[size];
+                }
+
+                @Override
+                public EthernetNetworkManagementException createFromParcel(@NonNull Parcel source) {
+                    return new EthernetNetworkManagementException(source.readString());
+                }
+            };
+}
diff --git a/framework-t/src/android/net/EthernetNetworkSpecifier.java b/framework-t/src/android/net/EthernetNetworkSpecifier.java
new file mode 100644
index 0000000..e4d6e24
--- /dev/null
+++ b/framework-t/src/android/net/EthernetNetworkSpecifier.java
@@ -0,0 +1,102 @@
+/*
+ * 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 android.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.Objects;
+
+/**
+ * A {@link NetworkSpecifier} used to identify ethernet interfaces.
+ *
+ * @see EthernetManager
+ */
+public final class EthernetNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+
+    /**
+     * Name of the network interface.
+     */
+    @NonNull
+    private final String mInterfaceName;
+
+    /**
+     * Create a new EthernetNetworkSpecifier.
+     * @param interfaceName Name of the ethernet interface the specifier refers to.
+     */
+    public EthernetNetworkSpecifier(@NonNull String interfaceName) {
+        if (TextUtils.isEmpty(interfaceName)) {
+            throw new IllegalArgumentException();
+        }
+        mInterfaceName = interfaceName;
+    }
+
+    /**
+     * Get the name of the ethernet interface the specifier refers to.
+     */
+    @Nullable
+    public String getInterfaceName() {
+        // This may be null in the future to support specifiers based on data other than the
+        // interface name.
+        return mInterfaceName;
+    }
+
+    /** @hide */
+    @Override
+    public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
+        return equals(other);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (!(o instanceof EthernetNetworkSpecifier)) return false;
+        return TextUtils.equals(mInterfaceName, ((EthernetNetworkSpecifier) o).mInterfaceName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(mInterfaceName);
+    }
+
+    @Override
+    public String toString() {
+        return "EthernetNetworkSpecifier (" + mInterfaceName + ")";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mInterfaceName);
+    }
+
+    public static final @NonNull Parcelable.Creator<EthernetNetworkSpecifier> CREATOR =
+            new Parcelable.Creator<EthernetNetworkSpecifier>() {
+        public EthernetNetworkSpecifier createFromParcel(Parcel in) {
+            return new EthernetNetworkSpecifier(in.readString());
+        }
+        public EthernetNetworkSpecifier[] newArray(int size) {
+            return new EthernetNetworkSpecifier[size];
+        }
+    };
+}
diff --git a/framework-t/src/android/net/EthernetNetworkUpdateRequest.aidl b/framework-t/src/android/net/EthernetNetworkUpdateRequest.aidl
new file mode 100644
index 0000000..debc348
--- /dev/null
+++ b/framework-t/src/android/net/EthernetNetworkUpdateRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 android.net;
+
+ parcelable EthernetNetworkUpdateRequest;
\ No newline at end of file
diff --git a/framework-t/src/android/net/EthernetNetworkUpdateRequest.java b/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
new file mode 100644
index 0000000..1691942
--- /dev/null
+++ b/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
@@ -0,0 +1,185 @@
+/*
+ * 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 android.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Represents a request to update an existing Ethernet interface.
+ *
+ * @see EthernetManager#updateConfiguration
+ *
+ * @hide
+ */
+@SystemApi
+public final class EthernetNetworkUpdateRequest implements Parcelable {
+    @Nullable
+    private final IpConfiguration mIpConfig;
+    @Nullable
+    private final NetworkCapabilities mNetworkCapabilities;
+
+    /**
+     * Setting the {@link IpConfiguration} is optional in {@link EthernetNetworkUpdateRequest}.
+     * When set to null, the existing IpConfiguration is not updated.
+     *
+     * @return the new {@link IpConfiguration} or null.
+     */
+    @Nullable
+    public IpConfiguration getIpConfiguration() {
+        return mIpConfig == null ? null : new IpConfiguration(mIpConfig);
+    }
+
+    /**
+     * Setting the {@link NetworkCapabilities} is optional in {@link EthernetNetworkUpdateRequest}.
+     * When set to null, the existing NetworkCapabilities are not updated.
+     *
+     * @return the new {@link NetworkCapabilities} or null.
+     */
+    @Nullable
+    public NetworkCapabilities getNetworkCapabilities() {
+        return mNetworkCapabilities == null ? null : new NetworkCapabilities(mNetworkCapabilities);
+    }
+
+    private EthernetNetworkUpdateRequest(@Nullable final IpConfiguration ipConfig,
+            @Nullable final NetworkCapabilities networkCapabilities) {
+        mIpConfig = ipConfig;
+        mNetworkCapabilities = networkCapabilities;
+    }
+
+    private EthernetNetworkUpdateRequest(@NonNull final Parcel source) {
+        Objects.requireNonNull(source);
+        mIpConfig = source.readParcelable(IpConfiguration.class.getClassLoader(),
+                IpConfiguration.class);
+        mNetworkCapabilities = source.readParcelable(NetworkCapabilities.class.getClassLoader(),
+                NetworkCapabilities.class);
+    }
+
+    /**
+     * Builder used to create {@link EthernetNetworkUpdateRequest} objects.
+     */
+    public static final class Builder {
+        @Nullable
+        private IpConfiguration mBuilderIpConfig;
+        @Nullable
+        private NetworkCapabilities mBuilderNetworkCapabilities;
+
+        public Builder(){}
+
+        /**
+         * Constructor to populate the builder's values with an already built
+         * {@link EthernetNetworkUpdateRequest}.
+         * @param request the {@link EthernetNetworkUpdateRequest} to populate with.
+         */
+        public Builder(@NonNull final EthernetNetworkUpdateRequest request) {
+            Objects.requireNonNull(request);
+            mBuilderIpConfig = null == request.mIpConfig
+                    ? null : new IpConfiguration(request.mIpConfig);
+            mBuilderNetworkCapabilities = null == request.mNetworkCapabilities
+                    ? null : new NetworkCapabilities(request.mNetworkCapabilities);
+        }
+
+        /**
+         * Set the {@link IpConfiguration} to be used with the {@code Builder}.
+         * @param ipConfig the {@link IpConfiguration} to set.
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setIpConfiguration(@Nullable final IpConfiguration ipConfig) {
+            mBuilderIpConfig = ipConfig == null ? null : new IpConfiguration(ipConfig);
+            return this;
+        }
+
+        /**
+         * Set the {@link NetworkCapabilities} to be used with the {@code Builder}.
+         * @param nc the {@link NetworkCapabilities} to set.
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setNetworkCapabilities(@Nullable final NetworkCapabilities nc) {
+            mBuilderNetworkCapabilities = nc == null ? null : new NetworkCapabilities(nc);
+            return this;
+        }
+
+        /**
+         * Build {@link EthernetNetworkUpdateRequest} return the current update request.
+         *
+         * @throws IllegalStateException when both mBuilderNetworkCapabilities and mBuilderIpConfig
+         *                               are null.
+         */
+        @NonNull
+        public EthernetNetworkUpdateRequest build() {
+            if (mBuilderIpConfig == null && mBuilderNetworkCapabilities == null) {
+                throw new IllegalStateException(
+                        "Cannot construct an empty EthernetNetworkUpdateRequest");
+            }
+            return new EthernetNetworkUpdateRequest(mBuilderIpConfig, mBuilderNetworkCapabilities);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "EthernetNetworkUpdateRequest{"
+                + "mIpConfig=" + mIpConfig
+                + ", mNetworkCapabilities=" + mNetworkCapabilities + '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        EthernetNetworkUpdateRequest that = (EthernetNetworkUpdateRequest) o;
+
+        return Objects.equals(that.getIpConfiguration(), mIpConfig)
+                && Objects.equals(that.getNetworkCapabilities(), mNetworkCapabilities);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mIpConfig, mNetworkCapabilities);
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeParcelable(mIpConfig, flags);
+        dest.writeParcelable(mNetworkCapabilities, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<EthernetNetworkUpdateRequest> CREATOR =
+            new Parcelable.Creator<EthernetNetworkUpdateRequest>() {
+                @Override
+                public EthernetNetworkUpdateRequest[] newArray(int size) {
+                    return new EthernetNetworkUpdateRequest[size];
+                }
+
+                @Override
+                public EthernetNetworkUpdateRequest createFromParcel(@NonNull Parcel source) {
+                    return new EthernetNetworkUpdateRequest(source);
+                }
+            };
+}
diff --git a/framework-t/src/android/net/IEthernetManager.aidl b/framework-t/src/android/net/IEthernetManager.aidl
new file mode 100644
index 0000000..42e4c1a
--- /dev/null
+++ b/framework-t/src/android/net/IEthernetManager.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 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;
+
+import android.net.IpConfiguration;
+import android.net.IEthernetServiceListener;
+import android.net.EthernetNetworkManagementException;
+import android.net.EthernetNetworkUpdateRequest;
+import android.net.INetworkInterfaceOutcomeReceiver;
+import android.net.ITetheredInterfaceCallback;
+
+import java.util.List;
+
+/**
+ * Interface that answers queries about, and allows changing
+ * ethernet configuration.
+ */
+/** {@hide} */
+interface IEthernetManager
+{
+    String[] getAvailableInterfaces();
+    IpConfiguration getConfiguration(String iface);
+    void setConfiguration(String iface, in IpConfiguration config);
+    boolean isAvailable(String iface);
+    void addListener(in IEthernetServiceListener listener);
+    void removeListener(in IEthernetServiceListener listener);
+    void setIncludeTestInterfaces(boolean include);
+    void requestTetheredInterface(in ITetheredInterfaceCallback callback);
+    void releaseTetheredInterface(in ITetheredInterfaceCallback callback);
+    void updateConfiguration(String iface, in EthernetNetworkUpdateRequest request,
+        in INetworkInterfaceOutcomeReceiver listener);
+    void connectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener);
+    void disconnectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener);
+    void setEthernetEnabled(boolean enabled);
+    List<String> getInterfaceList();
+}
diff --git a/framework-t/src/android/net/IEthernetServiceListener.aidl b/framework-t/src/android/net/IEthernetServiceListener.aidl
new file mode 100644
index 0000000..751605b
--- /dev/null
+++ b/framework-t/src/android/net/IEthernetServiceListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014 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;
+
+import android.net.IpConfiguration;
+
+/** @hide */
+oneway interface IEthernetServiceListener
+{
+    void onEthernetStateChanged(int state);
+    void onInterfaceStateChanged(String iface, int state, int role,
+            in IpConfiguration configuration);
+}
diff --git a/framework-t/src/android/net/IIpSecService.aidl b/framework-t/src/android/net/IIpSecService.aidl
new file mode 100644
index 0000000..933256a
--- /dev/null
+++ b/framework-t/src/android/net/IIpSecService.aidl
@@ -0,0 +1,78 @@
+/*
+** Copyright 2017, 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;
+
+import android.net.LinkAddress;
+import android.net.Network;
+import android.net.IpSecConfig;
+import android.net.IpSecUdpEncapResponse;
+import android.net.IpSecSpiResponse;
+import android.net.IpSecTransformResponse;
+import android.net.IpSecTunnelInterfaceResponse;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IIpSecService
+{
+    IpSecSpiResponse allocateSecurityParameterIndex(
+            in String destinationAddress, int requestedSpi, in IBinder binder);
+
+    void releaseSecurityParameterIndex(int resourceId);
+
+    IpSecUdpEncapResponse openUdpEncapsulationSocket(int port, in IBinder binder);
+
+    void closeUdpEncapsulationSocket(int resourceId);
+
+    IpSecTunnelInterfaceResponse createTunnelInterface(
+            in String localAddr,
+            in String remoteAddr,
+            in Network underlyingNetwork,
+            in IBinder binder,
+            in String callingPackage);
+
+    void addAddressToTunnelInterface(
+            int tunnelResourceId,
+            in LinkAddress localAddr,
+            in String callingPackage);
+
+    void removeAddressFromTunnelInterface(
+            int tunnelResourceId,
+            in LinkAddress localAddr,
+            in String callingPackage);
+
+    void setNetworkForTunnelInterface(
+            int tunnelResourceId, in Network underlyingNetwork, in String callingPackage);
+
+    void deleteTunnelInterface(int resourceId, in String callingPackage);
+
+    IpSecTransformResponse createTransform(
+            in IpSecConfig c, in IBinder binder, in String callingPackage);
+
+    void deleteTransform(int transformId);
+
+    void applyTransportModeTransform(
+            in ParcelFileDescriptor socket, int direction, int transformId);
+
+    void applyTunnelModeTransform(
+            int tunnelResourceId, int direction, int transformResourceId, in String callingPackage);
+
+    void removeTransportModeTransforms(in ParcelFileDescriptor socket);
+}
diff --git a/framework-t/src/android/net/INetworkInterfaceOutcomeReceiver.aidl b/framework-t/src/android/net/INetworkInterfaceOutcomeReceiver.aidl
new file mode 100644
index 0000000..85795ea
--- /dev/null
+++ b/framework-t/src/android/net/INetworkInterfaceOutcomeReceiver.aidl
@@ -0,0 +1,25 @@
+/**
+ * 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 android.net;
+
+import android.net.EthernetNetworkManagementException;
+
+/** @hide */
+oneway interface INetworkInterfaceOutcomeReceiver {
+    void onResult(in String iface);
+    void onError(in EthernetNetworkManagementException e);
+}
\ No newline at end of file
diff --git a/framework-t/src/android/net/INetworkStatsService.aidl b/framework-t/src/android/net/INetworkStatsService.aidl
new file mode 100644
index 0000000..c86f7fd
--- /dev/null
+++ b/framework-t/src/android/net/INetworkStatsService.aidl
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.net.DataUsageRequest;
+import android.net.INetworkStatsSession;
+import android.net.Network;
+import android.net.NetworkStateSnapshot;
+import android.net.NetworkStats;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.UnderlyingNetworkInfo;
+import android.net.netstats.IUsageCallback;
+import android.net.netstats.provider.INetworkStatsProvider;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.os.IBinder;
+import android.os.Messenger;
+
+/** {@hide} */
+interface INetworkStatsService {
+
+    /** Start a statistics query session. */
+    @UnsupportedAppUsage
+    INetworkStatsSession openSession();
+
+    /** Start a statistics query session. If calling package is profile or device owner then it is
+     *  granted automatic access if apiLevel is NetworkStatsManager.API_LEVEL_DPC_ALLOWED. If
+     *  apiLevel is at least NetworkStatsManager.API_LEVEL_REQUIRES_PACKAGE_USAGE_STATS then
+     *  PACKAGE_USAGE_STATS permission is always checked. If PACKAGE_USAGE_STATS is not granted
+     *  READ_NETWORK_USAGE_STATS is checked for.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
+    INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage);
+
+    /** Return data layer snapshot of UID network usage. */
+    @UnsupportedAppUsage
+    NetworkStats getDataLayerSnapshotForUid(int uid);
+
+    /** Get the transport NetworkStats for all UIDs since boot. */
+    NetworkStats getUidStatsForTransport(int transport);
+
+    /** Return set of any ifaces associated with mobile networks since boot. */
+    @UnsupportedAppUsage
+    String[] getMobileIfaces();
+
+    /** Increment data layer count of operations performed for UID and tag. */
+    void incrementOperationCount(int uid, int tag, int operationCount);
+
+    /**  Notify {@code NetworkStatsService} about network status changed. */
+    void notifyNetworkStatus(
+         in Network[] defaultNetworks,
+         in NetworkStateSnapshot[] snapshots,
+         in String activeIface,
+         in UnderlyingNetworkInfo[] underlyingNetworkInfos);
+    /** Force update of statistics. */
+    @UnsupportedAppUsage
+    void forceUpdate();
+
+    /** Registers a callback on data usage. */
+    DataUsageRequest registerUsageCallback(String callingPackage,
+            in DataUsageRequest request, in IUsageCallback callback);
+
+    /** Unregisters a callback on data usage. */
+    void unregisterUsageRequest(in DataUsageRequest request);
+
+    /** Get the uid stats information since boot */
+    long getUidStats(int uid, int type);
+
+    /** Get the iface stats information since boot */
+    long getIfaceStats(String iface, int type);
+
+    /** Get the total network stats information since boot */
+    long getTotalStats(int type);
+
+    /** Registers a network stats provider */
+    INetworkStatsProviderCallback registerNetworkStatsProvider(String tag,
+            in INetworkStatsProvider provider);
+
+    /** Mark given UID as being in foreground for stats purposes. */
+    void noteUidForeground(int uid, boolean uidForeground);
+
+    /** Advise persistence threshold; may be overridden internally. */
+    void advisePersistThreshold(long thresholdBytes);
+
+    /**
+     * Set the warning and limit to all registered custom network stats providers.
+     * Note that invocation of any interface will be sent to all providers.
+     */
+     void setStatsProviderWarningAndLimitAsync(String iface, long warning, long limit);
+}
diff --git a/framework-t/src/android/net/INetworkStatsSession.aidl b/framework-t/src/android/net/INetworkStatsSession.aidl
new file mode 100644
index 0000000..ab70be8
--- /dev/null
+++ b/framework-t/src/android/net/INetworkStatsSession.aidl
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import android.net.NetworkStats;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+
+/** {@hide} */
+interface INetworkStatsSession {
+
+    /** Return device aggregated network layer usage summary for traffic that matches template. */
+    NetworkStats getDeviceSummaryForNetwork(in NetworkTemplate template, long start, long end);
+
+    /** Return network layer usage summary for traffic that matches template. */
+    @UnsupportedAppUsage
+    NetworkStats getSummaryForNetwork(in NetworkTemplate template, long start, long end);
+    /** Return historical network layer stats for traffic that matches template. */
+    @UnsupportedAppUsage
+    NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template, int fields);
+    /**
+     * Return historical network layer stats for traffic that matches template, start and end
+     * timestamp.
+     */
+    NetworkStatsHistory getHistoryIntervalForNetwork(in NetworkTemplate template, int fields, long start, long end);
+
+    /**
+     * Return network layer usage summary per UID for traffic that matches template.
+     *
+     * <p>The resulting {@code NetworkStats#getElapsedRealtime()} contains time delta between
+     * {@code start} and {@code end}.
+     *
+     * @param template - a predicate to filter netstats.
+     * @param start - start of the range, timestamp in milliseconds since the epoch.
+     * @param end - end of the range, timestamp in milliseconds since the epoch.
+     * @param includeTags - includes data usage tags if true.
+     */
+    @UnsupportedAppUsage
+    NetworkStats getSummaryForAllUid(in NetworkTemplate template, long start, long end, boolean includeTags);
+
+    /** Return network layer usage summary per UID for tagged traffic that matches template. */
+    NetworkStats getTaggedSummaryForAllUid(in NetworkTemplate template, long start, long end);
+
+    /** Return historical network layer stats for specific UID traffic that matches template. */
+    @UnsupportedAppUsage
+    NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int set, int tag, int fields);
+    /** Return historical network layer stats for specific UID traffic that matches template. */
+    NetworkStatsHistory getHistoryIntervalForUid(in NetworkTemplate template, int uid, int set, int tag, int fields, long start, long end);
+
+    /** Return array of uids that have stats and are accessible to the calling user */
+    int[] getRelevantUids();
+
+    @UnsupportedAppUsage
+    void close();
+
+}
diff --git a/framework-t/src/android/net/ITetheredInterfaceCallback.aidl b/framework-t/src/android/net/ITetheredInterfaceCallback.aidl
new file mode 100644
index 0000000..14aa023
--- /dev/null
+++ b/framework-t/src/android/net/ITetheredInterfaceCallback.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 android.net;
+
+/** @hide */
+oneway interface ITetheredInterfaceCallback {
+    void onAvailable(in String iface);
+    void onUnavailable();
+}
\ No newline at end of file
diff --git a/framework-t/src/android/net/IpSecAlgorithm.java b/framework-t/src/android/net/IpSecAlgorithm.java
new file mode 100644
index 0000000..10a22ac
--- /dev/null
+++ b/framework-t/src/android/net/IpSecAlgorithm.java
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.annotation.NonNull;
+import android.annotation.StringDef;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * This class represents a single algorithm that can be used by an {@link IpSecTransform}.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the
+ * Internet Protocol</a>
+ */
+public final class IpSecAlgorithm implements Parcelable {
+    private static final String TAG = "IpSecAlgorithm";
+
+    /**
+     * Null cipher.
+     *
+     * @hide
+     */
+    public static final String CRYPT_NULL = "ecb(cipher_null)";
+
+    /**
+     * AES-CBC Encryption/Ciphering Algorithm.
+     *
+     * <p>Valid lengths for this key are {128, 192, 256}.
+     */
+    public static final String CRYPT_AES_CBC = "cbc(aes)";
+
+    /**
+     * AES-CTR Encryption/Ciphering Algorithm.
+     *
+     * <p>Valid lengths for keying material are {160, 224, 288}.
+     *
+     * <p>As per <a href="https://tools.ietf.org/html/rfc3686#section-5.1">RFC3686 (Section
+     * 5.1)</a>, keying material consists of a 128, 192, or 256 bit AES key followed by a 32-bit
+     * nonce. RFC compliance requires that the nonce must be unique per security association.
+     *
+     * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
+     * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
+     * included in the returned algorithm set. The returned algorithm set will not change unless the
+     * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
+     * requested on an unsupported device.
+     *
+     * <p>@see {@link #getSupportedAlgorithms()}
+     */
+    // This algorithm may be available on devices released before Android 12, and is guaranteed
+    // to be available on devices first shipped with Android 12 or later.
+    public static final String CRYPT_AES_CTR = "rfc3686(ctr(aes))";
+
+    /**
+     * MD5 HMAC Authentication/Integrity Algorithm. <b>This algorithm is not recommended for use in
+     * new applications and is provided for legacy compatibility with 3gpp infrastructure.</b>
+     *
+     * <p>Keys for this algorithm must be 128 bits in length.
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 96 to 128.
+     */
+    public static final String AUTH_HMAC_MD5 = "hmac(md5)";
+
+    /**
+     * SHA1 HMAC Authentication/Integrity Algorithm. <b>This algorithm is not recommended for use in
+     * new applications and is provided for legacy compatibility with 3gpp infrastructure.</b>
+     *
+     * <p>Keys for this algorithm must be 160 bits in length.
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 96 to 160.
+     */
+    public static final String AUTH_HMAC_SHA1 = "hmac(sha1)";
+
+    /**
+     * SHA256 HMAC Authentication/Integrity Algorithm.
+     *
+     * <p>Keys for this algorithm must be 256 bits in length.
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 96 to 256.
+     */
+    public static final String AUTH_HMAC_SHA256 = "hmac(sha256)";
+
+    /**
+     * SHA384 HMAC Authentication/Integrity Algorithm.
+     *
+     * <p>Keys for this algorithm must be 384 bits in length.
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 192 to 384.
+     */
+    public static final String AUTH_HMAC_SHA384 = "hmac(sha384)";
+
+    /**
+     * SHA512 HMAC Authentication/Integrity Algorithm.
+     *
+     * <p>Keys for this algorithm must be 512 bits in length.
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 256 to 512.
+     */
+    public static final String AUTH_HMAC_SHA512 = "hmac(sha512)";
+
+    /**
+     * AES-XCBC Authentication/Integrity Algorithm.
+     *
+     * <p>Keys for this algorithm must be 128 bits in length.
+     *
+     * <p>The only valid truncation length is 96 bits.
+     *
+     * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
+     * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
+     * included in the returned algorithm set. The returned algorithm set will not change unless the
+     * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
+     * requested on an unsupported device.
+     *
+     * <p>@see {@link #getSupportedAlgorithms()}
+     */
+    // This algorithm may be available on devices released before Android 12, and is guaranteed
+    // to be available on devices first shipped with Android 12 or later.
+    public static final String AUTH_AES_XCBC = "xcbc(aes)";
+
+    /**
+     * AES-CMAC Authentication/Integrity Algorithm.
+     *
+     * <p>Keys for this algorithm must be 128 bits in length.
+     *
+     * <p>The only valid truncation length is 96 bits.
+     *
+     * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
+     * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
+     * included in the returned algorithm set. The returned algorithm set will not change unless the
+     * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
+     * requested on an unsupported device.
+     *
+     * <p>@see {@link #getSupportedAlgorithms()}
+     */
+    // This algorithm may be available on devices released before Android 12, and is guaranteed
+    // to be available on devices first shipped with Android 12 or later.
+    public static final String AUTH_AES_CMAC = "cmac(aes)";
+
+    /**
+     * AES-GCM Authentication/Integrity + Encryption/Ciphering Algorithm.
+     *
+     * <p>Valid lengths for keying material are {160, 224, 288}.
+     *
+     * <p>As per <a href="https://tools.ietf.org/html/rfc4106#section-8.1">RFC4106 (Section
+     * 8.1)</a>, keying material consists of a 128, 192, or 256 bit AES key followed by a 32-bit
+     * salt. RFC compliance requires that the salt must be unique per invocation with the same key.
+     *
+     * <p>Valid ICV (truncation) lengths are {64, 96, 128}.
+     */
+    public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
+
+    /**
+     * ChaCha20-Poly1305 Authentication/Integrity + Encryption/Ciphering Algorithm.
+     *
+     * <p>Keys for this algorithm must be 288 bits in length.
+     *
+     * <p>As per <a href="https://tools.ietf.org/html/rfc7634#section-2">RFC7634 (Section 2)</a>,
+     * keying material consists of a 256 bit key followed by a 32-bit salt. The salt is fixed per
+     * security association.
+     *
+     * <p>The only valid ICV (truncation) length is 128 bits.
+     *
+     * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
+     * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
+     * included in the returned algorithm set. The returned algorithm set will not change unless the
+     * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
+     * requested on an unsupported device.
+     *
+     * <p>@see {@link #getSupportedAlgorithms()}
+     */
+    // This algorithm may be available on devices released before Android 12, and is guaranteed
+    // to be available on devices first shipped with Android 12 or later.
+    public static final String AUTH_CRYPT_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)";
+
+    /** @hide */
+    @StringDef({
+        CRYPT_AES_CBC,
+        CRYPT_AES_CTR,
+        AUTH_HMAC_MD5,
+        AUTH_HMAC_SHA1,
+        AUTH_HMAC_SHA256,
+        AUTH_HMAC_SHA384,
+        AUTH_HMAC_SHA512,
+        AUTH_AES_XCBC,
+        AUTH_AES_CMAC,
+        AUTH_CRYPT_AES_GCM,
+        AUTH_CRYPT_CHACHA20_POLY1305
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AlgorithmName {}
+
+    /** @hide */
+    @VisibleForTesting
+    public static final Map<String, Integer> ALGO_TO_REQUIRED_FIRST_SDK = new HashMap<>();
+
+    private static final int SDK_VERSION_ZERO = 0;
+
+    static {
+        ALGO_TO_REQUIRED_FIRST_SDK.put(CRYPT_AES_CBC, SDK_VERSION_ZERO);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_MD5, SDK_VERSION_ZERO);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA1, SDK_VERSION_ZERO);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA256, SDK_VERSION_ZERO);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA384, SDK_VERSION_ZERO);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA512, SDK_VERSION_ZERO);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_CRYPT_AES_GCM, SDK_VERSION_ZERO);
+
+        ALGO_TO_REQUIRED_FIRST_SDK.put(CRYPT_AES_CTR, Build.VERSION_CODES.S);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_XCBC, Build.VERSION_CODES.S);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_CMAC, Build.VERSION_CODES.S);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.S);
+    }
+
+    private static final Set<String> ENABLED_ALGOS =
+            Collections.unmodifiableSet(loadAlgos(Resources.getSystem()));
+
+    private final String mName;
+    private final byte[] mKey;
+    private final int mTruncLenBits;
+
+    /**
+     * Creates an IpSecAlgorithm of one of the supported types. Supported algorithm names are
+     * defined as constants in this class.
+     *
+     * <p>For algorithms that produce an integrity check value, the truncation length is a required
+     * parameter. See {@link #IpSecAlgorithm(String algorithm, byte[] key, int truncLenBits)}
+     *
+     * @param algorithm name of the algorithm.
+     * @param key key padded to a multiple of 8 bits.
+     * @throws IllegalArgumentException if algorithm or key length is invalid.
+     */
+    public IpSecAlgorithm(@NonNull @AlgorithmName String algorithm, @NonNull byte[] key) {
+        this(algorithm, key, 0);
+    }
+
+    /**
+     * Creates an IpSecAlgorithm of one of the supported types. Supported algorithm names are
+     * defined as constants in this class.
+     *
+     * <p>This constructor only supports algorithms that use a truncation length. i.e.
+     * Authentication and Authenticated Encryption algorithms.
+     *
+     * @param algorithm name of the algorithm.
+     * @param key key padded to a multiple of 8 bits.
+     * @param truncLenBits number of bits of output hash to use.
+     * @throws IllegalArgumentException if algorithm, key length or truncation length is invalid.
+     */
+    public IpSecAlgorithm(
+            @NonNull @AlgorithmName String algorithm, @NonNull byte[] key, int truncLenBits) {
+        mName = algorithm;
+        mKey = key.clone();
+        mTruncLenBits = truncLenBits;
+        checkValidOrThrow(mName, mKey.length * 8, mTruncLenBits);
+    }
+
+    /** Get the algorithm name */
+    @NonNull
+    public String getName() {
+        return mName;
+    }
+
+    /** Get the key for this algorithm */
+    @NonNull
+    public byte[] getKey() {
+        return mKey.clone();
+    }
+
+    /** Get the truncation length of this algorithm, in bits */
+    public int getTruncationLengthBits() {
+        return mTruncLenBits;
+    }
+
+    /** Parcelable Implementation */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Write to parcel */
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mName);
+        out.writeByteArray(mKey);
+        out.writeInt(mTruncLenBits);
+    }
+
+    /** Parcelable Creator */
+    public static final @android.annotation.NonNull Parcelable.Creator<IpSecAlgorithm> CREATOR =
+            new Parcelable.Creator<IpSecAlgorithm>() {
+                public IpSecAlgorithm createFromParcel(Parcel in) {
+                    final String name = in.readString();
+                    final byte[] key = in.createByteArray();
+                    final int truncLenBits = in.readInt();
+
+                    return new IpSecAlgorithm(name, key, truncLenBits);
+                }
+
+                public IpSecAlgorithm[] newArray(int size) {
+                    return new IpSecAlgorithm[size];
+                }
+            };
+
+    /**
+     * Returns supported IPsec algorithms for the current device.
+     *
+     * <p>Some algorithms may not be supported on old devices. Callers MUST check if an algorithm is
+     * supported before using it.
+     */
+    @NonNull
+    public static Set<String> getSupportedAlgorithms() {
+        return ENABLED_ALGOS;
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public static Set<String> loadAlgos(Resources systemResources) {
+        final Set<String> enabledAlgos = new HashSet<>();
+
+        // Load and validate the optional algorithm resource. Undefined or duplicate algorithms in
+        // the resource are not allowed.
+        final String[] resourceAlgos = systemResources.getStringArray(
+                android.R.array.config_optionalIpSecAlgorithms);
+        for (String str : resourceAlgos) {
+            if (!ALGO_TO_REQUIRED_FIRST_SDK.containsKey(str) || !enabledAlgos.add(str)) {
+                // This error should be caught by CTS and never be thrown to API callers
+                throw new IllegalArgumentException("Invalid or repeated algorithm " + str);
+            }
+        }
+
+        for (Entry<String, Integer> entry : ALGO_TO_REQUIRED_FIRST_SDK.entrySet()) {
+            if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= entry.getValue()) {
+                enabledAlgos.add(entry.getKey());
+            }
+        }
+
+        return enabledAlgos;
+    }
+
+    private static void checkValidOrThrow(String name, int keyLen, int truncLen) {
+        final boolean isValidLen;
+        final boolean isValidTruncLen;
+
+        if (!getSupportedAlgorithms().contains(name)) {
+            throw new IllegalArgumentException("Unsupported algorithm: " + name);
+        }
+
+        switch (name) {
+            case CRYPT_AES_CBC:
+                isValidLen = keyLen == 128 || keyLen == 192 || keyLen == 256;
+                isValidTruncLen = true;
+                break;
+            case CRYPT_AES_CTR:
+                // The keying material for AES-CTR is a key plus a 32-bit salt
+                isValidLen = keyLen == 128 + 32 || keyLen == 192 + 32 || keyLen == 256 + 32;
+                isValidTruncLen = true;
+                break;
+            case AUTH_HMAC_MD5:
+                isValidLen = keyLen == 128;
+                isValidTruncLen = truncLen >= 96 && truncLen <= 128;
+                break;
+            case AUTH_HMAC_SHA1:
+                isValidLen = keyLen == 160;
+                isValidTruncLen = truncLen >= 96 && truncLen <= 160;
+                break;
+            case AUTH_HMAC_SHA256:
+                isValidLen = keyLen == 256;
+                isValidTruncLen = truncLen >= 96 && truncLen <= 256;
+                break;
+            case AUTH_HMAC_SHA384:
+                isValidLen = keyLen == 384;
+                isValidTruncLen = truncLen >= 192 && truncLen <= 384;
+                break;
+            case AUTH_HMAC_SHA512:
+                isValidLen = keyLen == 512;
+                isValidTruncLen = truncLen >= 256 && truncLen <= 512;
+                break;
+            case AUTH_AES_XCBC:
+                isValidLen = keyLen == 128;
+                isValidTruncLen = truncLen == 96;
+                break;
+            case AUTH_AES_CMAC:
+                isValidLen = keyLen == 128;
+                isValidTruncLen = truncLen == 96;
+                break;
+            case AUTH_CRYPT_AES_GCM:
+                // The keying material for GCM is a key plus a 32-bit salt
+                isValidLen = keyLen == 128 + 32 || keyLen == 192 + 32 || keyLen == 256 + 32;
+                isValidTruncLen = truncLen == 64 || truncLen == 96 || truncLen == 128;
+                break;
+            case AUTH_CRYPT_CHACHA20_POLY1305:
+                // The keying material for ChaCha20Poly1305 is a key plus a 32-bit salt
+                isValidLen = keyLen == 256 + 32;
+                isValidTruncLen = truncLen == 128;
+                break;
+            default:
+                // Should never hit here.
+                throw new IllegalArgumentException("Couldn't find an algorithm: " + name);
+        }
+
+        if (!isValidLen) {
+            throw new IllegalArgumentException("Invalid key material keyLength: " + keyLen);
+        }
+        if (!isValidTruncLen) {
+            throw new IllegalArgumentException("Invalid truncation keyLength: " + truncLen);
+        }
+    }
+
+    /** @hide */
+    public boolean isAuthentication() {
+        switch (getName()) {
+            // Fallthrough
+            case AUTH_HMAC_MD5:
+            case AUTH_HMAC_SHA1:
+            case AUTH_HMAC_SHA256:
+            case AUTH_HMAC_SHA384:
+            case AUTH_HMAC_SHA512:
+            case AUTH_AES_XCBC:
+            case AUTH_AES_CMAC:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /** @hide */
+    public boolean isEncryption() {
+        switch (getName()) {
+            case CRYPT_AES_CBC: // fallthrough
+            case CRYPT_AES_CTR:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /** @hide */
+    public boolean isAead() {
+        switch (getName()) {
+            case AUTH_CRYPT_AES_GCM: // fallthrough
+            case AUTH_CRYPT_CHACHA20_POLY1305:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        return new StringBuilder()
+                .append("{mName=")
+                .append(mName)
+                .append(", mTruncLenBits=")
+                .append(mTruncLenBits)
+                .append("}")
+                .toString();
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public static boolean equals(IpSecAlgorithm lhs, IpSecAlgorithm rhs) {
+        if (lhs == null || rhs == null) return (lhs == rhs);
+        return (lhs.mName.equals(rhs.mName)
+                && Arrays.equals(lhs.mKey, rhs.mKey)
+                && lhs.mTruncLenBits == rhs.mTruncLenBits);
+    }
+};
diff --git a/framework-t/src/android/net/IpSecConfig.aidl b/framework-t/src/android/net/IpSecConfig.aidl
new file mode 100644
index 0000000..eaefca7
--- /dev/null
+++ b/framework-t/src/android/net/IpSecConfig.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 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;
+
+/** @hide */
+parcelable IpSecConfig;
diff --git a/framework-t/src/android/net/IpSecConfig.java b/framework-t/src/android/net/IpSecConfig.java
new file mode 100644
index 0000000..03bb187
--- /dev/null
+++ b/framework-t/src/android/net/IpSecConfig.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * This class encapsulates all the configuration parameters needed to create IPsec transforms and
+ * policies.
+ *
+ * @hide
+ */
+public final class IpSecConfig implements Parcelable {
+    private static final String TAG = "IpSecConfig";
+
+    // MODE_TRANSPORT or MODE_TUNNEL
+    private int mMode = IpSecTransform.MODE_TRANSPORT;
+
+    // Preventing this from being null simplifies Java->Native binder
+    private String mSourceAddress = "";
+
+    // Preventing this from being null simplifies Java->Native binder
+    private String mDestinationAddress = "";
+
+    // The underlying Network that represents the "gateway" Network
+    // for outbound packets. It may also be used to select packets.
+    private Network mNetwork;
+
+    // Minimum requirements for identifying a transform
+    // SPI identifying the IPsec SA in packet processing
+    // and a destination IP address
+    private int mSpiResourceId = IpSecManager.INVALID_RESOURCE_ID;
+
+    // Encryption Algorithm
+    private IpSecAlgorithm mEncryption;
+
+    // Authentication Algorithm
+    private IpSecAlgorithm mAuthentication;
+
+    // Authenticated Encryption Algorithm
+    private IpSecAlgorithm mAuthenticatedEncryption;
+
+    // For tunnel mode IPv4 UDP Encapsulation
+    // IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE
+    private int mEncapType = IpSecTransform.ENCAP_NONE;
+    private int mEncapSocketResourceId = IpSecManager.INVALID_RESOURCE_ID;
+    private int mEncapRemotePort;
+
+    // An interval, in seconds between the NattKeepalive packets
+    private int mNattKeepaliveInterval;
+
+    // XFRM mark and mask; defaults to 0 (no mark/mask)
+    private int mMarkValue;
+    private int mMarkMask;
+
+    // XFRM interface id
+    private int mXfrmInterfaceId;
+
+    /** Set the mode for this IPsec transform */
+    public void setMode(int mode) {
+        mMode = mode;
+    }
+
+    /** Set the source IP addres for this IPsec transform */
+    public void setSourceAddress(String sourceAddress) {
+        mSourceAddress = sourceAddress;
+    }
+
+    /** Set the destination IP address for this IPsec transform */
+    public void setDestinationAddress(String destinationAddress) {
+        mDestinationAddress = destinationAddress;
+    }
+
+    /** Set the SPI by resource ID */
+    public void setSpiResourceId(int resourceId) {
+        mSpiResourceId = resourceId;
+    }
+
+    /** Set the encryption algorithm */
+    public void setEncryption(IpSecAlgorithm encryption) {
+        mEncryption = encryption;
+    }
+
+    /** Set the authentication algorithm */
+    public void setAuthentication(IpSecAlgorithm authentication) {
+        mAuthentication = authentication;
+    }
+
+    /** Set the authenticated encryption algorithm */
+    public void setAuthenticatedEncryption(IpSecAlgorithm authenticatedEncryption) {
+        mAuthenticatedEncryption = authenticatedEncryption;
+    }
+
+    /** Set the underlying network that will carry traffic for this transform */
+    public void setNetwork(Network network) {
+        mNetwork = network;
+    }
+
+    public void setEncapType(int encapType) {
+        mEncapType = encapType;
+    }
+
+    public void setEncapSocketResourceId(int resourceId) {
+        mEncapSocketResourceId = resourceId;
+    }
+
+    public void setEncapRemotePort(int port) {
+        mEncapRemotePort = port;
+    }
+
+    public void setNattKeepaliveInterval(int interval) {
+        mNattKeepaliveInterval = interval;
+    }
+
+    /**
+     * Sets the mark value
+     *
+     * <p>Internal (System server) use only. Marks passed in by users will be overwritten or
+     * ignored.
+     */
+    public void setMarkValue(int mark) {
+        mMarkValue = mark;
+    }
+
+    /**
+     * Sets the mark mask
+     *
+     * <p>Internal (System server) use only. Marks passed in by users will be overwritten or
+     * ignored.
+     */
+    public void setMarkMask(int mask) {
+        mMarkMask = mask;
+    }
+
+    public void setXfrmInterfaceId(int xfrmInterfaceId) {
+        mXfrmInterfaceId = xfrmInterfaceId;
+    }
+
+    // Transport or Tunnel
+    public int getMode() {
+        return mMode;
+    }
+
+    public String getSourceAddress() {
+        return mSourceAddress;
+    }
+
+    public int getSpiResourceId() {
+        return mSpiResourceId;
+    }
+
+    public String getDestinationAddress() {
+        return mDestinationAddress;
+    }
+
+    public IpSecAlgorithm getEncryption() {
+        return mEncryption;
+    }
+
+    public IpSecAlgorithm getAuthentication() {
+        return mAuthentication;
+    }
+
+    public IpSecAlgorithm getAuthenticatedEncryption() {
+        return mAuthenticatedEncryption;
+    }
+
+    public Network getNetwork() {
+        return mNetwork;
+    }
+
+    public int getEncapType() {
+        return mEncapType;
+    }
+
+    public int getEncapSocketResourceId() {
+        return mEncapSocketResourceId;
+    }
+
+    public int getEncapRemotePort() {
+        return mEncapRemotePort;
+    }
+
+    public int getNattKeepaliveInterval() {
+        return mNattKeepaliveInterval;
+    }
+
+    public int getMarkValue() {
+        return mMarkValue;
+    }
+
+    public int getMarkMask() {
+        return mMarkMask;
+    }
+
+    public int getXfrmInterfaceId() {
+        return mXfrmInterfaceId;
+    }
+
+    // Parcelable Methods
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mMode);
+        out.writeString(mSourceAddress);
+        out.writeString(mDestinationAddress);
+        out.writeParcelable(mNetwork, flags);
+        out.writeInt(mSpiResourceId);
+        out.writeParcelable(mEncryption, flags);
+        out.writeParcelable(mAuthentication, flags);
+        out.writeParcelable(mAuthenticatedEncryption, flags);
+        out.writeInt(mEncapType);
+        out.writeInt(mEncapSocketResourceId);
+        out.writeInt(mEncapRemotePort);
+        out.writeInt(mNattKeepaliveInterval);
+        out.writeInt(mMarkValue);
+        out.writeInt(mMarkMask);
+        out.writeInt(mXfrmInterfaceId);
+    }
+
+    @VisibleForTesting
+    public IpSecConfig() {}
+
+    /** Copy constructor */
+    @VisibleForTesting
+    public IpSecConfig(IpSecConfig c) {
+        mMode = c.mMode;
+        mSourceAddress = c.mSourceAddress;
+        mDestinationAddress = c.mDestinationAddress;
+        mNetwork = c.mNetwork;
+        mSpiResourceId = c.mSpiResourceId;
+        mEncryption = c.mEncryption;
+        mAuthentication = c.mAuthentication;
+        mAuthenticatedEncryption = c.mAuthenticatedEncryption;
+        mEncapType = c.mEncapType;
+        mEncapSocketResourceId = c.mEncapSocketResourceId;
+        mEncapRemotePort = c.mEncapRemotePort;
+        mNattKeepaliveInterval = c.mNattKeepaliveInterval;
+        mMarkValue = c.mMarkValue;
+        mMarkMask = c.mMarkMask;
+        mXfrmInterfaceId = c.mXfrmInterfaceId;
+    }
+
+    private IpSecConfig(Parcel in) {
+        mMode = in.readInt();
+        mSourceAddress = in.readString();
+        mDestinationAddress = in.readString();
+        mNetwork = (Network) in.readParcelable(Network.class.getClassLoader(), android.net.Network.class);
+        mSpiResourceId = in.readInt();
+        mEncryption =
+                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader(), android.net.IpSecAlgorithm.class);
+        mAuthentication =
+                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader(), android.net.IpSecAlgorithm.class);
+        mAuthenticatedEncryption =
+                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader(), android.net.IpSecAlgorithm.class);
+        mEncapType = in.readInt();
+        mEncapSocketResourceId = in.readInt();
+        mEncapRemotePort = in.readInt();
+        mNattKeepaliveInterval = in.readInt();
+        mMarkValue = in.readInt();
+        mMarkMask = in.readInt();
+        mXfrmInterfaceId = in.readInt();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder strBuilder = new StringBuilder();
+        strBuilder
+                .append("{mMode=")
+                .append(mMode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT")
+                .append(", mSourceAddress=")
+                .append(mSourceAddress)
+                .append(", mDestinationAddress=")
+                .append(mDestinationAddress)
+                .append(", mNetwork=")
+                .append(mNetwork)
+                .append(", mEncapType=")
+                .append(mEncapType)
+                .append(", mEncapSocketResourceId=")
+                .append(mEncapSocketResourceId)
+                .append(", mEncapRemotePort=")
+                .append(mEncapRemotePort)
+                .append(", mNattKeepaliveInterval=")
+                .append(mNattKeepaliveInterval)
+                .append("{mSpiResourceId=")
+                .append(mSpiResourceId)
+                .append(", mEncryption=")
+                .append(mEncryption)
+                .append(", mAuthentication=")
+                .append(mAuthentication)
+                .append(", mAuthenticatedEncryption=")
+                .append(mAuthenticatedEncryption)
+                .append(", mMarkValue=")
+                .append(mMarkValue)
+                .append(", mMarkMask=")
+                .append(mMarkMask)
+                .append(", mXfrmInterfaceId=")
+                .append(mXfrmInterfaceId)
+                .append("}");
+
+        return strBuilder.toString();
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<IpSecConfig> CREATOR =
+            new Parcelable.Creator<IpSecConfig>() {
+                public IpSecConfig createFromParcel(Parcel in) {
+                    return new IpSecConfig(in);
+                }
+
+                public IpSecConfig[] newArray(int size) {
+                    return new IpSecConfig[size];
+                }
+            };
+
+    @Override
+    public boolean equals(@Nullable Object other) {
+        if (!(other instanceof IpSecConfig)) return false;
+        final IpSecConfig rhs = (IpSecConfig) other;
+        return (mMode == rhs.mMode
+                && mSourceAddress.equals(rhs.mSourceAddress)
+                && mDestinationAddress.equals(rhs.mDestinationAddress)
+                && ((mNetwork != null && mNetwork.equals(rhs.mNetwork))
+                        || (mNetwork == rhs.mNetwork))
+                && mEncapType == rhs.mEncapType
+                && mEncapSocketResourceId == rhs.mEncapSocketResourceId
+                && mEncapRemotePort == rhs.mEncapRemotePort
+                && mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
+                && mSpiResourceId == rhs.mSpiResourceId
+                && IpSecAlgorithm.equals(mEncryption, rhs.mEncryption)
+                && IpSecAlgorithm.equals(mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
+                && IpSecAlgorithm.equals(mAuthentication, rhs.mAuthentication)
+                && mMarkValue == rhs.mMarkValue
+                && mMarkMask == rhs.mMarkMask
+                && mXfrmInterfaceId == rhs.mXfrmInterfaceId);
+    }
+}
diff --git a/framework-t/src/android/net/IpSecManager.java b/framework-t/src/android/net/IpSecManager.java
new file mode 100644
index 0000000..9cb0947
--- /dev/null
+++ b/framework-t/src/android/net/IpSecManager.java
@@ -0,0 +1,1065 @@
+/*
+ * Copyright (C) 2017 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;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresFeature;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import android.util.AndroidException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import dalvik.system.CloseGuard;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.Objects;
+
+/**
+ * This class contains methods for managing IPsec sessions. Once configured, the kernel will apply
+ * confidentiality (encryption) and integrity (authentication) to IP traffic.
+ *
+ * <p>Note that not all aspects of IPsec are permitted by this API. Applications may create
+ * transport mode security associations and apply them to individual sockets. Applications looking
+ * to create an IPsec VPN should use {@link VpnManager} and {@link Ikev2VpnProfile}.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the
+ *     Internet Protocol</a>
+ */
+@SystemService(Context.IPSEC_SERVICE)
+public class IpSecManager {
+    private static final String TAG = "IpSecManager";
+
+    /**
+     * Used when applying a transform to direct traffic through an {@link IpSecTransform}
+     * towards the host.
+     *
+     * <p>See {@link #applyTransportModeTransform(Socket, int, IpSecTransform)}.
+     */
+    public static final int DIRECTION_IN = 0;
+
+    /**
+     * Used when applying a transform to direct traffic through an {@link IpSecTransform}
+     * away from the host.
+     *
+     * <p>See {@link #applyTransportModeTransform(Socket, int, IpSecTransform)}.
+     */
+    public static final int DIRECTION_OUT = 1;
+
+    /**
+     * Used when applying a transform to direct traffic through an {@link IpSecTransform} for
+     * forwarding between interfaces.
+     *
+     * <p>See {@link #applyTransportModeTransform(Socket, int, IpSecTransform)}.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int DIRECTION_FWD = 2;
+
+    /** @hide */
+    @IntDef(value = {DIRECTION_IN, DIRECTION_OUT})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PolicyDirection {}
+
+    /**
+     * The Security Parameter Index (SPI) 0 indicates an unknown or invalid index.
+     *
+     * <p>No IPsec packet may contain an SPI of 0.
+     *
+     * @hide
+     */
+    @TestApi public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
+
+    /** @hide */
+    public interface Status {
+        int OK = 0;
+        int RESOURCE_UNAVAILABLE = 1;
+        int SPI_UNAVAILABLE = 2;
+    }
+
+    /** @hide */
+    public static final int INVALID_RESOURCE_ID = -1;
+
+    /**
+     * Thrown to indicate that a requested SPI is in use.
+     *
+     * <p>The combination of remote {@code InetAddress} and SPI must be unique across all apps on
+     * one device. If this error is encountered, a new SPI is required before a transform may be
+     * created. This error can be avoided by calling {@link
+     * IpSecManager#allocateSecurityParameterIndex}.
+     */
+    public static final class SpiUnavailableException extends AndroidException {
+        private final int mSpi;
+
+        /**
+         * Construct an exception indicating that a transform with the given SPI is already in use
+         * or otherwise unavailable.
+         *
+         * @param msg description indicating the colliding SPI
+         * @param spi the SPI that could not be used due to a collision
+         */
+        SpiUnavailableException(String msg, int spi) {
+            super(msg + " (spi: " + spi + ")");
+            mSpi = spi;
+        }
+
+        /** Get the SPI that caused a collision. */
+        public int getSpi() {
+            return mSpi;
+        }
+    }
+
+    /**
+     * Thrown to indicate that an IPsec resource is unavailable.
+     *
+     * <p>This could apply to resources such as sockets, {@link SecurityParameterIndex}, {@link
+     * IpSecTransform}, or other system resources. If this exception is thrown, users should release
+     * allocated objects of the type requested.
+     */
+    public static final class ResourceUnavailableException extends AndroidException {
+
+        ResourceUnavailableException(String msg) {
+            super(msg);
+        }
+    }
+
+    private final Context mContext;
+    private final IIpSecService mService;
+
+    /**
+     * This class represents a reserved SPI.
+     *
+     * <p>Objects of this type are used to track reserved security parameter indices. They can be
+     * obtained by calling {@link IpSecManager#allocateSecurityParameterIndex} and must be released
+     * by calling {@link #close()} when they are no longer needed.
+     */
+    public static final class SecurityParameterIndex implements AutoCloseable {
+        private final IIpSecService mService;
+        private final InetAddress mDestinationAddress;
+        private final CloseGuard mCloseGuard = CloseGuard.get();
+        private int mSpi = INVALID_SECURITY_PARAMETER_INDEX;
+        private int mResourceId = INVALID_RESOURCE_ID;
+
+        /** Get the underlying SPI held by this object. */
+        public int getSpi() {
+            return mSpi;
+        }
+
+        /**
+         * Release an SPI that was previously reserved.
+         *
+         * <p>Release an SPI for use by other users in the system. If a SecurityParameterIndex is
+         * applied to an IpSecTransform, it will become unusable for future transforms but should
+         * still be closed to ensure system resources are released.
+         */
+        @Override
+        public void close() {
+            try {
+                mService.releaseSecurityParameterIndex(mResourceId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (Exception e) {
+                // On close we swallow all random exceptions since failure to close is not
+                // actionable by the user.
+                Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
+            } finally {
+                mResourceId = INVALID_RESOURCE_ID;
+                mCloseGuard.close();
+            }
+        }
+
+        /** Check that the SPI was closed properly. */
+        @Override
+        protected void finalize() throws Throwable {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
+            close();
+        }
+
+        private SecurityParameterIndex(
+                @NonNull IIpSecService service, InetAddress destinationAddress, int spi)
+                throws ResourceUnavailableException, SpiUnavailableException {
+            mService = service;
+            mDestinationAddress = destinationAddress;
+            try {
+                IpSecSpiResponse result =
+                        mService.allocateSecurityParameterIndex(
+                                destinationAddress.getHostAddress(), spi, new Binder());
+
+                if (result == null) {
+                    throw new NullPointerException("Received null response from IpSecService");
+                }
+
+                int status = result.status;
+                switch (status) {
+                    case Status.OK:
+                        break;
+                    case Status.RESOURCE_UNAVAILABLE:
+                        throw new ResourceUnavailableException(
+                                "No more SPIs may be allocated by this requester.");
+                    case Status.SPI_UNAVAILABLE:
+                        throw new SpiUnavailableException("Requested SPI is unavailable", spi);
+                    default:
+                        throw new RuntimeException(
+                                "Unknown status returned by IpSecService: " + status);
+                }
+                mSpi = result.spi;
+                mResourceId = result.resourceId;
+
+                if (mSpi == INVALID_SECURITY_PARAMETER_INDEX) {
+                    throw new RuntimeException("Invalid SPI returned by IpSecService: " + status);
+                }
+
+                if (mResourceId == INVALID_RESOURCE_ID) {
+                    throw new RuntimeException(
+                            "Invalid Resource ID returned by IpSecService: " + status);
+                }
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            mCloseGuard.open("open");
+        }
+
+        /** @hide */
+        @VisibleForTesting
+        public int getResourceId() {
+            return mResourceId;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                .append("SecurityParameterIndex{spi=")
+                .append(mSpi)
+                .append(",resourceId=")
+                .append(mResourceId)
+                .append("}")
+                .toString();
+        }
+    }
+
+    /**
+     * Reserve a random SPI for traffic bound to or from the specified destination address.
+     *
+     * <p>If successful, this SPI is guaranteed available until released by a call to {@link
+     * SecurityParameterIndex#close()}.
+     *
+     * @param destinationAddress the destination address for traffic bearing the requested SPI.
+     *     For inbound traffic, the destination should be an address currently assigned on-device.
+     * @return the reserved SecurityParameterIndex
+     * @throws ResourceUnavailableException indicating that too many SPIs are
+     *     currently allocated for this user
+     */
+    @NonNull
+    public SecurityParameterIndex allocateSecurityParameterIndex(
+                @NonNull InetAddress destinationAddress) throws ResourceUnavailableException {
+        try {
+            return new SecurityParameterIndex(
+                    mService,
+                    destinationAddress,
+                    IpSecManager.INVALID_SECURITY_PARAMETER_INDEX);
+        } catch (ServiceSpecificException e) {
+            throw rethrowUncheckedExceptionFromServiceSpecificException(e);
+        } catch (SpiUnavailableException unlikely) {
+            // Because this function allocates a totally random SPI, it really shouldn't ever
+            // fail to allocate an SPI; we simply need this because the exception is checked.
+            throw new ResourceUnavailableException("No SPIs available");
+        }
+    }
+
+    /**
+     * Reserve the requested SPI for traffic bound to or from the specified destination address.
+     *
+     * <p>If successful, this SPI is guaranteed available until released by a call to {@link
+     * SecurityParameterIndex#close()}.
+     *
+     * @param destinationAddress the destination address for traffic bearing the requested SPI.
+     *     For inbound traffic, the destination should be an address currently assigned on-device.
+     * @param requestedSpi the requested SPI. The range 1-255 is reserved and may not be used. See
+     *     RFC 4303 Section 2.1.
+     * @return the reserved SecurityParameterIndex
+     * @throws ResourceUnavailableException indicating that too many SPIs are
+     *     currently allocated for this user
+     * @throws SpiUnavailableException indicating that the requested SPI could not be
+     *     reserved
+     */
+    @NonNull
+    public SecurityParameterIndex allocateSecurityParameterIndex(
+            @NonNull InetAddress destinationAddress, int requestedSpi)
+            throws SpiUnavailableException, ResourceUnavailableException {
+        if (requestedSpi == IpSecManager.INVALID_SECURITY_PARAMETER_INDEX) {
+            throw new IllegalArgumentException("Requested SPI must be a valid (non-zero) SPI");
+        }
+        try {
+            return new SecurityParameterIndex(mService, destinationAddress, requestedSpi);
+        } catch (ServiceSpecificException e) {
+            throw rethrowUncheckedExceptionFromServiceSpecificException(e);
+        }
+    }
+
+    /**
+     * Apply an IPsec transform to a stream socket.
+     *
+     * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the
+     * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When
+     * the transform is removed from the socket by calling {@link #removeTransportModeTransforms},
+     * unprotected traffic can resume on that socket.
+     *
+     * <p>For security reasons, the destination address of any traffic on the socket must match the
+     * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any
+     * other IP address will result in an IOException. In addition, reads and writes on the socket
+     * will throw IOException if the user deactivates the transform (by calling {@link
+     * IpSecTransform#close()}) without calling {@link #removeTransportModeTransforms}.
+     *
+     * <p>Note that when applied to TCP sockets, calling {@link IpSecTransform#close()} on an
+     * applied transform before completion of graceful shutdown may result in the shutdown sequence
+     * failing to complete. As such, applications requiring graceful shutdown MUST close the socket
+     * prior to deactivating the applied transform. Socket closure may be performed asynchronously
+     * (in batches), so the returning of a close function does not guarantee shutdown of a socket.
+     * Setting an SO_LINGER timeout results in socket closure being performed synchronously, and is
+     * sufficient to ensure shutdown.
+     *
+     * Specifically, if the transform is deactivated (by calling {@link IpSecTransform#close()}),
+     * prior to the socket being closed, the standard [FIN - FIN/ACK - ACK], or the reset [RST]
+     * packets are dropped due to the lack of a valid Transform. Similarly, if a socket without the
+     * SO_LINGER option set is closed, the delayed/batched FIN packets may be dropped.
+     *
+     * <h4>Rekey Procedure</h4>
+     *
+     * <p>When applying a new tranform to a socket in the outbound direction, the previous transform
+     * will be removed and the new transform will take effect immediately, sending all traffic on
+     * the new transform; however, when applying a transform in the inbound direction, traffic
+     * on the old transform will continue to be decrypted and delivered until that transform is
+     * deallocated by calling {@link IpSecTransform#close()}. This overlap allows lossless rekey
+     * procedures where both transforms are valid until both endpoints are using the new transform
+     * and all in-flight packets have been received.
+     *
+     * @param socket a stream socket
+     * @param direction the direction in which the transform should be applied
+     * @param transform a transport mode {@code IpSecTransform}
+     * @throws IOException indicating that the transform could not be applied
+     */
+    public void applyTransportModeTransform(@NonNull Socket socket,
+            @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
+        // Ensure creation of FD. See b/77548890 for more details.
+        socket.getSoLinger();
+
+        applyTransportModeTransform(socket.getFileDescriptor$(), direction, transform);
+    }
+
+    /**
+     * Apply an IPsec transform to a datagram socket.
+     *
+     * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the
+     * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When
+     * the transform is removed from the socket by calling {@link #removeTransportModeTransforms},
+     * unprotected traffic can resume on that socket.
+     *
+     * <p>For security reasons, the destination address of any traffic on the socket must match the
+     * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any
+     * other IP address will result in an IOException. In addition, reads and writes on the socket
+     * will throw IOException if the user deactivates the transform (by calling {@link
+     * IpSecTransform#close()}) without calling {@link #removeTransportModeTransforms}.
+     *
+     * <h4>Rekey Procedure</h4>
+     *
+     * <p>When applying a new tranform to a socket in the outbound direction, the previous transform
+     * will be removed and the new transform will take effect immediately, sending all traffic on
+     * the new transform; however, when applying a transform in the inbound direction, traffic
+     * on the old transform will continue to be decrypted and delivered until that transform is
+     * deallocated by calling {@link IpSecTransform#close()}. This overlap allows lossless rekey
+     * procedures where both transforms are valid until both endpoints are using the new transform
+     * and all in-flight packets have been received.
+     *
+     * @param socket a datagram socket
+     * @param direction the direction in which the transform should be applied
+     * @param transform a transport mode {@code IpSecTransform}
+     * @throws IOException indicating that the transform could not be applied
+     */
+    public void applyTransportModeTransform(@NonNull DatagramSocket socket,
+            @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
+        applyTransportModeTransform(socket.getFileDescriptor$(), direction, transform);
+    }
+
+    /**
+     * Apply an IPsec transform to a socket.
+     *
+     * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the
+     * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When
+     * the transform is removed from the socket by calling {@link #removeTransportModeTransforms},
+     * unprotected traffic can resume on that socket.
+     *
+     * <p>For security reasons, the destination address of any traffic on the socket must match the
+     * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any
+     * other IP address will result in an IOException. In addition, reads and writes on the socket
+     * will throw IOException if the user deactivates the transform (by calling {@link
+     * IpSecTransform#close()}) without calling {@link #removeTransportModeTransforms}.
+     *
+     * <p>Note that when applied to TCP sockets, calling {@link IpSecTransform#close()} on an
+     * applied transform before completion of graceful shutdown may result in the shutdown sequence
+     * failing to complete. As such, applications requiring graceful shutdown MUST close the socket
+     * prior to deactivating the applied transform. Socket closure may be performed asynchronously
+     * (in batches), so the returning of a close function does not guarantee shutdown of a socket.
+     * Setting an SO_LINGER timeout results in socket closure being performed synchronously, and is
+     * sufficient to ensure shutdown.
+     *
+     * Specifically, if the transform is deactivated (by calling {@link IpSecTransform#close()}),
+     * prior to the socket being closed, the standard [FIN - FIN/ACK - ACK], or the reset [RST]
+     * packets are dropped due to the lack of a valid Transform. Similarly, if a socket without the
+     * SO_LINGER option set is closed, the delayed/batched FIN packets may be dropped.
+     *
+     * <h4>Rekey Procedure</h4>
+     *
+     * <p>When applying a new tranform to a socket in the outbound direction, the previous transform
+     * will be removed and the new transform will take effect immediately, sending all traffic on
+     * the new transform; however, when applying a transform in the inbound direction, traffic
+     * on the old transform will continue to be decrypted and delivered until that transform is
+     * deallocated by calling {@link IpSecTransform#close()}. This overlap allows lossless rekey
+     * procedures where both transforms are valid until both endpoints are using the new transform
+     * and all in-flight packets have been received.
+     *
+     * @param socket a socket file descriptor
+     * @param direction the direction in which the transform should be applied
+     * @param transform a transport mode {@code IpSecTransform}
+     * @throws IOException indicating that the transform could not be applied
+     */
+    public void applyTransportModeTransform(@NonNull FileDescriptor socket,
+            @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
+        // We dup() the FileDescriptor here because if we don't, then the ParcelFileDescriptor()
+        // constructor takes control and closes the user's FD when we exit the method.
+        try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) {
+            mService.applyTransportModeTransform(pfd, direction, transform.getResourceId());
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Remove an IPsec transform from a stream socket.
+     *
+     * <p>Once removed, traffic on the socket will not be encrypted. Removing transforms from a
+     * socket allows the socket to be reused for communication in the clear.
+     *
+     * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling
+     * {@link IpSecTransform#close()}, then communication on the socket will fail until this method
+     * is called.
+     *
+     * @param socket a socket that previously had a transform applied to it
+     * @throws IOException indicating that the transform could not be removed from the socket
+     */
+    public void removeTransportModeTransforms(@NonNull Socket socket) throws IOException {
+        // Ensure creation of FD. See b/77548890 for more details.
+        socket.getSoLinger();
+
+        removeTransportModeTransforms(socket.getFileDescriptor$());
+    }
+
+    /**
+     * Remove an IPsec transform from a datagram socket.
+     *
+     * <p>Once removed, traffic on the socket will not be encrypted. Removing transforms from a
+     * socket allows the socket to be reused for communication in the clear.
+     *
+     * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling
+     * {@link IpSecTransform#close()}, then communication on the socket will fail until this method
+     * is called.
+     *
+     * @param socket a socket that previously had a transform applied to it
+     * @throws IOException indicating that the transform could not be removed from the socket
+     */
+    public void removeTransportModeTransforms(@NonNull DatagramSocket socket) throws IOException {
+        removeTransportModeTransforms(socket.getFileDescriptor$());
+    }
+
+    /**
+     * Remove an IPsec transform from a socket.
+     *
+     * <p>Once removed, traffic on the socket will not be encrypted. Removing transforms from a
+     * socket allows the socket to be reused for communication in the clear.
+     *
+     * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling
+     * {@link IpSecTransform#close()}, then communication on the socket will fail until this method
+     * is called.
+     *
+     * @param socket a socket that previously had a transform applied to it
+     * @throws IOException indicating that the transform could not be removed from the socket
+     */
+    public void removeTransportModeTransforms(@NonNull FileDescriptor socket) throws IOException {
+        try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) {
+            mService.removeTransportModeTransforms(pfd);
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Remove a Tunnel Mode IPsec Transform from a {@link Network}. This must be used as part of
+     * cleanup if a tunneled Network experiences a change in default route. The Network will drop
+     * all traffic that cannot be routed to the Tunnel's outbound interface. If that interface is
+     * lost, all traffic will drop.
+     *
+     * <p>TODO: Update javadoc for tunnel mode APIs at the same time the APIs are re-worked.
+     *
+     * @param net a network that currently has transform applied to it.
+     * @param transform a Tunnel Mode IPsec Transform that has been previously applied to the given
+     *     network
+     * @hide
+     */
+    public void removeTunnelModeTransform(Network net, IpSecTransform transform) {}
+
+    /**
+     * This class provides access to a UDP encapsulation Socket.
+     *
+     * <p>{@code UdpEncapsulationSocket} wraps a system-provided datagram socket intended for IKEv2
+     * signalling and UDP encapsulated IPsec traffic. Instances can be obtained by calling {@link
+     * IpSecManager#openUdpEncapsulationSocket}. The provided socket cannot be re-bound by the
+     * caller. The caller should not close the {@code FileDescriptor} returned by {@link
+     * #getFileDescriptor}, but should use {@link #close} instead.
+     *
+     * <p>Allowing the user to close or unbind a UDP encapsulation socket could impact the traffic
+     * of the next user who binds to that port. To prevent this scenario, these sockets are held
+     * open by the system so that they may only be closed by calling {@link #close} or when the user
+     * process exits.
+     */
+    public static final class UdpEncapsulationSocket implements AutoCloseable {
+        private final ParcelFileDescriptor mPfd;
+        private final IIpSecService mService;
+        private int mResourceId = INVALID_RESOURCE_ID;
+        private final int mPort;
+        private final CloseGuard mCloseGuard = CloseGuard.get();
+
+        private UdpEncapsulationSocket(@NonNull IIpSecService service, int port)
+                throws ResourceUnavailableException, IOException {
+            mService = service;
+            try {
+                IpSecUdpEncapResponse result =
+                        mService.openUdpEncapsulationSocket(port, new Binder());
+                switch (result.status) {
+                    case Status.OK:
+                        break;
+                    case Status.RESOURCE_UNAVAILABLE:
+                        throw new ResourceUnavailableException(
+                                "No more Sockets may be allocated by this requester.");
+                    default:
+                        throw new RuntimeException(
+                                "Unknown status returned by IpSecService: " + result.status);
+                }
+                mResourceId = result.resourceId;
+                mPort = result.port;
+                mPfd = result.fileDescriptor;
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            mCloseGuard.open("constructor");
+        }
+
+        /** Get the encapsulation socket's file descriptor. */
+        public FileDescriptor getFileDescriptor() {
+            if (mPfd == null) {
+                return null;
+            }
+            return mPfd.getFileDescriptor();
+        }
+
+        /** Get the bound port of the wrapped socket. */
+        public int getPort() {
+            return mPort;
+        }
+
+        /**
+         * Close this socket.
+         *
+         * <p>This closes the wrapped socket. Open encapsulation sockets count against a user's
+         * resource limits, and forgetting to close them eventually will result in {@link
+         * ResourceUnavailableException} being thrown.
+         */
+        @Override
+        public void close() throws IOException {
+            try {
+                mService.closeUdpEncapsulationSocket(mResourceId);
+                mResourceId = INVALID_RESOURCE_ID;
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (Exception e) {
+                // On close we swallow all random exceptions since failure to close is not
+                // actionable by the user.
+                Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
+            } finally {
+                mResourceId = INVALID_RESOURCE_ID;
+                mCloseGuard.close();
+            }
+
+            try {
+                mPfd.close();
+            } catch (IOException e) {
+                Log.e(TAG, "Failed to close UDP Encapsulation Socket with Port= " + mPort);
+                throw e;
+            }
+        }
+
+        /** Check that the socket was closed properly. */
+        @Override
+        protected void finalize() throws Throwable {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+            close();
+        }
+
+        /** @hide */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public int getResourceId() {
+            return mResourceId;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                .append("UdpEncapsulationSocket{port=")
+                .append(mPort)
+                .append(",resourceId=")
+                .append(mResourceId)
+                .append("}")
+                .toString();
+        }
+    };
+
+    /**
+     * Open a socket for UDP encapsulation and bind to the given port.
+     *
+     * <p>See {@link UdpEncapsulationSocket} for the proper way to close the returned socket.
+     *
+     * @param port a local UDP port
+     * @return a socket that is bound to the given port
+     * @throws IOException indicating that the socket could not be opened or bound
+     * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open
+     */
+    // Returning a socket in this fashion that has been created and bound by the system
+    // is the only safe way to ensure that a socket is both accessible to the user and
+    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
+    // the port, which could potentially impact the traffic of the next user who binds to that
+    // socket.
+    @NonNull
+    public UdpEncapsulationSocket openUdpEncapsulationSocket(int port)
+            throws IOException, ResourceUnavailableException {
+        /*
+         * Most range checking is done in the service, but this version of the constructor expects
+         * a valid port number, and zero cannot be checked after being passed to the service.
+         */
+        if (port == 0) {
+            throw new IllegalArgumentException("Specified port must be a valid port number!");
+        }
+        try {
+            return new UdpEncapsulationSocket(mService, port);
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
+        }
+    }
+
+    /**
+     * Open a socket for UDP encapsulation.
+     *
+     * <p>See {@link UdpEncapsulationSocket} for the proper way to close the returned socket.
+     *
+     * <p>The local port of the returned socket can be obtained by calling {@link
+     * UdpEncapsulationSocket#getPort()}.
+     *
+     * @return a socket that is bound to a local port
+     * @throws IOException indicating that the socket could not be opened or bound
+     * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open
+     */
+    // Returning a socket in this fashion that has been created and bound by the system
+    // is the only safe way to ensure that a socket is both accessible to the user and
+    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
+    // the port, which could potentially impact the traffic of the next user who binds to that
+    // socket.
+    @NonNull
+    public UdpEncapsulationSocket openUdpEncapsulationSocket()
+            throws IOException, ResourceUnavailableException {
+        try {
+            return new UdpEncapsulationSocket(mService, 0);
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
+        }
+    }
+
+    /**
+     * This class represents an IpSecTunnelInterface
+     *
+     * <p>IpSecTunnelInterface objects track tunnel interfaces that serve as
+     * local endpoints for IPsec tunnels.
+     *
+     * <p>Creating an IpSecTunnelInterface creates a device to which IpSecTransforms may be
+     * applied to provide IPsec security to packets sent through the tunnel. While a tunnel
+     * cannot be used in standalone mode within Android, the higher layers may use the tunnel
+     * to create Network objects which are accessible to the Android system.
+     * @hide
+     */
+    @SystemApi
+    public static final class IpSecTunnelInterface implements AutoCloseable {
+        private final String mOpPackageName;
+        private final IIpSecService mService;
+        private final InetAddress mRemoteAddress;
+        private final InetAddress mLocalAddress;
+        private final Network mUnderlyingNetwork;
+        private final CloseGuard mCloseGuard = CloseGuard.get();
+        private String mInterfaceName;
+        private int mResourceId = INVALID_RESOURCE_ID;
+
+        /** Get the underlying SPI held by this object. */
+        @NonNull
+        public String getInterfaceName() {
+            return mInterfaceName;
+        }
+
+        /**
+         * Add an address to the IpSecTunnelInterface
+         *
+         * <p>Add an address which may be used as the local inner address for
+         * tunneled traffic.
+         *
+         * @param address the local address for traffic inside the tunnel
+         * @param prefixLen length of the InetAddress prefix
+         * @hide
+         */
+        @SystemApi
+        @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+        @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
+        public void addAddress(@NonNull InetAddress address, int prefixLen) throws IOException {
+            try {
+                mService.addAddressToTunnelInterface(
+                        mResourceId, new LinkAddress(address, prefixLen), mOpPackageName);
+            } catch (ServiceSpecificException e) {
+                throw rethrowCheckedExceptionFromServiceSpecificException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Remove an address from the IpSecTunnelInterface
+         *
+         * <p>Remove an address which was previously added to the IpSecTunnelInterface
+         *
+         * @param address to be removed
+         * @param prefixLen length of the InetAddress prefix
+         * @hide
+         */
+        @SystemApi
+        @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+        @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
+        public void removeAddress(@NonNull InetAddress address, int prefixLen) throws IOException {
+            try {
+                mService.removeAddressFromTunnelInterface(
+                        mResourceId, new LinkAddress(address, prefixLen), mOpPackageName);
+            } catch (ServiceSpecificException e) {
+                throw rethrowCheckedExceptionFromServiceSpecificException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Update the underlying network for this IpSecTunnelInterface.
+         *
+         * <p>This new underlying network will be used for all transforms applied AFTER this call is
+         * complete. Before new {@link IpSecTransform}(s) with matching addresses are applied to
+         * this tunnel interface, traffic will still use the old SA, and be routed on the old
+         * underlying network.
+         *
+         * <p>To migrate IPsec tunnel mode traffic, a caller should:
+         *
+         * <ol>
+         *   <li>Update the IpSecTunnelInterface’s underlying network.
+         *   <li>Apply {@link IpSecTransform}(s) with matching addresses to this
+         *       IpSecTunnelInterface.
+         * </ol>
+         *
+         * @param underlyingNetwork the new {@link Network} that will carry traffic for this tunnel.
+         *     This network MUST never be the network exposing this IpSecTunnelInterface, otherwise
+         *     this method will throw an {@link IllegalArgumentException}. If the
+         *     IpSecTunnelInterface is later added to this network, all outbound traffic will be
+         *     blackholed.
+         */
+        // TODO: b/169171001 Update the documentation when transform migration is supported.
+        // The purpose of making updating network and applying transforms separate is to leave open
+        // the possibility to support lossless migration procedures. To do that, Android platform
+        // will need to support multiple inbound tunnel mode transforms, just like it can support
+        // multiple transport mode transforms.
+        @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+        @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
+        public void setUnderlyingNetwork(@NonNull Network underlyingNetwork) throws IOException {
+            try {
+                mService.setNetworkForTunnelInterface(
+                        mResourceId, underlyingNetwork, mOpPackageName);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        private IpSecTunnelInterface(@NonNull Context ctx, @NonNull IIpSecService service,
+                @NonNull InetAddress localAddress, @NonNull InetAddress remoteAddress,
+                @NonNull Network underlyingNetwork)
+                throws ResourceUnavailableException, IOException {
+            mOpPackageName = ctx.getOpPackageName();
+            mService = service;
+            mLocalAddress = localAddress;
+            mRemoteAddress = remoteAddress;
+            mUnderlyingNetwork = underlyingNetwork;
+
+            try {
+                IpSecTunnelInterfaceResponse result =
+                        mService.createTunnelInterface(
+                                localAddress.getHostAddress(),
+                                remoteAddress.getHostAddress(),
+                                underlyingNetwork,
+                                new Binder(),
+                                mOpPackageName);
+                switch (result.status) {
+                    case Status.OK:
+                        break;
+                    case Status.RESOURCE_UNAVAILABLE:
+                        throw new ResourceUnavailableException(
+                                "No more tunnel interfaces may be allocated by this requester.");
+                    default:
+                        throw new RuntimeException(
+                                "Unknown status returned by IpSecService: " + result.status);
+                }
+                mResourceId = result.resourceId;
+                mInterfaceName = result.interfaceName;
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            mCloseGuard.open("constructor");
+        }
+
+        /**
+         * Delete an IpSecTunnelInterface
+         *
+         * <p>Calling close will deallocate the IpSecTunnelInterface and all of its system
+         * resources. Any packets bound for this interface either inbound or outbound will
+         * all be lost.
+         */
+        @Override
+        public void close() {
+            try {
+                mService.deleteTunnelInterface(mResourceId, mOpPackageName);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (Exception e) {
+                // On close we swallow all random exceptions since failure to close is not
+                // actionable by the user.
+                Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
+            } finally {
+                mResourceId = INVALID_RESOURCE_ID;
+                mCloseGuard.close();
+            }
+        }
+
+        /** Check that the Interface was closed properly. */
+        @Override
+        protected void finalize() throws Throwable {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+            close();
+        }
+
+        /** @hide */
+        @VisibleForTesting
+        public int getResourceId() {
+            return mResourceId;
+        }
+
+        @NonNull
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                .append("IpSecTunnelInterface{ifname=")
+                .append(mInterfaceName)
+                .append(",resourceId=")
+                .append(mResourceId)
+                .append("}")
+                .toString();
+        }
+    }
+
+    /**
+     * Create a new IpSecTunnelInterface as a local endpoint for tunneled IPsec traffic.
+     *
+     * <p>An application that creates tunnels is responsible for cleaning up the tunnel when the
+     * underlying network goes away, and the onLost() callback is received.
+     *
+     * @param localAddress The local addres of the tunnel
+     * @param remoteAddress The local addres of the tunnel
+     * @param underlyingNetwork the {@link Network} that will carry traffic for this tunnel.
+     *        This network should almost certainly be a network such as WiFi with an L2 address.
+     * @return a new {@link IpSecManager#IpSecTunnelInterface} with the specified properties
+     * @throws IOException indicating that the socket could not be opened or bound
+     * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+    @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
+    public IpSecTunnelInterface createIpSecTunnelInterface(@NonNull InetAddress localAddress,
+            @NonNull InetAddress remoteAddress, @NonNull Network underlyingNetwork)
+            throws ResourceUnavailableException, IOException {
+        try {
+            return new IpSecTunnelInterface(
+                    mContext, mService, localAddress, remoteAddress, underlyingNetwork);
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
+        }
+    }
+
+    /**
+     * Apply an active Tunnel Mode IPsec Transform to a {@link IpSecTunnelInterface}, which will
+     * tunnel all traffic for the given direction through the underlying network's interface with
+     * IPsec (applies an outer IP header and IPsec Header to all traffic, and expects an additional
+     * IP header and IPsec Header on all inbound traffic).
+     * <p>Applications should probably not use this API directly.
+     *
+     *
+     * @param tunnel The {@link IpSecManager#IpSecTunnelInterface} that will use the supplied
+     *        transform.
+     * @param direction the direction, {@link DIRECTION_OUT} or {@link #DIRECTION_IN} in which
+     *        the transform will be used.
+     * @param transform an {@link IpSecTransform} created in tunnel mode
+     * @throws IOException indicating that the transform could not be applied due to a lower
+     *         layer failure.
+     * @hide
+     */
+    @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+    @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
+    public void applyTunnelModeTransform(@NonNull IpSecTunnelInterface tunnel,
+            @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
+        try {
+            mService.applyTunnelModeTransform(
+                    tunnel.getResourceId(), direction,
+                    transform.getResourceId(), mContext.getOpPackageName());
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public IpSecTransformResponse createTransform(IpSecConfig config, IBinder binder,
+            String callingPackage) {
+        try {
+            return mService.createTransform(config, binder, callingPackage);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void deleteTransform(int resourceId) {
+        try {
+            mService.deleteTransform(resourceId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Construct an instance of IpSecManager within an application context.
+     *
+     * @param context the application context for this manager
+     * @hide
+     */
+    public IpSecManager(Context ctx, IIpSecService service) {
+        mContext = ctx;
+        mService = Objects.requireNonNull(service, "missing service");
+    }
+
+    private static void maybeHandleServiceSpecificException(ServiceSpecificException sse) {
+        // OsConstants are late binding, so switch statements can't be used.
+        if (sse.errorCode == OsConstants.EINVAL) {
+            throw new IllegalArgumentException(sse);
+        } else if (sse.errorCode == OsConstants.EAGAIN) {
+            throw new IllegalStateException(sse);
+        } else if (sse.errorCode == OsConstants.EOPNOTSUPP
+                || sse.errorCode == OsConstants.EPROTONOSUPPORT) {
+            throw new UnsupportedOperationException(sse);
+        }
+    }
+
+    /**
+     * Convert an Errno SSE to the correct Unchecked exception type.
+     *
+     * This method never actually returns.
+     */
+    // package
+    static RuntimeException
+            rethrowUncheckedExceptionFromServiceSpecificException(ServiceSpecificException sse) {
+        maybeHandleServiceSpecificException(sse);
+        throw new RuntimeException(sse);
+    }
+
+    /**
+     * Convert an Errno SSE to the correct Checked or Unchecked exception type.
+     *
+     * This method may throw IOException, or it may throw an unchecked exception; it will never
+     * actually return.
+     */
+    // package
+    static IOException rethrowCheckedExceptionFromServiceSpecificException(
+            ServiceSpecificException sse) throws IOException {
+        // First see if this is an unchecked exception of a type we know.
+        // If so, then we prefer the unchecked (specific) type of exception.
+        maybeHandleServiceSpecificException(sse);
+        // If not, then all we can do is provide the SSE in the form of an IOException.
+        throw new ErrnoException(
+                "IpSec encountered errno=" + sse.errorCode, sse.errorCode).rethrowAsIOException();
+    }
+}
diff --git a/framework-t/src/android/net/IpSecSpiResponse.aidl b/framework-t/src/android/net/IpSecSpiResponse.aidl
new file mode 100644
index 0000000..6484a00
--- /dev/null
+++ b/framework-t/src/android/net/IpSecSpiResponse.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 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;
+
+/** @hide */
+parcelable IpSecSpiResponse;
diff --git a/framework-t/src/android/net/IpSecSpiResponse.java b/framework-t/src/android/net/IpSecSpiResponse.java
new file mode 100644
index 0000000..f99e570
--- /dev/null
+++ b/framework-t/src/android/net/IpSecSpiResponse.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class is used to return an SPI and corresponding status from the IpSecService to an
+ * IpSecManager.SecurityParameterIndex.
+ *
+ * @hide
+ */
+public final class IpSecSpiResponse implements Parcelable {
+    private static final String TAG = "IpSecSpiResponse";
+
+    public final int resourceId;
+    public final int status;
+    public final int spi;
+    // Parcelable Methods
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(status);
+        out.writeInt(resourceId);
+        out.writeInt(spi);
+    }
+
+    public IpSecSpiResponse(int inStatus, int inResourceId, int inSpi) {
+        status = inStatus;
+        resourceId = inResourceId;
+        spi = inSpi;
+    }
+
+    public IpSecSpiResponse(int inStatus) {
+        if (inStatus == IpSecManager.Status.OK) {
+            throw new IllegalArgumentException("Valid status implies other args must be provided");
+        }
+        status = inStatus;
+        resourceId = IpSecManager.INVALID_RESOURCE_ID;
+        spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
+    }
+
+    private IpSecSpiResponse(Parcel in) {
+        status = in.readInt();
+        resourceId = in.readInt();
+        spi = in.readInt();
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<IpSecSpiResponse> CREATOR =
+            new Parcelable.Creator<IpSecSpiResponse>() {
+                public IpSecSpiResponse createFromParcel(Parcel in) {
+                    return new IpSecSpiResponse(in);
+                }
+
+                public IpSecSpiResponse[] newArray(int size) {
+                    return new IpSecSpiResponse[size];
+                }
+            };
+}
diff --git a/framework-t/src/android/net/IpSecTransform.java b/framework-t/src/android/net/IpSecTransform.java
new file mode 100644
index 0000000..68ae5de
--- /dev/null
+++ b/framework-t/src/android/net/IpSecTransform.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2017 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;
+
+import static android.net.IpSecManager.INVALID_RESOURCE_ID;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import dalvik.system.CloseGuard;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.InetAddress;
+import java.util.Objects;
+
+/**
+ * This class represents a transform, which roughly corresponds to an IPsec Security Association.
+ *
+ * <p>Transforms are created using {@link IpSecTransform.Builder}. Each {@code IpSecTransform}
+ * object encapsulates the properties and state of an IPsec security association. That includes,
+ * but is not limited to, algorithm choice, key material, and allocated system resources.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the
+ *     Internet Protocol</a>
+ */
+public final class IpSecTransform implements AutoCloseable {
+    private static final String TAG = "IpSecTransform";
+
+    /** @hide */
+    public static final int MODE_TRANSPORT = 0;
+
+    /** @hide */
+    public static final int MODE_TUNNEL = 1;
+
+    /** @hide */
+    public static final int ENCAP_NONE = 0;
+
+    /**
+     * IPsec traffic will be encapsulated within UDP, but with 8 zero-value bytes between the UDP
+     * header and payload. This prevents traffic from being interpreted as ESP or IKEv2.
+     *
+     * @hide
+     */
+    public static final int ENCAP_ESPINUDP_NON_IKE = 1;
+
+    /**
+     * IPsec traffic will be encapsulated within UDP as per
+     * <a href="https://tools.ietf.org/html/rfc3948">RFC 3498</a>.
+     *
+     * @hide
+     */
+    public static final int ENCAP_ESPINUDP = 2;
+
+    /** @hide */
+    @IntDef(value = {ENCAP_NONE, ENCAP_ESPINUDP, ENCAP_ESPINUDP_NON_IKE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncapType {}
+
+    /** @hide */
+    @VisibleForTesting
+    public IpSecTransform(Context context, IpSecConfig config) {
+        mContext = context;
+        mConfig = new IpSecConfig(config);
+        mResourceId = INVALID_RESOURCE_ID;
+    }
+
+    private IpSecManager getIpSecManager(Context context) {
+        return context.getSystemService(IpSecManager.class);
+    }
+    /**
+     * Checks the result status and throws an appropriate exception if the status is not Status.OK.
+     */
+    private void checkResultStatus(int status)
+            throws IOException, IpSecManager.ResourceUnavailableException,
+                    IpSecManager.SpiUnavailableException {
+        switch (status) {
+            case IpSecManager.Status.OK:
+                return;
+                // TODO: Pass Error string back from bundle so that errors can be more specific
+            case IpSecManager.Status.RESOURCE_UNAVAILABLE:
+                throw new IpSecManager.ResourceUnavailableException(
+                        "Failed to allocate a new IpSecTransform");
+            case IpSecManager.Status.SPI_UNAVAILABLE:
+                Log.wtf(TAG, "Attempting to use an SPI that was somehow not reserved");
+                // Fall through
+            default:
+                throw new IllegalStateException(
+                        "Failed to Create a Transform with status code " + status);
+        }
+    }
+
+    private IpSecTransform activate()
+            throws IOException, IpSecManager.ResourceUnavailableException,
+                    IpSecManager.SpiUnavailableException {
+        synchronized (this) {
+            try {
+                IpSecTransformResponse result = getIpSecManager(mContext).createTransform(
+                        mConfig, new Binder(), mContext.getOpPackageName());
+                int status = result.status;
+                checkResultStatus(status);
+                mResourceId = result.resourceId;
+                Log.d(TAG, "Added Transform with Id " + mResourceId);
+                mCloseGuard.open("build");
+            } catch (ServiceSpecificException e) {
+                throw IpSecManager.rethrowUncheckedExceptionFromServiceSpecificException(e);
+            }
+        }
+
+        return this;
+    }
+
+    /**
+     * Standard equals.
+     */
+    public boolean equals(@Nullable Object other) {
+        if (this == other) return true;
+        if (!(other instanceof IpSecTransform)) return false;
+        final IpSecTransform rhs = (IpSecTransform) other;
+        return getConfig().equals(rhs.getConfig()) && mResourceId == rhs.mResourceId;
+    }
+
+    /**
+     * Deactivate this {@code IpSecTransform} and free allocated resources.
+     *
+     * <p>Deactivating a transform while it is still applied to a socket will result in errors on
+     * that socket. Make sure to remove transforms by calling {@link
+     * IpSecManager#removeTransportModeTransforms}. Note, removing an {@code IpSecTransform} from a
+     * socket will not deactivate it (because one transform may be applied to multiple sockets).
+     *
+     * <p>It is safe to call this method on a transform that has already been deactivated.
+     */
+    public void close() {
+        Log.d(TAG, "Removing Transform with Id " + mResourceId);
+
+        // Always safe to attempt cleanup
+        if (mResourceId == INVALID_RESOURCE_ID) {
+            mCloseGuard.close();
+            return;
+        }
+        try {
+            getIpSecManager(mContext).deleteTransform(mResourceId);
+        } catch (Exception e) {
+            // On close we swallow all random exceptions since failure to close is not
+            // actionable by the user.
+            Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
+        } finally {
+            mResourceId = INVALID_RESOURCE_ID;
+            mCloseGuard.close();
+        }
+    }
+
+    /** Check that the transform was closed properly. */
+    @Override
+    protected void finalize() throws Throwable {
+        if (mCloseGuard != null) {
+            mCloseGuard.warnIfOpen();
+        }
+        close();
+    }
+
+    /* Package */
+    IpSecConfig getConfig() {
+        return mConfig;
+    }
+
+    private final IpSecConfig mConfig;
+    private int mResourceId;
+    private final Context mContext;
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    /** @hide */
+    @VisibleForTesting
+    public int getResourceId() {
+        return mResourceId;
+    }
+
+    /**
+     * A callback class to provide status information regarding a NAT-T keepalive session
+     *
+     * <p>Use this callback to receive status information regarding a NAT-T keepalive session
+     * by registering it when calling {@link #startNattKeepalive}.
+     *
+     * @hide
+     */
+    public static class NattKeepaliveCallback {
+        /** The specified {@code Network} is not connected. */
+        public static final int ERROR_INVALID_NETWORK = 1;
+        /** The hardware does not support this request. */
+        public static final int ERROR_HARDWARE_UNSUPPORTED = 2;
+        /** The hardware returned an error. */
+        public static final int ERROR_HARDWARE_ERROR = 3;
+
+        /** The requested keepalive was successfully started. */
+        public void onStarted() {}
+        /** The keepalive was successfully stopped. */
+        public void onStopped() {}
+        /** An error occurred. */
+        public void onError(int error) {}
+    }
+
+    /** This class is used to build {@link IpSecTransform} objects. */
+    public static class Builder {
+        private Context mContext;
+        private IpSecConfig mConfig;
+
+        /**
+         * Set the encryption algorithm.
+         *
+         * <p>Encryption is mutually exclusive with authenticated encryption.
+         *
+         * @param algo {@link IpSecAlgorithm} specifying the encryption to be applied.
+         */
+        @NonNull
+        public IpSecTransform.Builder setEncryption(@NonNull IpSecAlgorithm algo) {
+            // TODO: throw IllegalArgumentException if algo is not an encryption algorithm.
+            Objects.requireNonNull(algo);
+            mConfig.setEncryption(algo);
+            return this;
+        }
+
+        /**
+         * Set the authentication (integrity) algorithm.
+         *
+         * <p>Authentication is mutually exclusive with authenticated encryption.
+         *
+         * @param algo {@link IpSecAlgorithm} specifying the authentication to be applied.
+         */
+        @NonNull
+        public IpSecTransform.Builder setAuthentication(@NonNull IpSecAlgorithm algo) {
+            // TODO: throw IllegalArgumentException if algo is not an authentication algorithm.
+            Objects.requireNonNull(algo);
+            mConfig.setAuthentication(algo);
+            return this;
+        }
+
+        /**
+         * Set the authenticated encryption algorithm.
+         *
+         * <p>The Authenticated Encryption (AE) class of algorithms are also known as
+         * Authenticated Encryption with Associated Data (AEAD) algorithms, or Combined mode
+         * algorithms (as referred to in
+         * <a href="https://tools.ietf.org/html/rfc4301">RFC 4301</a>).
+         *
+         * <p>Authenticated encryption is mutually exclusive with encryption and authentication.
+         *
+         * @param algo {@link IpSecAlgorithm} specifying the authenticated encryption algorithm to
+         *     be applied.
+         */
+        @NonNull
+        public IpSecTransform.Builder setAuthenticatedEncryption(@NonNull IpSecAlgorithm algo) {
+            Objects.requireNonNull(algo);
+            mConfig.setAuthenticatedEncryption(algo);
+            return this;
+        }
+
+        /**
+         * Add UDP encapsulation to an IPv4 transform.
+         *
+         * <p>This allows IPsec traffic to pass through a NAT.
+         *
+         * @see <a href="https://tools.ietf.org/html/rfc3948">RFC 3948, UDP Encapsulation of IPsec
+         *     ESP Packets</a>
+         * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.23">RFC 7296 section 2.23,
+         *     NAT Traversal of IKEv2</a>
+         * @param localSocket a socket for sending and receiving encapsulated traffic
+         * @param remotePort the UDP port number of the remote host that will send and receive
+         *     encapsulated traffic. In the case of IKEv2, this should be port 4500.
+         */
+        @NonNull
+        public IpSecTransform.Builder setIpv4Encapsulation(
+                @NonNull IpSecManager.UdpEncapsulationSocket localSocket, int remotePort) {
+            Objects.requireNonNull(localSocket);
+            mConfig.setEncapType(ENCAP_ESPINUDP);
+            if (localSocket.getResourceId() == INVALID_RESOURCE_ID) {
+                throw new IllegalArgumentException("Invalid UdpEncapsulationSocket");
+            }
+            mConfig.setEncapSocketResourceId(localSocket.getResourceId());
+            mConfig.setEncapRemotePort(remotePort);
+            return this;
+        }
+
+        /**
+         * Build a transport mode {@link IpSecTransform}.
+         *
+         * <p>This builds and activates a transport mode transform. Note that an active transform
+         * will not affect any network traffic until it has been applied to one or more sockets.
+         *
+         * @see IpSecManager#applyTransportModeTransform
+         * @param sourceAddress the source {@code InetAddress} of traffic on sockets that will use
+         *     this transform; this address must belong to the Network used by all sockets that
+         *     utilize this transform; if provided, then only traffic originating from the
+         *     specified source address will be processed.
+         * @param spi a unique {@link IpSecManager.SecurityParameterIndex} to identify transformed
+         *     traffic
+         * @throws IllegalArgumentException indicating that a particular combination of transform
+         *     properties is invalid
+         * @throws IpSecManager.ResourceUnavailableException indicating that too many transforms
+         *     are active
+         * @throws IpSecManager.SpiUnavailableException indicating the rare case where an SPI
+         *     collides with an existing transform
+         * @throws IOException indicating other errors
+         */
+        @NonNull
+        public IpSecTransform buildTransportModeTransform(
+                @NonNull InetAddress sourceAddress,
+                @NonNull IpSecManager.SecurityParameterIndex spi)
+                throws IpSecManager.ResourceUnavailableException,
+                        IpSecManager.SpiUnavailableException, IOException {
+            Objects.requireNonNull(sourceAddress);
+            Objects.requireNonNull(spi);
+            if (spi.getResourceId() == INVALID_RESOURCE_ID) {
+                throw new IllegalArgumentException("Invalid SecurityParameterIndex");
+            }
+            mConfig.setMode(MODE_TRANSPORT);
+            mConfig.setSourceAddress(sourceAddress.getHostAddress());
+            mConfig.setSpiResourceId(spi.getResourceId());
+            // FIXME: modifying a builder after calling build can change the built transform.
+            return new IpSecTransform(mContext, mConfig).activate();
+        }
+
+        /**
+         * Build and return an {@link IpSecTransform} object as a Tunnel Mode Transform. Some
+         * parameters have interdependencies that are checked at build time.
+         *
+         * @param sourceAddress the {@link InetAddress} that provides the source address for this
+         *     IPsec tunnel. This is almost certainly an address belonging to the {@link Network}
+         *     that will originate the traffic, which is set as the {@link #setUnderlyingNetwork}.
+         * @param spi a unique {@link IpSecManager.SecurityParameterIndex} to identify transformed
+         *     traffic
+         * @throws IllegalArgumentException indicating that a particular combination of transform
+         *     properties is invalid.
+         * @throws IpSecManager.ResourceUnavailableException indicating that too many transforms
+         *     are active
+         * @throws IpSecManager.SpiUnavailableException indicating the rare case where an SPI
+         *     collides with an existing transform
+         * @throws IOException indicating other errors
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+        @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
+        public IpSecTransform buildTunnelModeTransform(
+                @NonNull InetAddress sourceAddress,
+                @NonNull IpSecManager.SecurityParameterIndex spi)
+                throws IpSecManager.ResourceUnavailableException,
+                        IpSecManager.SpiUnavailableException, IOException {
+            Objects.requireNonNull(sourceAddress);
+            Objects.requireNonNull(spi);
+            if (spi.getResourceId() == INVALID_RESOURCE_ID) {
+                throw new IllegalArgumentException("Invalid SecurityParameterIndex");
+            }
+            mConfig.setMode(MODE_TUNNEL);
+            mConfig.setSourceAddress(sourceAddress.getHostAddress());
+            mConfig.setSpiResourceId(spi.getResourceId());
+            return new IpSecTransform(mContext, mConfig).activate();
+        }
+
+        /**
+         * Create a new IpSecTransform.Builder.
+         *
+         * @param context current context
+         */
+        public Builder(@NonNull Context context) {
+            Objects.requireNonNull(context);
+            mContext = context;
+            mConfig = new IpSecConfig();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder()
+            .append("IpSecTransform{resourceId=")
+            .append(mResourceId)
+            .append("}")
+            .toString();
+    }
+}
diff --git a/framework-t/src/android/net/IpSecTransformResponse.aidl b/framework-t/src/android/net/IpSecTransformResponse.aidl
new file mode 100644
index 0000000..546230d
--- /dev/null
+++ b/framework-t/src/android/net/IpSecTransformResponse.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 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;
+
+/** @hide */
+parcelable IpSecTransformResponse;
diff --git a/framework-t/src/android/net/IpSecTransformResponse.java b/framework-t/src/android/net/IpSecTransformResponse.java
new file mode 100644
index 0000000..363f316
--- /dev/null
+++ b/framework-t/src/android/net/IpSecTransformResponse.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class is used to return an IpSecTransform resource Id and and corresponding status from the
+ * IpSecService to an IpSecTransform object.
+ *
+ * @hide
+ */
+public final class IpSecTransformResponse implements Parcelable {
+    private static final String TAG = "IpSecTransformResponse";
+
+    public final int resourceId;
+    public final int status;
+    // Parcelable Methods
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(status);
+        out.writeInt(resourceId);
+    }
+
+    public IpSecTransformResponse(int inStatus) {
+        if (inStatus == IpSecManager.Status.OK) {
+            throw new IllegalArgumentException("Valid status implies other args must be provided");
+        }
+        status = inStatus;
+        resourceId = IpSecManager.INVALID_RESOURCE_ID;
+    }
+
+    public IpSecTransformResponse(int inStatus, int inResourceId) {
+        status = inStatus;
+        resourceId = inResourceId;
+    }
+
+    private IpSecTransformResponse(Parcel in) {
+        status = in.readInt();
+        resourceId = in.readInt();
+    }
+
+    @android.annotation.NonNull
+    public static final Parcelable.Creator<IpSecTransformResponse> CREATOR =
+            new Parcelable.Creator<IpSecTransformResponse>() {
+                public IpSecTransformResponse createFromParcel(Parcel in) {
+                    return new IpSecTransformResponse(in);
+                }
+
+                public IpSecTransformResponse[] newArray(int size) {
+                    return new IpSecTransformResponse[size];
+                }
+            };
+}
diff --git a/framework-t/src/android/net/IpSecTunnelInterfaceResponse.aidl b/framework-t/src/android/net/IpSecTunnelInterfaceResponse.aidl
new file mode 100644
index 0000000..7239221
--- /dev/null
+++ b/framework-t/src/android/net/IpSecTunnelInterfaceResponse.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+package android.net;
+
+/** @hide */
+parcelable IpSecTunnelInterfaceResponse;
diff --git a/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java b/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java
new file mode 100644
index 0000000..127e30a
--- /dev/null
+++ b/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+package android.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class is used to return an IpSecTunnelInterface resource Id and and corresponding status
+ * from the IpSecService to an IpSecTunnelInterface object.
+ *
+ * @hide
+ */
+public final class IpSecTunnelInterfaceResponse implements Parcelable {
+    private static final String TAG = "IpSecTunnelInterfaceResponse";
+
+    public final int resourceId;
+    public final String interfaceName;
+    public final int status;
+    // Parcelable Methods
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(status);
+        out.writeInt(resourceId);
+        out.writeString(interfaceName);
+    }
+
+    public IpSecTunnelInterfaceResponse(int inStatus) {
+        if (inStatus == IpSecManager.Status.OK) {
+            throw new IllegalArgumentException("Valid status implies other args must be provided");
+        }
+        status = inStatus;
+        resourceId = IpSecManager.INVALID_RESOURCE_ID;
+        interfaceName = "";
+    }
+
+    public IpSecTunnelInterfaceResponse(int inStatus, int inResourceId, String inInterfaceName) {
+        status = inStatus;
+        resourceId = inResourceId;
+        interfaceName = inInterfaceName;
+    }
+
+    private IpSecTunnelInterfaceResponse(Parcel in) {
+        status = in.readInt();
+        resourceId = in.readInt();
+        interfaceName = in.readString();
+    }
+
+    @android.annotation.NonNull
+    public static final Parcelable.Creator<IpSecTunnelInterfaceResponse> CREATOR =
+            new Parcelable.Creator<IpSecTunnelInterfaceResponse>() {
+                public IpSecTunnelInterfaceResponse createFromParcel(Parcel in) {
+                    return new IpSecTunnelInterfaceResponse(in);
+                }
+
+                public IpSecTunnelInterfaceResponse[] newArray(int size) {
+                    return new IpSecTunnelInterfaceResponse[size];
+                }
+            };
+}
diff --git a/framework-t/src/android/net/IpSecUdpEncapResponse.aidl b/framework-t/src/android/net/IpSecUdpEncapResponse.aidl
new file mode 100644
index 0000000..5e451f3
--- /dev/null
+++ b/framework-t/src/android/net/IpSecUdpEncapResponse.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 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;
+
+/** @hide */
+parcelable IpSecUdpEncapResponse;
diff --git a/framework-t/src/android/net/IpSecUdpEncapResponse.java b/framework-t/src/android/net/IpSecUdpEncapResponse.java
new file mode 100644
index 0000000..390af82
--- /dev/null
+++ b/framework-t/src/android/net/IpSecUdpEncapResponse.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * This class is used to return a UDP Socket and corresponding status from the IpSecService to an
+ * IpSecManager.UdpEncapsulationSocket.
+ *
+ * @hide
+ */
+public final class IpSecUdpEncapResponse implements Parcelable {
+    private static final String TAG = "IpSecUdpEncapResponse";
+
+    public final int resourceId;
+    public final int port;
+    public final int status;
+    // There is a weird asymmetry with FileDescriptor: you can write a FileDescriptor
+    // but you read a ParcelFileDescriptor. To circumvent this, when we receive a FD
+    // from the user, we immediately create a ParcelFileDescriptor DUP, which we invalidate
+    // on writeParcel() by setting the flag to do close-on-write.
+    // TODO: tests to ensure this doesn't leak
+    public final ParcelFileDescriptor fileDescriptor;
+
+    // Parcelable Methods
+
+    @Override
+    public int describeContents() {
+        return (fileDescriptor != null) ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(status);
+        out.writeInt(resourceId);
+        out.writeInt(port);
+        out.writeParcelable(fileDescriptor, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+    }
+
+    public IpSecUdpEncapResponse(int inStatus) {
+        if (inStatus == IpSecManager.Status.OK) {
+            throw new IllegalArgumentException("Valid status implies other args must be provided");
+        }
+        status = inStatus;
+        resourceId = IpSecManager.INVALID_RESOURCE_ID;
+        port = -1;
+        fileDescriptor = null; // yes I know it's redundant, but readability
+    }
+
+    public IpSecUdpEncapResponse(int inStatus, int inResourceId, int inPort, FileDescriptor inFd)
+            throws IOException {
+        if (inStatus == IpSecManager.Status.OK && inFd == null) {
+            throw new IllegalArgumentException("Valid status implies FD must be non-null");
+        }
+        status = inStatus;
+        resourceId = inResourceId;
+        port = inPort;
+        fileDescriptor = (status == IpSecManager.Status.OK) ? ParcelFileDescriptor.dup(inFd) : null;
+    }
+
+    private IpSecUdpEncapResponse(Parcel in) {
+        status = in.readInt();
+        resourceId = in.readInt();
+        port = in.readInt();
+        fileDescriptor = in.readParcelable(ParcelFileDescriptor.class.getClassLoader(), android.os.ParcelFileDescriptor.class);
+    }
+
+    @android.annotation.NonNull
+    public static final Parcelable.Creator<IpSecUdpEncapResponse> CREATOR =
+            new Parcelable.Creator<IpSecUdpEncapResponse>() {
+                public IpSecUdpEncapResponse createFromParcel(Parcel in) {
+                    return new IpSecUdpEncapResponse(in);
+                }
+
+                public IpSecUdpEncapResponse[] newArray(int size) {
+                    return new IpSecUdpEncapResponse[size];
+                }
+            };
+}
diff --git a/framework-t/src/android/net/NetworkIdentity.java b/framework-t/src/android/net/NetworkIdentity.java
new file mode 100644
index 0000000..da5f88d
--- /dev/null
+++ b/framework-t/src/android/net/NetworkIdentity.java
@@ -0,0 +1,594 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.app.usage.NetworkStatsManager;
+import android.content.Context;
+import android.net.wifi.WifiInfo;
+import android.service.NetworkIdentityProto;
+import android.telephony.TelephonyManager;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.NetworkCapabilitiesUtils;
+import com.android.net.module.util.NetworkIdentityUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Objects;
+
+/**
+ * Network definition that includes strong identity. Analogous to combining
+ * {@link NetworkCapabilities} and an IMSI.
+ *
+ * @hide
+ */
+@SystemApi(client = MODULE_LIBRARIES)
+public class NetworkIdentity {
+    private static final String TAG = "NetworkIdentity";
+
+    /** @hide */
+    // TODO: Remove this after migrating all callers to use
+    //  {@link NetworkTemplate#NETWORK_TYPE_ALL} instead.
+    public static final int SUBTYPE_COMBINED = -1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "OEM_MANAGED_" }, flag = true, value = {
+            NetworkTemplate.OEM_MANAGED_NO,
+            NetworkTemplate.OEM_MANAGED_PAID,
+            NetworkTemplate.OEM_MANAGED_PRIVATE
+    })
+    public @interface OemManaged{}
+
+    /**
+     * Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}.
+     * @hide
+     */
+    public static final int OEM_NONE = 0x0;
+    /**
+     * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}.
+     * @hide
+     */
+    public static final int OEM_PAID = 1 << 0;
+    /**
+     * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}.
+     * @hide
+     */
+    public static final int OEM_PRIVATE = 1 << 1;
+
+    private static final long SUPPORTED_OEM_MANAGED_TYPES = OEM_PAID | OEM_PRIVATE;
+
+    final int mType;
+    final int mRatType;
+    final int mSubId;
+    final String mSubscriberId;
+    final String mWifiNetworkKey;
+    final boolean mRoaming;
+    final boolean mMetered;
+    final boolean mDefaultNetwork;
+    final int mOemManaged;
+
+    /** @hide */
+    public NetworkIdentity(
+            int type, int ratType, @Nullable String subscriberId, @Nullable String wifiNetworkKey,
+            boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged, int subId) {
+        mType = type;
+        mRatType = ratType;
+        mSubscriberId = subscriberId;
+        mWifiNetworkKey = wifiNetworkKey;
+        mRoaming = roaming;
+        mMetered = metered;
+        mDefaultNetwork = defaultNetwork;
+        mOemManaged = oemManaged;
+        mSubId = subId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mType, mRatType, mSubscriberId, mWifiNetworkKey, mRoaming, mMetered,
+                mDefaultNetwork, mOemManaged, mSubId);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj instanceof NetworkIdentity) {
+            final NetworkIdentity ident = (NetworkIdentity) obj;
+            return mType == ident.mType && mRatType == ident.mRatType && mRoaming == ident.mRoaming
+                    && Objects.equals(mSubscriberId, ident.mSubscriberId)
+                    && Objects.equals(mWifiNetworkKey, ident.mWifiNetworkKey)
+                    && mMetered == ident.mMetered
+                    && mDefaultNetwork == ident.mDefaultNetwork
+                    && mOemManaged == ident.mOemManaged
+                    && mSubId == ident.mSubId;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder("{");
+        builder.append("type=").append(mType);
+        builder.append(", ratType=");
+        if (mRatType == NETWORK_TYPE_ALL) {
+            builder.append("COMBINED");
+        } else {
+            builder.append(mRatType);
+        }
+        if (mSubscriberId != null) {
+            builder.append(", subscriberId=")
+                    .append(NetworkIdentityUtils.scrubSubscriberId(mSubscriberId));
+        }
+        if (mWifiNetworkKey != null) {
+            builder.append(", wifiNetworkKey=").append(mWifiNetworkKey);
+        }
+        if (mRoaming) {
+            builder.append(", ROAMING");
+        }
+        builder.append(", metered=").append(mMetered);
+        builder.append(", defaultNetwork=").append(mDefaultNetwork);
+        builder.append(", oemManaged=").append(getOemManagedNames(mOemManaged));
+        builder.append(", subId=").append(mSubId);
+        return builder.append("}").toString();
+    }
+
+    /**
+     * Get the human readable representation of a bitfield representing the OEM managed state of a
+     * network.
+     */
+    static String getOemManagedNames(int oemManaged) {
+        if (oemManaged == OEM_NONE) {
+            return "OEM_NONE";
+        }
+        final int[] bitPositions = NetworkCapabilitiesUtils.unpackBits(oemManaged);
+        final ArrayList<String> oemManagedNames = new ArrayList<String>();
+        for (int position : bitPositions) {
+            oemManagedNames.add(nameOfOemManaged(1 << position));
+        }
+        return String.join(",", oemManagedNames);
+    }
+
+    private static String nameOfOemManaged(int oemManagedBit) {
+        switch (oemManagedBit) {
+            case OEM_PAID:
+                return "OEM_PAID";
+            case OEM_PRIVATE:
+                return "OEM_PRIVATE";
+            default:
+                return "Invalid(" + oemManagedBit + ")";
+        }
+    }
+
+    /** @hide */
+    public void dumpDebug(ProtoOutputStream proto, long tag) {
+        final long start = proto.start(tag);
+
+        proto.write(NetworkIdentityProto.TYPE, mType);
+
+        // TODO: dump mRatType as well.
+
+        proto.write(NetworkIdentityProto.ROAMING, mRoaming);
+        proto.write(NetworkIdentityProto.METERED, mMetered);
+        proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork);
+        proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged);
+
+        proto.end(start);
+    }
+
+    /** Get the network type of this instance. */
+    public int getType() {
+        return mType;
+    }
+
+    /** Get the Radio Access Technology(RAT) type of this instance. */
+    public int getRatType() {
+        return mRatType;
+    }
+
+    /** Get the Subscriber Id of this instance. */
+    @Nullable
+    public String getSubscriberId() {
+        return mSubscriberId;
+    }
+
+    /** Get the Wifi Network Key of this instance. See {@link WifiInfo#getNetworkKey()}. */
+    @Nullable
+    public String getWifiNetworkKey() {
+        return mWifiNetworkKey;
+    }
+
+    /** @hide */
+    // TODO: Remove this function after all callers are removed.
+    public boolean getRoaming() {
+        return mRoaming;
+    }
+
+    /** Return whether this network is roaming. */
+    public boolean isRoaming() {
+        return mRoaming;
+    }
+
+    /** @hide */
+    // TODO: Remove this function after all callers are removed.
+    public boolean getMetered() {
+        return mMetered;
+    }
+
+    /** Return whether this network is metered. */
+    public boolean isMetered() {
+        return mMetered;
+    }
+
+    /** @hide */
+    // TODO: Remove this function after all callers are removed.
+    public boolean getDefaultNetwork() {
+        return mDefaultNetwork;
+    }
+
+    /** Return whether this network is the default network. */
+    public boolean isDefaultNetwork() {
+        return mDefaultNetwork;
+    }
+
+    /** Get the OEM managed type of this instance. */
+    public int getOemManaged() {
+        return mOemManaged;
+    }
+
+    /** Get the SubId of this instance. */
+    public int getSubId() {
+        return mSubId;
+    }
+
+    /**
+     * Assemble a {@link NetworkIdentity} from the passed arguments.
+     *
+     * This methods builds an identity based on the capabilities of the network in the
+     * snapshot and other passed arguments. The identity is used as a key to record data usage.
+     *
+     * @param snapshot the snapshot of network state. See {@link NetworkStateSnapshot}.
+     * @param defaultNetwork whether the network is a default network.
+     * @param ratType the Radio Access Technology(RAT) type of the network. Or
+     *                {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if not applicable.
+     *                See {@code TelephonyManager.NETWORK_TYPE_*}.
+     * @hide
+     * @deprecated See {@link NetworkIdentity.Builder}.
+     */
+    // TODO: Remove this after all callers are migrated to use new Api.
+    @Deprecated
+    @NonNull
+    public static NetworkIdentity buildNetworkIdentity(Context context,
+            @NonNull NetworkStateSnapshot snapshot, boolean defaultNetwork, int ratType) {
+        final NetworkIdentity.Builder builder = new NetworkIdentity.Builder()
+                .setNetworkStateSnapshot(snapshot).setDefaultNetwork(defaultNetwork)
+                .setSubId(snapshot.getSubId());
+        if (snapshot.getLegacyType() == TYPE_MOBILE && ratType != NETWORK_TYPE_ALL) {
+            builder.setRatType(ratType);
+        }
+        return builder.build();
+    }
+
+    /**
+     * Builds a bitfield of {@code NetworkIdentity.OEM_*} based on {@link NetworkCapabilities}.
+     * @hide
+     */
+    public static int getOemBitfield(@NonNull NetworkCapabilities nc) {
+        int oemManaged = OEM_NONE;
+
+        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)) {
+            oemManaged |= OEM_PAID;
+        }
+        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)) {
+            oemManaged |= OEM_PRIVATE;
+        }
+
+        return oemManaged;
+    }
+
+    /** @hide */
+    public static int compare(@NonNull NetworkIdentity left, @NonNull NetworkIdentity right) {
+        Objects.requireNonNull(right);
+        int res = Integer.compare(left.mType, right.mType);
+        if (res == 0) {
+            res = Integer.compare(left.mRatType, right.mRatType);
+        }
+        if (res == 0 && left.mSubscriberId != null && right.mSubscriberId != null) {
+            res = left.mSubscriberId.compareTo(right.mSubscriberId);
+        }
+        if (res == 0 && left.mWifiNetworkKey != null && right.mWifiNetworkKey != null) {
+            res = left.mWifiNetworkKey.compareTo(right.mWifiNetworkKey);
+        }
+        if (res == 0) {
+            res = Boolean.compare(left.mRoaming, right.mRoaming);
+        }
+        if (res == 0) {
+            res = Boolean.compare(left.mMetered, right.mMetered);
+        }
+        if (res == 0) {
+            res = Boolean.compare(left.mDefaultNetwork, right.mDefaultNetwork);
+        }
+        if (res == 0) {
+            res = Integer.compare(left.mOemManaged, right.mOemManaged);
+        }
+        if (res == 0) {
+            res = Integer.compare(left.mSubId, right.mSubId);
+        }
+        return res;
+    }
+
+    /**
+     * Builder class for {@link NetworkIdentity}.
+     */
+    public static final class Builder {
+        // Need to be synchronized with ConnectivityManager.
+        // TODO: Use {@link ConnectivityManager#MAX_NETWORK_TYPE} when this file is in the module.
+        private static final int MAX_NETWORK_TYPE = 18; // TYPE_TEST
+        private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
+
+        private int mType;
+        private int mRatType;
+        private String mSubscriberId;
+        private String mWifiNetworkKey;
+        private boolean mRoaming;
+        private boolean mMetered;
+        private boolean mDefaultNetwork;
+        private int mOemManaged;
+        private int mSubId;
+
+        /**
+         * Creates a new Builder.
+         */
+        public Builder() {
+            // Initialize with default values. Will be overwritten by setters.
+            mType = ConnectivityManager.TYPE_NONE;
+            mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
+            mSubscriberId = null;
+            mWifiNetworkKey = null;
+            mRoaming = false;
+            mMetered = false;
+            mDefaultNetwork = false;
+            mOemManaged = NetworkTemplate.OEM_MANAGED_NO;
+            mSubId = INVALID_SUBSCRIPTION_ID;
+        }
+
+        /**
+         * Add an {@link NetworkStateSnapshot} into the {@link NetworkIdentity} instance.
+         * This is a useful shorthand that will read from the snapshot and set the
+         * following fields, if they are set in the snapshot :
+         *  - type
+         *  - subscriberId
+         *  - roaming
+         *  - metered
+         *  - oemManaged
+         *  - wifiNetworkKey
+         *
+         * @param snapshot The target {@link NetworkStateSnapshot} object.
+         * @return The builder object.
+         */
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public Builder setNetworkStateSnapshot(@NonNull NetworkStateSnapshot snapshot) {
+            setType(snapshot.getLegacyType());
+
+            setSubscriberId(snapshot.getSubscriberId());
+            setRoaming(!snapshot.getNetworkCapabilities().hasCapability(
+                    NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING));
+            setMetered(!(snapshot.getNetworkCapabilities().hasCapability(
+                    NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+                    || snapshot.getNetworkCapabilities().hasCapability(
+                    NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)));
+
+            setOemManaged(getOemBitfield(snapshot.getNetworkCapabilities()));
+
+            if (mType == TYPE_WIFI) {
+                final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
+                        .getTransportInfo();
+                if (transportInfo instanceof WifiInfo) {
+                    final WifiInfo info = (WifiInfo) transportInfo;
+                    setWifiNetworkKey(info.getNetworkKey());
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Set the network type of the network.
+         *
+         * @param type the network type. See {@link ConnectivityManager#TYPE_*}.
+         *
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setType(int type) {
+            // Include TYPE_NONE for compatibility, type field might not be filled by some
+            // networks such as test networks.
+            if ((type < MIN_NETWORK_TYPE || MAX_NETWORK_TYPE < type)
+                    && type != ConnectivityManager.TYPE_NONE) {
+                throw new IllegalArgumentException("Invalid network type: " + type);
+            }
+            mType = type;
+            return this;
+        }
+
+        /**
+         * Set the Radio Access Technology(RAT) type of the network.
+         *
+         * No RAT type is specified by default. Call clearRatType to reset.
+         *
+         * @param ratType the Radio Access Technology(RAT) type if applicable. See
+         *                {@code TelephonyManager.NETWORK_TYPE_*}.
+         *
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setRatType(int ratType) {
+            if (!CollectionUtils.contains(TelephonyManager.getAllNetworkTypes(), ratType)
+                    && ratType != TelephonyManager.NETWORK_TYPE_UNKNOWN
+                    && ratType != NetworkStatsManager.NETWORK_TYPE_5G_NSA) {
+                throw new IllegalArgumentException("Invalid ratType " + ratType);
+            }
+            mRatType = ratType;
+            return this;
+        }
+
+        /**
+         * Clear the Radio Access Technology(RAT) type of the network.
+         *
+         * @return this builder.
+         */
+        @NonNull
+        public Builder clearRatType() {
+            mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
+            return this;
+        }
+
+        /**
+         * Set the Subscriber Id.
+         *
+         * @param subscriberId the Subscriber Id of the network. Or null if not applicable.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setSubscriberId(@Nullable String subscriberId) {
+            mSubscriberId = subscriberId;
+            return this;
+        }
+
+        /**
+         * Set the Wifi Network Key.
+         *
+         * @param wifiNetworkKey Wifi Network Key of the network,
+         *                        see {@link WifiInfo#getNetworkKey()}.
+         *                        Or null if not applicable.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) {
+            mWifiNetworkKey = wifiNetworkKey;
+            return this;
+        }
+
+        /**
+         * Set whether this network is roaming.
+         *
+         * This field is false by default. Call with false to reset.
+         *
+         * @param roaming the roaming status of the network.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setRoaming(boolean roaming) {
+            mRoaming = roaming;
+            return this;
+        }
+
+        /**
+         * Set whether this network is metered.
+         *
+         * This field is false by default. Call with false to reset.
+         *
+         * @param metered the meteredness of the network.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setMetered(boolean metered) {
+            mMetered = metered;
+            return this;
+        }
+
+        /**
+         * Set whether this network is the default network.
+         *
+         * This field is false by default. Call with false to reset.
+         *
+         * @param defaultNetwork the default network status of the network.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setDefaultNetwork(boolean defaultNetwork) {
+            mDefaultNetwork = defaultNetwork;
+            return this;
+        }
+
+        /**
+         * Set the OEM managed type.
+         *
+         * @param oemManaged Type of OEM managed network or unmanaged networks.
+         *                   See {@code NetworkTemplate#OEM_MANAGED_*}.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setOemManaged(@OemManaged int oemManaged) {
+            // Assert input does not contain illegal oemManage bits.
+            if ((~SUPPORTED_OEM_MANAGED_TYPES & oemManaged) != 0) {
+                throw new IllegalArgumentException("Invalid value for OemManaged : " + oemManaged);
+            }
+            mOemManaged = oemManaged;
+            return this;
+        }
+
+        /**
+         * Set the Subscription Id.
+         *
+         * @param subId the Subscription Id of the network. Or INVALID_SUBSCRIPTION_ID if not
+         *              applicable.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setSubId(int subId) {
+            mSubId = subId;
+            return this;
+        }
+
+        private void ensureValidParameters() {
+            // Assert non-mobile network cannot have a ratType.
+            if (mType != TYPE_MOBILE && mRatType != NetworkTemplate.NETWORK_TYPE_ALL) {
+                throw new IllegalArgumentException(
+                        "Invalid ratType " + mRatType + " for type " + mType);
+            }
+
+            // Assert non-wifi network cannot have a wifi network key.
+            if (mType != TYPE_WIFI && mWifiNetworkKey != null) {
+                throw new IllegalArgumentException("Invalid wifi network key for type " + mType);
+            }
+        }
+
+        /**
+         * Builds the instance of the {@link NetworkIdentity}.
+         *
+         * @return the built instance of {@link NetworkIdentity}.
+         */
+        @NonNull
+        public NetworkIdentity build() {
+            ensureValidParameters();
+            return new NetworkIdentity(mType, mRatType, mSubscriberId, mWifiNetworkKey,
+                    mRoaming, mMetered, mDefaultNetwork, mOemManaged, mSubId);
+        }
+    }
+}
diff --git a/framework-t/src/android/net/NetworkIdentitySet.java b/framework-t/src/android/net/NetworkIdentitySet.java
new file mode 100644
index 0000000..ad3a958
--- /dev/null
+++ b/framework-t/src/android/net/NetworkIdentitySet.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+import android.annotation.NonNull;
+import android.service.NetworkIdentitySetProto;
+import android.util.proto.ProtoOutputStream;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Identity of a {@code iface}, defined by the set of {@link NetworkIdentity}
+ * active on that interface.
+ *
+ * @hide
+ */
+public class NetworkIdentitySet extends HashSet<NetworkIdentity> {
+    private static final int VERSION_INIT = 1;
+    private static final int VERSION_ADD_ROAMING = 2;
+    private static final int VERSION_ADD_NETWORK_ID = 3;
+    private static final int VERSION_ADD_METERED = 4;
+    private static final int VERSION_ADD_DEFAULT_NETWORK = 5;
+    private static final int VERSION_ADD_OEM_MANAGED_NETWORK = 6;
+    private static final int VERSION_ADD_SUB_ID = 7;
+
+    /**
+     * Construct a {@link NetworkIdentitySet} object.
+     */
+    public NetworkIdentitySet() {
+        super();
+    }
+
+    /** @hide */
+    public NetworkIdentitySet(@NonNull Set<NetworkIdentity> ident) {
+        super(ident);
+    }
+
+    /** @hide */
+    public NetworkIdentitySet(DataInput in) throws IOException {
+        final int version = in.readInt();
+        final int size = in.readInt();
+        for (int i = 0; i < size; i++) {
+            if (version <= VERSION_INIT) {
+                final int ignored = in.readInt();
+            }
+            final int type = in.readInt();
+            final int ratType = in.readInt();
+            final String subscriberId = readOptionalString(in);
+            final String networkId;
+            if (version >= VERSION_ADD_NETWORK_ID) {
+                networkId = readOptionalString(in);
+            } else {
+                networkId = null;
+            }
+            final boolean roaming;
+            if (version >= VERSION_ADD_ROAMING) {
+                roaming = in.readBoolean();
+            } else {
+                roaming = false;
+            }
+
+            final boolean metered;
+            if (version >= VERSION_ADD_METERED) {
+                metered = in.readBoolean();
+            } else {
+                // If this is the old data and the type is mobile, treat it as metered. (Note that
+                // if this is a mobile network, TYPE_MOBILE is the only possible type that could be
+                // used.)
+                metered = (type == TYPE_MOBILE);
+            }
+
+            final boolean defaultNetwork;
+            if (version >= VERSION_ADD_DEFAULT_NETWORK) {
+                defaultNetwork = in.readBoolean();
+            } else {
+                defaultNetwork = true;
+            }
+
+            final int oemNetCapabilities;
+            if (version >= VERSION_ADD_OEM_MANAGED_NETWORK) {
+                oemNetCapabilities = in.readInt();
+            } else {
+                oemNetCapabilities = NetworkIdentity.OEM_NONE;
+            }
+
+            final int subId;
+            if (version >= VERSION_ADD_SUB_ID) {
+                subId = in.readInt();
+            } else {
+                subId = INVALID_SUBSCRIPTION_ID;
+            }
+
+            add(new NetworkIdentity(type, ratType, subscriberId, networkId, roaming, metered,
+                    defaultNetwork, oemNetCapabilities, subId));
+        }
+    }
+
+    /**
+     * Method to serialize this object into a {@code DataOutput}.
+     * @hide
+     */
+    public void writeToStream(DataOutput out) throws IOException {
+        out.writeInt(VERSION_ADD_SUB_ID);
+        out.writeInt(size());
+        for (NetworkIdentity ident : this) {
+            out.writeInt(ident.getType());
+            out.writeInt(ident.getRatType());
+            writeOptionalString(out, ident.getSubscriberId());
+            writeOptionalString(out, ident.getWifiNetworkKey());
+            out.writeBoolean(ident.isRoaming());
+            out.writeBoolean(ident.isMetered());
+            out.writeBoolean(ident.isDefaultNetwork());
+            out.writeInt(ident.getOemManaged());
+            out.writeInt(ident.getSubId());
+        }
+    }
+
+    /**
+     * @return whether any {@link NetworkIdentity} in this set is considered metered.
+     * @hide
+     */
+    public boolean isAnyMemberMetered() {
+        if (isEmpty()) {
+            return false;
+        }
+        for (NetworkIdentity ident : this) {
+            if (ident.isMetered()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @return whether any {@link NetworkIdentity} in this set is considered roaming.
+     * @hide
+     */
+    public boolean isAnyMemberRoaming() {
+        if (isEmpty()) {
+            return false;
+        }
+        for (NetworkIdentity ident : this) {
+            if (ident.isRoaming()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @return whether any {@link NetworkIdentity} in this set is considered on the default
+     *         network.
+     * @hide
+     */
+    public boolean areAllMembersOnDefaultNetwork() {
+        if (isEmpty()) {
+            return true;
+        }
+        for (NetworkIdentity ident : this) {
+            if (!ident.isDefaultNetwork()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static void writeOptionalString(DataOutput out, String value) throws IOException {
+        if (value != null) {
+            out.writeByte(1);
+            out.writeUTF(value);
+        } else {
+            out.writeByte(0);
+        }
+    }
+
+    private static String readOptionalString(DataInput in) throws IOException {
+        if (in.readByte() != 0) {
+            return in.readUTF();
+        } else {
+            return null;
+        }
+    }
+
+    public static int compare(@NonNull NetworkIdentitySet left, @NonNull NetworkIdentitySet right) {
+        Objects.requireNonNull(left);
+        Objects.requireNonNull(right);
+        if (left.isEmpty()) return -1;
+        if (right.isEmpty()) return 1;
+
+        final NetworkIdentity leftIdent = left.iterator().next();
+        final NetworkIdentity rightIdent = right.iterator().next();
+        return NetworkIdentity.compare(leftIdent, rightIdent);
+    }
+
+    /**
+     * Method to dump this object into proto debug file.
+     * @hide
+     */
+    public void dumpDebug(ProtoOutputStream proto, long tag) {
+        final long start = proto.start(tag);
+
+        for (NetworkIdentity ident : this) {
+            ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES);
+        }
+
+        proto.end(start);
+    }
+}
diff --git a/framework-t/src/android/net/NetworkStateSnapshot.java b/framework-t/src/android/net/NetworkStateSnapshot.java
new file mode 100644
index 0000000..c018e91
--- /dev/null
+++ b/framework-t/src/android/net/NetworkStateSnapshot.java
@@ -0,0 +1,192 @@
+/*
+ * 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 android.net;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.net.module.util.NetworkIdentityUtils;
+
+import java.util.Objects;
+
+/**
+ * Snapshot of network state.
+ *
+ * @hide
+ */
+@SystemApi(client = MODULE_LIBRARIES)
+public final class NetworkStateSnapshot implements Parcelable {
+    /** The network associated with this snapshot. */
+    @NonNull
+    private final Network mNetwork;
+
+    /** The {@link NetworkCapabilities} of the network associated with this snapshot. */
+    @NonNull
+    private final NetworkCapabilities mNetworkCapabilities;
+
+    /** The {@link LinkProperties} of the network associated with this snapshot. */
+    @NonNull
+    private final LinkProperties mLinkProperties;
+
+    /**
+     * The Subscriber Id of the network associated with this snapshot. See
+     * {@link android.telephony.TelephonyManager#getSubscriberId()}.
+     */
+    @Nullable
+    private final String mSubscriberId;
+
+    /**
+     * The legacy type of the network associated with this snapshot. See
+     * {@code ConnectivityManager#TYPE_*}.
+     */
+    private final int mLegacyType;
+
+    public NetworkStateSnapshot(@NonNull Network network,
+            @NonNull NetworkCapabilities networkCapabilities,
+            @NonNull LinkProperties linkProperties,
+            @Nullable String subscriberId, int legacyType) {
+        mNetwork = Objects.requireNonNull(network);
+        mNetworkCapabilities = Objects.requireNonNull(networkCapabilities);
+        mLinkProperties = Objects.requireNonNull(linkProperties);
+        mSubscriberId = subscriberId;
+        mLegacyType = legacyType;
+    }
+
+    /** @hide */
+    public NetworkStateSnapshot(@NonNull Parcel in) {
+        mNetwork = in.readParcelable(null, android.net.Network.class);
+        mNetworkCapabilities = in.readParcelable(null, android.net.NetworkCapabilities.class);
+        mLinkProperties = in.readParcelable(null, android.net.LinkProperties.class);
+        mSubscriberId = in.readString();
+        mLegacyType = in.readInt();
+    }
+
+    /** Get the network associated with this snapshot */
+    @NonNull
+    public Network getNetwork() {
+        return mNetwork;
+    }
+
+    /** Get {@link NetworkCapabilities} of the network associated with this snapshot. */
+    @NonNull
+    public NetworkCapabilities getNetworkCapabilities() {
+        return mNetworkCapabilities;
+    }
+
+    /** Get the {@link LinkProperties} of the network associated with this snapshot. */
+    @NonNull
+    public LinkProperties getLinkProperties() {
+        return mLinkProperties;
+    }
+
+    /**
+     * Get the Subscriber Id of the network associated with this snapshot.
+     * @deprecated Please use #getSubId, which doesn't return personally identifiable
+     * information.
+     */
+    @Deprecated
+    @Nullable
+    public String getSubscriberId() {
+        return mSubscriberId;
+    }
+
+    /** Get the subId of the network associated with this snapshot. */
+    public int getSubId() {
+        if (mNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
+            final NetworkSpecifier spec = mNetworkCapabilities.getNetworkSpecifier();
+            if (spec instanceof TelephonyNetworkSpecifier) {
+                return ((TelephonyNetworkSpecifier) spec).getSubscriptionId();
+            }
+        }
+        return INVALID_SUBSCRIPTION_ID;
+    }
+
+
+    /**
+     * Get the legacy type of the network associated with this snapshot.
+     * @return the legacy network type. See {@code ConnectivityManager#TYPE_*}.
+     */
+    public int getLegacyType() {
+        return mLegacyType;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeParcelable(mNetwork, flags);
+        out.writeParcelable(mNetworkCapabilities, flags);
+        out.writeParcelable(mLinkProperties, flags);
+        out.writeString(mSubscriberId);
+        out.writeInt(mLegacyType);
+    }
+
+    @NonNull
+    public static final Creator<NetworkStateSnapshot> CREATOR =
+            new Creator<NetworkStateSnapshot>() {
+        @NonNull
+        @Override
+        public NetworkStateSnapshot createFromParcel(@NonNull Parcel in) {
+            return new NetworkStateSnapshot(in);
+        }
+
+        @NonNull
+        @Override
+        public NetworkStateSnapshot[] newArray(int size) {
+            return new NetworkStateSnapshot[size];
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof NetworkStateSnapshot)) return false;
+        NetworkStateSnapshot that = (NetworkStateSnapshot) o;
+        return mLegacyType == that.mLegacyType
+                && Objects.equals(mNetwork, that.mNetwork)
+                && Objects.equals(mNetworkCapabilities, that.mNetworkCapabilities)
+                && Objects.equals(mLinkProperties, that.mLinkProperties)
+                && Objects.equals(mSubscriberId, that.mSubscriberId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mNetwork,
+                mNetworkCapabilities, mLinkProperties, mSubscriberId, mLegacyType);
+    }
+
+    @Override
+    public String toString() {
+        return "NetworkStateSnapshot{"
+                + "network=" + mNetwork
+                + ", networkCapabilities=" + mNetworkCapabilities
+                + ", linkProperties=" + mLinkProperties
+                + ", subscriberId='" + NetworkIdentityUtils.scrubSubscriberId(mSubscriberId) + '\''
+                + ", legacyType=" + mLegacyType
+                + '}';
+    }
+}
diff --git a/framework-t/src/android/net/NetworkStats.java b/framework-t/src/android/net/NetworkStats.java
new file mode 100644
index 0000000..bcfeab9
--- /dev/null
+++ b/framework-t/src/android/net/NetworkStats.java
@@ -0,0 +1,1860 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
+import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.Process;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.SparseBooleanArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.CollectionUtils;
+
+import libcore.util.EmptyArray;
+
+import java.io.CharArrayWriter;
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Predicate;
+
+/**
+ * Collection of active network statistics. Can contain summary details across
+ * all interfaces, or details with per-UID granularity. Internally stores data
+ * as a large table, closely matching {@code /proc/} data format. This structure
+ * optimizes for rapid in-memory comparison, but consider using
+ * {@link NetworkStatsHistory} when persisting.
+ *
+ * @hide
+ */
+// @NotThreadSafe
+@SystemApi
+public final class NetworkStats implements Parcelable, Iterable<NetworkStats.Entry> {
+    private static final String TAG = "NetworkStats";
+
+    /**
+     * {@link #iface} value when interface details unavailable.
+     * @hide
+     */
+    @Nullable public static final String IFACE_ALL = null;
+
+    /**
+     * Virtual network interface for video telephony. This is for VT data usage counting
+     * purpose.
+     */
+    public static final String IFACE_VT = "vt_data0";
+
+    /** {@link #uid} value when UID details unavailable. */
+    public static final int UID_ALL = -1;
+    /** Special UID value for data usage by tethering. */
+    public static final int UID_TETHERING = -5;
+
+    /**
+     * {@link #tag} value matching any tag.
+     * @hide
+     */
+    // TODO: Rename TAG_ALL to TAG_ANY.
+    public static final int TAG_ALL = -1;
+    /** {@link #set} value for all sets combined, not including debug sets. */
+    public static final int SET_ALL = -1;
+    /** {@link #set} value where background data is accounted. */
+    public static final int SET_DEFAULT = 0;
+    /** {@link #set} value where foreground data is accounted. */
+    public static final int SET_FOREGROUND = 1;
+    /**
+     * All {@link #set} value greater than SET_DEBUG_START are debug {@link #set} values.
+     * @hide
+     */
+    public static final int SET_DEBUG_START = 1000;
+    /**
+     * Debug {@link #set} value when the VPN stats are moved in.
+     * @hide
+     */
+    public static final int SET_DBG_VPN_IN = 1001;
+    /**
+     * Debug {@link #set} value when the VPN stats are moved out of a vpn UID.
+     * @hide
+     */
+    public static final int SET_DBG_VPN_OUT = 1002;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "SET_" }, value = {
+            SET_ALL,
+            SET_DEFAULT,
+            SET_FOREGROUND,
+    })
+    public @interface State {
+    }
+
+    /**
+     * Include all interfaces when filtering
+     * @hide
+     */
+    public @Nullable static final String[] INTERFACES_ALL = null;
+
+    /** {@link #tag} value for total data across all tags. */
+    public static final int TAG_NONE = 0;
+
+    /** {@link #metered} value to account for all metered states. */
+    public static final int METERED_ALL = -1;
+    /** {@link #metered} value where native, unmetered data is accounted. */
+    public static final int METERED_NO = 0;
+    /** {@link #metered} value where metered data is accounted. */
+    public static final int METERED_YES = 1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "METERED_" }, value = {
+            METERED_ALL,
+            METERED_NO,
+            METERED_YES
+    })
+    public @interface Meteredness {
+    }
+
+
+    /** {@link #roaming} value to account for all roaming states. */
+    public static final int ROAMING_ALL = -1;
+    /** {@link #roaming} value where native, non-roaming data is accounted. */
+    public static final int ROAMING_NO = 0;
+    /** {@link #roaming} value where roaming data is accounted. */
+    public static final int ROAMING_YES = 1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "ROAMING_" }, value = {
+            ROAMING_ALL,
+            ROAMING_NO,
+            ROAMING_YES
+    })
+    public @interface Roaming {
+    }
+
+    /** {@link #onDefaultNetwork} value to account for all default network states. */
+    public static final int DEFAULT_NETWORK_ALL = -1;
+    /** {@link #onDefaultNetwork} value to account for usage while not the default network. */
+    public static final int DEFAULT_NETWORK_NO = 0;
+    /** {@link #onDefaultNetwork} value to account for usage while the default network. */
+    public static final int DEFAULT_NETWORK_YES = 1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "DEFAULT_NETWORK_" }, value = {
+            DEFAULT_NETWORK_ALL,
+            DEFAULT_NETWORK_NO,
+            DEFAULT_NETWORK_YES
+    })
+    public @interface DefaultNetwork {
+    }
+
+    /**
+     * Denotes a request for stats at the interface level.
+     * @hide
+     */
+    public static final int STATS_PER_IFACE = 0;
+    /**
+     * Denotes a request for stats at the interface and UID level.
+     * @hide
+     */
+    public static final int STATS_PER_UID = 1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "STATS_PER_" }, value = {
+            STATS_PER_IFACE,
+            STATS_PER_UID
+    })
+    public @interface StatsType {
+    }
+
+    private static final String CLATD_INTERFACE_PREFIX = "v4-";
+    // Delta between IPv4 header (20b) and IPv6 header (40b).
+    // Used for correct stats accounting on clatd interfaces.
+    private static final int IPV4V6_HEADER_DELTA = 20;
+
+    // TODO: move fields to "mVariable" notation
+
+    /**
+     * {@link SystemClock#elapsedRealtime()} timestamp in milliseconds when this data was
+     * generated.
+     * It's a timestamps delta when {@link #subtract()},
+     * {@code INetworkStatsSession#getSummaryForAllUid()} methods are used.
+     */
+    private long elapsedRealtime;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int size;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int capacity;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private String[] iface;
+    @UnsupportedAppUsage
+    private int[] uid;
+    @UnsupportedAppUsage
+    private int[] set;
+    @UnsupportedAppUsage
+    private int[] tag;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int[] metered;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int[] roaming;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int[] defaultNetwork;
+    @UnsupportedAppUsage
+    private long[] rxBytes;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long[] rxPackets;
+    @UnsupportedAppUsage
+    private long[] txBytes;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long[] txPackets;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long[] operations;
+
+    /**
+     * Basic element of network statistics. Contains the number of packets and number of bytes
+     * transferred on both directions in a given set of conditions. See
+     * {@link Entry#Entry(String, int, int, int, int, int, int, long, long, long, long, long)}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static class Entry {
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public String iface;
+        /** @hide */
+        @UnsupportedAppUsage
+        public int uid;
+        /** @hide */
+        @UnsupportedAppUsage
+        public int set;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public int tag;
+        /**
+         * Note that this is only populated w/ the default value when read from /proc or written
+         * to disk. We merge in the correct value when reporting this value to clients of
+         * getSummary().
+         * @hide
+         */
+        public int metered;
+        /**
+         * Note that this is only populated w/ the default value when read from /proc or written
+         * to disk. We merge in the correct value when reporting this value to clients of
+         * getSummary().
+         * @hide
+         */
+        public int roaming;
+        /**
+         * Note that this is only populated w/ the default value when read from /proc or written
+         * to disk. We merge in the correct value when reporting this value to clients of
+         * getSummary().
+         * @hide
+         */
+        public int defaultNetwork;
+        /** @hide */
+        @UnsupportedAppUsage
+        public long rxBytes;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long rxPackets;
+        /** @hide */
+        @UnsupportedAppUsage
+        public long txBytes;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long txPackets;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long operations;
+
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public Entry() {
+            this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
+        }
+
+        /** @hide */
+        public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
+            this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets,
+                    operations);
+        }
+
+        /** @hide */
+        public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets,
+                long txBytes, long txPackets, long operations) {
+            this(iface, uid, set, tag, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO,
+                    rxBytes, rxPackets, txBytes, txPackets, operations);
+        }
+
+        /**
+         * Construct a {@link Entry} object by giving statistics of packet and byte transferred on
+         * both direction, and associated with a set of given conditions.
+         *
+         * @param iface interface name of this {@link Entry}. Or null if not specified.
+         * @param uid uid of this {@link Entry}. {@link #UID_TETHERING} if this {@link Entry} is
+         *            for tethering. Or {@link #UID_ALL} if this {@link NetworkStats} is only
+         *            counting iface stats.
+         * @param set usage state of this {@link Entry}.
+         * @param tag tag of this {@link Entry}.
+         * @param metered metered state of this {@link Entry}.
+         * @param roaming roaming state of this {@link Entry}.
+         * @param defaultNetwork default network status of this {@link Entry}.
+         * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param rxPackets Number of packets received for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param operations count of network operations performed for this {@link Entry}. This can
+         *                   be used to derive bytes-per-operation.
+         */
+        public Entry(@Nullable String iface, int uid, @State int set, int tag,
+                @Meteredness int metered, @Roaming int roaming, @DefaultNetwork int defaultNetwork,
+                long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
+            this.iface = iface;
+            this.uid = uid;
+            this.set = set;
+            this.tag = tag;
+            this.metered = metered;
+            this.roaming = roaming;
+            this.defaultNetwork = defaultNetwork;
+            this.rxBytes = rxBytes;
+            this.rxPackets = rxPackets;
+            this.txBytes = txBytes;
+            this.txPackets = txPackets;
+            this.operations = operations;
+        }
+
+        /** @hide */
+        public boolean isNegative() {
+            return rxBytes < 0 || rxPackets < 0 || txBytes < 0 || txPackets < 0 || operations < 0;
+        }
+
+        /** @hide */
+        public boolean isEmpty() {
+            return rxBytes == 0 && rxPackets == 0 && txBytes == 0 && txPackets == 0
+                    && operations == 0;
+        }
+
+        /** @hide */
+        public void add(Entry another) {
+            this.rxBytes += another.rxBytes;
+            this.rxPackets += another.rxPackets;
+            this.txBytes += another.txBytes;
+            this.txPackets += another.txPackets;
+            this.operations += another.operations;
+        }
+
+        /**
+         * @return interface name of this entry.
+         * @hide
+         */
+        @Nullable public String getIface() {
+            return iface;
+        }
+
+        /**
+         * @return the uid of this entry.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public int getUid() {
+            return uid;
+        }
+
+        /**
+         * @return the set state of this entry.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        @State public int getSet() {
+            return set;
+        }
+
+        /**
+         * @return the tag value of this entry.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public int getTag() {
+            return tag;
+        }
+
+        /**
+         * @return the metered state.
+         * @hide
+         */
+        @Meteredness
+        @SystemApi(client = MODULE_LIBRARIES)
+        public int getMetered() {
+            return metered;
+        }
+
+        /**
+         * @return the roaming state.
+         * @hide
+         */
+        @Roaming
+        @SystemApi(client = MODULE_LIBRARIES)
+        public int getRoaming() {
+            return roaming;
+        }
+
+        /**
+         * @return the default network state.
+         * @hide
+         */
+        @DefaultNetwork
+        @SystemApi(client = MODULE_LIBRARIES)
+        public int getDefaultNetwork() {
+            return defaultNetwork;
+        }
+
+        /**
+         * @return the number of received bytes.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public long getRxBytes() {
+            return rxBytes;
+        }
+
+        /**
+         * @return the number of received packets.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public long getRxPackets() {
+            return rxPackets;
+        }
+
+        /**
+         * @return the number of transmitted bytes.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public long getTxBytes() {
+            return txBytes;
+        }
+
+        /**
+         * @return the number of transmitted packets.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public long getTxPackets() {
+            return txPackets;
+        }
+
+        /**
+         * @return the count of network operations performed for this entry.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public long getOperations() {
+            return operations;
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder builder = new StringBuilder();
+            builder.append("iface=").append(iface);
+            builder.append(" uid=").append(uid);
+            builder.append(" set=").append(setToString(set));
+            builder.append(" tag=").append(tagToString(tag));
+            builder.append(" metered=").append(meteredToString(metered));
+            builder.append(" roaming=").append(roamingToString(roaming));
+            builder.append(" defaultNetwork=").append(defaultNetworkToString(defaultNetwork));
+            builder.append(" rxBytes=").append(rxBytes);
+            builder.append(" rxPackets=").append(rxPackets);
+            builder.append(" txBytes=").append(txBytes);
+            builder.append(" txPackets=").append(txPackets);
+            builder.append(" operations=").append(operations);
+            return builder.toString();
+        }
+
+        /** @hide */
+        @Override
+        public boolean equals(@Nullable Object o) {
+            if (o instanceof Entry) {
+                final Entry e = (Entry) o;
+                return uid == e.uid && set == e.set && tag == e.tag && metered == e.metered
+                        && roaming == e.roaming && defaultNetwork == e.defaultNetwork
+                        && rxBytes == e.rxBytes && rxPackets == e.rxPackets
+                        && txBytes == e.txBytes && txPackets == e.txPackets
+                        && operations == e.operations && TextUtils.equals(iface, e.iface);
+            }
+            return false;
+        }
+
+        /** @hide */
+        @Override
+        public int hashCode() {
+            return Objects.hash(uid, set, tag, metered, roaming, defaultNetwork, iface);
+        }
+    }
+
+    public NetworkStats(long elapsedRealtime, int initialSize) {
+        this.elapsedRealtime = elapsedRealtime;
+        this.size = 0;
+        if (initialSize > 0) {
+            this.capacity = initialSize;
+            this.iface = new String[initialSize];
+            this.uid = new int[initialSize];
+            this.set = new int[initialSize];
+            this.tag = new int[initialSize];
+            this.metered = new int[initialSize];
+            this.roaming = new int[initialSize];
+            this.defaultNetwork = new int[initialSize];
+            this.rxBytes = new long[initialSize];
+            this.rxPackets = new long[initialSize];
+            this.txBytes = new long[initialSize];
+            this.txPackets = new long[initialSize];
+            this.operations = new long[initialSize];
+        } else {
+            // Special case for use by NetworkStatsFactory to start out *really* empty.
+            clear();
+        }
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public NetworkStats(Parcel parcel) {
+        elapsedRealtime = parcel.readLong();
+        size = parcel.readInt();
+        capacity = parcel.readInt();
+        iface = parcel.createStringArray();
+        uid = parcel.createIntArray();
+        set = parcel.createIntArray();
+        tag = parcel.createIntArray();
+        metered = parcel.createIntArray();
+        roaming = parcel.createIntArray();
+        defaultNetwork = parcel.createIntArray();
+        rxBytes = parcel.createLongArray();
+        rxPackets = parcel.createLongArray();
+        txBytes = parcel.createLongArray();
+        txPackets = parcel.createLongArray();
+        operations = parcel.createLongArray();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeLong(elapsedRealtime);
+        dest.writeInt(size);
+        dest.writeInt(capacity);
+        dest.writeStringArray(iface);
+        dest.writeIntArray(uid);
+        dest.writeIntArray(set);
+        dest.writeIntArray(tag);
+        dest.writeIntArray(metered);
+        dest.writeIntArray(roaming);
+        dest.writeIntArray(defaultNetwork);
+        dest.writeLongArray(rxBytes);
+        dest.writeLongArray(rxPackets);
+        dest.writeLongArray(txBytes);
+        dest.writeLongArray(txPackets);
+        dest.writeLongArray(operations);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public NetworkStats clone() {
+        final NetworkStats clone = new NetworkStats(elapsedRealtime, size);
+        NetworkStats.Entry entry = null;
+        for (int i = 0; i < size; i++) {
+            entry = getValues(i, entry);
+            clone.insertEntry(entry);
+        }
+        return clone;
+    }
+
+    /**
+     * Clear all data stored in this object.
+     * @hide
+     */
+    public void clear() {
+        this.capacity = 0;
+        this.iface = EmptyArray.STRING;
+        this.uid = EmptyArray.INT;
+        this.set = EmptyArray.INT;
+        this.tag = EmptyArray.INT;
+        this.metered = EmptyArray.INT;
+        this.roaming = EmptyArray.INT;
+        this.defaultNetwork = EmptyArray.INT;
+        this.rxBytes = EmptyArray.LONG;
+        this.rxPackets = EmptyArray.LONG;
+        this.txBytes = EmptyArray.LONG;
+        this.txPackets = EmptyArray.LONG;
+        this.operations = EmptyArray.LONG;
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public NetworkStats insertEntry(
+            String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) {
+        return insertEntry(
+                iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L);
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public NetworkStats insertEntry(String iface, int uid, int set, int tag, long rxBytes,
+            long rxPackets, long txBytes, long txPackets, long operations) {
+        return insertEntry(new Entry(
+                iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public NetworkStats insertEntry(String iface, int uid, int set, int tag, int metered,
+            int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes,
+            long txPackets, long operations) {
+        return insertEntry(new Entry(
+                iface, uid, set, tag, metered, roaming, defaultNetwork, rxBytes, rxPackets,
+                txBytes, txPackets, operations));
+    }
+
+    /**
+     * Add new stats entry, copying from given {@link Entry}. The {@link Entry}
+     * object can be recycled across multiple calls.
+     * @hide
+     */
+    public NetworkStats insertEntry(Entry entry) {
+        if (size >= capacity) {
+            final int newLength = Math.max(size, 10) * 3 / 2;
+            iface = Arrays.copyOf(iface, newLength);
+            uid = Arrays.copyOf(uid, newLength);
+            set = Arrays.copyOf(set, newLength);
+            tag = Arrays.copyOf(tag, newLength);
+            metered = Arrays.copyOf(metered, newLength);
+            roaming = Arrays.copyOf(roaming, newLength);
+            defaultNetwork = Arrays.copyOf(defaultNetwork, newLength);
+            rxBytes = Arrays.copyOf(rxBytes, newLength);
+            rxPackets = Arrays.copyOf(rxPackets, newLength);
+            txBytes = Arrays.copyOf(txBytes, newLength);
+            txPackets = Arrays.copyOf(txPackets, newLength);
+            operations = Arrays.copyOf(operations, newLength);
+            capacity = newLength;
+        }
+
+        setValues(size, entry);
+        size++;
+
+        return this;
+    }
+
+    private void setValues(int i, Entry entry) {
+        iface[i] = entry.iface;
+        uid[i] = entry.uid;
+        set[i] = entry.set;
+        tag[i] = entry.tag;
+        metered[i] = entry.metered;
+        roaming[i] = entry.roaming;
+        defaultNetwork[i] = entry.defaultNetwork;
+        rxBytes[i] = entry.rxBytes;
+        rxPackets[i] = entry.rxPackets;
+        txBytes[i] = entry.txBytes;
+        txPackets[i] = entry.txPackets;
+        operations[i] = entry.operations;
+    }
+
+    /**
+     * Iterate over Entry objects.
+     *
+     * Return an iterator of this object that will iterate through all contained Entry objects.
+     *
+     * This iterator does not support concurrent modification and makes no guarantee of fail-fast
+     * behavior. If any method that can mutate the contents of this object is called while
+     * iteration is in progress, either inside the loop or in another thread, then behavior is
+     * undefined.
+     * The remove() method is not implemented and will throw UnsupportedOperationException.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull public Iterator<Entry> iterator() {
+        return new Iterator<Entry>() {
+            int mIndex = 0;
+
+            @Override
+            public boolean hasNext() {
+                return mIndex < size;
+            }
+
+            @Override
+            public Entry next() {
+                return getValues(mIndex++, null);
+            }
+        };
+    }
+
+    /**
+     * Return specific stats entry.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public Entry getValues(int i, @Nullable Entry recycle) {
+        final Entry entry = recycle != null ? recycle : new Entry();
+        entry.iface = iface[i];
+        entry.uid = uid[i];
+        entry.set = set[i];
+        entry.tag = tag[i];
+        entry.metered = metered[i];
+        entry.roaming = roaming[i];
+        entry.defaultNetwork = defaultNetwork[i];
+        entry.rxBytes = rxBytes[i];
+        entry.rxPackets = rxPackets[i];
+        entry.txBytes = txBytes[i];
+        entry.txPackets = txPackets[i];
+        entry.operations = operations[i];
+        return entry;
+    }
+
+    /**
+     * If @{code dest} is not equal to @{code src}, copy entry from index @{code src} to index
+     * @{code dest}.
+     */
+    private void maybeCopyEntry(int dest, int src) {
+        if (dest == src) return;
+        iface[dest] = iface[src];
+        uid[dest] = uid[src];
+        set[dest] = set[src];
+        tag[dest] = tag[src];
+        metered[dest] = metered[src];
+        roaming[dest] = roaming[src];
+        defaultNetwork[dest] = defaultNetwork[src];
+        rxBytes[dest] = rxBytes[src];
+        rxPackets[dest] = rxPackets[src];
+        txBytes[dest] = txBytes[src];
+        txPackets[dest] = txPackets[src];
+        operations[dest] = operations[src];
+    }
+
+    /** @hide */
+    public long getElapsedRealtime() {
+        return elapsedRealtime;
+    }
+
+    /** @hide */
+    public void setElapsedRealtime(long time) {
+        elapsedRealtime = time;
+    }
+
+    /**
+     * Return age of this {@link NetworkStats} object with respect to
+     * {@link SystemClock#elapsedRealtime()}.
+     * @hide
+     */
+    public long getElapsedRealtimeAge() {
+        return SystemClock.elapsedRealtime() - elapsedRealtime;
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public int size() {
+        return size;
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public int internalSize() {
+        return capacity;
+    }
+
+    /** @hide */
+    @Deprecated
+    public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
+            long txBytes, long txPackets, long operations) {
+        return combineValues(
+                iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes,
+                txPackets, operations);
+    }
+
+    /** @hide */
+    public NetworkStats combineValues(String iface, int uid, int set, int tag,
+            long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
+        return combineValues(new Entry(
+                iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
+    }
+
+    /**
+     * Combine given values with an existing row, or create a new row if
+     * {@link #findIndex(String, int, int, int, int, int, int)} is unable to find match. Can
+     * also be used to subtract values from existing rows. This method mutates the referencing
+     * {@link NetworkStats} object.
+     *
+     * @param entry the {@link Entry} to combine.
+     * @return a reference to this mutated {@link NetworkStats} object.
+     * @hide
+     */
+    public @NonNull NetworkStats combineValues(@NonNull Entry entry) {
+        final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.metered,
+                entry.roaming, entry.defaultNetwork);
+        if (i == -1) {
+            // only create new entry when positive contribution
+            insertEntry(entry);
+        } else {
+            rxBytes[i] += entry.rxBytes;
+            rxPackets[i] += entry.rxPackets;
+            txBytes[i] += entry.txBytes;
+            txPackets[i] += entry.txPackets;
+            operations[i] += entry.operations;
+        }
+        return this;
+    }
+
+    /**
+     * Add given values with an existing row, or create a new row if
+     * {@link #findIndex(String, int, int, int, int, int, int)} is unable to find match. Can
+     * also be used to subtract values from existing rows.
+     *
+     * @param entry the {@link Entry} to add.
+     * @return a new constructed {@link NetworkStats} object that contains the result.
+     */
+    public @NonNull NetworkStats addEntry(@NonNull Entry entry) {
+        return this.clone().combineValues(entry);
+    }
+
+    /**
+     * Add the given {@link NetworkStats} objects.
+     *
+     * @return the sum of two objects.
+     */
+    public @NonNull NetworkStats add(@NonNull NetworkStats another) {
+        final NetworkStats ret = this.clone();
+        ret.combineAllValues(another);
+        return ret;
+    }
+
+    /**
+     * Combine all values from another {@link NetworkStats} into this object.
+     * @hide
+     */
+    public void combineAllValues(@NonNull NetworkStats another) {
+        NetworkStats.Entry entry = null;
+        for (int i = 0; i < another.size; i++) {
+            entry = another.getValues(i, entry);
+            combineValues(entry);
+        }
+    }
+
+    /**
+     * Find first stats index that matches the requested parameters.
+     * @hide
+     */
+    public int findIndex(String iface, int uid, int set, int tag, int metered, int roaming,
+            int defaultNetwork) {
+        for (int i = 0; i < size; i++) {
+            if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
+                    && metered == this.metered[i] && roaming == this.roaming[i]
+                    && defaultNetwork == this.defaultNetwork[i]
+                    && Objects.equals(iface, this.iface[i])) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Find first stats index that matches the requested parameters, starting
+     * search around the hinted index as an optimization.
+     * @hide
+     */
+    @VisibleForTesting
+    public int findIndexHinted(String iface, int uid, int set, int tag, int metered, int roaming,
+            int defaultNetwork, int hintIndex) {
+        for (int offset = 0; offset < size; offset++) {
+            final int halfOffset = offset / 2;
+
+            // search outwards from hint index, alternating forward and backward
+            final int i;
+            if (offset % 2 == 0) {
+                i = (hintIndex + halfOffset) % size;
+            } else {
+                i = (size + hintIndex - halfOffset - 1) % size;
+            }
+
+            if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
+                    && metered == this.metered[i] && roaming == this.roaming[i]
+                    && defaultNetwork == this.defaultNetwork[i]
+                    && Objects.equals(iface, this.iface[i])) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Splice in {@link #operations} from the given {@link NetworkStats} based
+     * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface},
+     * since operation counts are at data layer.
+     * @hide
+     */
+    public void spliceOperationsFrom(NetworkStats stats) {
+        for (int i = 0; i < size; i++) {
+            final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], metered[i], roaming[i],
+                    defaultNetwork[i]);
+            if (j == -1) {
+                operations[i] = 0;
+            } else {
+                operations[i] = stats.operations[j];
+            }
+        }
+    }
+
+    /**
+     * Return list of unique interfaces known by this data structure.
+     * @hide
+     */
+    public String[] getUniqueIfaces() {
+        final HashSet<String> ifaces = new HashSet<String>();
+        for (String iface : this.iface) {
+            if (iface != IFACE_ALL) {
+                ifaces.add(iface);
+            }
+        }
+        return ifaces.toArray(new String[ifaces.size()]);
+    }
+
+    /**
+     * Return list of unique UIDs known by this data structure.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public int[] getUniqueUids() {
+        final SparseBooleanArray uids = new SparseBooleanArray();
+        for (int uid : this.uid) {
+            uids.put(uid, true);
+        }
+
+        final int size = uids.size();
+        final int[] result = new int[size];
+        for (int i = 0; i < size; i++) {
+            result[i] = uids.keyAt(i);
+        }
+        return result;
+    }
+
+    /**
+     * Return total bytes represented by this snapshot object, usually used when
+     * checking if a {@link #subtract(NetworkStats)} delta passes a threshold.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public long getTotalBytes() {
+        final Entry entry = getTotal(null);
+        return entry.rxBytes + entry.txBytes;
+    }
+
+    /**
+     * Return total of all fields represented by this snapshot object.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public Entry getTotal(Entry recycle) {
+        return getTotal(recycle, null, UID_ALL, false);
+    }
+
+    /**
+     * Return total of all fields represented by this snapshot object matching
+     * the requested {@link #uid}.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public Entry getTotal(Entry recycle, int limitUid) {
+        return getTotal(recycle, null, limitUid, false);
+    }
+
+    /**
+     * Return total of all fields represented by this snapshot object matching
+     * the requested {@link #iface}.
+     * @hide
+     */
+    public Entry getTotal(Entry recycle, HashSet<String> limitIface) {
+        return getTotal(recycle, limitIface, UID_ALL, false);
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public Entry getTotalIncludingTags(Entry recycle) {
+        return getTotal(recycle, null, UID_ALL, true);
+    }
+
+    /**
+     * Return total of all fields represented by this snapshot object matching
+     * the requested {@link #iface} and {@link #uid}.
+     *
+     * @param limitIface Set of {@link #iface} to include in total; or {@code
+     *            null} to include all ifaces.
+     */
+    private Entry getTotal(
+            Entry recycle, HashSet<String> limitIface, int limitUid, boolean includeTags) {
+        final Entry entry = recycle != null ? recycle : new Entry();
+
+        entry.iface = IFACE_ALL;
+        entry.uid = limitUid;
+        entry.set = SET_ALL;
+        entry.tag = TAG_NONE;
+        entry.metered = METERED_ALL;
+        entry.roaming = ROAMING_ALL;
+        entry.defaultNetwork = DEFAULT_NETWORK_ALL;
+        entry.rxBytes = 0;
+        entry.rxPackets = 0;
+        entry.txBytes = 0;
+        entry.txPackets = 0;
+        entry.operations = 0;
+
+        for (int i = 0; i < size; i++) {
+            final boolean matchesUid = (limitUid == UID_ALL) || (limitUid == uid[i]);
+            final boolean matchesIface = (limitIface == null) || (limitIface.contains(iface[i]));
+
+            if (matchesUid && matchesIface) {
+                // skip specific tags, since already counted in TAG_NONE
+                if (tag[i] != TAG_NONE && !includeTags) continue;
+
+                entry.rxBytes += rxBytes[i];
+                entry.rxPackets += rxPackets[i];
+                entry.txBytes += txBytes[i];
+                entry.txPackets += txPackets[i];
+                entry.operations += operations[i];
+            }
+        }
+        return entry;
+    }
+
+    /**
+     * Fast path for battery stats.
+     * @hide
+     */
+    public long getTotalPackets() {
+        long total = 0;
+        for (int i = size-1; i >= 0; i--) {
+            total += rxPackets[i] + txPackets[i];
+        }
+        return total;
+    }
+
+    /**
+     * Subtract the given {@link NetworkStats}, effectively leaving the delta
+     * between two snapshots in time. Assumes that statistics rows collect over
+     * time, and that none of them have disappeared. This method does not mutate
+     * the referencing object.
+     *
+     * @return the delta between two objects.
+     */
+    public @NonNull NetworkStats subtract(@NonNull NetworkStats right) {
+        return subtract(this, right, null, null);
+    }
+
+    /**
+     * Subtract the two given {@link NetworkStats} objects, returning the delta
+     * between two snapshots in time. Assumes that statistics rows collect over
+     * time, and that none of them have disappeared.
+     * <p>
+     * If counters have rolled backwards, they are clamped to {@code 0} and
+     * reported to the given {@link NonMonotonicObserver}.
+     * @hide
+     */
+    public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
+            NonMonotonicObserver<C> observer, C cookie) {
+        return subtract(left, right, observer, cookie, null);
+    }
+
+    /**
+     * Subtract the two given {@link NetworkStats} objects, returning the delta
+     * between two snapshots in time. Assumes that statistics rows collect over
+     * time, and that none of them have disappeared.
+     * <p>
+     * If counters have rolled backwards, they are clamped to {@code 0} and
+     * reported to the given {@link NonMonotonicObserver}.
+     * <p>
+     * If <var>recycle</var> is supplied, this NetworkStats object will be
+     * reused (and returned) as the result if it is large enough to contain
+     * the data.
+     * @hide
+     */
+    public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
+            NonMonotonicObserver<C> observer, C cookie, NetworkStats recycle) {
+        long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime;
+        if (deltaRealtime < 0) {
+            if (observer != null) {
+                observer.foundNonMonotonic(left, -1, right, -1, cookie);
+            }
+            deltaRealtime = 0;
+        }
+
+        // result will have our rows, and elapsed time between snapshots
+        final Entry entry = new Entry();
+        final NetworkStats result;
+        if (recycle != null && recycle.capacity >= left.size) {
+            result = recycle;
+            result.size = 0;
+            result.elapsedRealtime = deltaRealtime;
+        } else {
+            result = new NetworkStats(deltaRealtime, left.size);
+        }
+        for (int i = 0; i < left.size; i++) {
+            entry.iface = left.iface[i];
+            entry.uid = left.uid[i];
+            entry.set = left.set[i];
+            entry.tag = left.tag[i];
+            entry.metered = left.metered[i];
+            entry.roaming = left.roaming[i];
+            entry.defaultNetwork = left.defaultNetwork[i];
+            entry.rxBytes = left.rxBytes[i];
+            entry.rxPackets = left.rxPackets[i];
+            entry.txBytes = left.txBytes[i];
+            entry.txPackets = left.txPackets[i];
+            entry.operations = left.operations[i];
+
+            // find remote row that matches, and subtract
+            final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag,
+                    entry.metered, entry.roaming, entry.defaultNetwork, i);
+            if (j != -1) {
+                // Found matching row, subtract remote value.
+                entry.rxBytes -= right.rxBytes[j];
+                entry.rxPackets -= right.rxPackets[j];
+                entry.txBytes -= right.txBytes[j];
+                entry.txPackets -= right.txPackets[j];
+                entry.operations -= right.operations[j];
+            }
+
+            if (entry.isNegative()) {
+                if (observer != null) {
+                    observer.foundNonMonotonic(left, i, right, j, cookie);
+                }
+                entry.rxBytes = Math.max(entry.rxBytes, 0);
+                entry.rxPackets = Math.max(entry.rxPackets, 0);
+                entry.txBytes = Math.max(entry.txBytes, 0);
+                entry.txPackets = Math.max(entry.txPackets, 0);
+                entry.operations = Math.max(entry.operations, 0);
+            }
+
+            result.insertEntry(entry);
+        }
+
+        return result;
+    }
+
+    /**
+     * Calculate and apply adjustments to captured statistics for 464xlat traffic.
+     *
+     * <p>This mutates stacked traffic stats, to account for IPv4/IPv6 header size difference.
+     *
+     * <p>UID stats, which are only accounted on the stacked interface, need to be increased
+     * by 20 bytes/packet to account for translation overhead.
+     *
+     * <p>The potential additional overhead of 8 bytes/packet for ip fragments is ignored.
+     *
+     * <p>Interface stats need to sum traffic on both stacked and base interface because:
+     *   - eBPF offloaded packets appear only on the stacked interface
+     *   - Non-offloaded ingress packets appear only on the stacked interface
+     *     (due to iptables raw PREROUTING drop rules)
+     *   - Non-offloaded egress packets appear only on the stacked interface
+     *     (due to ignoring traffic from clat daemon by uid match)
+     * (and of course the 20 bytes/packet overhead needs to be applied to stacked interface stats)
+     *
+     * <p>This method will behave fine if {@code stackedIfaces} is an non-synchronized but add-only
+     * {@code ConcurrentHashMap}
+     * @param baseTraffic Traffic on the base interfaces. Will be mutated.
+     * @param stackedTraffic Stats with traffic stacked on top of our ifaces. Will also be mutated.
+     * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both.
+     * @hide
+     */
+    public static void apply464xlatAdjustments(NetworkStats baseTraffic,
+            NetworkStats stackedTraffic, Map<String, String> stackedIfaces) {
+        // For recycling
+        Entry entry = null;
+        for (int i = 0; i < stackedTraffic.size; i++) {
+            entry = stackedTraffic.getValues(i, entry);
+            if (entry == null) continue;
+            if (entry.iface == null) continue;
+            if (!entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) continue;
+
+            // For 464xlat traffic, per uid stats only counts the bytes of the native IPv4 packet
+            // sent on the stacked interface with prefix "v4-" and drops the IPv6 header size after
+            // unwrapping. To account correctly for on-the-wire traffic, add the 20 additional bytes
+            // difference for all packets (http://b/12249687, http:/b/33681750).
+            //
+            // Note: this doesn't account for LRO/GRO/GSO/TSO (ie. >mtu) traffic correctly, nor
+            // does it correctly account for the 8 extra bytes in the IPv6 fragmentation header.
+            //
+            // While the ebpf code path does try to simulate proper post segmentation packet
+            // counts, we have nothing of the sort of xt_qtaguid stats.
+            entry.rxBytes += entry.rxPackets * IPV4V6_HEADER_DELTA;
+            entry.txBytes += entry.txPackets * IPV4V6_HEADER_DELTA;
+            stackedTraffic.setValues(i, entry);
+        }
+    }
+
+    /**
+     * Calculate and apply adjustments to captured statistics for 464xlat traffic counted twice.
+     *
+     * <p>This mutates the object this method is called on. Equivalent to calling
+     * {@link #apply464xlatAdjustments(NetworkStats, NetworkStats, Map)} with {@code this} as
+     * base and stacked traffic.
+     * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both.
+     * @hide
+     */
+    public void apply464xlatAdjustments(Map<String, String> stackedIfaces) {
+        apply464xlatAdjustments(this, this, stackedIfaces);
+    }
+
+    /**
+     * Return total statistics grouped by {@link #iface}; doesn't mutate the
+     * original structure.
+     * @hide
+     */
+    public NetworkStats groupedByIface() {
+        final NetworkStats stats = new NetworkStats(elapsedRealtime, 10);
+
+        final Entry entry = new Entry();
+        entry.uid = UID_ALL;
+        entry.set = SET_ALL;
+        entry.tag = TAG_NONE;
+        entry.metered = METERED_ALL;
+        entry.roaming = ROAMING_ALL;
+        entry.defaultNetwork = DEFAULT_NETWORK_ALL;
+        entry.operations = 0L;
+
+        for (int i = 0; i < size; i++) {
+            // skip specific tags, since already counted in TAG_NONE
+            if (tag[i] != TAG_NONE) continue;
+
+            entry.iface = iface[i];
+            entry.rxBytes = rxBytes[i];
+            entry.rxPackets = rxPackets[i];
+            entry.txBytes = txBytes[i];
+            entry.txPackets = txPackets[i];
+            stats.combineValues(entry);
+        }
+
+        return stats;
+    }
+
+    /**
+     * Return total statistics grouped by {@link #uid}; doesn't mutate the
+     * original structure.
+     * @hide
+     */
+    public NetworkStats groupedByUid() {
+        final NetworkStats stats = new NetworkStats(elapsedRealtime, 10);
+
+        final Entry entry = new Entry();
+        entry.iface = IFACE_ALL;
+        entry.set = SET_ALL;
+        entry.tag = TAG_NONE;
+        entry.metered = METERED_ALL;
+        entry.roaming = ROAMING_ALL;
+        entry.defaultNetwork = DEFAULT_NETWORK_ALL;
+
+        for (int i = 0; i < size; i++) {
+            // skip specific tags, since already counted in TAG_NONE
+            if (tag[i] != TAG_NONE) continue;
+
+            entry.uid = uid[i];
+            entry.rxBytes = rxBytes[i];
+            entry.rxPackets = rxPackets[i];
+            entry.txBytes = txBytes[i];
+            entry.txPackets = txPackets[i];
+            entry.operations = operations[i];
+            stats.combineValues(entry);
+        }
+
+        return stats;
+    }
+
+    /**
+     * Remove all rows that match one of specified UIDs.
+     * This mutates the original structure in place.
+     * @hide
+     */
+    public void removeUids(int[] uids) {
+        filter(e -> !CollectionUtils.contains(uids, e.uid));
+    }
+
+    /**
+     * Remove all rows that match one of specified UIDs.
+     * @return the result object.
+     * @hide
+     */
+    @NonNull
+    public NetworkStats removeEmptyEntries() {
+        final NetworkStats ret = this.clone();
+        ret.filter(e -> e.rxBytes != 0 || e.rxPackets != 0 || e.txBytes != 0 || e.txPackets != 0
+                || e.operations != 0);
+        return ret;
+    }
+
+    /**
+     * Only keep entries that match all specified filters.
+     *
+     * <p>This mutates the original structure in place. After this method is called,
+     * size is the number of matching entries, and capacity is the previous capacity.
+     * @param limitUid UID to filter for, or {@link #UID_ALL}.
+     * @param limitIfaces Interfaces to filter for, or {@link #INTERFACES_ALL}.
+     * @param limitTag Tag to filter for, or {@link #TAG_ALL}.
+     * @hide
+     */
+    public void filter(int limitUid, String[] limitIfaces, int limitTag) {
+        if (limitUid == UID_ALL && limitTag == TAG_ALL && limitIfaces == INTERFACES_ALL) {
+            return;
+        }
+        filter(e -> (limitUid == UID_ALL || limitUid == e.uid)
+                && (limitTag == TAG_ALL || limitTag == e.tag)
+                && (limitIfaces == INTERFACES_ALL
+                    || CollectionUtils.contains(limitIfaces, e.iface)));
+    }
+
+    /**
+     * Only keep entries with {@link #set} value less than {@link #SET_DEBUG_START}.
+     *
+     * <p>This mutates the original structure in place.
+     * @hide
+     */
+    public void filterDebugEntries() {
+        filter(e -> e.set < SET_DEBUG_START);
+    }
+
+    private void filter(Predicate<Entry> predicate) {
+        Entry entry = new Entry();
+        int nextOutputEntry = 0;
+        for (int i = 0; i < size; i++) {
+            entry = getValues(i, entry);
+            if (predicate.test(entry)) {
+                if (nextOutputEntry != i) {
+                    setValues(nextOutputEntry, entry);
+                }
+                nextOutputEntry++;
+            }
+        }
+        size = nextOutputEntry;
+    }
+
+    /** @hide */
+    public void dump(String prefix, PrintWriter pw) {
+        pw.print(prefix);
+        pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime);
+        for (int i = 0; i < size; i++) {
+            pw.print(prefix);
+            pw.print("  ["); pw.print(i); pw.print("]");
+            pw.print(" iface="); pw.print(iface[i]);
+            pw.print(" uid="); pw.print(uid[i]);
+            pw.print(" set="); pw.print(setToString(set[i]));
+            pw.print(" tag="); pw.print(tagToString(tag[i]));
+            pw.print(" metered="); pw.print(meteredToString(metered[i]));
+            pw.print(" roaming="); pw.print(roamingToString(roaming[i]));
+            pw.print(" defaultNetwork="); pw.print(defaultNetworkToString(defaultNetwork[i]));
+            pw.print(" rxBytes="); pw.print(rxBytes[i]);
+            pw.print(" rxPackets="); pw.print(rxPackets[i]);
+            pw.print(" txBytes="); pw.print(txBytes[i]);
+            pw.print(" txPackets="); pw.print(txPackets[i]);
+            pw.print(" operations="); pw.println(operations[i]);
+        }
+    }
+
+    /**
+     * Return text description of {@link #set} value.
+     * @hide
+     */
+    public static String setToString(int set) {
+        switch (set) {
+            case SET_ALL:
+                return "ALL";
+            case SET_DEFAULT:
+                return "DEFAULT";
+            case SET_FOREGROUND:
+                return "FOREGROUND";
+            case SET_DBG_VPN_IN:
+                return "DBG_VPN_IN";
+            case SET_DBG_VPN_OUT:
+                return "DBG_VPN_OUT";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    /**
+     * Return text description of {@link #set} value.
+     * @hide
+     */
+    public static String setToCheckinString(int set) {
+        switch (set) {
+            case SET_ALL:
+                return "all";
+            case SET_DEFAULT:
+                return "def";
+            case SET_FOREGROUND:
+                return "fg";
+            case SET_DBG_VPN_IN:
+                return "vpnin";
+            case SET_DBG_VPN_OUT:
+                return "vpnout";
+            default:
+                return "unk";
+        }
+    }
+
+    /**
+     * @return true if the querySet matches the dataSet.
+     * @hide
+     */
+    public static boolean setMatches(int querySet, int dataSet) {
+        if (querySet == dataSet) {
+            return true;
+        }
+        // SET_ALL matches all non-debugging sets.
+        return querySet == SET_ALL && dataSet < SET_DEBUG_START;
+    }
+
+    /**
+     * Return text description of {@link #tag} value.
+     * @hide
+     */
+    public static String tagToString(int tag) {
+        return "0x" + Integer.toHexString(tag);
+    }
+
+    /**
+     * Return text description of {@link #metered} value.
+     * @hide
+     */
+    public static String meteredToString(int metered) {
+        switch (metered) {
+            case METERED_ALL:
+                return "ALL";
+            case METERED_NO:
+                return "NO";
+            case METERED_YES:
+                return "YES";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    /**
+     * Return text description of {@link #roaming} value.
+     * @hide
+     */
+    public static String roamingToString(int roaming) {
+        switch (roaming) {
+            case ROAMING_ALL:
+                return "ALL";
+            case ROAMING_NO:
+                return "NO";
+            case ROAMING_YES:
+                return "YES";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    /**
+     * Return text description of {@link #defaultNetwork} value.
+     * @hide
+     */
+    public static String defaultNetworkToString(int defaultNetwork) {
+        switch (defaultNetwork) {
+            case DEFAULT_NETWORK_ALL:
+                return "ALL";
+            case DEFAULT_NETWORK_NO:
+                return "NO";
+            case DEFAULT_NETWORK_YES:
+                return "YES";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    /** @hide */
+    @Override
+    public String toString() {
+        final CharArrayWriter writer = new CharArrayWriter();
+        dump("", new PrintWriter(writer));
+        return writer.toString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() {
+        @Override
+        public NetworkStats createFromParcel(Parcel in) {
+            return new NetworkStats(in);
+        }
+
+        @Override
+        public NetworkStats[] newArray(int size) {
+            return new NetworkStats[size];
+        }
+    };
+
+    /** @hide */
+    public interface NonMonotonicObserver<C> {
+        public void foundNonMonotonic(
+                NetworkStats left, int leftIndex, NetworkStats right, int rightIndex, C cookie);
+        public void foundNonMonotonic(
+                NetworkStats stats, int statsIndex, C cookie);
+    }
+
+    /**
+     * VPN accounting. Move some VPN's underlying traffic to other UIDs that use tun0 iface.
+     *
+     * <p>This method should only be called on delta NetworkStats. Do not call this method on a
+     * snapshot {@link NetworkStats} object because the tunUid and/or the underlyingIface may change
+     * over time.
+     *
+     * <p>This method performs adjustments for one active VPN package and one VPN iface at a time.
+     *
+     * @param tunUid uid of the VPN application
+     * @param tunIface iface of the vpn tunnel
+     * @param underlyingIfaces underlying network ifaces used by the VPN application
+     * @hide
+     */
+    public void migrateTun(int tunUid, @NonNull String tunIface,
+            @NonNull List<String> underlyingIfaces) {
+        // Combined usage by all apps using VPN.
+        final Entry tunIfaceTotal = new Entry();
+        // Usage by VPN, grouped by its {@code underlyingIfaces}.
+        final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.size()];
+        // Usage by VPN, summed across all its {@code underlyingIfaces}.
+        final Entry underlyingIfacesTotal = new Entry();
+
+        for (int i = 0; i < perInterfaceTotal.length; i++) {
+            perInterfaceTotal[i] = new Entry();
+        }
+
+        tunAdjustmentInit(tunUid, tunIface, underlyingIfaces, tunIfaceTotal, perInterfaceTotal,
+                underlyingIfacesTotal);
+
+        // If tunIface < underlyingIfacesTotal, it leaves the overhead traffic in the VPN app.
+        // If tunIface > underlyingIfacesTotal, the VPN app doesn't get credit for data compression.
+        // Negative stats should be avoided.
+        final Entry[] moved =
+                addTrafficToApplications(tunUid, tunIface, underlyingIfaces, tunIfaceTotal,
+                        perInterfaceTotal, underlyingIfacesTotal);
+        deductTrafficFromVpnApp(tunUid, underlyingIfaces, moved);
+    }
+
+    /**
+     * Initializes the data used by the migrateTun() method.
+     *
+     * <p>This is the first pass iteration which does the following work:
+     *
+     * <ul>
+     *   <li>Adds up all the traffic through the tunUid's underlyingIfaces (both foreground and
+     *       background).
+     *   <li>Adds up all the traffic through tun0 excluding traffic from the vpn app itself.
+     * </ul>
+     *
+     * @param tunUid uid of the VPN application
+     * @param tunIface iface of the vpn tunnel
+     * @param underlyingIfaces underlying network ifaces used by the VPN application
+     * @param tunIfaceTotal output parameter; combined data usage by all apps using VPN
+     * @param perInterfaceTotal output parameter; data usage by VPN app, grouped by its {@code
+     *     underlyingIfaces}
+     * @param underlyingIfacesTotal output parameter; data usage by VPN, summed across all of its
+     *     {@code underlyingIfaces}
+     */
+    private void tunAdjustmentInit(int tunUid, @NonNull String tunIface,
+            @NonNull List<String> underlyingIfaces, @NonNull Entry tunIfaceTotal,
+            @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
+        final Entry recycle = new Entry();
+        for (int i = 0; i < size; i++) {
+            getValues(i, recycle);
+            if (recycle.uid == UID_ALL) {
+                throw new IllegalStateException(
+                        "Cannot adjust VPN accounting on an iface aggregated NetworkStats.");
+            }
+            if (recycle.set == SET_DBG_VPN_IN || recycle.set == SET_DBG_VPN_OUT) {
+                throw new IllegalStateException(
+                        "Cannot adjust VPN accounting on a NetworkStats containing SET_DBG_VPN_*");
+            }
+            if (recycle.tag != TAG_NONE) {
+                // TODO(b/123666283): Take all tags for tunUid into account.
+                continue;
+            }
+
+            if (tunUid == Process.SYSTEM_UID) {
+                // Kernel-based VPN or VCN, traffic sent by apps on the VPN/VCN network
+                //
+                // Since the data is not UID-accounted on underlying networks, just use VPN/VCN
+                // network usage as ground truth. Encrypted traffic on the underlying networks will
+                // never be processed here because encrypted traffic on the underlying interfaces
+                // is not present in UID stats, and this method is only called on UID stats.
+                if (tunIface.equals(recycle.iface)) {
+                    tunIfaceTotal.add(recycle);
+                    underlyingIfacesTotal.add(recycle);
+
+                    // In steady state, there should always be one network, but edge cases may
+                    // result in the network being null (network lost), and thus no underlying
+                    // ifaces is possible.
+                    if (perInterfaceTotal.length > 0) {
+                        // While platform VPNs and VCNs have exactly one underlying network, that
+                        // network may have multiple interfaces (eg for 464xlat). This layer does
+                        // not have the required information to identify which of the interfaces
+                        // were used. Select "any" of the interfaces. Since overhead is already
+                        // lost, this number is an approximation anyways.
+                        perInterfaceTotal[0].add(recycle);
+                    }
+                }
+            } else if (recycle.uid == tunUid) {
+                // VpnService VPN, traffic sent by the VPN app over underlying networks
+                for (int j = 0; j < underlyingIfaces.size(); j++) {
+                    if (Objects.equals(underlyingIfaces.get(j), recycle.iface)) {
+                        perInterfaceTotal[j].add(recycle);
+                        underlyingIfacesTotal.add(recycle);
+                        break;
+                    }
+                }
+            } else if (tunIface.equals(recycle.iface)) {
+                // VpnService VPN; traffic sent by apps on the VPN network
+                tunIfaceTotal.add(recycle);
+            }
+        }
+    }
+
+    /**
+     * Distributes traffic across apps that are using given {@code tunIface}, and returns the total
+     * traffic that should be moved off of {@code tunUid} grouped by {@code underlyingIfaces}.
+     *
+     * @param tunUid uid of the VPN application
+     * @param tunIface iface of the vpn tunnel
+     * @param underlyingIfaces underlying network ifaces used by the VPN application
+     * @param tunIfaceTotal combined data usage across all apps using {@code tunIface}
+     * @param perInterfaceTotal data usage by VPN app, grouped by its {@code underlyingIfaces}
+     * @param underlyingIfacesTotal data usage by VPN, summed across all of its {@code
+     *     underlyingIfaces}
+     */
+    private Entry[] addTrafficToApplications(int tunUid, @NonNull String tunIface,
+            @NonNull List<String> underlyingIfaces, @NonNull Entry tunIfaceTotal,
+            @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
+        // Traffic that should be moved off of each underlying interface for tunUid (see
+        // deductTrafficFromVpnApp below).
+        final Entry[] moved = new Entry[underlyingIfaces.size()];
+        for (int i = 0; i < underlyingIfaces.size(); i++) {
+            moved[i] = new Entry();
+        }
+
+        final Entry tmpEntry = new Entry();
+        final int origSize = size;
+        for (int i = 0; i < origSize; i++) {
+            if (!Objects.equals(iface[i], tunIface)) {
+                // Consider only entries that go onto the VPN interface.
+                continue;
+            }
+
+            if (uid[i] == tunUid && tunUid != Process.SYSTEM_UID) {
+                // Exclude VPN app from the redistribution, as it can choose to create packet
+                // streams by writing to itself.
+                //
+                // However, for platform VPNs, do not exclude the system's usage of the VPN network,
+                // since it is never local-only, and never double counted
+                continue;
+            }
+            tmpEntry.uid = uid[i];
+            tmpEntry.tag = tag[i];
+            tmpEntry.metered = metered[i];
+            tmpEntry.roaming = roaming[i];
+            tmpEntry.defaultNetwork = defaultNetwork[i];
+
+            // In a first pass, compute this entry's total share of data across all
+            // underlyingIfaces. This is computed on the basis of the share of this entry's usage
+            // over tunIface.
+            // TODO: Consider refactoring first pass into a separate helper method.
+            long totalRxBytes = 0;
+            if (tunIfaceTotal.rxBytes > 0) {
+                // Note - The multiplication below should not overflow since NetworkStatsService
+                // processes this every time device has transmitted/received amount equivalent to
+                // global threshold alert (~ 2MB) across all interfaces.
+                final long rxBytesAcrossUnderlyingIfaces =
+                        multiplySafeByRational(underlyingIfacesTotal.rxBytes,
+                                rxBytes[i], tunIfaceTotal.rxBytes);
+                // app must not be blamed for more than it consumed on tunIface
+                totalRxBytes = Math.min(rxBytes[i], rxBytesAcrossUnderlyingIfaces);
+            }
+            long totalRxPackets = 0;
+            if (tunIfaceTotal.rxPackets > 0) {
+                final long rxPacketsAcrossUnderlyingIfaces =
+                        multiplySafeByRational(underlyingIfacesTotal.rxPackets,
+                                rxPackets[i], tunIfaceTotal.rxPackets);
+                totalRxPackets = Math.min(rxPackets[i], rxPacketsAcrossUnderlyingIfaces);
+            }
+            long totalTxBytes = 0;
+            if (tunIfaceTotal.txBytes > 0) {
+                final long txBytesAcrossUnderlyingIfaces =
+                        multiplySafeByRational(underlyingIfacesTotal.txBytes,
+                                txBytes[i], tunIfaceTotal.txBytes);
+                totalTxBytes = Math.min(txBytes[i], txBytesAcrossUnderlyingIfaces);
+            }
+            long totalTxPackets = 0;
+            if (tunIfaceTotal.txPackets > 0) {
+                final long txPacketsAcrossUnderlyingIfaces =
+                        multiplySafeByRational(underlyingIfacesTotal.txPackets,
+                                txPackets[i], tunIfaceTotal.txPackets);
+                totalTxPackets = Math.min(txPackets[i], txPacketsAcrossUnderlyingIfaces);
+            }
+            long totalOperations = 0;
+            if (tunIfaceTotal.operations > 0) {
+                final long operationsAcrossUnderlyingIfaces =
+                        multiplySafeByRational(underlyingIfacesTotal.operations,
+                                operations[i], tunIfaceTotal.operations);
+                totalOperations = Math.min(operations[i], operationsAcrossUnderlyingIfaces);
+            }
+            // In a second pass, distribute these values across interfaces in the proportion that
+            // each interface represents of the total traffic of the underlying interfaces.
+            for (int j = 0; j < underlyingIfaces.size(); j++) {
+                tmpEntry.iface = underlyingIfaces.get(j);
+                tmpEntry.rxBytes = 0;
+                // Reset 'set' to correct value since it gets updated when adding debug info below.
+                tmpEntry.set = set[i];
+                if (underlyingIfacesTotal.rxBytes > 0) {
+                    tmpEntry.rxBytes =
+                            multiplySafeByRational(totalRxBytes,
+                                    perInterfaceTotal[j].rxBytes,
+                                    underlyingIfacesTotal.rxBytes);
+                }
+                tmpEntry.rxPackets = 0;
+                if (underlyingIfacesTotal.rxPackets > 0) {
+                    tmpEntry.rxPackets =
+                            multiplySafeByRational(totalRxPackets,
+                                    perInterfaceTotal[j].rxPackets,
+                                    underlyingIfacesTotal.rxPackets);
+                }
+                tmpEntry.txBytes = 0;
+                if (underlyingIfacesTotal.txBytes > 0) {
+                    tmpEntry.txBytes =
+                            multiplySafeByRational(totalTxBytes,
+                                    perInterfaceTotal[j].txBytes,
+                                    underlyingIfacesTotal.txBytes);
+                }
+                tmpEntry.txPackets = 0;
+                if (underlyingIfacesTotal.txPackets > 0) {
+                    tmpEntry.txPackets =
+                            multiplySafeByRational(totalTxPackets,
+                                    perInterfaceTotal[j].txPackets,
+                                    underlyingIfacesTotal.txPackets);
+                }
+                tmpEntry.operations = 0;
+                if (underlyingIfacesTotal.operations > 0) {
+                    tmpEntry.operations =
+                            multiplySafeByRational(totalOperations,
+                                    perInterfaceTotal[j].operations,
+                                    underlyingIfacesTotal.operations);
+                }
+                // tmpEntry now contains the migrated data of the i-th entry for the j-th underlying
+                // interface. Add that data usage to this object.
+                combineValues(tmpEntry);
+                if (tag[i] == TAG_NONE) {
+                    // Add the migrated data to moved so it is deducted from the VPN app later.
+                    moved[j].add(tmpEntry);
+                    // Add debug info
+                    tmpEntry.set = SET_DBG_VPN_IN;
+                    combineValues(tmpEntry);
+                }
+            }
+        }
+        return moved;
+    }
+
+    private void deductTrafficFromVpnApp(
+            int tunUid,
+            @NonNull List<String> underlyingIfaces,
+            @NonNull Entry[] moved) {
+        if (tunUid == Process.SYSTEM_UID) {
+            // No traffic recorded on a per-UID basis for in-kernel VPN/VCNs over underlying
+            // networks; thus no traffic to deduct.
+            return;
+        }
+
+        for (int i = 0; i < underlyingIfaces.size(); i++) {
+            moved[i].uid = tunUid;
+            // Add debug info
+            moved[i].set = SET_DBG_VPN_OUT;
+            moved[i].tag = TAG_NONE;
+            moved[i].iface = underlyingIfaces.get(i);
+            moved[i].metered = METERED_ALL;
+            moved[i].roaming = ROAMING_ALL;
+            moved[i].defaultNetwork = DEFAULT_NETWORK_ALL;
+            combineValues(moved[i]);
+
+            // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
+            // the TAG_NONE traffic.
+            //
+            // Relies on the fact that the underlying traffic only has state ROAMING_NO and
+            // METERED_NO, which should be the case as it comes directly from the /proc file.
+            // We only blend in the roaming data after applying these adjustments, by checking the
+            // NetworkIdentity of the underlying iface.
+            final int idxVpnBackground = findIndex(underlyingIfaces.get(i), tunUid, SET_DEFAULT,
+                            TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
+            if (idxVpnBackground != -1) {
+                // Note - tunSubtract also updates moved[i]; whatever traffic that's left is removed
+                // from foreground usage.
+                tunSubtract(idxVpnBackground, this, moved[i]);
+            }
+
+            final int idxVpnForeground = findIndex(underlyingIfaces.get(i), tunUid, SET_FOREGROUND,
+                            TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
+            if (idxVpnForeground != -1) {
+                tunSubtract(idxVpnForeground, this, moved[i]);
+            }
+        }
+    }
+
+    private static void tunSubtract(int i, @NonNull NetworkStats left, @NonNull Entry right) {
+        long rxBytes = Math.min(left.rxBytes[i], right.rxBytes);
+        left.rxBytes[i] -= rxBytes;
+        right.rxBytes -= rxBytes;
+
+        long rxPackets = Math.min(left.rxPackets[i], right.rxPackets);
+        left.rxPackets[i] -= rxPackets;
+        right.rxPackets -= rxPackets;
+
+        long txBytes = Math.min(left.txBytes[i], right.txBytes);
+        left.txBytes[i] -= txBytes;
+        right.txBytes -= txBytes;
+
+        long txPackets = Math.min(left.txPackets[i], right.txPackets);
+        left.txPackets[i] -= txPackets;
+        right.txPackets -= txPackets;
+    }
+}
diff --git a/framework-t/src/android/net/NetworkStatsAccess.java b/framework-t/src/android/net/NetworkStatsAccess.java
new file mode 100644
index 0000000..b64fbdb
--- /dev/null
+++ b/framework-t/src/android/net/NetworkStatsAccess.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.NetworkStats.UID_ALL;
+import static android.net.TrafficStats.UID_REMOVED;
+import static android.net.TrafficStats.UID_TETHERING;
+
+import android.Manifest;
+import android.annotation.IntDef;
+import android.app.AppOpsManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Process;
+import android.os.UserHandle;
+import android.telephony.TelephonyManager;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Utility methods for controlling access to network stats APIs.
+ *
+ * @hide
+ */
+public final class NetworkStatsAccess {
+    private NetworkStatsAccess() {}
+
+    /**
+     * Represents an access level for the network usage history and statistics APIs.
+     *
+     * <p>Access levels are in increasing order; that is, it is reasonable to check access by
+     * verifying that the caller's access level is at least the minimum required level.
+     */
+    @IntDef({
+            Level.DEFAULT,
+            Level.USER,
+            Level.DEVICESUMMARY,
+            Level.DEVICE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Level {
+        /**
+         * Default, unprivileged access level.
+         *
+         * <p>Can only access usage for one's own UID.
+         *
+         * <p>Every app will have at least this access level.
+         */
+        int DEFAULT = 0;
+
+        /**
+         * Access level for apps which can access usage for any app running in the same user.
+         *
+         * <p>Granted to:
+         * <ul>
+         * <li>Profile owners.
+         * </ul>
+         */
+        int USER = 1;
+
+        /**
+         * Access level for apps which can access usage summary of device. Device summary includes
+         * usage by apps running in any profiles/users, however this access level does not
+         * allow querying usage of individual apps running in other profiles/users.
+         *
+         * <p>Granted to:
+         * <ul>
+         * <li>Apps with the PACKAGE_USAGE_STATS permission granted. Note that this is an AppOps bit
+         * so it is not necessarily sufficient to declare this in the manifest.
+         * <li>Apps with the (signature/privileged) READ_NETWORK_USAGE_HISTORY permission.
+         * </ul>
+         */
+        int DEVICESUMMARY = 2;
+
+        /**
+         * Access level for apps which can access usage for any app on the device, including apps
+         * running on other users/profiles.
+         *
+         * <p>Granted to:
+         * <ul>
+         * <li>Device owners.
+         * <li>Carrier-privileged applications.
+         * <li>The system UID.
+         * </ul>
+         */
+        int DEVICE = 3;
+    }
+
+    /** Returns the {@link NetworkStatsAccess.Level} for the given caller. */
+    public static @NetworkStatsAccess.Level int checkAccessLevel(
+            Context context, int callingPid, int callingUid, String callingPackage) {
+        final DevicePolicyManager mDpm = context.getSystemService(DevicePolicyManager.class);
+        final TelephonyManager tm = (TelephonyManager)
+                context.getSystemService(Context.TELEPHONY_SERVICE);
+        boolean hasCarrierPrivileges;
+        final long token = Binder.clearCallingIdentity();
+        try {
+            hasCarrierPrivileges = tm != null
+                    && tm.checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
+                            == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+
+        final boolean isDeviceOwner = mDpm != null && mDpm.isDeviceOwnerApp(callingPackage);
+        final int appId = UserHandle.getAppId(callingUid);
+
+        final boolean isNetworkStack = context.checkPermission(
+                android.Manifest.permission.NETWORK_STACK, callingPid, callingUid)
+                == PERMISSION_GRANTED;
+
+        if (hasCarrierPrivileges || isDeviceOwner
+                || appId == Process.SYSTEM_UID || isNetworkStack) {
+            // Carrier-privileged apps and device owners, and the system (including the
+            // network stack) can access data usage for all apps on the device.
+            return NetworkStatsAccess.Level.DEVICE;
+        }
+
+        boolean hasAppOpsPermission = hasAppOpsPermission(context, callingUid, callingPackage);
+        if (hasAppOpsPermission || context.checkCallingOrSelfPermission(
+                READ_NETWORK_USAGE_HISTORY) == PackageManager.PERMISSION_GRANTED) {
+            return NetworkStatsAccess.Level.DEVICESUMMARY;
+        }
+
+        //TODO(b/169395065) Figure out if this flow makes sense in Device Owner mode.
+        boolean isProfileOwner = mDpm != null && (mDpm.isProfileOwnerApp(callingPackage)
+                || mDpm.isDeviceOwnerApp(callingPackage));
+        if (isProfileOwner) {
+            // Apps with the AppOps permission, profile owners, and apps with the privileged
+            // permission can access data usage for all apps in this user/profile.
+            return NetworkStatsAccess.Level.USER;
+        }
+
+        // Everyone else gets default access (only to their own UID).
+        return NetworkStatsAccess.Level.DEFAULT;
+    }
+
+    /**
+     * Returns whether the given caller should be able to access the given UID when the caller has
+     * the given {@link NetworkStatsAccess.Level}.
+     */
+    public static boolean isAccessibleToUser(int uid, int callerUid,
+            @NetworkStatsAccess.Level int accessLevel) {
+        final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
+        final int callerUserId = UserHandle.getUserHandleForUid(callerUid).getIdentifier();
+        switch (accessLevel) {
+            case NetworkStatsAccess.Level.DEVICE:
+                // Device-level access - can access usage for any uid.
+                return true;
+            case NetworkStatsAccess.Level.DEVICESUMMARY:
+                // Can access usage for any app running in the same user, along
+                // with some special uids (system, removed, or tethering) and
+                // anonymized uids
+                return uid == android.os.Process.SYSTEM_UID || uid == UID_REMOVED
+                        || uid == UID_TETHERING || uid == UID_ALL
+                        || userId == callerUserId;
+            case NetworkStatsAccess.Level.USER:
+                // User-level access - can access usage for any app running in the same user, along
+                // with some special uids (system, removed, or tethering).
+                return uid == android.os.Process.SYSTEM_UID || uid == UID_REMOVED
+                        || uid == UID_TETHERING
+                        || userId == callerUserId;
+            case NetworkStatsAccess.Level.DEFAULT:
+            default:
+                // Default access level - can only access one's own usage.
+                return uid == callerUid;
+        }
+    }
+
+    private static boolean hasAppOpsPermission(
+            Context context, int callingUid, String callingPackage) {
+        if (callingPackage != null) {
+            AppOpsManager appOps = (AppOpsManager) context.getSystemService(
+                    Context.APP_OPS_SERVICE);
+
+            final int mode = appOps.noteOp(AppOpsManager.OPSTR_GET_USAGE_STATS,
+                    callingUid, callingPackage, null /* attributionTag */, null /* message */);
+            if (mode == AppOpsManager.MODE_DEFAULT) {
+                // The default behavior here is to check if PackageManager has given the app
+                // permission.
+                final int permissionCheck = context.checkCallingPermission(
+                        Manifest.permission.PACKAGE_USAGE_STATS);
+                return permissionCheck == PackageManager.PERMISSION_GRANTED;
+            }
+            return (mode == AppOpsManager.MODE_ALLOWED);
+        }
+        return false;
+    }
+}
diff --git a/framework-t/src/android/net/NetworkStatsCollection.java b/framework-t/src/android/net/NetworkStatsCollection.java
new file mode 100644
index 0000000..e385b33
--- /dev/null
+++ b/framework-t/src/android/net/NetworkStatsCollection.java
@@ -0,0 +1,956 @@
+/*
+ * 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;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
+import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
+import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.METERED_NO;
+import static android.net.NetworkStats.METERED_YES;
+import static android.net.NetworkStats.ROAMING_NO;
+import static android.net.NetworkStats.ROAMING_YES;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkStats.UID_ALL;
+import static android.net.TrafficStats.UID_REMOVED;
+import static android.text.format.DateUtils.WEEK_IN_MILLIS;
+
+import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.NetworkStats.State;
+import android.net.NetworkStatsHistory.Entry;
+import android.os.Binder;
+import android.service.NetworkStatsCollectionKeyProto;
+import android.service.NetworkStatsCollectionProto;
+import android.service.NetworkStatsCollectionStatsProto;
+import android.telephony.SubscriptionPlan;
+import android.text.format.DateUtils;
+import android.util.ArrayMap;
+import android.util.AtomicFile;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.Range;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FileRotator;
+import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.NetworkStatsUtils;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.ProtocolException;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Collection of {@link NetworkStatsHistory}, stored based on combined key of
+ * {@link NetworkIdentitySet}, UID, set, and tag. Knows how to persist itself.
+ *
+ * @hide
+ */
+@SystemApi(client = MODULE_LIBRARIES)
+public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.Writer {
+    private static final String TAG = NetworkStatsCollection.class.getSimpleName();
+    /** File header magic number: "ANET" */
+    private static final int FILE_MAGIC = 0x414E4554;
+
+    private static final int VERSION_NETWORK_INIT = 1;
+
+    private static final int VERSION_UID_INIT = 1;
+    private static final int VERSION_UID_WITH_IDENT = 2;
+    private static final int VERSION_UID_WITH_TAG = 3;
+    private static final int VERSION_UID_WITH_SET = 4;
+
+    private static final int VERSION_UNIFIED_INIT = 16;
+
+    private ArrayMap<Key, NetworkStatsHistory> mStats = new ArrayMap<>();
+
+    private final long mBucketDurationMillis;
+
+    private long mStartMillis;
+    private long mEndMillis;
+    private long mTotalBytes;
+    private boolean mDirty;
+
+    /**
+     * Construct a {@link NetworkStatsCollection} object.
+     *
+     * @param bucketDuration duration of the buckets in this object, in milliseconds.
+     * @hide
+     */
+    public NetworkStatsCollection(long bucketDurationMillis) {
+        mBucketDurationMillis = bucketDurationMillis;
+        reset();
+    }
+
+    /** @hide */
+    public void clear() {
+        reset();
+    }
+
+    /** @hide */
+    public void reset() {
+        mStats.clear();
+        mStartMillis = Long.MAX_VALUE;
+        mEndMillis = Long.MIN_VALUE;
+        mTotalBytes = 0;
+        mDirty = false;
+    }
+
+    /** @hide */
+    public long getStartMillis() {
+        return mStartMillis;
+    }
+
+    /**
+     * Return first atomic bucket in this collection, which is more conservative
+     * than {@link #mStartMillis}.
+     * @hide
+     */
+    public long getFirstAtomicBucketMillis() {
+        if (mStartMillis == Long.MAX_VALUE) {
+            return Long.MAX_VALUE;
+        } else {
+            return mStartMillis + mBucketDurationMillis;
+        }
+    }
+
+    /** @hide */
+    public long getEndMillis() {
+        return mEndMillis;
+    }
+
+    /** @hide */
+    public long getTotalBytes() {
+        return mTotalBytes;
+    }
+
+    /** @hide */
+    public boolean isDirty() {
+        return mDirty;
+    }
+
+    /** @hide */
+    public void clearDirty() {
+        mDirty = false;
+    }
+
+    /** @hide */
+    public boolean isEmpty() {
+        return mStartMillis == Long.MAX_VALUE && mEndMillis == Long.MIN_VALUE;
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public long roundUp(long time) {
+        if (time == Long.MIN_VALUE || time == Long.MAX_VALUE
+                || time == SubscriptionPlan.TIME_UNKNOWN) {
+            return time;
+        } else {
+            final long mod = time % mBucketDurationMillis;
+            if (mod > 0) {
+                time -= mod;
+                time += mBucketDurationMillis;
+            }
+            return time;
+        }
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public long roundDown(long time) {
+        if (time == Long.MIN_VALUE || time == Long.MAX_VALUE
+                || time == SubscriptionPlan.TIME_UNKNOWN) {
+            return time;
+        } else {
+            final long mod = time % mBucketDurationMillis;
+            if (mod > 0) {
+                time -= mod;
+            }
+            return time;
+        }
+    }
+
+    /** @hide */
+    public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel) {
+        return getRelevantUids(accessLevel, Binder.getCallingUid());
+    }
+
+    /** @hide */
+    public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel,
+                final int callerUid) {
+        final ArrayList<Integer> uids = new ArrayList<>();
+        for (int i = 0; i < mStats.size(); i++) {
+            final Key key = mStats.keyAt(i);
+            if (NetworkStatsAccess.isAccessibleToUser(key.uid, callerUid, accessLevel)) {
+                int j = Collections.binarySearch(uids, new Integer(key.uid));
+
+                if (j < 0) {
+                    j = ~j;
+                    uids.add(j, key.uid);
+                }
+            }
+        }
+        return CollectionUtils.toIntArray(uids);
+    }
+
+    /**
+     * Combine all {@link NetworkStatsHistory} in this collection which match
+     * the requested parameters.
+     * @hide
+     */
+    public NetworkStatsHistory getHistory(NetworkTemplate template, SubscriptionPlan augmentPlan,
+            int uid, int set, int tag, int fields, long start, long end,
+            @NetworkStatsAccess.Level int accessLevel, int callerUid) {
+        if (!NetworkStatsAccess.isAccessibleToUser(uid, callerUid, accessLevel)) {
+            throw new SecurityException("Network stats history of uid " + uid
+                    + " is forbidden for caller " + callerUid);
+        }
+
+        // 180 days of history should be enough for anyone; if we end up needing
+        // more, we'll dynamically grow the history object.
+        final int bucketEstimate = (int) NetworkStatsUtils.constrain(
+                ((end - start) / mBucketDurationMillis), 0,
+                (180 * DateUtils.DAY_IN_MILLIS) / mBucketDurationMillis);
+        final NetworkStatsHistory combined = new NetworkStatsHistory(
+                mBucketDurationMillis, bucketEstimate, fields);
+
+        // shortcut when we know stats will be empty
+        if (start == end) return combined;
+
+        // Figure out the window of time that we should be augmenting (if any)
+        long augmentStart = SubscriptionPlan.TIME_UNKNOWN;
+        long augmentEnd = (augmentPlan != null) ? augmentPlan.getDataUsageTime()
+                : SubscriptionPlan.TIME_UNKNOWN;
+        // And if augmenting, we might need to collect more data to adjust with
+        long collectStart = start;
+        long collectEnd = end;
+
+        if (augmentEnd != SubscriptionPlan.TIME_UNKNOWN) {
+            final Iterator<Range<ZonedDateTime>> it = augmentPlan.cycleIterator();
+            while (it.hasNext()) {
+                final Range<ZonedDateTime> cycle = it.next();
+                final long cycleStart = cycle.getLower().toInstant().toEpochMilli();
+                final long cycleEnd = cycle.getUpper().toInstant().toEpochMilli();
+                if (cycleStart <= augmentEnd && augmentEnd < cycleEnd) {
+                    augmentStart = cycleStart;
+                    collectStart = Long.min(collectStart, augmentStart);
+                    collectEnd = Long.max(collectEnd, augmentEnd);
+                    break;
+                }
+            }
+        }
+
+        if (augmentStart != SubscriptionPlan.TIME_UNKNOWN) {
+            // Shrink augmentation window so we don't risk undercounting.
+            augmentStart = roundUp(augmentStart);
+            augmentEnd = roundDown(augmentEnd);
+            // Grow collection window so we get all the stats needed.
+            collectStart = roundDown(collectStart);
+            collectEnd = roundUp(collectEnd);
+        }
+
+        for (int i = 0; i < mStats.size(); i++) {
+            final Key key = mStats.keyAt(i);
+            if (key.uid == uid && NetworkStats.setMatches(set, key.set) && key.tag == tag
+                    && templateMatches(template, key.ident)) {
+                final NetworkStatsHistory value = mStats.valueAt(i);
+                combined.recordHistory(value, collectStart, collectEnd);
+            }
+        }
+
+        if (augmentStart != SubscriptionPlan.TIME_UNKNOWN) {
+            final NetworkStatsHistory.Entry entry = combined.getValues(
+                    augmentStart, augmentEnd, null);
+
+            // If we don't have any recorded data for this time period, give
+            // ourselves something to scale with.
+            if (entry.rxBytes == 0 || entry.txBytes == 0) {
+                combined.recordData(augmentStart, augmentEnd,
+                        new NetworkStats.Entry(1, 0, 1, 0, 0));
+                combined.getValues(augmentStart, augmentEnd, entry);
+            }
+
+            final long rawBytes = (entry.rxBytes + entry.txBytes) == 0 ? 1 :
+                    (entry.rxBytes + entry.txBytes);
+            final long rawRxBytes = entry.rxBytes == 0 ? 1 : entry.rxBytes;
+            final long rawTxBytes = entry.txBytes == 0 ? 1 : entry.txBytes;
+            final long targetBytes = augmentPlan.getDataUsageBytes();
+
+            final long targetRxBytes = multiplySafeByRational(targetBytes, rawRxBytes, rawBytes);
+            final long targetTxBytes = multiplySafeByRational(targetBytes, rawTxBytes, rawBytes);
+
+
+            // Scale all matching buckets to reach anchor target
+            final long beforeTotal = combined.getTotalBytes();
+            for (int i = 0; i < combined.size(); i++) {
+                combined.getValues(i, entry);
+                if (entry.bucketStart >= augmentStart
+                        && entry.bucketStart + entry.bucketDuration <= augmentEnd) {
+                    entry.rxBytes = multiplySafeByRational(
+                            targetRxBytes, entry.rxBytes, rawRxBytes);
+                    entry.txBytes = multiplySafeByRational(
+                            targetTxBytes, entry.txBytes, rawTxBytes);
+                    // We purposefully clear out packet counters to indicate
+                    // that this data has been augmented.
+                    entry.rxPackets = 0;
+                    entry.txPackets = 0;
+                    combined.setValues(i, entry);
+                }
+            }
+
+            final long deltaTotal = combined.getTotalBytes() - beforeTotal;
+            if (deltaTotal != 0) {
+                Log.d(TAG, "Augmented network usage by " + deltaTotal + " bytes");
+            }
+
+            // Finally we can slice data as originally requested
+            final NetworkStatsHistory sliced = new NetworkStatsHistory(
+                    mBucketDurationMillis, bucketEstimate, fields);
+            sliced.recordHistory(combined, start, end);
+            return sliced;
+        } else {
+            return combined;
+        }
+    }
+
+    /**
+     * Summarize all {@link NetworkStatsHistory} in this collection which match
+     * the requested parameters across the requested range.
+     *
+     * @param template - a predicate for filtering netstats.
+     * @param start - start of the range, timestamp in milliseconds since the epoch.
+     * @param end - end of the range, timestamp in milliseconds since the epoch.
+     * @param accessLevel - caller access level.
+     * @param callerUid - caller UID.
+     * @hide
+     */
+    public NetworkStats getSummary(NetworkTemplate template, long start, long end,
+            @NetworkStatsAccess.Level int accessLevel, int callerUid) {
+        final long now = System.currentTimeMillis();
+
+        final NetworkStats stats = new NetworkStats(end - start, 24);
+
+        // shortcut when we know stats will be empty
+        if (start == end) return stats;
+
+        final NetworkStats.Entry entry = new NetworkStats.Entry();
+        NetworkStatsHistory.Entry historyEntry = null;
+
+        for (int i = 0; i < mStats.size(); i++) {
+            final Key key = mStats.keyAt(i);
+            if (templateMatches(template, key.ident)
+                    && NetworkStatsAccess.isAccessibleToUser(key.uid, callerUid, accessLevel)
+                    && key.set < NetworkStats.SET_DEBUG_START) {
+                final NetworkStatsHistory value = mStats.valueAt(i);
+                historyEntry = value.getValues(start, end, now, historyEntry);
+
+                entry.iface = IFACE_ALL;
+                entry.uid = key.uid;
+                entry.set = key.set;
+                entry.tag = key.tag;
+                entry.defaultNetwork = key.ident.areAllMembersOnDefaultNetwork()
+                        ? DEFAULT_NETWORK_YES : DEFAULT_NETWORK_NO;
+                entry.metered = key.ident.isAnyMemberMetered() ? METERED_YES : METERED_NO;
+                entry.roaming = key.ident.isAnyMemberRoaming() ? ROAMING_YES : ROAMING_NO;
+                entry.rxBytes = historyEntry.rxBytes;
+                entry.rxPackets = historyEntry.rxPackets;
+                entry.txBytes = historyEntry.txBytes;
+                entry.txPackets = historyEntry.txPackets;
+                entry.operations = historyEntry.operations;
+
+                if (!entry.isEmpty()) {
+                    stats.combineValues(entry);
+                }
+            }
+        }
+
+        return stats;
+    }
+
+    /**
+     * Record given {@link android.net.NetworkStats.Entry} into this collection.
+     * @hide
+     */
+    public void recordData(NetworkIdentitySet ident, int uid, int set, int tag, long start,
+            long end, NetworkStats.Entry entry) {
+        final NetworkStatsHistory history = findOrCreateHistory(ident, uid, set, tag);
+        history.recordData(start, end, entry);
+        noteRecordedHistory(history.getStart(), history.getEnd(), entry.rxBytes + entry.txBytes);
+    }
+
+    /**
+     * Record given {@link NetworkStatsHistory} into this collection.
+     *
+     * @hide
+     */
+    public void recordHistory(@NonNull Key key, @NonNull NetworkStatsHistory history) {
+        Objects.requireNonNull(key);
+        Objects.requireNonNull(history);
+        if (history.size() == 0) return;
+        noteRecordedHistory(history.getStart(), history.getEnd(), history.getTotalBytes());
+
+        NetworkStatsHistory target = mStats.get(key);
+        if (target == null) {
+            target = new NetworkStatsHistory(history.getBucketDuration());
+            mStats.put(key, target);
+        }
+        target.recordEntireHistory(history);
+    }
+
+    /**
+     * Record all {@link NetworkStatsHistory} contained in the given collection
+     * into this collection.
+     *
+     * @hide
+     */
+    public void recordCollection(@NonNull NetworkStatsCollection another) {
+        Objects.requireNonNull(another);
+        for (int i = 0; i < another.mStats.size(); i++) {
+            final Key key = another.mStats.keyAt(i);
+            final NetworkStatsHistory value = another.mStats.valueAt(i);
+            recordHistory(key, value);
+        }
+    }
+
+    private NetworkStatsHistory findOrCreateHistory(
+            NetworkIdentitySet ident, int uid, int set, int tag) {
+        final Key key = new Key(ident, uid, set, tag);
+        final NetworkStatsHistory existing = mStats.get(key);
+
+        // update when no existing, or when bucket duration changed
+        NetworkStatsHistory updated = null;
+        if (existing == null) {
+            updated = new NetworkStatsHistory(mBucketDurationMillis, 10);
+        } else if (existing.getBucketDuration() != mBucketDurationMillis) {
+            updated = new NetworkStatsHistory(existing, mBucketDurationMillis);
+        }
+
+        if (updated != null) {
+            mStats.put(key, updated);
+            return updated;
+        } else {
+            return existing;
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void read(InputStream in) throws IOException {
+        read((DataInput) new DataInputStream(in));
+    }
+
+    private void read(DataInput in) throws IOException {
+        // verify file magic header intact
+        final int magic = in.readInt();
+        if (magic != FILE_MAGIC) {
+            throw new ProtocolException("unexpected magic: " + magic);
+        }
+
+        final int version = in.readInt();
+        switch (version) {
+            case VERSION_UNIFIED_INIT: {
+                // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory))
+                final int identSize = in.readInt();
+                for (int i = 0; i < identSize; i++) {
+                    final NetworkIdentitySet ident = new NetworkIdentitySet(in);
+
+                    final int size = in.readInt();
+                    for (int j = 0; j < size; j++) {
+                        final int uid = in.readInt();
+                        final int set = in.readInt();
+                        final int tag = in.readInt();
+
+                        final Key key = new Key(ident, uid, set, tag);
+                        final NetworkStatsHistory history = new NetworkStatsHistory(in);
+                        recordHistory(key, history);
+                    }
+                }
+                break;
+            }
+            default: {
+                throw new ProtocolException("unexpected version: " + version);
+            }
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void write(OutputStream out) throws IOException {
+        write((DataOutput) new DataOutputStream(out));
+        out.flush();
+    }
+
+    private void write(DataOutput out) throws IOException {
+        // cluster key lists grouped by ident
+        final HashMap<NetworkIdentitySet, ArrayList<Key>> keysByIdent = new HashMap<>();
+        for (Key key : mStats.keySet()) {
+            ArrayList<Key> keys = keysByIdent.get(key.ident);
+            if (keys == null) {
+                keys = new ArrayList<>();
+                keysByIdent.put(key.ident, keys);
+            }
+            keys.add(key);
+        }
+
+        out.writeInt(FILE_MAGIC);
+        out.writeInt(VERSION_UNIFIED_INIT);
+
+        out.writeInt(keysByIdent.size());
+        for (NetworkIdentitySet ident : keysByIdent.keySet()) {
+            final ArrayList<Key> keys = keysByIdent.get(ident);
+            ident.writeToStream(out);
+
+            out.writeInt(keys.size());
+            for (Key key : keys) {
+                final NetworkStatsHistory history = mStats.get(key);
+                out.writeInt(key.uid);
+                out.writeInt(key.set);
+                out.writeInt(key.tag);
+                history.writeToStream(out);
+            }
+        }
+    }
+
+    /**
+     * Read legacy network summary statistics file format into the collection,
+     * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
+     *
+     * @deprecated
+     * @hide
+     */
+    @Deprecated
+    public void readLegacyNetwork(File file) throws IOException {
+        final AtomicFile inputFile = new AtomicFile(file);
+
+        DataInputStream in = null;
+        try {
+            in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
+
+            // verify file magic header intact
+            final int magic = in.readInt();
+            if (magic != FILE_MAGIC) {
+                throw new ProtocolException("unexpected magic: " + magic);
+            }
+
+            final int version = in.readInt();
+            switch (version) {
+                case VERSION_NETWORK_INIT: {
+                    // network := size *(NetworkIdentitySet NetworkStatsHistory)
+                    final int size = in.readInt();
+                    for (int i = 0; i < size; i++) {
+                        final NetworkIdentitySet ident = new NetworkIdentitySet(in);
+                        final NetworkStatsHistory history = new NetworkStatsHistory(in);
+
+                        final Key key = new Key(ident, UID_ALL, SET_ALL, TAG_NONE);
+                        recordHistory(key, history);
+                    }
+                    break;
+                }
+                default: {
+                    throw new ProtocolException("unexpected version: " + version);
+                }
+            }
+        } catch (FileNotFoundException e) {
+            // missing stats is okay, probably first boot
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+    }
+
+    /**
+     * Read legacy Uid statistics file format into the collection,
+     * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
+     *
+     * @deprecated
+     * @hide
+     */
+    @Deprecated
+    public void readLegacyUid(File file, boolean onlyTags) throws IOException {
+        final AtomicFile inputFile = new AtomicFile(file);
+
+        DataInputStream in = null;
+        try {
+            in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
+
+            // verify file magic header intact
+            final int magic = in.readInt();
+            if (magic != FILE_MAGIC) {
+                throw new ProtocolException("unexpected magic: " + magic);
+            }
+
+            final int version = in.readInt();
+            switch (version) {
+                case VERSION_UID_INIT: {
+                    // uid := size *(UID NetworkStatsHistory)
+
+                    // drop this data version, since we don't have a good
+                    // mapping into NetworkIdentitySet.
+                    break;
+                }
+                case VERSION_UID_WITH_IDENT: {
+                    // uid := size *(NetworkIdentitySet size *(UID NetworkStatsHistory))
+
+                    // drop this data version, since this version only existed
+                    // for a short time.
+                    break;
+                }
+                case VERSION_UID_WITH_TAG:
+                case VERSION_UID_WITH_SET: {
+                    // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory))
+                    final int identSize = in.readInt();
+                    for (int i = 0; i < identSize; i++) {
+                        final NetworkIdentitySet ident = new NetworkIdentitySet(in);
+
+                        final int size = in.readInt();
+                        for (int j = 0; j < size; j++) {
+                            final int uid = in.readInt();
+                            final int set = (version >= VERSION_UID_WITH_SET) ? in.readInt()
+                                    : SET_DEFAULT;
+                            final int tag = in.readInt();
+
+                            final Key key = new Key(ident, uid, set, tag);
+                            final NetworkStatsHistory history = new NetworkStatsHistory(in);
+
+                            if ((tag == TAG_NONE) != onlyTags) {
+                                recordHistory(key, history);
+                            }
+                        }
+                    }
+                    break;
+                }
+                default: {
+                    throw new ProtocolException("unexpected version: " + version);
+                }
+            }
+        } catch (FileNotFoundException e) {
+            // missing stats is okay, probably first boot
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+    }
+
+    /**
+     * Remove any {@link NetworkStatsHistory} attributed to the requested UID,
+     * moving any {@link NetworkStats#TAG_NONE} series to
+     * {@link TrafficStats#UID_REMOVED}.
+     * @hide
+     */
+    public void removeUids(int[] uids) {
+        final ArrayList<Key> knownKeys = new ArrayList<>();
+        knownKeys.addAll(mStats.keySet());
+
+        // migrate all UID stats into special "removed" bucket
+        for (Key key : knownKeys) {
+            if (CollectionUtils.contains(uids, key.uid)) {
+                // only migrate combined TAG_NONE history
+                if (key.tag == TAG_NONE) {
+                    final NetworkStatsHistory uidHistory = mStats.get(key);
+                    final NetworkStatsHistory removedHistory = findOrCreateHistory(
+                            key.ident, UID_REMOVED, SET_DEFAULT, TAG_NONE);
+                    removedHistory.recordEntireHistory(uidHistory);
+                }
+                mStats.remove(key);
+                mDirty = true;
+            }
+        }
+    }
+
+    private void noteRecordedHistory(long startMillis, long endMillis, long totalBytes) {
+        if (startMillis < mStartMillis) mStartMillis = startMillis;
+        if (endMillis > mEndMillis) mEndMillis = endMillis;
+        mTotalBytes += totalBytes;
+        mDirty = true;
+    }
+
+    private int estimateBuckets() {
+        return (int) (Math.min(mEndMillis - mStartMillis, WEEK_IN_MILLIS * 5)
+                / mBucketDurationMillis);
+    }
+
+    private ArrayList<Key> getSortedKeys() {
+        final ArrayList<Key> keys = new ArrayList<>();
+        keys.addAll(mStats.keySet());
+        Collections.sort(keys, (left, right) -> Key.compare(left, right));
+        return keys;
+    }
+
+    /** @hide */
+    public void dump(IndentingPrintWriter pw) {
+        for (Key key : getSortedKeys()) {
+            pw.print("ident="); pw.print(key.ident.toString());
+            pw.print(" uid="); pw.print(key.uid);
+            pw.print(" set="); pw.print(NetworkStats.setToString(key.set));
+            pw.print(" tag="); pw.println(NetworkStats.tagToString(key.tag));
+
+            final NetworkStatsHistory history = mStats.get(key);
+            pw.increaseIndent();
+            history.dump(pw, true);
+            pw.decreaseIndent();
+        }
+    }
+
+    /** @hide */
+    public void dumpDebug(ProtoOutputStream proto, long tag) {
+        final long start = proto.start(tag);
+
+        for (Key key : getSortedKeys()) {
+            final long startStats = proto.start(NetworkStatsCollectionProto.STATS);
+
+            // Key
+            final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY);
+            key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY);
+            proto.write(NetworkStatsCollectionKeyProto.UID, key.uid);
+            proto.write(NetworkStatsCollectionKeyProto.SET, key.set);
+            proto.write(NetworkStatsCollectionKeyProto.TAG, key.tag);
+            proto.end(startKey);
+
+            // Value
+            final NetworkStatsHistory history = mStats.get(key);
+            history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY);
+            proto.end(startStats);
+        }
+
+        proto.end(start);
+    }
+
+    /** @hide */
+    public void dumpCheckin(PrintWriter pw, long start, long end) {
+        dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateMobileWildcard(), "cell");
+        dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateWifiWildcard(), "wifi");
+        dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateEthernet(), "eth");
+        dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateBluetooth(), "bt");
+    }
+
+    /**
+     * Dump all contained stats that match requested parameters, but group
+     * together all matching {@link NetworkTemplate} under a single prefix.
+     */
+    private void dumpCheckin(PrintWriter pw, long start, long end, NetworkTemplate groupTemplate,
+            String groupPrefix) {
+        final ArrayMap<Key, NetworkStatsHistory> grouped = new ArrayMap<>();
+
+        // Walk through all history, grouping by matching network templates
+        for (int i = 0; i < mStats.size(); i++) {
+            final Key key = mStats.keyAt(i);
+            final NetworkStatsHistory value = mStats.valueAt(i);
+
+            if (!templateMatches(groupTemplate, key.ident)) continue;
+            if (key.set >= NetworkStats.SET_DEBUG_START) continue;
+
+            final Key groupKey = new Key(null, key.uid, key.set, key.tag);
+            NetworkStatsHistory groupHistory = grouped.get(groupKey);
+            if (groupHistory == null) {
+                groupHistory = new NetworkStatsHistory(value.getBucketDuration());
+                grouped.put(groupKey, groupHistory);
+            }
+            groupHistory.recordHistory(value, start, end);
+        }
+
+        for (int i = 0; i < grouped.size(); i++) {
+            final Key key = grouped.keyAt(i);
+            final NetworkStatsHistory value = grouped.valueAt(i);
+
+            if (value.size() == 0) continue;
+
+            pw.print("c,");
+            pw.print(groupPrefix); pw.print(',');
+            pw.print(key.uid); pw.print(',');
+            pw.print(NetworkStats.setToCheckinString(key.set)); pw.print(',');
+            pw.print(key.tag);
+            pw.println();
+
+            value.dumpCheckin(pw);
+        }
+    }
+
+    /**
+     * Test if given {@link NetworkTemplate} matches any {@link NetworkIdentity}
+     * in the given {@link NetworkIdentitySet}.
+     */
+    private static boolean templateMatches(NetworkTemplate template, NetworkIdentitySet identSet) {
+        for (NetworkIdentity ident : identSet) {
+            if (template.matches(ident)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the all historical stats of the collection {@link NetworkStatsCollection}.
+     *
+     * @return All {@link NetworkStatsHistory} in this collection.
+     */
+    @NonNull
+    public Map<Key, NetworkStatsHistory> getEntries() {
+        return new ArrayMap(mStats);
+    }
+
+    /**
+     * Builder class for {@link NetworkStatsCollection}.
+     */
+    public static final class Builder {
+        private final long mBucketDurationMillis;
+        private final ArrayMap<Key, NetworkStatsHistory> mEntries = new ArrayMap<>();
+
+        /**
+         * Creates a new Builder with given bucket duration.
+         *
+         * @param bucketDuration Duration of the buckets of the object, in milliseconds.
+         */
+        public Builder(long bucketDurationMillis) {
+            mBucketDurationMillis = bucketDurationMillis;
+        }
+
+        /**
+         * Add association of the history with the specified key in this map.
+         *
+         * @param key The object used to identify a network, see {@link Key}.
+         * @param history {@link NetworkStatsHistory} instance associated to the given {@link Key}.
+         * @return The builder object.
+         */
+        @NonNull
+        public NetworkStatsCollection.Builder addEntry(@NonNull Key key,
+                @NonNull NetworkStatsHistory history) {
+            Objects.requireNonNull(key);
+            Objects.requireNonNull(history);
+            final List<Entry> historyEntries = history.getEntries();
+
+            final NetworkStatsHistory.Builder historyBuilder =
+                    new NetworkStatsHistory.Builder(mBucketDurationMillis, historyEntries.size());
+            for (Entry entry : historyEntries) {
+                historyBuilder.addEntry(entry);
+            }
+
+            mEntries.put(key, historyBuilder.build());
+            return this;
+        }
+
+        /**
+         * Builds the instance of the {@link NetworkStatsCollection}.
+         *
+         * @return the built instance of {@link NetworkStatsCollection}.
+         */
+        @NonNull
+        public NetworkStatsCollection build() {
+            final NetworkStatsCollection collection =
+                    new NetworkStatsCollection(mBucketDurationMillis);
+            for (int i = 0; i < mEntries.size(); i++) {
+                collection.recordHistory(mEntries.keyAt(i), mEntries.valueAt(i));
+            }
+            return collection;
+        }
+    }
+
+    /**
+     * the identifier that associate with the {@link NetworkStatsHistory} object to identify
+     * a certain record in the {@link NetworkStatsCollection} object.
+     */
+    public static final class Key {
+        /** @hide */
+        public final NetworkIdentitySet ident;
+        /** @hide */
+        public final int uid;
+        /** @hide */
+        public final int set;
+        /** @hide */
+        public final int tag;
+
+        private final int mHashCode;
+
+        /**
+         * Construct a {@link Key} object.
+         *
+         * @param ident a Set of {@link NetworkIdentity} that associated with the record.
+         * @param uid Uid of the record.
+         * @param set Set of the record, see {@code NetworkStats#SET_*}.
+         * @param tag Tag of the record, see {@link TrafficStats#setThreadStatsTag(int)}.
+         */
+        public Key(@NonNull Set<NetworkIdentity> ident, int uid, @State int set, int tag) {
+            this(new NetworkIdentitySet(Objects.requireNonNull(ident)), uid, set, tag);
+        }
+
+        /** @hide */
+        public Key(@NonNull NetworkIdentitySet ident, int uid, int set, int tag) {
+            this.ident = Objects.requireNonNull(ident);
+            this.uid = uid;
+            this.set = set;
+            this.tag = tag;
+            mHashCode = Objects.hash(ident, uid, set, tag);
+        }
+
+        @Override
+        public int hashCode() {
+            return mHashCode;
+        }
+
+        @Override
+        public boolean equals(@Nullable Object obj) {
+            if (obj instanceof Key) {
+                final Key key = (Key) obj;
+                return uid == key.uid && set == key.set && tag == key.tag
+                        && Objects.equals(ident, key.ident);
+            }
+            return false;
+        }
+
+        /** @hide */
+        public static int compare(@NonNull Key left, @NonNull Key right) {
+            Objects.requireNonNull(left);
+            Objects.requireNonNull(right);
+            int res = 0;
+            if (left.ident != null && right.ident != null) {
+                res = NetworkIdentitySet.compare(left.ident, right.ident);
+            }
+            if (res == 0) {
+                res = Integer.compare(left.uid, right.uid);
+            }
+            if (res == 0) {
+                res = Integer.compare(left.set, right.set);
+            }
+            if (res == 0) {
+                res = Integer.compare(left.tag, right.tag);
+            }
+            return res;
+        }
+    }
+}
diff --git a/framework-t/src/android/net/NetworkStatsHistory.aidl b/framework-t/src/android/net/NetworkStatsHistory.aidl
new file mode 100644
index 0000000..8b9069f
--- /dev/null
+++ b/framework-t/src/android/net/NetworkStatsHistory.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+parcelable NetworkStatsHistory;
diff --git a/framework-t/src/android/net/NetworkStatsHistory.java b/framework-t/src/android/net/NetworkStatsHistory.java
new file mode 100644
index 0000000..301fef9
--- /dev/null
+++ b/framework-t/src/android/net/NetworkStatsHistory.java
@@ -0,0 +1,1162 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkStats.UID_ALL;
+import static android.net.NetworkStatsHistory.DataStreamUtils.readFullLongArray;
+import static android.net.NetworkStatsHistory.DataStreamUtils.readVarLongArray;
+import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLongArray;
+import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
+import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
+import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
+import static android.text.format.DateUtils.SECOND_IN_MILLIS;
+
+import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.service.NetworkStatsHistoryBucketProto;
+import android.service.NetworkStatsHistoryProto;
+import android.util.IndentingPrintWriter;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.NetworkStatsUtils;
+
+import libcore.util.EmptyArray;
+
+import java.io.CharArrayWriter;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.ProtocolException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Collection of historical network statistics, recorded into equally-sized
+ * "buckets" in time. Internally it stores data in {@code long} series for more
+ * efficient persistence.
+ * <p>
+ * Each bucket is defined by a {@link #bucketStart} timestamp, and lasts for
+ * {@link #bucketDuration}. Internally assumes that {@link #bucketStart} is
+ * sorted at all times.
+ *
+ * @hide
+ */
+@SystemApi(client = MODULE_LIBRARIES)
+public final class NetworkStatsHistory implements Parcelable {
+    private static final int VERSION_INIT = 1;
+    private static final int VERSION_ADD_PACKETS = 2;
+    private static final int VERSION_ADD_ACTIVE = 3;
+
+    /** @hide */
+    public static final int FIELD_ACTIVE_TIME = 0x01;
+    /** @hide */
+    public static final int FIELD_RX_BYTES = 0x02;
+    /** @hide */
+    public static final int FIELD_RX_PACKETS = 0x04;
+    /** @hide */
+    public static final int FIELD_TX_BYTES = 0x08;
+    /** @hide */
+    public static final int FIELD_TX_PACKETS = 0x10;
+    /** @hide */
+    public static final int FIELD_OPERATIONS = 0x20;
+    /** @hide */
+    public static final int FIELD_ALL = 0xFFFFFFFF;
+
+    private long bucketDuration;
+    private int bucketCount;
+    private long[] bucketStart;
+    private long[] activeTime;
+    private long[] rxBytes;
+    private long[] rxPackets;
+    private long[] txBytes;
+    private long[] txPackets;
+    private long[] operations;
+    private long totalBytes;
+
+    /** @hide */
+    public NetworkStatsHistory(long bucketDuration, long[] bucketStart, long[] activeTime,
+            long[] rxBytes, long[] rxPackets, long[] txBytes, long[] txPackets,
+            long[] operations, int bucketCount, long totalBytes) {
+        this.bucketDuration = bucketDuration;
+        this.bucketStart = bucketStart;
+        this.activeTime = activeTime;
+        this.rxBytes = rxBytes;
+        this.rxPackets = rxPackets;
+        this.txBytes = txBytes;
+        this.txPackets = txPackets;
+        this.operations = operations;
+        this.bucketCount = bucketCount;
+        this.totalBytes = totalBytes;
+    }
+
+    /**
+     * An instance to represent a single record in a {@link NetworkStatsHistory} object.
+     */
+    public static final class Entry {
+        /** @hide */
+        public static final long UNKNOWN = -1;
+
+        /** @hide */
+        // TODO: Migrate all callers to get duration from the history object and remove this field.
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long bucketDuration;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long bucketStart;
+        /** @hide */
+        public long activeTime;
+        /** @hide */
+        @UnsupportedAppUsage
+        public long rxBytes;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long rxPackets;
+        /** @hide */
+        @UnsupportedAppUsage
+        public long txBytes;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long txPackets;
+        /** @hide */
+        public long operations;
+        /** @hide */
+        Entry() {}
+
+        /**
+         * Construct a {@link Entry} instance to represent a single record in a
+         * {@link NetworkStatsHistory} object.
+         *
+         * @param bucketStart Start of period for this {@link Entry}, in milliseconds since the
+         *                    Unix epoch, see {@link java.lang.System#currentTimeMillis}.
+         * @param activeTime Active time for this {@link Entry}, in milliseconds.
+         * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param rxPackets Number of packets received for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param operations count of network operations performed for this {@link Entry}. This can
+         *                   be used to derive bytes-per-operation.
+         */
+        public Entry(long bucketStart, long activeTime, long rxBytes,
+                long rxPackets, long txBytes, long txPackets, long operations) {
+            this.bucketStart = bucketStart;
+            this.activeTime = activeTime;
+            this.rxBytes = rxBytes;
+            this.rxPackets = rxPackets;
+            this.txBytes = txBytes;
+            this.txPackets = txPackets;
+            this.operations = operations;
+        }
+
+        /**
+         * Get start timestamp of the bucket's time interval, in milliseconds since the Unix epoch.
+         */
+        public long getBucketStart() {
+            return bucketStart;
+        }
+
+        /**
+         * Get active time of the bucket's time interval, in milliseconds.
+         */
+        public long getActiveTime() {
+            return activeTime;
+        }
+
+        /** Get number of bytes received for this {@link Entry}. */
+        public long getRxBytes() {
+            return rxBytes;
+        }
+
+        /** Get number of packets received for this {@link Entry}. */
+        public long getRxPackets() {
+            return rxPackets;
+        }
+
+        /** Get number of bytes transmitted for this {@link Entry}. */
+        public long getTxBytes() {
+            return txBytes;
+        }
+
+        /** Get number of packets transmitted for this {@link Entry}. */
+        public long getTxPackets() {
+            return txPackets;
+        }
+
+        /** Get count of network operations performed for this {@link Entry}. */
+        public long getOperations() {
+            return operations;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o.getClass() != getClass()) return false;
+            Entry entry = (Entry) o;
+            return bucketStart == entry.bucketStart
+                    && activeTime == entry.activeTime && rxBytes == entry.rxBytes
+                    && rxPackets == entry.rxPackets && txBytes == entry.txBytes
+                    && txPackets == entry.txPackets && operations == entry.operations;
+        }
+
+        @Override
+        public int hashCode() {
+            return (int) (bucketStart * 2
+                    + activeTime * 3
+                    + rxBytes * 5
+                    + rxPackets * 7
+                    + txBytes * 11
+                    + txPackets * 13
+                    + operations * 17);
+        }
+
+        @Override
+        public String toString() {
+            return "Entry{"
+                    + "bucketStart=" + bucketStart
+                    + ", activeTime=" + activeTime
+                    + ", rxBytes=" + rxBytes
+                    + ", rxPackets=" + rxPackets
+                    + ", txBytes=" + txBytes
+                    + ", txPackets=" + txPackets
+                    + ", operations=" + operations
+                    + "}";
+        }
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public NetworkStatsHistory(long bucketDuration) {
+        this(bucketDuration, 10, FIELD_ALL);
+    }
+
+    /** @hide */
+    public NetworkStatsHistory(long bucketDuration, int initialSize) {
+        this(bucketDuration, initialSize, FIELD_ALL);
+    }
+
+    /** @hide */
+    public NetworkStatsHistory(long bucketDuration, int initialSize, int fields) {
+        this.bucketDuration = bucketDuration;
+        bucketStart = new long[initialSize];
+        if ((fields & FIELD_ACTIVE_TIME) != 0) activeTime = new long[initialSize];
+        if ((fields & FIELD_RX_BYTES) != 0) rxBytes = new long[initialSize];
+        if ((fields & FIELD_RX_PACKETS) != 0) rxPackets = new long[initialSize];
+        if ((fields & FIELD_TX_BYTES) != 0) txBytes = new long[initialSize];
+        if ((fields & FIELD_TX_PACKETS) != 0) txPackets = new long[initialSize];
+        if ((fields & FIELD_OPERATIONS) != 0) operations = new long[initialSize];
+        bucketCount = 0;
+        totalBytes = 0;
+    }
+
+    /** @hide */
+    public NetworkStatsHistory(NetworkStatsHistory existing, long bucketDuration) {
+        this(bucketDuration, existing.estimateResizeBuckets(bucketDuration));
+        recordEntireHistory(existing);
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public NetworkStatsHistory(Parcel in) {
+        bucketDuration = in.readLong();
+        bucketStart = readLongArray(in);
+        activeTime = readLongArray(in);
+        rxBytes = readLongArray(in);
+        rxPackets = readLongArray(in);
+        txBytes = readLongArray(in);
+        txPackets = readLongArray(in);
+        operations = readLongArray(in);
+        bucketCount = bucketStart.length;
+        totalBytes = in.readLong();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeLong(bucketDuration);
+        writeLongArray(out, bucketStart, bucketCount);
+        writeLongArray(out, activeTime, bucketCount);
+        writeLongArray(out, rxBytes, bucketCount);
+        writeLongArray(out, rxPackets, bucketCount);
+        writeLongArray(out, txBytes, bucketCount);
+        writeLongArray(out, txPackets, bucketCount);
+        writeLongArray(out, operations, bucketCount);
+        out.writeLong(totalBytes);
+    }
+
+    /** @hide */
+    public NetworkStatsHistory(DataInput in) throws IOException {
+        final int version = in.readInt();
+        switch (version) {
+            case VERSION_INIT: {
+                bucketDuration = in.readLong();
+                bucketStart = readFullLongArray(in);
+                rxBytes = readFullLongArray(in);
+                rxPackets = new long[bucketStart.length];
+                txBytes = readFullLongArray(in);
+                txPackets = new long[bucketStart.length];
+                operations = new long[bucketStart.length];
+                bucketCount = bucketStart.length;
+                totalBytes = CollectionUtils.total(rxBytes) + CollectionUtils.total(txBytes);
+                break;
+            }
+            case VERSION_ADD_PACKETS:
+            case VERSION_ADD_ACTIVE: {
+                bucketDuration = in.readLong();
+                bucketStart = readVarLongArray(in);
+                activeTime = (version >= VERSION_ADD_ACTIVE) ? readVarLongArray(in)
+                        : new long[bucketStart.length];
+                rxBytes = readVarLongArray(in);
+                rxPackets = readVarLongArray(in);
+                txBytes = readVarLongArray(in);
+                txPackets = readVarLongArray(in);
+                operations = readVarLongArray(in);
+                bucketCount = bucketStart.length;
+                totalBytes = CollectionUtils.total(rxBytes) + CollectionUtils.total(txBytes);
+                break;
+            }
+            default: {
+                throw new ProtocolException("unexpected version: " + version);
+            }
+        }
+
+        if (bucketStart.length != bucketCount || rxBytes.length != bucketCount
+                || rxPackets.length != bucketCount || txBytes.length != bucketCount
+                || txPackets.length != bucketCount || operations.length != bucketCount) {
+            throw new ProtocolException("Mismatched history lengths");
+        }
+    }
+
+    /** @hide */
+    public void writeToStream(DataOutput out) throws IOException {
+        out.writeInt(VERSION_ADD_ACTIVE);
+        out.writeLong(bucketDuration);
+        writeVarLongArray(out, bucketStart, bucketCount);
+        writeVarLongArray(out, activeTime, bucketCount);
+        writeVarLongArray(out, rxBytes, bucketCount);
+        writeVarLongArray(out, rxPackets, bucketCount);
+        writeVarLongArray(out, txBytes, bucketCount);
+        writeVarLongArray(out, txPackets, bucketCount);
+        writeVarLongArray(out, operations, bucketCount);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int size() {
+        return bucketCount;
+    }
+
+    /** @hide */
+    public long getBucketDuration() {
+        return bucketDuration;
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public long getStart() {
+        if (bucketCount > 0) {
+            return bucketStart[0];
+        } else {
+            return Long.MAX_VALUE;
+        }
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public long getEnd() {
+        if (bucketCount > 0) {
+            return bucketStart[bucketCount - 1] + bucketDuration;
+        } else {
+            return Long.MIN_VALUE;
+        }
+    }
+
+    /**
+     * Return total bytes represented by this history.
+     * @hide
+     */
+    public long getTotalBytes() {
+        return totalBytes;
+    }
+
+    /**
+     * Return index of bucket that contains or is immediately before the
+     * requested time.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int getIndexBefore(long time) {
+        int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time);
+        if (index < 0) {
+            index = (~index) - 1;
+        } else {
+            index -= 1;
+        }
+        return NetworkStatsUtils.constrain(index, 0, bucketCount - 1);
+    }
+
+    /**
+     * Return index of bucket that contains or is immediately after the
+     * requested time.
+     * @hide
+     */
+    public int getIndexAfter(long time) {
+        int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time);
+        if (index < 0) {
+            index = ~index;
+        } else {
+            index += 1;
+        }
+        return NetworkStatsUtils.constrain(index, 0, bucketCount - 1);
+    }
+
+    /**
+     * Return specific stats entry.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public Entry getValues(int i, Entry recycle) {
+        final Entry entry = recycle != null ? recycle : new Entry();
+        entry.bucketStart = bucketStart[i];
+        entry.bucketDuration = bucketDuration;
+        entry.activeTime = getLong(activeTime, i, UNKNOWN);
+        entry.rxBytes = getLong(rxBytes, i, UNKNOWN);
+        entry.rxPackets = getLong(rxPackets, i, UNKNOWN);
+        entry.txBytes = getLong(txBytes, i, UNKNOWN);
+        entry.txPackets = getLong(txPackets, i, UNKNOWN);
+        entry.operations = getLong(operations, i, UNKNOWN);
+        return entry;
+    }
+
+    /**
+     * Get List of {@link Entry} of the {@link NetworkStatsHistory} instance.
+     *
+     * @return
+     */
+    @NonNull
+    public List<Entry> getEntries() {
+        // TODO: Return a wrapper that uses this list instead, to prevent the returned result
+        //  from being changed.
+        final ArrayList<Entry> ret = new ArrayList<>(size());
+        for (int i = 0; i < size(); i++) {
+            ret.add(getValues(i, null /* recycle */));
+        }
+        return ret;
+    }
+
+    /** @hide */
+    public void setValues(int i, Entry entry) {
+        // Unwind old values
+        if (rxBytes != null) totalBytes -= rxBytes[i];
+        if (txBytes != null) totalBytes -= txBytes[i];
+
+        bucketStart[i] = entry.bucketStart;
+        setLong(activeTime, i, entry.activeTime);
+        setLong(rxBytes, i, entry.rxBytes);
+        setLong(rxPackets, i, entry.rxPackets);
+        setLong(txBytes, i, entry.txBytes);
+        setLong(txPackets, i, entry.txPackets);
+        setLong(operations, i, entry.operations);
+
+        // Apply new values
+        if (rxBytes != null) totalBytes += rxBytes[i];
+        if (txBytes != null) totalBytes += txBytes[i];
+    }
+
+    /**
+     * Record that data traffic occurred in the given time range. Will
+     * distribute across internal buckets, creating new buckets as needed.
+     * @hide
+     */
+    @Deprecated
+    public void recordData(long start, long end, long rxBytes, long txBytes) {
+        recordData(start, end, new NetworkStats.Entry(
+                IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0L));
+    }
+
+    /**
+     * Record that data traffic occurred in the given time range. Will
+     * distribute across internal buckets, creating new buckets as needed.
+     * @hide
+     */
+    public void recordData(long start, long end, NetworkStats.Entry entry) {
+        long rxBytes = entry.rxBytes;
+        long rxPackets = entry.rxPackets;
+        long txBytes = entry.txBytes;
+        long txPackets = entry.txPackets;
+        long operations = entry.operations;
+
+        if (entry.isNegative()) {
+            throw new IllegalArgumentException("tried recording negative data");
+        }
+        if (entry.isEmpty()) {
+            return;
+        }
+
+        // create any buckets needed by this range
+        ensureBuckets(start, end);
+        // Return fast if there is still no entry. This would typically happen when the start,
+        // end or duration are not valid values, e.g. start > end, negative duration value, etc.
+        if (bucketCount == 0) return;
+
+        // distribute data usage into buckets
+        long duration = end - start;
+        final int startIndex = getIndexAfter(end);
+        for (int i = startIndex; i >= 0; i--) {
+            final long curStart = bucketStart[i];
+            final long curEnd = curStart + bucketDuration;
+
+            // bucket is older than record; we're finished
+            if (curEnd < start) break;
+            // bucket is newer than record; keep looking
+            if (curStart > end) continue;
+
+            final long overlap = Math.min(curEnd, end) - Math.max(curStart, start);
+            if (overlap <= 0) continue;
+
+            // integer math each time is faster than floating point
+            final long fracRxBytes = multiplySafeByRational(rxBytes, overlap, duration);
+            final long fracRxPackets = multiplySafeByRational(rxPackets, overlap, duration);
+            final long fracTxBytes = multiplySafeByRational(txBytes, overlap, duration);
+            final long fracTxPackets = multiplySafeByRational(txPackets, overlap, duration);
+            final long fracOperations = multiplySafeByRational(operations, overlap, duration);
+
+
+            addLong(activeTime, i, overlap);
+            addLong(this.rxBytes, i, fracRxBytes); rxBytes -= fracRxBytes;
+            addLong(this.rxPackets, i, fracRxPackets); rxPackets -= fracRxPackets;
+            addLong(this.txBytes, i, fracTxBytes); txBytes -= fracTxBytes;
+            addLong(this.txPackets, i, fracTxPackets); txPackets -= fracTxPackets;
+            addLong(this.operations, i, fracOperations); operations -= fracOperations;
+
+            duration -= overlap;
+        }
+
+        totalBytes += entry.rxBytes + entry.txBytes;
+    }
+
+    /**
+     * Record an entire {@link NetworkStatsHistory} into this history. Usually
+     * for combining together stats for external reporting.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public void recordEntireHistory(NetworkStatsHistory input) {
+        recordHistory(input, Long.MIN_VALUE, Long.MAX_VALUE);
+    }
+
+    /**
+     * Record given {@link NetworkStatsHistory} into this history, copying only
+     * buckets that atomically occur in the inclusive time range. Doesn't
+     * interpolate across partial buckets.
+     * @hide
+     */
+    public void recordHistory(NetworkStatsHistory input, long start, long end) {
+        final NetworkStats.Entry entry = new NetworkStats.Entry(
+                IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
+        for (int i = 0; i < input.bucketCount; i++) {
+            final long bucketStart = input.bucketStart[i];
+            final long bucketEnd = bucketStart + input.bucketDuration;
+
+            // skip when bucket is outside requested range
+            if (bucketStart < start || bucketEnd > end) continue;
+
+            entry.rxBytes = getLong(input.rxBytes, i, 0L);
+            entry.rxPackets = getLong(input.rxPackets, i, 0L);
+            entry.txBytes = getLong(input.txBytes, i, 0L);
+            entry.txPackets = getLong(input.txPackets, i, 0L);
+            entry.operations = getLong(input.operations, i, 0L);
+
+            recordData(bucketStart, bucketEnd, entry);
+        }
+    }
+
+    /**
+     * Ensure that buckets exist for given time range, creating as needed.
+     */
+    private void ensureBuckets(long start, long end) {
+        // normalize incoming range to bucket boundaries
+        start -= start % bucketDuration;
+        end += (bucketDuration - (end % bucketDuration)) % bucketDuration;
+
+        for (long now = start; now < end; now += bucketDuration) {
+            // try finding existing bucket
+            final int index = Arrays.binarySearch(bucketStart, 0, bucketCount, now);
+            if (index < 0) {
+                // bucket missing, create and insert
+                insertBucket(~index, now);
+            }
+        }
+    }
+
+    /**
+     * Insert new bucket at requested index and starting time.
+     */
+    private void insertBucket(int index, long start) {
+        // create more buckets when needed
+        if (bucketCount >= bucketStart.length) {
+            final int newLength = Math.max(bucketStart.length, 10) * 3 / 2;
+            bucketStart = Arrays.copyOf(bucketStart, newLength);
+            if (activeTime != null) activeTime = Arrays.copyOf(activeTime, newLength);
+            if (rxBytes != null) rxBytes = Arrays.copyOf(rxBytes, newLength);
+            if (rxPackets != null) rxPackets = Arrays.copyOf(rxPackets, newLength);
+            if (txBytes != null) txBytes = Arrays.copyOf(txBytes, newLength);
+            if (txPackets != null) txPackets = Arrays.copyOf(txPackets, newLength);
+            if (operations != null) operations = Arrays.copyOf(operations, newLength);
+        }
+
+        // create gap when inserting bucket in middle
+        if (index < bucketCount) {
+            final int dstPos = index + 1;
+            final int length = bucketCount - index;
+
+            System.arraycopy(bucketStart, index, bucketStart, dstPos, length);
+            if (activeTime != null) System.arraycopy(activeTime, index, activeTime, dstPos, length);
+            if (rxBytes != null) System.arraycopy(rxBytes, index, rxBytes, dstPos, length);
+            if (rxPackets != null) System.arraycopy(rxPackets, index, rxPackets, dstPos, length);
+            if (txBytes != null) System.arraycopy(txBytes, index, txBytes, dstPos, length);
+            if (txPackets != null) System.arraycopy(txPackets, index, txPackets, dstPos, length);
+            if (operations != null) System.arraycopy(operations, index, operations, dstPos, length);
+        }
+
+        bucketStart[index] = start;
+        setLong(activeTime, index, 0L);
+        setLong(rxBytes, index, 0L);
+        setLong(rxPackets, index, 0L);
+        setLong(txBytes, index, 0L);
+        setLong(txPackets, index, 0L);
+        setLong(operations, index, 0L);
+        bucketCount++;
+    }
+
+    /**
+     * Clear all data stored in this object.
+     * @hide
+     */
+    public void clear() {
+        bucketStart = EmptyArray.LONG;
+        if (activeTime != null) activeTime = EmptyArray.LONG;
+        if (rxBytes != null) rxBytes = EmptyArray.LONG;
+        if (rxPackets != null) rxPackets = EmptyArray.LONG;
+        if (txBytes != null) txBytes = EmptyArray.LONG;
+        if (txPackets != null) txPackets = EmptyArray.LONG;
+        if (operations != null) operations = EmptyArray.LONG;
+        bucketCount = 0;
+        totalBytes = 0;
+    }
+
+    /**
+     * Remove buckets older than requested cutoff.
+     * @hide
+     */
+    public void removeBucketsBefore(long cutoff) {
+        // TODO: Consider use getIndexBefore.
+        int i;
+        for (i = 0; i < bucketCount; i++) {
+            final long curStart = bucketStart[i];
+            final long curEnd = curStart + bucketDuration;
+
+            // cutoff happens before or during this bucket; everything before
+            // this bucket should be removed.
+            if (curEnd > cutoff) break;
+        }
+
+        if (i > 0) {
+            final int length = bucketStart.length;
+            bucketStart = Arrays.copyOfRange(bucketStart, i, length);
+            if (activeTime != null) activeTime = Arrays.copyOfRange(activeTime, i, length);
+            if (rxBytes != null) rxBytes = Arrays.copyOfRange(rxBytes, i, length);
+            if (rxPackets != null) rxPackets = Arrays.copyOfRange(rxPackets, i, length);
+            if (txBytes != null) txBytes = Arrays.copyOfRange(txBytes, i, length);
+            if (txPackets != null) txPackets = Arrays.copyOfRange(txPackets, i, length);
+            if (operations != null) operations = Arrays.copyOfRange(operations, i, length);
+            bucketCount -= i;
+
+            totalBytes = 0;
+            if (rxBytes != null) totalBytes += CollectionUtils.total(rxBytes);
+            if (txBytes != null) totalBytes += CollectionUtils.total(txBytes);
+        }
+    }
+
+    /**
+     * Return interpolated data usage across the requested range. Interpolates
+     * across buckets, so values may be rounded slightly.
+     *
+     * <p>If the active bucket is not completed yet, it returns the proportional value of it
+     * based on its duration and the {@code end} param.
+     *
+     * @param start - start of the range, timestamp in milliseconds since the epoch.
+     * @param end - end of the range, timestamp in milliseconds since the epoch.
+     * @param recycle - entry instance for performance, could be null.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public Entry getValues(long start, long end, Entry recycle) {
+        return getValues(start, end, Long.MAX_VALUE, recycle);
+    }
+
+    /**
+     * Return interpolated data usage across the requested range. Interpolates
+     * across buckets, so values may be rounded slightly.
+     *
+     * @param start - start of the range, timestamp in milliseconds since the epoch.
+     * @param end - end of the range, timestamp in milliseconds since the epoch.
+     * @param now - current timestamp in milliseconds since the epoch (wall clock).
+     * @param recycle - entry instance for performance, could be null.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public Entry getValues(long start, long end, long now, Entry recycle) {
+        final Entry entry = recycle != null ? recycle : new Entry();
+        entry.bucketDuration = end - start;
+        entry.bucketStart = start;
+        entry.activeTime = activeTime != null ? 0 : UNKNOWN;
+        entry.rxBytes = rxBytes != null ? 0 : UNKNOWN;
+        entry.rxPackets = rxPackets != null ? 0 : UNKNOWN;
+        entry.txBytes = txBytes != null ? 0 : UNKNOWN;
+        entry.txPackets = txPackets != null ? 0 : UNKNOWN;
+        entry.operations = operations != null ? 0 : UNKNOWN;
+
+        // Return fast if there is no entry.
+        if (bucketCount == 0) return entry;
+
+        final int startIndex = getIndexAfter(end);
+        for (int i = startIndex; i >= 0; i--) {
+            final long curStart = bucketStart[i];
+            long curEnd = curStart + bucketDuration;
+
+            // bucket is older than request; we're finished
+            if (curEnd <= start) break;
+            // bucket is newer than request; keep looking
+            if (curStart >= end) continue;
+
+            // the active bucket is shorter then a normal completed bucket
+            if (curEnd > now) curEnd = now;
+            // usually this is simply bucketDuration
+            final long bucketSpan = curEnd - curStart;
+            // prevent division by zero
+            if (bucketSpan <= 0) continue;
+
+            final long overlapEnd = curEnd < end ? curEnd : end;
+            final long overlapStart = curStart > start ? curStart : start;
+            final long overlap = overlapEnd - overlapStart;
+            if (overlap <= 0) continue;
+
+            // integer math each time is faster than floating point
+            if (activeTime != null) {
+                entry.activeTime += multiplySafeByRational(activeTime[i], overlap, bucketSpan);
+            }
+            if (rxBytes != null) {
+                entry.rxBytes += multiplySafeByRational(rxBytes[i], overlap, bucketSpan);
+            }
+            if (rxPackets != null) {
+                entry.rxPackets += multiplySafeByRational(rxPackets[i], overlap, bucketSpan);
+            }
+            if (txBytes != null) {
+                entry.txBytes += multiplySafeByRational(txBytes[i], overlap, bucketSpan);
+            }
+            if (txPackets != null) {
+                entry.txPackets += multiplySafeByRational(txPackets[i], overlap, bucketSpan);
+            }
+            if (operations != null) {
+                entry.operations += multiplySafeByRational(operations[i], overlap, bucketSpan);
+            }
+        }
+        return entry;
+    }
+
+    /**
+     * @deprecated only for temporary testing
+     * @hide
+     */
+    @Deprecated
+    public void generateRandom(long start, long end, long bytes) {
+        final Random r = new Random();
+
+        final float fractionRx = r.nextFloat();
+        final long rxBytes = (long) (bytes * fractionRx);
+        final long txBytes = (long) (bytes * (1 - fractionRx));
+
+        final long rxPackets = rxBytes / 1024;
+        final long txPackets = txBytes / 1024;
+        final long operations = rxBytes / 2048;
+
+        generateRandom(start, end, rxBytes, rxPackets, txBytes, txPackets, operations, r);
+    }
+
+    /**
+     * @deprecated only for temporary testing
+     * @hide
+     */
+    @Deprecated
+    public void generateRandom(long start, long end, long rxBytes, long rxPackets, long txBytes,
+            long txPackets, long operations, Random r) {
+        ensureBuckets(start, end);
+
+        final NetworkStats.Entry entry = new NetworkStats.Entry(
+                IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
+        while (rxBytes > 1024 || rxPackets > 128 || txBytes > 1024 || txPackets > 128
+                || operations > 32) {
+            final long curStart = randomLong(r, start, end);
+            final long curEnd = curStart + randomLong(r, 0, (end - curStart) / 2);
+
+            entry.rxBytes = randomLong(r, 0, rxBytes);
+            entry.rxPackets = randomLong(r, 0, rxPackets);
+            entry.txBytes = randomLong(r, 0, txBytes);
+            entry.txPackets = randomLong(r, 0, txPackets);
+            entry.operations = randomLong(r, 0, operations);
+
+            rxBytes -= entry.rxBytes;
+            rxPackets -= entry.rxPackets;
+            txBytes -= entry.txBytes;
+            txPackets -= entry.txPackets;
+            operations -= entry.operations;
+
+            recordData(curStart, curEnd, entry);
+        }
+    }
+
+    /** @hide */
+    public static long randomLong(Random r, long start, long end) {
+        return (long) (start + (r.nextFloat() * (end - start)));
+    }
+
+    /**
+     * Quickly determine if this history intersects with given window.
+     * @hide
+     */
+    public boolean intersects(long start, long end) {
+        final long dataStart = getStart();
+        final long dataEnd = getEnd();
+        if (start >= dataStart && start <= dataEnd) return true;
+        if (end >= dataStart && end <= dataEnd) return true;
+        if (dataStart >= start && dataStart <= end) return true;
+        if (dataEnd >= start && dataEnd <= end) return true;
+        return false;
+    }
+
+    /** @hide */
+    public void dump(IndentingPrintWriter pw, boolean fullHistory) {
+        pw.print("NetworkStatsHistory: bucketDuration=");
+        pw.println(bucketDuration / SECOND_IN_MILLIS);
+        pw.increaseIndent();
+
+        final int start = fullHistory ? 0 : Math.max(0, bucketCount - 32);
+        if (start > 0) {
+            pw.print("(omitting "); pw.print(start); pw.println(" buckets)");
+        }
+
+        for (int i = start; i < bucketCount; i++) {
+            pw.print("st="); pw.print(bucketStart[i] / SECOND_IN_MILLIS);
+            if (rxBytes != null) { pw.print(" rb="); pw.print(rxBytes[i]); }
+            if (rxPackets != null) { pw.print(" rp="); pw.print(rxPackets[i]); }
+            if (txBytes != null) { pw.print(" tb="); pw.print(txBytes[i]); }
+            if (txPackets != null) { pw.print(" tp="); pw.print(txPackets[i]); }
+            if (operations != null) { pw.print(" op="); pw.print(operations[i]); }
+            pw.println();
+        }
+
+        pw.decreaseIndent();
+    }
+
+    /** @hide */
+    public void dumpCheckin(PrintWriter pw) {
+        pw.print("d,");
+        pw.print(bucketDuration / SECOND_IN_MILLIS);
+        pw.println();
+
+        for (int i = 0; i < bucketCount; i++) {
+            pw.print("b,");
+            pw.print(bucketStart[i] / SECOND_IN_MILLIS); pw.print(',');
+            if (rxBytes != null) { pw.print(rxBytes[i]); } else { pw.print("*"); } pw.print(',');
+            if (rxPackets != null) { pw.print(rxPackets[i]); } else { pw.print("*"); } pw.print(',');
+            if (txBytes != null) { pw.print(txBytes[i]); } else { pw.print("*"); } pw.print(',');
+            if (txPackets != null) { pw.print(txPackets[i]); } else { pw.print("*"); } pw.print(',');
+            if (operations != null) { pw.print(operations[i]); } else { pw.print("*"); }
+            pw.println();
+        }
+    }
+
+    /** @hide */
+    public void dumpDebug(ProtoOutputStream proto, long tag) {
+        final long start = proto.start(tag);
+
+        proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS, bucketDuration);
+
+        for (int i = 0; i < bucketCount; i++) {
+            final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS);
+
+            proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS,
+                    bucketStart[i]);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i);
+
+            proto.end(startBucket);
+        }
+
+        proto.end(start);
+    }
+
+    private static void dumpDebug(ProtoOutputStream proto, long tag, long[] array, int index) {
+        if (array != null) {
+            proto.write(tag, array[index]);
+        }
+    }
+
+    @Override
+    public String toString() {
+        final CharArrayWriter writer = new CharArrayWriter();
+        dump(new IndentingPrintWriter(writer, "  "), false);
+        return writer.toString();
+    }
+
+    @UnsupportedAppUsage
+    public static final @android.annotation.NonNull Creator<NetworkStatsHistory> CREATOR = new Creator<NetworkStatsHistory>() {
+        @Override
+        public NetworkStatsHistory createFromParcel(Parcel in) {
+            return new NetworkStatsHistory(in);
+        }
+
+        @Override
+        public NetworkStatsHistory[] newArray(int size) {
+            return new NetworkStatsHistory[size];
+        }
+    };
+
+    private static long getLong(long[] array, int i, long value) {
+        return array != null ? array[i] : value;
+    }
+
+    private static void setLong(long[] array, int i, long value) {
+        if (array != null) array[i] = value;
+    }
+
+    private static void addLong(long[] array, int i, long value) {
+        if (array != null) array[i] += value;
+    }
+
+    /** @hide */
+    public int estimateResizeBuckets(long newBucketDuration) {
+        return (int) (size() * getBucketDuration() / newBucketDuration);
+    }
+
+    /**
+     * Utility methods for interacting with {@link DataInputStream} and
+     * {@link DataOutputStream}, mostly dealing with writing partial arrays.
+     * @hide
+     */
+    public static class DataStreamUtils {
+        @Deprecated
+        public static long[] readFullLongArray(DataInput in) throws IOException {
+            final int size = in.readInt();
+            if (size < 0) throw new ProtocolException("negative array size");
+            final long[] values = new long[size];
+            for (int i = 0; i < values.length; i++) {
+                values[i] = in.readLong();
+            }
+            return values;
+        }
+
+        /**
+         * Read variable-length {@link Long} using protobuf-style approach.
+         */
+        public static long readVarLong(DataInput in) throws IOException {
+            int shift = 0;
+            long result = 0;
+            while (shift < 64) {
+                byte b = in.readByte();
+                result |= (long) (b & 0x7F) << shift;
+                if ((b & 0x80) == 0)
+                    return result;
+                shift += 7;
+            }
+            throw new ProtocolException("malformed long");
+        }
+
+        /**
+         * Write variable-length {@link Long} using protobuf-style approach.
+         */
+        public static void writeVarLong(DataOutput out, long value) throws IOException {
+            while (true) {
+                if ((value & ~0x7FL) == 0) {
+                    out.writeByte((int) value);
+                    return;
+                } else {
+                    out.writeByte(((int) value & 0x7F) | 0x80);
+                    value >>>= 7;
+                }
+            }
+        }
+
+        public static long[] readVarLongArray(DataInput in) throws IOException {
+            final int size = in.readInt();
+            if (size == -1) return null;
+            if (size < 0) throw new ProtocolException("negative array size");
+            final long[] values = new long[size];
+            for (int i = 0; i < values.length; i++) {
+                values[i] = readVarLong(in);
+            }
+            return values;
+        }
+
+        public static void writeVarLongArray(DataOutput out, long[] values, int size)
+                throws IOException {
+            if (values == null) {
+                out.writeInt(-1);
+                return;
+            }
+            if (size > values.length) {
+                throw new IllegalArgumentException("size larger than length");
+            }
+            out.writeInt(size);
+            for (int i = 0; i < size; i++) {
+                writeVarLong(out, values[i]);
+            }
+        }
+    }
+
+    /**
+     * Utility methods for interacting with {@link Parcel} structures, mostly
+     * dealing with writing partial arrays.
+     * @hide
+     */
+    public static class ParcelUtils {
+        public static long[] readLongArray(Parcel in) {
+            final int size = in.readInt();
+            if (size == -1) return null;
+            final long[] values = new long[size];
+            for (int i = 0; i < values.length; i++) {
+                values[i] = in.readLong();
+            }
+            return values;
+        }
+
+        public static void writeLongArray(Parcel out, long[] values, int size) {
+            if (values == null) {
+                out.writeInt(-1);
+                return;
+            }
+            if (size > values.length) {
+                throw new IllegalArgumentException("size larger than length");
+            }
+            out.writeInt(size);
+            for (int i = 0; i < size; i++) {
+                out.writeLong(values[i]);
+            }
+        }
+    }
+
+    /**
+     * Builder class for {@link NetworkStatsHistory}.
+     */
+    public static final class Builder {
+        private final long mBucketDuration;
+        private final List<Long> mBucketStart;
+        private final List<Long> mActiveTime;
+        private final List<Long> mRxBytes;
+        private final List<Long> mRxPackets;
+        private final List<Long> mTxBytes;
+        private final List<Long> mTxPackets;
+        private final List<Long> mOperations;
+
+        /**
+         * Creates a new Builder with given bucket duration and initial capacity to construct
+         * {@link NetworkStatsHistory} objects.
+         *
+         * @param bucketDuration Duration of the buckets of the object, in milliseconds.
+         * @param initialCapacity Estimated number of records.
+         */
+        public Builder(long bucketDuration, int initialCapacity) {
+            mBucketDuration = bucketDuration;
+            mBucketStart = new ArrayList<>(initialCapacity);
+            mActiveTime = new ArrayList<>(initialCapacity);
+            mRxBytes = new ArrayList<>(initialCapacity);
+            mRxPackets = new ArrayList<>(initialCapacity);
+            mTxBytes = new ArrayList<>(initialCapacity);
+            mTxPackets = new ArrayList<>(initialCapacity);
+            mOperations = new ArrayList<>(initialCapacity);
+        }
+
+        /**
+         * Add an {@link Entry} into the {@link NetworkStatsHistory} instance.
+         *
+         * @param entry The target {@link Entry} object.
+         * @return The builder object.
+         */
+        @NonNull
+        public Builder addEntry(@NonNull Entry entry) {
+            mBucketStart.add(entry.bucketStart);
+            mActiveTime.add(entry.activeTime);
+            mRxBytes.add(entry.rxBytes);
+            mRxPackets.add(entry.rxPackets);
+            mTxBytes.add(entry.txBytes);
+            mTxPackets.add(entry.txPackets);
+            mOperations.add(entry.operations);
+            return this;
+        }
+
+        private static long sum(@NonNull List<Long> list) {
+            long sum = 0;
+            for (long entry : list) {
+                sum += entry;
+            }
+            return sum;
+        }
+
+        /**
+         * Builds the instance of the {@link NetworkStatsHistory}.
+         *
+         * @return the built instance of {@link NetworkStatsHistory}.
+         */
+        @NonNull
+        public NetworkStatsHistory build() {
+            return new NetworkStatsHistory(mBucketDuration,
+                    CollectionUtils.toLongArray(mBucketStart),
+                    CollectionUtils.toLongArray(mActiveTime),
+                    CollectionUtils.toLongArray(mRxBytes),
+                    CollectionUtils.toLongArray(mRxPackets),
+                    CollectionUtils.toLongArray(mTxBytes),
+                    CollectionUtils.toLongArray(mTxPackets),
+                    CollectionUtils.toLongArray(mOperations),
+                    mBucketStart.size(),
+                    sum(mRxBytes) + sum(mTxBytes));
+        }
+    }
+}
diff --git a/framework-t/src/android/net/NetworkTemplate.java b/framework-t/src/android/net/NetworkTemplate.java
new file mode 100644
index 0000000..7b5afd7
--- /dev/null
+++ b/framework-t/src/android/net/NetworkTemplate.java
@@ -0,0 +1,1119 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
+import static android.net.ConnectivityManager.TYPE_ETHERNET;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_PROXY;
+import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
+import static android.net.ConnectivityManager.TYPE_WIMAX;
+import static android.net.NetworkIdentity.OEM_NONE;
+import static android.net.NetworkIdentity.OEM_PAID;
+import static android.net.NetworkIdentity.OEM_PRIVATE;
+import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
+import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
+import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
+import static android.net.NetworkStats.METERED_ALL;
+import static android.net.NetworkStats.METERED_NO;
+import static android.net.NetworkStats.METERED_YES;
+import static android.net.NetworkStats.ROAMING_ALL;
+import static android.net.NetworkStats.ROAMING_NO;
+import static android.net.NetworkStats.ROAMING_YES;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.usage.NetworkStatsManager;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.net.wifi.WifiInfo;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.ArraySet;
+
+import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.NetworkIdentityUtils;
+import com.android.net.module.util.NetworkStatsUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Predicate used to match {@link NetworkIdentity}, usually when collecting
+ * statistics. (It should probably have been named {@code NetworkPredicate}.)
+ *
+ * @hide
+ */
+@SystemApi(client = MODULE_LIBRARIES)
+public final class NetworkTemplate implements Parcelable {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "MATCH_" }, value = {
+            MATCH_MOBILE,
+            MATCH_WIFI,
+            MATCH_ETHERNET,
+            MATCH_BLUETOOTH,
+            MATCH_PROXY,
+            MATCH_CARRIER,
+    })
+    public @interface TemplateMatchRule{}
+
+    /** Match rule to match cellular networks with given Subscriber Ids. */
+    public static final int MATCH_MOBILE = 1;
+    /** Match rule to match wifi networks. */
+    public static final int MATCH_WIFI = 4;
+    /** Match rule to match ethernet networks. */
+    public static final int MATCH_ETHERNET = 5;
+    /**
+     * Match rule to match all cellular networks.
+     *
+     * @hide
+     */
+    public static final int MATCH_MOBILE_WILDCARD = 6;
+    /**
+     * Match rule to match all wifi networks.
+     *
+     * @hide
+     */
+    public static final int MATCH_WIFI_WILDCARD = 7;
+    /** Match rule to match bluetooth networks. */
+    public static final int MATCH_BLUETOOTH = 8;
+    /**
+     * Match rule to match networks with {@link ConnectivityManager#TYPE_PROXY} as the legacy
+     * network type.
+     */
+    public static final int MATCH_PROXY = 9;
+    /**
+     * Match rule to match all networks with subscriberId inside the template. Some carriers
+     * may offer non-cellular networks like WiFi, which will be matched by this rule.
+     */
+    public static final int MATCH_CARRIER = 10;
+
+    // TODO: Remove this and replace all callers with WIFI_NETWORK_KEY_ALL.
+    /** @hide */
+    public static final String WIFI_NETWORKID_ALL = null;
+
+    /**
+     * Wi-Fi Network Key is never supposed to be null (if it is, it is a bug that
+     * should be fixed), so it's not possible to want to match null vs
+     * non-null. Therefore it's fine to use null as a sentinel for Wifi Network Key.
+     *
+     * @hide
+     */
+    public static final String WIFI_NETWORK_KEY_ALL = WIFI_NETWORKID_ALL;
+
+    /**
+     * Include all network types when filtering. This is meant to merge in with the
+     * {@code TelephonyManager.NETWORK_TYPE_*} constants, and thus needs to stay in sync.
+     */
+    public static final int NETWORK_TYPE_ALL = -1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "OEM_MANAGED_" }, value = {
+            OEM_MANAGED_ALL,
+            OEM_MANAGED_NO,
+            OEM_MANAGED_YES,
+            OEM_MANAGED_PAID,
+            OEM_MANAGED_PRIVATE
+    })
+    public @interface OemManaged{}
+
+    /**
+     * Value to match both OEM managed and unmanaged networks (all networks).
+     */
+    public static final int OEM_MANAGED_ALL = -1;
+    /**
+     * Value to match networks which are not OEM managed.
+     */
+    public static final int OEM_MANAGED_NO = OEM_NONE;
+    /**
+     * Value to match any OEM managed network.
+     */
+    public static final int OEM_MANAGED_YES = -2;
+    /**
+     * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}.
+     */
+    public static final int OEM_MANAGED_PAID = OEM_PAID;
+    /**
+     * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}.
+     */
+    public static final int OEM_MANAGED_PRIVATE = OEM_PRIVATE;
+
+    private static boolean isKnownMatchRule(final int rule) {
+        switch (rule) {
+            case MATCH_MOBILE:
+            case MATCH_WIFI:
+            case MATCH_ETHERNET:
+            case MATCH_MOBILE_WILDCARD:
+            case MATCH_WIFI_WILDCARD:
+            case MATCH_BLUETOOTH:
+            case MATCH_PROXY:
+            case MATCH_CARRIER:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
+     * the given IMSI.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
+        return new NetworkTemplate(MATCH_MOBILE, subscriberId, null);
+    }
+
+    /**
+     * Template to match cellular networks with the given IMSI, {@code ratType} and
+     * {@code metered}. Use {@link #NETWORK_TYPE_ALL} to include all network types when
+     * filtering. See {@code TelephonyManager.NETWORK_TYPE_*}.
+     *
+     * @hide
+     */
+    public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId,
+            int ratType, int metered) {
+        if (TextUtils.isEmpty(subscriberId)) {
+            return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null /* subscriberId */,
+                    null /* matchSubscriberIds */,
+                    new String[0] /* matchWifiNetworkKeys */, metered, ROAMING_ALL,
+                    DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
+                    NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
+        }
+        return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[] { subscriberId },
+                new String[0] /* matchWifiNetworkKeys */,
+                metered, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
+                NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
+    }
+
+    /**
+     * Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks,
+     * regardless of IMSI.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static NetworkTemplate buildTemplateMobileWildcard() {
+        return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null);
+    }
+
+    /**
+     * Template to match all metered {@link ConnectivityManager#TYPE_WIFI} networks,
+     * regardless of key of the wifi network.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static NetworkTemplate buildTemplateWifiWildcard() {
+        // TODO: Consider replace this with MATCH_WIFI with NETWORK_ID_ALL
+        // and SUBSCRIBER_ID_MATCH_RULE_ALL.
+        return new NetworkTemplate(MATCH_WIFI_WILDCARD, null, null);
+    }
+
+    /** @hide */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static NetworkTemplate buildTemplateWifi() {
+        return buildTemplateWifiWildcard();
+    }
+
+    /**
+     * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
+     * given key of the wifi network.
+     *
+     * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()}
+     *                  to know details about the key.
+     * @hide
+     */
+    public static NetworkTemplate buildTemplateWifi(@NonNull String wifiNetworkKey) {
+        Objects.requireNonNull(wifiNetworkKey);
+        return new NetworkTemplate(MATCH_WIFI, null /* subscriberId */,
+                new String[] { null } /* matchSubscriberIds */,
+                new String[] { wifiNetworkKey }, METERED_ALL, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
+                NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL);
+    }
+
+    /**
+     * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks with the given
+     * key of the wifi network and IMSI.
+     *
+     * Call with {@link #WIFI_NETWORK_KEY_ALL} for {@code wifiNetworkKey} to get result regardless
+     * of key of the wifi network.
+     *
+     * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()}
+     *                  to know details about the key.
+     * @param subscriberId the IMSI associated to this wifi network.
+     *
+     * @hide
+     */
+    public static NetworkTemplate buildTemplateWifi(@Nullable String wifiNetworkKey,
+            @Nullable String subscriberId) {
+        return new NetworkTemplate(MATCH_WIFI, subscriberId, new String[] { subscriberId },
+                wifiNetworkKey != null
+                        ? new String[] { wifiNetworkKey } : new String[0],
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
+                NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
+    }
+
+    /**
+     * Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
+     * networks together.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static NetworkTemplate buildTemplateEthernet() {
+        return new NetworkTemplate(MATCH_ETHERNET, null, null);
+    }
+
+    /**
+     * Template to combine all {@link ConnectivityManager#TYPE_BLUETOOTH} style
+     * networks together.
+     *
+     * @hide
+     */
+    public static NetworkTemplate buildTemplateBluetooth() {
+        return new NetworkTemplate(MATCH_BLUETOOTH, null, null);
+    }
+
+    /**
+     * Template to combine all {@link ConnectivityManager#TYPE_PROXY} style
+     * networks together.
+     *
+     * @hide
+     */
+    public static NetworkTemplate buildTemplateProxy() {
+        return new NetworkTemplate(MATCH_PROXY, null, null);
+    }
+
+    /**
+     * Template to match all metered carrier networks with the given IMSI.
+     *
+     * @hide
+     */
+    public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) {
+        Objects.requireNonNull(subscriberId);
+        return new NetworkTemplate(MATCH_CARRIER, subscriberId,
+                new String[] { subscriberId },
+                new String[0] /* matchWifiNetworkKeys */,
+                METERED_YES, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
+                NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
+    }
+
+    private final int mMatchRule;
+    private final String mSubscriberId;
+
+    /**
+     * Ugh, templates are designed to target a single subscriber, but we might
+     * need to match several "merged" subscribers. These are the subscribers
+     * that should be considered to match this template.
+     * <p>
+     * Since the merge set is dynamic, it should <em>not</em> be persisted or
+     * used for determining equality.
+     */
+    private final String[] mMatchSubscriberIds;
+
+    @NonNull
+    private final String[] mMatchWifiNetworkKeys;
+
+    // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*.
+    private final int mMetered;
+    private final int mRoaming;
+    private final int mDefaultNetwork;
+    private final int mRatType;
+    /**
+     * The subscriber Id match rule defines how the template should match networks with
+     * specific subscriberId(s). See NetworkTemplate#SUBSCRIBER_ID_MATCH_RULE_* for more detail.
+     */
+    private final int mSubscriberIdMatchRule;
+
+    // Bitfield containing OEM network properties{@code NetworkIdentity#OEM_*}.
+    private final int mOemManaged;
+
+    private static void checkValidSubscriberIdMatchRule(int matchRule, int subscriberIdMatchRule) {
+        switch (matchRule) {
+            case MATCH_MOBILE:
+            case MATCH_CARRIER:
+                // MOBILE and CARRIER templates must always specify a subscriber ID.
+                if (subscriberIdMatchRule == NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL) {
+                    throw new IllegalArgumentException("Invalid SubscriberIdMatchRule "
+                            + "on match rule: " + getMatchRuleName(matchRule));
+                }
+                return;
+            default:
+                return;
+        }
+    }
+
+    /** @hide */
+    // TODO: Deprecate this constructor, mark it @UnsupportedAppUsage(maxTargetSdk = S)
+    @UnsupportedAppUsage
+    public NetworkTemplate(int matchRule, String subscriberId, String wifiNetworkKey) {
+        this(matchRule, subscriberId, new String[] { subscriberId }, wifiNetworkKey);
+    }
+
+    /** @hide */
+    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
+            String wifiNetworkKey) {
+        // Older versions used to only match MATCH_MOBILE and MATCH_MOBILE_WILDCARD templates
+        // to metered networks. It is now possible to match mobile with any meteredness, but
+        // in order to preserve backward compatibility of @UnsupportedAppUsage methods, this
+        //constructor passes METERED_YES for these types.
+        this(matchRule, subscriberId, matchSubscriberIds,
+                wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0],
+                (matchRule == MATCH_MOBILE || matchRule == MATCH_MOBILE_WILDCARD) ? METERED_YES
+                : METERED_ALL , ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                OEM_MANAGED_ALL, NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
+    }
+
+    /** @hide */
+    // TODO: Remove it after updating all of the caller.
+    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
+            String wifiNetworkKey, int metered, int roaming, int defaultNetwork, int ratType,
+            int oemManaged) {
+        this(matchRule, subscriberId, matchSubscriberIds,
+                wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0],
+                metered, roaming, defaultNetwork, ratType, oemManaged,
+                NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
+    }
+
+    /** @hide */
+    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
+            String[] matchWifiNetworkKeys, int metered, int roaming,
+            int defaultNetwork, int ratType, int oemManaged, int subscriberIdMatchRule) {
+        Objects.requireNonNull(matchWifiNetworkKeys);
+        mMatchRule = matchRule;
+        mSubscriberId = subscriberId;
+        // TODO: Check whether mMatchSubscriberIds = null or mMatchSubscriberIds = {null} when
+        // mSubscriberId is null
+        mMatchSubscriberIds = matchSubscriberIds;
+        mMatchWifiNetworkKeys = matchWifiNetworkKeys;
+        mMetered = metered;
+        mRoaming = roaming;
+        mDefaultNetwork = defaultNetwork;
+        mRatType = ratType;
+        mOemManaged = oemManaged;
+        mSubscriberIdMatchRule = subscriberIdMatchRule;
+        checkValidSubscriberIdMatchRule(matchRule, subscriberIdMatchRule);
+        if (!isKnownMatchRule(matchRule)) {
+            throw new IllegalArgumentException("Unknown network template rule " + matchRule
+                    + " will not match any identity.");
+        }
+    }
+
+    private NetworkTemplate(Parcel in) {
+        mMatchRule = in.readInt();
+        mSubscriberId = in.readString();
+        mMatchSubscriberIds = in.createStringArray();
+        mMatchWifiNetworkKeys = in.createStringArray();
+        mMetered = in.readInt();
+        mRoaming = in.readInt();
+        mDefaultNetwork = in.readInt();
+        mRatType = in.readInt();
+        mOemManaged = in.readInt();
+        mSubscriberIdMatchRule = in.readInt();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mMatchRule);
+        dest.writeString(mSubscriberId);
+        dest.writeStringArray(mMatchSubscriberIds);
+        dest.writeStringArray(mMatchWifiNetworkKeys);
+        dest.writeInt(mMetered);
+        dest.writeInt(mRoaming);
+        dest.writeInt(mDefaultNetwork);
+        dest.writeInt(mRatType);
+        dest.writeInt(mOemManaged);
+        dest.writeInt(mSubscriberIdMatchRule);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder("NetworkTemplate: ");
+        builder.append("matchRule=").append(getMatchRuleName(mMatchRule));
+        if (mSubscriberId != null) {
+            builder.append(", subscriberId=").append(
+                    NetworkIdentityUtils.scrubSubscriberId(mSubscriberId));
+        }
+        if (mMatchSubscriberIds != null) {
+            builder.append(", matchSubscriberIds=").append(
+                    Arrays.toString(NetworkIdentityUtils.scrubSubscriberIds(mMatchSubscriberIds)));
+        }
+        builder.append(", matchWifiNetworkKeys=").append(Arrays.toString(mMatchWifiNetworkKeys));
+        if (mMetered != METERED_ALL) {
+            builder.append(", metered=").append(NetworkStats.meteredToString(mMetered));
+        }
+        if (mRoaming != ROAMING_ALL) {
+            builder.append(", roaming=").append(NetworkStats.roamingToString(mRoaming));
+        }
+        if (mDefaultNetwork != DEFAULT_NETWORK_ALL) {
+            builder.append(", defaultNetwork=").append(NetworkStats.defaultNetworkToString(
+                    mDefaultNetwork));
+        }
+        if (mRatType != NETWORK_TYPE_ALL) {
+            builder.append(", ratType=").append(mRatType);
+        }
+        if (mOemManaged != OEM_MANAGED_ALL) {
+            builder.append(", oemManaged=").append(getOemManagedNames(mOemManaged));
+        }
+        builder.append(", subscriberIdMatchRule=")
+                .append(subscriberIdMatchRuleToString(mSubscriberIdMatchRule));
+        return builder.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mMatchRule, mSubscriberId, Arrays.hashCode(mMatchWifiNetworkKeys),
+                mMetered, mRoaming, mDefaultNetwork, mRatType, mOemManaged, mSubscriberIdMatchRule);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj instanceof NetworkTemplate) {
+            final NetworkTemplate other = (NetworkTemplate) obj;
+            return mMatchRule == other.mMatchRule
+                    && Objects.equals(mSubscriberId, other.mSubscriberId)
+                    && mMetered == other.mMetered
+                    && mRoaming == other.mRoaming
+                    && mDefaultNetwork == other.mDefaultNetwork
+                    && mRatType == other.mRatType
+                    && mOemManaged == other.mOemManaged
+                    && mSubscriberIdMatchRule == other.mSubscriberIdMatchRule
+                    && Arrays.equals(mMatchWifiNetworkKeys, other.mMatchWifiNetworkKeys);
+        }
+        return false;
+    }
+
+    private static String subscriberIdMatchRuleToString(int rule) {
+        switch (rule) {
+            case NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT:
+                return "EXACT_MATCH";
+            case NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL:
+                return "ALL";
+            default:
+                return "Unknown rule " + rule;
+        }
+    }
+
+    /** @hide */
+    public boolean isMatchRuleMobile() {
+        switch (mMatchRule) {
+            case MATCH_MOBILE:
+            case MATCH_MOBILE_WILDCARD:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Get match rule of the template. See {@code MATCH_*}.
+     */
+    @UnsupportedAppUsage
+    public int getMatchRule() {
+        // Wildcard rules are not exposed. For external callers, convert wildcard rules to
+        // exposed rules before returning.
+        switch (mMatchRule) {
+            case MATCH_MOBILE_WILDCARD:
+                return MATCH_MOBILE;
+            case MATCH_WIFI_WILDCARD:
+                return MATCH_WIFI;
+            default:
+                return mMatchRule;
+        }
+    }
+
+    /**
+     * Get subscriber Id of the template.
+     * @hide
+     */
+    @Nullable
+    @UnsupportedAppUsage
+    public String getSubscriberId() {
+        return mSubscriberId;
+    }
+
+    /**
+     * Get set of subscriber Ids of the template.
+     */
+    @NonNull
+    public Set<String> getSubscriberIds() {
+        return new ArraySet<>(Arrays.asList(mMatchSubscriberIds));
+    }
+
+    /**
+     * Get the set of Wifi Network Keys of the template.
+     * See {@link WifiInfo#getNetworkKey()}.
+     */
+    @NonNull
+    public Set<String> getWifiNetworkKeys() {
+        return new ArraySet<>(Arrays.asList(mMatchWifiNetworkKeys));
+    }
+
+    /** @hide */
+    // TODO: Remove this and replace all callers with {@link #getWifiNetworkKeys()}.
+    @Nullable
+    public String getNetworkId() {
+        return getWifiNetworkKeys().isEmpty() ? null : getWifiNetworkKeys().iterator().next();
+    }
+
+    /**
+     * Get meteredness filter of the template.
+     */
+    @NetworkStats.Meteredness
+    public int getMeteredness() {
+        return mMetered;
+    }
+
+    /**
+     * Get roaming filter of the template.
+     */
+    @NetworkStats.Roaming
+    public int getRoaming() {
+        return mRoaming;
+    }
+
+    /**
+     * Get the default network status filter of the template.
+     */
+    @NetworkStats.DefaultNetwork
+    public int getDefaultNetworkStatus() {
+        return mDefaultNetwork;
+    }
+
+    /**
+     * Get the Radio Access Technology(RAT) type filter of the template.
+     */
+    public int getRatType() {
+        return mRatType;
+    }
+
+    /**
+     * Get the OEM managed filter of the template. See {@code OEM_MANAGED_*} or
+     * {@code android.net.NetworkIdentity#OEM_*}.
+     */
+    @OemManaged
+    public int getOemManaged() {
+        return mOemManaged;
+    }
+
+    /**
+     * Test if given {@link NetworkIdentity} matches this template.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public boolean matches(@NonNull NetworkIdentity ident) {
+        Objects.requireNonNull(ident);
+        if (!matchesMetered(ident)) return false;
+        if (!matchesRoaming(ident)) return false;
+        if (!matchesDefaultNetwork(ident)) return false;
+        if (!matchesOemNetwork(ident)) return false;
+
+        switch (mMatchRule) {
+            case MATCH_MOBILE:
+                return matchesMobile(ident);
+            case MATCH_WIFI:
+                return matchesWifi(ident);
+            case MATCH_ETHERNET:
+                return matchesEthernet(ident);
+            case MATCH_MOBILE_WILDCARD:
+                return matchesMobileWildcard(ident);
+            case MATCH_WIFI_WILDCARD:
+                return matchesWifiWildcard(ident);
+            case MATCH_BLUETOOTH:
+                return matchesBluetooth(ident);
+            case MATCH_PROXY:
+                return matchesProxy(ident);
+            case MATCH_CARRIER:
+                return matchesCarrier(ident);
+            default:
+                // We have no idea what kind of network template we are, so we
+                // just claim not to match anything.
+                return false;
+        }
+    }
+
+    private boolean matchesMetered(NetworkIdentity ident) {
+        return (mMetered == METERED_ALL)
+            || (mMetered == METERED_YES && ident.mMetered)
+            || (mMetered == METERED_NO && !ident.mMetered);
+    }
+
+    private boolean matchesRoaming(NetworkIdentity ident) {
+        return (mRoaming == ROAMING_ALL)
+            || (mRoaming == ROAMING_YES && ident.mRoaming)
+            || (mRoaming == ROAMING_NO && !ident.mRoaming);
+    }
+
+    private boolean matchesDefaultNetwork(NetworkIdentity ident) {
+        return (mDefaultNetwork == DEFAULT_NETWORK_ALL)
+            || (mDefaultNetwork == DEFAULT_NETWORK_YES && ident.mDefaultNetwork)
+            || (mDefaultNetwork == DEFAULT_NETWORK_NO && !ident.mDefaultNetwork);
+    }
+
+    private boolean matchesOemNetwork(NetworkIdentity ident) {
+        return (mOemManaged == OEM_MANAGED_ALL)
+            || (mOemManaged == OEM_MANAGED_YES
+                    && ident.mOemManaged != OEM_NONE)
+            || (mOemManaged == ident.mOemManaged);
+    }
+
+    private boolean matchesCollapsedRatType(NetworkIdentity ident) {
+        return mRatType == NETWORK_TYPE_ALL
+                || NetworkStatsManager.getCollapsedRatType(mRatType)
+                == NetworkStatsManager.getCollapsedRatType(ident.mRatType);
+    }
+
+    /**
+     * Check if this template matches {@code subscriberId}. Returns true if this
+     * template was created with {@code SUBSCRIBER_ID_MATCH_RULE_ALL}, or with a
+     * {@code mMatchSubscriberIds} array that contains {@code subscriberId}.
+     *
+     * @hide
+     */
+    public boolean matchesSubscriberId(@Nullable String subscriberId) {
+        return mSubscriberIdMatchRule == NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
+                || CollectionUtils.contains(mMatchSubscriberIds, subscriberId);
+    }
+
+    /**
+     * Check if network matches key of the wifi network.
+     * Returns true when the key matches, or when {@code mMatchWifiNetworkKeys} is
+     * empty.
+     *
+     * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()}
+     *                  to know details about the key.
+     */
+    private boolean matchesWifiNetworkKey(@NonNull String wifiNetworkKey) {
+        Objects.requireNonNull(wifiNetworkKey);
+        return CollectionUtils.isEmpty(mMatchWifiNetworkKeys)
+                || CollectionUtils.contains(mMatchWifiNetworkKeys, wifiNetworkKey);
+    }
+
+    /**
+     * Check if mobile network matches IMSI.
+     */
+    private boolean matchesMobile(NetworkIdentity ident) {
+        if (ident.mType == TYPE_WIMAX) {
+            // TODO: consider matching against WiMAX subscriber identity
+            return true;
+        } else {
+            return ident.mType == TYPE_MOBILE && !CollectionUtils.isEmpty(mMatchSubscriberIds)
+                    && CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId)
+                    && matchesCollapsedRatType(ident);
+        }
+    }
+
+    /**
+     * Check if matches Wi-Fi network template.
+     */
+    private boolean matchesWifi(NetworkIdentity ident) {
+        switch (ident.mType) {
+            case TYPE_WIFI:
+                return matchesSubscriberId(ident.mSubscriberId)
+                        && matchesWifiNetworkKey(ident.mWifiNetworkKey);
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Check if matches Ethernet network template.
+     */
+    private boolean matchesEthernet(NetworkIdentity ident) {
+        if (ident.mType == TYPE_ETHERNET) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check if matches carrier network. The carrier networks means it includes the subscriberId.
+     */
+    private boolean matchesCarrier(NetworkIdentity ident) {
+        return ident.mSubscriberId != null
+                && !CollectionUtils.isEmpty(mMatchSubscriberIds)
+                && CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
+    }
+
+    private boolean matchesMobileWildcard(NetworkIdentity ident) {
+        if (ident.mType == TYPE_WIMAX) {
+            return true;
+        } else {
+            return ident.mType == TYPE_MOBILE && matchesCollapsedRatType(ident);
+        }
+    }
+
+    private boolean matchesWifiWildcard(NetworkIdentity ident) {
+        switch (ident.mType) {
+            case TYPE_WIFI:
+            case TYPE_WIFI_P2P:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Check if matches Bluetooth network template.
+     */
+    private boolean matchesBluetooth(NetworkIdentity ident) {
+        if (ident.mType == TYPE_BLUETOOTH) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check if matches Proxy network template.
+     */
+    private boolean matchesProxy(NetworkIdentity ident) {
+        return ident.mType == TYPE_PROXY;
+    }
+
+    private static String getMatchRuleName(int matchRule) {
+        switch (matchRule) {
+            case MATCH_MOBILE:
+                return "MOBILE";
+            case MATCH_WIFI:
+                return "WIFI";
+            case MATCH_ETHERNET:
+                return "ETHERNET";
+            case MATCH_MOBILE_WILDCARD:
+                return "MOBILE_WILDCARD";
+            case MATCH_WIFI_WILDCARD:
+                return "WIFI_WILDCARD";
+            case MATCH_BLUETOOTH:
+                return "BLUETOOTH";
+            case MATCH_PROXY:
+                return "PROXY";
+            case MATCH_CARRIER:
+                return "CARRIER";
+            default:
+                return "UNKNOWN(" + matchRule + ")";
+        }
+    }
+
+    private static String getOemManagedNames(int oemManaged) {
+        switch (oemManaged) {
+            case OEM_MANAGED_ALL:
+                return "OEM_MANAGED_ALL";
+            case OEM_MANAGED_NO:
+                return "OEM_MANAGED_NO";
+            case OEM_MANAGED_YES:
+                return "OEM_MANAGED_YES";
+            default:
+                return NetworkIdentity.getOemManagedNames(oemManaged);
+        }
+    }
+
+    /**
+     * Examine the given template and normalize it.
+     * We pick the "lowest" merged subscriber as the primary
+     * for key purposes, and expand the template to match all other merged
+     * subscribers.
+     * <p>
+     * For example, given an incoming template matching B, and the currently
+     * active merge set [A,B], we'd return a new template that primarily matches
+     * A, but also matches B.
+     * TODO: remove and use {@link #normalize(NetworkTemplate, List)}.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static NetworkTemplate normalize(NetworkTemplate template, String[] merged) {
+        return normalize(template, Arrays.<String[]>asList(merged));
+    }
+
+    /**
+     * Examine the given template and normalize it.
+     * We pick the "lowest" merged subscriber as the primary
+     * for key purposes, and expand the template to match all other merged
+     * subscribers.
+     *
+     * There can be multiple merged subscriberIds for multi-SIM devices.
+     *
+     * <p>
+     * For example, given an incoming template matching B, and the currently
+     * active merge set [A,B], we'd return a new template that primarily matches
+     * A, but also matches B.
+     *
+     * @hide
+     */
+    // TODO: @SystemApi when ready.
+    public static NetworkTemplate normalize(NetworkTemplate template, List<String[]> mergedList) {
+        // Now there are several types of network which uses SubscriberId to store network
+        // information. For instances:
+        // The TYPE_WIFI with subscriberId means that it is a merged carrier wifi network.
+        // The TYPE_CARRIER means that the network associate to specific carrier network.
+
+        if (template.mSubscriberId == null) return template;
+
+        for (String[] merged : mergedList) {
+            if (CollectionUtils.contains(merged, template.mSubscriberId)) {
+                // Requested template subscriber is part of the merge group; return
+                // a template that matches all merged subscribers.
+                final String[] matchWifiNetworkKeys = template.mMatchWifiNetworkKeys;
+                return new NetworkTemplate(template.mMatchRule, merged[0], merged,
+                        CollectionUtils.isEmpty(matchWifiNetworkKeys)
+                                ? null : matchWifiNetworkKeys[0]);
+            }
+        }
+
+        return template;
+    }
+
+    @UnsupportedAppUsage
+    public static final @android.annotation.NonNull Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
+        @Override
+        public NetworkTemplate createFromParcel(Parcel in) {
+            return new NetworkTemplate(in);
+        }
+
+        @Override
+        public NetworkTemplate[] newArray(int size) {
+            return new NetworkTemplate[size];
+        }
+    };
+
+    /**
+     * Builder class for NetworkTemplate.
+     */
+    public static final class Builder {
+        private final int mMatchRule;
+        // Use a SortedSet to provide a deterministic order when fetching the first one.
+        @NonNull
+        private final SortedSet<String> mMatchSubscriberIds =
+                new TreeSet<>(Comparator.nullsFirst(Comparator.naturalOrder()));
+        @NonNull
+        private final SortedSet<String> mMatchWifiNetworkKeys = new TreeSet<>();
+
+        // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*.
+        private int mMetered;
+        private int mRoaming;
+        private int mDefaultNetwork;
+        private int mRatType;
+
+        // Bitfield containing OEM network properties {@code NetworkIdentity#OEM_*}.
+        private int mOemManaged;
+
+        /**
+         * Creates a new Builder with given match rule to construct NetworkTemplate objects.
+         *
+         * @param matchRule the match rule of the template, see {@code MATCH_*}.
+         */
+        public Builder(@TemplateMatchRule final int matchRule) {
+            assertRequestableMatchRule(matchRule);
+            // Initialize members with default values.
+            mMatchRule = matchRule;
+            mMetered = METERED_ALL;
+            mRoaming = ROAMING_ALL;
+            mDefaultNetwork = DEFAULT_NETWORK_ALL;
+            mRatType = NETWORK_TYPE_ALL;
+            mOemManaged = OEM_MANAGED_ALL;
+        }
+
+        /**
+         * Set the Subscriber Ids. Calling this function with an empty set represents
+         * the intention of matching any Subscriber Ids.
+         *
+         * @param subscriberIds the list of Subscriber Ids.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setSubscriberIds(@NonNull Set<String> subscriberIds) {
+            Objects.requireNonNull(subscriberIds);
+            mMatchSubscriberIds.clear();
+            mMatchSubscriberIds.addAll(subscriberIds);
+            return this;
+        }
+
+        /**
+         * Set the Wifi Network Keys. Calling this function with an empty set represents
+         * the intention of matching any Wifi Network Key.
+         *
+         * @param wifiNetworkKeys the list of Wifi Network Key,
+         *                        see {@link WifiInfo#getNetworkKey()}.
+         *                        Or an empty list to match all networks.
+         *                        Note that {@code getNetworkKey()} might get null key
+         *                        when wifi disconnects. However, the caller should never invoke
+         *                        this function with a null Wifi Network Key since such statistics
+         *                        never exists.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setWifiNetworkKeys(@NonNull Set<String> wifiNetworkKeys) {
+            Objects.requireNonNull(wifiNetworkKeys);
+            for (String key : wifiNetworkKeys) {
+                if (key == null) {
+                    throw new IllegalArgumentException("Null is not a valid key");
+                }
+            }
+            mMatchWifiNetworkKeys.clear();
+            mMatchWifiNetworkKeys.addAll(wifiNetworkKeys);
+            return this;
+        }
+
+        /**
+         * Set the meteredness filter.
+         *
+         * @param metered the meteredness filter.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setMeteredness(@NetworkStats.Meteredness int metered) {
+            mMetered = metered;
+            return this;
+        }
+
+        /**
+         * Set the roaming filter.
+         *
+         * @param roaming the roaming filter.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setRoaming(@NetworkStats.Roaming int roaming) {
+            mRoaming = roaming;
+            return this;
+        }
+
+        /**
+         * Set the default network status filter.
+         *
+         * @param defaultNetwork the default network status filter.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setDefaultNetworkStatus(@NetworkStats.DefaultNetwork int defaultNetwork) {
+            mDefaultNetwork = defaultNetwork;
+            return this;
+        }
+
+        /**
+         * Set the Radio Access Technology(RAT) type filter.
+         *
+         * @param ratType the Radio Access Technology(RAT) type filter. Use
+         *                {@link #NETWORK_TYPE_ALL} to include all network types when filtering.
+         *                See {@code TelephonyManager.NETWORK_TYPE_*}.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setRatType(int ratType) {
+            // Input will be validated with the match rule when building the template.
+            mRatType = ratType;
+            return this;
+        }
+
+        /**
+         * Set the OEM managed filter.
+         *
+         * @param oemManaged the match rule to match different type of OEM managed network or
+         *                   unmanaged networks. See {@code OEM_MANAGED_*}.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setOemManaged(@OemManaged int oemManaged) {
+            mOemManaged = oemManaged;
+            return this;
+        }
+
+        /**
+         * Check whether the match rule is requestable.
+         *
+         * @param matchRule the target match rule to be checked.
+         */
+        private static void assertRequestableMatchRule(final int matchRule) {
+            if (!isKnownMatchRule(matchRule)
+                    || matchRule == MATCH_PROXY
+                    || matchRule == MATCH_MOBILE_WILDCARD
+                    || matchRule == MATCH_WIFI_WILDCARD) {
+                throw new IllegalArgumentException("Invalid match rule: "
+                        + getMatchRuleName(matchRule));
+            }
+        }
+
+        private void assertRequestableParameters() {
+            validateWifiNetworkKeys();
+            // TODO: Check all the input are legitimate.
+        }
+
+        private void validateWifiNetworkKeys() {
+            if (mMatchRule != MATCH_WIFI && !mMatchWifiNetworkKeys.isEmpty()) {
+                throw new IllegalArgumentException("Trying to build non wifi match rule: "
+                        + mMatchRule + " with wifi network keys");
+            }
+        }
+
+        /**
+         * For backward compatibility, deduce match rule to a wildcard match rule
+         * if the Subscriber Ids are empty.
+         */
+        private int getWildcardDeducedMatchRule() {
+            if (mMatchRule == MATCH_MOBILE && mMatchSubscriberIds.isEmpty()) {
+                return MATCH_MOBILE_WILDCARD;
+            } else if (mMatchRule == MATCH_WIFI && mMatchSubscriberIds.isEmpty()
+                    && mMatchWifiNetworkKeys.isEmpty()) {
+                return MATCH_WIFI_WILDCARD;
+            }
+            return mMatchRule;
+        }
+
+        /**
+         * Builds the instance of the NetworkTemplate.
+         *
+         * @return the built instance of NetworkTemplate.
+         */
+        @NonNull
+        public NetworkTemplate build() {
+            assertRequestableParameters();
+            final int subscriberIdMatchRule = mMatchSubscriberIds.isEmpty()
+                    ? NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
+                    : NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT;
+            return new NetworkTemplate(getWildcardDeducedMatchRule(),
+                    mMatchSubscriberIds.isEmpty() ? null : mMatchSubscriberIds.iterator().next(),
+                    mMatchSubscriberIds.toArray(new String[0]),
+                    mMatchWifiNetworkKeys.toArray(new String[0]), mMetered, mRoaming,
+                    mDefaultNetwork, mRatType, mOemManaged, subscriberIdMatchRule);
+        }
+    }
+}
diff --git a/framework-t/src/android/net/TrafficStats.java b/framework-t/src/android/net/TrafficStats.java
new file mode 100644
index 0000000..dc4ac55
--- /dev/null
+++ b/framework-t/src/android/net/TrafficStats.java
@@ -0,0 +1,1148 @@
+/*
+ * Copyright (C) 2007 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;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.app.DownloadManager;
+import android.app.backup.BackupManager;
+import android.app.usage.NetworkStatsManager;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.os.Binder;
+import android.os.Build;
+import android.os.RemoteException;
+import android.os.StrictMode;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.Socket;
+import java.net.SocketException;
+
+/**
+ * Class that provides network traffic statistics. These statistics include
+ * bytes transmitted and received and network packets transmitted and received,
+ * over all interfaces, over the mobile interface, and on a per-UID basis.
+ * <p>
+ * These statistics may not be available on all platforms. If the statistics are
+ * not supported by this device, {@link #UNSUPPORTED} will be returned.
+ * <p>
+ * Note that the statistics returned by this class reset and start from zero
+ * after every reboot. To access more robust historical network statistics data,
+ * use {@link NetworkStatsManager} instead.
+ */
+public class TrafficStats {
+    static {
+        System.loadLibrary("framework-connectivity-tiramisu-jni");
+    }
+
+    private static final String TAG = TrafficStats.class.getSimpleName();
+    /**
+     * The return value to indicate that the device does not support the statistic.
+     */
+    public final static int UNSUPPORTED = -1;
+
+    /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
+    @Deprecated
+    public static final long KB_IN_BYTES = 1024;
+    /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
+    @Deprecated
+    public static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
+    /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
+    @Deprecated
+    public static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
+    /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
+    @Deprecated
+    public static final long TB_IN_BYTES = GB_IN_BYTES * 1024;
+    /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
+    @Deprecated
+    public static final long PB_IN_BYTES = TB_IN_BYTES * 1024;
+
+    /**
+     * Special UID value used when collecting {@link NetworkStatsHistory} for
+     * removed applications.
+     *
+     * @hide
+     */
+    public static final int UID_REMOVED = -4;
+
+    /**
+     * Special UID value used when collecting {@link NetworkStatsHistory} for
+     * tethering traffic.
+     *
+     * @hide
+     */
+    public static final int UID_TETHERING = NetworkStats.UID_TETHERING;
+
+    /**
+     * Tag values in this range are reserved for the network stack. The network stack is
+     * running as UID {@link android.os.Process.NETWORK_STACK_UID} when in the mainline
+     * module separate process, and as the system UID otherwise.
+     */
+    /** @hide */
+    @SystemApi
+    public static final int TAG_NETWORK_STACK_RANGE_START = 0xFFFFFD00;
+    /** @hide */
+    @SystemApi
+    public static final int TAG_NETWORK_STACK_RANGE_END = 0xFFFFFEFF;
+
+    /**
+     * Tags between 0xFFFFFF00 and 0xFFFFFFFF are reserved and used internally by system services
+     * like DownloadManager when performing traffic on behalf of an application.
+     */
+    // Please note there is no enforcement of these constants, so do not rely on them to
+    // determine that the caller is a system caller.
+    /** @hide */
+    @SystemApi
+    public static final int TAG_SYSTEM_IMPERSONATION_RANGE_START = 0xFFFFFF00;
+    /** @hide */
+    @SystemApi
+    public static final int TAG_SYSTEM_IMPERSONATION_RANGE_END = 0xFFFFFF0F;
+
+    /**
+     * Tag values between these ranges are reserved for the network stack to do traffic
+     * on behalf of applications. It is a subrange of the range above.
+     */
+    /** @hide */
+    @SystemApi
+    public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_START = 0xFFFFFF80;
+    /** @hide */
+    @SystemApi
+    public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_END = 0xFFFFFF8F;
+
+    /**
+     * Default tag value for {@link DownloadManager} traffic.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFFFF01;
+
+    /**
+     * Default tag value for {@link MediaPlayer} traffic.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_MEDIA = 0xFFFFFF02;
+
+    /**
+     * Default tag value for {@link BackupManager} backup traffic; that is,
+     * traffic from the device to the storage backend.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03;
+
+    /**
+     * Default tag value for {@link BackupManager} restore traffic; that is,
+     * app data retrieved from the storage backend at install time.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04;
+
+    /**
+     * Default tag value for code (typically APKs) downloaded by an app store on
+     * behalf of the app, such as updates.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_APP = 0xFFFFFF05;
+
+    // TODO : remove this constant when Wifi code is updated
+    /** @hide */
+    public static final int TAG_SYSTEM_PROBE = 0xFFFFFF42;
+
+    private static INetworkStatsService sStatsService;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
+    private synchronized static INetworkStatsService getStatsService() {
+        if (sStatsService == null) {
+            throw new IllegalStateException("TrafficStats not initialized, uid="
+                    + Binder.getCallingUid());
+        }
+        return sStatsService;
+    }
+
+    /**
+     * Snapshot of {@link NetworkStats} when the currently active profiling
+     * session started, or {@code null} if no session active.
+     *
+     * @see #startDataProfiling(Context)
+     * @see #stopDataProfiling(Context)
+     */
+    private static NetworkStats sActiveProfilingStart;
+
+    private static Object sProfilingLock = new Object();
+
+    private static final String LOOPBACK_IFACE = "lo";
+
+    /**
+     * Initialization {@link TrafficStats} with the context, to
+     * allow {@link TrafficStats} to fetch the needed binder.
+     *
+     * @param context a long-lived context, such as the application context or system
+     *                server context.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @SuppressLint("VisiblySynchronized")
+    public static synchronized void init(@NonNull final Context context) {
+        if (sStatsService != null) {
+            throw new IllegalStateException("TrafficStats is already initialized, uid="
+                    + Binder.getCallingUid());
+        }
+        final NetworkStatsManager statsManager =
+                context.getSystemService(NetworkStatsManager.class);
+        if (statsManager == null) {
+            // TODO: Currently Process.isSupplemental is not working yet, because it depends on
+            //  process to run in a certain UID range, which is not true for now. Change this
+            //  to Log.wtf once Process.isSupplemental is ready.
+            Log.e(TAG, "TrafficStats not initialized, uid=" + Binder.getCallingUid());
+            return;
+        }
+        sStatsService = statsManager.getBinder();
+    }
+
+    /**
+     * Attach the socket tagger implementation to the current process, to
+     * get notified when a socket's {@link FileDescriptor} is assigned to
+     * a thread. See {@link SocketTagger#set(SocketTagger)}.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void attachSocketTagger() {
+        dalvik.system.SocketTagger.set(new SocketTagger());
+    }
+
+    private static class SocketTagger extends dalvik.system.SocketTagger {
+
+        // TODO: set to false
+        private static final boolean LOGD = true;
+
+        SocketTagger() {
+        }
+
+        @Override
+        public void tag(FileDescriptor fd) throws SocketException {
+            final UidTag tagInfo = sThreadUidTag.get();
+            if (LOGD) {
+                Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x"
+                        + Integer.toHexString(tagInfo.tag) + ", statsUid=" + tagInfo.uid);
+            }
+            if (tagInfo.tag == -1) {
+                StrictMode.noteUntaggedSocket();
+            }
+
+            if (tagInfo.tag == -1 && tagInfo.uid == -1) return;
+            final int errno = native_tagSocketFd(fd, tagInfo.tag, tagInfo.uid);
+            if (errno < 0) {
+                Log.i(TAG, "tagSocketFd(" + fd.getInt$() + ", "
+                        + tagInfo.tag + ", "
+                        + tagInfo.uid + ") failed with errno" + errno);
+            }
+        }
+
+        @Override
+        public void untag(FileDescriptor fd) throws SocketException {
+            if (LOGD) {
+                Log.i(TAG, "untagSocket(" + fd.getInt$() + ")");
+            }
+
+            final UidTag tagInfo = sThreadUidTag.get();
+            if (tagInfo.tag == -1 && tagInfo.uid == -1) return;
+
+            final int errno = native_untagSocketFd(fd);
+            if (errno < 0) {
+                Log.w(TAG, "untagSocket(" + fd.getInt$() + ") failed with errno " + errno);
+            }
+        }
+    }
+
+    private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid);
+    private static native int native_untagSocketFd(FileDescriptor fd);
+
+    private static class UidTag {
+        public int tag = -1;
+        public int uid = -1;
+    }
+
+    private static ThreadLocal<UidTag> sThreadUidTag = new ThreadLocal<UidTag>() {
+        @Override
+        protected UidTag initialValue() {
+            return new UidTag();
+        }
+    };
+
+    /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. Only one active tag per thread is supported.
+     * <p>
+     * Changes only take effect during subsequent calls to
+     * {@link #tagSocket(Socket)}.
+     * <p>
+     * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
+     * used internally by system services like {@link DownloadManager} when
+     * performing traffic on behalf of an application.
+     *
+     * @see #clearThreadStatsTag()
+     */
+    public static void setThreadStatsTag(int tag) {
+        getAndSetThreadStatsTag(tag);
+    }
+
+    /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. Only one active tag per thread is supported.
+     * <p>
+     * Changes only take effect during subsequent calls to
+     * {@link #tagSocket(Socket)}.
+     * <p>
+     * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
+     * used internally by system services like {@link DownloadManager} when
+     * performing traffic on behalf of an application.
+     *
+     * @return the current tag for the calling thread, which can be used to
+     *         restore any existing values after a nested operation is finished
+     */
+    public static int getAndSetThreadStatsTag(int tag) {
+        final int old = sThreadUidTag.get().tag;
+        sThreadUidTag.get().tag = tag;
+        return old;
+    }
+
+    /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. The tag used internally is well-defined to
+     * distinguish all backup-related traffic.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static void setThreadStatsTagBackup() {
+        setThreadStatsTag(TAG_SYSTEM_BACKUP);
+    }
+
+    /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. The tag used internally is well-defined to
+     * distinguish all restore-related traffic.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static void setThreadStatsTagRestore() {
+        setThreadStatsTag(TAG_SYSTEM_RESTORE);
+    }
+
+    /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. The tag used internally is well-defined to
+     * distinguish all code (typically APKs) downloaded by an app store on
+     * behalf of the app, such as updates.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static void setThreadStatsTagApp() {
+        setThreadStatsTag(TAG_SYSTEM_APP);
+    }
+
+    /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. The tag used internally is well-defined to
+     * distinguish all download provider traffic.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void setThreadStatsTagDownload() {
+        setThreadStatsTag(TAG_SYSTEM_DOWNLOAD);
+    }
+
+    /**
+     * Get the active tag used when accounting {@link Socket} traffic originating
+     * from the current thread. Only one active tag per thread is supported.
+     * {@link #tagSocket(Socket)}.
+     *
+     * @see #setThreadStatsTag(int)
+     */
+    public static int getThreadStatsTag() {
+        return sThreadUidTag.get().tag;
+    }
+
+    /**
+     * Clear any active tag set to account {@link Socket} traffic originating
+     * from the current thread.
+     *
+     * @see #setThreadStatsTag(int)
+     */
+    public static void clearThreadStatsTag() {
+        sThreadUidTag.get().tag = -1;
+    }
+
+    /**
+     * Set specific UID to use when accounting {@link Socket} traffic
+     * originating from the current thread. Designed for use when performing an
+     * operation on behalf of another application, or when another application
+     * is performing operations on your behalf.
+     * <p>
+     * Any app can <em>accept</em> blame for traffic performed on a socket
+     * originally created by another app by calling this method with the
+     * {@link android.system.Os#getuid()} value. However, only apps holding the
+     * {@code android.Manifest.permission#UPDATE_DEVICE_STATS} permission may
+     * <em>assign</em> blame to another UIDs.
+     * <p>
+     * Changes only take effect during subsequent calls to
+     * {@link #tagSocket(Socket)}.
+     */
+    @SuppressLint("RequiresPermission")
+    public static void setThreadStatsUid(int uid) {
+        sThreadUidTag.get().uid = uid;
+    }
+
+    /**
+     * Get the active UID used when accounting {@link Socket} traffic originating
+     * from the current thread. Only one active tag per thread is supported.
+     * {@link #tagSocket(Socket)}.
+     *
+     * @see #setThreadStatsUid(int)
+     */
+    public static int getThreadStatsUid() {
+        return sThreadUidTag.get().uid;
+    }
+
+    /**
+     * Set specific UID to use when accounting {@link Socket} traffic
+     * originating from the current thread as the calling UID. Designed for use
+     * when another application is performing operations on your behalf.
+     * <p>
+     * Changes only take effect during subsequent calls to
+     * {@link #tagSocket(Socket)}.
+     *
+     * @removed
+     * @deprecated use {@link #setThreadStatsUid(int)} instead.
+     */
+    @Deprecated
+    public static void setThreadStatsUidSelf() {
+        setThreadStatsUid(android.os.Process.myUid());
+    }
+
+    /**
+     * Clear any active UID set to account {@link Socket} traffic originating
+     * from the current thread.
+     *
+     * @see #setThreadStatsUid(int)
+     */
+    @SuppressLint("RequiresPermission")
+    public static void clearThreadStatsUid() {
+        setThreadStatsUid(-1);
+    }
+
+    /**
+     * Tag the given {@link Socket} with any statistics parameters active for
+     * the current thread. Subsequent calls always replace any existing
+     * parameters. When finished, call {@link #untagSocket(Socket)} to remove
+     * statistics parameters.
+     *
+     * @see #setThreadStatsTag(int)
+     */
+    public static void tagSocket(@NonNull Socket socket) throws SocketException {
+        SocketTagger.get().tag(socket);
+    }
+
+    /**
+     * Remove any statistics parameters from the given {@link Socket}.
+     * <p>
+     * In Android 8.1 (API level 27) and lower, a socket is automatically
+     * untagged when it's sent to another process using binder IPC with a
+     * {@code ParcelFileDescriptor} container. In Android 9.0 (API level 28)
+     * and higher, the socket tag is kept when the socket is sent to another
+     * process using binder IPC. You can mimic the previous behavior by
+     * calling {@code untagSocket()} before sending the socket to another
+     * process.
+     */
+    public static void untagSocket(@NonNull Socket socket) throws SocketException {
+        SocketTagger.get().untag(socket);
+    }
+
+    /**
+     * Tag the given {@link DatagramSocket} with any statistics parameters
+     * active for the current thread. Subsequent calls always replace any
+     * existing parameters. When finished, call
+     * {@link #untagDatagramSocket(DatagramSocket)} to remove statistics
+     * parameters.
+     *
+     * @see #setThreadStatsTag(int)
+     */
+    public static void tagDatagramSocket(@NonNull DatagramSocket socket) throws SocketException {
+        SocketTagger.get().tag(socket);
+    }
+
+    /**
+     * Remove any statistics parameters from the given {@link DatagramSocket}.
+     */
+    public static void untagDatagramSocket(@NonNull DatagramSocket socket) throws SocketException {
+        SocketTagger.get().untag(socket);
+    }
+
+    /**
+     * Tag the given {@link FileDescriptor} socket with any statistics
+     * parameters active for the current thread. Subsequent calls always replace
+     * any existing parameters. When finished, call
+     * {@link #untagFileDescriptor(FileDescriptor)} to remove statistics
+     * parameters.
+     *
+     * @see #setThreadStatsTag(int)
+     */
+    public static void tagFileDescriptor(@NonNull FileDescriptor fd) throws IOException {
+        SocketTagger.get().tag(fd);
+    }
+
+    /**
+     * Remove any statistics parameters from the given {@link FileDescriptor}
+     * socket.
+     */
+    public static void untagFileDescriptor(@NonNull FileDescriptor fd) throws IOException {
+        SocketTagger.get().untag(fd);
+    }
+
+    /**
+     * Start profiling data usage for current UID. Only one profiling session
+     * can be active at a time.
+     *
+     * @hide
+     */
+    public static void startDataProfiling(Context context) {
+        synchronized (sProfilingLock) {
+            if (sActiveProfilingStart != null) {
+                throw new IllegalStateException("already profiling data");
+            }
+
+            // take snapshot in time; we calculate delta later
+            sActiveProfilingStart = getDataLayerSnapshotForUid(context);
+        }
+    }
+
+    /**
+     * Stop profiling data usage for current UID.
+     *
+     * @return Detailed {@link NetworkStats} of data that occurred since last
+     *         {@link #startDataProfiling(Context)} call.
+     * @hide
+     */
+    public static NetworkStats stopDataProfiling(Context context) {
+        synchronized (sProfilingLock) {
+            if (sActiveProfilingStart == null) {
+                throw new IllegalStateException("not profiling data");
+            }
+
+            // subtract starting values and return delta
+            final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
+            final NetworkStats profilingDelta = NetworkStats.subtract(
+                    profilingStop, sActiveProfilingStart, null, null);
+            sActiveProfilingStart = null;
+            return profilingDelta;
+        }
+    }
+
+    /**
+     * Increment count of network operations performed under the accounting tag
+     * currently active on the calling thread. This can be used to derive
+     * bytes-per-operation.
+     *
+     * @param operationCount Number of operations to increment count by.
+     */
+    public static void incrementOperationCount(int operationCount) {
+        final int tag = getThreadStatsTag();
+        incrementOperationCount(tag, operationCount);
+    }
+
+    /**
+     * Increment count of network operations performed under the given
+     * accounting tag. This can be used to derive bytes-per-operation.
+     *
+     * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}.
+     * @param operationCount Number of operations to increment count by.
+     */
+    public static void incrementOperationCount(int tag, int operationCount) {
+        final int uid = android.os.Process.myUid();
+        try {
+            getStatsService().incrementOperationCount(uid, tag, operationCount);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** {@hide} */
+    public static void closeQuietly(INetworkStatsSession session) {
+        // TODO: move to NetworkStatsService once it exists
+        if (session != null) {
+            try {
+                session.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    private static long addIfSupported(long stat) {
+        return (stat == UNSUPPORTED) ? 0 : stat;
+    }
+
+    /**
+     * Return number of packets transmitted across mobile networks since device
+     * boot. Counts packets across all mobile network interfaces, and always
+     * increases monotonically since device boot. Statistics are measured at the
+     * network layer, so they include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
+     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
+     */
+    public static long getMobileTxPackets() {
+        long total = 0;
+        for (String iface : getMobileIfaces()) {
+            total += addIfSupported(getTxPackets(iface));
+        }
+        return total;
+    }
+
+    /**
+     * Return number of packets received across mobile networks since device
+     * boot. Counts packets across all mobile network interfaces, and always
+     * increases monotonically since device boot. Statistics are measured at the
+     * network layer, so they include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
+     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
+     */
+    public static long getMobileRxPackets() {
+        long total = 0;
+        for (String iface : getMobileIfaces()) {
+            total += addIfSupported(getRxPackets(iface));
+        }
+        return total;
+    }
+
+    /**
+     * Return number of bytes transmitted across mobile networks since device
+     * boot. Counts packets across all mobile network interfaces, and always
+     * increases monotonically since device boot. Statistics are measured at the
+     * network layer, so they include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
+     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
+     */
+    public static long getMobileTxBytes() {
+        long total = 0;
+        for (String iface : getMobileIfaces()) {
+            total += addIfSupported(getTxBytes(iface));
+        }
+        return total;
+    }
+
+    /**
+     * Return number of bytes received across mobile networks since device boot.
+     * Counts packets across all mobile network interfaces, and always increases
+     * monotonically since device boot. Statistics are measured at the network
+     * layer, so they include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
+     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
+     */
+    public static long getMobileRxBytes() {
+        long total = 0;
+        for (String iface : getMobileIfaces()) {
+            total += addIfSupported(getRxBytes(iface));
+        }
+        return total;
+    }
+
+    /** {@hide} */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static long getMobileTcpRxPackets() {
+        long total = 0;
+        for (String iface : getMobileIfaces()) {
+            long stat = UNSUPPORTED;
+            try {
+                stat = getStatsService().getIfaceStats(iface, TYPE_TCP_RX_PACKETS);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            total += addIfSupported(stat);
+        }
+        return total;
+    }
+
+    /** {@hide} */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static long getMobileTcpTxPackets() {
+        long total = 0;
+        for (String iface : getMobileIfaces()) {
+            long stat = UNSUPPORTED;
+            try {
+                stat = getStatsService().getIfaceStats(iface, TYPE_TCP_TX_PACKETS);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            total += addIfSupported(stat);
+        }
+        return total;
+    }
+
+    /**
+     * Return the number of packets transmitted on the specified interface since the interface
+     * was created. Statistics are measured at the network layer, so both TCP and
+     * UDP usage are included.
+     *
+     * Note that the returned values are partial statistics that do not count data from several
+     * sources and do not apply several adjustments that are necessary for correctness, such
+     * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to
+     * determine whether traffic is being transferred on the specific interface but are not a
+     * substitute for the more accurate statistics provided by the {@link NetworkStatsManager}
+     * APIs.
+     *
+     * @param iface The name of the interface.
+     * @return The number of transmitted packets.
+     */
+    public static long getTxPackets(@NonNull String iface) {
+        try {
+            return getStatsService().getIfaceStats(iface, TYPE_TX_PACKETS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return the number of packets received on the specified interface since the interface was
+     * created. Statistics are measured at the network layer, so both TCP
+     * and UDP usage are included.
+     *
+     * Note that the returned values are partial statistics that do not count data from several
+     * sources and do not apply several adjustments that are necessary for correctness, such
+     * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to
+     * determine whether traffic is being transferred on the specific interface but are not a
+     * substitute for the more accurate statistics provided by the {@link NetworkStatsManager}
+     * APIs.
+     *
+     * @param iface The name of the interface.
+     * @return The number of received packets.
+     */
+    public static long getRxPackets(@NonNull String iface) {
+        try {
+            return getStatsService().getIfaceStats(iface, TYPE_RX_PACKETS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return the number of bytes transmitted on the specified interface since the interface
+     * was created. Statistics are measured at the network layer, so both TCP and
+     * UDP usage are included.
+     *
+     * Note that the returned values are partial statistics that do not count data from several
+     * sources and do not apply several adjustments that are necessary for correctness, such
+     * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to
+     * determine whether traffic is being transferred on the specific interface but are not a
+     * substitute for the more accurate statistics provided by the {@link NetworkStatsManager}
+     * APIs.
+     *
+     * @param iface The name of the interface.
+     * @return The number of transmitted bytes.
+     */
+    public static long getTxBytes(@NonNull String iface) {
+        try {
+            return getStatsService().getIfaceStats(iface, TYPE_TX_BYTES);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return the number of bytes received on the specified interface since the interface
+     * was created. Statistics are measured at the network layer, so both TCP
+     * and UDP usage are included.
+     *
+     * Note that the returned values are partial statistics that do not count data from several
+     * sources and do not apply several adjustments that are necessary for correctness, such
+     * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to
+     * determine whether traffic is being transferred on the specific interface but are not a
+     * substitute for the more accurate statistics provided by the {@link NetworkStatsManager}
+     * APIs.
+     *
+     * @param iface The name of the interface.
+     * @return The number of received bytes.
+     */
+    public static long getRxBytes(@NonNull String iface) {
+        try {
+            return getStatsService().getIfaceStats(iface, TYPE_RX_BYTES);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** {@hide} */
+    @TestApi
+    public static long getLoopbackTxPackets() {
+        try {
+            return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_TX_PACKETS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** {@hide} */
+    @TestApi
+    public static long getLoopbackRxPackets() {
+        try {
+            return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_RX_PACKETS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** {@hide} */
+    @TestApi
+    public static long getLoopbackTxBytes() {
+        try {
+            return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_TX_BYTES);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** {@hide} */
+    @TestApi
+    public static long getLoopbackRxBytes() {
+        try {
+            return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_RX_BYTES);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return number of packets transmitted since device boot. Counts packets
+     * across all network interfaces, and always increases monotonically since
+     * device boot. Statistics are measured at the network layer, so they
+     * include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
+     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
+     */
+    public static long getTotalTxPackets() {
+        try {
+            return getStatsService().getTotalStats(TYPE_TX_PACKETS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return number of packets received since device boot. Counts packets
+     * across all network interfaces, and always increases monotonically since
+     * device boot. Statistics are measured at the network layer, so they
+     * include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
+     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
+     */
+    public static long getTotalRxPackets() {
+        try {
+            return getStatsService().getTotalStats(TYPE_RX_PACKETS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return number of bytes transmitted since device boot. Counts packets
+     * across all network interfaces, and always increases monotonically since
+     * device boot. Statistics are measured at the network layer, so they
+     * include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
+     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
+     */
+    public static long getTotalTxBytes() {
+        try {
+            return getStatsService().getTotalStats(TYPE_TX_BYTES);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return number of bytes received since device boot. Counts packets across
+     * all network interfaces, and always increases monotonically since device
+     * boot. Statistics are measured at the network layer, so they include both
+     * TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
+     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
+     */
+    public static long getTotalRxBytes() {
+        try {
+            return getStatsService().getTotalStats(TYPE_RX_BYTES);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return number of bytes transmitted by the given UID since device boot.
+     * Counts packets across all network interfaces, and always increases
+     * monotonically since device boot. Statistics are measured at the network
+     * layer, so they include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
+     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
+     * report traffic statistics for the calling UID. It will return
+     * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
+     * historical network statistics belonging to other UIDs, use
+     * {@link NetworkStatsManager}.
+     *
+     * @see android.os.Process#myUid()
+     * @see android.content.pm.ApplicationInfo#uid
+     */
+    public static long getUidTxBytes(int uid) {
+        try {
+            return getStatsService().getUidStats(uid, TYPE_TX_BYTES);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return number of bytes received by the given UID since device boot.
+     * Counts packets across all network interfaces, and always increases
+     * monotonically since device boot. Statistics are measured at the network
+     * layer, so they include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
+     * {@link #UNSUPPORTED} on devices where statistics aren't available.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
+     * report traffic statistics for the calling UID. It will return
+     * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
+     * historical network statistics belonging to other UIDs, use
+     * {@link NetworkStatsManager}.
+     *
+     * @see android.os.Process#myUid()
+     * @see android.content.pm.ApplicationInfo#uid
+     */
+    public static long getUidRxBytes(int uid) {
+        try {
+            return getStatsService().getUidStats(uid, TYPE_RX_BYTES);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return number of packets transmitted by the given UID since device boot.
+     * Counts packets across all network interfaces, and always increases
+     * monotonically since device boot. Statistics are measured at the network
+     * layer, so they include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
+     * {@link #UNSUPPORTED} on devices where statistics aren't available.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
+     * report traffic statistics for the calling UID. It will return
+     * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
+     * historical network statistics belonging to other UIDs, use
+     * {@link NetworkStatsManager}.
+     *
+     * @see android.os.Process#myUid()
+     * @see android.content.pm.ApplicationInfo#uid
+     */
+    public static long getUidTxPackets(int uid) {
+        try {
+            return getStatsService().getUidStats(uid, TYPE_TX_PACKETS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return number of packets received by the given UID since device boot.
+     * Counts packets across all network interfaces, and always increases
+     * monotonically since device boot. Statistics are measured at the network
+     * layer, so they include both TCP and UDP usage.
+     * <p>
+     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
+     * {@link #UNSUPPORTED} on devices where statistics aren't available.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
+     * report traffic statistics for the calling UID. It will return
+     * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
+     * historical network statistics belonging to other UIDs, use
+     * {@link NetworkStatsManager}.
+     *
+     * @see android.os.Process#myUid()
+     * @see android.content.pm.ApplicationInfo#uid
+     */
+    public static long getUidRxPackets(int uid) {
+        try {
+            return getStatsService().getUidStats(uid, TYPE_RX_PACKETS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
+     *             transport layer statistics are no longer available, and will
+     *             always return {@link #UNSUPPORTED}.
+     * @see #getUidTxBytes(int)
+     */
+    @Deprecated
+    public static long getUidTcpTxBytes(int uid) {
+        return UNSUPPORTED;
+    }
+
+    /**
+     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
+     *             transport layer statistics are no longer available, and will
+     *             always return {@link #UNSUPPORTED}.
+     * @see #getUidRxBytes(int)
+     */
+    @Deprecated
+    public static long getUidTcpRxBytes(int uid) {
+        return UNSUPPORTED;
+    }
+
+    /**
+     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
+     *             transport layer statistics are no longer available, and will
+     *             always return {@link #UNSUPPORTED}.
+     * @see #getUidTxBytes(int)
+     */
+    @Deprecated
+    public static long getUidUdpTxBytes(int uid) {
+        return UNSUPPORTED;
+    }
+
+    /**
+     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
+     *             transport layer statistics are no longer available, and will
+     *             always return {@link #UNSUPPORTED}.
+     * @see #getUidRxBytes(int)
+     */
+    @Deprecated
+    public static long getUidUdpRxBytes(int uid) {
+        return UNSUPPORTED;
+    }
+
+    /**
+     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
+     *             transport layer statistics are no longer available, and will
+     *             always return {@link #UNSUPPORTED}.
+     * @see #getUidTxPackets(int)
+     */
+    @Deprecated
+    public static long getUidTcpTxSegments(int uid) {
+        return UNSUPPORTED;
+    }
+
+    /**
+     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
+     *             transport layer statistics are no longer available, and will
+     *             always return {@link #UNSUPPORTED}.
+     * @see #getUidRxPackets(int)
+     */
+    @Deprecated
+    public static long getUidTcpRxSegments(int uid) {
+        return UNSUPPORTED;
+    }
+
+    /**
+     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
+     *             transport layer statistics are no longer available, and will
+     *             always return {@link #UNSUPPORTED}.
+     * @see #getUidTxPackets(int)
+     */
+    @Deprecated
+    public static long getUidUdpTxPackets(int uid) {
+        return UNSUPPORTED;
+    }
+
+    /**
+     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
+     *             transport layer statistics are no longer available, and will
+     *             always return {@link #UNSUPPORTED}.
+     * @see #getUidRxPackets(int)
+     */
+    @Deprecated
+    public static long getUidUdpRxPackets(int uid) {
+        return UNSUPPORTED;
+    }
+
+    /**
+     * Return detailed {@link NetworkStats} for the current UID. Requires no
+     * special permission.
+     */
+    private static NetworkStats getDataLayerSnapshotForUid(Context context) {
+        // TODO: take snapshot locally, since proc file is now visible
+        final int uid = android.os.Process.myUid();
+        try {
+            return getStatsService().getDataLayerSnapshotForUid(uid);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return set of any ifaces associated with mobile networks since boot.
+     * Interfaces are never removed from this list, so counters should always be
+     * monotonic.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
+    private static String[] getMobileIfaces() {
+        try {
+            return getStatsService().getMobileIfaces();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    // NOTE: keep these in sync with {@code com_android_server_net_NetworkStatsService.cpp}.
+    /** {@hide} */
+    public static final int TYPE_RX_BYTES = 0;
+    /** {@hide} */
+    public static final int TYPE_RX_PACKETS = 1;
+    /** {@hide} */
+    public static final int TYPE_TX_BYTES = 2;
+    /** {@hide} */
+    public static final int TYPE_TX_PACKETS = 3;
+    /** {@hide} */
+    public static final int TYPE_TCP_RX_PACKETS = 4;
+    /** {@hide} */
+    public static final int TYPE_TCP_TX_PACKETS = 5;
+}
diff --git a/framework-t/src/android/net/UnderlyingNetworkInfo.aidl b/framework-t/src/android/net/UnderlyingNetworkInfo.aidl
new file mode 100644
index 0000000..a56f2f4
--- /dev/null
+++ b/framework-t/src/android/net/UnderlyingNetworkInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+parcelable UnderlyingNetworkInfo;
diff --git a/framework-t/src/android/net/UnderlyingNetworkInfo.java b/framework-t/src/android/net/UnderlyingNetworkInfo.java
new file mode 100644
index 0000000..7ab53b1
--- /dev/null
+++ b/framework-t/src/android/net/UnderlyingNetworkInfo.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A lightweight container used to carry information on the networks that underly a given
+ * virtual network.
+ *
+ * @hide
+ */
+@SystemApi(client = MODULE_LIBRARIES)
+public final class UnderlyingNetworkInfo implements Parcelable {
+    /** The owner of this network. */
+    private final int mOwnerUid;
+
+    /** The interface name of this network. */
+    @NonNull
+    private final String mIface;
+
+    /** The names of the interfaces underlying this network. */
+    @NonNull
+    private final List<String> mUnderlyingIfaces;
+
+    public UnderlyingNetworkInfo(int ownerUid, @NonNull String iface,
+            @NonNull List<String> underlyingIfaces) {
+        Objects.requireNonNull(iface);
+        Objects.requireNonNull(underlyingIfaces);
+        mOwnerUid = ownerUid;
+        mIface = iface;
+        mUnderlyingIfaces = Collections.unmodifiableList(new ArrayList<>(underlyingIfaces));
+    }
+
+    private UnderlyingNetworkInfo(@NonNull Parcel in) {
+        mOwnerUid = in.readInt();
+        mIface = in.readString();
+        List<String> underlyingIfaces = new ArrayList<>();
+        in.readList(underlyingIfaces, null /*classLoader*/, java.lang.String.class);
+        mUnderlyingIfaces = Collections.unmodifiableList(underlyingIfaces);
+    }
+
+    /** Get the owner of this network. */
+    public int getOwnerUid() {
+        return mOwnerUid;
+    }
+
+    /** Get the interface name of this network. */
+    @NonNull
+    public String getInterface() {
+        return mIface;
+    }
+
+    /** Get the names of the interfaces underlying this network. */
+    @NonNull
+    public List<String> getUnderlyingInterfaces() {
+        return mUnderlyingIfaces;
+    }
+
+    @Override
+    public String toString() {
+        return "UnderlyingNetworkInfo{"
+                + "ownerUid=" + mOwnerUid
+                + ", iface='" + mIface + '\''
+                + ", underlyingIfaces='" + mUnderlyingIfaces.toString() + '\''
+                + '}';
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mOwnerUid);
+        dest.writeString(mIface);
+        dest.writeList(mUnderlyingIfaces);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<UnderlyingNetworkInfo> CREATOR =
+            new Parcelable.Creator<UnderlyingNetworkInfo>() {
+        @NonNull
+        @Override
+        public UnderlyingNetworkInfo createFromParcel(@NonNull Parcel in) {
+            return new UnderlyingNetworkInfo(in);
+        }
+
+        @NonNull
+        @Override
+        public UnderlyingNetworkInfo[] newArray(int size) {
+            return new UnderlyingNetworkInfo[size];
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof UnderlyingNetworkInfo)) return false;
+        final UnderlyingNetworkInfo that = (UnderlyingNetworkInfo) o;
+        return mOwnerUid == that.getOwnerUid()
+                && Objects.equals(mIface, that.getInterface())
+                && Objects.equals(mUnderlyingIfaces, that.getUnderlyingInterfaces());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mOwnerUid, mIface, mUnderlyingIfaces);
+    }
+}
diff --git a/framework-t/src/android/net/netstats/IUsageCallback.aidl b/framework-t/src/android/net/netstats/IUsageCallback.aidl
new file mode 100644
index 0000000..4e8a5b2
--- /dev/null
+++ b/framework-t/src/android/net/netstats/IUsageCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package android.net.netstats;
+
+import android.net.DataUsageRequest;
+
+/**
+ * Interface for NetworkStatsService to notify events to the callers of registerUsageCallback.
+ *
+ * @hide
+ */
+oneway interface IUsageCallback {
+    void onThresholdReached(in DataUsageRequest request);
+    void onCallbackReleased(in DataUsageRequest request);
+}
diff --git a/framework-t/src/android/net/netstats/provider/INetworkStatsProvider.aidl b/framework-t/src/android/net/netstats/provider/INetworkStatsProvider.aidl
new file mode 100644
index 0000000..74c3ba4
--- /dev/null
+++ b/framework-t/src/android/net/netstats/provider/INetworkStatsProvider.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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 android.net.netstats.provider;
+
+/**
+ * Interface for NetworkStatsService to query network statistics and set data limits.
+ *
+ * @hide
+ */
+oneway interface INetworkStatsProvider {
+    void onRequestStatsUpdate(int token);
+    void onSetAlert(long quotaBytes);
+    void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes);
+}
diff --git a/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
new file mode 100644
index 0000000..01ff02d
--- /dev/null
+++ b/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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 android.net.netstats.provider;
+
+import android.net.NetworkStats;
+
+/**
+ * Interface for implementor of {@link INetworkStatsProviderCallback} to push events
+ * such as network statistics update or notify limit reached.
+ * @hide
+ */
+oneway interface INetworkStatsProviderCallback {
+    void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
+    void notifyAlertReached();
+    void notifyWarningReached();
+    void notifyLimitReached();
+    void unregister();
+}
diff --git a/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java b/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java
new file mode 100644
index 0000000..d37a53d
--- /dev/null
+++ b/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java
@@ -0,0 +1,232 @@
+/*
+ * 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 android.net.netstats.provider;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.NetworkStats;
+import android.os.RemoteException;
+
+/**
+ * A base class that allows external modules to implement a custom network statistics provider.
+ * @hide
+ */
+@SystemApi
+public abstract class NetworkStatsProvider {
+    /**
+     * A value used by {@link #onSetLimit}, {@link #onSetAlert} and {@link #onSetWarningAndLimit}
+     * indicates there is no limit.
+     */
+    public static final int QUOTA_UNLIMITED = -1;
+
+    @NonNull private final INetworkStatsProvider mProviderBinder =
+            new INetworkStatsProvider.Stub() {
+
+        @Override
+        public void onRequestStatsUpdate(int token) {
+            NetworkStatsProvider.this.onRequestStatsUpdate(token);
+        }
+
+        @Override
+        public void onSetAlert(long quotaBytes) {
+            NetworkStatsProvider.this.onSetAlert(quotaBytes);
+        }
+
+        @Override
+        public void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes) {
+            NetworkStatsProvider.this.onSetWarningAndLimit(iface, warningBytes, limitBytes);
+        }
+    };
+
+    // The binder given by the service when successfully registering. Only null before registering,
+    // never null once non-null.
+    @Nullable
+    private INetworkStatsProviderCallback mProviderCbBinder;
+
+    /**
+     * Return the binder invoked by the service and redirect function calls to the overridden
+     * methods.
+     * @hide
+     */
+    @NonNull
+    public INetworkStatsProvider getProviderBinder() {
+        return mProviderBinder;
+    }
+
+    /**
+     * Store the binder that was returned by the service when successfully registering. Note that
+     * the provider cannot be re-registered. Hence this method can only be called once per provider.
+     *
+     * @hide
+     */
+    public void setProviderCallbackBinder(@NonNull INetworkStatsProviderCallback binder) {
+        if (mProviderCbBinder != null) {
+            throw new IllegalArgumentException("provider is already registered");
+        }
+        mProviderCbBinder = binder;
+    }
+
+    /**
+     * Get the binder that was returned by the service when successfully registering. Or null if the
+     * provider was never registered.
+     *
+     * @hide
+     */
+    @Nullable
+    public INetworkStatsProviderCallback getProviderCallbackBinder() {
+        return mProviderCbBinder;
+    }
+
+    /**
+     * Get the binder that was returned by the service when successfully registering. Throw an
+     * {@link IllegalStateException} if the provider is not registered.
+     *
+     * @hide
+     */
+    @NonNull
+    public INetworkStatsProviderCallback getProviderCallbackBinderOrThrow() {
+        if (mProviderCbBinder == null) {
+            throw new IllegalStateException("the provider is not registered");
+        }
+        return mProviderCbBinder;
+    }
+
+    /**
+     * Notify the system of new network statistics.
+     *
+     * Send the network statistics recorded since the last call to {@link #notifyStatsUpdated}. Must
+     * be called as soon as possible after {@link NetworkStatsProvider#onRequestStatsUpdate(int)}
+     * being called. Responding later increases the probability stats will be dropped. The
+     * provider can also call this whenever it wants to reports new stats for any reason.
+     * Note that the system will not necessarily immediately propagate the statistics to
+     * reflect the update.
+     *
+     * @param token the token under which these stats were gathered. Providers can call this method
+     *              with the current token as often as they want, until the token changes.
+     *              {@see NetworkStatsProvider#onRequestStatsUpdate()}
+     * @param ifaceStats the {@link NetworkStats} per interface to be reported.
+     *                   The provider should not include any traffic that is already counted by
+     *                   kernel interface counters.
+     * @param uidStats the same stats as above, but counts {@link NetworkStats}
+     *                 per uid.
+     */
+    public void notifyStatsUpdated(int token, @NonNull NetworkStats ifaceStats,
+            @NonNull NetworkStats uidStats) {
+        try {
+            getProviderCallbackBinderOrThrow().notifyStatsUpdated(token, ifaceStats, uidStats);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Notify system that the quota set by {@code onSetAlert} has been reached.
+     */
+    public void notifyAlertReached() {
+        try {
+            getProviderCallbackBinderOrThrow().notifyAlertReached();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Notify system that the warning set by {@link #onSetWarningAndLimit} has been reached.
+     */
+    public void notifyWarningReached() {
+        try {
+            // Reuse the code path to notify warning reached with limit reached
+            // since framework handles them in the same way.
+            getProviderCallbackBinderOrThrow().notifyWarningReached();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Notify system that the limit set by {@link #onSetLimit} or limit set by
+     * {@link #onSetWarningAndLimit} has been reached.
+     */
+    public void notifyLimitReached() {
+        try {
+            getProviderCallbackBinderOrThrow().notifyLimitReached();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Called by {@code NetworkStatsService} when it requires to know updated stats.
+     * The provider MUST respond by calling {@link #notifyStatsUpdated} as soon as possible.
+     * Responding later increases the probability stats will be dropped. Memory allowing, the
+     * system will try to take stats into account up to one minute after calling
+     * {@link #onRequestStatsUpdate}.
+     *
+     * @param token a positive number identifying the new state of the system under which
+     *              {@link NetworkStats} have to be gathered from now on. When this is called,
+     *              custom implementations of providers MUST tally and report the latest stats with
+     *              the previous token, under which stats were being gathered so far.
+     */
+    public abstract void onRequestStatsUpdate(int token);
+
+    /**
+     * Called by {@code NetworkStatsService} when setting the interface quota for the specified
+     * upstream interface. When this is called, the custom implementation should block all egress
+     * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have
+     * been reached, and MUST respond to it by calling
+     * {@link NetworkStatsProvider#notifyLimitReached()}.
+     *
+     * @param iface the interface requiring the operation.
+     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
+     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
+     */
+    public abstract void onSetLimit(@NonNull String iface, long quotaBytes);
+
+    /**
+     * Called by {@code NetworkStatsService} when setting the interface quotas for the specified
+     * upstream interface. If a provider implements {@link #onSetWarningAndLimit}, the system
+     * will not call {@link #onSetLimit}. When this method is called, the implementation
+     * should behave as follows:
+     *   1. If {@code warningBytes} is reached on {@code iface}, block all further traffic on
+     *      {@code iface} and call {@link NetworkStatsProvider@notifyWarningReached()}.
+     *   2. If {@code limitBytes} is reached on {@code iface}, block all further traffic on
+     *   {@code iface} and call {@link NetworkStatsProvider#notifyLimitReached()}.
+     *
+     * @param iface the interface requiring the operation.
+     * @param warningBytes the warning defined as the number of bytes, starting from zero and
+     *                     counting from now. A value of {@link #QUOTA_UNLIMITED} indicates
+     *                     there is no warning.
+     * @param limitBytes the limit defined as the number of bytes, starting from zero and counting
+     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
+     */
+    public void onSetWarningAndLimit(@NonNull String iface, long warningBytes, long limitBytes) {
+        // Backward compatibility for those who didn't override this function.
+        onSetLimit(iface, limitBytes);
+    }
+
+    /**
+     * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations
+     * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes
+     * have been reached. Unlike {@link #onSetLimit(String, long)}, the custom implementation should
+     * not block all egress packets.
+     *
+     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
+     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert.
+     */
+    public abstract void onSetAlert(long quotaBytes);
+}
diff --git a/framework-t/src/android/net/nsd/INsdManager.aidl b/framework-t/src/android/net/nsd/INsdManager.aidl
new file mode 100644
index 0000000..89e9cdb
--- /dev/null
+++ b/framework-t/src/android/net/nsd/INsdManager.aidl
@@ -0,0 +1,30 @@
+/**
+ * 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 android.net.nsd;
+
+import android.net.nsd.INsdManagerCallback;
+import android.net.nsd.INsdServiceConnector;
+import android.os.Messenger;
+
+/**
+ * Interface that NsdService implements to connect NsdManager clients.
+ *
+ * {@hide}
+ */
+interface INsdManager {
+    INsdServiceConnector connect(INsdManagerCallback cb);
+}
diff --git a/framework-t/src/android/net/nsd/INsdManagerCallback.aidl b/framework-t/src/android/net/nsd/INsdManagerCallback.aidl
new file mode 100644
index 0000000..1a262ec
--- /dev/null
+++ b/framework-t/src/android/net/nsd/INsdManagerCallback.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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 android.net.nsd;
+
+import android.os.Messenger;
+import android.net.nsd.NsdServiceInfo;
+
+/**
+ * Callbacks from NsdService to NsdManager
+ * @hide
+ */
+oneway interface INsdManagerCallback {
+    void onDiscoverServicesStarted(int listenerKey, in NsdServiceInfo info);
+    void onDiscoverServicesFailed(int listenerKey, int error);
+    void onServiceFound(int listenerKey, in NsdServiceInfo info);
+    void onServiceLost(int listenerKey, in NsdServiceInfo info);
+    void onStopDiscoveryFailed(int listenerKey, int error);
+    void onStopDiscoverySucceeded(int listenerKey);
+    void onRegisterServiceFailed(int listenerKey, int error);
+    void onRegisterServiceSucceeded(int listenerKey, in NsdServiceInfo info);
+    void onUnregisterServiceFailed(int listenerKey, int error);
+    void onUnregisterServiceSucceeded(int listenerKey);
+    void onResolveServiceFailed(int listenerKey, int error);
+    void onResolveServiceSucceeded(int listenerKey, in NsdServiceInfo info);
+}
diff --git a/framework-t/src/android/net/nsd/INsdServiceConnector.aidl b/framework-t/src/android/net/nsd/INsdServiceConnector.aidl
new file mode 100644
index 0000000..b06ae55
--- /dev/null
+++ b/framework-t/src/android/net/nsd/INsdServiceConnector.aidl
@@ -0,0 +1,35 @@
+/**
+ * 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 android.net.nsd;
+
+import android.net.nsd.INsdManagerCallback;
+import android.net.nsd.NsdServiceInfo;
+import android.os.Messenger;
+
+/**
+ * Interface that NsdService implements for each NsdManager client.
+ *
+ * {@hide}
+ */
+interface INsdServiceConnector {
+    void registerService(int listenerKey, in NsdServiceInfo serviceInfo);
+    void unregisterService(int listenerKey);
+    void discoverServices(int listenerKey, in NsdServiceInfo serviceInfo);
+    void stopDiscovery(int listenerKey);
+    void resolveService(int listenerKey, in NsdServiceInfo serviceInfo);
+    void startDaemon();
+}
\ No newline at end of file
diff --git a/framework-t/src/android/net/nsd/NsdManager.java b/framework-t/src/android/net/nsd/NsdManager.java
new file mode 100644
index 0000000..209f372
--- /dev/null
+++ b/framework-t/src/android/net/nsd/NsdManager.java
@@ -0,0 +1,1083 @@
+/*
+ * 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 android.net.nsd;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemService;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkRequest;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * The Network Service Discovery Manager class provides the API to discover services
+ * on a network. As an example, if device A and device B are connected over a Wi-Fi
+ * network, a game registered on device A can be discovered by a game on device
+ * B. Another example use case is an application discovering printers on the network.
+ *
+ * <p> The API currently supports DNS based service discovery and discovery is currently
+ * limited to a local network over Multicast DNS. DNS service discovery is described at
+ * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
+ *
+ * <p> The API is asynchronous, and responses to requests from an application are on listener
+ * callbacks on a separate internal thread.
+ *
+ * <p> There are three main operations the API supports - registration, discovery and resolution.
+ * <pre>
+ *                          Application start
+ *                                 |
+ *                                 |
+ *                                 |                  onServiceRegistered()
+ *                     Register any local services  /
+ *                      to be advertised with       \
+ *                       registerService()            onRegistrationFailed()
+ *                                 |
+ *                                 |
+ *                          discoverServices()
+ *                                 |
+ *                      Maintain a list to track
+ *                        discovered services
+ *                                 |
+ *                                 |--------->
+ *                                 |          |
+ *                                 |      onServiceFound()
+ *                                 |          |
+ *                                 |     add service to list
+ *                                 |          |
+ *                                 |<----------
+ *                                 |
+ *                                 |--------->
+ *                                 |          |
+ *                                 |      onServiceLost()
+ *                                 |          |
+ *                                 |   remove service from list
+ *                                 |          |
+ *                                 |<----------
+ *                                 |
+ *                                 |
+ *                                 | Connect to a service
+ *                                 | from list ?
+ *                                 |
+ *                          resolveService()
+ *                                 |
+ *                         onServiceResolved()
+ *                                 |
+ *                     Establish connection to service
+ *                     with the host and port information
+ *
+ * </pre>
+ * An application that needs to advertise itself over a network for other applications to
+ * discover it can do so with a call to {@link #registerService}. If Example is a http based
+ * application that can provide HTML data to peer services, it can register a name "Example"
+ * with service type "_http._tcp". A successful registration is notified with a callback to
+ * {@link RegistrationListener#onServiceRegistered} and a failure to register is notified
+ * over {@link RegistrationListener#onRegistrationFailed}
+ *
+ * <p> A peer application looking for http services can initiate a discovery for "_http._tcp"
+ * with a call to {@link #discoverServices}. A service found is notified with a callback
+ * to {@link DiscoveryListener#onServiceFound} and a service lost is notified on
+ * {@link DiscoveryListener#onServiceLost}.
+ *
+ * <p> Once the peer application discovers the "Example" http service, and either needs to read the
+ * attributes of the service or wants to receive data from the "Example" application, it can
+ * initiate a resolve with {@link #resolveService} to resolve the attributes, host, and port
+ * details. A successful resolve is notified on {@link ResolveListener#onServiceResolved} and a
+ * failure is notified on {@link ResolveListener#onResolveFailed}.
+ *
+ * Applications can reserve for a service type at
+ * http://www.iana.org/form/ports-service. Existing services can be found at
+ * http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml
+ *
+ * {@see NsdServiceInfo}
+ */
+@SystemService(Context.NSD_SERVICE)
+public final class NsdManager {
+    private static final String TAG = NsdManager.class.getSimpleName();
+    private static final boolean DBG = false;
+
+    /**
+     * When enabled, apps targeting < Android 12 are considered legacy for
+     * the NSD native daemon.
+     * The platform will only keep the daemon running as long as there are
+     * any legacy apps connected.
+     *
+     * After Android 12, directly communicate with native daemon might not
+     * work since the native damon won't always stay alive.
+     * Use the NSD APIs from NsdManager as the replacement is recommended.
+     * An another alternative could be bundling your own mdns solutions instead of
+     * depending on the system mdns native daemon.
+     *
+     * @hide
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S)
+    public static final long RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS = 191844585L;
+
+    /**
+     * Broadcast intent action to indicate whether network service discovery is
+     * enabled or disabled. An extra {@link #EXTRA_NSD_STATE} provides the state
+     * information as int.
+     *
+     * @see #EXTRA_NSD_STATE
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
+
+    /**
+     * The lookup key for an int that indicates whether network service discovery is enabled
+     * or disabled. Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
+     *
+     * @see #NSD_STATE_DISABLED
+     * @see #NSD_STATE_ENABLED
+     */
+    public static final String EXTRA_NSD_STATE = "nsd_state";
+
+    /**
+     * Network service discovery is disabled
+     *
+     * @see #ACTION_NSD_STATE_CHANGED
+     */
+    public static final int NSD_STATE_DISABLED = 1;
+
+    /**
+     * Network service discovery is enabled
+     *
+     * @see #ACTION_NSD_STATE_CHANGED
+     */
+    public static final int NSD_STATE_ENABLED = 2;
+
+    /** @hide */
+    public static final int DISCOVER_SERVICES                       = 1;
+    /** @hide */
+    public static final int DISCOVER_SERVICES_STARTED               = 2;
+    /** @hide */
+    public static final int DISCOVER_SERVICES_FAILED                = 3;
+    /** @hide */
+    public static final int SERVICE_FOUND                           = 4;
+    /** @hide */
+    public static final int SERVICE_LOST                            = 5;
+
+    /** @hide */
+    public static final int STOP_DISCOVERY                          = 6;
+    /** @hide */
+    public static final int STOP_DISCOVERY_FAILED                   = 7;
+    /** @hide */
+    public static final int STOP_DISCOVERY_SUCCEEDED                = 8;
+
+    /** @hide */
+    public static final int REGISTER_SERVICE                        = 9;
+    /** @hide */
+    public static final int REGISTER_SERVICE_FAILED                 = 10;
+    /** @hide */
+    public static final int REGISTER_SERVICE_SUCCEEDED              = 11;
+
+    /** @hide */
+    public static final int UNREGISTER_SERVICE                      = 12;
+    /** @hide */
+    public static final int UNREGISTER_SERVICE_FAILED               = 13;
+    /** @hide */
+    public static final int UNREGISTER_SERVICE_SUCCEEDED            = 14;
+
+    /** @hide */
+    public static final int RESOLVE_SERVICE                         = 15;
+    /** @hide */
+    public static final int RESOLVE_SERVICE_FAILED                  = 16;
+    /** @hide */
+    public static final int RESOLVE_SERVICE_SUCCEEDED               = 17;
+
+    /** @hide */
+    public static final int DAEMON_CLEANUP                          = 18;
+
+    /** @hide */
+    public static final int DAEMON_STARTUP                          = 19;
+
+    /** @hide */
+    public static final int ENABLE                                  = 20;
+    /** @hide */
+    public static final int DISABLE                                 = 21;
+
+    /** @hide */
+    public static final int NATIVE_DAEMON_EVENT                     = 22;
+
+    /** @hide */
+    public static final int REGISTER_CLIENT                         = 23;
+    /** @hide */
+    public static final int UNREGISTER_CLIENT                       = 24;
+
+    /** Dns based service discovery protocol */
+    public static final int PROTOCOL_DNS_SD = 0x0001;
+
+    private static final SparseArray<String> EVENT_NAMES = new SparseArray<>();
+    static {
+        EVENT_NAMES.put(DISCOVER_SERVICES, "DISCOVER_SERVICES");
+        EVENT_NAMES.put(DISCOVER_SERVICES_STARTED, "DISCOVER_SERVICES_STARTED");
+        EVENT_NAMES.put(DISCOVER_SERVICES_FAILED, "DISCOVER_SERVICES_FAILED");
+        EVENT_NAMES.put(SERVICE_FOUND, "SERVICE_FOUND");
+        EVENT_NAMES.put(SERVICE_LOST, "SERVICE_LOST");
+        EVENT_NAMES.put(STOP_DISCOVERY, "STOP_DISCOVERY");
+        EVENT_NAMES.put(STOP_DISCOVERY_FAILED, "STOP_DISCOVERY_FAILED");
+        EVENT_NAMES.put(STOP_DISCOVERY_SUCCEEDED, "STOP_DISCOVERY_SUCCEEDED");
+        EVENT_NAMES.put(REGISTER_SERVICE, "REGISTER_SERVICE");
+        EVENT_NAMES.put(REGISTER_SERVICE_FAILED, "REGISTER_SERVICE_FAILED");
+        EVENT_NAMES.put(REGISTER_SERVICE_SUCCEEDED, "REGISTER_SERVICE_SUCCEEDED");
+        EVENT_NAMES.put(UNREGISTER_SERVICE, "UNREGISTER_SERVICE");
+        EVENT_NAMES.put(UNREGISTER_SERVICE_FAILED, "UNREGISTER_SERVICE_FAILED");
+        EVENT_NAMES.put(UNREGISTER_SERVICE_SUCCEEDED, "UNREGISTER_SERVICE_SUCCEEDED");
+        EVENT_NAMES.put(RESOLVE_SERVICE, "RESOLVE_SERVICE");
+        EVENT_NAMES.put(RESOLVE_SERVICE_FAILED, "RESOLVE_SERVICE_FAILED");
+        EVENT_NAMES.put(RESOLVE_SERVICE_SUCCEEDED, "RESOLVE_SERVICE_SUCCEEDED");
+        EVENT_NAMES.put(DAEMON_CLEANUP, "DAEMON_CLEANUP");
+        EVENT_NAMES.put(DAEMON_STARTUP, "DAEMON_STARTUP");
+        EVENT_NAMES.put(ENABLE, "ENABLE");
+        EVENT_NAMES.put(DISABLE, "DISABLE");
+        EVENT_NAMES.put(NATIVE_DAEMON_EVENT, "NATIVE_DAEMON_EVENT");
+    }
+
+    /** @hide */
+    public static String nameOf(int event) {
+        String name = EVENT_NAMES.get(event);
+        if (name == null) {
+            return Integer.toString(event);
+        }
+        return name;
+    }
+
+    private static final int FIRST_LISTENER_KEY = 1;
+
+    private final INsdServiceConnector mService;
+    private final Context mContext;
+
+    private int mListenerKey = FIRST_LISTENER_KEY;
+    @GuardedBy("mMapLock")
+    private final SparseArray mListenerMap = new SparseArray();
+    @GuardedBy("mMapLock")
+    private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<>();
+    @GuardedBy("mMapLock")
+    private final SparseArray<Executor> mExecutorMap = new SparseArray<>();
+    private final Object mMapLock = new Object();
+    // Map of listener key sent by client -> per-network discovery tracker
+    @GuardedBy("mPerNetworkDiscoveryMap")
+    private final ArrayMap<Integer, PerNetworkDiscoveryTracker>
+            mPerNetworkDiscoveryMap = new ArrayMap<>();
+
+    private final ServiceHandler mHandler;
+
+    private class PerNetworkDiscoveryTracker {
+        final String mServiceType;
+        final int mProtocolType;
+        final DiscoveryListener mBaseListener;
+        final Executor mBaseExecutor;
+        final ArrayMap<Network, DelegatingDiscoveryListener> mPerNetworkListeners =
+                new ArrayMap<>();
+
+        final NetworkCallback mNetworkCb = new NetworkCallback() {
+            @Override
+            public void onAvailable(@NonNull Network network) {
+                final DelegatingDiscoveryListener wrappedListener = new DelegatingDiscoveryListener(
+                        network, mBaseListener);
+                mPerNetworkListeners.put(network, wrappedListener);
+                discoverServices(mServiceType, mProtocolType, network, mBaseExecutor,
+                        wrappedListener);
+            }
+
+            @Override
+            public void onLost(@NonNull Network network) {
+                final DelegatingDiscoveryListener listener = mPerNetworkListeners.get(network);
+                if (listener == null) return;
+                listener.notifyAllServicesLost();
+                // Listener will be removed from map in discovery stopped callback
+                stopServiceDiscovery(listener);
+            }
+        };
+
+        // Accessed from mHandler
+        private boolean mStopRequested;
+
+        public void start(@NonNull NetworkRequest request) {
+            final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+            cm.registerNetworkCallback(request, mNetworkCb, mHandler);
+            mHandler.post(() -> mBaseListener.onDiscoveryStarted(mServiceType));
+        }
+
+        /**
+         * Stop discovery on all networks tracked by this class.
+         *
+         * This will request all underlying listeners to stop, and the last one to stop will call
+         * onDiscoveryStopped or onStopDiscoveryFailed.
+         *
+         * Must be called on the handler thread.
+         */
+        public void requestStop() {
+            mHandler.post(() -> {
+                mStopRequested = true;
+                final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+                cm.unregisterNetworkCallback(mNetworkCb);
+                if (mPerNetworkListeners.size() == 0) {
+                    mBaseListener.onDiscoveryStopped(mServiceType);
+                    return;
+                }
+                for (int i = 0; i < mPerNetworkListeners.size(); i++) {
+                    final DelegatingDiscoveryListener listener = mPerNetworkListeners.valueAt(i);
+                    stopServiceDiscovery(listener);
+                }
+            });
+        }
+
+        private PerNetworkDiscoveryTracker(String serviceType, int protocolType,
+                Executor baseExecutor, DiscoveryListener baseListener) {
+            mServiceType = serviceType;
+            mProtocolType = protocolType;
+            mBaseExecutor = baseExecutor;
+            mBaseListener = baseListener;
+        }
+
+        /**
+         * Subset of NsdServiceInfo that is tracked to generate service lost notifications when a
+         * network is lost.
+         *
+         * Service lost notifications only contain service name, type and network, so only track
+         * that information (Network is known from the listener). This also implements
+         * equals/hashCode for usage in maps.
+         */
+        private class TrackedNsdInfo {
+            private final String mServiceName;
+            private final String mServiceType;
+            TrackedNsdInfo(NsdServiceInfo info) {
+                mServiceName = info.getServiceName();
+                mServiceType = info.getServiceType();
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(mServiceName, mServiceType);
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                if (!(obj instanceof TrackedNsdInfo)) return false;
+                final TrackedNsdInfo other = (TrackedNsdInfo) obj;
+                return Objects.equals(mServiceName, other.mServiceName)
+                        && Objects.equals(mServiceType, other.mServiceType);
+            }
+        }
+
+        private class DelegatingDiscoveryListener implements DiscoveryListener {
+            private final Network mNetwork;
+            private final DiscoveryListener mWrapped;
+            private final ArraySet<TrackedNsdInfo> mFoundInfo = new ArraySet<>();
+
+            private DelegatingDiscoveryListener(Network network, DiscoveryListener listener) {
+                mNetwork = network;
+                mWrapped = listener;
+            }
+
+            void notifyAllServicesLost() {
+                for (int i = 0; i < mFoundInfo.size(); i++) {
+                    final TrackedNsdInfo trackedInfo = mFoundInfo.valueAt(i);
+                    final NsdServiceInfo serviceInfo = new NsdServiceInfo(
+                            trackedInfo.mServiceName, trackedInfo.mServiceType);
+                    serviceInfo.setNetwork(mNetwork);
+                    mWrapped.onServiceLost(serviceInfo);
+                }
+            }
+
+            @Override
+            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
+                // The delegated listener is used when NsdManager takes care of starting/stopping
+                // discovery on multiple networks. Failure to start on one network is not a global
+                // failure to be reported up, as other networks may succeed: just log.
+                Log.e(TAG, "Failed to start discovery for " + serviceType + " on " + mNetwork
+                        + " with code " + errorCode);
+                mPerNetworkListeners.remove(mNetwork);
+            }
+
+            @Override
+            public void onDiscoveryStarted(String serviceType) {
+                // Wrapped listener was called upon registration, it is not called for discovery
+                // on each network
+            }
+
+            @Override
+            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
+                Log.e(TAG, "Failed to stop discovery for " + serviceType + " on " + mNetwork
+                        + " with code " + errorCode);
+                mPerNetworkListeners.remove(mNetwork);
+                if (mStopRequested && mPerNetworkListeners.size() == 0) {
+                    // Do not report onStopDiscoveryFailed when some underlying listeners failed:
+                    // this does not mean that all listeners did, and onStopDiscoveryFailed is not
+                    // actionable anyway. Just report that discovery stopped.
+                    mWrapped.onDiscoveryStopped(serviceType);
+                }
+            }
+
+            @Override
+            public void onDiscoveryStopped(String serviceType) {
+                mPerNetworkListeners.remove(mNetwork);
+                if (mStopRequested && mPerNetworkListeners.size() == 0) {
+                    mWrapped.onDiscoveryStopped(serviceType);
+                }
+            }
+
+            @Override
+            public void onServiceFound(NsdServiceInfo serviceInfo) {
+                mFoundInfo.add(new TrackedNsdInfo(serviceInfo));
+                mWrapped.onServiceFound(serviceInfo);
+            }
+
+            @Override
+            public void onServiceLost(NsdServiceInfo serviceInfo) {
+                mFoundInfo.remove(new TrackedNsdInfo(serviceInfo));
+                mWrapped.onServiceLost(serviceInfo);
+            }
+        }
+    }
+
+    /**
+     * Create a new Nsd instance. Applications use
+     * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
+     * {@link android.content.Context#NSD_SERVICE Context.NSD_SERVICE}.
+     * @param service the Binder interface
+     * @hide - hide this because it takes in a parameter of type INsdManager, which
+     * is a system private class.
+     */
+    public NsdManager(Context context, INsdManager service) {
+        mContext = context;
+
+        HandlerThread t = new HandlerThread("NsdManager");
+        t.start();
+        mHandler = new ServiceHandler(t.getLooper());
+
+        try {
+            mService = service.connect(new NsdCallbackImpl(mHandler));
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed to connect to NsdService");
+        }
+
+        // Only proactively start the daemon if the target SDK < S, otherwise the internal service
+        // would automatically start/stop the native daemon as needed.
+        if (!CompatChanges.isChangeEnabled(RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS)) {
+            try {
+                mService.startDaemon();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to proactively start daemon");
+                // Continue: the daemon can still be started on-demand later
+            }
+        }
+    }
+
+    private static class NsdCallbackImpl extends INsdManagerCallback.Stub {
+        private final Handler mServHandler;
+
+        NsdCallbackImpl(Handler serviceHandler) {
+            mServHandler = serviceHandler;
+        }
+
+        private void sendInfo(int message, int listenerKey, NsdServiceInfo info) {
+            mServHandler.sendMessage(mServHandler.obtainMessage(message, 0, listenerKey, info));
+        }
+
+        private void sendError(int message, int listenerKey, int error) {
+            mServHandler.sendMessage(mServHandler.obtainMessage(message, error, listenerKey));
+        }
+
+        private void sendNoArg(int message, int listenerKey) {
+            mServHandler.sendMessage(mServHandler.obtainMessage(message, 0, listenerKey));
+        }
+
+        @Override
+        public void onDiscoverServicesStarted(int listenerKey, NsdServiceInfo info) {
+            sendInfo(DISCOVER_SERVICES_STARTED, listenerKey, info);
+        }
+
+        @Override
+        public void onDiscoverServicesFailed(int listenerKey, int error) {
+            sendError(DISCOVER_SERVICES_FAILED, listenerKey, error);
+        }
+
+        @Override
+        public void onServiceFound(int listenerKey, NsdServiceInfo info) {
+            sendInfo(SERVICE_FOUND, listenerKey, info);
+        }
+
+        @Override
+        public void onServiceLost(int listenerKey, NsdServiceInfo info) {
+            sendInfo(SERVICE_LOST, listenerKey, info);
+        }
+
+        @Override
+        public void onStopDiscoveryFailed(int listenerKey, int error) {
+            sendError(STOP_DISCOVERY_FAILED, listenerKey, error);
+        }
+
+        @Override
+        public void onStopDiscoverySucceeded(int listenerKey) {
+            sendNoArg(STOP_DISCOVERY_SUCCEEDED, listenerKey);
+        }
+
+        @Override
+        public void onRegisterServiceFailed(int listenerKey, int error) {
+            sendError(REGISTER_SERVICE_FAILED, listenerKey, error);
+        }
+
+        @Override
+        public void onRegisterServiceSucceeded(int listenerKey, NsdServiceInfo info) {
+            sendInfo(REGISTER_SERVICE_SUCCEEDED, listenerKey, info);
+        }
+
+        @Override
+        public void onUnregisterServiceFailed(int listenerKey, int error) {
+            sendError(UNREGISTER_SERVICE_FAILED, listenerKey, error);
+        }
+
+        @Override
+        public void onUnregisterServiceSucceeded(int listenerKey) {
+            sendNoArg(UNREGISTER_SERVICE_SUCCEEDED, listenerKey);
+        }
+
+        @Override
+        public void onResolveServiceFailed(int listenerKey, int error) {
+            sendError(RESOLVE_SERVICE_FAILED, listenerKey, error);
+        }
+
+        @Override
+        public void onResolveServiceSucceeded(int listenerKey, NsdServiceInfo info) {
+            sendInfo(RESOLVE_SERVICE_SUCCEEDED, listenerKey, info);
+        }
+    }
+
+    /**
+     * Failures are passed with {@link RegistrationListener#onRegistrationFailed},
+     * {@link RegistrationListener#onUnregistrationFailed},
+     * {@link DiscoveryListener#onStartDiscoveryFailed},
+     * {@link DiscoveryListener#onStopDiscoveryFailed} or {@link ResolveListener#onResolveFailed}.
+     *
+     * Indicates that the operation failed due to an internal error.
+     */
+    public static final int FAILURE_INTERNAL_ERROR               = 0;
+
+    /**
+     * Indicates that the operation failed because it is already active.
+     */
+    public static final int FAILURE_ALREADY_ACTIVE              = 3;
+
+    /**
+     * Indicates that the operation failed because the maximum outstanding
+     * requests from the applications have reached.
+     */
+    public static final int FAILURE_MAX_LIMIT                   = 4;
+
+    /** Interface for callback invocation for service discovery */
+    public interface DiscoveryListener {
+
+        public void onStartDiscoveryFailed(String serviceType, int errorCode);
+
+        public void onStopDiscoveryFailed(String serviceType, int errorCode);
+
+        public void onDiscoveryStarted(String serviceType);
+
+        public void onDiscoveryStopped(String serviceType);
+
+        public void onServiceFound(NsdServiceInfo serviceInfo);
+
+        public void onServiceLost(NsdServiceInfo serviceInfo);
+    }
+
+    /** Interface for callback invocation for service registration */
+    public interface RegistrationListener {
+
+        public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
+
+        public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
+
+        public void onServiceRegistered(NsdServiceInfo serviceInfo);
+
+        public void onServiceUnregistered(NsdServiceInfo serviceInfo);
+    }
+
+    /** Interface for callback invocation for service resolution */
+    public interface ResolveListener {
+
+        public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode);
+
+        public void onServiceResolved(NsdServiceInfo serviceInfo);
+    }
+
+    @VisibleForTesting
+    class ServiceHandler extends Handler {
+        ServiceHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message message) {
+            final int what = message.what;
+            final int key = message.arg2;
+            final Object listener;
+            final NsdServiceInfo ns;
+            final Executor executor;
+            synchronized (mMapLock) {
+                listener = mListenerMap.get(key);
+                ns = mServiceMap.get(key);
+                executor = mExecutorMap.get(key);
+            }
+            if (listener == null) {
+                Log.d(TAG, "Stale key " + message.arg2);
+                return;
+            }
+            if (DBG) {
+                Log.d(TAG, "received " + nameOf(what) + " for key " + key + ", service " + ns);
+            }
+            switch (what) {
+                case DISCOVER_SERVICES_STARTED:
+                    final String s = getNsdServiceInfoType((NsdServiceInfo) message.obj);
+                    executor.execute(() -> ((DiscoveryListener) listener).onDiscoveryStarted(s));
+                    break;
+                case DISCOVER_SERVICES_FAILED:
+                    removeListener(key);
+                    executor.execute(() -> ((DiscoveryListener) listener).onStartDiscoveryFailed(
+                            getNsdServiceInfoType(ns), message.arg1));
+                    break;
+                case SERVICE_FOUND:
+                    executor.execute(() -> ((DiscoveryListener) listener).onServiceFound(
+                            (NsdServiceInfo) message.obj));
+                    break;
+                case SERVICE_LOST:
+                    executor.execute(() -> ((DiscoveryListener) listener).onServiceLost(
+                            (NsdServiceInfo) message.obj));
+                    break;
+                case STOP_DISCOVERY_FAILED:
+                    // TODO: failure to stop discovery should be internal and retried internally, as
+                    // the effect for the client is indistinguishable from STOP_DISCOVERY_SUCCEEDED
+                    removeListener(key);
+                    executor.execute(() -> ((DiscoveryListener) listener).onStopDiscoveryFailed(
+                            getNsdServiceInfoType(ns), message.arg1));
+                    break;
+                case STOP_DISCOVERY_SUCCEEDED:
+                    removeListener(key);
+                    executor.execute(() -> ((DiscoveryListener) listener).onDiscoveryStopped(
+                            getNsdServiceInfoType(ns)));
+                    break;
+                case REGISTER_SERVICE_FAILED:
+                    removeListener(key);
+                    executor.execute(() -> ((RegistrationListener) listener).onRegistrationFailed(
+                            ns, message.arg1));
+                    break;
+                case REGISTER_SERVICE_SUCCEEDED:
+                    executor.execute(() -> ((RegistrationListener) listener).onServiceRegistered(
+                            (NsdServiceInfo) message.obj));
+                    break;
+                case UNREGISTER_SERVICE_FAILED:
+                    removeListener(key);
+                    executor.execute(() -> ((RegistrationListener) listener).onUnregistrationFailed(
+                            ns, message.arg1));
+                    break;
+                case UNREGISTER_SERVICE_SUCCEEDED:
+                    // TODO: do not unregister listener until service is unregistered, or provide
+                    // alternative way for unregistering ?
+                    removeListener(message.arg2);
+                    executor.execute(() -> ((RegistrationListener) listener).onServiceUnregistered(
+                            ns));
+                    break;
+                case RESOLVE_SERVICE_FAILED:
+                    removeListener(key);
+                    executor.execute(() -> ((ResolveListener) listener).onResolveFailed(
+                            ns, message.arg1));
+                    break;
+                case RESOLVE_SERVICE_SUCCEEDED:
+                    removeListener(key);
+                    executor.execute(() -> ((ResolveListener) listener).onServiceResolved(
+                            (NsdServiceInfo) message.obj));
+                    break;
+                default:
+                    Log.d(TAG, "Ignored " + message);
+                    break;
+            }
+        }
+    }
+
+    private int nextListenerKey() {
+        // Ensure mListenerKey >= FIRST_LISTENER_KEY;
+        mListenerKey = Math.max(FIRST_LISTENER_KEY, mListenerKey + 1);
+        return mListenerKey;
+    }
+
+    // Assert that the listener is not in the map, then add it and returns its key
+    private int putListener(Object listener, Executor e, NsdServiceInfo s) {
+        checkListener(listener);
+        final int key;
+        synchronized (mMapLock) {
+            int valueIndex = mListenerMap.indexOfValue(listener);
+            if (valueIndex != -1) {
+                throw new IllegalArgumentException("listener already in use");
+            }
+            key = nextListenerKey();
+            mListenerMap.put(key, listener);
+            mServiceMap.put(key, s);
+            mExecutorMap.put(key, e);
+        }
+        return key;
+    }
+
+    private void removeListener(int key) {
+        synchronized (mMapLock) {
+            mListenerMap.remove(key);
+            mServiceMap.remove(key);
+            mExecutorMap.remove(key);
+        }
+    }
+
+    private int getListenerKey(Object listener) {
+        checkListener(listener);
+        synchronized (mMapLock) {
+            int valueIndex = mListenerMap.indexOfValue(listener);
+            if (valueIndex == -1) {
+                throw new IllegalArgumentException("listener not registered");
+            }
+            return mListenerMap.keyAt(valueIndex);
+        }
+    }
+
+    private static String getNsdServiceInfoType(NsdServiceInfo s) {
+        if (s == null) return "?";
+        return s.getServiceType();
+    }
+
+    /**
+     * Register a service to be discovered by other services.
+     *
+     * <p> The function call immediately returns after sending a request to register service
+     * to the framework. The application is notified of a successful registration
+     * through the callback {@link RegistrationListener#onServiceRegistered} or a failure
+     * through {@link RegistrationListener#onRegistrationFailed}.
+     *
+     * <p> The application should call {@link #unregisterService} when the service
+     * registration is no longer required, and/or whenever the application is stopped.
+     *
+     * @param serviceInfo The service being registered
+     * @param protocolType The service discovery protocol
+     * @param listener The listener notifies of a successful registration and is used to
+     * unregister this service through a call on {@link #unregisterService}. Cannot be null.
+     * Cannot be in use for an active service registration.
+     */
+    public void registerService(NsdServiceInfo serviceInfo, int protocolType,
+            RegistrationListener listener) {
+        registerService(serviceInfo, protocolType, Runnable::run, listener);
+    }
+
+    /**
+     * Register a service to be discovered by other services.
+     *
+     * <p> The function call immediately returns after sending a request to register service
+     * to the framework. The application is notified of a successful registration
+     * through the callback {@link RegistrationListener#onServiceRegistered} or a failure
+     * through {@link RegistrationListener#onRegistrationFailed}.
+     *
+     * <p> The application should call {@link #unregisterService} when the service
+     * registration is no longer required, and/or whenever the application is stopped.
+     * @param serviceInfo The service being registered
+     * @param protocolType The service discovery protocol
+     * @param executor Executor to run listener callbacks with
+     * @param listener The listener notifies of a successful registration and is used to
+     * unregister this service through a call on {@link #unregisterService}. Cannot be null.
+     */
+    public void registerService(@NonNull NsdServiceInfo serviceInfo, int protocolType,
+            @NonNull Executor executor, @NonNull RegistrationListener listener) {
+        if (serviceInfo.getPort() <= 0) {
+            throw new IllegalArgumentException("Invalid port number");
+        }
+        checkServiceInfo(serviceInfo);
+        checkProtocol(protocolType);
+        int key = putListener(listener, executor, serviceInfo);
+        try {
+            mService.registerService(key, serviceInfo);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Unregister a service registered through {@link #registerService}. A successful
+     * unregister is notified to the application with a call to
+     * {@link RegistrationListener#onServiceUnregistered}.
+     *
+     * @param listener This should be the listener object that was passed to
+     * {@link #registerService}. It identifies the service that should be unregistered
+     * and notifies of a successful or unsuccessful unregistration via the listener
+     * callbacks.  In API versions 20 and above, the listener object may be used for
+     * another service registration once the callback has been called.  In API versions <= 19,
+     * there is no entirely reliable way to know when a listener may be re-used, and a new
+     * listener should be created for each service registration request.
+     */
+    public void unregisterService(RegistrationListener listener) {
+        int id = getListenerKey(listener);
+        try {
+            mService.unregisterService(id);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Initiate service discovery to browse for instances of a service type. Service discovery
+     * consumes network bandwidth and will continue until the application calls
+     * {@link #stopServiceDiscovery}.
+     *
+     * <p> The function call immediately returns after sending a request to start service
+     * discovery to the framework. The application is notified of a success to initiate
+     * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
+     * through {@link DiscoveryListener#onStartDiscoveryFailed}.
+     *
+     * <p> Upon successful start, application is notified when a service is found with
+     * {@link DiscoveryListener#onServiceFound} or when a service is lost with
+     * {@link DiscoveryListener#onServiceLost}.
+     *
+     * <p> Upon failure to start, service discovery is not active and application does
+     * not need to invoke {@link #stopServiceDiscovery}
+     *
+     * <p> The application should call {@link #stopServiceDiscovery} when discovery of this
+     * service type is no longer required, and/or whenever the application is paused or
+     * stopped.
+     *
+     * @param serviceType The service type being discovered. Examples include "_http._tcp" for
+     * http services or "_ipp._tcp" for printers
+     * @param protocolType The service discovery protocol
+     * @param listener  The listener notifies of a successful discovery and is used
+     * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
+     * Cannot be null. Cannot be in use for an active service discovery.
+     */
+    public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) {
+        discoverServices(serviceType, protocolType, (Network) null, Runnable::run, listener);
+    }
+
+    /**
+     * Initiate service discovery to browse for instances of a service type. Service discovery
+     * consumes network bandwidth and will continue until the application calls
+     * {@link #stopServiceDiscovery}.
+     *
+     * <p> The function call immediately returns after sending a request to start service
+     * discovery to the framework. The application is notified of a success to initiate
+     * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
+     * through {@link DiscoveryListener#onStartDiscoveryFailed}.
+     *
+     * <p> Upon successful start, application is notified when a service is found with
+     * {@link DiscoveryListener#onServiceFound} or when a service is lost with
+     * {@link DiscoveryListener#onServiceLost}.
+     *
+     * <p> Upon failure to start, service discovery is not active and application does
+     * not need to invoke {@link #stopServiceDiscovery}
+     *
+     * <p> The application should call {@link #stopServiceDiscovery} when discovery of this
+     * service type is no longer required, and/or whenever the application is paused or
+     * stopped.
+     * @param serviceType The service type being discovered. Examples include "_http._tcp" for
+     * http services or "_ipp._tcp" for printers
+     * @param protocolType The service discovery protocol
+     * @param network Network to discover services on, or null to discover on all available networks
+     * @param executor Executor to run listener callbacks with
+     * @param listener  The listener notifies of a successful discovery and is used
+     * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
+     */
+    public void discoverServices(@NonNull String serviceType, int protocolType,
+            @Nullable Network network, @NonNull Executor executor,
+            @NonNull DiscoveryListener listener) {
+        if (TextUtils.isEmpty(serviceType)) {
+            throw new IllegalArgumentException("Service type cannot be empty");
+        }
+        checkProtocol(protocolType);
+
+        NsdServiceInfo s = new NsdServiceInfo();
+        s.setServiceType(serviceType);
+        s.setNetwork(network);
+
+        int key = putListener(listener, executor, s);
+        try {
+            mService.discoverServices(key, s);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Initiate service discovery to browse for instances of a service type. Service discovery
+     * consumes network bandwidth and will continue until the application calls
+     * {@link #stopServiceDiscovery}.
+     *
+     * <p> The function call immediately returns after sending a request to start service
+     * discovery to the framework. The application is notified of a success to initiate
+     * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
+     * through {@link DiscoveryListener#onStartDiscoveryFailed}.
+     *
+     * <p> Upon successful start, application is notified when a service is found with
+     * {@link DiscoveryListener#onServiceFound} or when a service is lost with
+     * {@link DiscoveryListener#onServiceLost}.
+     *
+     * <p> Upon failure to start, service discovery is not active and application does
+     * not need to invoke {@link #stopServiceDiscovery}
+     *
+     * <p> The application should call {@link #stopServiceDiscovery} when discovery of this
+     * service type is no longer required, and/or whenever the application is paused or
+     * stopped.
+     *
+     * <p> During discovery, new networks may connect or existing networks may disconnect - for
+     * example if wifi is reconnected. When a service was found on a network that disconnects,
+     * {@link DiscoveryListener#onServiceLost} will be called. If a new network connects that
+     * matches the {@link NetworkRequest}, {@link DiscoveryListener#onServiceFound} will be called
+     * for services found on that network. Applications that do not want to track networks
+     * themselves are encouraged to use this method instead of other overloads of
+     * {@code discoverServices}, as they will receive proper notifications when a service becomes
+     * available or unavailable due to network changes.
+     * @param serviceType The service type being discovered. Examples include "_http._tcp" for
+     * http services or "_ipp._tcp" for printers
+     * @param protocolType The service discovery protocol
+     * @param networkRequest Request specifying networks that should be considered when discovering
+     * @param executor Executor to run listener callbacks with
+     * @param listener  The listener notifies of a successful discovery and is used
+     * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    public void discoverServices(@NonNull String serviceType, int protocolType,
+            @NonNull NetworkRequest networkRequest, @NonNull Executor executor,
+            @NonNull DiscoveryListener listener) {
+        if (TextUtils.isEmpty(serviceType)) {
+            throw new IllegalArgumentException("Service type cannot be empty");
+        }
+        Objects.requireNonNull(networkRequest, "NetworkRequest cannot be null");
+        checkProtocol(protocolType);
+
+        NsdServiceInfo s = new NsdServiceInfo();
+        s.setServiceType(serviceType);
+
+        final int baseListenerKey = putListener(listener, executor, s);
+
+        final PerNetworkDiscoveryTracker discoveryInfo = new PerNetworkDiscoveryTracker(
+                serviceType, protocolType, executor, listener);
+
+        synchronized (mPerNetworkDiscoveryMap) {
+            mPerNetworkDiscoveryMap.put(baseListenerKey, discoveryInfo);
+            discoveryInfo.start(networkRequest);
+        }
+    }
+
+    /**
+     * Stop service discovery initiated with {@link #discoverServices}.  An active service
+     * discovery is notified to the application with {@link DiscoveryListener#onDiscoveryStarted}
+     * and it stays active until the application invokes a stop service discovery. A successful
+     * stop is notified to with a call to {@link DiscoveryListener#onDiscoveryStopped}.
+     *
+     * <p> Upon failure to stop service discovery, application is notified through
+     * {@link DiscoveryListener#onStopDiscoveryFailed}.
+     *
+     * @param listener This should be the listener object that was passed to {@link #discoverServices}.
+     * It identifies the discovery that should be stopped and notifies of a successful or
+     * unsuccessful stop.  In API versions 20 and above, the listener object may be used for
+     * another service discovery once the callback has been called.  In API versions <= 19,
+     * there is no entirely reliable way to know when a listener may be re-used, and a new
+     * listener should be created for each service discovery request.
+     */
+    public void stopServiceDiscovery(DiscoveryListener listener) {
+        int id = getListenerKey(listener);
+        // If this is a PerNetworkDiscovery request, handle it as such
+        synchronized (mPerNetworkDiscoveryMap) {
+            final PerNetworkDiscoveryTracker info = mPerNetworkDiscoveryMap.get(id);
+            if (info != null) {
+                info.requestStop();
+                return;
+            }
+        }
+        try {
+            mService.stopDiscovery(id);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Resolve a discovered service. An application can resolve a service right before
+     * establishing a connection to fetch the IP and port details on which to setup
+     * the connection.
+     *
+     * @param serviceInfo service to be resolved
+     * @param listener to receive callback upon success or failure. Cannot be null.
+     * Cannot be in use for an active service resolution.
+     */
+    public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) {
+        resolveService(serviceInfo, Runnable::run, listener);
+    }
+
+    /**
+     * Resolve a discovered service. An application can resolve a service right before
+     * establishing a connection to fetch the IP and port details on which to setup
+     * the connection.
+     * @param serviceInfo service to be resolved
+     * @param executor Executor to run listener callbacks with
+     * @param listener to receive callback upon success or failure.
+     */
+    public void resolveService(@NonNull NsdServiceInfo serviceInfo,
+            @NonNull Executor executor, @NonNull ResolveListener listener) {
+        checkServiceInfo(serviceInfo);
+        int key = putListener(listener, executor, serviceInfo);
+        try {
+            mService.resolveService(key, serviceInfo);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    private static void checkListener(Object listener) {
+        Objects.requireNonNull(listener, "listener cannot be null");
+    }
+
+    private static void checkProtocol(int protocolType) {
+        if (protocolType != PROTOCOL_DNS_SD) {
+            throw new IllegalArgumentException("Unsupported protocol");
+        }
+    }
+
+    private static void checkServiceInfo(NsdServiceInfo serviceInfo) {
+        Objects.requireNonNull(serviceInfo, "NsdServiceInfo cannot be null");
+        if (TextUtils.isEmpty(serviceInfo.getServiceName())) {
+            throw new IllegalArgumentException("Service name cannot be empty");
+        }
+        if (TextUtils.isEmpty(serviceInfo.getServiceType())) {
+            throw new IllegalArgumentException("Service type cannot be empty");
+        }
+    }
+}
diff --git a/framework-t/src/android/net/nsd/NsdServiceInfo.java b/framework-t/src/android/net/nsd/NsdServiceInfo.java
new file mode 100644
index 0000000..8506db1
--- /dev/null
+++ b/framework-t/src/android/net/nsd/NsdServiceInfo.java
@@ -0,0 +1,418 @@
+/*
+ * 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.nsd;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.net.Network;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Base64;
+import android.util.Log;
+
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * A class representing service information for network service discovery
+ * {@see NsdManager}
+ */
+public final class NsdServiceInfo implements Parcelable {
+
+    private static final String TAG = "NsdServiceInfo";
+
+    private String mServiceName;
+
+    private String mServiceType;
+
+    private final ArrayMap<String, byte[]> mTxtRecord = new ArrayMap<>();
+
+    private InetAddress mHost;
+
+    private int mPort;
+
+    @Nullable
+    private Network mNetwork;
+
+    public NsdServiceInfo() {
+    }
+
+    /** @hide */
+    public NsdServiceInfo(String sn, String rt) {
+        mServiceName = sn;
+        mServiceType = rt;
+    }
+
+    /** Get the service name */
+    public String getServiceName() {
+        return mServiceName;
+    }
+
+    /** Set the service name */
+    public void setServiceName(String s) {
+        mServiceName = s;
+    }
+
+    /** Get the service type */
+    public String getServiceType() {
+        return mServiceType;
+    }
+
+    /** Set the service type */
+    public void setServiceType(String s) {
+        mServiceType = s;
+    }
+
+    /** Get the host address. The host address is valid for a resolved service. */
+    public InetAddress getHost() {
+        return mHost;
+    }
+
+    /** Set the host address */
+    public void setHost(InetAddress s) {
+        mHost = s;
+    }
+
+    /** Get port number. The port number is valid for a resolved service. */
+    public int getPort() {
+        return mPort;
+    }
+
+    /** Set port number */
+    public void setPort(int p) {
+        mPort = p;
+    }
+
+    /**
+     * Unpack txt information from a base-64 encoded byte array.
+     *
+     * @param rawRecords The raw base64 encoded records string read from netd.
+     *
+     * @hide
+     */
+    public void setTxtRecords(@NonNull String rawRecords) {
+        byte[] txtRecordsRawBytes = Base64.decode(rawRecords, Base64.DEFAULT);
+
+        // There can be multiple TXT records after each other. Each record has to following format:
+        //
+        // byte                  type                  required   meaning
+        // -------------------   -------------------   --------   ----------------------------------
+        // 0                     unsigned 8 bit        yes        size of record excluding this byte
+        // 1 - n                 ASCII but not '='     yes        key
+        // n + 1                 '='                   optional   separator of key and value
+        // n + 2 - record size   uninterpreted bytes   optional   value
+        //
+        // Example legal records:
+        // [11, 'm', 'y', 'k', 'e', 'y', '=', 0x0, 0x4, 0x65, 0x7, 0xff]
+        // [17, 'm', 'y', 'K', 'e', 'y', 'W', 'i', 't', 'h', 'N', 'o', 'V', 'a', 'l', 'u', 'e', '=']
+        // [12, 'm', 'y', 'B', 'o', 'o', 'l', 'e', 'a', 'n', 'K', 'e', 'y']
+        //
+        // Example corrupted records
+        // [3, =, 1, 2]    <- key is empty
+        // [3, 0, =, 2]    <- key contains non-ASCII character. We handle this by replacing the
+        //                    invalid characters instead of skipping the record.
+        // [30, 'a', =, 2] <- length exceeds total left over bytes in the TXT records array, we
+        //                    handle this by reducing the length of the record as needed.
+        int pos = 0;
+        while (pos < txtRecordsRawBytes.length) {
+            // recordLen is an unsigned 8 bit value
+            int recordLen = txtRecordsRawBytes[pos] & 0xff;
+            pos += 1;
+
+            try {
+                if (recordLen == 0) {
+                    throw new IllegalArgumentException("Zero sized txt record");
+                } else if (pos + recordLen > txtRecordsRawBytes.length) {
+                    Log.w(TAG, "Corrupt record length (pos = " + pos + "): " + recordLen);
+                    recordLen = txtRecordsRawBytes.length - pos;
+                }
+
+                // Decode key-value records
+                String key = null;
+                byte[] value = null;
+                int valueLen = 0;
+                for (int i = pos; i < pos + recordLen; i++) {
+                    if (key == null) {
+                        if (txtRecordsRawBytes[i] == '=') {
+                            key = new String(txtRecordsRawBytes, pos, i - pos,
+                                    StandardCharsets.US_ASCII);
+                        }
+                    } else {
+                        if (value == null) {
+                            value = new byte[recordLen - key.length() - 1];
+                        }
+                        value[valueLen] = txtRecordsRawBytes[i];
+                        valueLen++;
+                    }
+                }
+
+                // If '=' was not found we have a boolean record
+                if (key == null) {
+                    key = new String(txtRecordsRawBytes, pos, recordLen, StandardCharsets.US_ASCII);
+                }
+
+                if (TextUtils.isEmpty(key)) {
+                    // Empty keys are not allowed (RFC6763 6.4)
+                    throw new IllegalArgumentException("Invalid txt record (key is empty)");
+                }
+
+                if (getAttributes().containsKey(key)) {
+                    // When we have a duplicate record, the later ones are ignored (RFC6763 6.4)
+                    throw new IllegalArgumentException("Invalid txt record (duplicate key \"" + key + "\")");
+                }
+
+                setAttribute(key, value);
+            } catch (IllegalArgumentException e) {
+                Log.e(TAG, "While parsing txt records (pos = " + pos + "): " + e.getMessage());
+            }
+
+            pos += recordLen;
+        }
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public void setAttribute(String key, byte[] value) {
+        if (TextUtils.isEmpty(key)) {
+            throw new IllegalArgumentException("Key cannot be empty");
+        }
+
+        // Key must be printable US-ASCII, excluding =.
+        for (int i = 0; i < key.length(); ++i) {
+            char character = key.charAt(i);
+            if (character < 0x20 || character > 0x7E) {
+                throw new IllegalArgumentException("Key strings must be printable US-ASCII");
+            } else if (character == 0x3D) {
+                throw new IllegalArgumentException("Key strings must not include '='");
+            }
+        }
+
+        // Key length + value length must be < 255.
+        if (key.length() + (value == null ? 0 : value.length) >= 255) {
+            throw new IllegalArgumentException("Key length + value length must be < 255 bytes");
+        }
+
+        // Warn if key is > 9 characters, as recommended by RFC 6763 section 6.4.
+        if (key.length() > 9) {
+            Log.w(TAG, "Key lengths > 9 are discouraged: " + key);
+        }
+
+        // Check against total TXT record size limits.
+        // Arbitrary 400 / 1300 byte limits taken from RFC 6763 section 6.2.
+        int txtRecordSize = getTxtRecordSize();
+        int futureSize = txtRecordSize + key.length() + (value == null ? 0 : value.length) + 2;
+        if (futureSize > 1300) {
+            throw new IllegalArgumentException("Total length of attributes must be < 1300 bytes");
+        } else if (futureSize > 400) {
+            Log.w(TAG, "Total length of all attributes exceeds 400 bytes; truncation may occur");
+        }
+
+        mTxtRecord.put(key, value);
+    }
+
+    /**
+     * Add a service attribute as a key/value pair.
+     *
+     * <p> Service attributes are included as DNS-SD TXT record pairs.
+     *
+     * <p> The key must be US-ASCII printable characters, excluding the '=' character.  Values may
+     * be UTF-8 strings or null.  The total length of key + value must be less than 255 bytes.
+     *
+     * <p> Keys should be short, ideally no more than 9 characters, and unique per instance of
+     * {@link NsdServiceInfo}.  Calling {@link #setAttribute} twice with the same key will overwrite
+     * first value.
+     */
+    public void setAttribute(String key, String value) {
+        try {
+            setAttribute(key, value == null ? (byte []) null : value.getBytes("UTF-8"));
+        } catch (UnsupportedEncodingException e) {
+            throw new IllegalArgumentException("Value must be UTF-8");
+        }
+    }
+
+    /** Remove an attribute by key */
+    public void removeAttribute(String key) {
+        mTxtRecord.remove(key);
+    }
+
+    /**
+     * Retrieve attributes as a map of String keys to byte[] values. The attributes map is only
+     * valid for a resolved service.
+     *
+     * <p> The returned map is unmodifiable; changes must be made through {@link #setAttribute} and
+     * {@link #removeAttribute}.
+     */
+    public Map<String, byte[]> getAttributes() {
+        return Collections.unmodifiableMap(mTxtRecord);
+    }
+
+    private int getTxtRecordSize() {
+        int txtRecordSize = 0;
+        for (Map.Entry<String, byte[]> entry : mTxtRecord.entrySet()) {
+            txtRecordSize += 2;  // One for the length byte, one for the = between key and value.
+            txtRecordSize += entry.getKey().length();
+            byte[] value = entry.getValue();
+            txtRecordSize += value == null ? 0 : value.length;
+        }
+        return txtRecordSize;
+    }
+
+    /** @hide */
+    public @NonNull byte[] getTxtRecord() {
+        int txtRecordSize = getTxtRecordSize();
+        if (txtRecordSize == 0) {
+            return new byte[]{};
+        }
+
+        byte[] txtRecord = new byte[txtRecordSize];
+        int ptr = 0;
+        for (Map.Entry<String, byte[]> entry : mTxtRecord.entrySet()) {
+            String key = entry.getKey();
+            byte[] value = entry.getValue();
+
+            // One byte to record the length of this key/value pair.
+            txtRecord[ptr++] = (byte) (key.length() + (value == null ? 0 : value.length) + 1);
+
+            // The key, in US-ASCII.
+            // Note: use the StandardCharsets const here because it doesn't raise exceptions and we
+            // already know the key is ASCII at this point.
+            System.arraycopy(key.getBytes(StandardCharsets.US_ASCII), 0, txtRecord, ptr,
+                    key.length());
+            ptr += key.length();
+
+            // US-ASCII '=' character.
+            txtRecord[ptr++] = (byte)'=';
+
+            // The value, as any raw bytes.
+            if (value != null) {
+                System.arraycopy(value, 0, txtRecord, ptr, value.length);
+                ptr += value.length;
+            }
+        }
+        return txtRecord;
+    }
+
+    /**
+     * Get the network where the service can be found.
+     *
+     * This is never null if this {@link NsdServiceInfo} was obtained from
+     * {@link NsdManager#discoverServices} or {@link NsdManager#resolveService}.
+     */
+    @Nullable
+    public Network getNetwork() {
+        return mNetwork;
+    }
+
+    /**
+     * Set the network where the service can be found.
+     * @param network The network, or null to search for, or to announce, the service on all
+     *                connected networks.
+     */
+    public void setNetwork(@Nullable Network network) {
+        mNetwork = network;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("name: ").append(mServiceName)
+                .append(", type: ").append(mServiceType)
+                .append(", host: ").append(mHost)
+                .append(", port: ").append(mPort)
+                .append(", network: ").append(mNetwork);
+
+        byte[] txtRecord = getTxtRecord();
+        sb.append(", txtRecord: ").append(new String(txtRecord, StandardCharsets.UTF_8));
+        return sb.toString();
+    }
+
+    /** Implement the Parcelable interface */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mServiceName);
+        dest.writeString(mServiceType);
+        if (mHost != null) {
+            dest.writeInt(1);
+            dest.writeByteArray(mHost.getAddress());
+        } else {
+            dest.writeInt(0);
+        }
+        dest.writeInt(mPort);
+
+        // TXT record key/value pairs.
+        dest.writeInt(mTxtRecord.size());
+        for (String key : mTxtRecord.keySet()) {
+            byte[] value = mTxtRecord.get(key);
+            if (value != null) {
+                dest.writeInt(1);
+                dest.writeInt(value.length);
+                dest.writeByteArray(value);
+            } else {
+                dest.writeInt(0);
+            }
+            dest.writeString(key);
+        }
+
+        dest.writeParcelable(mNetwork, 0);
+    }
+
+    /** Implement the Parcelable interface */
+    public static final @android.annotation.NonNull Creator<NsdServiceInfo> CREATOR =
+        new Creator<NsdServiceInfo>() {
+            public NsdServiceInfo createFromParcel(Parcel in) {
+                NsdServiceInfo info = new NsdServiceInfo();
+                info.mServiceName = in.readString();
+                info.mServiceType = in.readString();
+
+                if (in.readInt() == 1) {
+                    try {
+                        info.mHost = InetAddress.getByAddress(in.createByteArray());
+                    } catch (java.net.UnknownHostException e) {}
+                }
+
+                info.mPort = in.readInt();
+
+                // TXT record key/value pairs.
+                int recordCount = in.readInt();
+                for (int i = 0; i < recordCount; ++i) {
+                    byte[] valueArray = null;
+                    if (in.readInt() == 1) {
+                        int valueLength = in.readInt();
+                        valueArray = new byte[valueLength];
+                        in.readByteArray(valueArray);
+                    }
+                    info.mTxtRecord.put(in.readString(), valueArray);
+                }
+                info.mNetwork = in.readParcelable(null, Network.class);
+                return info;
+            }
+
+            public NsdServiceInfo[] newArray(int size) {
+                return new NsdServiceInfo[size];
+            }
+        };
+}
diff --git a/framework/aidl-export/android/net/NetworkStats.aidl b/framework/aidl-export/android/net/NetworkStats.aidl
new file mode 100644
index 0000000..d06ca65
--- /dev/null
+++ b/framework/aidl-export/android/net/NetworkStats.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+parcelable NetworkStats;
diff --git a/framework/aidl-export/android/net/NetworkTemplate.aidl b/framework/aidl-export/android/net/NetworkTemplate.aidl
new file mode 100644
index 0000000..3d37488
--- /dev/null
+++ b/framework/aidl-export/android/net/NetworkTemplate.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+parcelable NetworkTemplate;
diff --git a/framework/aidl-export/android/net/nsd/NsdServiceInfo.aidl b/framework/aidl-export/android/net/nsd/NsdServiceInfo.aidl
new file mode 100644
index 0000000..657bdd1
--- /dev/null
+++ b/framework/aidl-export/android/net/nsd/NsdServiceInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 android.net.nsd;
+
+@JavaOnlyStableParcelable parcelable NsdServiceInfo;
\ No newline at end of file
diff --git a/nearby/.gitignore b/nearby/.gitignore
new file mode 100644
index 0000000..4402b3d
--- /dev/null
+++ b/nearby/.gitignore
@@ -0,0 +1,8 @@
+# Eclipse project
+**/.classpath
+**/.project
+
+# IntelliJ project
+**/.idea
+**/*.iml
+**/*.ipr
\ No newline at end of file
diff --git a/nearby/Android.bp b/nearby/Android.bp
deleted file mode 100644
index fb4e3cd..0000000
--- a/nearby/Android.bp
+++ /dev/null
@@ -1,39 +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.
-//
-
-package {
-    // See: http://go/android-license-faq
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-// Empty sources and libraries to avoid merge conflicts with downstream
-// branches
-// TODO: remove once the Nearby sources are available in this branch
-filegroup {
-    name: "framework-nearby-java-sources",
-    srcs: [],
-    visibility: ["//packages/modules/Connectivity:__subpackages__"],
-}
-
-
-java_library {
-    name: "service-nearby-pre-jarjar",
-    srcs: ["service-src/**/*.java"],
-    sdk_version: "module_current",
-    min_sdk_version: "30",
-    apex_available: ["com.android.tethering"],
-    visibility: ["//packages/modules/Connectivity:__subpackages__"],
-}
diff --git a/nearby/PREUPLOAD.cfg b/nearby/PREUPLOAD.cfg
new file mode 100644
index 0000000..048ddb6
--- /dev/null
+++ b/nearby/PREUPLOAD.cfg
@@ -0,0 +1,10 @@
+[Builtin Hooks]
+xmllint = true
+clang_format = true
+commit_msg_changeid_field = true
+
+[Builtin Hooks Options]
+clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+
+[Hook Scripts]
+checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
\ No newline at end of file
diff --git a/nearby/README.md b/nearby/README.md
new file mode 100644
index 0000000..6925dc4
--- /dev/null
+++ b/nearby/README.md
@@ -0,0 +1,42 @@
+# Nearby Mainline Module
+This directory contains code for the AOSP Nearby mainline module.
+
+##Directory Structure
+
+`apex`
+ - Files associated with the Nearby mainline module APEX.
+
+`framework`
+ - Contains client side APIs and AIDL files.
+
+`jni`
+ - JNI wrapper for invoking Android APIs from native code.
+
+`native`
+ - Native code implementation for nearby module services.
+
+`service`
+ - Server side implementation for nearby module services.
+
+`tests`
+ - Unit/Multi devices tests for Nearby module (both Java and native code).
+
+## IDE setup
+
+```sh
+$ source build/envsetup.sh && lunch <TARGET>
+$ cd packages/modules/Nearby
+$ aidegen .
+# This will launch Intellij project for Nearby module.
+```
+
+## Build and Install
+
+```sh
+$ source build/envsetup.sh && lunch <TARGET>
+$ m com.google.android.tethering.next deapexer
+$ $ANDROID_BUILD_TOP/out/host/linux-x86/bin/deapexer decompress --input \
+    ${ANDROID_PRODUCT_OUT}/system/apex/com.google.android.tethering.next.capex \
+    --output /tmp/tethering.apex
+$ adb install -r /tmp/tethering.apex
+```
diff --git a/nearby/TEST_MAPPING b/nearby/TEST_MAPPING
new file mode 100644
index 0000000..dbaca33
--- /dev/null
+++ b/nearby/TEST_MAPPING
@@ -0,0 +1,24 @@
+{
+  "presubmit": [
+    {
+      "name": "NearbyUnitTests"
+    },
+    {
+      "name": "NearbyIntegrationPrivilegedTests"
+    },
+    {
+      "name": "NearbyIntegrationUntrustedTests"
+    }
+  ],
+  "postsubmit": [
+    {
+      "name": "NearbyUnitTests"
+    }
+  ]
+  // TODO(b/193602229): uncomment once it's supported.
+  //"mainline-presubmit": [
+  //  {
+  //    "name": "NearbyUnitTests[com.google.android.nearby.apex]"
+  //  }
+  //]
+}
diff --git a/nearby/apex/Android.bp b/nearby/apex/Android.bp
new file mode 100644
index 0000000..d7f063a
--- /dev/null
+++ b/nearby/apex/Android.bp
@@ -0,0 +1,21 @@
+// 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+    name: "nearby-jarjar-rules",
+    srcs: ["jarjar-rules.txt"],
+}
diff --git a/nearby/apex/jarjar-rules.txt b/nearby/apex/jarjar-rules.txt
new file mode 100644
index 0000000..826f54f
--- /dev/null
+++ b/nearby/apex/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.android.internal.** com.android.nearby.jarjar.@0
diff --git a/nearby/apex/manifest.json b/nearby/apex/manifest.json
new file mode 100644
index 0000000..b91d259
--- /dev/null
+++ b/nearby/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.nearby",
+  "version": 1
+}
diff --git a/nearby/framework/Android.bp b/nearby/framework/Android.bp
new file mode 100644
index 0000000..e223b54
--- /dev/null
+++ b/nearby/framework/Android.bp
@@ -0,0 +1,55 @@
+// 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// Sources included in the framework-connectivity-t jar
+// TODO: consider moving files to packages/modules/Connectivity
+filegroup {
+    name: "framework-nearby-java-sources",
+    srcs: [
+        "java/**/*.java",
+        "java/**/*.aidl",
+    ],
+    path: "java",
+    visibility: [
+        "//packages/modules/Connectivity/framework-t:__subpackages__",
+    ],
+}
+
+filegroup {
+    name: "framework-nearby-sources",
+    srcs: [
+        ":framework-nearby-java-sources",
+    ],
+    visibility: ["//frameworks/base"],
+}
+
+// Build of only framework-nearby (not as part of connectivity) for
+// unit tests
+java_library {
+    name: "framework-nearby-static",
+    srcs: [":framework-nearby-java-sources"],
+    sdk_version: "module_current",
+    libs: [
+        "framework-annotations-lib",
+        "framework-bluetooth",
+    ],
+    static_libs: [
+        "modules-utils-preconditions",
+    ],
+    visibility: ["//packages/modules/Connectivity/nearby/tests:__subpackages__"],
+}
diff --git a/nearby/framework/java/android/nearby/BroadcastCallback.java b/nearby/framework/java/android/nearby/BroadcastCallback.java
new file mode 100644
index 0000000..cc94308
--- /dev/null
+++ b/nearby/framework/java/android/nearby/BroadcastCallback.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Callback when broadcasting request using nearby specification.
+ *
+ * @hide
+ */
+@SystemApi
+public interface BroadcastCallback {
+    /** Broadcast was successful. */
+    int STATUS_OK = 0;
+
+    /** General status code when broadcast failed. */
+    int STATUS_FAILURE = 1;
+
+    /**
+     * Broadcast failed as the callback was already registered.
+     */
+    int STATUS_FAILURE_ALREADY_REGISTERED = 2;
+
+    /**
+     * Broadcast failed as the request contains excessive data.
+     */
+    int STATUS_FAILURE_SIZE_EXCEED_LIMIT = 3;
+
+    /**
+     * Broadcast failed as the client doesn't hold required permissions.
+     */
+    int STATUS_FAILURE_MISSING_PERMISSIONS = 4;
+
+    /** @hide **/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({STATUS_OK, STATUS_FAILURE, STATUS_FAILURE_ALREADY_REGISTERED,
+            STATUS_FAILURE_SIZE_EXCEED_LIMIT, STATUS_FAILURE_MISSING_PERMISSIONS})
+    @interface BroadcastStatus {
+    }
+
+    /**
+     * Called when broadcast status changes.
+     */
+    void onStatusChanged(@BroadcastStatus int status);
+}
diff --git a/nearby/framework/java/android/nearby/BroadcastRequest.java b/nearby/framework/java/android/nearby/BroadcastRequest.java
new file mode 100644
index 0000000..3273ea1
--- /dev/null
+++ b/nearby/framework/java/android/nearby/BroadcastRequest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a {@link BroadcastRequest}.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class BroadcastRequest {
+
+    /** An unknown nearby broadcast request type. */
+    public static final int BROADCAST_TYPE_UNKNOWN = -1;
+
+    /** Broadcast type for advertising using nearby presence protocol. */
+    public static final int BROADCAST_TYPE_NEARBY_PRESENCE = 3;
+
+    /** @hide **/
+    // Currently, only Nearby Presence broadcast is supported, in the future
+    // broadcasting using other nearby specifications will be added.
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({BROADCAST_TYPE_UNKNOWN, BROADCAST_TYPE_NEARBY_PRESENCE})
+    public @interface BroadcastType {
+    }
+
+    /**
+     * Tx Power when the value is not set in the broadcast.
+     */
+    public static final int UNKNOWN_TX_POWER = -127;
+
+    /**
+     * An unknown version of presence broadcast request.
+     */
+    public static final int PRESENCE_VERSION_UNKNOWN = -1;
+
+    /**
+     * A legacy presence version that is only suitable for legacy (31 bytes) BLE advertisements.
+     * This exists to support legacy presence version, and not recommended for use.
+     */
+    public static final int PRESENCE_VERSION_V0 = 0;
+
+    /**
+     * V1 of Nearby Presence Protocol. This version supports both legacy (31 bytes) BLE
+     * advertisements, and extended BLE advertisements.
+     */
+    public static final int PRESENCE_VERSION_V1 = 1;
+
+    /** @hide **/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({PRESENCE_VERSION_UNKNOWN, PRESENCE_VERSION_V0, PRESENCE_VERSION_V1})
+    public @interface BroadcastVersion {
+    }
+
+    /**
+     * The medium where the broadcast request should be sent.
+     *
+     * @hide
+     */
+    @IntDef({Medium.BLE, Medium.MDNS})
+    public @interface Medium {
+        int BLE = 1;
+        int MDNS = 2;
+    }
+
+    /**
+     * Creates a {@link BroadcastRequest} from parcel.
+     *
+     * @hide
+     */
+    @NonNull
+    public static BroadcastRequest createFromParcel(Parcel in) {
+        int type = in.readInt();
+        switch (type) {
+            case BroadcastRequest.BROADCAST_TYPE_NEARBY_PRESENCE:
+                return PresenceBroadcastRequest.createFromParcelBody(in);
+            default:
+                throw new IllegalStateException(
+                        "Unexpected broadcast type (value " + type + ") in parcel.");
+        }
+    }
+
+    private final @BroadcastType int mType;
+    private final @BroadcastVersion int mVersion;
+    private final int mTxPower;
+    private final @Medium List<Integer> mMediums;
+
+    BroadcastRequest(@BroadcastType int type, @BroadcastVersion int version, int txPower,
+            @Medium List<Integer> mediums) {
+        this.mType = type;
+        this.mVersion = version;
+        this.mTxPower = txPower;
+        this.mMediums = mediums;
+    }
+
+    BroadcastRequest(@BroadcastType int type, Parcel in) {
+        mType = type;
+        mVersion = in.readInt();
+        mTxPower = in.readInt();
+        mMediums = new ArrayList<>();
+        in.readList(mMediums, Integer.class.getClassLoader(), Integer.class);
+    }
+
+    /**
+     * Returns the type of the broadcast.
+     */
+    public @BroadcastType int getType() {
+        return mType;
+    }
+
+    /**
+     * Returns the version of the broadcast.
+     */
+    public @BroadcastVersion int getVersion() {
+        return mVersion;
+    }
+
+    /**
+     * Returns the calibrated TX power when this request is broadcast.
+     */
+    @IntRange(from = -127, to = 126)
+    public int getTxPower() {
+        return mTxPower;
+    }
+
+    /**
+     * Returns the list of broadcast mediums.
+     */
+    @NonNull
+    @Medium
+    public List<Integer> getMediums() {
+        return mMediums;
+    }
+
+    /**
+     * Writes the BroadcastRequest to the parcel.
+     *
+     * @hide
+     */
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mType);
+        dest.writeInt(mVersion);
+        dest.writeInt(mTxPower);
+        dest.writeList(mMediums);
+    }
+}
diff --git a/nearby/framework/java/android/nearby/BroadcastRequestParcelable.aidl b/nearby/framework/java/android/nearby/BroadcastRequestParcelable.aidl
new file mode 100644
index 0000000..818f8d5
--- /dev/null
+++ b/nearby/framework/java/android/nearby/BroadcastRequestParcelable.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+parcelable BroadcastRequestParcelable;
diff --git a/nearby/framework/java/android/nearby/BroadcastRequestParcelable.java b/nearby/framework/java/android/nearby/BroadcastRequestParcelable.java
new file mode 100644
index 0000000..4a2ff6d
--- /dev/null
+++ b/nearby/framework/java/android/nearby/BroadcastRequestParcelable.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A wrapper of {@link BroadcastRequest} that is parcelable.
+ *
+ * @hide
+ */
+public class BroadcastRequestParcelable implements Parcelable {
+    private final BroadcastRequest mBroadcastRequest;
+
+    public static final Creator<BroadcastRequestParcelable> CREATOR =
+            new Creator<BroadcastRequestParcelable>() {
+                @Override
+                public BroadcastRequestParcelable createFromParcel(Parcel in) {
+                    return new BroadcastRequestParcelable(BroadcastRequest.createFromParcel(in));
+                }
+
+                @Override
+                public BroadcastRequestParcelable[] newArray(int size) {
+                    return new BroadcastRequestParcelable[size];
+                }
+            };
+
+    BroadcastRequestParcelable(BroadcastRequest broadcastRequest) {
+        mBroadcastRequest = broadcastRequest;
+    }
+
+    /**
+     * Returns the broadcastRequest.
+     */
+    public BroadcastRequest getBroadcastRequest() {
+        return mBroadcastRequest;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        mBroadcastRequest.writeToParcel(dest, flags);
+    }
+}
diff --git a/nearby/framework/java/android/nearby/CredentialElement.java b/nearby/framework/java/android/nearby/CredentialElement.java
new file mode 100644
index 0000000..7a43b01
--- /dev/null
+++ b/nearby/framework/java/android/nearby/CredentialElement.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Represents an element in {@link PresenceCredential}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class CredentialElement implements Parcelable {
+    private final String mKey;
+    private final byte[] mValue;
+
+    /** Constructs a {@link CredentialElement}. */
+    public CredentialElement(@NonNull String key, @NonNull byte[] value) {
+        Preconditions.checkState(key != null && value != null, "neither key or value can be null");
+        mKey = key;
+        mValue = value;
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<CredentialElement> CREATOR =
+            new Parcelable.Creator<CredentialElement>() {
+                @Override
+                public CredentialElement createFromParcel(Parcel in) {
+                    String key = in.readString();
+                    byte[] value = new byte[in.readInt()];
+                    in.readByteArray(value);
+                    return new CredentialElement(key, value);
+                }
+
+                @Override
+                public CredentialElement[] newArray(int size) {
+                    return new CredentialElement[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mKey);
+        dest.writeInt(mValue.length);
+        dest.writeByteArray(mValue);
+    }
+
+    /** Returns the key of the credential element. */
+    @NonNull
+    public String getKey() {
+        return mKey;
+    }
+
+    /** Returns the value of the credential element. */
+    @NonNull
+    public byte[] getValue() {
+        return mValue;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj instanceof CredentialElement) {
+            CredentialElement that = (CredentialElement) obj;
+            return mKey.equals(that.mKey) && Arrays.equals(mValue, that.mValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mKey.hashCode(), Arrays.hashCode(mValue));
+    }
+}
diff --git a/nearby/framework/java/android/nearby/DataElement.java b/nearby/framework/java/android/nearby/DataElement.java
new file mode 100644
index 0000000..6fa5fb5
--- /dev/null
+++ b/nearby/framework/java/android/nearby/DataElement.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+
+/**
+ * Represents a data element in Nearby Presence.
+ *
+ * @hide
+ */
+@SystemApi
+public final class DataElement implements Parcelable {
+
+    private final int mKey;
+    private final byte[] mValue;
+
+    /**
+     * Constructs a {@link DataElement}.
+     */
+    public DataElement(int key, @NonNull byte[] value) {
+        Preconditions.checkState(value != null, "value cannot be null");
+        mKey = key;
+        mValue = value;
+    }
+
+    @NonNull
+    public static final Creator<DataElement> CREATOR = new Creator<DataElement>() {
+        @Override
+        public DataElement createFromParcel(Parcel in) {
+            int key = in.readInt();
+            byte[] value = new byte[in.readInt()];
+            in.readByteArray(value);
+            return new DataElement(key, value);
+        }
+
+        @Override
+        public DataElement[] newArray(int size) {
+            return new DataElement[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mKey);
+        dest.writeInt(mValue.length);
+        dest.writeByteArray(mValue);
+    }
+
+    /**
+     * Returns the key of the data element, as defined in the nearby presence specification.
+     */
+    public int getKey() {
+        return mKey;
+    }
+
+    /**
+     * Returns the value of the data element.
+     */
+    @NonNull
+    public byte[] getValue() {
+        return mValue;
+    }
+}
diff --git a/nearby/framework/java/android/nearby/FastPairAccountKeyDeviceMetadata.java b/nearby/framework/java/android/nearby/FastPairAccountKeyDeviceMetadata.java
new file mode 100644
index 0000000..160ad75
--- /dev/null
+++ b/nearby/framework/java/android/nearby/FastPairAccountKeyDeviceMetadata.java
@@ -0,0 +1,196 @@
+/*
+ * 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 android.nearby;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
+
+/**
+ * Class for metadata of a Fast Pair device associated with an account.
+ *
+ * @hide
+ */
+@SystemApi
+public class FastPairAccountKeyDeviceMetadata {
+
+    FastPairAccountKeyDeviceMetadataParcel mMetadataParcel;
+
+    FastPairAccountKeyDeviceMetadata(FastPairAccountKeyDeviceMetadataParcel metadataParcel) {
+        this.mMetadataParcel = metadataParcel;
+    }
+
+    /**
+     * Get Device Account Key, which uniquely identifies a Fast Pair device associated with an
+     * account. AccountKey is 16 bytes: first byte is 0x04. Other 15 bytes are randomly generated.
+     *
+     * @return 16-byte Account Key.
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public byte[] getDeviceAccountKey() {
+        return mMetadataParcel.deviceAccountKey;
+    }
+
+    /**
+     * Get a hash value of device's account key and public bluetooth address without revealing the
+     * public bluetooth address. Sha256 hash value is 32 bytes.
+     *
+     * @return 32-byte Sha256 hash value.
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public byte[] getSha256DeviceAccountKeyPublicAddress() {
+        return mMetadataParcel.sha256DeviceAccountKeyPublicAddress;
+    }
+
+    /**
+     * Get metadata of a Fast Pair device type.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public FastPairDeviceMetadata getFastPairDeviceMetadata() {
+        if (mMetadataParcel.metadata == null) {
+            return null;
+        }
+        return new FastPairDeviceMetadata(mMetadataParcel.metadata);
+    }
+
+    /**
+     * Get Fast Pair discovery item, which is tied to both the device type and the account.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public FastPairDiscoveryItem getFastPairDiscoveryItem() {
+        if (mMetadataParcel.discoveryItem == null) {
+            return null;
+        }
+        return new FastPairDiscoveryItem(mMetadataParcel.discoveryItem);
+    }
+
+    /**
+     * Builder used to create FastPairAccountKeyDeviceMetadata.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder {
+
+        private final FastPairAccountKeyDeviceMetadataParcel mBuilderParcel;
+
+        /**
+         * Default constructor of Builder.
+         *
+         * @hide
+         */
+        @SystemApi
+        public Builder() {
+            mBuilderParcel = new FastPairAccountKeyDeviceMetadataParcel();
+            mBuilderParcel.deviceAccountKey = null;
+            mBuilderParcel.sha256DeviceAccountKeyPublicAddress = null;
+            mBuilderParcel.metadata = null;
+            mBuilderParcel.discoveryItem = null;
+        }
+
+        /**
+         * Set Account Key.
+         *
+         * @param deviceAccountKey Fast Pair device account key, which is 16 bytes: first byte is
+         *                         0x04. Next 15 bytes are randomly generated.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setDeviceAccountKey(@Nullable byte[] deviceAccountKey) {
+            mBuilderParcel.deviceAccountKey = deviceAccountKey;
+            return this;
+        }
+
+        /**
+         * Set sha256 hash value of account key and public bluetooth address.
+         *
+         * @param sha256DeviceAccountKeyPublicAddress 32-byte sha256 hash value of account key and
+         *                                            public bluetooth address.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setSha256DeviceAccountKeyPublicAddress(
+                @Nullable byte[] sha256DeviceAccountKeyPublicAddress) {
+            mBuilderParcel.sha256DeviceAccountKeyPublicAddress =
+                    sha256DeviceAccountKeyPublicAddress;
+            return this;
+        }
+
+
+        /**
+         * Set Fast Pair metadata.
+         *
+         * @param metadata Fast Pair metadata.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setFastPairDeviceMetadata(@Nullable FastPairDeviceMetadata metadata) {
+            if (metadata == null) {
+                mBuilderParcel.metadata = null;
+            } else {
+                mBuilderParcel.metadata = metadata.mMetadataParcel;
+            }
+            return this;
+        }
+
+        /**
+         * Set Fast Pair discovery item.
+         *
+         * @param discoveryItem Fast Pair discovery item.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setFastPairDiscoveryItem(@Nullable FastPairDiscoveryItem discoveryItem) {
+            if (discoveryItem == null) {
+                mBuilderParcel.discoveryItem = null;
+            } else {
+                mBuilderParcel.discoveryItem = discoveryItem.mMetadataParcel;
+            }
+            return this;
+        }
+
+        /**
+         * Build {@link FastPairAccountKeyDeviceMetadata} with the currently set configuration.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public FastPairAccountKeyDeviceMetadata build() {
+            return new FastPairAccountKeyDeviceMetadata(mBuilderParcel);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/FastPairAntispoofKeyDeviceMetadata.java b/nearby/framework/java/android/nearby/FastPairAntispoofKeyDeviceMetadata.java
new file mode 100644
index 0000000..1837671
--- /dev/null
+++ b/nearby/framework/java/android/nearby/FastPairAntispoofKeyDeviceMetadata.java
@@ -0,0 +1,128 @@
+/*
+ * 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 android.nearby;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataParcel;
+
+/**
+ * Class for a type of registered Fast Pair device keyed by modelID, or antispoofKey.
+ *
+ * @hide
+ */
+@SystemApi
+public class FastPairAntispoofKeyDeviceMetadata {
+
+    FastPairAntispoofKeyDeviceMetadataParcel mMetadataParcel;
+    FastPairAntispoofKeyDeviceMetadata(
+            FastPairAntispoofKeyDeviceMetadataParcel metadataParcel) {
+        this.mMetadataParcel = metadataParcel;
+    }
+
+    /**
+     * Get Antispoof public key.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public byte[] getAntispoofPublicKey() {
+        return this.mMetadataParcel.antispoofPublicKey;
+    }
+
+    /**
+     * Get metadata of a Fast Pair device type.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public FastPairDeviceMetadata getFastPairDeviceMetadata() {
+        if (this.mMetadataParcel.deviceMetadata == null) {
+            return null;
+        }
+        return new FastPairDeviceMetadata(this.mMetadataParcel.deviceMetadata);
+    }
+
+    /**
+     * Builder used to create FastPairAntispoofkeyDeviceMetadata.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder {
+
+        private final FastPairAntispoofKeyDeviceMetadataParcel mBuilderParcel;
+
+        /**
+         * Default constructor of Builder.
+         *
+         * @hide
+         */
+        @SystemApi
+        public Builder() {
+            mBuilderParcel = new FastPairAntispoofKeyDeviceMetadataParcel();
+            mBuilderParcel.antispoofPublicKey = null;
+            mBuilderParcel.deviceMetadata = null;
+        }
+
+        /**
+         * Set AntiSpoof public key, which uniquely identify a Fast Pair device type.
+         *
+         * @param antispoofPublicKey is 64 bytes, see <a href="https://developers.google.com/nearby/fast-pair/spec#data_format">Data Format</a>.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setAntispoofPublicKey(@Nullable byte[] antispoofPublicKey) {
+            mBuilderParcel.antispoofPublicKey = antispoofPublicKey;
+            return this;
+        }
+
+        /**
+         * Set Fast Pair metadata, which is the property of a Fast Pair device type, including
+         * device images and strings.
+         *
+         * @param metadata Fast Pair device meta data.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setFastPairDeviceMetadata(@Nullable FastPairDeviceMetadata metadata) {
+            if (metadata != null) {
+                mBuilderParcel.deviceMetadata = metadata.mMetadataParcel;
+            } else {
+                mBuilderParcel.deviceMetadata = null;
+            }
+            return this;
+        }
+
+        /**
+         * Build {@link FastPairAntispoofKeyDeviceMetadata} with the currently set configuration.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public FastPairAntispoofKeyDeviceMetadata build() {
+            return new FastPairAntispoofKeyDeviceMetadata(mBuilderParcel);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/FastPairDataProviderService.java b/nearby/framework/java/android/nearby/FastPairDataProviderService.java
new file mode 100644
index 0000000..c6a1a65
--- /dev/null
+++ b/nearby/framework/java/android/nearby/FastPairDataProviderService.java
@@ -0,0 +1,761 @@
+/*
+ * 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 android.nearby;
+
+import android.accounts.Account;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.nearby.aidl.ByteArrayParcel;
+import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel;
+import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataRequestParcel;
+import android.nearby.aidl.FastPairEligibleAccountParcel;
+import android.nearby.aidl.FastPairEligibleAccountsRequestParcel;
+import android.nearby.aidl.FastPairManageAccountDeviceRequestParcel;
+import android.nearby.aidl.FastPairManageAccountRequestParcel;
+import android.nearby.aidl.IFastPairAccountDevicesMetadataCallback;
+import android.nearby.aidl.IFastPairAntispoofKeyDeviceMetadataCallback;
+import android.nearby.aidl.IFastPairDataProvider;
+import android.nearby.aidl.IFastPairEligibleAccountsCallback;
+import android.nearby.aidl.IFastPairManageAccountCallback;
+import android.nearby.aidl.IFastPairManageAccountDeviceCallback;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * A service class for fast pair data providers outside the system server.
+ *
+ * Fast pair providers should be wrapped in a non-exported service which returns the result of
+ * {@link #getBinder()} from the service's {@link android.app.Service#onBind(Intent)} method. The
+ * service should not be exported so that components other than the system server cannot bind to it.
+ * Alternatively, the service may be guarded by a permission that only system server can obtain.
+ *
+ * <p>Fast Pair providers are identified by their UID / package name.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class FastPairDataProviderService extends Service {
+    /**
+     * The action the wrapping service should have in its intent filter to implement the
+     * {@link android.nearby.FastPairDataProviderBase}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String ACTION_FAST_PAIR_DATA_PROVIDER =
+            "android.nearby.action.FAST_PAIR_DATA_PROVIDER";
+
+    /**
+     * Manage request type to add, or opt-in.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int MANAGE_REQUEST_ADD = 0;
+
+    /**
+     * Manage request type to remove, or opt-out.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int MANAGE_REQUEST_REMOVE = 1;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            MANAGE_REQUEST_ADD,
+            MANAGE_REQUEST_REMOVE})
+    @interface ManageRequestType {}
+
+    /**
+     * Error code for bad request.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int ERROR_CODE_BAD_REQUEST = 0;
+
+    /**
+     * Error code for internal error.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int ERROR_CODE_INTERNAL_ERROR = 1;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            ERROR_CODE_BAD_REQUEST,
+            ERROR_CODE_INTERNAL_ERROR})
+    @interface ErrorCode {}
+
+    private final IBinder mBinder;
+    private final String mTag;
+
+    /**
+     * Constructor of FastPairDataProviderService.
+     *
+     * @param tag TAG for on device logging.
+     * @hide
+     */
+    @SystemApi
+    public FastPairDataProviderService(@NonNull String tag) {
+        mBinder = new Service();
+        mTag = tag;
+    }
+
+    @Override
+    @NonNull
+    public final IBinder onBind(@NonNull Intent intent) {
+        return mBinder;
+    }
+
+    /**
+     * Callback to be invoked when an AntispoofKeyed device metadata is loaded.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface FastPairAntispoofKeyDeviceMetadataCallback {
+
+        /**
+         * Invoked once the meta data is loaded.
+         *
+         * @hide
+         */
+        @SystemApi
+        void onFastPairAntispoofKeyDeviceMetadataReceived(
+                @NonNull FastPairAntispoofKeyDeviceMetadata metadata);
+
+        /** Invoked in case of error.
+         *
+         * @hide
+         */
+        @SystemApi
+        void onError(@ErrorCode int code, @Nullable String message);
+    }
+
+    /**
+     * Callback to be invoked when Fast Pair devices of a given account is loaded.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface FastPairAccountDevicesMetadataCallback {
+
+        /**
+         * Should be invoked once the metadatas are loaded.
+         *
+         * @hide
+         */
+        @SystemApi
+        void onFastPairAccountDevicesMetadataReceived(
+                @NonNull Collection<FastPairAccountKeyDeviceMetadata> metadatas);
+        /**
+         * Invoked in case of error.
+         *
+         * @hide
+         */
+        @SystemApi
+        void onError(@ErrorCode int code, @Nullable String message);
+    }
+
+    /**
+     * Callback to be invoked when FastPair eligible accounts are loaded.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface FastPairEligibleAccountsCallback {
+
+        /**
+         * Should be invoked once the eligible accounts are loaded.
+         *
+         * @hide
+         */
+        @SystemApi
+        void onFastPairEligibleAccountsReceived(
+                @NonNull Collection<FastPairEligibleAccount> accounts);
+        /**
+         * Invoked in case of error.
+         *
+         * @hide
+         */
+        @SystemApi
+        void onError(@ErrorCode int code, @Nullable String message);
+    }
+
+    /**
+     * Callback to be invoked when a management action is finished.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface FastPairManageActionCallback {
+
+        /**
+         * Should be invoked once the manage action is successful.
+         *
+         * @hide
+         */
+        @SystemApi
+        void onSuccess();
+        /**
+         * Invoked in case of error.
+         *
+         * @hide
+         */
+        @SystemApi
+        void onError(@ErrorCode int code, @Nullable String message);
+    }
+
+    /**
+     * Fulfills the Fast Pair device metadata request by using callback to send back the
+     * device meta data of a given modelId.
+     *
+     * @hide
+     */
+    @SystemApi
+    public abstract void onLoadFastPairAntispoofKeyDeviceMetadata(
+            @NonNull FastPairAntispoofKeyDeviceMetadataRequest request,
+            @NonNull FastPairAntispoofKeyDeviceMetadataCallback callback);
+
+    /**
+     * Fulfills the account tied Fast Pair devices metadata request by using callback to send back
+     * all Fast Pair device's metadata of a given account.
+     *
+     * @hide
+     */
+    @SystemApi
+    public abstract void onLoadFastPairAccountDevicesMetadata(
+            @NonNull FastPairAccountDevicesMetadataRequest request,
+            @NonNull FastPairAccountDevicesMetadataCallback callback);
+
+    /**
+     * Fulfills the Fast Pair eligible accounts request by using callback to send back Fast Pair
+     * eligible accounts.
+     *
+     * @hide
+     */
+    @SystemApi
+    public abstract void onLoadFastPairEligibleAccounts(
+            @NonNull FastPairEligibleAccountsRequest request,
+            @NonNull FastPairEligibleAccountsCallback callback);
+
+    /**
+     * Fulfills the Fast Pair account management request by using callback to send back result.
+     *
+     * @hide
+     */
+    @SystemApi
+    public abstract void onManageFastPairAccount(
+            @NonNull FastPairManageAccountRequest request,
+            @NonNull FastPairManageActionCallback callback);
+
+    /**
+     * Fulfills the request to manage device-account mapping by using callback to send back result.
+     *
+     * @hide
+     */
+    @SystemApi
+    public abstract void onManageFastPairAccountDevice(
+            @NonNull FastPairManageAccountDeviceRequest request,
+            @NonNull FastPairManageActionCallback callback);
+
+    /**
+     * Class for reading FastPairAntispoofKeyDeviceMetadataRequest, which specifies the model ID of
+     * a Fast Pair device. To fulfill this request, corresponding
+     * {@link FastPairAntispoofKeyDeviceMetadata} should be fetched and returned.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static class FastPairAntispoofKeyDeviceMetadataRequest {
+
+        private final FastPairAntispoofKeyDeviceMetadataRequestParcel mMetadataRequestParcel;
+
+        private FastPairAntispoofKeyDeviceMetadataRequest(
+                final FastPairAntispoofKeyDeviceMetadataRequestParcel metaDataRequestParcel) {
+            this.mMetadataRequestParcel = metaDataRequestParcel;
+        }
+
+        /**
+         * Get modelId (24 bit), the key for FastPairAntispoofKeyDeviceMetadata in the same format
+         * returned by Google at device registration time.
+         *
+         * ModelId format is defined at device registration time, see
+         * <a href="https://developers.google.com/nearby/fast-pair/spec#model_id">Model ID</a>.
+         * @return raw bytes of modelId in the same format returned by Google at device registration
+         *         time.
+         * @hide
+         */
+        @SystemApi
+        public @NonNull byte[] getModelId() {
+            return this.mMetadataRequestParcel.modelId;
+        }
+    }
+
+    /**
+     * Class for reading FastPairAccountDevicesMetadataRequest, which specifies the Fast Pair
+     * account and the allow list of the FastPair device keys saved to the account (i.e., FastPair
+     * accountKeys).
+     *
+     * A Fast Pair accountKey is created when a Fast Pair device is saved to an account. It is per
+     * Fast Pair device per account.
+     *
+     * To retrieve all Fast Pair accountKeys saved to an account, the caller needs to set
+     * account with an empty allow list.
+     *
+     * To retrieve metadata of a selected list of Fast Pair devices saved to an account, the caller
+     * needs to set account with a non-empty allow list.
+     * @hide
+     */
+    @SystemApi
+    public static class FastPairAccountDevicesMetadataRequest {
+
+        private final FastPairAccountDevicesMetadataRequestParcel mMetadataRequestParcel;
+
+        private FastPairAccountDevicesMetadataRequest(
+                final FastPairAccountDevicesMetadataRequestParcel metaDataRequestParcel) {
+            this.mMetadataRequestParcel = metaDataRequestParcel;
+        }
+
+        /**
+         * Get FastPair account, whose Fast Pair devices' metadata is requested.
+         *
+         * @return a FastPair account.
+         * @hide
+         */
+        @SystemApi
+        public @NonNull Account getAccount() {
+            return this.mMetadataRequestParcel.account;
+        }
+
+        /**
+         * Get allowlist of Fast Pair devices using a collection of deviceAccountKeys.
+         * Note that as a special case, empty list actually means all FastPair devices under the
+         * account instead of none.
+         *
+         * DeviceAccountKey is 16 bytes: first byte is 0x04. Other 15 bytes are randomly generated.
+         *
+         * @return allowlist of Fast Pair devices using a collection of deviceAccountKeys.
+         * @hide
+         */
+        @SystemApi
+        public @NonNull Collection<byte[]> getDeviceAccountKeys()  {
+            if (this.mMetadataRequestParcel.deviceAccountKeys == null) {
+                return new ArrayList<byte[]>(0);
+            }
+            List<byte[]> deviceAccountKeys =
+                    new ArrayList<>(this.mMetadataRequestParcel.deviceAccountKeys.length);
+            for (ByteArrayParcel deviceAccountKey : this.mMetadataRequestParcel.deviceAccountKeys) {
+                deviceAccountKeys.add(deviceAccountKey.byteArray);
+            }
+            return deviceAccountKeys;
+        }
+    }
+
+    /**
+     *  Class for reading FastPairEligibleAccountsRequest. Upon receiving this request, Fast Pair
+     *  eligible accounts should be returned to bind Fast Pair devices.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static class FastPairEligibleAccountsRequest {
+        @SuppressWarnings("UnusedVariable")
+        private final FastPairEligibleAccountsRequestParcel mAccountsRequestParcel;
+
+        private FastPairEligibleAccountsRequest(
+                final FastPairEligibleAccountsRequestParcel accountsRequestParcel) {
+            this.mAccountsRequestParcel = accountsRequestParcel;
+        }
+    }
+
+    /**
+     * Class for reading FastPairManageAccountRequest. If the request type is MANAGE_REQUEST_ADD,
+     * the account is enabled to bind Fast Pair devices; If the request type is
+     * MANAGE_REQUEST_REMOVE, the account is disabled to bind more Fast Pair devices. Furthermore,
+     * all existing bounded Fast Pair devices are unbounded.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static class FastPairManageAccountRequest {
+
+        private final FastPairManageAccountRequestParcel mAccountRequestParcel;
+
+        private FastPairManageAccountRequest(
+                final FastPairManageAccountRequestParcel accountRequestParcel) {
+            this.mAccountRequestParcel = accountRequestParcel;
+        }
+
+        /**
+         * Get request type: MANAGE_REQUEST_ADD, or MANAGE_REQUEST_REMOVE.
+         *
+         * @hide
+         */
+        @SystemApi
+        public @ManageRequestType int getRequestType() {
+            return this.mAccountRequestParcel.requestType;
+        }
+        /**
+         * Get account.
+         *
+         * @hide
+         */
+        @SystemApi
+        public @NonNull Account getAccount() {
+            return this.mAccountRequestParcel.account;
+        }
+    }
+
+    /**
+     *  Class for reading FastPairManageAccountDeviceRequest. If the request type is
+     *  MANAGE_REQUEST_ADD, then a Fast Pair device is bounded to a Fast Pair account. If the
+     *  request type is MANAGE_REQUEST_REMOVE, then a Fast Pair device is removed from a Fast Pair
+     *  account.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static class FastPairManageAccountDeviceRequest {
+
+        private final FastPairManageAccountDeviceRequestParcel mRequestParcel;
+
+        private FastPairManageAccountDeviceRequest(
+                final FastPairManageAccountDeviceRequestParcel requestParcel) {
+            this.mRequestParcel = requestParcel;
+        }
+
+        /**
+         * Get request type: MANAGE_REQUEST_ADD, or MANAGE_REQUEST_REMOVE.
+         *
+         * @hide
+         */
+        @SystemApi
+        public @ManageRequestType int getRequestType() {
+            return this.mRequestParcel.requestType;
+        }
+        /**
+         * Get account.
+         *
+         * @hide
+         */
+        @SystemApi
+        public @NonNull Account getAccount() {
+            return this.mRequestParcel.account;
+        }
+        /**
+         * Get BleAddress.
+         *
+         * @hide
+         */
+        @SystemApi
+        public @Nullable String getBleAddress() {
+            return this.mRequestParcel.bleAddress;
+        }
+        /**
+         * Get account key device metadata.
+         *
+         * @hide
+         */
+        @SystemApi
+        public @NonNull FastPairAccountKeyDeviceMetadata getAccountKeyDeviceMetadata() {
+            return new FastPairAccountKeyDeviceMetadata(
+                    this.mRequestParcel.accountKeyDeviceMetadata);
+        }
+    }
+
+    /**
+     * Callback class that sends back FastPairAntispoofKeyDeviceMetadata.
+     */
+    private final class WrapperFastPairAntispoofKeyDeviceMetadataCallback implements
+            FastPairAntispoofKeyDeviceMetadataCallback {
+
+        private IFastPairAntispoofKeyDeviceMetadataCallback mCallback;
+
+        private WrapperFastPairAntispoofKeyDeviceMetadataCallback(
+                IFastPairAntispoofKeyDeviceMetadataCallback callback) {
+            mCallback = callback;
+        }
+
+        /**
+         * Sends back FastPairAntispoofKeyDeviceMetadata.
+         */
+        @Override
+        public void onFastPairAntispoofKeyDeviceMetadataReceived(
+                @NonNull FastPairAntispoofKeyDeviceMetadata metadata) {
+            try {
+                mCallback.onFastPairAntispoofKeyDeviceMetadataReceived(metadata.mMetadataParcel);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+
+        @Override
+        public void onError(@ErrorCode int code, @Nullable String message) {
+            try {
+                mCallback.onError(code, message);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+    }
+
+    /**
+     * Callback class that sends back collection of FastPairAccountKeyDeviceMetadata.
+     */
+    private final class WrapperFastPairAccountDevicesMetadataCallback implements
+            FastPairAccountDevicesMetadataCallback {
+
+        private IFastPairAccountDevicesMetadataCallback mCallback;
+
+        private WrapperFastPairAccountDevicesMetadataCallback(
+                IFastPairAccountDevicesMetadataCallback callback) {
+            mCallback = callback;
+        }
+
+        /**
+         * Sends back collection of FastPairAccountKeyDeviceMetadata.
+         */
+        @Override
+        public void onFastPairAccountDevicesMetadataReceived(
+                @NonNull Collection<FastPairAccountKeyDeviceMetadata> metadatas) {
+            FastPairAccountKeyDeviceMetadataParcel[] metadataParcels =
+                    new FastPairAccountKeyDeviceMetadataParcel[metadatas.size()];
+            int i = 0;
+            for (FastPairAccountKeyDeviceMetadata metadata : metadatas) {
+                metadataParcels[i] = metadata.mMetadataParcel;
+                i = i + 1;
+            }
+            try {
+                mCallback.onFastPairAccountDevicesMetadataReceived(metadataParcels);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+
+        @Override
+        public void onError(@ErrorCode int code, @Nullable String message) {
+            try {
+                mCallback.onError(code, message);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+    }
+
+    /**
+     * Callback class that sends back eligible Fast Pair accounts.
+     */
+    private final class WrapperFastPairEligibleAccountsCallback implements
+            FastPairEligibleAccountsCallback {
+
+        private IFastPairEligibleAccountsCallback mCallback;
+
+        private WrapperFastPairEligibleAccountsCallback(
+                IFastPairEligibleAccountsCallback callback) {
+            mCallback = callback;
+        }
+
+        /**
+         * Sends back the eligible Fast Pair accounts.
+         */
+        @Override
+        public void onFastPairEligibleAccountsReceived(
+                @NonNull Collection<FastPairEligibleAccount> accounts) {
+            int i = 0;
+            FastPairEligibleAccountParcel[] accountParcels =
+                    new FastPairEligibleAccountParcel[accounts.size()];
+            for (FastPairEligibleAccount account: accounts) {
+                accountParcels[i] = account.mAccountParcel;
+                i = i + 1;
+            }
+            try {
+                mCallback.onFastPairEligibleAccountsReceived(accountParcels);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+
+        @Override
+        public void onError(@ErrorCode int code, @Nullable String message) {
+            try {
+                mCallback.onError(code, message);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+    }
+
+    /**
+     * Callback class that sends back Fast Pair account management result.
+     */
+    private final class WrapperFastPairManageAccountCallback implements
+            FastPairManageActionCallback {
+
+        private IFastPairManageAccountCallback mCallback;
+
+        private WrapperFastPairManageAccountCallback(
+                IFastPairManageAccountCallback callback) {
+            mCallback = callback;
+        }
+
+        /**
+         * Sends back Fast Pair account opt in result.
+         */
+        @Override
+        public void onSuccess() {
+            try {
+                mCallback.onSuccess();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+
+        @Override
+        public void onError(@ErrorCode int code, @Nullable String message) {
+            try {
+                mCallback.onError(code, message);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+    }
+
+    /**
+     * Call back class that sends back account-device mapping management result.
+     */
+    private final class WrapperFastPairManageAccountDeviceCallback implements
+            FastPairManageActionCallback {
+
+        private IFastPairManageAccountDeviceCallback mCallback;
+
+        private WrapperFastPairManageAccountDeviceCallback(
+                IFastPairManageAccountDeviceCallback callback) {
+            mCallback = callback;
+        }
+
+        /**
+         * Sends back the account-device mapping management result.
+         */
+        @Override
+        public void onSuccess() {
+            try {
+                mCallback.onSuccess();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+
+        @Override
+        public void onError(@ErrorCode int code, @Nullable String message) {
+            try {
+                mCallback.onError(code, message);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } catch (RuntimeException e) {
+                Log.w(mTag, e);
+            }
+        }
+    }
+
+    private final class Service extends IFastPairDataProvider.Stub {
+
+        Service() {
+        }
+
+        @Override
+        public void loadFastPairAntispoofKeyDeviceMetadata(
+                @NonNull FastPairAntispoofKeyDeviceMetadataRequestParcel requestParcel,
+                IFastPairAntispoofKeyDeviceMetadataCallback callback) {
+            onLoadFastPairAntispoofKeyDeviceMetadata(
+                    new FastPairAntispoofKeyDeviceMetadataRequest(requestParcel),
+                    new WrapperFastPairAntispoofKeyDeviceMetadataCallback(callback));
+        }
+
+        @Override
+        public void loadFastPairAccountDevicesMetadata(
+                @NonNull FastPairAccountDevicesMetadataRequestParcel requestParcel,
+                IFastPairAccountDevicesMetadataCallback callback) {
+            onLoadFastPairAccountDevicesMetadata(
+                    new FastPairAccountDevicesMetadataRequest(requestParcel),
+                    new WrapperFastPairAccountDevicesMetadataCallback(callback));
+        }
+
+        @Override
+        public void loadFastPairEligibleAccounts(
+                @NonNull FastPairEligibleAccountsRequestParcel requestParcel,
+                IFastPairEligibleAccountsCallback callback) {
+            onLoadFastPairEligibleAccounts(new FastPairEligibleAccountsRequest(requestParcel),
+                    new WrapperFastPairEligibleAccountsCallback(callback));
+        }
+
+        @Override
+        public void manageFastPairAccount(
+                @NonNull FastPairManageAccountRequestParcel requestParcel,
+                IFastPairManageAccountCallback callback) {
+            onManageFastPairAccount(new FastPairManageAccountRequest(requestParcel),
+                    new WrapperFastPairManageAccountCallback(callback));
+        }
+
+        @Override
+        public void manageFastPairAccountDevice(
+                @NonNull FastPairManageAccountDeviceRequestParcel requestParcel,
+                IFastPairManageAccountDeviceCallback callback) {
+            onManageFastPairAccountDevice(new FastPairManageAccountDeviceRequest(requestParcel),
+                    new WrapperFastPairManageAccountDeviceCallback(callback));
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/FastPairDevice.aidl b/nearby/framework/java/android/nearby/FastPairDevice.aidl
new file mode 100644
index 0000000..5942966
--- /dev/null
+++ b/nearby/framework/java/android/nearby/FastPairDevice.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+/**
+ * A class represents a Fast Pair device that can be discovered by multiple mediums.
+ *
+ * {@hide}
+ */
+parcelable FastPairDevice;
diff --git a/nearby/framework/java/android/nearby/FastPairDevice.java b/nearby/framework/java/android/nearby/FastPairDevice.java
new file mode 100644
index 0000000..7160533
--- /dev/null
+++ b/nearby/framework/java/android/nearby/FastPairDevice.java
@@ -0,0 +1,332 @@
+/*
+ * 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 android.nearby;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A class represents a Fast Pair device that can be discovered by multiple mediums.
+ *
+ * @hide
+ */
+public class FastPairDevice extends NearbyDevice implements Parcelable {
+    /**
+     * Used to read a FastPairDevice from a Parcel.
+     */
+    public static final Creator<FastPairDevice> CREATOR = new Creator<FastPairDevice>() {
+        @Override
+        public FastPairDevice createFromParcel(Parcel in) {
+            FastPairDevice.Builder builder = new FastPairDevice.Builder();
+            if (in.readInt() == 1) {
+                builder.setName(in.readString());
+            }
+            int size = in.readInt();
+            for (int i = 0; i < size; i++) {
+                builder.addMedium(in.readInt());
+            }
+            builder.setRssi(in.readInt());
+            builder.setTxPower(in.readInt());
+            if (in.readInt() == 1) {
+                builder.setModelId(in.readString());
+            }
+            builder.setBluetoothAddress(in.readString());
+            if (in.readInt() == 1) {
+                int dataLength = in.readInt();
+                byte[] data = new byte[dataLength];
+                in.readByteArray(data);
+                builder.setData(data);
+            }
+            return builder.build();
+        }
+
+        @Override
+        public FastPairDevice[] newArray(int size) {
+            return new FastPairDevice[size];
+        }
+    };
+
+    // The transmit power in dBm. Valid range is [-127, 126]. a
+    // See android.bluetooth.le.ScanResult#getTxPower
+    private int mTxPower;
+
+    // Some OEM devices devices don't have model Id.
+    @Nullable private final String mModelId;
+
+    // Bluetooth hardware address as string. Can be read from BLE ScanResult.
+    private final String mBluetoothAddress;
+
+    @Nullable
+    private final byte[] mData;
+
+    /**
+     * Creates a new FastPairDevice.
+     *
+     * @param name Name of the FastPairDevice. Can be {@code null} if there is no name.
+     * @param mediums The {@link Medium}s over which the device is discovered.
+     * @param rssi The received signal strength in dBm.
+     * @param txPower The transmit power in dBm. Valid range is [-127, 126].
+     * @param modelId The identifier of the Fast Pair device.
+     *                Can be {@code null} if there is no Model ID.
+     * @param bluetoothAddress The hardware address of this BluetoothDevice.
+     * @param data Extra data for a Fast Pair device.
+     */
+    public FastPairDevice(@Nullable String name,
+            List<Integer> mediums,
+            int rssi,
+            int txPower,
+            @Nullable String modelId,
+            @NonNull String bluetoothAddress,
+            @Nullable byte[] data) {
+        super(name, mediums, rssi);
+        this.mTxPower = txPower;
+        this.mModelId = modelId;
+        this.mBluetoothAddress = bluetoothAddress;
+        this.mData = data;
+    }
+
+    /**
+     * Gets the transmit power in dBm. A value of
+     * android.bluetooth.le.ScanResult#TX_POWER_NOT_PRESENT
+     * indicates that the TX power is not present.
+     */
+    @IntRange(from = -127, to = 126)
+    public int getTxPower() {
+        return mTxPower;
+    }
+
+    /**
+     * Gets the identifier of the Fast Pair device. Can be {@code null} if there is no Model ID.
+     */
+    @Nullable
+    public String getModelId() {
+        return this.mModelId;
+    }
+
+    /**
+     * Gets the hardware address of this BluetoothDevice.
+     */
+    @NonNull
+    public String getBluetoothAddress() {
+        return mBluetoothAddress;
+    }
+
+    /**
+     * Gets the extra data for a Fast Pair device. Can be {@code null} if there is extra data.
+     *
+     * @hide
+     */
+    @Nullable
+    public byte[] getData() {
+        return mData;
+    }
+
+    /**
+     * No special parcel contents.
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Returns a string representation of this FastPairDevice.
+     */
+    @Override
+    public String toString() {
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("FastPairDevice [");
+        String name = getName();
+        if (getName() != null && !name.isEmpty()) {
+            stringBuilder.append("name=").append(name).append(", ");
+        }
+        stringBuilder.append("medium={");
+        for (int medium: getMediums()) {
+            stringBuilder.append(mediumToString(medium));
+        }
+        stringBuilder.append("} rssi=").append(getRssi());
+        stringBuilder.append(" txPower=").append(mTxPower);
+        stringBuilder.append(" modelId=").append(mModelId);
+        stringBuilder.append(" bluetoothAddress=").append(mBluetoothAddress);
+        stringBuilder.append("]");
+        return stringBuilder.toString();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof FastPairDevice) {
+            FastPairDevice otherDevice = (FastPairDevice) other;
+            if (!super.equals(other)) {
+                return false;
+            }
+            return  mTxPower == otherDevice.mTxPower
+                    && Objects.equals(mModelId, otherDevice.mModelId)
+                    && Objects.equals(mBluetoothAddress, otherDevice.mBluetoothAddress)
+                    && Arrays.equals(mData, otherDevice.mData);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                getName(), getMediums(), getRssi(), mTxPower, mModelId, mBluetoothAddress,
+                Arrays.hashCode(mData));
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        String name = getName();
+        dest.writeInt(name == null ? 0 : 1);
+        if (name != null) {
+            dest.writeString(name);
+        }
+        List<Integer> mediums = getMediums();
+        dest.writeInt(mediums.size());
+        for (int medium : mediums) {
+            dest.writeInt(medium);
+        }
+        dest.writeInt(getRssi());
+        dest.writeInt(mTxPower);
+        dest.writeInt(mModelId == null ? 0 : 1);
+        if (mModelId != null) {
+            dest.writeString(mModelId);
+        }
+        dest.writeString(mBluetoothAddress);
+        dest.writeInt(mData == null ? 0 : 1);
+        if (mData != null) {
+            dest.writeInt(mData.length);
+            dest.writeByteArray(mData);
+        }
+    }
+
+    /**
+     * A builder class for {@link FastPairDevice}
+     *
+     * @hide
+     */
+    public static final class Builder {
+        private final List<Integer> mMediums;
+
+        @Nullable private String mName;
+        private int mRssi;
+        private int mTxPower;
+        @Nullable private String mModelId;
+        private String mBluetoothAddress;
+        @Nullable private byte[] mData;
+
+        public Builder() {
+            mMediums = new ArrayList<>();
+        }
+
+        /**
+         * Sets the name of the Fast Pair device.
+         *
+         * @param name Name of the FastPairDevice. Can be {@code null} if there is no name.
+         */
+        @NonNull
+        public Builder setName(@Nullable String name) {
+            mName = name;
+            return this;
+        }
+
+        /**
+         * Sets the medium over which the Fast Pair device is discovered.
+         *
+         * @param medium The {@link Medium} over which the device is discovered.
+         */
+        @NonNull
+        public Builder addMedium(@Medium int medium) {
+            mMediums.add(medium);
+            return this;
+        }
+
+        /**
+         * Sets the RSSI between the scan device and the discovered Fast Pair device.
+         *
+         * @param rssi The received signal strength in dBm.
+         */
+        @NonNull
+        public Builder setRssi(@IntRange(from = -127, to = 126) int rssi) {
+            mRssi = rssi;
+            return this;
+        }
+
+        /**
+         * Sets the txPower.
+         *
+         * @param txPower The transmit power in dBm
+         */
+        @NonNull
+        public Builder setTxPower(@IntRange(from = -127, to = 126) int txPower) {
+            mTxPower = txPower;
+            return this;
+        }
+
+        /**
+         * Sets the model Id of this Fast Pair device.
+         *
+         * @param modelId The identifier of the Fast Pair device. Can be {@code null}
+         *                if there is no Model ID.
+         */
+        @NonNull
+        public Builder setModelId(@Nullable String modelId) {
+            mModelId = modelId;
+            return this;
+        }
+
+        /**
+         * Sets the hardware address of this BluetoothDevice.
+         *
+         * @param bluetoothAddress The hardware address of this BluetoothDevice.
+         */
+        @NonNull
+        public Builder setBluetoothAddress(@NonNull String bluetoothAddress) {
+            Objects.requireNonNull(bluetoothAddress);
+            mBluetoothAddress = bluetoothAddress;
+            return this;
+        }
+
+        /**
+         * Sets the raw data for a FastPairDevice. Can be {@code null} if there is no extra data.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setData(@Nullable byte[] data) {
+            mData = data;
+            return this;
+        }
+
+        /**
+         * Builds a FastPairDevice and return it.
+         */
+        @NonNull
+        public FastPairDevice build() {
+            return new FastPairDevice(mName, mMediums, mRssi, mTxPower, mModelId,
+                    mBluetoothAddress, mData);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/FastPairDeviceMetadata.java b/nearby/framework/java/android/nearby/FastPairDeviceMetadata.java
new file mode 100644
index 0000000..ea75271
--- /dev/null
+++ b/nearby/framework/java/android/nearby/FastPairDeviceMetadata.java
@@ -0,0 +1,1009 @@
+/*
+ * 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 android.nearby;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.nearby.aidl.FastPairDeviceMetadataParcel;
+
+/**
+ * Class for the properties of a given type of Fast Pair device, including images and text.
+ *
+ * @hide
+ */
+@SystemApi
+public class FastPairDeviceMetadata {
+
+    FastPairDeviceMetadataParcel mMetadataParcel;
+
+    FastPairDeviceMetadata(
+            FastPairDeviceMetadataParcel metadataParcel) {
+        this.mMetadataParcel = metadataParcel;
+    }
+
+    /**
+     * Get ImageUrl, which will be displayed in notification.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getImageUrl() {
+        return mMetadataParcel.imageUrl;
+    }
+
+    /**
+     * Get IntentUri, which will be launched to install companion app.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getIntentUri() {
+        return mMetadataParcel.intentUri;
+    }
+
+    /**
+     * Get BLE transmit power, as described in Fast Pair spec, see
+     * <a href="https://developers.google.com/nearby/fast-pair/spec#transmit_power">Transmit Power</a>
+     *
+     * @hide
+     */
+    @SystemApi
+    public int getBleTxPower() {
+        return mMetadataParcel.bleTxPower;
+    }
+
+    /**
+     * Get Fast Pair Half Sheet trigger distance in meters.
+     *
+     * @hide
+     */
+    @SystemApi
+    public float getTriggerDistance() {
+        return mMetadataParcel.triggerDistance;
+    }
+
+    /**
+     * Get Fast Pair device image, which is submitted at device registration time to display on
+     * notification. It is a 32-bit PNG with dimensions of 512px by 512px.
+     *
+     * @return Fast Pair device image in 32-bit PNG with dimensions of 512px by 512px.
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public byte[] getImage() {
+        return mMetadataParcel.image;
+    }
+
+    /**
+     * Get Fast Pair device type.
+     * DEVICE_TYPE_UNSPECIFIED = 0;
+     * HEADPHONES = 1;
+     * TRUE_WIRELESS_HEADPHONES = 7;
+     * @hide
+     */
+    @SystemApi
+    public int getDeviceType() {
+        return mMetadataParcel.deviceType;
+    }
+
+    /**
+     * Get Fast Pair device name. e.g., "Pixel Buds A-Series".
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getName() {
+        return mMetadataParcel.name;
+    }
+
+    /**
+     * Get true wireless image url for left bud.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getTrueWirelessImageUrlLeftBud() {
+        return mMetadataParcel.trueWirelessImageUrlLeftBud;
+    }
+
+    /**
+     * Get true wireless image url for right bud.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getTrueWirelessImageUrlRightBud() {
+        return mMetadataParcel.trueWirelessImageUrlRightBud;
+    }
+
+    /**
+     * Get true wireless image url for case.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getTrueWirelessImageUrlCase() {
+        return mMetadataParcel.trueWirelessImageUrlCase;
+    }
+
+    /**
+     * Get Locale of the device.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getLocale() {
+        return mMetadataParcel.locale;
+    }
+
+    /**
+     * Get InitialNotificationDescription, which is a translated string of
+     * "Tap to pair. Earbuds will be tied to %s" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getInitialNotificationDescription() {
+        return mMetadataParcel.initialNotificationDescription;
+    }
+
+    /**
+     * Get InitialNotificationDescriptionNoAccount, which is a translated string of
+     * "Tap to pair with this device" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getInitialNotificationDescriptionNoAccount() {
+        return mMetadataParcel.initialNotificationDescriptionNoAccount;
+    }
+
+    /**
+     * Get OpenCompanionAppDescription, which is a translated string of
+     * "Tap to finish setup" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getOpenCompanionAppDescription() {
+        return mMetadataParcel.openCompanionAppDescription;
+    }
+
+    /**
+     * Get UpdateCompanionAppDescription, which is a translated string of
+     * "Tap to update device settings and finish setup" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getUpdateCompanionAppDescription() {
+        return mMetadataParcel.updateCompanionAppDescription;
+    }
+
+    /**
+     * Get DownloadCompanionAppDescription, which is a translated string of
+     * "Tap to download device app on Google Play and see all features" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getDownloadCompanionAppDescription() {
+        return mMetadataParcel.downloadCompanionAppDescription;
+    }
+
+    /**
+     * Get UnableToConnectTitle, which is a translated string of
+     * "Unable to connect" based on locale.
+     */
+    @Nullable
+    public String getUnableToConnectTitle() {
+        return mMetadataParcel.unableToConnectTitle;
+    }
+
+    /**
+     * Get UnableToConnectDescription, which is a translated string of
+     * "Try manually pairing to the device" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getUnableToConnectDescription() {
+        return mMetadataParcel.unableToConnectDescription;
+    }
+
+    /**
+     * Get InitialPairingDescription, which is a translated string of
+     * "%s will appear on devices linked with %s" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getInitialPairingDescription() {
+        return mMetadataParcel.initialPairingDescription;
+    }
+
+    /**
+     * Get ConnectSuccessCompanionAppInstalled, which is a translated string of
+     * "Your device is ready to be set up" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getConnectSuccessCompanionAppInstalled() {
+        return mMetadataParcel.connectSuccessCompanionAppInstalled;
+    }
+
+    /**
+     * Get ConnectSuccessCompanionAppNotInstalled, which is a translated string of
+     * "Download the device app on Google Play to see all available features" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getConnectSuccessCompanionAppNotInstalled() {
+        return mMetadataParcel.connectSuccessCompanionAppNotInstalled;
+    }
+
+    /**
+     * Get SubsequentPairingDescription, which is a translated string of
+     * "Connect %s to this phone" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getSubsequentPairingDescription() {
+        return mMetadataParcel.subsequentPairingDescription;
+    }
+
+    /**
+     * Get RetroactivePairingDescription, which is a translated string of
+     * "Save device to %s for faster pairing to your other devices" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getRetroactivePairingDescription() {
+        return mMetadataParcel.retroactivePairingDescription;
+    }
+
+    /**
+     * Get WaitLaunchCompanionAppDescription, which is a translated string of
+     * "This will take a few moments" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getWaitLaunchCompanionAppDescription() {
+        return mMetadataParcel.waitLaunchCompanionAppDescription;
+    }
+
+    /**
+     * Get FailConnectGoToSettingsDescription, which is a translated string of
+     * "Try manually pairing to the device by going to Settings" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getFailConnectGoToSettingsDescription() {
+        return mMetadataParcel.failConnectGoToSettingsDescription;
+    }
+
+    /**
+     * Get ConfirmPinTitle, which is a translated string of
+     * based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getConfirmPinTitle() {
+        return mMetadataParcel.confirmPinTitle;
+    }
+
+    /**
+     * Get ConfirmPinDescription, which is a translated string of "confirm pin" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getConfirmPinDescription() {
+        return mMetadataParcel.confirmPinDescription;
+    }
+
+    /**
+     * Get SyncContactsTitle, which is a translated string of "sync contacts title" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getSyncContactsTitle() {
+        return mMetadataParcel.syncContactsTitle;
+    }
+
+    /**
+     * Get SyncContactsDescription, which is a translated string of "sync contacts description"
+     * based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getSyncContactsDescription() {
+        return mMetadataParcel.syncContactsDescription;
+    }
+
+    /**
+     * Get SyncSmsTitle, which is a translated string of "sync sms title" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getSyncSmsTitle() {
+        return mMetadataParcel.syncSmsTitle;
+    }
+
+    /**
+     * Get SyncSmsDescription, which is a translated string of "sync sms description" based on
+     * locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getSyncSmsDescription() {
+        return mMetadataParcel.syncSmsDescription;
+    }
+
+    /**
+     * Get AssistantSetupHalfSheet, which is a translated string of
+     * "Tap to set up your Google Assistant" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getAssistantSetupHalfSheet() {
+        return mMetadataParcel.assistantSetupHalfSheet;
+    }
+
+    /**
+     * Get AssistantSetupNotification, which is a translated string of
+     * "Tap to set up your Google Assistant" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getAssistantSetupNotification() {
+        return mMetadataParcel.assistantSetupNotification;
+    }
+
+    /**
+     * Get FastPairTvConnectDeviceNoAccountDescription, which is a translated string of
+     * "Select connect to pair your %s with this device" based on locale.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getFastPairTvConnectDeviceNoAccountDescription() {
+        return mMetadataParcel.fastPairTvConnectDeviceNoAccountDescription;
+    }
+
+    /**
+     * Builder used to create FastPairDeviceMetadata.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder {
+
+        private final FastPairDeviceMetadataParcel mBuilderParcel;
+
+        /**
+         * Default constructor of Builder.
+         *
+         * @hide
+         */
+        @SystemApi
+        public Builder() {
+            mBuilderParcel = new FastPairDeviceMetadataParcel();
+            mBuilderParcel.imageUrl = null;
+            mBuilderParcel.intentUri = null;
+            mBuilderParcel.name = null;
+            mBuilderParcel.bleTxPower = 0;
+            mBuilderParcel.triggerDistance = 0;
+            mBuilderParcel.image = null;
+            mBuilderParcel.deviceType = 0;  // DEVICE_TYPE_UNSPECIFIED
+            mBuilderParcel.trueWirelessImageUrlLeftBud = null;
+            mBuilderParcel.trueWirelessImageUrlRightBud = null;
+            mBuilderParcel.trueWirelessImageUrlCase = null;
+            mBuilderParcel.locale = null;
+            mBuilderParcel.initialNotificationDescription = null;
+            mBuilderParcel.initialNotificationDescriptionNoAccount = null;
+            mBuilderParcel.openCompanionAppDescription = null;
+            mBuilderParcel.updateCompanionAppDescription = null;
+            mBuilderParcel.downloadCompanionAppDescription = null;
+            mBuilderParcel.unableToConnectTitle = null;
+            mBuilderParcel.unableToConnectDescription = null;
+            mBuilderParcel.initialPairingDescription = null;
+            mBuilderParcel.connectSuccessCompanionAppInstalled = null;
+            mBuilderParcel.connectSuccessCompanionAppNotInstalled = null;
+            mBuilderParcel.subsequentPairingDescription = null;
+            mBuilderParcel.retroactivePairingDescription = null;
+            mBuilderParcel.waitLaunchCompanionAppDescription = null;
+            mBuilderParcel.failConnectGoToSettingsDescription = null;
+            mBuilderParcel.confirmPinTitle = null;
+            mBuilderParcel.confirmPinDescription = null;
+            mBuilderParcel.syncContactsTitle = null;
+            mBuilderParcel.syncContactsDescription = null;
+            mBuilderParcel.syncSmsTitle = null;
+            mBuilderParcel.syncSmsDescription = null;
+            mBuilderParcel.assistantSetupHalfSheet = null;
+            mBuilderParcel.assistantSetupNotification = null;
+            mBuilderParcel.fastPairTvConnectDeviceNoAccountDescription = null;
+        }
+
+        /**
+         * Set ImageUlr.
+         *
+         * @param imageUrl Image Ulr.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setImageUrl(@Nullable String imageUrl) {
+            mBuilderParcel.imageUrl = imageUrl;
+            return this;
+        }
+
+        /**
+         * Set IntentUri.
+         *
+         * @param intentUri Intent uri.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setIntentUri(@Nullable String intentUri) {
+            mBuilderParcel.intentUri = intentUri;
+            return this;
+        }
+
+        /**
+         * Set device name.
+         *
+         * @param name Device name.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setName(@Nullable String name) {
+            mBuilderParcel.name = name;
+            return this;
+        }
+
+        /**
+         * Set ble transmission power.
+         *
+         * @param bleTxPower Ble transmission power.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setBleTxPower(int bleTxPower) {
+            mBuilderParcel.bleTxPower = bleTxPower;
+            return this;
+        }
+
+        /**
+         * Set trigger distance.
+         *
+         * @param triggerDistance Fast Pair trigger distance.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setTriggerDistance(float triggerDistance) {
+            mBuilderParcel.triggerDistance = triggerDistance;
+            return this;
+        }
+
+        /**
+         * Set image.
+         *
+         * @param image Fast Pair device image, which is submitted at device registration time to
+         *              display on notification. It is a 32-bit PNG with dimensions of
+         *              512px by 512px.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setImage(@Nullable byte[] image) {
+            mBuilderParcel.image = image;
+            return this;
+        }
+
+        /**
+         * Set device type.
+         *
+         * @param deviceType Fast Pair device type.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setDeviceType(int deviceType) {
+            mBuilderParcel.deviceType = deviceType;
+            return this;
+        }
+
+        /**
+         * Set true wireless image url for left bud.
+         *
+         * @param trueWirelessImageUrlLeftBud True wireless image url for left bud.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setTrueWirelessImageUrlLeftBud(
+                @Nullable String trueWirelessImageUrlLeftBud) {
+            mBuilderParcel.trueWirelessImageUrlLeftBud = trueWirelessImageUrlLeftBud;
+            return this;
+        }
+
+        /**
+         * Set true wireless image url for right bud.
+         *
+         * @param trueWirelessImageUrlRightBud True wireless image url for right bud.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setTrueWirelessImageUrlRightBud(
+                @Nullable String trueWirelessImageUrlRightBud) {
+            mBuilderParcel.trueWirelessImageUrlRightBud = trueWirelessImageUrlRightBud;
+            return this;
+        }
+
+        /**
+         * Set true wireless image url for case.
+         *
+         * @param trueWirelessImageUrlCase True wireless image url for case.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setTrueWirelessImageUrlCase(@Nullable String trueWirelessImageUrlCase) {
+            mBuilderParcel.trueWirelessImageUrlCase = trueWirelessImageUrlCase;
+            return this;
+        }
+
+        /**
+         * Set Locale.
+         *
+         * @param locale Device locale.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setLocale(@Nullable String locale) {
+            mBuilderParcel.locale = locale;
+            return this;
+        }
+
+        /**
+         * Set InitialNotificationDescription.
+         *
+         * @param initialNotificationDescription Initial notification description.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setInitialNotificationDescription(
+                @Nullable String initialNotificationDescription) {
+            mBuilderParcel.initialNotificationDescription = initialNotificationDescription;
+            return this;
+        }
+
+        /**
+         * Set InitialNotificationDescriptionNoAccount.
+         *
+         * @param initialNotificationDescriptionNoAccount Initial notification description when
+         *                                                account is not present.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setInitialNotificationDescriptionNoAccount(
+                @Nullable String initialNotificationDescriptionNoAccount) {
+            mBuilderParcel.initialNotificationDescriptionNoAccount =
+                    initialNotificationDescriptionNoAccount;
+            return this;
+        }
+
+        /**
+         * Set OpenCompanionAppDescription.
+         *
+         * @param openCompanionAppDescription Description for opening companion app.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setOpenCompanionAppDescription(
+                @Nullable String openCompanionAppDescription) {
+            mBuilderParcel.openCompanionAppDescription = openCompanionAppDescription;
+            return this;
+        }
+
+        /**
+         * Set UpdateCompanionAppDescription.
+         *
+         * @param updateCompanionAppDescription Description for updating companion app.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setUpdateCompanionAppDescription(
+                @Nullable String updateCompanionAppDescription) {
+            mBuilderParcel.updateCompanionAppDescription = updateCompanionAppDescription;
+            return this;
+        }
+
+        /**
+         * Set DownloadCompanionAppDescription.
+         *
+         * @param downloadCompanionAppDescription Description for downloading companion app.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setDownloadCompanionAppDescription(
+                @Nullable String downloadCompanionAppDescription) {
+            mBuilderParcel.downloadCompanionAppDescription = downloadCompanionAppDescription;
+            return this;
+        }
+
+        /**
+         * Set UnableToConnectTitle.
+         *
+         * @param unableToConnectTitle Title when Fast Pair device is unable to be connected to.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setUnableToConnectTitle(@Nullable String unableToConnectTitle) {
+            mBuilderParcel.unableToConnectTitle = unableToConnectTitle;
+            return this;
+        }
+
+        /**
+         * Set UnableToConnectDescription.
+         *
+         * @param unableToConnectDescription Description when Fast Pair device is unable to be
+         *                                   connected to.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setUnableToConnectDescription(
+                @Nullable String unableToConnectDescription) {
+            mBuilderParcel.unableToConnectDescription = unableToConnectDescription;
+            return this;
+        }
+
+        /**
+         * Set InitialPairingDescription.
+         *
+         * @param initialPairingDescription Description for Fast Pair initial pairing.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setInitialPairingDescription(@Nullable String initialPairingDescription) {
+            mBuilderParcel.initialPairingDescription = initialPairingDescription;
+            return this;
+        }
+
+        /**
+         * Set ConnectSuccessCompanionAppInstalled.
+         *
+         * @param connectSuccessCompanionAppInstalled Description that let user open the companion
+         *                                            app.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setConnectSuccessCompanionAppInstalled(
+                @Nullable String connectSuccessCompanionAppInstalled) {
+            mBuilderParcel.connectSuccessCompanionAppInstalled =
+                    connectSuccessCompanionAppInstalled;
+            return this;
+        }
+
+        /**
+         * Set ConnectSuccessCompanionAppNotInstalled.
+         *
+         * @param connectSuccessCompanionAppNotInstalled Description that let user download the
+         *                                               companion app.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setConnectSuccessCompanionAppNotInstalled(
+                @Nullable String connectSuccessCompanionAppNotInstalled) {
+            mBuilderParcel.connectSuccessCompanionAppNotInstalled =
+                    connectSuccessCompanionAppNotInstalled;
+            return this;
+        }
+
+        /**
+         * Set SubsequentPairingDescription.
+         *
+         * @param subsequentPairingDescription Description that reminds user there is a paired
+         *                                     device nearby.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setSubsequentPairingDescription(
+                @Nullable String subsequentPairingDescription) {
+            mBuilderParcel.subsequentPairingDescription = subsequentPairingDescription;
+            return this;
+        }
+
+        /**
+         * Set RetroactivePairingDescription.
+         *
+         * @param retroactivePairingDescription Description that reminds users opt in their device.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setRetroactivePairingDescription(
+                @Nullable String retroactivePairingDescription) {
+            mBuilderParcel.retroactivePairingDescription = retroactivePairingDescription;
+            return this;
+        }
+
+        /**
+         * Set WaitLaunchCompanionAppDescription.
+         *
+         * @param waitLaunchCompanionAppDescription Description that indicates companion app is
+         *                                          about to launch.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setWaitLaunchCompanionAppDescription(
+                @Nullable String waitLaunchCompanionAppDescription) {
+            mBuilderParcel.waitLaunchCompanionAppDescription =
+                    waitLaunchCompanionAppDescription;
+            return this;
+        }
+
+        /**
+         * Set FailConnectGoToSettingsDescription.
+         *
+         * @param failConnectGoToSettingsDescription Description that indicates go to bluetooth
+         *                                           settings when connection fail.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setFailConnectGoToSettingsDescription(
+                @Nullable String failConnectGoToSettingsDescription) {
+            mBuilderParcel.failConnectGoToSettingsDescription =
+                    failConnectGoToSettingsDescription;
+            return this;
+        }
+
+        /**
+         * Set ConfirmPinTitle.
+         *
+         * @param confirmPinTitle Title of the UI to ask the user to confirm the pin code.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setConfirmPinTitle(@Nullable String confirmPinTitle) {
+            mBuilderParcel.confirmPinTitle = confirmPinTitle;
+            return this;
+        }
+
+        /**
+         * Set ConfirmPinDescription.
+         *
+         * @param confirmPinDescription Description of the UI to ask the user to confirm the pin
+         *                              code.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setConfirmPinDescription(@Nullable String confirmPinDescription) {
+            mBuilderParcel.confirmPinDescription = confirmPinDescription;
+            return this;
+        }
+
+        /**
+         * Set SyncContactsTitle.
+         *
+         * @param syncContactsTitle Title of the UI to ask the user to confirm to sync contacts.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setSyncContactsTitle(@Nullable String syncContactsTitle) {
+            mBuilderParcel.syncContactsTitle = syncContactsTitle;
+            return this;
+        }
+
+        /**
+         * Set SyncContactsDescription.
+         *
+         * @param syncContactsDescription Description of the UI to ask the user to confirm to sync
+         *                                contacts.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setSyncContactsDescription(@Nullable String syncContactsDescription) {
+            mBuilderParcel.syncContactsDescription = syncContactsDescription;
+            return this;
+        }
+
+        /**
+         * Set SyncSmsTitle.
+         *
+         * @param syncSmsTitle Title of the UI to ask the user to confirm to sync SMS.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setSyncSmsTitle(@Nullable String syncSmsTitle) {
+            mBuilderParcel.syncSmsTitle = syncSmsTitle;
+            return this;
+        }
+
+        /**
+         * Set SyncSmsDescription.
+         *
+         * @param syncSmsDescription Description of the UI to ask the user to confirm to sync SMS.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setSyncSmsDescription(@Nullable String syncSmsDescription) {
+            mBuilderParcel.syncSmsDescription = syncSmsDescription;
+            return this;
+        }
+
+        /**
+         * Set AssistantSetupHalfSheet.
+         *
+         * @param assistantSetupHalfSheet Description in half sheet to ask user setup google
+         * assistant.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setAssistantSetupHalfSheet(@Nullable String assistantSetupHalfSheet) {
+            mBuilderParcel.assistantSetupHalfSheet = assistantSetupHalfSheet;
+            return this;
+        }
+
+        /**
+         * Set AssistantSetupNotification.
+         *
+         * @param assistantSetupNotification Description in notification to ask user setup google
+         *                                   assistant.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setAssistantSetupNotification(
+                @Nullable String assistantSetupNotification) {
+            mBuilderParcel.assistantSetupNotification = assistantSetupNotification;
+            return this;
+        }
+
+        /**
+         * Set FastPairTvConnectDeviceNoAccountDescription.
+         *
+         * @param fastPairTvConnectDeviceNoAccountDescription Description of the connect device
+         *                                                    action on TV, when user is not logged
+         *                                                    in.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setFastPairTvConnectDeviceNoAccountDescription(
+                @Nullable String fastPairTvConnectDeviceNoAccountDescription) {
+            mBuilderParcel.fastPairTvConnectDeviceNoAccountDescription =
+                    fastPairTvConnectDeviceNoAccountDescription;
+            return this;
+        }
+
+        /**
+         * Build {@link FastPairDeviceMetadata} with the currently set configuration.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public FastPairDeviceMetadata build() {
+            return new FastPairDeviceMetadata(mBuilderParcel);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/FastPairDiscoveryItem.java b/nearby/framework/java/android/nearby/FastPairDiscoveryItem.java
new file mode 100644
index 0000000..bc6a6f8
--- /dev/null
+++ b/nearby/framework/java/android/nearby/FastPairDiscoveryItem.java
@@ -0,0 +1,825 @@
+/*
+ * 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 android.nearby;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.nearby.aidl.FastPairDiscoveryItemParcel;
+
+/**
+ * Class for FastPairDiscoveryItem and its builder.
+ *
+ * @hide
+ */
+@SystemApi
+public class FastPairDiscoveryItem {
+
+    FastPairDiscoveryItemParcel mMetadataParcel;
+
+    FastPairDiscoveryItem(
+            FastPairDiscoveryItemParcel metadataParcel) {
+        this.mMetadataParcel = metadataParcel;
+    }
+
+    /**
+     * Get Id.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getId() {
+        return mMetadataParcel.id;
+    }
+
+    /**
+     * Get Type.
+     *
+     * @hide
+     */
+    @SystemApi
+    public int getType() {
+        return mMetadataParcel.type;
+    }
+
+    /**
+     * Get MacAddress.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getMacAddress() {
+        return mMetadataParcel.macAddress;
+    }
+
+    /**
+     * Get ActionUrl.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getActionUrl() {
+        return mMetadataParcel.actionUrl;
+    }
+
+    /**
+     * Get DeviceName.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getDeviceName() {
+        return mMetadataParcel.deviceName;
+    }
+
+    /**
+     * Get Title.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getTitle() {
+        return mMetadataParcel.title;
+    }
+
+    /**
+     * Get Description.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getDescription() {
+        return mMetadataParcel.description;
+    }
+
+    /**
+     * Get DisplayUrl.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getDisplayUrl() {
+        return mMetadataParcel.displayUrl;
+    }
+
+    /**
+     * Get LastObservationTimestampMillis.
+     *
+     * @hide
+     */
+    @SystemApi
+    public long getLastObservationTimestampMillis() {
+        return mMetadataParcel.lastObservationTimestampMillis;
+    }
+
+    /**
+     * Get FirstObservationTimestampMillis.
+     *
+     * @hide
+     */
+    @SystemApi
+    public long getFirstObservationTimestampMillis() {
+        return mMetadataParcel.firstObservationTimestampMillis;
+    }
+
+    /**
+     * Get State.
+     *
+     * @hide
+     */
+    @SystemApi
+    public int getState() {
+        return mMetadataParcel.state;
+    }
+
+    /**
+     * Get ActionUrlType.
+     *
+     * @hide
+     */
+    @SystemApi
+    public int getActionUrlType() {
+        return mMetadataParcel.actionUrlType;
+    }
+
+    /**
+     * Get Rssi.
+     *
+     * @hide
+     */
+    @SystemApi
+    public int getRssi() {
+        return mMetadataParcel.rssi;
+    }
+
+    /**
+     * Get PendingAppInstallTimestampMillis.
+     *
+     * @hide
+     */
+    @SystemApi
+    public long getPendingAppInstallTimestampMillis() {
+        return mMetadataParcel.pendingAppInstallTimestampMillis;
+    }
+
+    /**
+     * Get TxPower.
+     *
+     * @hide
+     */
+    @SystemApi
+    public int getTxPower() {
+        return mMetadataParcel.txPower;
+    }
+
+    /**
+     * Get AppName.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getAppName() {
+        return mMetadataParcel.appName;
+    }
+
+    /**
+     * Get GroupId.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getGroupId() {
+        return mMetadataParcel.groupId;
+    }
+
+    /**
+     * Get AttachmentType.
+     *
+     * @hide
+     */
+    @SystemApi
+    public int getAttachmentType() {
+        return mMetadataParcel.attachmentType;
+    }
+
+    /**
+     * Get PackageName.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getPackageName() {
+        return mMetadataParcel.packageName;
+    }
+
+    /**
+     * Get FeatureGraphicUrl.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getFeatureGraphicUrl() {
+        return mMetadataParcel.featureGraphicUrl;
+    }
+
+    /**
+     * Get TriggerId.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getTriggerId() {
+        return mMetadataParcel.triggerId;
+    }
+
+    /**
+     * Get IconPng, which is submitted at device registration time to display on notification. It is
+     * a 32-bit PNG with dimensions of 512px by 512px.
+     *
+     * @return IconPng in 32-bit PNG with dimensions of 512px by 512px.
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public byte[] getIconPng() {
+        return mMetadataParcel.iconPng;
+    }
+
+    /**
+     * Get IconFifeUrl.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getIconFfeUrl() {
+        return mMetadataParcel.iconFifeUrl;
+    }
+
+    /**
+     * Get DebugMessage.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getDebugMessage() {
+        return mMetadataParcel.debugMessage;
+    }
+
+    /**
+     * Get DebugCategory.
+     *
+     * @hide
+     */
+    @SystemApi
+    public int getDebugCategory() {
+        return mMetadataParcel.debugCategory;
+    }
+
+    /**
+     * Get LostMillis.
+     */
+    public long getLostMillis() {
+        return mMetadataParcel.lostMillis;
+    }
+
+    /**
+     * Get LastUserExperience.
+     *
+     * @hide
+     */
+    @SystemApi
+    public int getLastUserExperience() {
+        return mMetadataParcel.lastUserExperience;
+    }
+
+    /**
+     * Get BleRecordBytes. Raw bytes of {@link android.bluetooth.le.ScanRecord}.
+     * It is the most recent BLE advertisement related to this item.
+     *
+     * @return the most recent BLE advertisement in raw bytes of
+     *         {@link android.bluetooth.le.ScanRecord}.
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public byte[] getBleRecordBytes() {
+        return mMetadataParcel.bleRecordBytes;
+    }
+
+    /**
+     * Get EntityId.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getEntityId() {
+        return mMetadataParcel.entityId;
+    }
+
+    /**
+     * Get authenticationPublicKeySecp256r1, which is same as AntiSpoof public key, see
+     * <a href="https://developers.google.com/nearby/fast-pair/spec#data_format">Data Format</a>.
+     *
+     * @return 64-byte authenticationPublicKeySecp256r1.
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public byte[] getAuthenticationPublicKeySecp256r1() {
+        return mMetadataParcel.authenticationPublicKeySecp256r1;
+    }
+
+    /**
+     * Builder used to create FastPairDiscoveryItem.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder {
+
+        private final FastPairDiscoveryItemParcel mBuilderParcel;
+
+        /**
+         * Default constructor of Builder.
+         *
+         * @hide
+         */
+        @SystemApi
+        public Builder() {
+            mBuilderParcel = new FastPairDiscoveryItemParcel();
+        }
+
+        /**
+         * Set Id.
+         *
+         * @param id Unique id.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setId(@Nullable String id) {
+            mBuilderParcel.id = id;
+            return this;
+        }
+
+        /**
+         * Set Nearby Type.
+         *
+         * @param type Nearby type.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setType(int type) {
+            mBuilderParcel.type = type;
+            return this;
+        }
+
+        /**
+         * Set MacAddress.
+         *
+         * @param macAddress Fast Pair device rotating mac address.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setMacAddress(@Nullable String macAddress) {
+            mBuilderParcel.macAddress = macAddress;
+            return this;
+        }
+
+        /**
+         * Set ActionUrl.
+         *
+         * @param actionUrl Action Url of Fast Pair device.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setActionUrl(@Nullable String actionUrl) {
+            mBuilderParcel.actionUrl = actionUrl;
+            return this;
+        }
+
+        /**
+         * Set DeviceName.
+         * @param deviceName Fast Pair device name.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setDeviceName(@Nullable String deviceName) {
+            mBuilderParcel.deviceName = deviceName;
+            return this;
+        }
+
+        /**
+         * Set Title.
+         *
+         * @param title Title of Fast Pair device.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setTitle(@Nullable String title) {
+            mBuilderParcel.title = title;
+            return this;
+        }
+
+        /**
+         * Set Description.
+         *
+         * @param description Description of Fast Pair device.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setDescription(@Nullable String description) {
+            mBuilderParcel.description = description;
+            return this;
+        }
+
+        /**
+         * Set DisplayUrl.
+         *
+         * @param displayUrl Display Url of Fast Pair device.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setDisplayUrl(@Nullable String displayUrl) {
+            mBuilderParcel.displayUrl = displayUrl;
+            return this;
+        }
+
+        /**
+         * Set LastObservationTimestampMillis.
+         *
+         * @param lastObservationTimestampMillis Last observed timestamp of Fast Pair device, keyed
+         *                                       by a rotating id.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setLastObservationTimestampMillis(
+                long lastObservationTimestampMillis) {
+            mBuilderParcel.lastObservationTimestampMillis = lastObservationTimestampMillis;
+            return this;
+        }
+
+        /**
+         * Set FirstObservationTimestampMillis.
+         *
+         * @param firstObservationTimestampMillis First observed timestamp of Fast Pair device,
+         *                                        keyed by a rotating id.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setFirstObservationTimestampMillis(
+                long firstObservationTimestampMillis) {
+            mBuilderParcel.firstObservationTimestampMillis = firstObservationTimestampMillis;
+            return this;
+        }
+
+        /**
+         * Set State.
+         *
+         * @param state Item's current state. e.g. if the item is blocked.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setState(int state) {
+            mBuilderParcel.state = state;
+            return this;
+        }
+
+        /**
+         * Set ActionUrlType.
+         *
+         * @param actionUrlType The resolved url type for the action_url.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setActionUrlType(int actionUrlType) {
+            mBuilderParcel.actionUrlType = actionUrlType;
+            return this;
+        }
+
+        /**
+         * Set Rssi.
+         *
+         * @param rssi Beacon's RSSI value.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setRssi(int rssi) {
+            mBuilderParcel.rssi = rssi;
+            return this;
+        }
+
+        /**
+         * Set PendingAppInstallTimestampMillis.
+         *
+         * @param pendingAppInstallTimestampMillis The timestamp when the user is redirected to App
+         *                                         Store after clicking on the item.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setPendingAppInstallTimestampMillis(long pendingAppInstallTimestampMillis) {
+            mBuilderParcel.pendingAppInstallTimestampMillis = pendingAppInstallTimestampMillis;
+            return this;
+        }
+
+        /**
+         * Set TxPower.
+         *
+         * @param txPower Beacon's tx power.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setTxPower(int txPower) {
+            mBuilderParcel.txPower = txPower;
+            return this;
+        }
+
+        /**
+         * Set AppName.
+         *
+         * @param appName Human readable name of the app designated to open the uri.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setAppName(@Nullable String appName) {
+            mBuilderParcel.appName = appName;
+            return this;
+        }
+
+        /**
+         * Set GroupId.
+         *
+         * @param groupId ID used for associating several DiscoveryItems. These items may be
+         *                visually displayed together.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setGroupId(@Nullable String groupId) {
+            mBuilderParcel.groupId = groupId;
+            return this;
+        }
+
+        /**
+         * Set AttachmentType.
+         *
+         * @param attachmentType Whether the attachment is created in debug namespace.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setAttachmentType(int attachmentType) {
+            mBuilderParcel.attachmentType = attachmentType;
+            return this;
+        }
+
+        /**
+         * Set PackageName.
+         *
+         * @param packageName Package name of the App that owns this item.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setPackageName(@Nullable String packageName) {
+            mBuilderParcel.packageName = packageName;
+            return this;
+        }
+
+        /**
+         * Set FeatureGraphicUrl.
+         *
+         * @param featureGraphicUrl The "feature" graphic image url used for large sized list view
+         *                          entries.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setFeatureGraphicUrl(@Nullable String featureGraphicUrl) {
+            mBuilderParcel.featureGraphicUrl = featureGraphicUrl;
+            return this;
+        }
+
+        /**
+         * Set TriggerId.
+         *
+         * @param triggerId TriggerId identifies the trigger/beacon that is attached with a message.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setTriggerId(@Nullable String triggerId) {
+            mBuilderParcel.triggerId = triggerId;
+            return this;
+        }
+
+        /**
+         * Set IconPng.
+         *
+         * @param iconPng Bytes of item icon in PNG format displayed in Discovery item list.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setIconPng(@Nullable byte[] iconPng) {
+            mBuilderParcel.iconPng = iconPng;
+            return this;
+        }
+
+        /**
+         * Set IconFifeUrl.
+         *
+         * @param iconFifeUrl A FIFE URL of the item icon displayed in Discovery item list.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setIconFfeUrl(@Nullable String iconFifeUrl) {
+            mBuilderParcel.iconFifeUrl = iconFifeUrl;
+            return this;
+        }
+
+        /**
+         * Set DebugMessage.
+         *
+         * @param debugMessage Message written to bugreport for 3P developers.(No sensitive info)
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setDebugMessage(@Nullable String debugMessage) {
+            mBuilderParcel.debugMessage = debugMessage;
+            return this;
+        }
+
+        /**
+         * Set DebugCategory.
+         *
+         * @param debugCategory Weather the item is filtered out on server.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setDebugCategory(int debugCategory) {
+            mBuilderParcel.debugCategory = debugCategory;
+            return this;
+        }
+
+        /**
+         * Set LostMillis.
+         *
+         * @param lostMillis Client timestamp when the trigger (e.g. beacon) was last lost
+         *                   (e.g. when Messages told us the beacon's no longer nearby).
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setLostMillis(long lostMillis) {
+            mBuilderParcel.lostMillis = lostMillis;
+            return this;
+        }
+
+        /**
+         * Set LastUserExperience.
+         *
+         * @param lastUserExperience The kind of experience the user last had with this (e.g. if
+         *                           they dismissed the notification, that's bad; but if they tapped
+         *                           it, that's good).
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setLastUserExperience(int lastUserExperience) {
+            mBuilderParcel.lastUserExperience = lastUserExperience;
+            return this;
+        }
+
+        /**
+         * Set BleRecordBytes.
+         *
+         * @param bleRecordBytes The most recent BLE advertisement related to this item. Raw bytes
+         *                       of {@link android.bluetooth.le.ScanRecord}.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setBleRecordBytes(@Nullable byte[] bleRecordBytes) {
+            mBuilderParcel.bleRecordBytes = bleRecordBytes;
+            return this;
+        }
+
+        /**
+         * Set EntityId.
+         *
+         * @param entityId An ID generated on the server to uniquely identify content.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setEntityId(@Nullable String entityId) {
+            mBuilderParcel.entityId = entityId;
+            return this;
+        }
+
+        /**
+         * Set authenticationPublicKeySecp256r1, which is same as AntiSpoof public key, see
+         * <a href="https://developers.google.com/nearby/fast-pair/spec#data_format">Data Format</a>
+         *
+         * @param authenticationPublicKeySecp256r1 64-byte Fast Pair device public key.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setAuthenticationPublicKeySecp256r1(
+                @Nullable byte[] authenticationPublicKeySecp256r1) {
+            mBuilderParcel.authenticationPublicKeySecp256r1 = authenticationPublicKeySecp256r1;
+            return this;
+        }
+
+        /**
+         * Build {@link FastPairDiscoveryItem} with the currently set configuration.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public FastPairDiscoveryItem build() {
+            return new FastPairDiscoveryItem(mBuilderParcel);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/FastPairEligibleAccount.java b/nearby/framework/java/android/nearby/FastPairEligibleAccount.java
new file mode 100644
index 0000000..e6c3047
--- /dev/null
+++ b/nearby/framework/java/android/nearby/FastPairEligibleAccount.java
@@ -0,0 +1,121 @@
+/*
+ * 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 android.nearby;
+
+import android.accounts.Account;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.nearby.aidl.FastPairEligibleAccountParcel;
+
+/**
+ * Class for FastPairEligibleAccount and its builder.
+ *
+ * @hide
+ */
+@SystemApi
+public class FastPairEligibleAccount {
+
+    FastPairEligibleAccountParcel mAccountParcel;
+
+    FastPairEligibleAccount(FastPairEligibleAccountParcel accountParcel) {
+        this.mAccountParcel = accountParcel;
+    }
+
+    /**
+     * Get Account.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public Account getAccount() {
+        return this.mAccountParcel.account;
+    }
+
+    /**
+     * Get OptIn Status.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean isOptIn() {
+        return this.mAccountParcel.optIn;
+    }
+
+    /**
+     * Builder used to create FastPairEligibleAccount.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder {
+
+        private final FastPairEligibleAccountParcel mBuilderParcel;
+
+        /**
+         * Default constructor of Builder.
+         *
+         * @hide
+         */
+        @SystemApi
+        public Builder() {
+            mBuilderParcel = new FastPairEligibleAccountParcel();
+            mBuilderParcel.account = null;
+            mBuilderParcel.optIn = false;
+        }
+
+        /**
+         * Set Account.
+         *
+         * @param account Fast Pair eligible account.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setAccount(@Nullable Account account) {
+            mBuilderParcel.account = account;
+            return this;
+        }
+
+        /**
+         * Set whether the account is opt into Fast Pair.
+         *
+         * @param optIn Whether the Fast Pair eligible account opts into Fast Pair.
+         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setOptIn(boolean optIn) {
+            mBuilderParcel.optIn = optIn;
+            return this;
+        }
+
+        /**
+         * Build {@link FastPairEligibleAccount} with the currently set configuration.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public FastPairEligibleAccount build() {
+            return new FastPairEligibleAccount(mBuilderParcel);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/FastPairStatusCallback.java b/nearby/framework/java/android/nearby/FastPairStatusCallback.java
new file mode 100644
index 0000000..1567828
--- /dev/null
+++ b/nearby/framework/java/android/nearby/FastPairStatusCallback.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.NonNull;
+
+/**
+ * Reports the pair status for an ongoing pair with a {@link FastPairDevice}.
+ * @hide
+ */
+public interface FastPairStatusCallback {
+
+    /** Reports a pair status related metadata associated with a {@link FastPairDevice} */
+    void onPairUpdate(@NonNull FastPairDevice fastPairDevice,
+            PairStatusMetadata pairStatusMetadata);
+}
diff --git a/nearby/framework/java/android/nearby/IBroadcastListener.aidl b/nearby/framework/java/android/nearby/IBroadcastListener.aidl
new file mode 100644
index 0000000..98c7e17
--- /dev/null
+++ b/nearby/framework/java/android/nearby/IBroadcastListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+/**
+ * Callback when brodacast status changes.
+ *
+ * {@hide}
+ */
+oneway interface IBroadcastListener {
+    /** Called when the broadcast status changes. */
+    void onStatusChanged(int status);
+}
diff --git a/nearby/framework/java/android/nearby/IFastPairHalfSheetCallback.aidl b/nearby/framework/java/android/nearby/IFastPairHalfSheetCallback.aidl
new file mode 100644
index 0000000..2e6fc87
--- /dev/null
+++ b/nearby/framework/java/android/nearby/IFastPairHalfSheetCallback.aidl
@@ -0,0 +1,25 @@
+// 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 android.nearby;
+
+import android.content.Intent;
+/**
+  * Provides callback interface for halfsheet to send FastPair call back.
+  *
+  * {@hide}
+  */
+interface IFastPairHalfSheetCallback {
+     void onHalfSheetConnectionConfirm(in Intent intent);
+ }
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/INearbyManager.aidl b/nearby/framework/java/android/nearby/INearbyManager.aidl
new file mode 100644
index 0000000..62e109e
--- /dev/null
+++ b/nearby/framework/java/android/nearby/INearbyManager.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.nearby.IBroadcastListener;
+import android.nearby.IScanListener;
+import android.nearby.BroadcastRequestParcelable;
+import android.nearby.ScanRequest;
+
+/**
+ * Interface for communicating with the nearby services.
+ *
+ * @hide
+ */
+interface INearbyManager {
+
+    int registerScanListener(in ScanRequest scanRequest, in IScanListener listener);
+
+    void unregisterScanListener(in IScanListener listener);
+
+    void startBroadcast(in BroadcastRequestParcelable broadcastRequest,
+            in IBroadcastListener callback);
+
+    void stopBroadcast(in IBroadcastListener callback);
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/IScanListener.aidl b/nearby/framework/java/android/nearby/IScanListener.aidl
new file mode 100644
index 0000000..54033aa
--- /dev/null
+++ b/nearby/framework/java/android/nearby/IScanListener.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.nearby.NearbyDeviceParcelable;
+
+/**
+ * Binder callback for ScanCallback.
+ *
+ * {@hide}
+ */
+oneway interface IScanListener {
+        /** Reports a {@link NearbyDevice} being discovered. */
+        void onDiscovered(in NearbyDeviceParcelable nearbyDeviceParcelable);
+
+        /** Reports a {@link NearbyDevice} information(distance, packet, and etc) changed. */
+        void onUpdated(in NearbyDeviceParcelable nearbyDeviceParcelable);
+
+        /** Reports a {@link NearbyDevice} is no longer within range. */
+        void onLost(in NearbyDeviceParcelable nearbyDeviceParcelable);
+}
diff --git a/nearby/framework/java/android/nearby/NearbyDevice.java b/nearby/framework/java/android/nearby/NearbyDevice.java
new file mode 100644
index 0000000..538940c
--- /dev/null
+++ b/nearby/framework/java/android/nearby/NearbyDevice.java
@@ -0,0 +1,151 @@
+/*
+ * 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 android.nearby;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A class represents a device that can be discovered by multiple mediums.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class NearbyDevice {
+
+    @Nullable
+    private final String mName;
+
+    @Medium
+    private final List<Integer> mMediums;
+
+    private final int mRssi;
+
+    /**
+     * Creates a new NearbyDevice.
+     *
+     * @param name Local device name. Can be {@code null} if there is no name.
+     * @param mediums The {@link Medium}s over which the device is discovered.
+     * @param rssi The received signal strength in dBm.
+     * @hide
+     */
+    public NearbyDevice(@Nullable String name, List<Integer> mediums, int rssi) {
+        for (int medium : mediums) {
+            Preconditions.checkState(isValidMedium(medium),
+                    "Not supported medium: " + medium
+                            + ", scan medium must be one of NearbyDevice#Medium.");
+        }
+        mName = name;
+        mMediums = mediums;
+        mRssi = rssi;
+    }
+
+    static String mediumToString(@Medium int medium) {
+        switch (medium) {
+            case Medium.BLE:
+                return "BLE";
+            case Medium.BLUETOOTH:
+                return "Bluetooth Classic";
+            default:
+                return "Unknown";
+        }
+    }
+
+    /**
+     * True if the medium is defined in {@link Medium}.
+     *
+     * @param medium Integer that may represent a medium type.
+     */
+    public static boolean isValidMedium(@Medium int medium) {
+        return medium == Medium.BLE
+                || medium == Medium.BLUETOOTH;
+    }
+
+    /**
+     * The name of the device, or null if not available.
+     */
+    @Nullable
+    public String getName() {
+        return mName;
+    }
+
+    /** The medium over which this device was discovered. */
+    @NonNull
+    @Medium public List<Integer> getMediums() {
+        return mMediums;
+    }
+
+    /**
+     * Returns the received signal strength in dBm.
+     */
+    @IntRange(from = -127, to = 126)
+    public int getRssi() {
+        return mRssi;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("NearbyDevice [");
+        if (mName != null && !mName.isEmpty()) {
+            stringBuilder.append("name=").append(mName).append(", ");
+        }
+        stringBuilder.append("medium={");
+        for (int medium : mMediums) {
+            stringBuilder.append(mediumToString(medium));
+        }
+        stringBuilder.append("} rssi=").append(mRssi);
+        stringBuilder.append("]");
+        return stringBuilder.toString();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof NearbyDevice) {
+            NearbyDevice otherDevice = (NearbyDevice) other;
+            return Objects.equals(mName, otherDevice.mName)
+                    && mMediums == otherDevice.mMediums
+                    && mRssi == otherDevice.mRssi;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mName, mMediums, mRssi);
+    }
+
+    /**
+     * The medium where a NearbyDevice was discovered on.
+     *
+     * @hide
+     */
+    @IntDef({Medium.BLE, Medium.BLUETOOTH})
+    public @interface Medium {
+        int BLE = 1;
+        int BLUETOOTH = 2;
+    }
+}
+
diff --git a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.aidl b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.aidl
new file mode 100644
index 0000000..1a88181
--- /dev/null
+++ b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.nearby;
+
+parcelable NearbyDeviceParcelable;
+
diff --git a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
new file mode 100644
index 0000000..1ad3571
--- /dev/null
+++ b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
@@ -0,0 +1,437 @@
+/*
+ * 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 android.nearby;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * A data class representing scan result from Nearby Service. Scan result can come from multiple
+ * mediums like BLE, Wi-Fi Aware, and etc. A scan result consists of An encapsulation of various
+ * parameters for requesting nearby scans.
+ *
+ * <p>All scan results generated through {@link NearbyManager} are guaranteed to have a valid
+ * medium, identifier, timestamp (both UTC time and elapsed real-time since boot), and accuracy. All
+ * other parameters are optional.
+ *
+ * @hide
+ */
+public final class NearbyDeviceParcelable implements Parcelable {
+
+    /** Used to read a NearbyDeviceParcelable from a Parcel. */
+    @NonNull
+    public static final Creator<NearbyDeviceParcelable> CREATOR =
+            new Creator<NearbyDeviceParcelable>() {
+                @Override
+                public NearbyDeviceParcelable createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    if (in.readInt() == 1) {
+                        builder.setName(in.readString());
+                    }
+                    builder.setMedium(in.readInt());
+                    builder.setTxPower(in.readInt());
+                    builder.setRssi(in.readInt());
+                    builder.setAction(in.readInt());
+                    builder.setPublicCredential(
+                            in.readParcelable(
+                                    PublicCredential.class.getClassLoader(),
+                                    PublicCredential.class));
+                    if (in.readInt() == 1) {
+                        builder.setFastPairModelId(in.readString());
+                    }
+                    if (in.readInt() == 1) {
+                        builder.setBluetoothAddress(in.readString());
+                    }
+                    if (in.readInt() == 1) {
+                        int dataLength = in.readInt();
+                        byte[] data = new byte[dataLength];
+                        in.readByteArray(data);
+                        builder.setData(data);
+                    }
+                    return builder.build();
+                }
+
+                @Override
+                public NearbyDeviceParcelable[] newArray(int size) {
+                    return new NearbyDeviceParcelable[size];
+                }
+            };
+
+    @ScanRequest.ScanType int mScanType;
+    @Nullable private final String mName;
+    @NearbyDevice.Medium private final int mMedium;
+    private final int mTxPower;
+    private final int mRssi;
+    private final int mAction;
+    private final PublicCredential mPublicCredential;
+    @Nullable private final String mBluetoothAddress;
+    @Nullable private final String mFastPairModelId;
+    @Nullable private final byte[] mData;
+
+    private NearbyDeviceParcelable(
+            @ScanRequest.ScanType int scanType,
+            @Nullable String name,
+            int medium,
+            int TxPower,
+            int rssi,
+            int action,
+            PublicCredential publicCredential,
+            @Nullable String fastPairModelId,
+            @Nullable String bluetoothAddress,
+            @Nullable byte[] data) {
+        mScanType = scanType;
+        mName = name;
+        mMedium = medium;
+        mTxPower = TxPower;
+        mRssi = rssi;
+        mAction = action;
+        mPublicCredential = publicCredential;
+        mFastPairModelId = fastPairModelId;
+        mBluetoothAddress = bluetoothAddress;
+        mData = data;
+    }
+
+    /** No special parcel contents. */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Flatten this NearbyDeviceParcelable in to a Parcel.
+     *
+     * @param dest The Parcel in which the object should be written.
+     * @param flags Additional flags about how the object should be written.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mName == null ? 0 : 1);
+        if (mName != null) {
+            dest.writeString(mName);
+        }
+        dest.writeInt(mMedium);
+        dest.writeInt(mTxPower);
+        dest.writeInt(mRssi);
+        dest.writeInt(mAction);
+        dest.writeParcelable(mPublicCredential, flags);
+        dest.writeInt(mFastPairModelId == null ? 0 : 1);
+        if (mFastPairModelId != null) {
+            dest.writeString(mFastPairModelId);
+        }
+        dest.writeInt(mBluetoothAddress == null ? 0 : 1);
+        if (mBluetoothAddress != null) {
+            dest.writeString(mBluetoothAddress);
+        }
+        dest.writeInt(mData == null ? 0 : 1);
+        if (mData != null) {
+            dest.writeInt(mData.length);
+            dest.writeByteArray(mData);
+        }
+    }
+
+    /** Returns a string representation of this ScanRequest. */
+    @Override
+    public String toString() {
+        return "NearbyDeviceParcelable["
+                + "name="
+                + mName
+                + ", medium="
+                + NearbyDevice.mediumToString(mMedium)
+                + ", txPower="
+                + mTxPower
+                + ", rssi="
+                + mRssi
+                + ", action="
+                + mAction
+                + ", bluetoothAddress="
+                + mBluetoothAddress
+                + ", fastPairModelId="
+                + mFastPairModelId
+                + ", data="
+                + Arrays.toString(mData)
+                + "]";
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof NearbyDeviceParcelable) {
+            NearbyDeviceParcelable otherNearbyDeviceParcelable = (NearbyDeviceParcelable) other;
+            return Objects.equals(mName, otherNearbyDeviceParcelable.mName)
+                    && (mMedium == otherNearbyDeviceParcelable.mMedium)
+                    && (mTxPower == otherNearbyDeviceParcelable.mTxPower)
+                    && (mRssi == otherNearbyDeviceParcelable.mRssi)
+                    && (mAction == otherNearbyDeviceParcelable.mAction)
+                    && (Objects.equals(
+                            mPublicCredential, otherNearbyDeviceParcelable.mPublicCredential))
+                    && (Objects.equals(
+                            mBluetoothAddress, otherNearbyDeviceParcelable.mBluetoothAddress))
+                    && (Objects.equals(
+                            mFastPairModelId, otherNearbyDeviceParcelable.mFastPairModelId))
+                    && (Arrays.equals(mData, otherNearbyDeviceParcelable.mData));
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                mName,
+                mMedium,
+                mRssi,
+                mAction,
+                mPublicCredential.hashCode(),
+                mBluetoothAddress,
+                mFastPairModelId,
+                Arrays.hashCode(mData));
+    }
+
+    /**
+     * Returns the type of the scan.
+     *
+     * @hide
+     */
+    @ScanRequest.ScanType
+    public int getScanType() {
+        return mScanType;
+    }
+
+    /** Gets the name of the NearbyDeviceParcelable. Returns {@code null} If there is no name. */
+    @Nullable
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Gets the {@link android.nearby.NearbyDevice.Medium} of the NearbyDeviceParcelable over which
+     * it is discovered.
+     */
+    @NearbyDevice.Medium
+    public int getMedium() {
+        return mMedium;
+    }
+
+    /**
+     * Gets the transmission power in dBm.
+     *
+     * @hide
+     */
+    @IntRange(from = -127, to = 126)
+    public int getTxPower() {
+        return mTxPower;
+    }
+
+    /** Gets the received signal strength in dBm. */
+    @IntRange(from = -127, to = 126)
+    public int getRssi() {
+        return mRssi;
+    }
+
+    /**
+     * Gets the Action.
+     *
+     * @hide
+     */
+    @IntRange(from = -127, to = 126)
+    public int getAction() {
+        return mAction;
+    }
+
+    /**
+     * Gets the public credential.
+     *
+     * @hide
+     */
+    @NonNull
+    public PublicCredential getPublicCredential() {
+        return mPublicCredential;
+    }
+
+    /**
+     * Gets the Fast Pair identifier. Returns {@code null} if there is no Model ID or this is not a
+     * Fast Pair device.
+     */
+    @Nullable
+    public String getFastPairModelId() {
+        return mFastPairModelId;
+    }
+
+    /**
+     * Gets the Bluetooth device hardware address. Returns {@code null} if the device is not
+     * discovered by Bluetooth.
+     */
+    @Nullable
+    public String getBluetoothAddress() {
+        return mBluetoothAddress;
+    }
+
+    /** Gets the raw data from the scanning. Returns {@code null} if there is no extra data. */
+    @Nullable
+    public byte[] getData() {
+        return mData;
+    }
+
+    /** Builder class for {@link NearbyDeviceParcelable}. */
+    public static final class Builder {
+        @Nullable private String mName;
+        @NearbyDevice.Medium private int mMedium;
+        private int mTxPower;
+        private int mRssi;
+        private int mAction;
+        private PublicCredential mPublicCredential;
+        @ScanRequest.ScanType int mScanType;
+        @Nullable private String mFastPairModelId;
+        @Nullable private String mBluetoothAddress;
+        @Nullable private byte[] mData;
+
+        /**
+         * Sets the scan type of the NearbyDeviceParcelable.
+         *
+         * @hide
+         */
+        public Builder setScanType(@ScanRequest.ScanType int scanType) {
+            mScanType = scanType;
+            return this;
+        }
+
+        /**
+         * Sets the name of the scanned device.
+         *
+         * @param name The local name of the scanned device.
+         */
+        @NonNull
+        public Builder setName(@Nullable String name) {
+            mName = name;
+            return this;
+        }
+
+        /**
+         * Sets the medium over which the device is discovered.
+         *
+         * @param medium The {@link NearbyDevice.Medium} over which the device is discovered.
+         */
+        @NonNull
+        public Builder setMedium(@NearbyDevice.Medium int medium) {
+            mMedium = medium;
+            return this;
+        }
+
+        /**
+         * Sets the transmission power of the discovered device.
+         *
+         * @param txPower The transmission power in dBm.
+         * @hide
+         */
+        @NonNull
+        public Builder setTxPower(int txPower) {
+            mTxPower = txPower;
+            return this;
+        }
+
+        /**
+         * Sets the RSSI between scanned device and the discovered device.
+         *
+         * @param rssi The received signal strength in dBm.
+         */
+        @NonNull
+        public Builder setRssi(@IntRange(from = -127, to = 126) int rssi) {
+            mRssi = rssi;
+            return this;
+        }
+
+        /**
+         * Sets the action from the discovered device.
+         *
+         * @param action The action of the discovered device.
+         * @hide
+         */
+        @NonNull
+        public Builder setAction(int action) {
+            mAction = action;
+            return this;
+        }
+
+        /**
+         * Sets the public credential of the discovered device.
+         *
+         * @param publicCredential The public credential.
+         * @hide
+         */
+        @NonNull
+        public Builder setPublicCredential(@NonNull PublicCredential publicCredential) {
+            mPublicCredential = publicCredential;
+            return this;
+        }
+
+        /**
+         * Sets the Fast Pair model Id.
+         *
+         * @param fastPairModelId Fast Pair device identifier.
+         */
+        @NonNull
+        public Builder setFastPairModelId(@Nullable String fastPairModelId) {
+            mFastPairModelId = fastPairModelId;
+            return this;
+        }
+
+        /**
+         * Sets the bluetooth address.
+         *
+         * @param bluetoothAddress The hardware address of the bluetooth device.
+         */
+        @NonNull
+        public Builder setBluetoothAddress(@Nullable String bluetoothAddress) {
+            mBluetoothAddress = bluetoothAddress;
+            return this;
+        }
+
+        /**
+         * Sets the scanned raw data.
+         *
+         * @param data Data the scan. For example, {@link ScanRecord#getServiceData()} if scanned by
+         *     Bluetooth.
+         */
+        @NonNull
+        public Builder setData(@Nullable byte[] data) {
+            mData = data;
+            return this;
+        }
+
+        /** Builds a ScanResult. */
+        @NonNull
+        public NearbyDeviceParcelable build() {
+            return new NearbyDeviceParcelable(
+                    mScanType,
+                    mName,
+                    mMedium,
+                    mTxPower,
+                    mRssi,
+                    mAction,
+                    mPublicCredential,
+                    mFastPairModelId,
+                    mBluetoothAddress,
+                    mData);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/NearbyFrameworkInitializer.java b/nearby/framework/java/android/nearby/NearbyFrameworkInitializer.java
new file mode 100644
index 0000000..3780fbb
--- /dev/null
+++ b/nearby/framework/java/android/nearby/NearbyFrameworkInitializer.java
@@ -0,0 +1,50 @@
+/*
+ * 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 android.nearby;
+
+import android.annotation.SystemApi;
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+
+/**
+ * Class for performing registration for all Nearby services.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class NearbyFrameworkInitializer {
+
+    private NearbyFrameworkInitializer() {}
+
+    /**
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers all
+     * Nearby services to {@link Context}, so that {@link Context#getSystemService} can return them.
+     *
+     * @throws IllegalStateException if this is called from anywhere besides
+     * {@link SystemServiceRegistry}
+     */
+    public static void registerServiceWrappers() {
+        SystemServiceRegistry.registerContextAwareService(
+                Context.NEARBY_SERVICE,
+                NearbyManager.class,
+                (context, serviceBinder) -> {
+                    INearbyManager service = INearbyManager.Stub.asInterface(serviceBinder);
+                    return new NearbyManager(service);
+                }
+        );
+    }
+}
diff --git a/nearby/framework/java/android/nearby/NearbyManager.java b/nearby/framework/java/android/nearby/NearbyManager.java
new file mode 100644
index 0000000..1b82dca
--- /dev/null
+++ b/nearby/framework/java/android/nearby/NearbyManager.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright 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 android.nearby;
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.os.RemoteException;
+import android.provider.Settings;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.lang.ref.WeakReference;
+import java.util.Objects;
+import java.util.WeakHashMap;
+import java.util.concurrent.Executor;
+
+/**
+ * This class provides a way to perform Nearby related operations such as scanning, broadcasting
+ * and connecting to nearby devices.
+ *
+ * <p> To get a {@link NearbyManager} instance, call the
+ * <code>Context.getSystemService(NearbyManager.class)</code>.
+ *
+ * @hide
+ */
+@SystemApi
+@SystemService(Context.NEARBY_SERVICE)
+public class NearbyManager {
+
+    /**
+     * Represents the scanning state.
+     *
+     * @hide
+     */
+    @IntDef({
+            ScanStatus.UNKNOWN,
+            ScanStatus.SUCCESS,
+            ScanStatus.ERROR,
+    })
+    public @interface ScanStatus {
+        // Default, invalid state.
+        int UNKNOWN = 0;
+        // The successful state.
+        int SUCCESS = 1;
+        // Failed state.
+        int ERROR = 2;
+    }
+
+    /**
+     * Whether allows Fast Pair to scan.
+     *
+     * (0 = disabled, 1 = enabled)
+     *
+     * @hide
+     */
+    public static final String FAST_PAIR_SCAN_ENABLED = "fast_pair_scan_enabled";
+
+    @GuardedBy("sScanListeners")
+    private static final WeakHashMap<ScanCallback, WeakReference<ScanListenerTransport>>
+            sScanListeners = new WeakHashMap<>();
+    @GuardedBy("sBroadcastListeners")
+    private static final WeakHashMap<BroadcastCallback, WeakReference<BroadcastListenerTransport>>
+            sBroadcastListeners = new WeakHashMap<>();
+
+    private final INearbyManager mService;
+
+    /**
+     * Creates a new NearbyManager.
+     *
+     * @param service the service object
+     */
+    NearbyManager(@NonNull INearbyManager service) {
+        mService = service;
+    }
+
+    private static NearbyDevice toClientNearbyDevice(
+            NearbyDeviceParcelable nearbyDeviceParcelable,
+            @ScanRequest.ScanType int scanType) {
+        if (scanType == ScanRequest.SCAN_TYPE_FAST_PAIR) {
+            return new FastPairDevice.Builder()
+                    .setName(nearbyDeviceParcelable.getName())
+                    .addMedium(nearbyDeviceParcelable.getMedium())
+                    .setRssi(nearbyDeviceParcelable.getRssi())
+                    .setTxPower(nearbyDeviceParcelable.getTxPower())
+                    .setModelId(nearbyDeviceParcelable.getFastPairModelId())
+                    .setBluetoothAddress(nearbyDeviceParcelable.getBluetoothAddress())
+                    .setData(nearbyDeviceParcelable.getData()).build();
+        }
+        return null;
+    }
+
+    /**
+     * Start scan for nearby devices with given parameters. Devices matching {@link ScanRequest}
+     * will be delivered through the given callback.
+     *
+     * @param scanRequest various parameters clients send when requesting scanning
+     * @param executor executor where the listener method is called
+     * @param scanCallback the callback to notify clients when there is a scan result
+     *
+     * @return whether scanning was successfully started
+     */
+    @RequiresPermission(allOf = {android.Manifest.permission.BLUETOOTH_SCAN,
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED})
+    @ScanStatus
+    public int startScan(@NonNull ScanRequest scanRequest,
+            @CallbackExecutor @NonNull Executor executor,
+            @NonNull ScanCallback scanCallback) {
+        Objects.requireNonNull(scanRequest, "scanRequest must not be null");
+        Objects.requireNonNull(scanCallback, "scanCallback must not be null");
+        Objects.requireNonNull(executor, "executor must not be null");
+
+        try {
+            synchronized (sScanListeners) {
+                WeakReference<ScanListenerTransport> reference = sScanListeners.get(scanCallback);
+                ScanListenerTransport transport = reference != null ? reference.get() : null;
+                if (transport == null) {
+                    transport = new ScanListenerTransport(scanRequest.getScanType(), scanCallback,
+                            executor);
+                } else {
+                    Preconditions.checkState(transport.isRegistered());
+                    transport.setExecutor(executor);
+                }
+                @ScanStatus int status = mService.registerScanListener(scanRequest, transport);
+                if (status != ScanStatus.SUCCESS) {
+                    return status;
+                }
+                sScanListeners.put(scanCallback, new WeakReference<>(transport));
+                return ScanStatus.SUCCESS;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Stops the nearby device scan for the specified callback. The given callback
+     * is guaranteed not to receive any invocations that happen after this method
+     * is invoked.
+     *
+     * Suppressed lint: Registration methods should have overload that accepts delivery Executor.
+     * Already have executor in startScan() method.
+     *
+     * @param scanCallback the callback that was used to start the scan
+     */
+    @SuppressLint("ExecutorRegistration")
+    @RequiresPermission(allOf = {android.Manifest.permission.BLUETOOTH_SCAN,
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED})
+    public void stopScan(@NonNull ScanCallback scanCallback) {
+        Preconditions.checkArgument(scanCallback != null,
+                "invalid null scanCallback");
+        try {
+            synchronized (sScanListeners) {
+                WeakReference<ScanListenerTransport> reference = sScanListeners.remove(
+                        scanCallback);
+                ScanListenerTransport transport = reference != null ? reference.get() : null;
+                if (transport != null) {
+                    transport.unregister();
+                    mService.unregisterScanListener(transport);
+                }
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Start broadcasting the request using nearby specification.
+     *
+     * @param broadcastRequest request for the nearby broadcast
+     * @param executor executor for running the callback
+     * @param callback callback for notifying the client
+     */
+    @RequiresPermission(allOf = {Manifest.permission.BLUETOOTH_ADVERTISE,
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED})
+    public void startBroadcast(@NonNull BroadcastRequest broadcastRequest,
+            @CallbackExecutor @NonNull Executor executor, @NonNull BroadcastCallback callback) {
+        try {
+            synchronized (sBroadcastListeners) {
+                WeakReference<BroadcastListenerTransport> reference = sBroadcastListeners.get(
+                        callback);
+                BroadcastListenerTransport transport = reference != null ? reference.get() : null;
+                if (transport == null) {
+                    transport = new BroadcastListenerTransport(callback, executor);
+                } else {
+                    Preconditions.checkState(transport.isRegistered());
+                    transport.setExecutor(executor);
+                }
+                mService.startBroadcast(new BroadcastRequestParcelable(broadcastRequest),
+                        transport);
+                sBroadcastListeners.put(callback, new WeakReference<>(transport));
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Stop the broadcast associated with the given callback.
+     *
+     * @param callback the callback that was used for starting the broadcast
+     */
+    @SuppressLint("ExecutorRegistration")
+    @RequiresPermission(allOf = {Manifest.permission.BLUETOOTH_ADVERTISE,
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED})
+    public void stopBroadcast(@NonNull BroadcastCallback callback) {
+        try {
+            synchronized (sBroadcastListeners) {
+                WeakReference<BroadcastListenerTransport> reference = sBroadcastListeners.remove(
+                        callback);
+                BroadcastListenerTransport transport = reference != null ? reference.get() : null;
+                if (transport != null) {
+                    transport.unregister();
+                    mService.stopBroadcast(transport);
+                }
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Read from {@link Settings} whether Fast Pair scan is enabled.
+     *
+     * @param context the {@link Context} to query the setting
+     * @return whether the Fast Pair is enabled
+     */
+    public static boolean getFastPairScanEnabled(@NonNull Context context) {
+        final int enabled = Settings.Secure.getInt(
+                context.getContentResolver(), FAST_PAIR_SCAN_ENABLED, 0);
+        return enabled != 0;
+    }
+
+    /**
+     * Write into {@link Settings} whether Fast Pair scan is enabled
+     *
+     * @param context the {@link Context} to set the setting
+     * @param enable whether the Fast Pair scan should be enabled
+     */
+    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+    public static void setFastPairScanEnabled(@NonNull Context context, boolean enable) {
+        Settings.Secure.putInt(
+                context.getContentResolver(), FAST_PAIR_SCAN_ENABLED, enable ? 1 : 0);
+    }
+
+    private static class ScanListenerTransport extends IScanListener.Stub {
+
+        private @ScanRequest.ScanType int mScanType;
+        private volatile @Nullable ScanCallback mScanCallback;
+        private Executor mExecutor;
+
+        ScanListenerTransport(@ScanRequest.ScanType int scanType, ScanCallback scanCallback,
+                @CallbackExecutor Executor executor) {
+            Preconditions.checkArgument(scanCallback != null,
+                    "invalid null callback");
+            Preconditions.checkState(ScanRequest.isValidScanType(scanType),
+                    "invalid scan type : " + scanType
+                            + ", scan type must be one of ScanRequest#SCAN_TYPE_");
+            mScanType = scanType;
+            mScanCallback = scanCallback;
+            mExecutor = executor;
+        }
+
+        void setExecutor(Executor executor) {
+            Preconditions.checkArgument(
+                    executor != null, "invalid null executor");
+            mExecutor = executor;
+        }
+
+        boolean isRegistered() {
+            return mScanCallback != null;
+        }
+
+        void unregister() {
+            mScanCallback = null;
+        }
+
+        @Override
+        public void onDiscovered(NearbyDeviceParcelable nearbyDeviceParcelable)
+                throws RemoteException {
+            mExecutor.execute(() -> mScanCallback.onDiscovered(
+                    toClientNearbyDevice(nearbyDeviceParcelable, mScanType)));
+        }
+
+        @Override
+        public void onUpdated(NearbyDeviceParcelable nearbyDeviceParcelable)
+                throws RemoteException {
+            mExecutor.execute(
+                    () -> mScanCallback.onUpdated(
+                            toClientNearbyDevice(nearbyDeviceParcelable, mScanType)));
+        }
+
+        @Override
+        public void onLost(NearbyDeviceParcelable nearbyDeviceParcelable) throws RemoteException {
+            mExecutor.execute(
+                    () -> mScanCallback.onLost(
+                            toClientNearbyDevice(nearbyDeviceParcelable, mScanType)));
+        }
+    }
+
+    private static class BroadcastListenerTransport extends IBroadcastListener.Stub {
+        private volatile @Nullable BroadcastCallback mBroadcastCallback;
+        private Executor mExecutor;
+
+        BroadcastListenerTransport(BroadcastCallback broadcastCallback,
+                @CallbackExecutor Executor executor) {
+            mBroadcastCallback = broadcastCallback;
+            mExecutor = executor;
+        }
+
+        void setExecutor(Executor executor) {
+            Preconditions.checkArgument(
+                    executor != null, "invalid null executor");
+            mExecutor = executor;
+        }
+
+        boolean isRegistered() {
+            return mBroadcastCallback != null;
+        }
+
+        void unregister() {
+            mBroadcastCallback = null;
+        }
+
+        @Override
+        public void onStatusChanged(int status) {
+            mExecutor.execute(() -> {
+                if (mBroadcastCallback != null) {
+                    mBroadcastCallback.onStatusChanged(status);
+                }
+            });
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/PairStatusMetadata.aidl b/nearby/framework/java/android/nearby/PairStatusMetadata.aidl
new file mode 100644
index 0000000..911a300
--- /dev/null
+++ b/nearby/framework/java/android/nearby/PairStatusMetadata.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+/**
+ * Metadata about an ongoing paring. Wraps transient data like status and progress.
+ *
+ * @hide
+ */
+parcelable PairStatusMetadata;
diff --git a/nearby/framework/java/android/nearby/PairStatusMetadata.java b/nearby/framework/java/android/nearby/PairStatusMetadata.java
new file mode 100644
index 0000000..438cd6b
--- /dev/null
+++ b/nearby/framework/java/android/nearby/PairStatusMetadata.java
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Metadata about an ongoing paring. Wraps transient data like status and progress.
+ *
+ * @hide
+ */
+public final class PairStatusMetadata implements Parcelable {
+
+    @Status
+    private final int mStatus;
+
+    /** The status of the pairing. */
+    @IntDef({
+            Status.UNKNOWN,
+            Status.SUCCESS,
+            Status.FAIL,
+            Status.DISMISS
+    })
+    public @interface Status {
+        int UNKNOWN = 1000;
+        int SUCCESS = 1001;
+        int FAIL = 1002;
+        int DISMISS = 1003;
+    }
+
+    /** Converts the status to readable string. */
+    public static String statusToString(@Status int status) {
+        switch (status) {
+            case Status.SUCCESS:
+                return "SUCCESS";
+            case Status.FAIL:
+                return "FAIL";
+            case Status.DISMISS:
+                return "DISMISS";
+            case Status.UNKNOWN:
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    public int getStatus() {
+        return mStatus;
+    }
+
+    @Override
+    public String toString() {
+        return "PairStatusMetadata[ status=" + statusToString(mStatus) + "]";
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof PairStatusMetadata) {
+            return mStatus == ((PairStatusMetadata) other).mStatus;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mStatus);
+    }
+
+    public PairStatusMetadata(@Status int status) {
+        mStatus = status;
+    }
+
+    public static final Creator<PairStatusMetadata> CREATOR = new Creator<PairStatusMetadata>() {
+        @Override
+        public PairStatusMetadata createFromParcel(Parcel in) {
+            return new PairStatusMetadata(in.readInt());
+        }
+
+        @Override
+        public PairStatusMetadata[] newArray(int size) {
+            return new PairStatusMetadata[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public int getStability() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mStatus);
+    }
+}
diff --git a/nearby/framework/java/android/nearby/PresenceBroadcastRequest.java b/nearby/framework/java/android/nearby/PresenceBroadcastRequest.java
new file mode 100644
index 0000000..d01be06
--- /dev/null
+++ b/nearby/framework/java/android/nearby/PresenceBroadcastRequest.java
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Request for Nearby Presence Broadcast.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PresenceBroadcastRequest extends BroadcastRequest implements Parcelable {
+    private final byte[] mSalt;
+    private final List<Integer> mActions;
+    private final PrivateCredential mCredential;
+    private final List<DataElement> mExtendedProperties;
+
+    private PresenceBroadcastRequest(@BroadcastVersion int version, int txPower,
+            List<Integer> mediums, byte[] salt, List<Integer> actions,
+            PrivateCredential credential, List<DataElement> extendedProperties) {
+        super(BROADCAST_TYPE_NEARBY_PRESENCE, version, txPower, mediums);
+        mSalt = salt;
+        mActions = actions;
+        mCredential = credential;
+        mExtendedProperties = extendedProperties;
+    }
+
+    private PresenceBroadcastRequest(Parcel in) {
+        super(BROADCAST_TYPE_NEARBY_PRESENCE, in);
+        mSalt = new byte[in.readInt()];
+        in.readByteArray(mSalt);
+
+        mActions = new ArrayList<>();
+        in.readList(mActions, Integer.class.getClassLoader(), Integer.class);
+        mCredential = in.readParcelable(PrivateCredential.class.getClassLoader(),
+                PrivateCredential.class);
+        mExtendedProperties = new ArrayList<>();
+        in.readList(mExtendedProperties, DataElement.class.getClassLoader(), DataElement.class);
+    }
+
+    @NonNull
+    public static final Creator<PresenceBroadcastRequest> CREATOR =
+            new Creator<PresenceBroadcastRequest>() {
+                @Override
+                public PresenceBroadcastRequest createFromParcel(Parcel in) {
+                    // Skip Broadcast request type - it's used by parent class.
+                    in.readInt();
+                    return createFromParcelBody(in);
+                }
+
+                @Override
+                public PresenceBroadcastRequest[] newArray(int size) {
+                    return new PresenceBroadcastRequest[size];
+                }
+            };
+
+    static PresenceBroadcastRequest createFromParcelBody(Parcel in) {
+        return new PresenceBroadcastRequest(in);
+    }
+
+    /**
+     * Returns the salt associated with this broadcast request.
+     */
+    @NonNull
+    public byte[] getSalt() {
+        return mSalt;
+    }
+
+    /**
+     * Returns actions associated with this broadcast request.
+     */
+    @NonNull
+    public List<Integer> getActions() {
+        return mActions;
+    }
+
+    /**
+     * Returns the private credential associated with this broadcast request.
+     */
+    @NonNull
+    public PrivateCredential getCredential() {
+        return mCredential;
+    }
+
+    /**
+     * Returns extended property information associated with this broadcast request.
+     */
+    @NonNull
+    public List<DataElement> getExtendedProperties() {
+        return mExtendedProperties;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(mSalt.length);
+        dest.writeByteArray(mSalt);
+        dest.writeList(mActions);
+        dest.writeParcelable(mCredential, /** parcelableFlags= */0);
+        dest.writeList(mExtendedProperties);
+    }
+
+    /**
+     * Builder for {@link PresenceBroadcastRequest}.
+     */
+    public static final class Builder {
+        private final List<Integer> mMediums;
+        private final List<Integer> mActions;
+        private final List<DataElement> mExtendedProperties;
+        private final byte[] mSalt;
+        private final PrivateCredential mCredential;
+
+        private int mVersion;
+        private int mTxPower;
+
+        public Builder(@NonNull List<Integer> mediums, @NonNull byte[] salt,
+                @NonNull PrivateCredential credential) {
+            Preconditions.checkState(!mediums.isEmpty(), "mediums cannot be empty");
+            Preconditions.checkState(salt != null && salt.length > 0, "salt cannot be empty");
+
+            mVersion = PRESENCE_VERSION_V0;
+            mTxPower = UNKNOWN_TX_POWER;
+            mCredential = credential;
+            mActions = new ArrayList<>();
+            mExtendedProperties = new ArrayList<>();
+
+            mSalt = salt;
+            mMediums = mediums;
+        }
+
+        /**
+         * Sets the version for this request.
+         */
+        @NonNull
+        public Builder setVersion(@BroadcastVersion int version) {
+            mVersion = version;
+            return this;
+        }
+
+        /**
+         * Sets the calibrated tx power level in dBm for this request. The tx power level should
+         * be between -127 dBm and 126 dBm.
+         */
+        @NonNull
+        public Builder setTxPower(@IntRange(from = -127, to = 126) int txPower) {
+            mTxPower = txPower;
+            return this;
+        }
+
+        /**
+         * Adds an action for the presence broadcast request.
+         */
+        @NonNull
+        public Builder addAction(@IntRange(from = 1, to = 255) int action) {
+            mActions.add(action);
+            return this;
+        }
+
+        /**
+         * Adds an extended property for the presence broadcast request.
+         */
+        @NonNull
+        public Builder addExtendedProperty(@NonNull DataElement dataElement) {
+            Objects.requireNonNull(dataElement);
+            mExtendedProperties.add(dataElement);
+            return this;
+        }
+
+        /**
+         * Builds a {@link PresenceBroadcastRequest}.
+         */
+        @NonNull
+        public PresenceBroadcastRequest build() {
+            return new PresenceBroadcastRequest(mVersion, mTxPower, mMediums, mSalt, mActions,
+                    mCredential, mExtendedProperties);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/PresenceCredential.java b/nearby/framework/java/android/nearby/PresenceCredential.java
new file mode 100644
index 0000000..1e851d6
--- /dev/null
+++ b/nearby/framework/java/android/nearby/PresenceCredential.java
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Represents a credential for Nearby Presence.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class PresenceCredential {
+    /** Private credential type. */
+    public static final int CREDENTIAL_TYPE_PRIVATE = 0;
+
+    /** Public credential type. */
+    public static final int CREDENTIAL_TYPE_PUBLIC = 1;
+
+    /**
+     * @hide *
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({CREDENTIAL_TYPE_PUBLIC, CREDENTIAL_TYPE_PRIVATE})
+    public @interface CredentialType {}
+
+    /** Unknown identity type. */
+    public static final int IDENTITY_TYPE_UNKNOWN = 0;
+
+    /** Private identity type. */
+    public static final int IDENTITY_TYPE_PRIVATE = 1;
+    /** Provisioned identity type. */
+    public static final int IDENTITY_TYPE_PROVISIONED = 2;
+    /** Trusted identity type. */
+    public static final int IDENTITY_TYPE_TRUSTED = 3;
+    /** Public identity type. */
+    public static final int IDENTITY_TYPE_PUBLIC = 4;
+
+    /**
+     * @hide *
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        IDENTITY_TYPE_UNKNOWN,
+        IDENTITY_TYPE_PRIVATE,
+        IDENTITY_TYPE_PROVISIONED,
+        IDENTITY_TYPE_TRUSTED,
+        IDENTITY_TYPE_PUBLIC
+    })
+    public @interface IdentityType {}
+
+    private final @CredentialType int mType;
+    private final @IdentityType int mIdentityType;
+    private final byte[] mSecretId;
+    private final byte[] mAuthenticityKey;
+    private final List<CredentialElement> mCredentialElements;
+
+    PresenceCredential(
+            @CredentialType int type,
+            @IdentityType int identityType,
+            byte[] secretId,
+            byte[] authenticityKey,
+            List<CredentialElement> credentialElements) {
+        mType = type;
+        mIdentityType = identityType;
+        mSecretId = secretId;
+        mAuthenticityKey = authenticityKey;
+        mCredentialElements = credentialElements;
+    }
+
+    PresenceCredential(@CredentialType int type, Parcel in) {
+        mType = type;
+        mIdentityType = in.readInt();
+        mSecretId = new byte[in.readInt()];
+        in.readByteArray(mSecretId);
+        mAuthenticityKey = new byte[in.readInt()];
+        in.readByteArray(mAuthenticityKey);
+        mCredentialElements = new ArrayList<>();
+        in.readList(
+                mCredentialElements,
+                CredentialElement.class.getClassLoader(),
+                CredentialElement.class);
+    }
+
+    /** Returns the type of the credential. */
+    public @CredentialType int getType() {
+        return mType;
+    }
+
+    /** Returns the identity type of the credential. */
+    public @IdentityType int getIdentityType() {
+        return mIdentityType;
+    }
+
+    /** Returns the secret id of the credential. */
+    @NonNull
+    public byte[] getSecretId() {
+        return mSecretId;
+    }
+
+    /** Returns the authenticity key of the credential. */
+    @NonNull
+    public byte[] getAuthenticityKey() {
+        return mAuthenticityKey;
+    }
+
+    /** Returns the elements of the credential. */
+    @NonNull
+    public List<CredentialElement> getCredentialElements() {
+        return mCredentialElements;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof PresenceCredential) {
+            PresenceCredential that = (PresenceCredential) obj;
+            return mType == that.mType
+                    && mIdentityType == that.mIdentityType
+                    && Arrays.equals(mSecretId, that.mSecretId)
+                    && Arrays.equals(mAuthenticityKey, that.mAuthenticityKey)
+                    && mCredentialElements.equals(that.mCredentialElements);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                mType,
+                mIdentityType,
+                Arrays.hashCode(mSecretId),
+                Arrays.hashCode(mAuthenticityKey),
+                mCredentialElements.hashCode());
+    }
+
+    /**
+     * Writes the presence credential to the parcel.
+     *
+     * @hide
+     */
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mType);
+        dest.writeInt(mIdentityType);
+        dest.writeInt(mSecretId.length);
+        dest.writeByteArray(mSecretId);
+        dest.writeInt(mAuthenticityKey.length);
+        dest.writeByteArray(mAuthenticityKey);
+        dest.writeList(mCredentialElements);
+    }
+}
diff --git a/nearby/framework/java/android/nearby/PresenceDevice.java b/nearby/framework/java/android/nearby/PresenceDevice.java
new file mode 100644
index 0000000..12fc2a3
--- /dev/null
+++ b/nearby/framework/java/android/nearby/PresenceDevice.java
@@ -0,0 +1,373 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Represents a Presence device from nearby scans.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PresenceDevice extends NearbyDevice implements Parcelable {
+
+    /** The type of presence device. */
+    /** @hide **/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            DeviceType.UNKNOWN,
+            DeviceType.PHONE,
+            DeviceType.TABLET,
+            DeviceType.DISPLAY,
+            DeviceType.LAPTOP,
+            DeviceType.TV,
+            DeviceType.WATCH,
+    })
+    public @interface DeviceType {
+        /** The type of the device is unknown. */
+        int UNKNOWN = 0;
+        /** The device is a phone. */
+        int PHONE = 1;
+        /** The device is a tablet. */
+        int TABLET = 2;
+        /** The device is a display. */
+        int DISPLAY = 3;
+        /** The device is a laptop. */
+        int LAPTOP = 4;
+        /** The device is a TV. */
+        int TV = 5;
+        /** The device is a watch. */
+        int WATCH = 6;
+    }
+
+    private final String mDeviceId;
+    private final byte[] mSalt;
+    private final byte[] mSecretId;
+    private final byte[] mEncryptedIdentity;
+    private final int mDeviceType;
+    private final String mDeviceImageUrl;
+    private final long mDiscoveryTimestampMillis;
+    private final List<DataElement> mExtendedProperties;
+
+    /**
+     * The id of the device.
+     *
+     * <p>This id is not a hardware id. It may rotate based on the remote device's broadcasts.
+     */
+    @NonNull
+    public String getDeviceId() {
+        return mDeviceId;
+    }
+
+    /**
+     * Returns the salt used when presence device is discovered.
+     */
+    @NonNull
+    public byte[] getSalt() {
+        return mSalt;
+    }
+
+    /**
+     * Returns the secret used when presence device is discovered.
+     */
+    @NonNull
+    public byte[] getSecretId() {
+        return mSecretId;
+    }
+
+    /**
+     * Returns the encrypted identity used when presence device is discovered.
+     */
+    @NonNull
+    public byte[] getEncryptedIdentity() {
+        return mEncryptedIdentity;
+    }
+
+    /** The type of the device. */
+    @DeviceType
+    public int getDeviceType() {
+        return mDeviceType;
+    }
+
+    /** An image URL representing the device. */
+    @Nullable
+    public String getDeviceImageUrl() {
+        return mDeviceImageUrl;
+    }
+
+    /** The timestamp (since boot) when the device is discovered. */
+    public long getDiscoveryTimestampMillis() {
+        return mDiscoveryTimestampMillis;
+    }
+
+    /**
+     * The extended properties of the device.
+     */
+    @NonNull
+    public List<DataElement> getExtendedProperties() {
+        return mExtendedProperties;
+    }
+
+    private PresenceDevice(String deviceName, List<Integer> mMediums, int rssi, String deviceId,
+            byte[] salt, byte[] secretId, byte[] encryptedIdentity, int deviceType,
+            String deviceImageUrl, long discoveryTimestampMillis,
+            List<DataElement> extendedProperties) {
+        super(deviceName, mMediums, rssi);
+        mDeviceId = deviceId;
+        mSalt = salt;
+        mSecretId = secretId;
+        mEncryptedIdentity = encryptedIdentity;
+        mDeviceType = deviceType;
+        mDeviceImageUrl = deviceImageUrl;
+        mDiscoveryTimestampMillis = discoveryTimestampMillis;
+        mExtendedProperties = extendedProperties;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        String name = getName();
+        dest.writeInt(name == null ? 0 : 1);
+        if (name != null) {
+            dest.writeString(name);
+        }
+        List<Integer> mediums = getMediums();
+        dest.writeInt(mediums.size());
+        for (int medium : mediums) {
+            dest.writeInt(medium);
+        }
+        dest.writeInt(getRssi());
+        dest.writeInt(mSalt.length);
+        dest.writeByteArray(mSalt);
+        dest.writeInt(mSecretId.length);
+        dest.writeByteArray(mSecretId);
+        dest.writeInt(mEncryptedIdentity.length);
+        dest.writeByteArray(mEncryptedIdentity);
+        dest.writeString(mDeviceId);
+        dest.writeInt(mDeviceType);
+        dest.writeInt(mDeviceImageUrl == null ? 0 : 1);
+        if (mDeviceImageUrl != null) {
+            dest.writeString(mDeviceImageUrl);
+        }
+        dest.writeLong(mDiscoveryTimestampMillis);
+        dest.writeInt(mExtendedProperties.size());
+        for (DataElement dataElement : mExtendedProperties) {
+            dest.writeParcelable(dataElement, 0);
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    public static final Creator<PresenceDevice> CREATOR = new Creator<PresenceDevice>() {
+        @Override
+        public PresenceDevice createFromParcel(Parcel in) {
+            String name = null;
+            if (in.readInt() == 1) {
+                name = in.readString();
+            }
+            int size = in.readInt();
+            List<Integer> mediums = new ArrayList<>();
+            for (int i = 0; i < size; i++) {
+                mediums.add(in.readInt());
+            }
+            int rssi = in.readInt();
+            byte[] salt = new byte[in.readInt()];
+            in.readByteArray(salt);
+            byte[] secretId = new byte[in.readInt()];
+            in.readByteArray(secretId);
+            byte[] encryptedIdentity = new byte[in.readInt()];
+            in.readByteArray(encryptedIdentity);
+            String deviceId = in.readString();
+            int deviceType = in.readInt();
+            String deviceImageUrl = null;
+            if (in.readInt() == 1) {
+                deviceImageUrl = in.readString();
+            }
+            long discoveryTimeMillis = in.readLong();
+            int dataElementSize = in.readInt();
+            List<DataElement> dataElements = new ArrayList<>();
+            for (int i = 0; i < dataElementSize; i++) {
+                dataElements.add(
+                        in.readParcelable(DataElement.class.getClassLoader(), DataElement.class));
+            }
+            Builder builder = new Builder(deviceId, salt, secretId, encryptedIdentity)
+                    .setName(name)
+                    .setRssi(rssi)
+                    .setDeviceType(deviceType)
+                    .setDeviceImageUrl(deviceImageUrl)
+                    .setDiscoveryTimestampMillis(discoveryTimeMillis);
+            for (int i = 0; i < mediums.size(); i++) {
+                builder.addMedium(mediums.get(i));
+            }
+            for (int i = 0; i < dataElements.size(); i++) {
+                builder.addExtendedProperty(dataElements.get(i));
+            }
+            return builder.build();
+        }
+
+        @Override
+        public PresenceDevice[] newArray(int size) {
+            return new PresenceDevice[size];
+        }
+    };
+
+    /**
+     * Builder class for {@link PresenceDevice}.
+     */
+    public static final class Builder {
+
+        private final List<DataElement> mExtendedProperties;
+        private final List<Integer> mMediums;
+        private final String mDeviceId;
+        private final byte[] mSalt;
+        private final byte[] mSecretId;
+        private final byte[] mEncryptedIdentity;
+
+        private String mName;
+        private int mRssi;
+        private int mDeviceType;
+        private String mDeviceImageUrl;
+        private long mDiscoveryTimestampMillis;
+
+        /**
+         * Constructs a {@link Builder}.
+         *
+         * @param deviceId the identifier on the discovered Presence device
+         * @param salt a random salt used in the beacon from the Presence device.
+         * @param secretId a secret identifier used in the beacon from the Presence device.
+         * @param encryptedIdentity the identity associated with the Presence device.
+         */
+        public Builder(@NonNull String deviceId, @NonNull byte[] salt, @NonNull byte[] secretId,
+                @NonNull byte[] encryptedIdentity) {
+            mDeviceId = deviceId;
+            mSalt = salt;
+            mSecretId = secretId;
+            mEncryptedIdentity = encryptedIdentity;
+            mMediums = new ArrayList<>();
+            mExtendedProperties = new ArrayList<>();
+            mRssi = -127;
+        }
+
+        /**
+         * Sets the name of the Presence device.
+         *
+         * @param name Name of the Presence. Can be {@code null} if there is no name.
+         */
+        @NonNull
+        public Builder setName(@Nullable String name) {
+            mName = name;
+            return this;
+        }
+
+        /**
+         * Adds the medium over which the Presence device is discovered.
+         *
+         * @param medium The {@link Medium} over which the device is discovered.
+         */
+        @NonNull
+        public Builder addMedium(@Medium int medium) {
+            mMediums.add(medium);
+            return this;
+        }
+
+        /**
+         * Sets the RSSI on the discovered Presence device.
+         *
+         * @param rssi The received signal strength in dBm.
+         */
+        @NonNull
+        public Builder setRssi(int rssi) {
+            mRssi = rssi;
+            return this;
+        }
+
+        /**
+         * Sets the type of discovered Presence device.
+         *
+         * @param deviceType Type of the Presence device.
+         */
+        @NonNull
+        public Builder setDeviceType(@DeviceType int deviceType) {
+            mDeviceType = deviceType;
+            return this;
+        }
+
+
+        /**
+         * Sets the image url of the discovered Presence device.
+         *
+         * @param deviceImageUrl Url of the image for the Presence device.
+         */
+        @NonNull
+        public Builder setDeviceImageUrl(@Nullable String deviceImageUrl) {
+            mDeviceImageUrl = deviceImageUrl;
+            return this;
+        }
+
+
+        /**
+         * Sets discovery timestamp, the clock is based on elapsed time.
+         *
+         * @param discoveryTimestampMillis Timestamp when the presence device is discovered.
+         */
+        @NonNull
+        public Builder setDiscoveryTimestampMillis(long discoveryTimestampMillis) {
+            mDiscoveryTimestampMillis = discoveryTimestampMillis;
+            return this;
+        }
+
+
+        /**
+         * Adds an extended property of the discovered presence device.
+         *
+         * @param dataElement Data element of the extended property.
+         */
+        @NonNull
+        public Builder addExtendedProperty(@NonNull DataElement dataElement) {
+            Objects.requireNonNull(dataElement);
+            mExtendedProperties.add(dataElement);
+            return this;
+        }
+
+        /**
+         * Builds a Presence device.
+         */
+        @NonNull
+        public PresenceDevice build() {
+            return new PresenceDevice(mName, mMediums, mRssi, mDeviceId,
+                    mSalt, mSecretId, mEncryptedIdentity,
+                    mDeviceType,
+                    mDeviceImageUrl,
+                    mDiscoveryTimestampMillis, mExtendedProperties);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/PresenceScanFilter.java b/nearby/framework/java/android/nearby/PresenceScanFilter.java
new file mode 100644
index 0000000..f0c3c06
--- /dev/null
+++ b/nearby/framework/java/android/nearby/PresenceScanFilter.java
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArraySet;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Filter for scanning a nearby presence device.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PresenceScanFilter extends ScanFilter implements Parcelable {
+
+    private final List<PublicCredential> mCredentials;
+    private final List<Integer> mPresenceActions;
+    private final List<DataElement> mExtendedProperties;
+
+    /**
+     * A list of credentials to filter on.
+     */
+    @NonNull
+    public List<PublicCredential> getCredentials() {
+        return mCredentials;
+    }
+
+    /**
+     * A list of presence actions for matching.
+     */
+    @NonNull
+    public List<Integer> getPresenceActions() {
+        return mPresenceActions;
+    }
+
+    /**
+     * A bundle of extended properties for matching.
+     */
+    @NonNull
+    public List<DataElement> getExtendedProperties() {
+        return mExtendedProperties;
+    }
+
+    private PresenceScanFilter(int rssiThreshold, List<PublicCredential> credentials,
+            List<Integer> presenceActions, List<DataElement> extendedProperties) {
+        super(ScanRequest.SCAN_TYPE_NEARBY_PRESENCE, rssiThreshold);
+        mCredentials = new ArrayList<>(credentials);
+        mPresenceActions = new ArrayList<>(presenceActions);
+        mExtendedProperties = extendedProperties;
+    }
+
+    private PresenceScanFilter(Parcel in) {
+        super(ScanRequest.SCAN_TYPE_NEARBY_PRESENCE, in);
+        mCredentials = new ArrayList<>();
+        if (in.readInt() != 0) {
+            in.readParcelableList(mCredentials, PublicCredential.class.getClassLoader(),
+                    PublicCredential.class);
+        }
+        mPresenceActions = new ArrayList<>();
+        if (in.readInt() != 0) {
+            in.readList(mPresenceActions, Integer.class.getClassLoader(), Integer.class);
+        }
+        mExtendedProperties = new ArrayList<>();
+        if (in.readInt() != 0) {
+            in.readParcelableList(mExtendedProperties, DataElement.class.getClassLoader(),
+                    DataElement.class);
+        }
+    }
+
+    @NonNull
+    public static final Creator<PresenceScanFilter> CREATOR = new Creator<PresenceScanFilter>() {
+        @Override
+        public PresenceScanFilter createFromParcel(Parcel in) {
+            // Skip Scan Filter type as it's used for parent class.
+            in.readInt();
+            return createFromParcelBody(in);
+        }
+
+        @Override
+        public PresenceScanFilter[] newArray(int size) {
+            return new PresenceScanFilter[size];
+        }
+    };
+
+    /**
+     * Create a {@link PresenceScanFilter} from the parcel body. Scan Filter type is skipped.
+     */
+    static PresenceScanFilter createFromParcelBody(Parcel in) {
+        return new PresenceScanFilter(in);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(mCredentials.size());
+        if (!mCredentials.isEmpty()) {
+            dest.writeParcelableList(mCredentials, 0);
+        }
+        dest.writeInt(mPresenceActions.size());
+        if (!mPresenceActions.isEmpty()) {
+            dest.writeList(mPresenceActions);
+        }
+        dest.writeInt(mExtendedProperties.size());
+        if (!mExtendedProperties.isEmpty()) {
+            dest.writeList(mExtendedProperties);
+        }
+    }
+
+    /**
+     * Builder for {@link PresenceScanFilter}.
+     */
+    public static final class Builder {
+        private int mMaxPathLoss;
+        private final Set<PublicCredential> mCredentials;
+        private final Set<Integer> mPresenceIdentities;
+        private final Set<Integer> mPresenceActions;
+        private final List<DataElement> mExtendedProperties;
+
+        public Builder() {
+            mMaxPathLoss = 127;
+            mCredentials = new ArraySet<>();
+            mPresenceIdentities = new ArraySet<>();
+            mPresenceActions = new ArraySet<>();
+            mExtendedProperties = new ArrayList<>();
+        }
+
+        /**
+         * Sets the max path loss (in dBm) for the scan request. The path loss is the attenuation
+         * of radio energy between sender and receiver. Path loss here is defined as (TxPower -
+         * Rssi).
+         */
+        @NonNull
+        public Builder setMaxPathLoss(@IntRange(from = 0, to = 127) int maxPathLoss) {
+            mMaxPathLoss = maxPathLoss;
+            return this;
+        }
+
+        /**
+         * Adds a credential the scan filter is expected to match.
+         */
+
+        @NonNull
+        public Builder addCredential(@NonNull PublicCredential credential) {
+            Objects.requireNonNull(credential);
+            mCredentials.add(credential);
+            return this;
+        }
+
+        /**
+         * Adds a presence action for filtering, which is an action the discoverer could take
+         * when it receives the broadcast of a presence device.
+         */
+        @NonNull
+        public Builder addPresenceAction(@IntRange(from = 1, to = 255) int action) {
+            mPresenceActions.add(action);
+            return this;
+        }
+
+        /**
+         * Add an extended property for scan filtering.
+         */
+        @NonNull
+        public Builder addExtendedProperty(@NonNull DataElement dataElement) {
+            Objects.requireNonNull(dataElement);
+            mExtendedProperties.add(dataElement);
+            return this;
+        }
+
+        /**
+         * Builds the scan filter.
+         */
+        @NonNull
+        public PresenceScanFilter build() {
+            Preconditions.checkState(!mCredentials.isEmpty(), "credentials cannot be empty");
+            return new PresenceScanFilter(mMaxPathLoss,
+                    new ArrayList<>(mCredentials),
+                    new ArrayList<>(mPresenceActions),
+                    mExtendedProperties);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/PrivateCredential.java b/nearby/framework/java/android/nearby/PrivateCredential.java
new file mode 100644
index 0000000..d915cc6
--- /dev/null
+++ b/nearby/framework/java/android/nearby/PrivateCredential.java
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a private credential.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PrivateCredential extends PresenceCredential implements Parcelable {
+
+    @NonNull
+    public static final Creator<PrivateCredential> CREATOR = new Creator<PrivateCredential>() {
+        @Override
+        public PrivateCredential createFromParcel(Parcel in) {
+            in.readInt(); // Skip the type as it's used by parent class only.
+            return createFromParcelBody(in);
+        }
+
+        @Override
+        public PrivateCredential[] newArray(int size) {
+            return new PrivateCredential[size];
+        }
+    };
+
+    private byte[] mMetadataEncryptionKey;
+    private String mDeviceName;
+
+    private PrivateCredential(Parcel in) {
+        super(CREDENTIAL_TYPE_PRIVATE, in);
+        mMetadataEncryptionKey = new byte[in.readInt()];
+        in.readByteArray(mMetadataEncryptionKey);
+        mDeviceName = in.readString();
+    }
+
+    private PrivateCredential(int identityType, byte[] secretId,
+            String deviceName, byte[] authenticityKey, List<CredentialElement> credentialElements,
+            byte[] metadataEncryptionKey) {
+        super(CREDENTIAL_TYPE_PRIVATE, identityType, secretId, authenticityKey,
+                credentialElements);
+        mDeviceName = deviceName;
+        mMetadataEncryptionKey = metadataEncryptionKey;
+    }
+
+    static PrivateCredential createFromParcelBody(Parcel in) {
+        return new PrivateCredential(in);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(mMetadataEncryptionKey.length);
+        dest.writeByteArray(mMetadataEncryptionKey);
+        dest.writeString(mDeviceName);
+    }
+
+    /**
+     * Returns the metadata encryption key associated with this credential.
+     */
+    @NonNull
+    public byte[] getMetadataEncryptionKey() {
+        return mMetadataEncryptionKey;
+    }
+
+    /**
+     * Returns the device name associated with this credential.
+     */
+    @NonNull
+    public String getDeviceName() {
+        return mDeviceName;
+    }
+
+    /**
+     * Builder class for {@link PresenceCredential}.
+     */
+    public static final class Builder {
+        private final List<CredentialElement> mCredentialElements;
+
+        private @IdentityType int mIdentityType;
+        private final byte[] mSecretId;
+        private final byte[] mAuthenticityKey;
+        private final byte[] mMetadataEncryptionKey;
+        private final String mDeviceName;
+
+        public Builder(@NonNull byte[] secretId, @NonNull byte[] authenticityKey,
+                @NonNull byte[] metadataEncryptionKey, @NonNull String deviceName) {
+            Preconditions.checkState(secretId != null && secretId.length > 0,
+                    "secret id cannot be empty");
+            Preconditions.checkState(authenticityKey != null && authenticityKey.length > 0,
+                    "authenticity key cannot be empty");
+            Preconditions.checkState(
+                    metadataEncryptionKey != null && metadataEncryptionKey.length > 0,
+                    "metadataEncryptionKey cannot be empty");
+            Preconditions.checkState(deviceName != null && deviceName.length() > 0,
+                    "deviceName cannot be empty");
+            mSecretId = secretId;
+            mAuthenticityKey = authenticityKey;
+            mMetadataEncryptionKey = metadataEncryptionKey;
+            mDeviceName = deviceName;
+            mCredentialElements = new ArrayList<>();
+        }
+
+        /**
+         * Sets the identity type for the presence credential.
+         */
+        @NonNull
+        public Builder setIdentityType(@IdentityType int identityType) {
+            mIdentityType = identityType;
+            return this;
+        }
+
+        /**
+         * Adds an element to the credential.
+         */
+        @NonNull
+        public Builder addCredentialElement(@NonNull CredentialElement credentialElement) {
+            mCredentialElements.add(credentialElement);
+            return this;
+        }
+
+        /**
+         * Builds the {@link PresenceCredential}.
+         */
+        @NonNull
+        public PrivateCredential build() {
+            return new PrivateCredential(mIdentityType, mSecretId, mDeviceName,
+                    mAuthenticityKey, mCredentialElements, mMetadataEncryptionKey);
+        }
+
+    }
+}
diff --git a/nearby/framework/java/android/nearby/PublicCredential.java b/nearby/framework/java/android/nearby/PublicCredential.java
new file mode 100644
index 0000000..5998d19
--- /dev/null
+++ b/nearby/framework/java/android/nearby/PublicCredential.java
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Represents a public credential.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PublicCredential extends PresenceCredential implements Parcelable {
+    @NonNull
+    public static final Creator<PublicCredential> CREATOR =
+            new Creator<PublicCredential>() {
+                @Override
+                public PublicCredential createFromParcel(Parcel in) {
+                    in.readInt(); // Skip the type as it's used by parent class only.
+                    return createFromParcelBody(in);
+                }
+
+                @Override
+                public PublicCredential[] newArray(int size) {
+                    return new PublicCredential[size];
+                }
+            };
+
+    private final byte[] mPublicKey;
+    private final byte[] mEncryptedMetadata;
+    private final byte[] mEncryptedMetadataKeyTag;
+
+    private PublicCredential(
+            int identityType,
+            byte[] secretId,
+            byte[] authenticityKey,
+            List<CredentialElement> credentialElements,
+            byte[] publicKey,
+            byte[] encryptedMetadata,
+            byte[] metadataEncryptionKeyTag) {
+        super(CREDENTIAL_TYPE_PUBLIC, identityType, secretId, authenticityKey, credentialElements);
+        mPublicKey = publicKey;
+        mEncryptedMetadata = encryptedMetadata;
+        mEncryptedMetadataKeyTag = metadataEncryptionKeyTag;
+    }
+
+    private PublicCredential(Parcel in) {
+        super(CREDENTIAL_TYPE_PUBLIC, in);
+        mPublicKey = new byte[in.readInt()];
+        in.readByteArray(mPublicKey);
+        mEncryptedMetadata = new byte[in.readInt()];
+        in.readByteArray(mEncryptedMetadata);
+        mEncryptedMetadataKeyTag = new byte[in.readInt()];
+        in.readByteArray(mEncryptedMetadataKeyTag);
+    }
+
+    static PublicCredential createFromParcelBody(Parcel in) {
+        return new PublicCredential(in);
+    }
+
+    /** Returns the public key associated with this credential. */
+    @NonNull
+    public byte[] getPublicKey() {
+        return mPublicKey;
+    }
+
+    /** Returns the encrypted metadata associated with this credential. */
+    @NonNull
+    public byte[] getEncryptedMetadata() {
+        return mEncryptedMetadata;
+    }
+
+    /** Returns the metadata encryption key tag associated with this credential. */
+    @NonNull
+    public byte[] getEncryptedMetadataKeyTag() {
+        return mEncryptedMetadataKeyTag;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj instanceof PublicCredential) {
+            PublicCredential that = (PublicCredential) obj;
+            return super.equals(obj)
+                    && Arrays.equals(mPublicKey, that.mPublicKey)
+                    && Arrays.equals(mEncryptedMetadata, that.mEncryptedMetadata)
+                    && Arrays.equals(mEncryptedMetadataKeyTag, that.mEncryptedMetadataKeyTag);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                super.hashCode(),
+                Arrays.hashCode(mPublicKey),
+                Arrays.hashCode(mEncryptedMetadata),
+                Arrays.hashCode(mEncryptedMetadataKeyTag));
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(mPublicKey.length);
+        dest.writeByteArray(mPublicKey);
+        dest.writeInt(mEncryptedMetadata.length);
+        dest.writeByteArray(mEncryptedMetadata);
+        dest.writeInt(mEncryptedMetadataKeyTag.length);
+        dest.writeByteArray(mEncryptedMetadataKeyTag);
+    }
+
+    /** Builder class for {@link PresenceCredential}. */
+    public static final class Builder {
+        private final List<CredentialElement> mCredentialElements;
+
+        private @IdentityType int mIdentityType;
+        private final byte[] mSecretId;
+        private final byte[] mAuthenticityKey;
+        private final byte[] mPublicKey;
+        private final byte[] mEncryptedMetadata;
+        private final byte[] mEncryptedMetadataKeyTag;
+
+        public Builder(
+                @NonNull byte[] secretId,
+                @NonNull byte[] authenticityKey,
+                @NonNull byte[] publicKey,
+                @NonNull byte[] encryptedMetadata,
+                @NonNull byte[] encryptedMetadataKeyTag) {
+            Preconditions.checkState(
+                    secretId != null && secretId.length > 0, "secret id cannot be empty");
+            Preconditions.checkState(
+                    authenticityKey != null && authenticityKey.length > 0,
+                    "authenticity key cannot be empty");
+            Preconditions.checkState(
+                    publicKey != null && publicKey.length > 0, "publicKey cannot be empty");
+            Preconditions.checkState(
+                    encryptedMetadata != null && encryptedMetadata.length > 0,
+                    "encryptedMetadata cannot be empty");
+            Preconditions.checkState(
+                    encryptedMetadataKeyTag != null && encryptedMetadataKeyTag.length > 0,
+                    "encryptedMetadataKeyTag cannot be empty");
+
+            mSecretId = secretId;
+            mAuthenticityKey = authenticityKey;
+            mPublicKey = publicKey;
+            mEncryptedMetadata = encryptedMetadata;
+            mEncryptedMetadataKeyTag = encryptedMetadataKeyTag;
+            mCredentialElements = new ArrayList<>();
+        }
+
+        /** Sets the identity type for the presence credential. */
+        @NonNull
+        public Builder setIdentityType(@IdentityType int identityType) {
+            mIdentityType = identityType;
+            return this;
+        }
+
+        /** Adds an element to the credential. */
+        @NonNull
+        public Builder addCredentialElement(@NonNull CredentialElement credentialElement) {
+            Objects.requireNonNull(credentialElement);
+            mCredentialElements.add(credentialElement);
+            return this;
+        }
+
+        /** Builds the {@link PresenceCredential}. */
+        @NonNull
+        public PublicCredential build() {
+            return new PublicCredential(
+                    mIdentityType,
+                    mSecretId,
+                    mAuthenticityKey,
+                    mCredentialElements,
+                    mPublicKey,
+                    mEncryptedMetadata,
+                    mEncryptedMetadataKeyTag);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/ScanCallback.java b/nearby/framework/java/android/nearby/ScanCallback.java
new file mode 100644
index 0000000..1b1b4bc
--- /dev/null
+++ b/nearby/framework/java/android/nearby/ScanCallback.java
@@ -0,0 +1,54 @@
+/*
+ * 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 android.nearby;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Reports newly discovered devices.
+ * Note: The frequency of the callback is dependent on whether the caller
+ * is in the foreground or background. Foreground callbacks will occur
+ * as fast as the underlying medium supports, whereas background
+ * use cases will be rate limited to improve performance (ie, only on
+ * found/lost/significant changes).
+ *
+ * @hide
+ */
+@SystemApi
+public interface ScanCallback {
+    /**
+     * Reports a {@link NearbyDevice} being discovered.
+     *
+     * @param device {@link NearbyDevice} that is found.
+     */
+    void onDiscovered(@NonNull NearbyDevice device);
+
+    /**
+     * Reports a {@link NearbyDevice} information(distance, packet, and etc) changed.
+     *
+     * @param device {@link NearbyDevice} that has updates.
+     */
+    void onUpdated(@NonNull NearbyDevice device);
+
+    /**
+     * Reports a {@link NearbyDevice} is no longer within range.
+     *
+     * @param device {@link NearbyDevice} that is lost.
+     */
+    void onLost(@NonNull NearbyDevice device);
+}
diff --git a/nearby/framework/java/android/nearby/ScanFilter.java b/nearby/framework/java/android/nearby/ScanFilter.java
new file mode 100644
index 0000000..1409426
--- /dev/null
+++ b/nearby/framework/java/android/nearby/ScanFilter.java
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+
+/**
+ * Filter for scanning a nearby device.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class ScanFilter {
+    /**
+     * Creates a {@link ScanFilter} from the parcel.
+     *
+     * @hide
+     */
+    public static ScanFilter createFromParcel(Parcel in) {
+        int type = in.readInt();
+        switch (type) {
+            // Currently, only Nearby Presence filtering is supported, in the future
+            // filtering other nearby specifications will be added.
+            case ScanRequest.SCAN_TYPE_NEARBY_PRESENCE:
+                return PresenceScanFilter.createFromParcelBody(in);
+            default:
+                throw new IllegalStateException(
+                        "Unexpected scan type (value " + type + ") in parcel.");
+        }
+    }
+
+    private final @ScanRequest.ScanType int mType;
+    private final int mMaxPathLoss;
+
+    /**
+     * Constructs a Scan Filter.
+     *
+     * @hide
+     */
+    ScanFilter(@ScanRequest.ScanType int type, @IntRange(from = 0, to = 127) int maxPathLoss) {
+        mType = type;
+        mMaxPathLoss = maxPathLoss;
+    }
+
+    /**
+     * Constructs a Scan Filter.
+     *
+     * @hide
+     */
+    ScanFilter(@ScanRequest.ScanType int type, Parcel in) {
+        mType = type;
+        mMaxPathLoss = in.readInt();
+    }
+
+    /**
+     * Returns the type of this scan filter.
+     */
+    public @ScanRequest.ScanType int getType() {
+        return mType;
+    }
+
+    /**
+     * Returns the maximum path loss (in dBm) of the received scan result. The path loss is the
+     * attenuation of radio energy between sender and receiver. Path loss here is defined as
+     * (TxPower - Rssi).
+     */
+    @IntRange(from = 0, to = 127)
+    public int getMaxPathLoss() {
+        return mMaxPathLoss;
+    }
+
+    /**
+     *
+     * Writes the scan filter to the parcel.
+     *
+     * @hide
+     */
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mType);
+        dest.writeInt(mMaxPathLoss);
+    }
+}
diff --git a/nearby/framework/java/android/nearby/ScanRequest.aidl b/nearby/framework/java/android/nearby/ScanRequest.aidl
new file mode 100644
index 0000000..438dfed
--- /dev/null
+++ b/nearby/framework/java/android/nearby/ScanRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.nearby;
+
+parcelable ScanRequest;
diff --git a/nearby/framework/java/android/nearby/ScanRequest.java b/nearby/framework/java/android/nearby/ScanRequest.java
new file mode 100644
index 0000000..a90b72d
--- /dev/null
+++ b/nearby/framework/java/android/nearby/ScanRequest.java
@@ -0,0 +1,366 @@
+/*
+ * 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 android.nearby;
+
+import android.Manifest;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.WorkSource;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * An encapsulation of various parameters for requesting nearby scans.
+ *
+ * @hide
+ */
+@SystemApi
+public final class ScanRequest implements Parcelable {
+
+    /** Scan type for scanning devices using fast pair protocol. */
+    public static final int SCAN_TYPE_FAST_PAIR = 1;
+    /** Scan type for scanning devices using nearby share protocol. */
+    public static final int SCAN_TYPE_NEARBY_SHARE = 2;
+    /** Scan type for scanning devices using nearby presence protocol. */
+    public static final int SCAN_TYPE_NEARBY_PRESENCE = 3;
+    /** Scan type for scanning devices using exposure notification protocol. */
+    public static final int SCAN_TYPE_EXPOSURE_NOTIFICATION = 4;
+
+    /** Scan mode uses highest duty cycle. */
+    public static final int SCAN_MODE_LOW_LATENCY = 2;
+    /** Scan in balanced power mode.
+     *  Scan results are returned at a rate that provides a good trade-off between scan
+     *  frequency and power consumption.
+     */
+    public static final int SCAN_MODE_BALANCED = 1;
+    /** Perform scan in low power mode. This is the default scan mode. */
+    public static final int SCAN_MODE_LOW_POWER = 0;
+    /**
+     * A special scan mode. Applications using this scan mode will passively listen for other scan
+     * results without starting BLE scans themselves.
+     */
+    public static final int SCAN_MODE_NO_POWER = -1;
+    /**
+     * Used to read a ScanRequest from a Parcel.
+     */
+    @NonNull
+    public static final Creator<ScanRequest> CREATOR = new Creator<ScanRequest>() {
+        @Override
+        public ScanRequest createFromParcel(Parcel in) {
+            ScanRequest.Builder builder = new ScanRequest.Builder()
+                    .setScanType(in.readInt())
+                    .setScanMode(in.readInt())
+                    .setBleEnabled(in.readBoolean())
+                    .setWorkSource(in.readTypedObject(WorkSource.CREATOR));
+            for (int i = 0; i < in.readInt(); i++) {
+                builder.addScanFilter(ScanFilter.createFromParcel(in));
+            }
+            return builder.build();
+        }
+
+        @Override
+        public ScanRequest[] newArray(int size) {
+            return new ScanRequest[size];
+        }
+    };
+
+    private final @ScanType int mScanType;
+    private final @ScanMode int mScanMode;
+    private final boolean mBleEnabled;
+    private final @NonNull WorkSource mWorkSource;
+    private final List<ScanFilter> mScanFilters;
+
+    private ScanRequest(@ScanType int scanType, @ScanMode int scanMode, boolean bleEnabled,
+            @NonNull WorkSource workSource, List<ScanFilter> scanFilters) {
+        mScanType = scanType;
+        mScanMode = scanMode;
+        mBleEnabled = bleEnabled;
+        mWorkSource = workSource;
+        mScanFilters = scanFilters;
+    }
+
+    /**
+     * Convert scan mode to readable string.
+     *
+     * @param scanMode Integer that may represent a{@link ScanMode}.
+     */
+    @NonNull
+    public static String scanModeToString(@ScanMode int scanMode) {
+        switch (scanMode) {
+            case SCAN_MODE_LOW_LATENCY:
+                return "SCAN_MODE_LOW_LATENCY";
+            case SCAN_MODE_BALANCED:
+                return "SCAN_MODE_BALANCED";
+            case SCAN_MODE_LOW_POWER:
+                return "SCAN_MODE_LOW_POWER";
+            case SCAN_MODE_NO_POWER:
+                return "SCAN_MODE_NO_POWER";
+            default:
+                return "SCAN_MODE_INVALID";
+        }
+    }
+
+    /**
+     * Returns true if an integer is a defined scan type.
+     */
+    public static boolean isValidScanType(@ScanType int scanType) {
+        return scanType == SCAN_TYPE_FAST_PAIR
+                || scanType == SCAN_TYPE_NEARBY_SHARE
+                || scanType == SCAN_TYPE_NEARBY_PRESENCE
+                || scanType == SCAN_TYPE_EXPOSURE_NOTIFICATION;
+    }
+
+    /**
+     * Returns true if an integer is a defined scan mode.
+     */
+    public static boolean isValidScanMode(@ScanMode int scanMode) {
+        return scanMode == SCAN_MODE_LOW_LATENCY
+                || scanMode == SCAN_MODE_BALANCED
+                || scanMode == SCAN_MODE_LOW_POWER
+                || scanMode == SCAN_MODE_NO_POWER;
+    }
+
+    /**
+     * Returns the scan type for this request.
+     */
+    public @ScanType int getScanType() {
+        return mScanType;
+    }
+
+    /**
+     * Returns the scan mode for this request.
+     */
+    public @ScanMode int getScanMode() {
+        return mScanMode;
+    }
+
+    /**
+     * Returns if Bluetooth Low Energy enabled for scanning.
+     */
+    public boolean isBleEnabled() {
+        return mBleEnabled;
+    }
+
+    /**
+     * Returns Scan Filters for this request.
+     */
+    @NonNull
+    public List<ScanFilter> getScanFilters() {
+        return mScanFilters;
+    }
+
+    /**
+     * Returns the work source used for power attribution of this request.
+     *
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    public WorkSource getWorkSource() {
+        return mWorkSource;
+    }
+
+    /**
+     * No special parcel contents.
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Returns a string representation of this ScanRequest.
+     */
+    @Override
+    public String toString() {
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("Request[")
+                .append("scanType=").append(mScanType);
+        stringBuilder.append(", scanMode=").append(scanModeToString(mScanMode));
+        stringBuilder.append(", enableBle=").append(mBleEnabled);
+        stringBuilder.append(", workSource=").append(mWorkSource);
+        stringBuilder.append(", scanFilters=").append(mScanFilters);
+        stringBuilder.append("]");
+        return stringBuilder.toString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mScanType);
+        dest.writeInt(mScanMode);
+        dest.writeBoolean(mBleEnabled);
+        dest.writeTypedObject(mWorkSource, /* parcelableFlags= */0);
+        dest.writeInt(mScanFilters.size());
+        for (int i = 0; i < mScanFilters.size(); ++i) {
+            mScanFilters.get(i).writeToParcel(dest, flags);
+        }
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof ScanRequest) {
+            ScanRequest otherRequest = (ScanRequest) other;
+            return mScanType == otherRequest.mScanType
+                    && (mScanMode == otherRequest.mScanMode)
+                    && (mBleEnabled == otherRequest.mBleEnabled)
+                    && (Objects.equals(mWorkSource, otherRequest.mWorkSource));
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mScanType, mScanMode, mBleEnabled, mWorkSource);
+    }
+
+    /** @hide **/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({SCAN_TYPE_FAST_PAIR, SCAN_TYPE_NEARBY_SHARE, SCAN_TYPE_NEARBY_PRESENCE,
+            SCAN_TYPE_EXPOSURE_NOTIFICATION})
+    public @interface ScanType {
+    }
+
+    /** @hide **/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({SCAN_MODE_LOW_LATENCY, SCAN_MODE_BALANCED,
+            SCAN_MODE_LOW_POWER,
+            SCAN_MODE_NO_POWER})
+    public @interface ScanMode {}
+
+    /** A builder class for {@link ScanRequest}. */
+    public static final class Builder {
+        private static final int INVALID_SCAN_TYPE = -1;
+        private @ScanType int mScanType;
+        private @ScanMode int mScanMode;
+
+        private boolean mBleEnabled;
+        private WorkSource mWorkSource;
+        private List<ScanFilter> mScanFilters;
+
+        /** Creates a new Builder with the given scan type. */
+        public Builder() {
+            mScanType = INVALID_SCAN_TYPE;
+            mBleEnabled = true;
+            mWorkSource = new WorkSource();
+            mScanFilters = new ArrayList<>();
+        }
+
+        /**
+         * Sets the scan type for the request. The scan type must be one of the SCAN_TYPE_ constants
+         * in {@link ScanRequest}.
+         *
+         * @param scanType The scan type for the request
+         */
+        @NonNull
+        public Builder setScanType(@ScanType int scanType) {
+            mScanType = scanType;
+            return this;
+        }
+
+        /**
+         * Sets the scan mode for the request. The scan type must be one of the SCAN_MODE_ constants
+         * in {@link ScanRequest}.
+         *
+         * @param scanMode The scan mode for the request
+         */
+        @NonNull
+        public Builder setScanMode(@ScanMode int scanMode) {
+            mScanMode = scanMode;
+            return this;
+        }
+
+        /**
+         * Sets if the ble is enabled for scanning.
+         *
+         * @param bleEnabled If the BluetoothLe is enabled in the device.
+         */
+        @NonNull
+        public Builder setBleEnabled(boolean bleEnabled) {
+            mBleEnabled = bleEnabled;
+            return this;
+        }
+
+        /**
+         * Sets the work source to use for power attribution for this scan request. Defaults to
+         * empty work source, which implies the caller that sends the scan request will be used
+         * for power attribution.
+         *
+         * <p>Permission enforcement occurs when the resulting scan request is used, not when
+         * this method is invoked.
+         *
+         * @param workSource identifying the application(s) for which to blame for the scan.
+         * @hide
+         */
+        @RequiresPermission(Manifest.permission.UPDATE_DEVICE_STATS)
+        @NonNull
+        @SystemApi
+        public Builder setWorkSource(@Nullable WorkSource workSource) {
+            if (workSource == null) {
+                mWorkSource = new WorkSource();
+            } else {
+                mWorkSource = workSource;
+            }
+            return this;
+        }
+
+        /**
+         * Adds a scan filter to the request. Client can call this method multiple times to add
+         * more than one scan filter. Scan results that match any of these scan filters will
+         * be returned.
+         *
+         * <p>On devices with hardware support, scan filters can significantly improve the battery
+         * usage of Nearby scans.
+         *
+         * @param scanFilter Filter for scanning the request.
+         */
+        @NonNull
+        public Builder addScanFilter(@NonNull ScanFilter scanFilter) {
+            Objects.requireNonNull(scanFilter);
+            mScanFilters.add(scanFilter);
+            return this;
+        }
+
+        /**
+         * Builds a scan request from this builder.
+         *
+         * @return a new nearby scan request.
+         * @throws IllegalStateException if the scanType is not one of the SCAN_TYPE_ constants in
+         *                               {@link ScanRequest}.
+         */
+        @NonNull
+        public ScanRequest build() {
+            Preconditions.checkState(isValidScanType(mScanType),
+                    "invalid scan type : " + mScanType
+                            + ", scan type must be one of ScanRequest#SCAN_TYPE_");
+            Preconditions.checkState(isValidScanMode(mScanMode),
+                    "invalid scan mode : " + mScanMode
+                            + ", scan mode must be one of ScanMode#SCAN_MODE_");
+            return new ScanRequest(mScanType, mScanMode, mBleEnabled, mWorkSource, mScanFilters);
+        }
+    }
+}
diff --git a/nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl b/nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl
new file mode 100644
index 0000000..53c73bd
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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 android.nearby.aidl;
+
+/**
+ * This is to support 2D byte arrays.
+ * {@hide}
+ */
+parcelable ByteArrayParcel {
+    byte[] byteArray;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl
new file mode 100644
index 0000000..fc3ba22
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 android.nearby.aidl;
+
+import android.accounts.Account;
+import android.nearby.aidl.ByteArrayParcel;
+
+/**
+ * Request details for Metadata of Fast Pair devices associated with an account.
+ * {@hide}
+ */
+parcelable FastPairAccountDevicesMetadataRequestParcel {
+    Account account;
+    ByteArrayParcel[] deviceAccountKeys;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairAccountKeyDeviceMetadataParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairAccountKeyDeviceMetadataParcel.aidl
new file mode 100644
index 0000000..8014323
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairAccountKeyDeviceMetadataParcel.aidl
@@ -0,0 +1,35 @@
+// 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 android.nearby.aidl;
+
+import android.nearby.aidl.FastPairDeviceMetadataParcel;
+import android.nearby.aidl.FastPairDiscoveryItemParcel;
+
+/**
+ * Metadata of a Fast Pair device associated with an account.
+ * {@hide}
+ */
+ // TODO(b/204780849): remove unnecessary fields and polish comments.
+parcelable FastPairAccountKeyDeviceMetadataParcel {
+    // Key of the Fast Pair device associated with the account.
+    byte[] deviceAccountKey;
+    // Hash function of device account key and public bluetooth address.
+    byte[] sha256DeviceAccountKeyPublicAddress;
+    // Fast Pair device metadata for the Fast Pair device.
+    FastPairDeviceMetadataParcel metadata;
+    // Fast Pair discovery item tied to both the Fast Pair device and the
+    // account.
+    FastPairDiscoveryItemParcel discoveryItem;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairAntispoofKeyDeviceMetadataParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairAntispoofKeyDeviceMetadataParcel.aidl
new file mode 100644
index 0000000..4fd4d4b
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairAntispoofKeyDeviceMetadataParcel.aidl
@@ -0,0 +1,31 @@
+// 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 android.nearby.aidl;
+
+import android.nearby.aidl.FastPairDeviceMetadataParcel;
+
+/**
+ * Metadata of a Fast Pair device keyed by AntispoofKey,
+ * Used by initial pairing without account association.
+ *
+ * {@hide}
+ */
+parcelable FastPairAntispoofKeyDeviceMetadataParcel {
+    // Anti-spoof public key.
+    byte[] antispoofPublicKey;
+
+    // Fast Pair device metadata for the Fast Pair device.
+    FastPairDeviceMetadataParcel deviceMetadata;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairAntispoofKeyDeviceMetadataRequestParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairAntispoofKeyDeviceMetadataRequestParcel.aidl
new file mode 100644
index 0000000..afdcf15
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairAntispoofKeyDeviceMetadataRequestParcel.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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 android.nearby.aidl;
+
+/**
+ * Request details for metadata of a Fast Pair device keyed by either
+ * antispoofKey or modelId.
+ * {@hide}
+ */
+parcelable FastPairAntispoofKeyDeviceMetadataRequestParcel {
+    byte[] modelId;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairDeviceMetadataParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairDeviceMetadataParcel.aidl
new file mode 100644
index 0000000..ef00321
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairDeviceMetadataParcel.aidl
@@ -0,0 +1,130 @@
+/*
+ * 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 android.nearby.aidl;
+
+/**
+ * Fast Pair Device Metadata for a given device model ID.
+ * @hide
+ */
+// TODO(b/204780849): remove unnecessary fields and polish comments.
+parcelable FastPairDeviceMetadataParcel {
+    // The image to show on the notification.
+    String imageUrl;
+
+    // The intent that will be launched via the notification.
+    String intentUri;
+
+    // The transmit power of the device's BLE chip.
+    int bleTxPower;
+
+    // The distance that the device must be within to show a notification.
+    // If no distance is set, we default to 0.6 meters. Only Nearby admins can
+    // change this.
+    float triggerDistance;
+
+    // The image icon that shows in the notification.
+    byte[] image;
+
+    // The name of the device.
+    String name;
+
+    int deviceType;
+
+    // The image urls for device with device type "true wireless".
+    String trueWirelessImageUrlLeftBud;
+    String trueWirelessImageUrlRightBud;
+    String trueWirelessImageUrlCase;
+
+    // Stings to be displayed in notification surfaced for a device.
+    // The locale of all of the Strings.
+    String locale;
+
+    // The notification description for when the device is initially discovered.
+    String initialNotificationDescription;
+
+    // The notification description for when the device is initially discovered
+    // and no account is logged in.
+    String initialNotificationDescriptionNoAccount;
+
+    // The notification description for once we have finished pairing and the
+    // companion app has been opened. For Bisto devices, this String will point
+    // users to setting up the assistant.
+    String openCompanionAppDescription;
+
+    // The notification description for once we have finished pairing and the
+    // companion app needs to be updated before use.
+    String updateCompanionAppDescription;
+
+    // The notification description for once we have finished pairing and the
+    // companion app needs to be installed.
+    String downloadCompanionAppDescription;
+
+    // The notification title when a pairing fails.
+    String unableToConnectTitle;
+
+    // The notification summary when a pairing fails.
+    String unableToConnectDescription;
+
+    // The description that helps user initially paired with device.
+    String initialPairingDescription;
+
+    // The description that let user open the companion app.
+    String connectSuccessCompanionAppInstalled;
+
+    // The description that let user download the companion app.
+    String connectSuccessCompanionAppNotInstalled;
+
+    // The description that reminds user there is a paired device nearby.
+    String subsequentPairingDescription;
+
+    // The description that reminds users opt in their device.
+    String retroactivePairingDescription;
+
+    // The description that indicates companion app is about to launch.
+    String waitLaunchCompanionAppDescription;
+
+    // The description that indicates go to bluetooth settings when connection
+    // fail.
+    String failConnectGoToSettingsDescription;
+
+    // The title of the UI to ask the user to confirm the pin code.
+    String confirmPinTitle;
+
+    // The description of the UI to ask the user to confirm the pin code.
+    String confirmPinDescription;
+
+    // The title of the UI to ask the user to confirm to sync contacts.
+    String syncContactsTitle;
+
+    // The description of the UI to ask the user to confirm to sync contacts.
+    String syncContactsDescription;
+
+    // The title of the UI to ask the user to confirm to sync SMS.
+    String syncSmsTitle;
+
+    // The description of the UI to ask the user to confirm to sync SMS.
+    String syncSmsDescription;
+
+    // The description in half sheet to ask user setup google assistant
+    String assistantSetupHalfSheet;
+
+    // The description in notification to ask user setup google assistant
+    String assistantSetupNotification;
+
+    // Description of the connect device action on TV, when user is not logged in.
+    String fastPairTvConnectDeviceNoAccountDescription;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairDiscoveryItemParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairDiscoveryItemParcel.aidl
new file mode 100644
index 0000000..5ba18bb
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairDiscoveryItemParcel.aidl
@@ -0,0 +1,126 @@
+/*
+ * 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 android.nearby.aidl;
+
+/**
+ * Fast Pair Discovery Item.
+ * @hide
+ */
+// TODO(b/204780849): remove unnecessary fields and polish comments.
+parcelable FastPairDiscoveryItemParcel {
+  // Offline item: unique ID generated on client.
+  // Online item: unique ID generated on server.
+  String id;
+
+  int type;
+
+  // The most recent all upper case mac associated with this item.
+  // (Mac-to-DiscoveryItem is a many-to-many relationship)
+  String macAddress;
+
+  String actionUrl;
+
+  // The bluetooth device name from advertisement
+  String deviceName;
+
+  // Item's title
+  String title;
+
+  // Item's description.
+  String description;
+
+  // The URL for display
+  String displayUrl;
+
+  // Client timestamp when the beacon was last observed in BLE scan.
+  long lastObservationTimestampMillis;
+
+  // Client timestamp when the beacon was first observed in BLE scan.
+  long firstObservationTimestampMillis;
+
+  // Item's current state. e.g. if the item is blocked.
+  int state;
+
+  // The resolved url type for the action_url.
+  int actionUrlType;
+
+  // The timestamp when the user is redirected to Play Store after clicking on
+  // the item.
+  long pendingAppInstallTimestampMillis;
+
+  // Beacon's RSSI value
+  int rssi;
+
+  // Beacon's tx power
+  int txPower;
+
+  // Human readable name of the app designated to open the uri
+  // Used in the second line of the notification, "Open in {} app"
+  String appName;
+
+  // ID used for associating several DiscoveryItems.  These items may be
+  // visually displayed together.
+  String groupId;
+
+  // Whether the attachment is created in debug namespace
+  int attachmentType;
+
+  // Package name of the App that owns this item.
+  String packageName;
+
+  // The "feature" graphic image url used for large sized list view entries.
+  String featureGraphicUrl;
+
+  // TriggerId identifies the trigger/beacon that is attached with a message.
+  // It's generated from server for online messages to synchronize formatting
+  // across client versions.
+  // Example:
+  // * BLE_UID: 3||deadbeef
+  // * BLE_URL: http://trigger.id
+  // See go/discovery-store-message-and-trigger-id for more details.
+  String triggerId;
+
+  // Bytes of item icon in PNG format displayed in Discovery item list.
+  byte[] iconPng;
+
+  // A FIFE URL of the item icon displayed in Discovery item list.
+  String iconFifeUrl;
+
+  // Message written to bugreport for 3P developers.(No sensitive info)
+  // null if the item is valid
+  String debugMessage;
+
+  // Weather the item is filtered out on server.
+  int debugCategory;
+
+  // Client timestamp when the trigger (e.g. beacon) was last lost (e.g. when
+  // Messages told us the beacon's no longer nearby).
+  long lostMillis;
+
+  // The kind of experience the user last had with this (e.g. if they dismissed
+  // the notification, that's bad; but if they tapped it, that's good).
+  int lastUserExperience;
+
+  // The most recent BLE advertisement related to this item.
+  byte[] bleRecordBytes;
+
+  // An ID generated on the server to uniquely identify content.
+  String entityId;
+
+  // Fast Pair antispoof key.
+  byte[] authenticationPublicKeySecp256r1;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairEligibleAccountParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairEligibleAccountParcel.aidl
new file mode 100644
index 0000000..747758d
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairEligibleAccountParcel.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 android.nearby.aidl;
+
+import android.accounts.Account;
+
+/**
+ * Fast Pair Eligible Account.
+ * {@hide}
+ */
+parcelable FastPairEligibleAccountParcel {
+    Account account;
+    // Whether the account opts in Fast Pair.
+    boolean optIn;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairEligibleAccountsRequestParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairEligibleAccountsRequestParcel.aidl
new file mode 100644
index 0000000..8db3356
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairEligibleAccountsRequestParcel.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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 android.nearby.aidl;
+
+/**
+ * Request details for Fast Pair eligible accounts.
+ * Empty place holder for future expansion.
+ * {@hide}
+ */
+parcelable FastPairEligibleAccountsRequestParcel {
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairManageAccountDeviceRequestParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairManageAccountDeviceRequestParcel.aidl
new file mode 100644
index 0000000..82cf550
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairManageAccountDeviceRequestParcel.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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 android.nearby.aidl;
+
+import android.accounts.Account;
+import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
+
+/**
+ * Request details for managing Fast Pair device-account mapping.
+ * {@hide}
+ */
+ // TODO(b/204780849): remove unnecessary fields and polish comments.
+parcelable FastPairManageAccountDeviceRequestParcel {
+    Account account;
+    // MANAGE_ACCOUNT_DEVICE_ADD: add Fast Pair device to the account.
+    // MANAGE_ACCOUNT_DEVICE_REMOVE: remove Fast Pair device from the account.
+    int requestType;
+    // Fast Pair account key-ed device metadata.
+    FastPairAccountKeyDeviceMetadataParcel accountKeyDeviceMetadata;
+    // BLE address of the device at the device add time.
+    String bleAddress;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairManageAccountRequestParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairManageAccountRequestParcel.aidl
new file mode 100644
index 0000000..3d92064
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/FastPairManageAccountRequestParcel.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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 android.nearby.aidl;
+
+import android.accounts.Account;
+
+/**
+ * Request details for managing a Fast Pair account.
+ *
+ * {@hide}
+ */
+parcelable FastPairManageAccountRequestParcel {
+    Account account;
+    // MANAGE_ACCOUNT_OPT_IN: opt account into Fast Pair.
+    // MANAGE_ACCOUNT_OPT_OUT: opt account out of Fast Pair.
+    int requestType;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/IFastPairAccountDevicesMetadataCallback.aidl b/nearby/framework/java/android/nearby/aidl/IFastPairAccountDevicesMetadataCallback.aidl
new file mode 100644
index 0000000..7db18d0
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/IFastPairAccountDevicesMetadataCallback.aidl
@@ -0,0 +1,28 @@
+// 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 android.nearby.aidl;
+
+import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
+
+/**
+  * Provides callback interface for OEMs to send back metadata of FastPair
+  * devices associated with an account.
+  *
+  * {@hide}
+  */
+interface IFastPairAccountDevicesMetadataCallback {
+     void onFastPairAccountDevicesMetadataReceived(in FastPairAccountKeyDeviceMetadataParcel[] accountDevicesMetadata);
+     void onError(int code, String message);
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/IFastPairAntispoofKeyDeviceMetadataCallback.aidl b/nearby/framework/java/android/nearby/aidl/IFastPairAntispoofKeyDeviceMetadataCallback.aidl
new file mode 100644
index 0000000..38abba4
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/IFastPairAntispoofKeyDeviceMetadataCallback.aidl
@@ -0,0 +1,27 @@
+// 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 android.nearby.aidl;
+
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataParcel;
+
+/**
+  * Provides callback interface for OEMs to send FastPair AntispoofKey Device metadata back.
+  *
+  * {@hide}
+  */
+interface IFastPairAntispoofKeyDeviceMetadataCallback {
+     void onFastPairAntispoofKeyDeviceMetadataReceived(in FastPairAntispoofKeyDeviceMetadataParcel metadata);
+     void onError(int code, String message);
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/IFastPairDataProvider.aidl b/nearby/framework/java/android/nearby/aidl/IFastPairDataProvider.aidl
new file mode 100644
index 0000000..2956211
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/IFastPairDataProvider.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.
+
+package android.nearby.aidl;
+
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataRequestParcel;
+import android.nearby.aidl.IFastPairAntispoofKeyDeviceMetadataCallback;
+import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel;
+import android.nearby.aidl.IFastPairAccountDevicesMetadataCallback;
+import android.nearby.aidl.FastPairEligibleAccountsRequestParcel;
+import android.nearby.aidl.IFastPairEligibleAccountsCallback;
+import android.nearby.aidl.FastPairManageAccountRequestParcel;
+import android.nearby.aidl.IFastPairManageAccountCallback;
+import android.nearby.aidl.FastPairManageAccountDeviceRequestParcel;
+import android.nearby.aidl.IFastPairManageAccountDeviceCallback;
+
+/**
+ * Interface for communicating with the fast pair providers.
+ *
+ * {@hide}
+ */
+oneway interface IFastPairDataProvider {
+    void loadFastPairAntispoofKeyDeviceMetadata(in FastPairAntispoofKeyDeviceMetadataRequestParcel request,
+        in IFastPairAntispoofKeyDeviceMetadataCallback callback);
+    void loadFastPairAccountDevicesMetadata(in FastPairAccountDevicesMetadataRequestParcel request,
+        in IFastPairAccountDevicesMetadataCallback callback);
+    void loadFastPairEligibleAccounts(in FastPairEligibleAccountsRequestParcel request,
+        in IFastPairEligibleAccountsCallback callback);
+    void manageFastPairAccount(in FastPairManageAccountRequestParcel request,
+        in IFastPairManageAccountCallback callback);
+    void manageFastPairAccountDevice(in FastPairManageAccountDeviceRequestParcel request,
+        in IFastPairManageAccountDeviceCallback callback);
+}
diff --git a/nearby/framework/java/android/nearby/aidl/IFastPairEligibleAccountsCallback.aidl b/nearby/framework/java/android/nearby/aidl/IFastPairEligibleAccountsCallback.aidl
new file mode 100644
index 0000000..9990014
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/IFastPairEligibleAccountsCallback.aidl
@@ -0,0 +1,28 @@
+// 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 android.nearby.aidl;
+
+import android.accounts.Account;
+import android.nearby.aidl.FastPairEligibleAccountParcel;
+
+/**
+  * Provides callback interface for OEMs to return FastPair Eligible accounts.
+  *
+  * {@hide}
+  */
+interface IFastPairEligibleAccountsCallback {
+     void onFastPairEligibleAccountsReceived(in FastPairEligibleAccountParcel[] accounts);
+     void onError(int code, String message);
+ }
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/IFastPairManageAccountCallback.aidl b/nearby/framework/java/android/nearby/aidl/IFastPairManageAccountCallback.aidl
new file mode 100644
index 0000000..6b4aaee
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/IFastPairManageAccountCallback.aidl
@@ -0,0 +1,25 @@
+// 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 android.nearby.aidl;
+
+/**
+  * Provides callback interface to send response for account management request.
+  *
+  * {@hide}
+  */
+interface IFastPairManageAccountCallback {
+     void onSuccess();
+     void onError(int code, String message);
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/IFastPairManageAccountDeviceCallback.aidl b/nearby/framework/java/android/nearby/aidl/IFastPairManageAccountDeviceCallback.aidl
new file mode 100644
index 0000000..bffc533
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/IFastPairManageAccountDeviceCallback.aidl
@@ -0,0 +1,26 @@
+// 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 android.nearby.aidl;
+
+/**
+  * Provides callback interface to send response for account-device mapping
+  * management request.
+  *
+  * {@hide}
+  */
+interface IFastPairManageAccountDeviceCallback {
+     void onSuccess();
+     void onError(int code, String message);
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/IFastPairStatusCallback.aidl b/nearby/framework/java/android/nearby/aidl/IFastPairStatusCallback.aidl
new file mode 100644
index 0000000..d844c06
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/IFastPairStatusCallback.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package android.nearby.aidl;
+
+import android.nearby.FastPairDevice;
+import android.nearby.PairStatusMetadata;
+
+/**
+ *
+ * Provides callbacks for Fast Pair foreground activity to learn about paring status from backend.
+ *
+ * {@hide}
+ */
+interface IFastPairStatusCallback {
+
+    /** Reports a pair status related metadata associated with a {@link FastPairDevice} */
+    void onPairUpdate(in FastPairDevice fastPairDevice, in PairStatusMetadata pairStatusMetadata);
+}
diff --git a/nearby/framework/java/android/nearby/aidl/IFastPairUiService.aidl b/nearby/framework/java/android/nearby/aidl/IFastPairUiService.aidl
new file mode 100644
index 0000000..9200a9d
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/IFastPairUiService.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package android.nearby.aidl;
+
+import android.nearby.aidl.IFastPairStatusCallback;
+import android.nearby.FastPairDevice;
+
+/**
+ * 0p API for controlling Fast Pair. Used to talk between foreground activities
+ * and background services.
+ *
+ * {@hide}
+ */
+interface IFastPairUiService {
+
+    void registerCallback(in IFastPairStatusCallback fastPairStatusCallback);
+
+    void unregisterCallback(in IFastPairStatusCallback fastPairStatusCallback);
+
+    void connect(in FastPairDevice fastPairDevice);
+
+    void cancel(in FastPairDevice fastPairDevice);
+}
\ No newline at end of file
diff --git a/nearby/halfsheet/Android.bp b/nearby/halfsheet/Android.bp
new file mode 100644
index 0000000..486a3ff
--- /dev/null
+++ b/nearby/halfsheet/Android.bp
@@ -0,0 +1,57 @@
+// 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_app {
+    name: "HalfSheetUX",
+    defaults: ["platform_app_defaults"],
+    srcs: ["src/**/*.java"],
+    sdk_version: "module_current",
+    // This is included in tethering apex, which uses min SDK 30
+    min_sdk_version: "30",
+    target_sdk_version: "current",
+    updatable: true,
+    certificate: ":com.android.nearby.halfsheetcertificate",
+    libs: [
+        "framework-bluetooth",
+        "framework-connectivity-t",
+        "nearby-service-string",
+    ],
+    static_libs: [
+        "androidx.annotation_annotation",
+        "androidx.fragment_fragment",
+        "androidx-constraintlayout_constraintlayout",
+        "androidx.localbroadcastmanager_localbroadcastmanager",
+        "androidx.core_core",
+        "androidx.appcompat_appcompat",
+        "androidx.recyclerview_recyclerview",
+        "androidx.lifecycle_lifecycle-runtime",
+        "androidx.lifecycle_lifecycle-extensions",
+        "com.google.android.material_material",
+        "fast-pair-lite-protos",
+    ],
+    plugins: ["java_api_finder"],
+    manifest: "AndroidManifest.xml",
+    jarjar_rules: ":nearby-jarjar-rules",
+    apex_available: ["com.android.tethering",],
+    lint: { strict_updatability_linting: true }
+}
+
+android_app_certificate {
+    name: "com.android.nearby.halfsheetcertificate",
+    certificate: "apk-certs/com.android.nearby.halfsheet"
+}
diff --git a/nearby/halfsheet/AndroidManifest.xml b/nearby/halfsheet/AndroidManifest.xml
new file mode 100644
index 0000000..22987fb
--- /dev/null
+++ b/nearby/halfsheet/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.nearby.halfsheet">
+    <application>
+        <activity
+            android:name="com.android.nearby.halfsheet.HalfSheetActivity"
+            android:exported="true"
+            android:launchMode="singleInstance"
+            android:theme="@style/HalfSheetStyle" >
+            <intent-filter>
+                <action android:name="android.nearby.SHOW_HALFSHEET"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/nearby/halfsheet/apk-certs/com.android.nearby.halfsheet.pk8 b/nearby/halfsheet/apk-certs/com.android.nearby.halfsheet.pk8
new file mode 100644
index 0000000..187d51e
--- /dev/null
+++ b/nearby/halfsheet/apk-certs/com.android.nearby.halfsheet.pk8
Binary files differ
diff --git a/nearby/halfsheet/apk-certs/com.android.nearby.halfsheet.x509.pem b/nearby/halfsheet/apk-certs/com.android.nearby.halfsheet.x509.pem
new file mode 100644
index 0000000..440c524
--- /dev/null
+++ b/nearby/halfsheet/apk-certs/com.android.nearby.halfsheet.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF6zCCA9OgAwIBAgIUU5ATKevcNA5ZSurwgwGenwrr4c4wDQYJKoZIhvcNAQEL
+BQAwgYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQwwCgYDVQQH
+DANNVFYxDzANBgNVBAoMBkdvb2dsZTEPMA0GA1UECwwGbmVhcmJ5MQswCQYDVQQD
+DAJ3czEiMCAGCSqGSIb3DQEJARYTd2VpY2VzdW5AZ29vZ2xlLmNvbTAgFw0yMTEy
+MDgwMTMxMzFaGA80NzU5MTEwNDAxMzEzMVowgYMxCzAJBgNVBAYTAlVTMRMwEQYD
+VQQIDApDYWxpZm9ybmlhMQwwCgYDVQQHDANNVFYxDzANBgNVBAoMBkdvb2dsZTEP
+MA0GA1UECwwGbmVhcmJ5MQswCQYDVQQDDAJ3czEiMCAGCSqGSIb3DQEJARYTd2Vp
+Y2VzdW5AZ29vZ2xlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+AO0JW1YZ5bKHZG5B9eputz3kGREmXcWZ97dg/ODDs3+op4ulBmgaYeo5yeCy29GI
+Sjgxo4G+9fNZ7Fejrk5/LLWovAoRvVxnkRxCkTfp15jZpKNnZjT2iTRLXzNz2O04
+cC0jB81mu5vJ9a8pt+EQkuSwjDMiUi6q4Sf6IRxtTCd5a1yn9eHf1y2BbCmU+Eys
+bs97HJl9PgMCp7hP+dYDxEtNTAESg5IpJ1i7uINgPNl8d0tvJ9rOEdy0IcdeGwt/
+t0L9fIoRCePttH+idKIyDjcNyp9WtX2/wZKlsGap83rGzLdL2PI4DYJ2Ytmy8W3a
+9qFJNrhl3Q3BYgPlcCg9qQOIKq6ZJgFFH3snVDKvtSFd8b9ofK7UzD5g2SllTqDA
+4YvrdK4GETQunSjG7AC/2PpvN/FdhHm7pBi0fkgwykMh35gv0h8mmb6pBISYgr85
++GMBilNiNJ4G6j3cdOa72pvfDW5qn5dn5ks8cIgW2X1uF/GT8rR6Mb2rwhjY9eXk
+TaP0RykyzheMY/7dWeA/PdN3uMCEJEt72ZakDIswgQVPCIw8KQPIf6pl0d5hcLSV
+QzhqBaXudseVg0QlZ86iaobpZvCrW0KqQmMU5GVhEtDc2sPe5e+TCmUC/H+vo8F8
+1UYu3MJaBcpePFlgIsLhW0niUTfCq2FiNrPykOJT7U9NAgMBAAGjUzBRMB0GA1Ud
+DgQWBBQKSepRcKTv9hr8mmKjYCL7NeG2izAfBgNVHSMEGDAWgBQKSepRcKTv9hr8
+mmKjYCL7NeG2izAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQC/
+BoItafzvjYPzENY16BIkgRqJVU7IosWxGLczzg19NFu6HPa54alqkawp7RI1ZNVH
+bJjQma5ap0L+Y06/peIU9rvEtfbCkkYJwvIaSRlTlzrNwNEcj3yJMmGTr/wfIzq8
+PN1t0hihnqI8ZguOPC+sV6ARoC+ygkwaLU1oPbVvOGz9WplvSokE1mvtqKAyuDoL
+LZfWwbhxRAgwgCIEz6cPfEcgg3Xzc+L4OzmNhTTc7GNOAtvvW7Zqc2Lohb8nQMNw
+uY65yiHPNmjmc+xLHZk3jQg82tKv792JJRkVXPsIfQV087IzxFFjjvKy82rVfeaN
+F9g2EpUvdjtm8zx7K5tiDv9Es/Up7oOnoB5baLgnMAEVMTZY+4k/6BfVM5CVUu+H
+AO1yh2yeNWbzY8B+zxRef3C2Ax68lJHFyz8J1pfrGpWxML3rDmWiVDMtEk73t3g+
+lcyLYo7OW+iBn6BODRcINO4R640oyMjFz2wPSPAsU0Zj/MbgC6iaS+goS3QnyPQS
+O3hKWfwqQuA7BZ0la1n+plKH5PKxQESAbd37arzCsgQuktl33ONiwYOt6eUyHl/S
+E3ZdldkmGm9z0mcBYG9NczDBSYmtuZOGjEzIRqI5GFD2WixE+dqTzVP/kyBd4BLc
+OTmBynN/8D/qdUZNrT+tgs+mH/I2SsKYW9Zymwf7Qw==
+-----END CERTIFICATE-----
diff --git a/nearby/halfsheet/apk-certs/key.pem b/nearby/halfsheet/apk-certs/key.pem
new file mode 100644
index 0000000..e9f4288
--- /dev/null
+++ b/nearby/halfsheet/apk-certs/key.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDtCVtWGeWyh2Ru
+QfXqbrc95BkRJl3Fmfe3YPzgw7N/qKeLpQZoGmHqOcngstvRiEo4MaOBvvXzWexX
+o65Ofyy1qLwKEb1cZ5EcQpE36deY2aSjZ2Y09ok0S18zc9jtOHAtIwfNZrubyfWv
+KbfhEJLksIwzIlIuquEn+iEcbUwneWtcp/Xh39ctgWwplPhMrG7PexyZfT4DAqe4
+T/nWA8RLTUwBEoOSKSdYu7iDYDzZfHdLbyfazhHctCHHXhsLf7dC/XyKEQnj7bR/
+onSiMg43DcqfVrV9v8GSpbBmqfN6xsy3S9jyOA2CdmLZsvFt2vahSTa4Zd0NwWID
+5XAoPakDiCqumSYBRR97J1Qyr7UhXfG/aHyu1Mw+YNkpZU6gwOGL63SuBhE0Lp0o
+xuwAv9j6bzfxXYR5u6QYtH5IMMpDId+YL9IfJpm+qQSEmIK/OfhjAYpTYjSeBuo9
+3HTmu9qb3w1uap+XZ+ZLPHCIFtl9bhfxk/K0ejG9q8IY2PXl5E2j9EcpMs4XjGP+
+3VngPz3Td7jAhCRLe9mWpAyLMIEFTwiMPCkDyH+qZdHeYXC0lUM4agWl7nbHlYNE
+JWfOomqG6Wbwq1tCqkJjFORlYRLQ3NrD3uXvkwplAvx/r6PBfNVGLtzCWgXKXjxZ
+YCLC4VtJ4lE3wqthYjaz8pDiU+1PTQIDAQABAoICAQCt4R5CM+8enlka1IIbvann
+2cpVnUpOaNqhh6EZFBY5gDOfqafgd/H5yvh/P1UnCI5BWJBz3ew33nAT/fsglAPt
+ImEGFetNvJ9jFqXGWWCRPJ6cS35bPbp6RQwKB2JK6grH4ZmYoFLhPi5elwDPNcQ7
+xBKkc/nLSAiwtbjSTI7/qf8K0h752aTUOctpWWEnhZon00ywf4Ic3TbBatF/n/W/
+s20coEMp1cyKN/JrVQ5uD/LGwDyBModB2lWpFSxLrB14I9DWyxbxP28X7ckXLhbl
+ZdWMOyQZoa/S7n5PYT49g1Wq5BW54UpvuH5c6fpWtrgSqk1cyUR2EbTf3NAAhPLU
+PgPK8wbFMcMB3TpQDXl7USA7QX5wSv22OfhivPsHQ9szGM0f84mK0PhXYPWBiNUY
+Y8rrIjOijB4eFGDFnTIMTofAb07NxRThci710BYUqgBVTBG5N+avIesjwkikMjOI
+PwYukKSQSw/Tqxy5Z9l22xksGynBZFjEFs/WT5pDczPAktA4xW3CGxjkMsIYaOBs
+OCEujqc5+mHSywYvy8aN+nA+yPucJP5e5pLZ1qaU0tqyakCx8XeeOyP6Wfm3UAAV
+AYelBRcWcJxM51w4o5UnUnpBD+Uxiz1sRVlqa9bLJjP4M+wJNL+WaIn9D6WhPOvl
++naDC+p29ou2JzyKFDsOQQKCAQEA+Jalm+xAAPc+t/gCdAqEDo0NMA2/NG8m9BRc
+CVZRRaWVyGPeg5ziT/7caGwy2jpOZEjK0OOTCAqF+sJRDj6DDIw7nDrlxNyaXnCF
+gguQHFIYaHcjKGTs5l0vgL3H7pMFHN2qVynf4xrTuBXyT1GJ4vdWKAJbooa02c8W
+XI2fjwZ7Y8wSWrm1tn3oTTBR3N6o1GyPY6/TrL0mhpWwgx5eJeLl3GuUxOhXY5R9
+y48ziS97Dqdq75MxUOHickofCNcm7p+jA8Hg+SxLMR/kUFsXOxawmvsBqdL1XzU5
+LTS7xAEY9iMuBcO6yIxcxqBx96idjsPXx1lgARo1CpaZYCzgPQKCAQEA9BqKMN/Y
+o+T+ac99St8x3TYkk5lkvLVqlPw+EQhEqrm9EEBPntxWM5FEIpPVmFm7taGTgPfN
+KKaaNxX5XyK9B2v1QqN7XrX0nF4+6x7ao64fdpRUParIuBVctqzQWWthme66eHrf
+L86T/tkt3o/7p+Hd4Z9UT3FaAew1ggWr00xz5PJ/4b3f3mRmtNmgeTYskWMxOpSj
+bEenom4Row7sfLNeXNSWDGlzJ/lf6svvbVM2X5h2uFsxlt/Frq9ooTA3wwhnbd1i
+cFifDQ6cxF5mBpz/V/hnlHVfuXlknEZa9EQXHNo/aC9y+bR+ai05FJyK/WgqleW8
+5PBmoTReWA2MUQKCAQAnnnLkh+GnhcBEN83ESszDOO3KI9a+d5yguAH3Jv+q9voJ
+Rwl2tnFHSJo+NkhgiXxm9UcFxc9wL6Us0v1yJLpkLJFvk9984Z/kv1A36rncGaV0
+ONCspnEvQdjJTvXnax0cfaOhYrYhDuyBYVYOGDO+rabYl4+dNpTqRdwNgjDU7baK
+sEKYnRJ99FEqxDG33vDPckHkJGi7FiZmusK4EwX0SdZSq/6450LORyNJZxhSm/Oj
+4UDkz/PDLU0W5ANQOGInE+A6QBMoA0w0lx2fRPVN4I7jFHAubcXXl7b2InpugbJF
+wFOcbZZ+UgiTS4z+aKw7zbC9P9xSMKgVeO0W6/ANAoIBABe0LA8q7YKczgfAWk5W
+9iShCVQ75QheJYdqJyzIPMLHXpChbhnjE4vWY2NoL6mnrQ6qLgSsC4QTCY6n15th
+aDG8Tgi2j1hXGvXEQR/b0ydp1SxSowuJ9gvKJ0Kl7WWBg+zKvdjNNbcSvFRXCpk+
+KhXXXRB3xFwiibb+FQQXQOQ33FkzIy/snDygS0jsiSS8Gf/UPgeOP4BYRPME9Tl8
+TYKeeF9TVW7HHqOXF7VZMFrRZcpKp9ynHl2kRTH9Xo+oewG5YzHL+a8nK+q8rIR1
+Fjs2K6WDPauw6ia8nwR94H8vzX7Dwrx/Pw74c/4jfhN+UBDjeJ8tu/YPUif9SdwL
+FMECggEALdCGKfQ4vPmqI6UdfVB5hdCPoM6tUsI2yrXFvlHjSGVanC/IG9x2mpRb
+4odamLYx4G4NjP1IJSY08LFT9VhLZtRM1W3fGeboW12LTEVNrI3lRBU84rAQ1ced
+l6/DvTKJjhfwTxb/W7sqmZY5hF3QuNxs67Z8x0pe4b58musa0qFCs4Sa8qTNZKRW
+fIbxIKuvu1HSNOKkZLu6Gq8km+XIlVAaSVA03Tt+EK74MFL6+pcd7/VkS00MAYUC
+gS4ic+QFzCl5P8zl/GoX8iUFsRZQCSJkZ75VwO13pEupVwCAW8WWJO83U4jBsnJs
+ayrX7pbsnW6jsNYBUlck+RYVYkVkxA==
+-----END PRIVATE KEY-----
diff --git a/nearby/halfsheet/res/anim/fast_pair_bottom_sheet_enter.xml b/nearby/halfsheet/res/anim/fast_pair_bottom_sheet_enter.xml
new file mode 100644
index 0000000..098dccb
--- /dev/null
+++ b/nearby/halfsheet/res/anim/fast_pair_bottom_sheet_enter.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:interpolator="@android:interpolator/decelerate_quint">
+    <translate android:fromYDelta="100%"
+               android:toYDelta="0"
+               android:duration="900"/>
+</set>
diff --git a/nearby/halfsheet/res/anim/fast_pair_bottom_sheet_exit.xml b/nearby/halfsheet/res/anim/fast_pair_bottom_sheet_exit.xml
new file mode 100644
index 0000000..1cf7401
--- /dev/null
+++ b/nearby/halfsheet/res/anim/fast_pair_bottom_sheet_exit.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:interpolator="@android:interpolator/decelerate_quint">
+    <translate android:fromYDelta="0"
+               android:toYDelta="100%"
+               android:duration="500"/>
+</set>
diff --git a/nearby/halfsheet/res/anim/fast_pair_half_sheet_slide_in.xml b/nearby/halfsheet/res/anim/fast_pair_half_sheet_slide_in.xml
new file mode 100644
index 0000000..9a51ddb
--- /dev/null
+++ b/nearby/halfsheet/res/anim/fast_pair_half_sheet_slide_in.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:targetApi="23"
+    android:duration="@integer/half_sheet_slide_in_duration"
+    android:interpolator="@android:interpolator/fast_out_slow_in">
+  <translate
+      android:fromYDelta="100%p"
+      android:toYDelta="0%p"/>
+
+  <alpha
+      android:fromAlpha="0.0"
+      android:toAlpha="1.0"/>
+</set>
diff --git a/nearby/halfsheet/res/anim/fast_pair_half_sheet_slide_out.xml b/nearby/halfsheet/res/anim/fast_pair_half_sheet_slide_out.xml
new file mode 100644
index 0000000..c589482
--- /dev/null
+++ b/nearby/halfsheet/res/anim/fast_pair_half_sheet_slide_out.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:duration="@integer/half_sheet_fade_out_duration"
+    android:interpolator="@android:interpolator/fast_out_slow_in">
+
+  <translate
+      android:fromYDelta="0%p"
+      android:toYDelta="100%p"/>
+
+  <alpha
+      android:fromAlpha="1.0"
+      android:toAlpha="0.0"/>
+
+</set>
diff --git a/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml b/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml
new file mode 100644
index 0000000..7d61d1c
--- /dev/null
+++ b/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ 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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="@color/fast_pair_half_sheet_subtitle_color">
+    <path
+        android:fillColor="@color/fast_pair_half_sheet_subtitle_color"
+        android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
+</vector>
\ No newline at end of file
diff --git a/nearby/halfsheet/res/drawable/fastpair_outline.xml b/nearby/halfsheet/res/drawable/fastpair_outline.xml
new file mode 100644
index 0000000..6765e11
--- /dev/null
+++ b/nearby/halfsheet/res/drawable/fastpair_outline.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+  <stroke
+      android:width="1dp"
+      android:color="@color/fast_pair_notification_image_outline"/>
+</shape>
diff --git a/nearby/halfsheet/res/drawable/half_sheet_bg.xml b/nearby/halfsheet/res/drawable/half_sheet_bg.xml
new file mode 100644
index 0000000..7e7d8dd
--- /dev/null
+++ b/nearby/halfsheet/res/drawable/half_sheet_bg.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:targetApi="23">
+  <solid android:color="@color/fast_pair_half_sheet_background" />
+  <corners
+      android:topLeftRadius="16dp"
+      android:topRightRadius="16dp"
+      android:padding="8dp"/>
+</shape>
diff --git a/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml b/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml
new file mode 100644
index 0000000..7fbe229
--- /dev/null
+++ b/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    tools:ignore="RtlCompat"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+  <androidx.constraintlayout.widget.ConstraintLayout
+      android:id="@+id/image_view"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:minHeight="340dp"
+      android:paddingStart="12dp"
+      android:paddingEnd="12dp"
+      android:paddingTop="12dp"
+      android:paddingBottom="12dp">
+    <TextView
+        android:id="@+id/header_subtitle"
+        android:textColor="@color/fast_pair_half_sheet_subtitle_color"
+        android:fontFamily="google-sans"
+        android:textSize="14sp"
+        android:maxLines="3"
+        android:gravity="center"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent" />
+
+    <ImageView
+        android:id="@+id/pairing_pic"
+        android:layout_width="@dimen/fast_pair_half_sheet_image_size"
+        android:layout_height="@dimen/fast_pair_half_sheet_image_size"
+        android:paddingTop="18dp"
+        android:paddingBottom="18dp"
+        android:importantForAccessibility="no"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/header_subtitle" />
+
+    <TextView
+        android:id="@+id/pin_code"
+        android:textColor="@color/fast_pair_half_sheet_subtitle_color"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/fast_pair_half_sheet_image_size"
+        android:paddingTop="18dp"
+        android:paddingBottom="18dp"
+        android:visibility="invisible"
+        android:textSize="50sp"
+        android:letterSpacing="0.2"
+        android:fontFamily="google-sans-medium"
+        android:gravity="center"
+        android:importantForAccessibility="yes"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/header_subtitle" />
+
+    <ProgressBar
+        android:id="@+id/connect_progressbar"
+        android:layout_width="@dimen/fast_pair_half_sheet_image_size"
+        android:layout_height="2dp"
+        android:indeterminate="true"
+        android:indeterminateTint="@color/fast_pair_progress_color"
+        android:indeterminateTintMode="src_in"
+        style="?android:attr/progressBarStyleHorizontal"
+        android:layout_marginBottom="6dp"
+        app:layout_constraintTop_toBottomOf="@+id/pairing_pic"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"/>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toBottomOf="@+id/connect_progressbar"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent">
+
+      <ImageView
+          android:id="@+id/info_icon"
+          android:layout_width="24dp"
+          android:layout_height="24dp"
+          app:srcCompat="@drawable/fast_pair_ic_info"
+          android:layout_centerInParent="true"
+          android:contentDescription="@null"
+          android:layout_marginEnd="10dp"
+          android:layout_toStartOf="@id/connect_btn"
+          android:visibility="invisible" />
+
+      <com.google.android.material.button.MaterialButton
+          android:id="@+id/connect_btn"
+          android:layout_width="@dimen/fast_pair_half_sheet_image_size"
+          android:layout_height="wrap_content"
+          android:text="@string/paring_action_connect"
+          android:layout_centerInParent="true"
+          style="@style/HalfSheetButton" />
+
+    </RelativeLayout>
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/settings_btn"
+        android:text="@string/paring_action_settings"
+        android:layout_height="wrap_content"
+        android:layout_width="@dimen/fast_pair_half_sheet_image_size"
+        app:layout_constraintTop_toBottomOf="@+id/connect_progressbar"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        android:visibility="invisible"
+        style="@style/HalfSheetButton" />
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/cancel_btn"
+        android:text="@string/paring_action_done"
+        android:visibility="invisible"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        android:gravity="start|center_vertical"
+        android:layout_marginTop="6dp"
+        style="@style/HalfSheetButtonBorderless"/>
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/setup_btn"
+        android:text="@string/paring_action_launch"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_marginTop="6dp"
+        android:layout_marginBottom="16dp"
+        android:background="@color/fast_pair_half_sheet_button_color"
+        android:visibility="invisible"
+        android:layout_height="@dimen/fast_pair_half_sheet_bottom_button_height"
+        android:layout_width="wrap_content"
+        style="@style/HalfSheetButton" />
+
+  </androidx.constraintlayout.widget.ConstraintLayout>
+
+</LinearLayout>
diff --git a/nearby/halfsheet/res/layout/fast_pair_half_sheet.xml b/nearby/halfsheet/res/layout/fast_pair_half_sheet.xml
new file mode 100644
index 0000000..705aa1b
--- /dev/null
+++ b/nearby/halfsheet/res/layout/fast_pair_half_sheet.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:ignore="RtlCompat, UselessParent, MergeRootFrame"
+    android:id="@+id/background"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+  <LinearLayout
+      android:id="@+id/card"
+      android:orientation="vertical"
+      android:transitionName="card"
+      android:layout_height="wrap_content"
+      android:layout_width="match_parent"
+      android:layout_gravity= "center|bottom"
+      android:paddingLeft="12dp"
+      android:paddingRight="12dp"
+      android:background="@drawable/half_sheet_bg"
+      android:accessibilityLiveRegion="polite"
+      android:gravity="bottom">
+
+    <RelativeLayout
+        android:id="@+id/toolbar_wrapper"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="20dp"
+        android:paddingRight="20dp">
+
+      <ImageView
+          android:layout_marginTop="9dp"
+          android:layout_marginBottom="9dp"
+          android:id="@+id/toolbar_image"
+          android:layout_width="42dp"
+          android:layout_height="42dp"
+          android:contentDescription="@null"
+          android:layout_toStartOf="@id/toolbar_title"
+          android:layout_centerHorizontal="true"
+          android:visibility="invisible"/>
+
+      <TextView
+          android:layout_marginTop="18dp"
+          android:layout_marginBottom="18dp"
+          android:layout_centerHorizontal="true"
+          android:id="@+id/toolbar_title"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:fontFamily="google-sans-medium"
+          android:textSize="24sp"
+          android:textColor="@color/fast_pair_half_sheet_text_color"
+          style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" />
+    </RelativeLayout>
+
+    <FrameLayout
+        android:id="@+id/fragment_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+  </LinearLayout>
+
+</FrameLayout>
+
diff --git a/nearby/halfsheet/res/layout/fast_pair_heads_up_notification.xml b/nearby/halfsheet/res/layout/fast_pair_heads_up_notification.xml
new file mode 100644
index 0000000..11b8343
--- /dev/null
+++ b/nearby/halfsheet/res/layout/fast_pair_heads_up_notification.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:baselineAligned="false"
+    android:background="@color/fast_pair_notification_background"
+    tools:ignore="ContentDescription,UnusedAttribute,RtlCompat,Overdraw">
+
+  <LinearLayout
+      android:orientation="vertical"
+      android:layout_width="0dp"
+      android:layout_height="wrap_content"
+      android:layout_weight="1"
+      android:layout_marginTop="@dimen/fast_pair_notification_padding"
+      android:layout_marginStart="@dimen/fast_pair_notification_padding"
+      android:layout_marginEnd="@dimen/fast_pair_notification_padding">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+      <TextView
+          android:id="@android:id/title"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:fontFamily="sans-serif-medium"
+          android:textSize="@dimen/fast_pair_notification_text_size"
+          android:textColor="@color/fast_pair_primary_text"
+          android:layout_marginBottom="2dp"
+          android:lines="1"/>
+
+      <TextView
+          android:id="@android:id/text2"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:textSize="@dimen/fast_pair_notification_text_size_small"
+          android:textColor="@color/fast_pair_primary_text"
+          android:layout_marginBottom="2dp"
+          android:layout_marginStart="4dp"
+          android:lines="1"/>
+    </LinearLayout>
+
+    <TextView
+        android:id="@android:id/text1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="@dimen/fast_pair_notification_text_size"
+        android:textColor="@color/fast_pair_primary_text"
+        android:maxLines="2"
+        android:ellipsize="end"
+        android:breakStrategy="simple" />
+
+    <FrameLayout
+        android:id="@android:id/secondaryProgress"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="32dp"
+        android:orientation="horizontal"
+        android:visibility="gone">
+
+      <ProgressBar
+          android:id="@android:id/progress"
+          style="?android:attr/progressBarStyleHorizontal"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:layout_gravity="center_vertical"
+          android:indeterminateTint="@color/discovery_activity_accent"/>
+
+    </FrameLayout>
+
+  </LinearLayout>
+
+  <FrameLayout
+      android:id="@android:id/icon1"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"/>
+
+</LinearLayout>
diff --git a/nearby/halfsheet/res/layout/fast_pair_heads_up_notification_large_image.xml b/nearby/halfsheet/res/layout/fast_pair_heads_up_notification_large_image.xml
new file mode 100644
index 0000000..dd28947
--- /dev/null
+++ b/nearby/halfsheet/res/layout/fast_pair_heads_up_notification_large_image.xml
@@ -0,0 +1,7 @@
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@android:id/icon"
+    android:layout_width="@dimen/fast_pair_notification_large_image_size"
+    android:layout_height="@dimen/fast_pair_notification_large_image_size"
+    android:scaleType="fitStart"
+    tools:ignore="ContentDescription"/>
diff --git a/nearby/halfsheet/res/layout/fast_pair_heads_up_notification_small_image.xml b/nearby/halfsheet/res/layout/fast_pair_heads_up_notification_small_image.xml
new file mode 100644
index 0000000..ee1d89f
--- /dev/null
+++ b/nearby/halfsheet/res/layout/fast_pair_heads_up_notification_small_image.xml
@@ -0,0 +1,11 @@
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@android:id/icon"
+    android:layout_width="@dimen/fast_pair_notification_small_image_size"
+    android:layout_height="@dimen/fast_pair_notification_small_image_size"
+    android:layout_marginTop="@dimen/fast_pair_notification_padding"
+    android:layout_marginBottom="@dimen/fast_pair_notification_padding"
+    android:layout_marginStart="@dimen/fast_pair_notification_padding"
+    android:layout_marginEnd="@dimen/fast_pair_notification_padding"
+    android:scaleType="fitStart"
+    tools:ignore="ContentDescription,RtlCompat"/>
diff --git a/nearby/halfsheet/res/values-en-rXC/strings.xml b/nearby/halfsheet/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..460cc1b
--- /dev/null
+++ b/nearby/halfsheet/res/values-en-rXC/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ 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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="fast_pair_setup_in_progress" msgid="4158762239172829807">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‏‏‏‎Starting Setup…‎‏‎‎‏‎"</string>
+    <string name="fast_pair_title_setup" msgid="2894360355540593246">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎Set up device‎‏‎‎‏‎"</string>
+    <string name="fast_pair_device_ready" msgid="2903490346082833101">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎Device connected‎‏‎‎‏‎"</string>
+    <string name="fast_pair_title_fail" msgid="5677174346601290232">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎Couldn\'t connect‎‏‎‎‏‎"</string>
+    <string name="paring_action_done" msgid="6888875159174470731">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‏‏‎Done‎‏‎‎‏‎"</string>
+    <string name="paring_action_save" msgid="6259357442067880136">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎Save‎‏‎‎‏‎"</string>
+    <string name="paring_action_connect" msgid="4801102939608129181">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎Connect‎‏‎‎‏‎"</string>
+    <string name="paring_action_launch" msgid="8940808384126591230">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎Set up‎‏‎‎‏‎"</string>
+    <string name="paring_action_settings" msgid="424875657242864302">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎Settings‎‏‎‎‏‎"</string>
+</resources>
diff --git a/nearby/halfsheet/res/values/colors.xml b/nearby/halfsheet/res/values/colors.xml
new file mode 100644
index 0000000..b066665
--- /dev/null
+++ b/nearby/halfsheet/res/values/colors.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+  <!-- Use original background color -->
+  <color name="fast_pair_notification_background">#00000000</color>
+  <!-- Ignores NewApi as below system colors are available since API 31, and HalfSheet is always
+       running on T+ even though it has min_sdk 30 to match its containing APEX -->
+  <color name="fast_pair_half_sheet_button_color" tools:ignore="NewApi">@android:color/system_accent1_100</color>
+  <color name="fast_pair_half_sheet_button_text" tools:ignore="NewApi">@android:color/system_neutral1_900</color>
+  <color name="fast_pair_half_sheet_button_accent_text" tools:ignore="NewApi">@android:color/system_neutral1_900</color>
+  <color name="fast_pair_progress_color" tools:ignore="NewApi">@android:color/system_accent1_600</color>
+  <color name="fast_pair_half_sheet_subtitle_color" tools:ignore="NewApi">@android:color/system_neutral2_700</color>
+  <color name="fast_pair_half_sheet_text_color" tools:ignore="NewApi">@android:color/system_neutral1_900</color>
+
+  <!-- Nearby Discoverer -->
+  <color name="discovery_activity_accent">#4285F4</color>
+
+  <!-- Fast Pair -->
+  <color name="fast_pair_primary_text">#DE000000</color>
+  <color name="fast_pair_notification_image_outline">#24000000</color>
+  <color name="fast_pair_battery_level_low">#D93025</color>
+  <color name="fast_pair_battery_level_normal">#80868B</color>
+  <color name="fast_pair_half_sheet_background">#FFFFFF</color>
+  <color name="fast_pair_half_sheet_color_accent">#1A73E8</color>
+  <color name="fast_pair_fail_progress_color">#F44336</color>
+  <color name="fast_pair_progress_back_ground">#24000000</color>
+</resources>
diff --git a/nearby/halfsheet/res/values/dimens.xml b/nearby/halfsheet/res/values/dimens.xml
new file mode 100644
index 0000000..f843042
--- /dev/null
+++ b/nearby/halfsheet/res/values/dimens.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <!-- Fast Pair notification values -->
+  <dimen name="fast_pair_halfsheet_mid_image_size">160dp</dimen>
+  <dimen name="fast_pair_notification_text_size">14sp</dimen>
+  <dimen name="fast_pair_notification_text_size_small">11sp</dimen>
+  <dimen name="fast_pair_battery_notification_empty_view_height">4dp</dimen>
+  <dimen name="fast_pair_battery_notification_margin_top">8dp</dimen>
+  <dimen name="fast_pair_battery_notification_margin_bottom">8dp</dimen>
+  <dimen name="fast_pair_battery_notification_content_height">40dp</dimen>
+  <dimen name="fast_pair_battery_notification_content_height_v2">64dp</dimen>
+  <dimen name="fast_pair_battery_notification_image_size">32dp</dimen>
+  <dimen name="fast_pair_battery_notification_image_padding">3dp</dimen>
+  <dimen name="fast_pair_half_sheet_min_height">350dp</dimen>
+  <dimen name="fast_pair_half_sheet_image_size">215dp</dimen>
+  <dimen name="fast_pair_half_sheet_land_image_size">136dp</dimen>
+  <dimen name="fast_pair_connect_button_height">36dp</dimen>
+  <dimen name="accessibility_required_min_touch_target_size">48dp</dimen>
+  <dimen name="fast_pair_half_sheet_battery_case_image_size">152dp</dimen>
+  <dimen name="fast_pair_half_sheet_battery_bud_image_size">100dp</dimen>
+  <integer name="half_sheet_battery_case_width_dp">156</integer>
+  <integer name="half_sheet_battery_case_height_dp">182</integer>
+
+  <!-- Maximum height for SliceView, override on slices/view/src/main/res/values/dimens.xml -->
+  <dimen name="abc_slice_large_height">360dp</dimen>
+
+  <dimen name="action_dialog_content_margin_left">16dp</dimen>
+  <dimen name="action_dialog_content_margin_top">70dp</dimen>
+  <dimen name="action_button_focused_elevation">4dp</dimen>
+  <!-- Subsequent Notification -->
+  <dimen name="fast_pair_notification_padding">4dp</dimen>
+  <dimen name="fast_pair_notification_large_image_size">32dp</dimen>
+  <dimen name="fast_pair_notification_small_image_size">32dp</dimen>
+  <!-- Battery Notification -->
+  <dimen name="fast_pair_battery_notification_main_view_padding">0dp</dimen>
+  <dimen name="fast_pair_battery_notification_title_image_margin_start">0dp</dimen>
+  <dimen name="fast_pair_battery_notification_title_text_margin_start">0dp</dimen>
+  <dimen name="fast_pair_battery_notification_title_text_margin_start_v2">0dp</dimen>
+  <dimen name="fast_pair_battery_notification_image_margin_start">0dp</dimen>
+
+  <dimen name="fast_pair_half_sheet_bottom_button_height">48dp</dimen>
+</resources>
diff --git a/nearby/halfsheet/res/values/ints.xml b/nearby/halfsheet/res/values/ints.xml
new file mode 100644
index 0000000..07bf9d2
--- /dev/null
+++ b/nearby/halfsheet/res/values/ints.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <integer name="half_sheet_slide_in_duration">250</integer>
+  <integer name="half_sheet_fade_out_duration">250</integer>
+</resources>
diff --git a/nearby/halfsheet/res/values/overlayable.xml b/nearby/halfsheet/res/values/overlayable.xml
new file mode 100644
index 0000000..fffa2e3
--- /dev/null
+++ b/nearby/halfsheet/res/values/overlayable.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <overlayable name="NearbyHalfSheetResourcesConfig">
+        <policy type="product|system|vendor">
+            <item type="color" name="fast_pair_half_sheet_background"/>
+            <item type="color" name="fast_pair_half_sheet_button_color"/>
+        </policy>
+    </overlayable>
+</resources>
\ No newline at end of file
diff --git a/nearby/halfsheet/res/values/strings.xml b/nearby/halfsheet/res/values/strings.xml
new file mode 100644
index 0000000..01a82e4
--- /dev/null
+++ b/nearby/halfsheet/res/values/strings.xml
@@ -0,0 +1,72 @@
+<!--
+  ~ 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.
+  -->
+
+<resources>
+
+    <!--
+      ============================================================
+      PAIRING FRAGMENT
+      ============================================================
+    -->
+
+    <!--
+      A button shown to remind user setup is in progress. [CHAR LIMIT=30]
+    -->
+    <string name="fast_pair_setup_in_progress">Starting Setup&#x2026;</string>
+    <!--
+      Title text shown to remind user to setup a device through companion app. [CHAR LIMIT=40]
+    -->
+    <string name="fast_pair_title_setup">Set up device</string>
+    <!--
+      Title after we successfully pair with the audio device
+      [CHAR LIMIT=30]
+    -->
+    <string name="fast_pair_device_ready">Device connected</string>
+    <!-- Title text shown when peripheral device fail to connect to phone. [CHAR_LIMIT=30] -->
+    <string name="fast_pair_title_fail">Couldn\'t connect</string>
+
+    <!--
+      ============================================================
+      MISCELLANEOUS
+      ============================================================
+    -->
+
+    <!--
+      A button shown after paring process to dismiss the current activity.
+      [CHAR LIMIT=30]
+    -->
+    <string name="paring_action_done">Done</string>
+    <!--
+      A button shown for retroactive paring.
+      [CHAR LIMIT=30]
+     -->
+    <string name="paring_action_save">Save</string>
+    <!--
+      A button to start connecting process.
+      [CHAR LIMIT=30]
+     -->
+    <string name="paring_action_connect">Connect</string>
+    <!--
+      A button to launch a companion app.
+      [CHAR LIMIT=30]
+    -->
+    <string name="paring_action_launch">Set up</string>
+    <!--
+      A button to launch a bluetooth Settings page.
+      [CHAR LIMIT=20]
+    -->
+    <string name="paring_action_settings">Settings</string>
+</resources>
\ No newline at end of file
diff --git a/nearby/halfsheet/res/values/styles.xml b/nearby/halfsheet/res/values/styles.xml
new file mode 100644
index 0000000..917bb63
--- /dev/null
+++ b/nearby/halfsheet/res/values/styles.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+  <style name="HalfSheetStyle" parent="Theme.Material3.DayNight.NoActionBar">
+    <item name="android:windowFrame">@null</item>
+    <item name="android:windowBackground">@android:color/transparent</item>
+    <item name="android:windowEnterAnimation">@anim/fast_pair_half_sheet_slide_in</item>
+    <item name="android:windowExitAnimation">@anim/fast_pair_half_sheet_slide_out</item>
+    <item name="android:windowIsTranslucent">true</item>
+    <item name="android:windowContentOverlay">@null</item>
+    <item name="android:windowNoTitle">true</item>
+    <item name="android:backgroundDimEnabled">true</item>
+    <item name="android:statusBarColor">@android:color/transparent</item>
+    <item name="android:fitsSystemWindows">true</item>
+    <item name="android:windowTranslucentNavigation">true</item>
+  </style>
+
+  <style name="HalfSheetButton" parent="@style/Widget.Material3.Button.TonalButton">
+    <item name="android:textColor">@color/fast_pair_half_sheet_button_accent_text</item>
+    <item name="android:backgroundTint">@color/fast_pair_half_sheet_button_color</item>
+    <item name="android:textSize">@dimen/fast_pair_notification_text_size</item>
+    <item name="android:fontFamily">google-sans-medium</item>
+    <item name="android:textAlignment">center</item>
+    <item name="android:textAllCaps">false</item>
+  </style>
+
+  <style name="HalfSheetButtonBorderless" parent="@style/Widget.Material3.Button.OutlinedButton">
+    <item name="android:textColor">@color/fast_pair_half_sheet_button_text</item>
+    <item name="android:strokeColor">@color/fast_pair_half_sheet_button_color</item>
+    <item name="android:textAllCaps">false</item>
+    <item name="android:textSize">@dimen/fast_pair_notification_text_size</item>
+    <item name="android:fontFamily">google-sans-medium</item>
+    <item name="android:layout_width">wrap_content</item>
+    <item name="android:layout_height">wrap_content</item>
+    <item name="android:textAlignment">center</item>
+    <item name="android:minHeight">@dimen/accessibility_required_min_touch_target_size</item>
+  </style>
+
+</resources>
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/FastPairUiServiceClient.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/FastPairUiServiceClient.java
new file mode 100644
index 0000000..bec0c0a
--- /dev/null
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/FastPairUiServiceClient.java
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+package com.android.nearby.halfsheet;
+
+import android.content.Context;
+import android.nearby.FastPairDevice;
+import android.nearby.FastPairStatusCallback;
+import android.nearby.PairStatusMetadata;
+import android.nearby.aidl.IFastPairStatusCallback;
+import android.nearby.aidl.IFastPairUiService;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import androidx.annotation.BinderThread;
+import androidx.annotation.UiThread;
+
+import java.lang.ref.WeakReference;
+
+/**
+ *  A utility class for connecting to the {@link IFastPairUiService} and receive callbacks.
+ *
+ * @hide
+ */
+@UiThread
+public class FastPairUiServiceClient {
+
+    private static final String TAG = "FastPairHalfSheet";
+
+    private final IBinder mBinder;
+    private final WeakReference<Context> mWeakContext;
+    IFastPairUiService mFastPairUiService;
+    PairStatusCallbackIBinder mPairStatusCallbackIBinder;
+
+    /**
+     * The Ibinder instance should be from
+     * {@link com.android.server.nearby.fastpair.halfsheet.FastPairUiServiceImpl} so that the client can
+     * talk with the service.
+     */
+    public FastPairUiServiceClient(Context context, IBinder binder) {
+        mBinder = binder;
+        mFastPairUiService = IFastPairUiService.Stub.asInterface(mBinder);
+        mWeakContext = new WeakReference<>(context);
+    }
+
+    /**
+     * Registers a callback at service to get UI updates.
+     */
+    public void registerHalfSheetStateCallBack(FastPairStatusCallback fastPairStatusCallback) {
+        if (mPairStatusCallbackIBinder != null) {
+            return;
+        }
+        mPairStatusCallbackIBinder = new PairStatusCallbackIBinder(fastPairStatusCallback);
+        try {
+            mFastPairUiService.registerCallback(mPairStatusCallbackIBinder);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to register fastPairStatusCallback", e);
+        }
+    }
+
+    /**
+     * Pairs the device at service.
+     */
+    public void connect(FastPairDevice fastPairDevice) {
+        try {
+            mFastPairUiService.connect(fastPairDevice);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to connect Fast Pair device" + fastPairDevice, e);
+        }
+    }
+
+    /**
+     * Cancels Fast Pair connection and dismisses half sheet.
+     */
+    public void cancel(FastPairDevice fastPairDevice) {
+        try {
+            mFastPairUiService.cancel(fastPairDevice);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to connect Fast Pair device" + fastPairDevice, e);
+        }
+    }
+
+    private class PairStatusCallbackIBinder extends IFastPairStatusCallback.Stub {
+        private final FastPairStatusCallback mStatusCallback;
+
+        private PairStatusCallbackIBinder(FastPairStatusCallback fastPairStatusCallback) {
+            mStatusCallback = fastPairStatusCallback;
+        }
+
+        @BinderThread
+        @Override
+        public synchronized void onPairUpdate(FastPairDevice fastPairDevice,
+                PairStatusMetadata pairStatusMetadata) {
+            Context context = mWeakContext.get();
+            if (context != null) {
+                Handler handler = new Handler(context.getMainLooper());
+                handler.post(() ->
+                        mStatusCallback.onPairUpdate(fastPairDevice, pairStatusMetadata));
+            }
+        }
+    }
+}
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/HalfSheetActivity.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/HalfSheetActivity.java
new file mode 100644
index 0000000..2a38b8a
--- /dev/null
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/HalfSheetActivity.java
@@ -0,0 +1,239 @@
+/*
+ * 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.nearby.halfsheet;
+
+import static com.android.nearby.halfsheet.fragment.DevicePairingFragment.APP_LAUNCH_FRAGMENT_TYPE;
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairConstants.EXTRA_MODEL_ID;
+import static com.android.server.nearby.common.fastpair.service.UserActionHandlerBase.EXTRA_MAC_ADDRESS;
+import static com.android.server.nearby.fastpair.Constant.ACTION_FAST_PAIR_HALF_SHEET_CANCEL;
+import static com.android.server.nearby.fastpair.Constant.DEVICE_PAIRING_FRAGMENT_TYPE;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_INFO;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_TYPE;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+
+import com.android.nearby.halfsheet.fragment.DevicePairingFragment;
+import com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment;
+import com.android.nearby.halfsheet.utils.BroadcastUtils;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import java.util.Locale;
+
+import service.proto.Cache;
+
+/**
+ * A class show Fast Pair related information in Half sheet format.
+ */
+public class HalfSheetActivity extends FragmentActivity {
+
+    public static final String TAG = "FastPairHalfSheet";
+
+    public static final String EXTRA_HALF_SHEET_CONTENT =
+            "com.android.nearby.halfsheet.HALF_SHEET_CONTENT";
+    public static final String EXTRA_TITLE =
+            "com.android.nearby.halfsheet.HALF_SHEET_TITLE";
+    public static final String EXTRA_DESCRIPTION =
+            "com.android.nearby.halfsheet.HALF_SHEET_DESCRIPTION";
+    public static final String EXTRA_HALF_SHEET_ID =
+            "com.android.nearby.halfsheet.HALF_SHEET_ID";
+    public static final String EXTRA_HALF_SHEET_IS_RETROACTIVE =
+            "com.android.nearby.halfsheet.HALF_SHEET_IS_RETROACTIVE";
+    public static final String EXTRA_HALF_SHEET_IS_SUBSEQUENT_PAIR =
+            "com.android.nearby.halfsheet.HALF_SHEET_IS_SUBSEQUENT_PAIR";
+    public static final String EXTRA_HALF_SHEET_PAIRING_RESURFACE =
+            "com.android.nearby.halfsheet.EXTRA_HALF_SHEET_PAIRING_RESURFACE";
+    public static final String ACTION_HALF_SHEET_FOREGROUND_STATE =
+            "com.android.nearby.halfsheet.ACTION_HALF_SHEET_FOREGROUND_STATE";
+    // Intent extra contains the user gmail name eg. testaccount@gmail.com.
+    public static final String EXTRA_HALF_SHEET_ACCOUNT_NAME =
+            "com.android.nearby.halfsheet.HALF_SHEET_ACCOUNT_NAME";
+    public static final String EXTRA_HALF_SHEET_FOREGROUND =
+            "com.android.nearby.halfsheet.EXTRA_HALF_SHEET_FOREGROUND";
+    public static final String ARG_FRAGMENT_STATE = "ARG_FRAGMENT_STATE";
+    @Nullable
+    private HalfSheetModuleFragment mHalfSheetModuleFragment;
+    @Nullable
+    private Cache.ScanFastPairStoreItem mScanFastPairStoreItem;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        byte[] infoArray = getIntent().getByteArrayExtra(EXTRA_HALF_SHEET_INFO);
+        String fragmentType = getIntent().getStringExtra(EXTRA_HALF_SHEET_TYPE);
+        if (infoArray == null || fragmentType == null) {
+            Log.d(
+                    "HalfSheetActivity",
+                    "exit flag off or do not have enough half sheet information.");
+            finish();
+            return;
+        }
+
+        switch (fragmentType) {
+            case DEVICE_PAIRING_FRAGMENT_TYPE:
+                mHalfSheetModuleFragment = DevicePairingFragment.newInstance(getIntent(),
+                        savedInstanceState);
+                if (mHalfSheetModuleFragment == null) {
+                    Log.d(TAG, "device pairing fragment has error.");
+                    finish();
+                    return;
+                }
+                break;
+            case APP_LAUNCH_FRAGMENT_TYPE:
+                // currentFragment = AppLaunchFragment.newInstance(getIntent());
+                if (mHalfSheetModuleFragment == null) {
+                    Log.v(TAG, "app launch fragment has error.");
+                    finish();
+                    return;
+                }
+                break;
+            default:
+                Log.w(TAG, "there is no valid type for half sheet");
+                finish();
+                return;
+        }
+        if (mHalfSheetModuleFragment != null) {
+            getSupportFragmentManager()
+                    .beginTransaction()
+                    .replace(R.id.fragment_container, mHalfSheetModuleFragment)
+                    .commit();
+        }
+        setContentView(R.layout.fast_pair_half_sheet);
+
+        // If the user taps on the background, then close the activity.
+        // Unless they tap on the card itself, then ignore the tap.
+        findViewById(R.id.background).setOnClickListener(v -> onCancelClicked());
+        findViewById(R.id.card)
+                .setOnClickListener(
+                        v -> Log.v(TAG, "card view is clicked noop"));
+        try {
+            mScanFastPairStoreItem =
+                    Cache.ScanFastPairStoreItem.parseFrom(infoArray);
+        } catch (InvalidProtocolBufferException e) {
+            Log.w(
+                    TAG, "error happens when pass info to half sheet");
+        }
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+    }
+
+    @Override
+    protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
+        super.onSaveInstanceState(savedInstanceState);
+        if (mHalfSheetModuleFragment != null) {
+            mHalfSheetModuleFragment.onSaveInstanceState(savedInstanceState);
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        super.onBackPressed();
+        sendHalfSheetCancelBroadcast();
+    }
+
+    @Override
+    protected void onUserLeaveHint() {
+        super.onUserLeaveHint();
+        sendHalfSheetCancelBroadcast();
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        String fragmentType = getIntent().getStringExtra(EXTRA_HALF_SHEET_TYPE);
+        if (fragmentType == null) {
+            return;
+        }
+        if (fragmentType.equals(DEVICE_PAIRING_FRAGMENT_TYPE)
+                && intent.getExtras() != null
+                && intent.getByteArrayExtra(EXTRA_HALF_SHEET_INFO) != null) {
+            try {
+                Cache.ScanFastPairStoreItem testScanFastPairStoreItem =
+                        Cache.ScanFastPairStoreItem.parseFrom(
+                                intent.getByteArrayExtra(EXTRA_HALF_SHEET_INFO));
+                if (mScanFastPairStoreItem != null
+                        && !testScanFastPairStoreItem.getAddress().equals(
+                        mScanFastPairStoreItem.getAddress())
+                        && testScanFastPairStoreItem.getModelId().equals(
+                        mScanFastPairStoreItem.getModelId())) {
+                    Log.d(TAG, "possible factory reset happens");
+                    halfSheetStateChange();
+                }
+            } catch (InvalidProtocolBufferException | NullPointerException e) {
+                Log.w(TAG, "error happens when pass info to half sheet");
+            }
+        }
+    }
+
+    /** This function should be called when user click empty area and cancel button. */
+    public void onCancelClicked() {
+        Log.d(TAG, "Cancels the half sheet and paring.");
+        sendHalfSheetCancelBroadcast();
+        finish();
+    }
+
+    /** Changes the half sheet foreground state to false. */
+    public void halfSheetStateChange() {
+        BroadcastUtils.sendBroadcast(
+                this,
+                new Intent(ACTION_HALF_SHEET_FOREGROUND_STATE)
+                        .putExtra(EXTRA_HALF_SHEET_FOREGROUND, false));
+        finish();
+    }
+
+    private void sendHalfSheetCancelBroadcast() {
+        BroadcastUtils.sendBroadcast(
+                this,
+                new Intent(ACTION_HALF_SHEET_FOREGROUND_STATE)
+                        .putExtra(EXTRA_HALF_SHEET_FOREGROUND, false));
+        if (mScanFastPairStoreItem != null) {
+            BroadcastUtils.sendBroadcast(
+                    this,
+                    new Intent(ACTION_FAST_PAIR_HALF_SHEET_CANCEL)
+                            .putExtra(EXTRA_MODEL_ID,
+                                    mScanFastPairStoreItem.getModelId().toLowerCase(Locale.ROOT))
+                            .putExtra(EXTRA_HALF_SHEET_TYPE,
+                                    getIntent().getStringExtra(EXTRA_HALF_SHEET_TYPE))
+                            .putExtra(
+                                    EXTRA_HALF_SHEET_IS_SUBSEQUENT_PAIR,
+                                    getIntent().getBooleanExtra(EXTRA_HALF_SHEET_IS_SUBSEQUENT_PAIR,
+                                            false))
+                            .putExtra(
+                                    EXTRA_HALF_SHEET_IS_RETROACTIVE,
+                                    getIntent().getBooleanExtra(EXTRA_HALF_SHEET_IS_RETROACTIVE,
+                                            false))
+                            .putExtra(EXTRA_MAC_ADDRESS, mScanFastPairStoreItem.getAddress()));
+        }
+    }
+
+    @Override
+    public void setTitle(CharSequence title) {
+        super.setTitle(title);
+        TextView toolbarTitle = findViewById(R.id.toolbar_title);
+        toolbarTitle.setText(title);
+    }
+}
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/DevicePairingFragment.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/DevicePairingFragment.java
new file mode 100644
index 0000000..320965b
--- /dev/null
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/DevicePairingFragment.java
@@ -0,0 +1,487 @@
+/*
+ * 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.nearby.halfsheet.fragment;
+
+import static android.text.TextUtils.isEmpty;
+
+import static com.android.nearby.halfsheet.HalfSheetActivity.ARG_FRAGMENT_STATE;
+import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_DESCRIPTION;
+import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_HALF_SHEET_ACCOUNT_NAME;
+import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_HALF_SHEET_CONTENT;
+import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_HALF_SHEET_ID;
+import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_TITLE;
+import static com.android.nearby.halfsheet.HalfSheetActivity.TAG;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.FAILED;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.FOUND_DEVICE;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.NOT_STARTED;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.PAIRED_LAUNCHABLE;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.PAIRED_UNLAUNCHABLE;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.PAIRING;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_BINDER;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_BUNDLE;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_INFO;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.nearby.FastPairDevice;
+import android.nearby.FastPairStatusCallback;
+import android.nearby.NearbyDevice;
+import android.nearby.PairStatusMetadata;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.nearby.halfsheet.FastPairUiServiceClient;
+import com.android.nearby.halfsheet.HalfSheetActivity;
+import com.android.nearby.halfsheet.R;
+import com.android.nearby.halfsheet.utils.FastPairUtils;
+import com.android.nearby.halfsheet.utils.IconUtils;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import java.util.Objects;
+
+import service.proto.Cache.ScanFastPairStoreItem;
+
+/**
+ * Modularize half sheet for fast pair this fragment will show when half sheet does device pairing.
+ *
+ * <p>This fragment will handle initial pairing subsequent pairing and retroactive pairing.
+ */
+@SuppressWarnings("nullness")
+public class DevicePairingFragment extends HalfSheetModuleFragment implements
+        FastPairStatusCallback {
+    private TextView mTitleView;
+    private TextView mSubTitleView;
+    private ImageView mImage;
+
+    private Button mConnectButton;
+    private Button mSetupButton;
+    private Button mCancelButton;
+    // Opens Bluetooth Settings.
+    private Button mSettingsButton;
+    private ImageView mInfoIconButton;
+    private ProgressBar mConnectProgressBar;
+
+    private Bundle mBundle;
+
+    private ScanFastPairStoreItem mScanFastPairStoreItem;
+    private FastPairUiServiceClient mFastPairUiServiceClient;
+
+    private @PairStatusMetadata.Status int mPairStatus = PairStatusMetadata.Status.UNKNOWN;
+    // True when there is a companion app to open.
+    private boolean mIsLaunchable;
+    private boolean mIsConnecting;
+    // Indicates that the setup button is clicked before.
+    private boolean mSetupButtonClicked = false;
+
+    // Holds the new text while we transition between the two.
+    private static final int TAG_PENDING_TEXT = R.id.toolbar_title;
+    public static final String APP_LAUNCH_FRAGMENT_TYPE = "APP_LAUNCH";
+
+    private static final String ARG_SETUP_BUTTON_CLICKED = "SETUP_BUTTON_CLICKED";
+    private static final String ARG_PAIRING_RESULT = "PAIRING_RESULT";
+
+    /**
+     * Create certain fragment according to the intent.
+     */
+    @Nullable
+    public static HalfSheetModuleFragment newInstance(
+            Intent intent, @Nullable Bundle saveInstanceStates) {
+        Bundle args = new Bundle();
+        byte[] infoArray = intent.getByteArrayExtra(EXTRA_HALF_SHEET_INFO);
+
+        Bundle bundle = intent.getBundleExtra(EXTRA_BUNDLE);
+        String title = intent.getStringExtra(EXTRA_TITLE);
+        String description = intent.getStringExtra(EXTRA_DESCRIPTION);
+        String accountName = intent.getStringExtra(EXTRA_HALF_SHEET_ACCOUNT_NAME);
+        String result = intent.getStringExtra(EXTRA_HALF_SHEET_CONTENT);
+        int halfSheetId = intent.getIntExtra(EXTRA_HALF_SHEET_ID, 0);
+
+        args.putByteArray(EXTRA_HALF_SHEET_INFO, infoArray);
+        args.putString(EXTRA_HALF_SHEET_ACCOUNT_NAME, accountName);
+        args.putString(EXTRA_TITLE, title);
+        args.putString(EXTRA_DESCRIPTION, description);
+        args.putInt(EXTRA_HALF_SHEET_ID, halfSheetId);
+        args.putString(EXTRA_HALF_SHEET_CONTENT, result == null ? "" : result);
+        args.putBundle(EXTRA_BUNDLE, bundle);
+        if (saveInstanceStates != null) {
+            if (saveInstanceStates.containsKey(ARG_FRAGMENT_STATE)) {
+                args.putSerializable(
+                        ARG_FRAGMENT_STATE, saveInstanceStates.getSerializable(ARG_FRAGMENT_STATE));
+            }
+            if (saveInstanceStates.containsKey(BluetoothDevice.EXTRA_DEVICE)) {
+                args.putParcelable(
+                        BluetoothDevice.EXTRA_DEVICE,
+                        saveInstanceStates.getParcelable(BluetoothDevice.EXTRA_DEVICE));
+            }
+            if (saveInstanceStates.containsKey(BluetoothDevice.EXTRA_PAIRING_KEY)) {
+                args.putInt(
+                        BluetoothDevice.EXTRA_PAIRING_KEY,
+                        saveInstanceStates.getInt(BluetoothDevice.EXTRA_PAIRING_KEY));
+            }
+            if (saveInstanceStates.containsKey(ARG_SETUP_BUTTON_CLICKED)) {
+                args.putBoolean(
+                        ARG_SETUP_BUTTON_CLICKED,
+                        saveInstanceStates.getBoolean(ARG_SETUP_BUTTON_CLICKED));
+            }
+            if (saveInstanceStates.containsKey(ARG_PAIRING_RESULT)) {
+                args.putBoolean(ARG_PAIRING_RESULT,
+                        saveInstanceStates.getBoolean(ARG_PAIRING_RESULT));
+            }
+        }
+        DevicePairingFragment fragment = new DevicePairingFragment();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(
+            LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        /* attachToRoot= */
+        View rootView = inflater.inflate(
+                R.layout.fast_pair_device_pairing_fragment, container, /* attachToRoot= */
+                false);
+        if (getContext() == null) {
+            Log.d(TAG, "can't find the attached activity");
+            return rootView;
+        }
+
+        Bundle args = getArguments();
+        byte[] storeFastPairItemBytesArray = args.getByteArray(EXTRA_HALF_SHEET_INFO);
+        mBundle = args.getBundle(EXTRA_BUNDLE);
+        if (mBundle != null) {
+            mFastPairUiServiceClient =
+                    new FastPairUiServiceClient(getContext(), mBundle.getBinder(EXTRA_BINDER));
+            mFastPairUiServiceClient.registerHalfSheetStateCallBack(this);
+        }
+        if (args.containsKey(ARG_FRAGMENT_STATE)) {
+            mFragmentState = (HalfSheetFragmentState) args.getSerializable(ARG_FRAGMENT_STATE);
+        }
+        if (args.containsKey(ARG_SETUP_BUTTON_CLICKED)) {
+            mSetupButtonClicked = args.getBoolean(ARG_SETUP_BUTTON_CLICKED);
+        }
+        if (args.containsKey(ARG_PAIRING_RESULT)) {
+            mPairStatus = args.getInt(ARG_PAIRING_RESULT);
+        }
+
+        // Initiate views.
+        mTitleView = Objects.requireNonNull(getActivity()).findViewById(R.id.toolbar_title);
+        mSubTitleView = rootView.findViewById(R.id.header_subtitle);
+        mImage = rootView.findViewById(R.id.pairing_pic);
+        mConnectProgressBar = rootView.findViewById(R.id.connect_progressbar);
+        mConnectButton = rootView.findViewById(R.id.connect_btn);
+        mCancelButton = rootView.findViewById(R.id.cancel_btn);
+        mSettingsButton = rootView.findViewById(R.id.settings_btn);
+        mSetupButton = rootView.findViewById(R.id.setup_btn);
+        mInfoIconButton = rootView.findViewById(R.id.info_icon);
+        mInfoIconButton.setImageResource(R.drawable.fast_pair_ic_info);
+
+        try {
+            setScanFastPairStoreItem(ScanFastPairStoreItem.parseFrom(storeFastPairItemBytesArray));
+        } catch (InvalidProtocolBufferException e) {
+            Log.w(TAG,
+                    "DevicePairingFragment: error happens when pass info to half sheet");
+            return rootView;
+        }
+
+        // Config for landscape mode
+        DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
+        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            rootView.getLayoutParams().height = displayMetrics.heightPixels * 4 / 5;
+            rootView.getLayoutParams().width = displayMetrics.heightPixels * 4 / 5;
+            mImage.getLayoutParams().height = displayMetrics.heightPixels / 2;
+            mImage.getLayoutParams().width = displayMetrics.heightPixels / 2;
+            mConnectProgressBar.getLayoutParams().width = displayMetrics.heightPixels / 2;
+            mConnectButton.getLayoutParams().width = displayMetrics.heightPixels / 2;
+            //TODO(b/213373051): Add cancel button
+        }
+
+        Bitmap icon = IconUtils.getIcon(mScanFastPairStoreItem.getIconPng().toByteArray(),
+                mScanFastPairStoreItem.getIconPng().size());
+        if (icon != null) {
+            mImage.setImageBitmap(icon);
+        }
+        mConnectButton.setOnClickListener(v -> onConnectClick());
+        mCancelButton.setOnClickListener(v ->
+                ((HalfSheetActivity) getActivity()).onCancelClicked());
+        mSettingsButton.setOnClickListener(v -> onSettingsClicked());
+        mSetupButton.setOnClickListener(v -> onSetupClick());
+
+        return rootView;
+    }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // Get access to the activity's menu
+        setHasOptionsMenu(true);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        Log.v(TAG, "onStart: invalidate states");
+        invalidateState();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle savedInstanceState) {
+        super.onSaveInstanceState(savedInstanceState);
+
+        savedInstanceState.putSerializable(ARG_FRAGMENT_STATE, mFragmentState);
+        savedInstanceState.putBoolean(ARG_SETUP_BUTTON_CLICKED, mSetupButtonClicked);
+        savedInstanceState.putInt(ARG_PAIRING_RESULT, mPairStatus);
+    }
+
+    private void onSettingsClicked() {
+        startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
+    }
+
+    private void onSetupClick() {
+        String companionApp =
+                FastPairUtils.getCompanionAppFromActionUrl(mScanFastPairStoreItem.getActionUrl());
+        Intent intent =
+                FastPairUtils.createCompanionAppIntent(
+                        Objects.requireNonNull(getContext()),
+                        companionApp,
+                        mScanFastPairStoreItem.getAddress());
+        mSetupButtonClicked = true;
+        if (mFragmentState == PAIRED_LAUNCHABLE) {
+            if (intent != null) {
+                startActivity(intent);
+            }
+        } else {
+            Log.d(TAG, "onSetupClick: State is " + mFragmentState);
+        }
+    }
+
+    private void onConnectClick() {
+        if (mScanFastPairStoreItem == null) {
+            Log.w(TAG, "No pairing related information in half sheet");
+            return;
+        }
+        if (getFragmentState() == PAIRING) {
+            return;
+        }
+        mIsConnecting = true;
+        invalidateState();
+        mFastPairUiServiceClient.connect(
+                new FastPairDevice.Builder()
+                        .addMedium(NearbyDevice.Medium.BLE)
+                        .setBluetoothAddress(mScanFastPairStoreItem.getAddress())
+                        .setData(FastPairUtils.convertFrom(mScanFastPairStoreItem)
+                                .toByteArray())
+                        .build());
+    }
+
+    // Receives callback from service.
+    @Override
+    public void onPairUpdate(FastPairDevice fastPairDevice, PairStatusMetadata pairStatusMetadata) {
+        @PairStatusMetadata.Status int status = pairStatusMetadata.getStatus();
+        if (status == PairStatusMetadata.Status.DISMISS && getActivity() != null) {
+            getActivity().finish();
+        }
+        mIsConnecting = false;
+        mPairStatus = status;
+        invalidateState();
+    }
+
+    @Override
+    public void invalidateState() {
+        HalfSheetFragmentState newState = NOT_STARTED;
+        if (mIsConnecting) {
+            newState = PAIRING;
+        } else {
+            switch (mPairStatus) {
+                case PairStatusMetadata.Status.SUCCESS:
+                    newState = mIsLaunchable ? PAIRED_LAUNCHABLE : PAIRED_UNLAUNCHABLE;
+                    break;
+                case PairStatusMetadata.Status.FAIL:
+                    newState = FAILED;
+                    break;
+                default:
+                    if (mScanFastPairStoreItem != null) {
+                        newState = FOUND_DEVICE;
+                    }
+            }
+        }
+        if (newState == mFragmentState) {
+            return;
+        }
+        setState(newState);
+    }
+
+    @Override
+    public void setState(HalfSheetFragmentState state) {
+        super.setState(state);
+        invalidateTitles();
+        invalidateButtons();
+    }
+
+    private void setScanFastPairStoreItem(ScanFastPairStoreItem item) {
+        mScanFastPairStoreItem = item;
+        invalidateLaunchable();
+    }
+
+    private void invalidateLaunchable() {
+        String companionApp =
+                FastPairUtils.getCompanionAppFromActionUrl(mScanFastPairStoreItem.getActionUrl());
+        if (isEmpty(companionApp)) {
+            mIsLaunchable = false;
+            return;
+        }
+        mIsLaunchable =
+                FastPairUtils.isLaunchable(Objects.requireNonNull(getContext()), companionApp);
+    }
+
+    private void invalidateButtons() {
+        mConnectProgressBar.setVisibility(View.INVISIBLE);
+        mConnectButton.setVisibility(View.INVISIBLE);
+        mCancelButton.setVisibility(View.INVISIBLE);
+        mSetupButton.setVisibility(View.INVISIBLE);
+        mSettingsButton.setVisibility(View.INVISIBLE);
+        mInfoIconButton.setVisibility(View.INVISIBLE);
+
+        switch (mFragmentState) {
+            case FOUND_DEVICE:
+                mInfoIconButton.setVisibility(View.VISIBLE);
+                mConnectButton.setVisibility(View.VISIBLE);
+                break;
+            case PAIRING:
+                mConnectProgressBar.setVisibility(View.VISIBLE);
+                mCancelButton.setVisibility(View.VISIBLE);
+                setBackgroundClickable(false);
+                break;
+            case PAIRED_LAUNCHABLE:
+                mCancelButton.setVisibility(View.VISIBLE);
+                mSetupButton.setVisibility(View.VISIBLE);
+                setBackgroundClickable(true);
+                break;
+            case FAILED:
+                mSettingsButton.setVisibility(View.VISIBLE);
+                setBackgroundClickable(true);
+                break;
+            case NOT_STARTED:
+            case PAIRED_UNLAUNCHABLE:
+            default:
+                mCancelButton.setVisibility(View.VISIBLE);
+                setBackgroundClickable(true);
+        }
+    }
+
+    private void setBackgroundClickable(boolean isClickable) {
+        HalfSheetActivity activity = (HalfSheetActivity) getActivity();
+        if (activity == null) {
+            Log.w(TAG, "setBackgroundClickable: failed to set clickable to " + isClickable
+                    + " because cannot get HalfSheetActivity.");
+            return;
+        }
+        View background = activity.findViewById(R.id.background);
+        if (background == null) {
+            Log.w(TAG, "setBackgroundClickable: failed to set clickable to " + isClickable
+                    + " cannot find background at HalfSheetActivity.");
+            return;
+        }
+        Log.d(TAG, "setBackgroundClickable to " + isClickable);
+        background.setClickable(isClickable);
+    }
+
+    private void invalidateTitles() {
+        String newTitle = getTitle();
+        invalidateTextView(mTitleView, newTitle);
+        String newSubTitle = getSubTitle();
+        invalidateTextView(mSubTitleView, newSubTitle);
+    }
+
+    private void invalidateTextView(TextView textView, String newText) {
+        CharSequence oldText =
+                textView.getTag(TAG_PENDING_TEXT) != null
+                        ? (CharSequence) textView.getTag(TAG_PENDING_TEXT)
+                        : textView.getText();
+        if (TextUtils.equals(oldText, newText)) {
+            return;
+        }
+        if (TextUtils.isEmpty(oldText)) {
+            // First time run. Don't animate since there's nothing to animate from.
+            textView.setText(newText);
+        } else {
+            textView.setTag(TAG_PENDING_TEXT, newText);
+            textView
+                    .animate()
+                    .alpha(0f)
+                    .setDuration(TEXT_ANIMATION_DURATION_MILLISECONDS)
+                    .withEndAction(
+                            () -> {
+                                textView.setText(newText);
+                                textView
+                                        .animate()
+                                        .alpha(1f)
+                                        .setDuration(TEXT_ANIMATION_DURATION_MILLISECONDS);
+                            });
+        }
+    }
+
+    private String getTitle() {
+        switch (mFragmentState) {
+            case PAIRED_LAUNCHABLE:
+                return getString(R.string.fast_pair_title_setup);
+            case FAILED:
+                return getString(R.string.fast_pair_title_fail);
+            case FOUND_DEVICE:
+            case NOT_STARTED:
+            case PAIRED_UNLAUNCHABLE:
+            default:
+                return mScanFastPairStoreItem.getDeviceName();
+        }
+    }
+
+    private String getSubTitle() {
+        switch (mFragmentState) {
+            case PAIRED_LAUNCHABLE:
+                return String.format(
+                        mScanFastPairStoreItem
+                                .getFastPairStrings()
+                                .getPairingFinishedCompanionAppInstalled(),
+                        mScanFastPairStoreItem.getDeviceName());
+            case FAILED:
+                return mScanFastPairStoreItem.getFastPairStrings().getPairingFailDescription();
+            case PAIRED_UNLAUNCHABLE:
+                getString(R.string.fast_pair_device_ready);
+            // fall through
+            case FOUND_DEVICE:
+            case NOT_STARTED:
+                return mScanFastPairStoreItem.getFastPairStrings().getInitialPairingDescription();
+            default:
+                return "";
+        }
+    }
+}
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/HalfSheetModuleFragment.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/HalfSheetModuleFragment.java
new file mode 100644
index 0000000..f1db4d0
--- /dev/null
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/HalfSheetModuleFragment.java
@@ -0,0 +1,77 @@
+/*
+ * 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.nearby.halfsheet.fragment;
+
+import static com.android.nearby.halfsheet.HalfSheetActivity.TAG;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.NOT_STARTED;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+
+/** Base class for all of the half sheet fragment. */
+public abstract class HalfSheetModuleFragment extends Fragment {
+
+    static final int TEXT_ANIMATION_DURATION_MILLISECONDS = 200;
+
+    HalfSheetFragmentState mFragmentState = NOT_STARTED;
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    /** UI states of the half-sheet fragment. */
+    public enum HalfSheetFragmentState {
+        NOT_STARTED, // Initial status
+        FOUND_DEVICE, // When a device is found found from Nearby scan service
+        PAIRING, // When user taps 'Connect' and Fast Pair stars pairing process
+        PAIRED_LAUNCHABLE, // When pair successfully
+        // and we found a launchable companion app installed
+        PAIRED_UNLAUNCHABLE, // When pair successfully
+        // but we cannot find a companion app to launch it
+        FAILED, // When paring was failed
+        FINISHED // When the activity is about to end finished.
+    }
+
+    /**
+     * Returns the {@link HalfSheetFragmentState} to the parent activity.
+     *
+     * <p>Overrides this method if the fragment's state needs to be preserved in the parent
+     * activity.
+     */
+    public HalfSheetFragmentState getFragmentState() {
+        return mFragmentState;
+    }
+
+    void setState(HalfSheetFragmentState state) {
+        Log.v(TAG, "Settings state from " + mFragmentState + " to " + state);
+        mFragmentState = state;
+    }
+
+    /**
+     * Populate data to UI widgets according to the latest {@link HalfSheetFragmentState}.
+     */
+    abstract void invalidateState();
+}
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/BroadcastUtils.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/BroadcastUtils.java
new file mode 100644
index 0000000..467997c
--- /dev/null
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/BroadcastUtils.java
@@ -0,0 +1,36 @@
+/*
+ * 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.nearby.halfsheet.utils;
+
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Broadcast util class
+ */
+public class BroadcastUtils {
+
+    /**
+     * Helps send broadcast.
+     */
+    public static void sendBroadcast(Context context, Intent intent) {
+        context.sendBroadcast(intent);
+    }
+
+    private BroadcastUtils() {
+    }
+}
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java
new file mode 100644
index 0000000..903ea90
--- /dev/null
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java
@@ -0,0 +1,151 @@
+/*
+ * 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.nearby.halfsheet.utils;
+
+import static com.android.server.nearby.common.fastpair.service.UserActionHandlerBase.EXTRA_COMPANION_APP;
+import static com.android.server.nearby.fastpair.UserActionHandler.ACTION_FAST_PAIR;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.net.URISyntaxException;
+
+import service.proto.Cache;
+
+/**
+ * Util class in half sheet apk
+ */
+public class FastPairUtils {
+
+    /** FastPair util method check certain app is install on the device or not. */
+    public static boolean isAppInstalled(Context context, String packageName) {
+        try {
+            context.getPackageManager().getPackageInfo(packageName, 0);
+            return true;
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    /** FastPair util method to properly format the action url extra. */
+    @Nullable
+    public static String getCompanionAppFromActionUrl(String actionUrl) {
+        try {
+            Intent intent = Intent.parseUri(actionUrl, Intent.URI_INTENT_SCHEME);
+            if (!intent.getAction().equals(ACTION_FAST_PAIR)) {
+                Log.e("FastPairUtils", "Companion app launch attempted from malformed action url");
+                return null;
+            }
+            return intent.getStringExtra(EXTRA_COMPANION_APP);
+        } catch (URISyntaxException e) {
+            Log.e("FastPairUtils", "FastPair: fail to get companion app info from discovery item");
+            return null;
+        }
+    }
+
+    /**
+     * Converts {@link service.proto.Cache.StoredDiscoveryItem} from
+     * {@link service.proto.Cache.ScanFastPairStoreItem}
+     */
+    public static Cache.StoredDiscoveryItem convertFrom(Cache.ScanFastPairStoreItem item) {
+        return convertFrom(item, /* isSubsequentPair= */ false);
+    }
+
+    /**
+     * Converts a {@link service.proto.Cache.ScanFastPairStoreItem}
+     * to a {@link service.proto.Cache.StoredDiscoveryItem}.
+     *
+     * <p>This is needed to make the new Fast Pair scanning stack compatible with the rest of the
+     * legacy Fast Pair code.
+     */
+    public static Cache.StoredDiscoveryItem convertFrom(
+            Cache.ScanFastPairStoreItem item, boolean isSubsequentPair) {
+        return Cache.StoredDiscoveryItem.newBuilder()
+                .setId(item.getModelId())
+                .setFirstObservationTimestampMillis(item.getFirstObservationTimestampMillis())
+                .setLastObservationTimestampMillis(item.getLastObservationTimestampMillis())
+                .setType(Cache.NearbyType.NEARBY_DEVICE)
+                .setActionUrl(item.getActionUrl())
+                .setActionUrlType(Cache.ResolvedUrlType.APP)
+                .setTitle(
+                        isSubsequentPair
+                                ? item.getFastPairStrings().getTapToPairWithoutAccount()
+                                : item.getDeviceName())
+                .setMacAddress(item.getAddress())
+                .setState(Cache.StoredDiscoveryItem.State.STATE_ENABLED)
+                .setTriggerId(item.getModelId())
+                .setIconPng(item.getIconPng())
+                .setIconFifeUrl(item.getIconFifeUrl())
+                .setDescription(
+                        isSubsequentPair
+                                ? item.getDeviceName()
+                                : item.getFastPairStrings().getTapToPairWithoutAccount())
+                .setAuthenticationPublicKeySecp256R1(item.getAntiSpoofingPublicKey())
+                .setCompanionDetail(item.getCompanionDetail())
+                .setFastPairStrings(item.getFastPairStrings())
+                .setFastPairInformation(
+                        Cache.FastPairInformation.newBuilder()
+                                .setDataOnlyConnection(item.getDataOnlyConnection())
+                                .setTrueWirelessImages(item.getTrueWirelessImages())
+                                .setAssistantSupported(item.getAssistantSupported())
+                                .setCompanyName(item.getCompanyName()))
+                .build();
+    }
+
+    /**
+     * Returns true the application is installed and can be opened on device.
+     */
+    public static boolean isLaunchable(@NonNull Context context, String companionApp) {
+        return isAppInstalled(context, companionApp)
+                && createCompanionAppIntent(context, companionApp, null) != null;
+    }
+
+    /**
+     * Returns an intent to launch given the package name and bluetooth address (if provided).
+     * Returns null if no such an intent can be found.
+     */
+    @Nullable
+    public static Intent createCompanionAppIntent(@NonNull Context context, String packageName,
+            @Nullable String address) {
+        Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
+        if (intent == null) {
+            return null;
+        }
+        if (address != null) {
+            BluetoothAdapter adapter = getBluetoothAdapter(context);
+            if (adapter != null) {
+                intent.putExtra(BluetoothDevice.EXTRA_DEVICE, adapter.getRemoteDevice(address));
+            }
+        }
+        return intent;
+    }
+
+    @Nullable
+    private static BluetoothAdapter getBluetoothAdapter(@NonNull Context context) {
+        BluetoothManager bluetoothManager = context.getSystemService(BluetoothManager.class);
+        return bluetoothManager == null ? null : bluetoothManager.getAdapter();
+    }
+
+    private FastPairUtils() {}
+}
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java
new file mode 100644
index 0000000..218c756
--- /dev/null
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+package com.android.nearby.halfsheet.utils;
+
+import static com.android.nearby.halfsheet.HalfSheetActivity.TAG;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.core.graphics.ColorUtils;
+
+/**
+ * Utility class for icon size verification.
+ */
+public class IconUtils {
+
+    private static final float NOTIFICATION_BACKGROUND_PADDING_PERCENT = 0.125f;
+    private static final float NOTIFICATION_BACKGROUND_ALPHA = 0.7f;
+    private static final int MIN_ICON_SIZE = 16;
+    private static final int DESIRED_ICON_SIZE = 32;
+
+    /**
+     * Verify that the icon is non null and falls in the small bucket. Just because an icon isn't
+     * small doesn't guarantee it is large or exists.
+     */
+    public static boolean isIconSizedSmall(@Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return false;
+        }
+        return bitmap.getWidth() >= MIN_ICON_SIZE
+                && bitmap.getWidth() < DESIRED_ICON_SIZE
+                && bitmap.getHeight() >= MIN_ICON_SIZE
+                && bitmap.getHeight() < DESIRED_ICON_SIZE;
+    }
+
+    /**
+     * Verify that the icon is non null and falls in the regular / default size bucket. Doesn't
+     * guarantee if not regular then it is small.
+     */
+    static boolean isIconSizedRegular(@Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return false;
+        }
+        return bitmap.getWidth() >= DESIRED_ICON_SIZE && bitmap.getHeight() >= DESIRED_ICON_SIZE;
+    }
+
+    /**
+     * All icons that are sized correctly (larger than the MIN_ICON_SIZE icon size)
+     * are resize on the server to the DESIRED_ICON_SIZE icon size so that
+     * they appear correct.
+     */
+    public static boolean isIconSizeCorrect(@Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return false;
+        }
+        return isIconSizedSmall(bitmap) || isIconSizedRegular(bitmap);
+    }
+
+    /**
+     * Returns the bitmap from the byte array. Returns null if cannot decode or not in correct size.
+     */
+    @Nullable
+    public static Bitmap getIcon(byte[] imageData, int size) {
+        try {
+            Bitmap icon =
+                    BitmapFactory.decodeByteArray(imageData, /* offset= */ 0, size);
+            if (IconUtils.isIconSizeCorrect(icon)) {
+                // Do not add background for Half Sheet.
+                return IconUtils.addWhiteCircleBackground(icon);
+            }
+        } catch (OutOfMemoryError e) {
+            Log.w(TAG, "getIcon: Failed to decode icon, returning null.", e);
+        }
+        return null;
+    }
+
+    /** Adds a circular, white background to the bitmap. */
+    @Nullable
+    public static Bitmap addWhiteCircleBackground(Bitmap bitmap) {
+        if (bitmap == null) {
+            Log.w(TAG, "addWhiteCircleBackground: Bitmap is null, not adding background.");
+            return null;
+        }
+
+        if (bitmap.getWidth() != bitmap.getHeight()) {
+            Log.w(TAG, "addWhiteCircleBackground: Bitmap dimensions not square. Skipping"
+                    + "adding background.");
+            return bitmap;
+        }
+
+        int padding = (int) (bitmap.getWidth() * NOTIFICATION_BACKGROUND_PADDING_PERCENT);
+        Bitmap bitmapWithBackground =
+                Bitmap.createBitmap(
+                        bitmap.getWidth() + (2 * padding),
+                        bitmap.getHeight() + (2 * padding),
+                        bitmap.getConfig());
+        Canvas canvas = new Canvas(bitmapWithBackground);
+        Paint paint = new Paint();
+        paint.setColor(
+                ColorUtils.setAlphaComponent(
+                        Color.WHITE, (int) (255 * NOTIFICATION_BACKGROUND_ALPHA)));
+        paint.setStyle(Paint.Style.FILL);
+        paint.setAntiAlias(true);
+        canvas.drawCircle(
+                bitmapWithBackground.getWidth() / 2,
+                bitmapWithBackground.getHeight() / 2,
+                bitmapWithBackground.getWidth() / 2,
+                paint);
+        canvas.drawBitmap(bitmap, padding, padding, null);
+
+        return bitmapWithBackground;
+    }
+}
+
diff --git a/nearby/service-src/com/android/server/nearby/NearbyService.java b/nearby/service-src/com/android/server/nearby/NearbyService.java
deleted file mode 100644
index 88752cc..0000000
--- a/nearby/service-src/com/android/server/nearby/NearbyService.java
+++ /dev/null
@@ -1,36 +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.
- */
-
-package com.android.server.nearby;
-
-import android.content.Context;
-import android.os.Binder;
-
-/**
- * Stub NearbyService class, used until NearbyService code is available in all branches.
- *
- * This can be published as an empty service in branches that use it.
- */
-public final class NearbyService extends Binder {
-    public NearbyService(Context ctx) {
-        throw new UnsupportedOperationException("This is a stub service");
-    }
-
-    /** Called by the service initializer on each boot phase */
-    public void onBootPhase(int phase) {
-        // Do nothing
-    }
-}
diff --git a/nearby/service/Android.bp b/nearby/service/Android.bp
new file mode 100644
index 0000000..802e2c8
--- /dev/null
+++ b/nearby/service/Android.bp
@@ -0,0 +1,98 @@
+// 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+    name: "nearby-service-srcs",
+    srcs: [
+        "java/**/*.java",
+        ":statslog-nearby-java-gen",
+    ],
+}
+
+filegroup {
+    name: "nearby-service-string-res",
+    srcs: [
+        "java/**/Constant.java",
+        "java/**/UserActionHandlerBase.java",
+        "java/**/UserActionHandler.java",
+        "java/**/FastPairConstants.java",
+    ],
+}
+
+java_library {
+    name: "nearby-service-string",
+    srcs: [":nearby-service-string-res"],
+    libs: ["framework-bluetooth"],
+    sdk_version: "module_current",
+}
+
+
+// Main lib for nearby services.
+java_library {
+    name: "service-nearby-pre-jarjar",
+    srcs: [":nearby-service-srcs"],
+
+    defaults: [
+        "framework-system-server-module-defaults"
+    ],
+    libs: [
+        "framework-bluetooth.stubs.module_lib", // TODO(b/215722418): Change to framework-bluetooth once fixed
+        "error_prone_annotations",
+        "framework-connectivity-t.impl",
+        "framework-statsd.stubs.module_lib",
+    ],
+    static_libs: [
+        "androidx.annotation_annotation",
+        "androidx.core_core",
+        "androidx.localbroadcastmanager_localbroadcastmanager",
+        "guava",
+        "libprotobuf-java-lite",
+        "fast-pair-lite-protos",
+        "modules-utils-build",
+        "modules-utils-handlerexecutor",
+        "modules-utils-preconditions",
+        "modules-utils-backgroundthread",
+        "presence-lite-protos",
+    ],
+    sdk_version: "system_server_current",
+    // This is included in service-connectivity which is 30+
+    // TODO: allow APEXes to have service jars with higher min_sdk than the APEX
+    // (service-connectivity is only used on 31+) and use 31 here
+    min_sdk_version: "30",
+
+    installable: true,
+    dex_preopt: {
+        enabled: false,
+        app_image: false,
+    },
+    visibility: [
+        "//packages/modules/Nearby/apex",
+    ],
+    apex_available: [
+        "com.android.tethering",
+    ],
+}
+
+genrule {
+    name: "statslog-nearby-java-gen",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --java $(out) --module nearby " +
+         " --javaPackage com.android.server.nearby.proto --javaClass NearbyStatsLog" +
+         " --minApiLevel 33",
+    out: ["com/android/server/nearby/proto/NearbyStatsLog.java"],
+}
diff --git a/nearby/service/java/com/android/server/nearby/NearbyConfiguration.java b/nearby/service/java/com/android/server/nearby/NearbyConfiguration.java
new file mode 100644
index 0000000..8fdac87
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/NearbyConfiguration.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby;
+
+import android.provider.DeviceConfig;
+
+import androidx.annotation.VisibleForTesting;
+
+/**
+ * A utility class for encapsulating Nearby feature flag configurations.
+ */
+public class NearbyConfiguration {
+
+    /**
+     * Flag use to enable presence legacy broadcast.
+     */
+    public static final String NEARBY_ENABLE_PRESENCE_BROADCAST_LEGACY =
+            "nearby_enable_presence_broadcast_legacy";
+
+    private boolean mEnablePresenceBroadcastLegacy;
+
+    public NearbyConfiguration() {
+        mEnablePresenceBroadcastLegacy = getDeviceConfigBoolean(
+                NEARBY_ENABLE_PRESENCE_BROADCAST_LEGACY, false /* defaultValue */);
+
+    }
+
+    /**
+     * Returns whether broadcasting legacy presence spec is enabled.
+     */
+    public boolean isPresenceBroadcastLegacyEnabled() {
+        return mEnablePresenceBroadcastLegacy;
+    }
+
+    private boolean getDeviceConfigBoolean(final String name, final boolean defaultValue) {
+        final String value = getDeviceConfigProperty(name);
+        return value != null ? Boolean.parseBoolean(value) : defaultValue;
+    }
+
+    @VisibleForTesting
+    protected String getDeviceConfigProperty(String name) {
+        return DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TETHERING, name);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/NearbyService.java b/nearby/service/java/com/android/server/nearby/NearbyService.java
new file mode 100644
index 0000000..e3e5b5d
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/NearbyService.java
@@ -0,0 +1,180 @@
+/*
+ * 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.server.nearby;
+
+import static com.android.server.SystemService.PHASE_BOOT_COMPLETED;
+import static com.android.server.SystemService.PHASE_THIRD_PARTY_APPS_CAN_START;
+
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.location.ContextHubManager;
+import android.nearby.BroadcastRequestParcelable;
+import android.nearby.IBroadcastListener;
+import android.nearby.INearbyManager;
+import android.nearby.IScanListener;
+import android.nearby.NearbyManager;
+import android.nearby.ScanRequest;
+import android.util.Log;
+
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+import com.android.server.nearby.fastpair.FastPairManager;
+import com.android.server.nearby.injector.ContextHubManagerAdapter;
+import com.android.server.nearby.injector.Injector;
+import com.android.server.nearby.presence.PresenceManager;
+import com.android.server.nearby.provider.BroadcastProviderManager;
+import com.android.server.nearby.provider.DiscoveryProviderManager;
+import com.android.server.nearby.provider.FastPairDataProvider;
+
+/** Service implementing nearby functionality. */
+public class NearbyService extends INearbyManager.Stub {
+    public static final String TAG = "NearbyService";
+
+    private final Context mContext;
+    private final SystemInjector mSystemInjector;
+    private final FastPairManager mFastPairManager;
+    private final PresenceManager mPresenceManager;
+    private final BroadcastReceiver mBluetoothReceiver =
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    int state =
+                            intent.getIntExtra(
+                                    BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+                    if (state == BluetoothAdapter.STATE_ON) {
+                        if (mSystemInjector != null) {
+                            // Have to do this logic in listener. Even during PHASE_BOOT_COMPLETED
+                            // phase, BluetoothAdapter is not null, the BleScanner is null.
+                            Log.v(TAG, "Initiating BluetoothAdapter when Bluetooth is turned on.");
+                            mSystemInjector.initializeBluetoothAdapter();
+                        }
+                    }
+                }
+            };
+    private DiscoveryProviderManager mProviderManager;
+    private BroadcastProviderManager mBroadcastProviderManager;
+
+    public NearbyService(Context context) {
+        mContext = context;
+        mSystemInjector = new SystemInjector(context);
+        mProviderManager = new DiscoveryProviderManager(context, mSystemInjector);
+        mBroadcastProviderManager = new BroadcastProviderManager(context, mSystemInjector);
+        final LocatorContextWrapper lcw = new LocatorContextWrapper(context, null);
+        mFastPairManager = new FastPairManager(lcw);
+        mPresenceManager = new PresenceManager(lcw);
+    }
+
+    @Override
+    @NearbyManager.ScanStatus
+    public int registerScanListener(ScanRequest scanRequest, IScanListener listener) {
+        if (mProviderManager.registerScanListener(scanRequest, listener)) {
+            return NearbyManager.ScanStatus.SUCCESS;
+        }
+        return NearbyManager.ScanStatus.ERROR;
+    }
+
+    @Override
+    public void unregisterScanListener(IScanListener listener) {
+        mProviderManager.unregisterScanListener(listener);
+    }
+
+    @Override
+    public void startBroadcast(BroadcastRequestParcelable broadcastRequestParcelable,
+            IBroadcastListener listener) {
+        mBroadcastProviderManager.startBroadcast(
+                broadcastRequestParcelable.getBroadcastRequest(),
+                listener);
+    }
+
+    @Override
+    public void stopBroadcast(IBroadcastListener listener) {
+        mBroadcastProviderManager.stopBroadcast(listener);
+    }
+
+    /**
+     * Called by the service initializer.
+     *
+     * <p>{@see com.android.server.SystemService#onBootPhase}.
+     */
+    public void onBootPhase(int phase) {
+        switch (phase) {
+            case PHASE_THIRD_PARTY_APPS_CAN_START:
+                // Ensures that a fast pair data provider exists which will work in direct boot.
+                FastPairDataProvider.init(mContext);
+                break;
+            case PHASE_BOOT_COMPLETED:
+                // The nearby service must be functioning after this boot phase.
+                mSystemInjector.initializeBluetoothAdapter();
+                mContext.registerReceiver(
+                        mBluetoothReceiver,
+                        new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
+                mFastPairManager.initiate();
+                // Initialize ContextManager for CHRE scan.
+                mSystemInjector.initializeContextHubManagerAdapter();
+                mPresenceManager.initiate();
+                break;
+        }
+    }
+
+    private static final class SystemInjector implements Injector {
+        private final Context mContext;
+        @Nullable private BluetoothAdapter mBluetoothAdapter;
+        @Nullable private ContextHubManagerAdapter mContextHubManagerAdapter;
+
+        SystemInjector(Context context) {
+            mContext = context;
+        }
+
+        @Override
+        @Nullable
+        public BluetoothAdapter getBluetoothAdapter() {
+            return mBluetoothAdapter;
+        }
+
+        @Override
+        @Nullable
+        public ContextHubManagerAdapter getContextHubManagerAdapter() {
+            return mContextHubManagerAdapter;
+        }
+
+        synchronized void initializeBluetoothAdapter() {
+            if (mBluetoothAdapter != null) {
+                return;
+            }
+            BluetoothManager manager = mContext.getSystemService(BluetoothManager.class);
+            if (manager == null) {
+                return;
+            }
+            mBluetoothAdapter = manager.getAdapter();
+        }
+
+        synchronized void initializeContextHubManagerAdapter() {
+            if (mContextHubManagerAdapter != null) {
+                return;
+            }
+            ContextHubManager manager = mContext.getSystemService(ContextHubManager.class);
+            if (manager == null) {
+                return;
+            }
+            mContextHubManagerAdapter = new ContextHubManagerAdapter(manager);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/ble/BleFilter.java b/nearby/service/java/com/android/server/nearby/common/ble/BleFilter.java
new file mode 100644
index 0000000..23d5170
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/ble/BleFilter.java
@@ -0,0 +1,746 @@
+/*
+ * 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.server.nearby.common.ble;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanFilter;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import androidx.annotation.Nullable;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * Criteria for filtering BLE devices. A {@link BleFilter} allows clients to restrict BLE devices to
+ * only those that are of interest to them.
+ *
+ *
+ * <p>Current filtering on the following fields are supported:
+ * <li>Service UUIDs which identify the bluetooth gatt services running on the device.
+ * <li>Name of remote Bluetooth LE device.
+ * <li>Mac address of the remote device.
+ * <li>Service data which is the data associated with a service.
+ * <li>Manufacturer specific data which is the data associated with a particular manufacturer.
+ *
+ * @see BleSighting
+ */
+public final class BleFilter implements Parcelable {
+
+    @Nullable
+    private String mDeviceName;
+
+    @Nullable
+    private String mDeviceAddress;
+
+    @Nullable
+    private ParcelUuid mServiceUuid;
+
+    @Nullable
+    private ParcelUuid mServiceUuidMask;
+
+    @Nullable
+    private ParcelUuid mServiceDataUuid;
+
+    @Nullable
+    private byte[] mServiceData;
+
+    @Nullable
+    private byte[] mServiceDataMask;
+
+    private int mManufacturerId;
+
+    @Nullable
+    private byte[] mManufacturerData;
+
+    @Nullable
+    private byte[] mManufacturerDataMask;
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    BleFilter() {
+    }
+
+    BleFilter(
+            @Nullable String deviceName,
+            @Nullable String deviceAddress,
+            @Nullable ParcelUuid serviceUuid,
+            @Nullable ParcelUuid serviceUuidMask,
+            @Nullable ParcelUuid serviceDataUuid,
+            @Nullable byte[] serviceData,
+            @Nullable byte[] serviceDataMask,
+            int manufacturerId,
+            @Nullable byte[] manufacturerData,
+            @Nullable byte[] manufacturerDataMask) {
+        this.mDeviceName = deviceName;
+        this.mDeviceAddress = deviceAddress;
+        this.mServiceUuid = serviceUuid;
+        this.mServiceUuidMask = serviceUuidMask;
+        this.mServiceDataUuid = serviceDataUuid;
+        this.mServiceData = serviceData;
+        this.mServiceDataMask = serviceDataMask;
+        this.mManufacturerId = manufacturerId;
+        this.mManufacturerData = manufacturerData;
+        this.mManufacturerDataMask = manufacturerDataMask;
+    }
+
+    public static final Parcelable.Creator<BleFilter> CREATOR = new Creator<BleFilter>() {
+        @Override
+        public BleFilter createFromParcel(Parcel source) {
+            BleFilter nBleFilter = new BleFilter();
+            nBleFilter.mDeviceName = source.readString();
+            nBleFilter.mDeviceAddress = source.readString();
+            nBleFilter.mManufacturerId = source.readInt();
+            nBleFilter.mManufacturerData = source.marshall();
+            nBleFilter.mManufacturerDataMask = source.marshall();
+            nBleFilter.mServiceDataUuid = source.readParcelable(null);
+            nBleFilter.mServiceData = source.marshall();
+            nBleFilter.mServiceDataMask = source.marshall();
+            nBleFilter.mServiceUuid = source.readParcelable(null);
+            nBleFilter.mServiceUuidMask = source.readParcelable(null);
+            return nBleFilter;
+        }
+
+        @Override
+        public BleFilter[] newArray(int size) {
+            return new BleFilter[size];
+        }
+    };
+
+
+    /** Returns the filter set on the device name field of Bluetooth advertisement data. */
+    @Nullable
+    public String getDeviceName() {
+        return mDeviceName;
+    }
+
+    /** Returns the filter set on the service uuid. */
+    @Nullable
+    public ParcelUuid getServiceUuid() {
+        return mServiceUuid;
+    }
+
+    /** Returns the mask for the service uuid. */
+    @Nullable
+    public ParcelUuid getServiceUuidMask() {
+        return mServiceUuidMask;
+    }
+
+    /** Returns the filter set on the device address. */
+    @Nullable
+    public String getDeviceAddress() {
+        return mDeviceAddress;
+    }
+
+    /** Returns the filter set on the service data. */
+    @Nullable
+    public byte[] getServiceData() {
+        return mServiceData;
+    }
+
+    /** Returns the mask for the service data. */
+    @Nullable
+    public byte[] getServiceDataMask() {
+        return mServiceDataMask;
+    }
+
+    /** Returns the filter set on the service data uuid. */
+    @Nullable
+    public ParcelUuid getServiceDataUuid() {
+        return mServiceDataUuid;
+    }
+
+    /** Returns the manufacturer id. -1 if the manufacturer filter is not set. */
+    public int getManufacturerId() {
+        return mManufacturerId;
+    }
+
+    /** Returns the filter set on the manufacturer data. */
+    @Nullable
+    public byte[] getManufacturerData() {
+        return mManufacturerData;
+    }
+
+    /** Returns the mask for the manufacturer data. */
+    @Nullable
+    public byte[] getManufacturerDataMask() {
+        return mManufacturerDataMask;
+    }
+
+    /**
+     * Check if the filter matches a {@code BleSighting}. A BLE sighting is considered as a match if
+     * it matches all the field filters.
+     */
+    public boolean matches(@Nullable BleSighting bleSighting) {
+        if (bleSighting == null) {
+            return false;
+        }
+        BluetoothDevice device = bleSighting.getDevice();
+        // Device match.
+        if (mDeviceAddress != null && (device == null || !mDeviceAddress.equals(
+                device.getAddress()))) {
+            return false;
+        }
+
+        BleRecord bleRecord = bleSighting.getBleRecord();
+
+        // Scan record is null but there exist filters on it.
+        if (bleRecord == null
+                && (mDeviceName != null
+                || mServiceUuid != null
+                || mManufacturerData != null
+                || mServiceData != null)) {
+            return false;
+        }
+
+        // Local name match.
+        if (mDeviceName != null && !mDeviceName.equals(bleRecord.getDeviceName())) {
+            return false;
+        }
+
+        // UUID match.
+        if (mServiceUuid != null
+                && !matchesServiceUuids(mServiceUuid, mServiceUuidMask,
+                bleRecord.getServiceUuids())) {
+            return false;
+        }
+
+        // Service data match
+        if (mServiceDataUuid != null
+                && !matchesPartialData(
+                mServiceData, mServiceDataMask, bleRecord.getServiceData(mServiceDataUuid))) {
+            return false;
+        }
+
+        // Manufacturer data match.
+        if (mManufacturerId >= 0
+                && !matchesPartialData(
+                mManufacturerData,
+                mManufacturerDataMask,
+                bleRecord.getManufacturerSpecificData(mManufacturerId))) {
+            return false;
+        }
+
+        // All filters match.
+        return true;
+    }
+
+    /**
+     * Determines if the characteristics of this filter are a superset of the characteristics of the
+     * given filter.
+     */
+    public boolean isSuperset(@Nullable BleFilter bleFilter) {
+        if (bleFilter == null) {
+            return false;
+        }
+
+        if (equals(bleFilter)) {
+            return true;
+        }
+
+        // Verify device address matches.
+        if (mDeviceAddress != null && !mDeviceAddress.equals(bleFilter.getDeviceAddress())) {
+            return false;
+        }
+
+        // Verify device name matches.
+        if (mDeviceName != null && !mDeviceName.equals(bleFilter.getDeviceName())) {
+            return false;
+        }
+
+        // Verify UUID is a superset.
+        if (mServiceUuid != null
+                && !serviceUuidIsSuperset(
+                mServiceUuid,
+                mServiceUuidMask,
+                bleFilter.getServiceUuid(),
+                bleFilter.getServiceUuidMask())) {
+            return false;
+        }
+
+        // Verify service data is a superset.
+        if (mServiceDataUuid != null
+                && (!mServiceDataUuid.equals(bleFilter.getServiceDataUuid())
+                || !partialDataIsSuperset(
+                mServiceData,
+                mServiceDataMask,
+                bleFilter.getServiceData(),
+                bleFilter.getServiceDataMask()))) {
+            return false;
+        }
+
+        // Verify manufacturer data is a superset.
+        if (mManufacturerId >= 0
+                && (mManufacturerId != bleFilter.getManufacturerId()
+                || !partialDataIsSuperset(
+                mManufacturerData,
+                mManufacturerDataMask,
+                bleFilter.getManufacturerData(),
+                bleFilter.getManufacturerDataMask()))) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /** Determines if the first uuid and mask are a superset of the second uuid and mask. */
+    private static boolean serviceUuidIsSuperset(
+            @Nullable ParcelUuid uuid1,
+            @Nullable ParcelUuid uuidMask1,
+            @Nullable ParcelUuid uuid2,
+            @Nullable ParcelUuid uuidMask2) {
+        // First uuid1 is null so it can match any service UUID.
+        if (uuid1 == null) {
+            return true;
+        }
+
+        // uuid2 is a superset of uuid1, but not the other way around.
+        if (uuid2 == null) {
+            return false;
+        }
+
+        // Without a mask, the uuids must match.
+        if (uuidMask1 == null) {
+            return uuid1.equals(uuid2);
+        }
+
+        // Mask2 should be at least as specific as mask1.
+        if (uuidMask2 != null) {
+            long uuid1MostSig = uuidMask1.getUuid().getMostSignificantBits();
+            long uuid1LeastSig = uuidMask1.getUuid().getLeastSignificantBits();
+            long uuid2MostSig = uuidMask2.getUuid().getMostSignificantBits();
+            long uuid2LeastSig = uuidMask2.getUuid().getLeastSignificantBits();
+            if (((uuid1MostSig & uuid2MostSig) != uuid1MostSig)
+                    || ((uuid1LeastSig & uuid2LeastSig) != uuid1LeastSig)) {
+                return false;
+            }
+        }
+
+        if (!matchesServiceUuids(uuid1, uuidMask1, Arrays.asList(uuid2))) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /** Determines if the first data and mask are the superset of the second data and mask. */
+    private static boolean partialDataIsSuperset(
+            @Nullable byte[] data1,
+            @Nullable byte[] dataMask1,
+            @Nullable byte[] data2,
+            @Nullable byte[] dataMask2) {
+        if (Arrays.equals(data1, data2) && Arrays.equals(dataMask1, dataMask2)) {
+            return true;
+        }
+
+        if (data1 == null) {
+            return true;
+        }
+
+        if (data2 == null) {
+            return false;
+        }
+
+        // Mask2 should be at least as specific as mask1.
+        if (dataMask1 != null && dataMask2 != null) {
+            for (int i = 0, j = 0; i < dataMask1.length && j < dataMask2.length; i++, j++) {
+                if ((dataMask1[i] & dataMask2[j]) != dataMask1[i]) {
+                    return false;
+                }
+            }
+        }
+
+        if (!matchesPartialData(data1, dataMask1, data2)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /** Check if the uuid pattern is contained in a list of parcel uuids. */
+    private static boolean matchesServiceUuids(
+            @Nullable ParcelUuid uuid, @Nullable ParcelUuid parcelUuidMask,
+            List<ParcelUuid> uuids) {
+        if (uuid == null) {
+            // No service uuid filter has been set, so there's a match.
+            return true;
+        }
+
+        UUID uuidMask = parcelUuidMask == null ? null : parcelUuidMask.getUuid();
+        for (ParcelUuid parcelUuid : uuids) {
+            if (matchesServiceUuid(uuid.getUuid(), uuidMask, parcelUuid.getUuid())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** Check if the uuid pattern matches the particular service uuid. */
+    private static boolean matchesServiceUuid(UUID uuid, @Nullable UUID mask, UUID data) {
+        if (mask == null) {
+            return uuid.equals(data);
+        }
+        if ((uuid.getLeastSignificantBits() & mask.getLeastSignificantBits())
+                != (data.getLeastSignificantBits() & mask.getLeastSignificantBits())) {
+            return false;
+        }
+        return ((uuid.getMostSignificantBits() & mask.getMostSignificantBits())
+                == (data.getMostSignificantBits() & mask.getMostSignificantBits()));
+    }
+
+    /**
+     * Check whether the data pattern matches the parsed data. Assumes that {@code data} and {@code
+     * dataMask} have the same length.
+     */
+    /* package */
+    static boolean matchesPartialData(
+            @Nullable byte[] data, @Nullable byte[] dataMask, @Nullable byte[] parsedData) {
+        if (data == null || parsedData == null || parsedData.length < data.length) {
+            return false;
+        }
+        if (dataMask == null) {
+            for (int i = 0; i < data.length; ++i) {
+                if (parsedData[i] != data[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        for (int i = 0; i < data.length; ++i) {
+            if ((dataMask[i] & parsedData[i]) != (dataMask[i] & data[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "BleFilter [deviceName="
+                + mDeviceName
+                + ", deviceAddress="
+                + mDeviceAddress
+                + ", uuid="
+                + mServiceUuid
+                + ", uuidMask="
+                + mServiceUuidMask
+                + ", serviceDataUuid="
+                + mServiceDataUuid
+                + ", serviceData="
+                + Arrays.toString(mServiceData)
+                + ", serviceDataMask="
+                + Arrays.toString(mServiceDataMask)
+                + ", manufacturerId="
+                + mManufacturerId
+                + ", manufacturerData="
+                + Arrays.toString(mManufacturerData)
+                + ", manufacturerDataMask="
+                + Arrays.toString(mManufacturerDataMask)
+                + "]";
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mDeviceName);
+        out.writeString(mDeviceAddress);
+        out.writeInt(mManufacturerId);
+        out.writeByteArray(mManufacturerData);
+        out.writeByteArray(mManufacturerDataMask);
+        out.writeParcelable(mServiceDataUuid, flags);
+        out.writeByteArray(mServiceData);
+        out.writeByteArray(mServiceDataMask);
+        out.writeParcelable(mServiceUuid, flags);
+        out.writeParcelable(mServiceUuidMask, flags);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                mDeviceName,
+                mDeviceAddress,
+                mManufacturerId,
+                Arrays.hashCode(mManufacturerData),
+                Arrays.hashCode(mManufacturerDataMask),
+                mServiceDataUuid,
+                Arrays.hashCode(mServiceData),
+                Arrays.hashCode(mServiceDataMask),
+                mServiceUuid,
+                mServiceUuidMask);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        BleFilter other = (BleFilter) obj;
+        return mDeviceName.equals(other.mDeviceName)
+                && mDeviceAddress.equals(other.mDeviceAddress)
+                && mManufacturerId == other.mManufacturerId
+                && Arrays.equals(mManufacturerData, other.mManufacturerData)
+                && Arrays.equals(mManufacturerDataMask, other.mManufacturerDataMask)
+                && mServiceDataUuid.equals(other.mServiceDataUuid)
+                && Arrays.equals(mServiceData, other.mServiceData)
+                && Arrays.equals(mServiceDataMask, other.mServiceDataMask)
+                && mServiceUuid.equals(other.mServiceUuid)
+                && mServiceUuidMask.equals(other.mServiceUuidMask);
+    }
+
+    /** Builder class for {@link BleFilter}. */
+    public static final class Builder {
+
+        private String mDeviceName;
+        private String mDeviceAddress;
+
+        @Nullable
+        private ParcelUuid mServiceUuid;
+        @Nullable
+        private ParcelUuid mUuidMask;
+
+        private ParcelUuid mServiceDataUuid;
+        @Nullable
+        private byte[] mServiceData;
+        @Nullable
+        private byte[] mServiceDataMask;
+
+        private int mManufacturerId = -1;
+        private byte[] mManufacturerData;
+        @Nullable
+        private byte[] mManufacturerDataMask;
+
+        /** Set filter on device name. */
+        public Builder setDeviceName(String deviceName) {
+            this.mDeviceName = deviceName;
+            return this;
+        }
+
+        /**
+         * Set filter on device address.
+         *
+         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
+         *                      format of "01:02:03:AB:CD:EF". The device address can be validated
+         *                      using {@link
+         *                      BluetoothAdapter#checkBluetoothAddress}.
+         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
+         */
+        public Builder setDeviceAddress(String deviceAddress) {
+            if (!BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
+                throw new IllegalArgumentException("invalid device address " + deviceAddress);
+            }
+            this.mDeviceAddress = deviceAddress;
+            return this;
+        }
+
+        /** Set filter on service uuid. */
+        public Builder setServiceUuid(@Nullable ParcelUuid serviceUuid) {
+            this.mServiceUuid = serviceUuid;
+            mUuidMask = null; // clear uuid mask
+            return this;
+        }
+
+        /**
+         * Set filter on partial service uuid. The {@code uuidMask} is the bit mask for the {@code
+         * serviceUuid}. Set any bit in the mask to 1 to indicate a match is needed for the bit in
+         * {@code serviceUuid}, and 0 to ignore that bit.
+         *
+         * @throws IllegalArgumentException If {@code serviceUuid} is {@code null} but {@code
+         *                                  uuidMask}
+         *                                  is not {@code null}.
+         */
+        public Builder setServiceUuid(@Nullable ParcelUuid serviceUuid,
+                @Nullable ParcelUuid uuidMask) {
+            if (uuidMask != null && serviceUuid == null) {
+                throw new IllegalArgumentException("uuid is null while uuidMask is not null!");
+            }
+            this.mServiceUuid = serviceUuid;
+            this.mUuidMask = uuidMask;
+            return this;
+        }
+
+        /**
+         * Set filtering on service data.
+         */
+        public Builder setServiceData(ParcelUuid serviceDataUuid, @Nullable byte[] serviceData) {
+            this.mServiceDataUuid = serviceDataUuid;
+            this.mServiceData = serviceData;
+            mServiceDataMask = null; // clear service data mask
+            return this;
+        }
+
+        /**
+         * Set partial filter on service data. For any bit in the mask, set it to 1 if it needs to
+         * match
+         * the one in service data, otherwise set it to 0 to ignore that bit.
+         *
+         * <p>The {@code serviceDataMask} must have the same length of the {@code serviceData}.
+         *
+         * @throws IllegalArgumentException If {@code serviceDataMask} is {@code null} while {@code
+         *                                  serviceData} is not or {@code serviceDataMask} and
+         *                                  {@code serviceData} has different
+         *                                  length.
+         */
+        public Builder setServiceData(
+                ParcelUuid serviceDataUuid,
+                @Nullable byte[] serviceData,
+                @Nullable byte[] serviceDataMask) {
+            if (serviceDataMask != null) {
+                if (serviceData == null) {
+                    throw new IllegalArgumentException(
+                            "serviceData is null while serviceDataMask is not null");
+                }
+                // Since the serviceDataMask is a bit mask for serviceData, the lengths of the two
+                // byte array need to be the same.
+                if (serviceData.length != serviceDataMask.length) {
+                    throw new IllegalArgumentException(
+                            "size mismatch for service data and service data mask");
+                }
+            }
+            this.mServiceDataUuid = serviceDataUuid;
+            this.mServiceData = serviceData;
+            this.mServiceDataMask = serviceDataMask;
+            return this;
+        }
+
+        /**
+         * Set filter on on manufacturerData. A negative manufacturerId is considered as invalid id.
+         *
+         * <p>Note the first two bytes of the {@code manufacturerData} is the manufacturerId.
+         *
+         * @throws IllegalArgumentException If the {@code manufacturerId} is invalid.
+         */
+        public Builder setManufacturerData(int manufacturerId, @Nullable byte[] manufacturerData) {
+            return setManufacturerData(manufacturerId, manufacturerData, null /* mask */);
+        }
+
+        /**
+         * Set filter on partial manufacture data. For any bit in the mask, set it to 1 if it needs
+         * to
+         * match the one in manufacturer data, otherwise set it to 0.
+         *
+         * <p>The {@code manufacturerDataMask} must have the same length of {@code
+         * manufacturerData}.
+         *
+         * @throws IllegalArgumentException If the {@code manufacturerId} is invalid, or {@code
+         *                                  manufacturerData} is null while {@code
+         *                                  manufacturerDataMask} is not, or {@code
+         *                                  manufacturerData} and {@code manufacturerDataMask} have
+         *                                  different length.
+         */
+        public Builder setManufacturerData(
+                int manufacturerId,
+                @Nullable byte[] manufacturerData,
+                @Nullable byte[] manufacturerDataMask) {
+            if (manufacturerData != null && manufacturerId < 0) {
+                throw new IllegalArgumentException("invalid manufacture id");
+            }
+            if (manufacturerDataMask != null) {
+                if (manufacturerData == null) {
+                    throw new IllegalArgumentException(
+                            "manufacturerData is null while manufacturerDataMask is not null");
+                }
+                // Since the manufacturerDataMask is a bit mask for manufacturerData, the lengths
+                // of the two byte array need to be the same.
+                if (manufacturerData.length != manufacturerDataMask.length) {
+                    throw new IllegalArgumentException(
+                            "size mismatch for manufacturerData and manufacturerDataMask");
+                }
+            }
+            this.mManufacturerId = manufacturerId;
+            this.mManufacturerData = manufacturerData == null ? new byte[0] : manufacturerData;
+            this.mManufacturerDataMask = manufacturerDataMask;
+            return this;
+        }
+
+
+        /**
+         * Builds the filter.
+         *
+         * @throws IllegalArgumentException If the filter cannot be built.
+         */
+        public BleFilter build() {
+            return new BleFilter(
+                    mDeviceName,
+                    mDeviceAddress,
+                    mServiceUuid,
+                    mUuidMask,
+                    mServiceDataUuid,
+                    mServiceData,
+                    mServiceDataMask,
+                    mManufacturerId,
+                    mManufacturerData,
+                    mManufacturerDataMask);
+        }
+    }
+
+    /**
+     * Changes ble filter to os filter
+     */
+    public ScanFilter toOsFilter() {
+        ScanFilter.Builder osFilterBuilder = new ScanFilter.Builder();
+        if (!TextUtils.isEmpty(getDeviceAddress())) {
+            osFilterBuilder.setDeviceAddress(getDeviceAddress());
+        }
+        if (!TextUtils.isEmpty(getDeviceName())) {
+            osFilterBuilder.setDeviceName(getDeviceName());
+        }
+
+        byte[] manufacturerData = getManufacturerData();
+        if (getManufacturerId() != -1 && manufacturerData != null) {
+            byte[] manufacturerDataMask = getManufacturerDataMask();
+            if (manufacturerDataMask != null) {
+                osFilterBuilder.setManufacturerData(
+                        getManufacturerId(), manufacturerData, manufacturerDataMask);
+            } else {
+                osFilterBuilder.setManufacturerData(getManufacturerId(), manufacturerData);
+            }
+        }
+
+        ParcelUuid serviceDataUuid = getServiceDataUuid();
+        byte[] serviceData = getServiceData();
+        if (serviceDataUuid != null && serviceData != null) {
+            byte[] serviceDataMask = getServiceDataMask();
+            if (serviceDataMask != null) {
+                osFilterBuilder.setServiceData(serviceDataUuid, serviceData, serviceDataMask);
+            } else {
+                osFilterBuilder.setServiceData(serviceDataUuid, serviceData);
+            }
+        }
+
+        ParcelUuid serviceUuid = getServiceUuid();
+        if (serviceUuid != null) {
+            ParcelUuid serviceUuidMask = getServiceUuidMask();
+            if (serviceUuidMask != null) {
+                osFilterBuilder.setServiceUuid(serviceUuid, serviceUuidMask);
+            } else {
+                osFilterBuilder.setServiceUuid(serviceUuid);
+            }
+        }
+        return osFilterBuilder.build();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/ble/BleRecord.java b/nearby/service/java/com/android/server/nearby/common/ble/BleRecord.java
new file mode 100644
index 0000000..103a27f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/ble/BleRecord.java
@@ -0,0 +1,395 @@
+/*
+ * 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.server.nearby.common.ble;
+
+import android.os.ParcelUuid;
+import android.util.Log;
+import android.util.SparseArray;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.ble.util.StringUtils;
+
+import com.google.common.collect.ImmutableList;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Represents a BLE record from Bluetooth LE scan.
+ */
+public final class BleRecord {
+
+    // The following data type values are assigned by Bluetooth SIG.
+    // For more details refer to Bluetooth 4.1 specification, Volume 3, Part C, Section 18.
+    private static final int DATA_TYPE_FLAGS = 0x01;
+    private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL = 0x02;
+    private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE = 0x03;
+    private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL = 0x04;
+    private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE = 0x05;
+    private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL = 0x06;
+    private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE = 0x07;
+    private static final int DATA_TYPE_LOCAL_NAME_SHORT = 0x08;
+    private static final int DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09;
+    private static final int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
+    private static final int DATA_TYPE_SERVICE_DATA = 0x16;
+    private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
+
+    /** The base 128-bit UUID representation of a 16-bit UUID. */
+    private static final ParcelUuid BASE_UUID =
+            ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
+    /** Length of bytes for 16 bit UUID. */
+    private static final int UUID_BYTES_16_BIT = 2;
+    /** Length of bytes for 32 bit UUID. */
+    private static final int UUID_BYTES_32_BIT = 4;
+    /** Length of bytes for 128 bit UUID. */
+    private static final int UUID_BYTES_128_BIT = 16;
+
+    // Flags of the advertising data.
+    // -1 when the scan record is not valid.
+    private final int mAdvertiseFlags;
+
+    private final ImmutableList<ParcelUuid> mServiceUuids;
+
+    // null when the scan record is not valid.
+    @Nullable
+    private final SparseArray<byte[]> mManufacturerSpecificData;
+
+    // null when the scan record is not valid.
+    @Nullable
+    private final Map<ParcelUuid, byte[]> mServiceData;
+
+    // Transmission power level(in dB).
+    // Integer.MIN_VALUE when the scan record is not valid.
+    private final int mTxPowerLevel;
+
+    // Local name of the Bluetooth LE device.
+    // null when the scan record is not valid.
+    @Nullable
+    private final String mDeviceName;
+
+    // Raw bytes of scan record.
+    // Never null, whether valid or not.
+    private final byte[] mBytes;
+
+    // If the raw scan record byte[] cannot be parsed, all non-primitive args here other than the
+    // raw scan record byte[] and serviceUudis will be null. See parsefromBytes().
+    private BleRecord(
+            List<ParcelUuid> serviceUuids,
+            @Nullable SparseArray<byte[]> manufacturerData,
+            @Nullable Map<ParcelUuid, byte[]> serviceData,
+            int advertiseFlags,
+            int txPowerLevel,
+            @Nullable String deviceName,
+            byte[] bytes) {
+        this.mServiceUuids = ImmutableList.copyOf(serviceUuids);
+        mManufacturerSpecificData = manufacturerData;
+        this.mServiceData = serviceData;
+        this.mDeviceName = deviceName;
+        this.mAdvertiseFlags = advertiseFlags;
+        this.mTxPowerLevel = txPowerLevel;
+        this.mBytes = bytes;
+    }
+
+    /**
+     * Returns a list of service UUIDs within the advertisement that are used to identify the
+     * bluetooth GATT services.
+     */
+    public ImmutableList<ParcelUuid> getServiceUuids() {
+        return mServiceUuids;
+    }
+
+    /**
+     * Returns a sparse array of manufacturer identifier and its corresponding manufacturer specific
+     * data.
+     */
+    @Nullable
+    public SparseArray<byte[]> getManufacturerSpecificData() {
+        return mManufacturerSpecificData;
+    }
+
+    /**
+     * Returns the manufacturer specific data associated with the manufacturer id. Returns {@code
+     * null} if the {@code manufacturerId} is not found.
+     */
+    @Nullable
+    public byte[] getManufacturerSpecificData(int manufacturerId) {
+        if (mManufacturerSpecificData == null) {
+            return null;
+        }
+        return mManufacturerSpecificData.get(manufacturerId);
+    }
+
+    /** Returns a map of service UUID and its corresponding service data. */
+    @Nullable
+    public Map<ParcelUuid, byte[]> getServiceData() {
+        return mServiceData;
+    }
+
+    /**
+     * Returns the service data byte array associated with the {@code serviceUuid}. Returns {@code
+     * null} if the {@code serviceDataUuid} is not found.
+     */
+    @Nullable
+    public byte[] getServiceData(ParcelUuid serviceDataUuid) {
+        if (serviceDataUuid == null || mServiceData == null) {
+            return null;
+        }
+        return mServiceData.get(serviceDataUuid);
+    }
+
+    /**
+     * Returns the transmission power level of the packet in dBm. Returns {@link Integer#MIN_VALUE}
+     * if
+     * the field is not set. This value can be used to calculate the path loss of a received packet
+     * using the following equation:
+     *
+     * <p><code>pathloss = txPowerLevel - rssi</code>
+     */
+    public int getTxPowerLevel() {
+        return mTxPowerLevel;
+    }
+
+    /** Returns the local name of the BLE device. The is a UTF-8 encoded string. */
+    @Nullable
+    public String getDeviceName() {
+        return mDeviceName;
+    }
+
+    /** Returns raw bytes of scan record. */
+    public byte[] getBytes() {
+        return mBytes;
+    }
+
+    /**
+     * Parse scan record bytes to {@link BleRecord}.
+     *
+     * <p>The format is defined in Bluetooth 4.1 specification, Volume 3, Part C, Section 11 and 18.
+     *
+     * <p>All numerical multi-byte entities and values shall use little-endian <strong>byte</strong>
+     * order.
+     *
+     * @param scanRecord The scan record of Bluetooth LE advertisement and/or scan response.
+     */
+    public static BleRecord parseFromBytes(byte[] scanRecord) {
+        int currentPos = 0;
+        int advertiseFlag = -1;
+        List<ParcelUuid> serviceUuids = new ArrayList<>();
+        String localName = null;
+        int txPowerLevel = Integer.MIN_VALUE;
+
+        SparseArray<byte[]> manufacturerData = new SparseArray<>();
+        Map<ParcelUuid, byte[]> serviceData = new HashMap<>();
+
+        try {
+            while (currentPos < scanRecord.length) {
+                // length is unsigned int.
+                int length = scanRecord[currentPos++] & 0xFF;
+                if (length == 0) {
+                    break;
+                }
+                // Note the length includes the length of the field type itself.
+                int dataLength = length - 1;
+                // fieldType is unsigned int.
+                int fieldType = scanRecord[currentPos++] & 0xFF;
+                switch (fieldType) {
+                    case DATA_TYPE_FLAGS:
+                        advertiseFlag = scanRecord[currentPos] & 0xFF;
+                        break;
+                    case DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL:
+                    case DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE:
+                        parseServiceUuid(scanRecord, currentPos, dataLength, UUID_BYTES_16_BIT,
+                                serviceUuids);
+                        break;
+                    case DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL:
+                    case DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE:
+                        parseServiceUuid(scanRecord, currentPos, dataLength, UUID_BYTES_32_BIT,
+                                serviceUuids);
+                        break;
+                    case DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL:
+                    case DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE:
+                        parseServiceUuid(scanRecord, currentPos, dataLength, UUID_BYTES_128_BIT,
+                                serviceUuids);
+                        break;
+                    case DATA_TYPE_LOCAL_NAME_SHORT:
+                    case DATA_TYPE_LOCAL_NAME_COMPLETE:
+                        localName = new String(extractBytes(scanRecord, currentPos, dataLength));
+                        break;
+                    case DATA_TYPE_TX_POWER_LEVEL:
+                        txPowerLevel = scanRecord[currentPos];
+                        break;
+                    case DATA_TYPE_SERVICE_DATA:
+                        // The first two bytes of the service data are service data UUID in little
+                        // endian. The rest bytes are service data.
+                        int serviceUuidLength = UUID_BYTES_16_BIT;
+                        byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
+                                serviceUuidLength);
+                        ParcelUuid serviceDataUuid = parseUuidFrom(serviceDataUuidBytes);
+                        byte[] serviceDataArray =
+                                extractBytes(
+                                        scanRecord, currentPos + serviceUuidLength,
+                                        dataLength - serviceUuidLength);
+                        serviceData.put(serviceDataUuid, serviceDataArray);
+                        break;
+                    case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
+                        // The first two bytes of the manufacturer specific data are
+                        // manufacturer ids in little endian.
+                        int manufacturerId =
+                                ((scanRecord[currentPos + 1] & 0xFF) << 8) + (scanRecord[currentPos]
+                                        & 0xFF);
+                        byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2,
+                                dataLength - 2);
+                        manufacturerData.put(manufacturerId, manufacturerDataBytes);
+                        break;
+                    default:
+                        // Just ignore, we don't handle such data type.
+                        break;
+                }
+                currentPos += dataLength;
+            }
+
+            return new BleRecord(
+                    serviceUuids,
+                    manufacturerData,
+                    serviceData,
+                    advertiseFlag,
+                    txPowerLevel,
+                    localName,
+                    scanRecord);
+        } catch (Exception e) {
+            Log.w("BleRecord", "Unable to parse scan record: " + Arrays.toString(scanRecord), e);
+            // As the record is invalid, ignore all the parsed results for this packet
+            // and return an empty record with raw scanRecord bytes in results
+            // check at the top of this method does? Maybe we expect callers to use the
+            // scanRecord part in
+            // some fallback. But if that's the reason, it would seem we still can return null.
+            // They still
+            // have the raw scanRecord in hand, 'cause they passed it to us. It seems too easy for a
+            // caller to misuse this "empty" BleRecord (as in b/22693067).
+            return new BleRecord(ImmutableList.of(), null, null, -1, Integer.MIN_VALUE, null,
+                    scanRecord);
+        }
+    }
+
+    // Parse service UUIDs.
+    private static int parseServiceUuid(
+            byte[] scanRecord,
+            int currentPos,
+            int dataLength,
+            int uuidLength,
+            List<ParcelUuid> serviceUuids) {
+        while (dataLength > 0) {
+            byte[] uuidBytes = extractBytes(scanRecord, currentPos, uuidLength);
+            serviceUuids.add(parseUuidFrom(uuidBytes));
+            dataLength -= uuidLength;
+            currentPos += uuidLength;
+        }
+        return currentPos;
+    }
+
+    // Helper method to extract bytes from byte array.
+    private static byte[] extractBytes(byte[] scanRecord, int start, int length) {
+        byte[] bytes = new byte[length];
+        System.arraycopy(scanRecord, start, bytes, 0, length);
+        return bytes;
+    }
+
+    @Override
+    public String toString() {
+        return "BleRecord [advertiseFlags="
+                + mAdvertiseFlags
+                + ", serviceUuids="
+                + mServiceUuids
+                + ", manufacturerSpecificData="
+                + StringUtils.toString(mManufacturerSpecificData)
+                + ", serviceData="
+                + StringUtils.toString(mServiceData)
+                + ", txPowerLevel="
+                + mTxPowerLevel
+                + ", deviceName="
+                + mDeviceName
+                + "]";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof BleRecord)) {
+            return false;
+        }
+        BleRecord record = (BleRecord) obj;
+        // BleRecord objects are built from bytes, so we only need that field.
+        return Arrays.equals(mBytes, record.mBytes);
+    }
+
+    @Override
+    public int hashCode() {
+        // BleRecord objects are built from bytes, so we only need that field.
+        return Arrays.hashCode(mBytes);
+    }
+
+    /**
+     * Parse UUID from bytes. The {@code uuidBytes} can represent a 16-bit, 32-bit or 128-bit UUID,
+     * but the returned UUID is always in 128-bit format. Note UUID is little endian in Bluetooth.
+     *
+     * @param uuidBytes Byte representation of uuid.
+     * @return {@link ParcelUuid} parsed from bytes.
+     * @throws IllegalArgumentException If the {@code uuidBytes} cannot be parsed.
+     */
+    private static ParcelUuid parseUuidFrom(byte[] uuidBytes) {
+        if (uuidBytes == null) {
+            throw new IllegalArgumentException("uuidBytes cannot be null");
+        }
+        int length = uuidBytes.length;
+        if (length != UUID_BYTES_16_BIT
+                && length != UUID_BYTES_32_BIT
+                && length != UUID_BYTES_128_BIT) {
+            throw new IllegalArgumentException("uuidBytes length invalid - " + length);
+        }
+        // Construct a 128 bit UUID.
+        if (length == UUID_BYTES_128_BIT) {
+            ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN);
+            long msb = buf.getLong(8);
+            long lsb = buf.getLong(0);
+            return new ParcelUuid(new UUID(msb, lsb));
+        }
+        // For 16 bit and 32 bit UUID we need to convert them to 128 bit value.
+        // 128_bit_value = uuid * 2^96 + BASE_UUID
+        long shortUuid;
+        if (length == UUID_BYTES_16_BIT) {
+            shortUuid = uuidBytes[0] & 0xFF;
+            shortUuid += (uuidBytes[1] & 0xFF) << 8;
+        } else {
+            shortUuid = uuidBytes[0] & 0xFF;
+            shortUuid += (uuidBytes[1] & 0xFF) << 8;
+            shortUuid += (uuidBytes[2] & 0xFF) << 16;
+            shortUuid += (uuidBytes[3] & 0xFF) << 24;
+        }
+        long msb = BASE_UUID.getUuid().getMostSignificantBits() + (shortUuid << 32);
+        long lsb = BASE_UUID.getUuid().getLeastSignificantBits();
+        return new ParcelUuid(new UUID(msb, lsb));
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/ble/BleSighting.java b/nearby/service/java/com/android/server/nearby/common/ble/BleSighting.java
new file mode 100644
index 0000000..71ec10c
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/ble/BleSighting.java
@@ -0,0 +1,215 @@
+/*
+ * 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.server.nearby.common.ble;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.os.Build.VERSION_CODES;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.VisibleForTesting;
+
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A sighting of a BLE device found in a Bluetooth LE scan.
+ */
+
+public class BleSighting implements Parcelable {
+
+    public static final Parcelable.Creator<BleSighting> CREATOR = new Creator<BleSighting>() {
+        @Override
+        public BleSighting createFromParcel(Parcel source) {
+            BleSighting nBleSighting = new BleSighting(source.readParcelable(null),
+                    source.marshall(), source.readInt(), source.readLong());
+            return null;
+        }
+
+        @Override
+        public BleSighting[] newArray(int size) {
+            return new BleSighting[size];
+        }
+    };
+
+    // Max and min rssi value which is from {@link android.bluetooth.le.ScanResult#getRssi()}.
+    @VisibleForTesting
+    public static final int MAX_RSSI_VALUE = 126;
+    @VisibleForTesting
+    public static final int MIN_RSSI_VALUE = -127;
+
+    /** Remote bluetooth device. */
+    private final BluetoothDevice mDevice;
+
+    /**
+     * BLE record, including advertising data and response data. BleRecord is not parcelable, so
+     * this
+     * is created from bleRecordBytes.
+     */
+    private final BleRecord mBleRecord;
+
+    /** The bytes of a BLE record. */
+    private final byte[] mBleRecordBytes;
+
+    /** Received signal strength. */
+    private final int mRssi;
+
+    /** Nanos timestamp when the ble device was observed (epoch time). */
+    private final long mTimestampEpochNanos;
+
+    /**
+     * Constructor of a BLE sighting.
+     *
+     * @param device              Remote bluetooth device that is found.
+     * @param bleRecordBytes      The bytes that will create a BleRecord.
+     * @param rssi                Received signal strength.
+     * @param timestampEpochNanos Nanos timestamp when the BLE device was observed (epoch time).
+     */
+    public BleSighting(BluetoothDevice device, byte[] bleRecordBytes, int rssi,
+            long timestampEpochNanos) {
+        this.mDevice = device;
+        this.mBleRecordBytes = bleRecordBytes;
+        this.mRssi = rssi;
+        this.mTimestampEpochNanos = timestampEpochNanos;
+        mBleRecord = BleRecord.parseFromBytes(bleRecordBytes);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Returns the remote bluetooth device identified by the bluetooth device address. */
+    public BluetoothDevice getDevice() {
+        return mDevice;
+    }
+
+    /** Returns the BLE record, which is a combination of advertisement and scan response. */
+    public BleRecord getBleRecord() {
+        return mBleRecord;
+    }
+
+    /** Returns the bytes of the BLE record. */
+    public byte[] getBleRecordBytes() {
+        return mBleRecordBytes;
+    }
+
+    /** Returns the received signal strength in dBm. The valid range is [-127, 127]. */
+    public int getRssi() {
+        return mRssi;
+    }
+
+    /**
+     * Returns the received signal strength normalized with the offset specific to the given device.
+     * 3 is the rssi offset to calculate fast init distance.
+     * <p>This method utilized the rssi offset maintained by Nearby Sharing.
+     *
+     * @return normalized rssi which is between [-127, 126] according to {@link
+     * android.bluetooth.le.ScanResult#getRssi()}.
+     */
+    public int getNormalizedRSSI() {
+        int adjustedRssi = mRssi + 3;
+        if (adjustedRssi < MIN_RSSI_VALUE) {
+            return MIN_RSSI_VALUE;
+        } else if (adjustedRssi > MAX_RSSI_VALUE) {
+            return MAX_RSSI_VALUE;
+        } else {
+            return adjustedRssi;
+        }
+    }
+
+    /** Returns timestamp in epoch time when the scan record was observed. */
+    public long getTimestampNanos() {
+        return mTimestampEpochNanos;
+    }
+
+    /** Returns timestamp in epoch time when the scan record was observed, in millis. */
+    public long getTimestampMillis() {
+        return TimeUnit.NANOSECONDS.toMillis(mTimestampEpochNanos);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mDevice, flags);
+        dest.writeByteArray(mBleRecordBytes);
+        dest.writeInt(mRssi);
+        dest.writeLong(mTimestampEpochNanos);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mDevice, mRssi, mTimestampEpochNanos, Arrays.hashCode(mBleRecordBytes));
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof BleSighting)) {
+            return false;
+        }
+        BleSighting other = (BleSighting) obj;
+        return Objects.equals(mDevice, other.mDevice)
+                && mRssi == other.mRssi
+                && Arrays.equals(mBleRecordBytes, other.mBleRecordBytes)
+                && mTimestampEpochNanos == other.mTimestampEpochNanos;
+    }
+
+    @Override
+    public String toString() {
+        return "BleSighting{"
+                + "device="
+                + mDevice
+                + ", bleRecord="
+                + mBleRecord
+                + ", rssi="
+                + mRssi
+                + ", timestampNanos="
+                + mTimestampEpochNanos
+                + "}";
+    }
+
+    /** Creates {@link BleSighting} using the {@link ScanResult}. */
+    @RequiresApi(api = VERSION_CODES.LOLLIPOP)
+    @Nullable
+    public static BleSighting createFromOsScanResult(ScanResult osResult) {
+        ScanRecord osScanRecord = osResult.getScanRecord();
+        if (osScanRecord == null) {
+            return null;
+        }
+
+        return new BleSighting(
+                osResult.getDevice(),
+                osScanRecord.getBytes(),
+                osResult.getRssi(),
+                // The timestamp from ScanResult is 'nanos since boot', Beacon lib will change it
+                // as 'nanos
+                // since epoch', but Nearby never reference this field, just pass it as 'nanos
+                // since boot'.
+                // ref to beacon/scan/impl/LBluetoothLeScannerCompat.fromOs for beacon design
+                // about how to
+                // convert nanos since boot to epoch.
+                osResult.getTimestampNanos());
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/ble/decode/BeaconDecoder.java b/nearby/service/java/com/android/server/nearby/common/ble/decode/BeaconDecoder.java
new file mode 100644
index 0000000..9e795ac
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/ble/decode/BeaconDecoder.java
@@ -0,0 +1,106 @@
+/*
+ * 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.server.nearby.common.ble.decode;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.ble.BleRecord;
+
+/**
+ * This class encapsulates the logic specific to each manufacturer for parsing formats for beacons,
+ * and presents a common API to access important ADV/EIR packet fields such as:
+ *
+ * <ul>
+ *   <li><b>UUID (universally unique identifier)</b>, a value uniquely identifying a group of one or
+ *       more beacons as belonging to an organization or of a certain type, up to 128 bits.
+ *   <li><b>Instance</b> a 32-bit unsigned integer that can be used to group related beacons that
+ *       have the same UUID.
+ *   <li>the mathematics of <b>TX signal strength</b>, used for proximity calculations.
+ * </ul>
+ *
+ * ...and others.
+ *
+ * @see <a href="http://go/ble-glossary">BLE Glossary</a>
+ * @see <a href="https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=245130">Bluetooth
+ * Data Types Specification</a>
+ */
+public abstract class BeaconDecoder {
+    /**
+     * Returns true if the bleRecord corresponds to a beacon format that contains sufficient
+     * information to construct a BeaconId and contains the Tx power.
+     */
+    public boolean supportsBeaconIdAndTxPower(@SuppressWarnings("unused") BleRecord bleRecord) {
+        return true;
+    }
+
+    /**
+     * Returns true if this decoder supports returning TxPower via {@link
+     * #getCalibratedBeaconTxPower(BleRecord)}.
+     */
+    public boolean supportsTxPower() {
+        return true;
+    }
+
+    /**
+     * Reads the calibrated transmitted power at 1 meter of the beacon in dBm. This value is
+     * contained
+     * in the scan record, as set by the transmitting beacon. Suitable for use in computing path
+     * loss,
+     * distance, and related derived values.
+     *
+     * @param bleRecord the parsed payload contained in the beacon packet
+     * @return integer value of the calibrated Tx power in dBm or null if the bleRecord doesn't
+     * contain sufficient information to calculate the Tx power.
+     */
+    @Nullable
+    public abstract Integer getCalibratedBeaconTxPower(BleRecord bleRecord);
+
+    /**
+     * Extract telemetry information from the beacon. Byte 0 of the returned telemetry block should
+     * encode the telemetry format.
+     *
+     * @return telemetry block for this beacon, or null if no telemetry data is found in the scan
+     * record.
+     */
+    @Nullable
+    public byte[] getTelemetry(@SuppressWarnings("unused") BleRecord bleRecord) {
+        return null;
+    }
+
+    /** Returns the appropriate type for this scan record. */
+    public abstract int getBeaconIdType();
+
+    /**
+     * Returns an array of bytes which uniquely identify this beacon, for beacons from any of the
+     * supported beacon types. This unique identifier is the indexing key for various internal
+     * services. Returns null if the bleRecord doesn't contain sufficient information to construct
+     * the
+     * ID.
+     */
+    @Nullable
+    public abstract byte[] getBeaconIdBytes(BleRecord bleRecord);
+
+    /**
+     * Returns the URL of the beacon. Returns null if the bleRecord doesn't contain a URL or
+     * contains
+     * a malformed URL.
+     */
+    @Nullable
+    public String getUrl(BleRecord bleRecord) {
+        return null;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/ble/decode/FastPairDecoder.java b/nearby/service/java/com/android/server/nearby/common/ble/decode/FastPairDecoder.java
new file mode 100644
index 0000000..c1ff9fd
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/ble/decode/FastPairDecoder.java
@@ -0,0 +1,297 @@
+/*
+ * 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.server.nearby.common.ble.decode;
+
+import android.bluetooth.le.ScanRecord;
+import android.os.ParcelUuid;
+import android.util.Log;
+import android.util.SparseArray;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.ble.BleFilter;
+import com.android.server.nearby.common.ble.BleRecord;
+
+import java.util.Arrays;
+
+/**
+ * Parses Fast Pair information out of {@link BleRecord}s.
+ *
+ * <p>There are 2 different packet formats that are supported, which is used can be determined by
+ * packet length:
+ *
+ * <p>For 3-byte packets, the full packet is the model ID.
+ *
+ * <p>For all other packets, the first byte is the header, followed by the model ID, followed by
+ * zero or more extra fields. Each field has its own header byte followed by the field value. The
+ * packet header is formatted as 0bVVVLLLLR (V = version, L = model ID length, R = reserved) and
+ * each extra field header is 0bLLLLTTTT (L = field length, T = field type).
+ *
+ * @see <a href="http://go/fast-pair-2-service-data">go/fast-pair-2-service-data</a>
+ */
+public class FastPairDecoder extends BeaconDecoder {
+
+    private static final int FIELD_TYPE_BLOOM_FILTER = 0;
+    private static final int FIELD_TYPE_BLOOM_FILTER_SALT = 1;
+    private static final int FIELD_TYPE_BLOOM_FILTER_NO_NOTIFICATION = 2;
+    private static final int FIELD_TYPE_BATTERY = 3;
+    private static final int FIELD_TYPE_BATTERY_NO_NOTIFICATION = 4;
+    public static final int FIELD_TYPE_CONNECTION_STATE = 5;
+    private static final int FIELD_TYPE_RANDOM_RESOLVABLE_DATA = 6;
+
+    /** FE2C is the 16-bit Service UUID. The rest is the base UUID. See BluetoothUuid (hidden). */
+    private static final ParcelUuid FAST_PAIR_SERVICE_PARCEL_UUID =
+            ParcelUuid.fromString("0000FE2C-0000-1000-8000-00805F9B34FB");
+
+    /** The filter you use to scan for Fast Pair BLE advertisements. */
+    public static final BleFilter FILTER =
+            new BleFilter.Builder().setServiceData(FAST_PAIR_SERVICE_PARCEL_UUID,
+                    new byte[0]).build();
+
+    // NOTE: Ensure that all bitmasks are always ints, not bytes so that bitshifting works correctly
+    // without needing worry about signing errors.
+    private static final int HEADER_VERSION_BITMASK = 0b11100000;
+    private static final int HEADER_LENGTH_BITMASK = 0b00011110;
+    private static final int HEADER_VERSION_OFFSET = 5;
+    private static final int HEADER_LENGTH_OFFSET = 1;
+
+    private static final int EXTRA_FIELD_LENGTH_BITMASK = 0b11110000;
+    private static final int EXTRA_FIELD_TYPE_BITMASK = 0b00001111;
+    private static final int EXTRA_FIELD_LENGTH_OFFSET = 4;
+    private static final int EXTRA_FIELD_TYPE_OFFSET = 0;
+
+    private static final int MIN_ID_LENGTH = 3;
+    private static final int MAX_ID_LENGTH = 14;
+    private static final int HEADER_INDEX = 0;
+    private static final int HEADER_LENGTH = 1;
+    private static final int FIELD_HEADER_LENGTH = 1;
+
+    // Not using java.util.IllegalFormatException because it is unchecked.
+    private static class IllegalFormatException extends Exception {
+        private IllegalFormatException(String message) {
+            super(message);
+        }
+    }
+
+    @Nullable
+    @Override
+    public Integer getCalibratedBeaconTxPower(BleRecord bleRecord) {
+        return null;
+    }
+
+    // TODO(b/205320613) create beacon type
+    @Override
+    public int getBeaconIdType() {
+        return 1;
+    }
+
+    /** Returns the Model ID from our service data, if present. */
+    @Nullable
+    @Override
+    public byte[] getBeaconIdBytes(BleRecord bleRecord) {
+        return getModelId(bleRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID));
+    }
+
+    /** Returns the Model ID from our service data, if present. */
+    @Nullable
+    public static byte[] getModelId(@Nullable byte[] serviceData) {
+        if (serviceData == null) {
+            return null;
+        }
+
+        if (serviceData.length >= MIN_ID_LENGTH) {
+            if (serviceData.length == MIN_ID_LENGTH) {
+                // If the length == 3, all bytes are the ID. See flag docs for more about
+                // endianness.
+                return serviceData;
+            } else {
+                // Otherwise, the first byte is a header which contains the length of the
+                // big-endian model
+                // ID that follows. The model ID will be trimmed if it contains leading zeros.
+                int idIndex = 1;
+                int end = idIndex + getIdLength(serviceData);
+                while (serviceData[idIndex] == 0 && end - idIndex > MIN_ID_LENGTH) {
+                    idIndex++;
+                }
+                return Arrays.copyOfRange(serviceData, idIndex, end);
+            }
+        }
+        return null;
+    }
+
+    /** Gets the FastPair service data array if available, otherwise returns null. */
+    @Nullable
+    public static byte[] getServiceDataArray(BleRecord bleRecord) {
+        return bleRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID);
+    }
+
+    /** Gets the FastPair service data array if available, otherwise returns null. */
+    @Nullable
+    public static byte[] getServiceDataArray(ScanRecord scanRecord) {
+        return scanRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID);
+    }
+
+    /** Gets the bloom filter from the extra fields if available, otherwise returns null. */
+    @Nullable
+    public static byte[] getBloomFilter(@Nullable byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER);
+    }
+
+    /** Gets the bloom filter salt from the extra fields if available, otherwise returns null. */
+    @Nullable
+    public static byte[] getBloomFilterSalt(byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER_SALT);
+    }
+
+    /**
+     * Gets the suppress notification with bloom filter from the extra fields if available,
+     * otherwise
+     * returns null.
+     */
+    @Nullable
+    public static byte[] getBloomFilterNoNotification(@Nullable byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER_NO_NOTIFICATION);
+    }
+
+    /** Gets the battery level from extra fields if available, otherwise return null. */
+    @Nullable
+    public static byte[] getBatteryLevel(byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_BATTERY);
+    }
+
+    /**
+     * Gets the suppress notification with battery level from extra fields if available, otherwise
+     * return null.
+     */
+    @Nullable
+    public static byte[] getBatteryLevelNoNotification(byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_BATTERY_NO_NOTIFICATION);
+    }
+
+    /**
+     * Gets the random resolvable data from extra fields if available, otherwise
+     * return null.
+     */
+    @Nullable
+    public static byte[] getRandomResolvableData(byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_RANDOM_RESOLVABLE_DATA);
+    }
+
+    @Nullable
+    private static byte[] getExtraField(@Nullable byte[] serviceData, int fieldId) {
+        if (serviceData == null || serviceData.length < HEADER_INDEX + HEADER_LENGTH) {
+            return null;
+        }
+        try {
+            return getExtraFields(serviceData).get(fieldId);
+        } catch (IllegalFormatException e) {
+            Log.v("FastPairDecode", "Extra fields incorrectly formatted.");
+            return null;
+        }
+    }
+
+    /** Gets extra field data at the end of the packet, defined by the extra field header. */
+    private static SparseArray<byte[]> getExtraFields(byte[] serviceData)
+            throws IllegalFormatException {
+        SparseArray<byte[]> extraFields = new SparseArray<>();
+        if (getVersion(serviceData) != 0) {
+            return extraFields;
+        }
+        int headerIndex = getFirstExtraFieldHeaderIndex(serviceData);
+        while (headerIndex < serviceData.length) {
+            int length = getExtraFieldLength(serviceData, headerIndex);
+            int index = headerIndex + FIELD_HEADER_LENGTH;
+            int type = getExtraFieldType(serviceData, headerIndex);
+            int end = index + length;
+            if (extraFields.get(type) == null) {
+                if (end <= serviceData.length) {
+                    extraFields.put(type, Arrays.copyOfRange(serviceData, index, end));
+                } else {
+                    throw new IllegalFormatException(
+                            "Invalid length, " + end + " is longer than service data size "
+                                    + serviceData.length);
+                }
+            }
+            headerIndex = end;
+        }
+        return extraFields;
+    }
+
+    /** Checks whether or not a valid ID is included in the service data packet. */
+    public static boolean hasBeaconIdBytes(BleRecord bleRecord) {
+        byte[] serviceData = bleRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID);
+        return checkModelId(serviceData);
+    }
+
+    /** Check whether byte array is FastPair model id or not. */
+    public static boolean checkModelId(@Nullable byte[] scanResult) {
+        return scanResult != null
+                // The 3-byte format has no header byte (all bytes are the ID).
+                && (scanResult.length == MIN_ID_LENGTH
+                // Header byte exists. We support only format version 0. (A different version
+                // indicates
+                // a breaking change in the format.)
+                || (scanResult.length > MIN_ID_LENGTH
+                && getVersion(scanResult) == 0
+                && isIdLengthValid(scanResult)));
+    }
+
+    /** Checks whether or not bloom filter is included in the service data packet. */
+    public static boolean hasBloomFilter(BleRecord bleRecord) {
+        return (getBloomFilter(getServiceDataArray(bleRecord)) != null
+                || getBloomFilterNoNotification(getServiceDataArray(bleRecord)) != null);
+    }
+
+    /** Checks whether or not bloom filter is included in the service data packet. */
+    public static boolean hasBloomFilter(ScanRecord scanRecord) {
+        return (getBloomFilter(getServiceDataArray(scanRecord)) != null
+                || getBloomFilterNoNotification(getServiceDataArray(scanRecord)) != null);
+    }
+
+    private static int getVersion(byte[] serviceData) {
+        return serviceData.length == MIN_ID_LENGTH
+                ? 0
+                : (serviceData[HEADER_INDEX] & HEADER_VERSION_BITMASK) >> HEADER_VERSION_OFFSET;
+    }
+
+    private static int getIdLength(byte[] serviceData) {
+        return serviceData.length == MIN_ID_LENGTH
+                ? MIN_ID_LENGTH
+                : (serviceData[HEADER_INDEX] & HEADER_LENGTH_BITMASK) >> HEADER_LENGTH_OFFSET;
+    }
+
+    private static int getFirstExtraFieldHeaderIndex(byte[] serviceData) {
+        return HEADER_INDEX + HEADER_LENGTH + getIdLength(serviceData);
+    }
+
+    private static int getExtraFieldLength(byte[] serviceData, int extraFieldIndex) {
+        return (serviceData[extraFieldIndex] & EXTRA_FIELD_LENGTH_BITMASK)
+                >> EXTRA_FIELD_LENGTH_OFFSET;
+    }
+
+    private static int getExtraFieldType(byte[] serviceData, int extraFieldIndex) {
+        return (serviceData[extraFieldIndex] & EXTRA_FIELD_TYPE_BITMASK) >> EXTRA_FIELD_TYPE_OFFSET;
+    }
+
+    private static boolean isIdLengthValid(byte[] serviceData) {
+        int idLength = getIdLength(serviceData);
+        return MIN_ID_LENGTH <= idLength
+                && idLength <= MAX_ID_LENGTH
+                && idLength + HEADER_LENGTH <= serviceData.length;
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/ble/testing/FastPairTestData.java b/nearby/service/java/com/android/server/nearby/common/ble/testing/FastPairTestData.java
new file mode 100644
index 0000000..f27899f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/ble/testing/FastPairTestData.java
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.common.ble.testing;
+
+import com.android.server.nearby.util.ArrayUtils;
+import com.android.server.nearby.util.Hex;
+
+/**
+ * Test class to provide example to unit test.
+ */
+public class FastPairTestData {
+    private static final byte[] FAST_PAIR_RECORD_BIG_ENDIAN =
+            Hex.stringToBytes("02011E020AF006162CFEAABBCC");
+
+    /**
+     * A Fast Pair frame, Note: The service UUID is FE2C, but in the
+     * packet it's 2CFE, since the core Bluetooth data types are little-endian.
+     *
+     * <p>However, the model ID is big-endian (multi-byte values in our spec are now big-endian, aka
+     * network byte order).
+     *
+     * @see {http://go/fast-pair-service-data}
+     */
+    public static byte[] getFastPairRecord() {
+        return FAST_PAIR_RECORD_BIG_ENDIAN;
+    }
+
+    /** A Fast Pair frame, with a shared account key. */
+    public static final byte[] FAST_PAIR_SHARED_ACCOUNT_KEY_RECORD =
+            Hex.stringToBytes("02011E020AF00C162CFE007011223344556677");
+
+    /** Model ID in {@link #getFastPairRecord()}. */
+    public static final byte[] FAST_PAIR_MODEL_ID = Hex.stringToBytes("AABBCC");
+
+    /** @see #getFastPairRecord() */
+    public static byte[] newFastPairRecord(byte header, byte[] modelId) {
+        return newFastPairRecord(
+                modelId.length == 3 ? modelId : ArrayUtils.concatByteArrays(new byte[] {header},
+                        modelId));
+    }
+
+    /** @see #getFastPairRecord() */
+    public static byte[] newFastPairRecord(byte[] serviceData) {
+        int length = /* length of type and service UUID = */ 3 + serviceData.length;
+        return Hex.stringToBytes(
+                String.format("02011E020AF0%02X162CFE%s", length,
+                        Hex.bytesToStringUppercase(serviceData)));
+    }
+
+    // This is an example of advertising data with AD types
+    public static byte[] adv_1 = {
+            0x02, // Length of this Data
+            0x01, // <<Flags>>
+            0x01, // LE Limited Discoverable Mode
+            0x0A, // Length of this Data
+            0x09, // <<Complete local name>>
+            'P', 'e', 'd', 'o', 'm', 'e', 't', 'e', 'r'
+    };
+
+    // This is an example of advertising data with positive TX Power
+    // Level.
+    public static byte[] adv_2 = {
+            0x02, // Length of this Data
+            0x0a, // <<TX Power Level>>
+            127 // Level = 127
+    };
+
+    // Example data including a service data block
+    public static byte[] sd1 = {
+            0x02, // Length of this Data
+            0x01, // <<Flags>>
+            0x04, // BR/EDR Not Supported.
+            0x03, // Length of this Data
+            0x02, // <<Incomplete List of 16-bit Service UUIDs>>
+            0x04,
+            0x18, // TX Power Service UUID
+            0x1e, // Length of this Data
+            (byte) 0x16, // <<Service Specific Data>>
+            // Service UUID
+            (byte) 0xe0,
+            0x00,
+            // gBeacon Header
+            0x15,
+            // Running time ENCRYPT
+            (byte) 0xd2,
+            0x77,
+            0x01,
+            0x00,
+            // Scan Freq ENCRYPT
+            0x32,
+            0x05,
+            // Time in slow mode
+            0x00,
+            0x00,
+            // Time in fast mode
+            0x7f,
+            0x17,
+            // Subset of UID
+            0x56,
+            0x00,
+            // ID Mask
+            (byte) 0xd4,
+            0x7c,
+            0x18,
+            // RFU (reserved)
+            0x00,
+            // GUID = decimal 1297482358
+            0x76,
+            0x02,
+            0x56,
+            0x4d,
+            0x00,
+            // Ranging Payload Header
+            0x24,
+            // MAC of scanning address
+            (byte) 0xa4,
+            (byte) 0xbb,
+            // NORM RX RSSI -67dBm
+            (byte) 0xb0,
+            // NORM TX POWER -77dBm, so actual TX POWER = -36dBm
+            (byte) 0xb3,
+            // Note based on the values aboves PATH LOSS = (-36) - (-67) = 31dBm
+            // Below zero padding added to test it is handled correctly
+            0x00
+    };
+
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/ble/util/RangingUtils.java b/nearby/service/java/com/android/server/nearby/common/ble/util/RangingUtils.java
new file mode 100644
index 0000000..321e125
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/ble/util/RangingUtils.java
@@ -0,0 +1,163 @@
+/*
+ * 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.server.nearby.common.ble.util;
+
+
+/**
+ * Ranging utilities embody the physics of converting RF path loss to distance. The free space path
+ * loss is proportional to the square of the distance from transmitter to receiver, and to the
+ * square of the frequency of the propagation signal.
+ */
+public final class RangingUtils {
+    /*
+     * Key to variable names used in this class (viz. Physics):
+     *
+     * c   = speed of light (2.9979 x 10^8 m/s);
+     * f   = frequency (Bluetooth center frequency is 2.44175GHz = 2.44175x10^9 Hz);
+     * l   = wavelength (meters);
+     * d   = distance (from transmitter to receiver in meters);
+     * dB  = decibels
+     * dBm = decibel milliwatts
+     *
+     *
+     * Free-space path loss (FSPL) is proportional to the square of the distance between the
+     * transmitter and the receiver, and also proportional to the square of the frequency of the
+     * radio signal.
+     *
+     * FSPL      = (4 * pi * d / l)^2 = (4 * pi * d * f / c)^2
+     *
+     * FSPL (dB) = 10*log10((4 * pi * d * f / c)^2)
+     *           = 20*log10(4 * pi * d * f / c)
+     *           = 20*log10(d) + 20*log10(f) + 20*log10(4*pi/c)
+     *
+     * Calculating constants:
+     *
+     * FSPL_FREQ        = 20*log10(f)
+     *                  = 20*log10(2.44175 * 10^9)
+     *                  = 187.75
+     *
+     * FSPL_LIGHT       = 20*log10(4*pi/c)
+     *                  = 20*log10(4*pi/(2.9979*10^8))
+     *                  = -147.55
+     *
+     * FSPL_DISTANCE_1M = 20*log10(1m)
+     *                  = 0
+     *
+     * PATH_LOSS_AT_1M  = FSPL_DISTANCE_1M + FSPL_FREQ + FSPL_LIGHT
+     *                  = 0                + 187.75    + (-147.55)
+     *                  = 40.20 [round to 41]
+     *
+     * Note that PATH_LOSS_AT_1M is rounded to 41 instead to the more natural 40. The first version
+     * of this file had a typo that caused the value to be close to 41; when this was discovered,
+     * the value 41 was already used in many places, and it was more important to be consistent
+     * rather than exact.
+     *
+     * Given this we can work out a formula for distance from a given RSSI (received signal strength
+     * indicator) and a given value for the expected strength at one meter from the beacon (aka
+     * calibrated transmission power). Both values are in dBm.
+     *
+     * FSPL = 20*log10(d) + PATH_LOSS_AT_1M = full_power - RSSI
+     *        20*log10(d) + PATH_LOSS_AT_1M = power_at_1m + PATH_LOSS_AT_1M - RSSI
+     *        20*log10(d)                   = power_at_1m - RSSI
+     *           log10(d)                   = (power_at_1m - RSSI) / 20
+     *                 d                    = 10 ^ ((power_at_1m - RSSI) / 20)
+     *
+     * Note: because of how logarithms work, units get a bit funny. If you take a two values x and y
+     * whose units are dBm, the value of x - y has units of dB, not dBm. Similarly, if x is dBm and
+     * y is in dB, then x - y will be in dBm.
+     */
+
+    /* (dBm) PATH_LOSS at 1m for isotropic antenna transmitting BLE */
+    public static final int PATH_LOSS_AT_1M = 41;
+
+    /** Different region categories, based on distance range. */
+    public static final class Region {
+
+        public static final int UNKNOWN = -1;
+        public static final int NEAR = 0;
+        public static final int MID = 1;
+        public static final int FAR = 2;
+
+        private Region() {}
+    }
+
+    // Cutoff distances between different regions.
+    public static final double NEAR_TO_MID_METERS = 0.5;
+    public static final double MID_TO_FAR_METERS = 2.0;
+
+    public static final int DEFAULT_CALIBRATED_TX_POWER = -77;
+
+    private RangingUtils() {}
+
+    /**
+     * Convert RSSI to path loss using the free space path loss equation. See <a
+     * href="http://en.wikipedia.org/wiki/Free-space_path_loss">Free-space_path_loss</a>
+     *
+     * @param rssi Received Signal Strength Indication (RSSI) in dBm
+     * @param calibratedTxPower the calibrated power of the transmitter (dBm) at 1 meter
+     * @return The calculated path loss.
+     */
+    public static int pathLossFromRssi(int rssi, int calibratedTxPower) {
+        return calibratedTxPower + PATH_LOSS_AT_1M - rssi;
+    }
+
+    /**
+     * Convert RSSI to distance using the free space path loss equation. See <a
+     * href="http://en.wikipedia.org/wiki/Free-space_path_loss">Free-space_path_loss</a>
+     *
+     * @param rssi Received Signal Strength Indication (RSSI) in dBm
+     * @param calibratedTxPower the calibrated power of the transmitter (dBm) at 1 meter
+     * @return the distance at which that rssi value would occur in meters
+     */
+    public static double distanceFromRssi(int rssi, int calibratedTxPower) {
+        return Math.pow(10, (calibratedTxPower - rssi) / 20.0);
+    }
+
+    /**
+     * Determine the region of a beacon given its perceived distance.
+     *
+     * @param distance The measured distance in meters.
+     * @return the region as one of the constants in {@link Region}.
+     */
+    public static int regionFromDistance(double distance) {
+        if (distance < 0) {
+            return Region.UNKNOWN;
+        }
+        if (distance <= NEAR_TO_MID_METERS) {
+            return Region.NEAR;
+        }
+        if (distance <= MID_TO_FAR_METERS) {
+            return Region.MID;
+        }
+        return Region.FAR;
+    }
+
+    /**
+     * Convert distance to RSSI using the free space path loss equation. See <a
+     * href="http://en.wikipedia.org/wiki/Free-space_path_loss">Free-space_path_loss</a>
+     *
+     * @param distanceInMeters distance in meters (m)
+     * @param calibratedTxPower transmitted power (dBm) calibrated to 1 meter
+     * @return the rssi (dBm) that would be measured at that distance
+     */
+    public static int rssiFromDistance(double distanceInMeters, int calibratedTxPower) {
+        return distanceInMeters == 0
+                ? calibratedTxPower + PATH_LOSS_AT_1M
+                : (int) (calibratedTxPower - (20 * Math.log10(distanceInMeters)));
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/ble/util/StringUtils.java b/nearby/service/java/com/android/server/nearby/common/ble/util/StringUtils.java
new file mode 100644
index 0000000..4d90b6d
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/ble/util/StringUtils.java
@@ -0,0 +1,70 @@
+/*
+ * 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.server.nearby.common.ble.util;
+
+import android.annotation.Nullable;
+import android.util.SparseArray;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+
+/** Helper class for Bluetooth LE utils. */
+public final class StringUtils {
+    private StringUtils() {
+    }
+
+    /** Returns a string composed from a {@link SparseArray}. */
+    public static String toString(@Nullable SparseArray<byte[]> array) {
+        if (array == null) {
+            return "null";
+        }
+        if (array.size() == 0) {
+            return "{}";
+        }
+        StringBuilder buffer = new StringBuilder();
+        buffer.append('{');
+        for (int i = 0; i < array.size(); ++i) {
+            buffer.append(array.keyAt(i)).append("=").append(Arrays.toString(array.valueAt(i)));
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+
+    /** Returns a string composed from a {@link Map}. */
+    public static <T> String toString(@Nullable Map<T, byte[]> map) {
+        if (map == null) {
+            return "null";
+        }
+        if (map.isEmpty()) {
+            return "{}";
+        }
+        StringBuilder buffer = new StringBuilder();
+        buffer.append('{');
+        Iterator<Map.Entry<T, byte[]>> it = map.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<T, byte[]> entry = it.next();
+            Object key = entry.getKey();
+            buffer.append(key).append("=").append(Arrays.toString(map.get(key)));
+            if (it.hasNext()) {
+                buffer.append(", ");
+            }
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bloomfilter/BloomFilter.java b/nearby/service/java/com/android/server/nearby/common/bloomfilter/BloomFilter.java
new file mode 100644
index 0000000..6d4275f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bloomfilter/BloomFilter.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.common.bloomfilter;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.common.primitives.UnsignedInts;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.BitSet;
+
+/**
+ * A bloom filter that gives access to the underlying BitSet.
+ */
+public class BloomFilter {
+    private static final Charset CHARSET = UTF_8;
+
+    /**
+     * Receives a value and converts it into an array of ints that will be converted to indexes for
+     * the filter.
+     */
+    public interface Hasher {
+        /**
+         * Generate hash value.
+         */
+        int[] getHashes(byte[] value);
+    }
+
+    // The backing data for this bloom filter. As additions are made, they're OR'd until it
+    // eventually reaches 0xFF.
+    private final BitSet mBits;
+    // The max length of bits.
+    private final int mBitLength;
+    // The hasher to use for converting a value into an array of hashes.
+    private final Hasher mHasher;
+
+    public BloomFilter(byte[] bytes, Hasher hasher) {
+        this.mBits = BitSet.valueOf(bytes);
+        this.mBitLength = bytes.length * 8;
+        this.mHasher = hasher;
+    }
+
+    /**
+     * Return the bloom filter check bit set as byte array.
+     */
+    public byte[] asBytes() {
+        // BitSet.toByteArray() truncates all the unset bits after the last set bit (eg. [0,0,1,0]
+        // becomes [0,0,1]) so we re-add those bytes if needed with Arrays.copy().
+        byte[] b = mBits.toByteArray();
+        if (b.length == mBitLength / 8) {
+            return b;
+        }
+        return Arrays.copyOf(b, mBitLength / 8);
+    }
+
+    /**
+     * Add string value to bloom filter hash.
+     */
+    public void add(String s) {
+        add(s.getBytes(CHARSET));
+    }
+
+    /**
+     * Adds value to bloom filter hash.
+     */
+    public void add(byte[] value) {
+        int[] hashes = mHasher.getHashes(value);
+        for (int hash : hashes) {
+            mBits.set(UnsignedInts.remainder(hash, mBitLength));
+        }
+    }
+
+    /**
+     * Check if the string format has collision.
+     */
+    public boolean possiblyContains(String s) {
+        return possiblyContains(s.getBytes(CHARSET));
+    }
+
+    /**
+     * Checks if value after hash will have collision.
+     */
+    public boolean possiblyContains(byte[] value) {
+        int[] hashes = mHasher.getHashes(value);
+        for (int hash : hashes) {
+            if (!mBits.get(UnsignedInts.remainder(hash, mBitLength))) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/bloomfilter/FastPairBloomFilterHasher.java b/nearby/service/java/com/android/server/nearby/common/bloomfilter/FastPairBloomFilterHasher.java
new file mode 100644
index 0000000..0ccee97
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bloomfilter/FastPairBloomFilterHasher.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.common.bloomfilter;
+
+import com.google.common.hash.Hashing;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Hasher which hashes a value using SHA-256 and splits it into parts, each of which can be
+ * converted to an index.
+ */
+public class FastPairBloomFilterHasher implements BloomFilter.Hasher {
+
+    private static final int NUM_INDEXES = 8;
+
+    @Override
+    public int[] getHashes(byte[] value) {
+        byte[] hash = Hashing.sha256().hashBytes(value).asBytes();
+        ByteBuffer buffer = ByteBuffer.wrap(hash);
+        int[] hashes = new int[NUM_INDEXES];
+        for (int i = 0; i < NUM_INDEXES; i++) {
+            hashes[i] = buffer.getInt();
+        }
+        return hashes;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothConsts.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothConsts.java
new file mode 100644
index 0000000..3a02b18
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothConsts.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth;
+
+import java.util.UUID;
+
+/**
+ * Bluetooth constants.
+ */
+public class BluetoothConsts {
+
+    /**
+     * Default MTU when value is unknown.
+     */
+    public static final int DEFAULT_MTU = 23;
+
+    // The following random uuids are used to indicate that the device has dynamic services.
+    /**
+     * UUID of dynamic service.
+     */
+    public static final UUID SERVICE_DYNAMIC_SERVICE =
+            UUID.fromString("00000100-0af3-11e5-a6c0-1697f925ec7b");
+
+    /**
+     * UUID of dynamic characteristic.
+     */
+    public static final UUID SERVICE_DYNAMIC_CHARACTERISTIC =
+            UUID.fromString("00002A05-0af3-11e5-a6c0-1697f925ec7b");
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothException.java
new file mode 100644
index 0000000..db2e1cc
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth;
+
+/**
+ * {@link Exception} thrown during a Bluetooth operation.
+ */
+public class BluetoothException extends Exception {
+    /** Constructor. */
+    public BluetoothException(String message) {
+        super(message);
+    }
+
+    /** Constructor. */
+    public BluetoothException(String message, Throwable throwable) {
+        super(message, throwable);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothGattException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothGattException.java
new file mode 100644
index 0000000..5ac4882
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothGattException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth;
+
+/**
+ * Exception for Bluetooth GATT operations.
+ */
+public class BluetoothGattException extends BluetoothException {
+    private final int mErrorCode;
+
+    /** Constructor. */
+    public BluetoothGattException(String message, int errorCode) {
+        super(message);
+        mErrorCode = errorCode;
+    }
+
+    /** Constructor. */
+    public BluetoothGattException(String message, int errorCode, Throwable cause) {
+        super(message, cause);
+        mErrorCode = errorCode;
+    }
+
+    /** Returns Gatt error code. */
+    public int getGattErrorCode() {
+        return mErrorCode;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothTimeoutException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothTimeoutException.java
new file mode 100644
index 0000000..30fd188
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothTimeoutException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth;
+
+/**
+ * {@link Exception} thrown during a Bluetooth operation when a timeout occurs.
+ */
+public class BluetoothTimeoutException extends BluetoothException {
+
+    /** Constructor. */
+    public BluetoothTimeoutException(String message) {
+        super(message);
+    }
+
+    /** Constructor. */
+    public BluetoothTimeoutException(String message, Throwable throwable) {
+        super(message, throwable);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/ReservedUuids.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/ReservedUuids.java
new file mode 100644
index 0000000..249011a
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/ReservedUuids.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth;
+
+import java.util.UUID;
+
+/**
+ * Reserved UUIDS by BT SIG.
+ * <p>
+ * See https://developer.bluetooth.org for more details.
+ */
+public class ReservedUuids {
+    /** UUIDs reserved for services. */
+    public static class Services {
+        /**
+         * The Device Information Service exposes manufacturer and/or vendor info about a device.
+         * <p>
+         * See reserved UUID org.bluetooth.service.device_information.
+         */
+        public static final UUID DEVICE_INFORMATION = fromShortUuid((short) 0x180A);
+
+        /**
+         * Generic attribute service.
+         * <p>
+         * See reserved UUID org.bluetooth.service.generic_attribute.
+         */
+        public static final UUID GENERIC_ATTRIBUTE = fromShortUuid((short) 0x1801);
+    }
+
+    /** UUIDs reserved for characteristics. */
+    public static class Characteristics {
+        /**
+         * The value of this characteristic is a UTF-8 string representing the firmware revision for
+         * the firmware within the device.
+         * <p>
+         * See reserved UUID org.bluetooth.characteristic.firmware_revision_string.
+         */
+        public static final UUID FIRMWARE_REVISION_STRING = fromShortUuid((short) 0x2A26);
+
+        /**
+         * Service change characteristic.
+         * <p>
+         * See reserved UUID org.bluetooth.characteristic.gatt.service_changed.
+         */
+        public static final UUID SERVICE_CHANGE = fromShortUuid((short) 0x2A05);
+    }
+
+    /** UUIDs reserved for descriptors. */
+    public static class Descriptors {
+        /**
+         * This descriptor shall be persistent across connections for bonded devices. The Client
+         * Characteristic Configuration descriptor is unique for each client. A client may read and
+         * write this descriptor to determine and set the configuration for that client.
+         * Authentication and authorization may be required by the server to write this descriptor.
+         * The default value for the Client Characteristic Configuration descriptor is 0x00. Upon
+         * connection of non-binded clients, this descriptor is set to the default value.
+         * <p>
+         * See reserved UUID org.bluetooth.descriptor.gatt.client_characteristic_configuration.
+         */
+        public static final UUID CLIENT_CHARACTERISTIC_CONFIGURATION =
+                fromShortUuid((short) 0x2902);
+    }
+
+    /** The base 128-bit UUID representation of a 16-bit UUID */
+    public static final UUID BASE_16_BIT_UUID =
+            UUID.fromString("00000000-0000-1000-8000-00805F9B34FB");
+
+    /** Converts from short UUId to UUID. */
+    public static UUID fromShortUuid(short shortUuid) {
+        return new UUID(((((long) shortUuid) << 32) & 0x0000FFFF00000000L)
+                | ReservedUuids.BASE_16_BIT_UUID.getMostSignificantBits(),
+                ReservedUuids.BASE_16_BIT_UUID.getLeastSignificantBits());
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AccountKeyGenerator.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AccountKeyGenerator.java
new file mode 100644
index 0000000..28a9c33
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AccountKeyGenerator.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption.generateKey;
+
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.AccountKeyCharacteristic;
+
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * This is to generate account key with fast-pair style.
+ */
+public final class AccountKeyGenerator {
+
+    // Generate a key where the first byte is always defined as the type, 0x04. This maintains 15
+    // bytes of entropy in the key while also allowing providers to verify that they have received
+    // a properly formatted key and decrypted it correctly, minimizing the risk of replay attacks.
+
+    /**
+     * Creates account key.
+     */
+    public static byte[] createAccountKey() throws NoSuchAlgorithmException {
+        byte[] accountKey = generateKey();
+        accountKey[0] = AccountKeyCharacteristic.TYPE;
+        return accountKey;
+    }
+
+    private AccountKeyGenerator() {
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AdditionalDataEncoder.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AdditionalDataEncoder.java
new file mode 100644
index 0000000..c9ccfd5
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AdditionalDataEncoder.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.NONCE_SIZE;
+
+import static com.google.common.primitives.Bytes.concat;
+
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+
+/**
+ * Utilities for encoding/decoding the additional data packet and verifying both the data integrity
+ * and the authentication.
+ *
+ * <p>Additional Data packet is:
+ *
+ * <ol>
+ *   <li>AdditionalData_Packet[0 - 7]: the first 8-byte of HMAC.
+ *   <li>AdditionalData_Packet[8 - var]: the encrypted message by AES-CTR, with 8-byte nonce
+ *       appended to the front.
+ * </ol>
+ *
+ * See https://developers.google.com/nearby/fast-pair/spec#AdditionalData.
+ */
+public final class AdditionalDataEncoder {
+
+    static final int EXTRACT_HMAC_SIZE = 8;
+    static final int MAX_LENGTH_OF_DATA = 64;
+
+    /**
+     * Encodes the given data to additional data packet by the given secret.
+     */
+    static byte[] encodeAdditionalDataPacket(byte[] secret, byte[] additionalData)
+            throws GeneralSecurityException {
+        if (secret == null || secret.length != AesCtrMultipleBlockEncryption.KEY_LENGTH) {
+            throw new GeneralSecurityException(
+                    "Incorrect secret for encoding additional data packet, secret.length = "
+                            + (secret == null ? "NULL" : secret.length));
+        }
+
+        if ((additionalData == null)
+                || (additionalData.length == 0)
+                || (additionalData.length > MAX_LENGTH_OF_DATA)) {
+            throw new GeneralSecurityException(
+                    "Invalid data for encoding additional data packet, data = "
+                            + (additionalData == null ? "NULL" : additionalData.length));
+        }
+
+        byte[] encryptedData = AesCtrMultipleBlockEncryption.encrypt(secret, additionalData);
+        byte[] extractedHmac =
+                Arrays.copyOf(HmacSha256.build(secret, encryptedData), EXTRACT_HMAC_SIZE);
+
+        return concat(extractedHmac, encryptedData);
+    }
+
+    /**
+     * Decodes additional data packet by the given secret.
+     *
+     * @param secret AES-128 key used in the encryption to decrypt data
+     * @param additionalDataPacket additional data packet which is encoded by the given secret
+     * @return the data byte array decoded from the given packet
+     * @throws GeneralSecurityException if the given key or additional data packet is invalid for
+     * decoding
+     */
+    static byte[] decodeAdditionalDataPacket(byte[] secret, byte[] additionalDataPacket)
+            throws GeneralSecurityException {
+        if (secret == null || secret.length != AesCtrMultipleBlockEncryption.KEY_LENGTH) {
+            throw new GeneralSecurityException(
+                    "Incorrect secret for decoding additional data packet, secret.length = "
+                            + (secret == null ? "NULL" : secret.length));
+        }
+        if (additionalDataPacket == null
+                || additionalDataPacket.length <= EXTRACT_HMAC_SIZE
+                || additionalDataPacket.length
+                > (MAX_LENGTH_OF_DATA + EXTRACT_HMAC_SIZE + NONCE_SIZE)) {
+            throw new GeneralSecurityException(
+                    "Additional data packet size is incorrect, additionalDataPacket.length is "
+                            + (additionalDataPacket == null ? "NULL"
+                            : additionalDataPacket.length));
+        }
+
+        if (!verifyHmac(secret, additionalDataPacket)) {
+            throw new GeneralSecurityException(
+                    "Verify HMAC failed, could be incorrect key or packet.");
+        }
+        byte[] encryptedData =
+                Arrays.copyOfRange(
+                        additionalDataPacket, EXTRACT_HMAC_SIZE, additionalDataPacket.length);
+        return AesCtrMultipleBlockEncryption.decrypt(secret, encryptedData);
+    }
+
+    // Computes the HMAC of the given key and additional data, and compares the first 8-byte of the
+    // HMAC result with the one from additional data packet.
+    // Must call constant-time comparison to prevent a possible timing attack, e.g. time the same
+    // MAC with all different first byte for a given ciphertext, the right one will take longer as
+    // it will fail on the second byte's verification.
+    private static boolean verifyHmac(byte[] key, byte[] additionalDataPacket)
+            throws GeneralSecurityException {
+        byte[] packetHmac =
+                Arrays.copyOfRange(additionalDataPacket, /* from= */ 0, EXTRACT_HMAC_SIZE);
+        byte[] encryptedData =
+                Arrays.copyOfRange(
+                        additionalDataPacket, EXTRACT_HMAC_SIZE, additionalDataPacket.length);
+        byte[] computedHmac = Arrays.copyOf(
+                HmacSha256.build(key, encryptedData), EXTRACT_HMAC_SIZE);
+
+        return HmacSha256.compareTwoHMACs(packetHmac, computedHmac);
+    }
+
+    private AdditionalDataEncoder() {
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AesCtrMultipleBlockEncryption.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AesCtrMultipleBlockEncryption.java
new file mode 100644
index 0000000..50a818b
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AesCtrMultipleBlockEncryption.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.primitives.Bytes.concat;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+/**
+ * AES-CTR utilities used for encrypting and decrypting Fast Pair packets that contain multiple
+ * blocks. Encrypts input data by:
+ *
+ * <ol>
+ *   <li>encryptedBlock[i] = clearBlock[i] ^ AES(counter), and
+ *   <li>concat(encryptedBlock[0], encryptedBlock[1],...) to create the encrypted result, where
+ *   <li>counter: the 16-byte input of AES. counter = iv + block_index.
+ *   <li>iv: extend 8-byte nonce to 16 bytes with zero padding. i.e. concat(0x0000000000000000,
+ *       nonce).
+ *   <li>nonce: the cryptographically random 8 bytes, must never be reused with the same key.
+ * </ol>
+ */
+final class AesCtrMultipleBlockEncryption {
+
+    /** Length for AES-128 key. */
+    static final int KEY_LENGTH = AesEcbSingleBlockEncryption.KEY_LENGTH;
+
+    @VisibleForTesting
+    static final int AES_BLOCK_LENGTH = AesEcbSingleBlockEncryption.AES_BLOCK_LENGTH;
+
+    /** Length of the nonce, a byte array of cryptographically random bytes. */
+    static final int NONCE_SIZE = 8;
+
+    private static final int IV_SIZE = AES_BLOCK_LENGTH;
+    private static final int MAX_NUMBER_OF_BLOCKS = 4;
+
+    private AesCtrMultipleBlockEncryption() {}
+
+    /** Generates a 16-byte AES key. */
+    static byte[] generateKey() throws NoSuchAlgorithmException {
+        return AesEcbSingleBlockEncryption.generateKey();
+    }
+
+    /**
+     * Encrypts data using AES-CTR by the given secret.
+     *
+     * @param secret AES-128 key.
+     * @param data the plaintext to be encrypted.
+     * @return the encrypted data with the 8-byte nonce appended to the front.
+     */
+    static byte[] encrypt(byte[] secret, byte[] data) throws GeneralSecurityException {
+        byte[] nonce = generateNonce();
+        return concat(nonce, doAesCtr(secret, data, nonce));
+    }
+
+    /**
+     * Decrypts data using AES-CTR by the given secret and nonce.
+     *
+     * @param secret AES-128 key.
+     * @param data the first 8 bytes is the nonce, and the remaining is the encrypted data to be
+     *     decrypted.
+     * @return the decrypted data.
+     */
+    static byte[] decrypt(byte[] secret, byte[] data) throws GeneralSecurityException {
+        if (data == null || data.length <= NONCE_SIZE) {
+            throw new GeneralSecurityException(
+                    "Incorrect data length "
+                            + (data == null ? "NULL" : data.length)
+                            + " to decrypt, the data should contain nonce.");
+        }
+        byte[] nonce = Arrays.copyOf(data, NONCE_SIZE);
+        byte[] encryptedData = Arrays.copyOfRange(data, NONCE_SIZE, data.length);
+        return doAesCtr(secret, encryptedData, nonce);
+    }
+
+    /**
+     * Generates cryptographically random NONCE_SIZE bytes nonce. This nonce can be used only once.
+     * Always call this function to generate a new nonce before a new encryption.
+     */
+    // Suppression for a warning for potentially insecure random numbers on Android 4.3 and older.
+    // Fast Pair service is only for Android 6.0+ devices.
+    static byte[] generateNonce() {
+        SecureRandom random = new SecureRandom();
+        byte[] nonce = new byte[NONCE_SIZE];
+        random.nextBytes(nonce);
+
+        return nonce;
+    }
+
+    // AES-CTR implementation.
+    @VisibleForTesting
+    static byte[] doAesCtr(byte[] secret, byte[] data, byte[] nonce)
+            throws GeneralSecurityException {
+        if (secret.length != KEY_LENGTH) {
+            throw new IllegalArgumentException(
+                    "Incorrect key length for encryption, only supports 16-byte AES Key.");
+        }
+        if (nonce.length != NONCE_SIZE) {
+            throw new IllegalArgumentException(
+                    "Incorrect nonce length for encryption, "
+                            + "Fast Pair naming scheme only supports 8-byte nonce.");
+        }
+
+        // Keeps the following operations on this byte[], returns it as the final AES-CTR result.
+        byte[] aesCtrResult = new byte[data.length];
+        System.arraycopy(data, /*srcPos=*/ 0, aesCtrResult, /*destPos=*/ 0, data.length);
+
+        // Initializes counter as IV.
+        byte[] counter = createIv(nonce);
+        // The length of the given data is permitted to non-align block size.
+        int numberOfBlocks =
+                (data.length / AES_BLOCK_LENGTH) + ((data.length % AES_BLOCK_LENGTH == 0) ? 0 : 1);
+
+        if (numberOfBlocks > MAX_NUMBER_OF_BLOCKS) {
+            throw new IllegalArgumentException(
+                    "Incorrect data size, Fast Pair naming scheme only supports 4 blocks.");
+        }
+
+        for (int i = 0; i < numberOfBlocks; i++) {
+            // Performs the operation: encryptedBlock[i] = clearBlock[i] ^ AES(counter).
+            counter[0] = (byte) (i & 0xFF);
+            byte[] aesOfCounter = doAesSingleBlock(secret, counter);
+            int start = i * AES_BLOCK_LENGTH;
+            // The size of the last block of data may not be 16 bytes. If not, still do xor to the
+            // last byte of data.
+            int end = Math.min(start + AES_BLOCK_LENGTH, data.length);
+            for (int j = 0; start < end; j++, start++) {
+                aesCtrResult[start] ^= aesOfCounter[j];
+            }
+        }
+        return aesCtrResult;
+    }
+
+    private static byte[] doAesSingleBlock(byte[] secret, byte[] counter)
+            throws GeneralSecurityException {
+        return AesEcbSingleBlockEncryption.encrypt(secret, counter);
+    }
+
+    /** Extends 8-byte nonce to 16 bytes with zero padding to create IV. */
+    private static byte[] createIv(byte[] nonce) {
+        return concat(new byte[IV_SIZE - NONCE_SIZE], nonce);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AesEcbSingleBlockEncryption.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AesEcbSingleBlockEncryption.java
new file mode 100644
index 0000000..547931e
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/AesEcbSingleBlockEncryption.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import android.annotation.SuppressLint;
+
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Utilities used for encrypting and decrypting Fast Pair packets.
+ */
+// SuppressLint for ""ecb encryption mode should not be used".
+// Reasons:
+//    1. FastPair data is guaranteed to be only 1 AES block in size, ECB is secure.
+//    2. In each case, the encrypted data is less than 16-bytes and is
+//       padded up to 16-bytes using random data to fill the rest of the byte array,
+//       so the plaintext will never be the same.
+@SuppressLint("GetInstance")
+public final class AesEcbSingleBlockEncryption {
+
+    public static final int AES_BLOCK_LENGTH = 16;
+    public static final int KEY_LENGTH = 16;
+
+    private AesEcbSingleBlockEncryption() {
+    }
+
+    /**
+     * Generates a 16-byte AES key.
+     */
+    public static byte[] generateKey() throws NoSuchAlgorithmException {
+        KeyGenerator generator = KeyGenerator.getInstance("AES");
+        generator.init(KEY_LENGTH * 8); // Ensure a 16-byte key is always used.
+        return generator.generateKey().getEncoded();
+    }
+
+    /**
+     * Encrypts data with the provided secret.
+     */
+    public static byte[] encrypt(byte[] secret, byte[] data) throws GeneralSecurityException {
+        return doEncryption(Cipher.ENCRYPT_MODE, secret, data);
+    }
+
+    /**
+     * Decrypts data with the provided secret.
+     */
+    public static byte[] decrypt(byte[] secret, byte[] data) throws GeneralSecurityException {
+        return doEncryption(Cipher.DECRYPT_MODE, secret, data);
+    }
+
+    private static byte[] doEncryption(int mode, byte[] secret, byte[] data)
+            throws GeneralSecurityException {
+        if (data.length != AES_BLOCK_LENGTH) {
+            throw new IllegalArgumentException("This encrypter only supports 16-byte inputs.");
+        }
+        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
+        cipher.init(mode, new SecretKeySpec(secret, "AES"));
+        return cipher.doFinal(data);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAddress.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAddress.java
new file mode 100644
index 0000000..9bb5a86
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAddress.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.io.BaseEncoding.base16;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.google.common.base.Ascii;
+import com.google.common.io.BaseEncoding;
+
+import java.util.Locale;
+
+/** Utils for dealing with Bluetooth addresses. */
+public final class BluetoothAddress {
+
+    private static final BaseEncoding ENCODING = base16().upperCase().withSeparator(":", 2);
+
+    @VisibleForTesting
+    static final String SECURE_SETTINGS_KEY_BLUETOOTH_ADDRESS = "bluetooth_address";
+
+    /**
+     * @return The string format used by e.g. {@link android.bluetooth.BluetoothDevice}. Upper case.
+     *     Example: "AA:BB:CC:11:22:33"
+     */
+    public static String encode(byte[] address) {
+        return ENCODING.encode(address);
+    }
+
+    /**
+     * @param address The string format used by e.g. {@link android.bluetooth.BluetoothDevice}.
+     *     Case-insensitive. Example: "AA:BB:CC:11:22:33"
+     */
+    public static byte[] decode(String address) {
+        return ENCODING.decode(address.toUpperCase(Locale.US));
+    }
+
+    /**
+     * Get public bluetooth address.
+     *
+     * @param context a valid {@link Context} instance.
+     */
+    public static @Nullable byte[] getPublicAddress(Context context) {
+        String publicAddress =
+                Settings.Secure.getString(
+                        context.getContentResolver(), SECURE_SETTINGS_KEY_BLUETOOTH_ADDRESS);
+        return publicAddress != null && BluetoothAdapter.checkBluetoothAddress(publicAddress)
+                ? decode(publicAddress)
+                : null;
+    }
+
+    /**
+     * Hides partial information of Bluetooth address.
+     * ex1: input is null, output should be empty string
+     * ex2: input is String(AA:BB:CC), output should be AA:BB:CC
+     * ex3: input is String(AA:BB:CC:DD:EE:FF), output should be XX:XX:XX:XX:EE:FF
+     * ex4: input is String(Aa:Bb:Cc:Dd:Ee:Ff), output should be XX:XX:XX:XX:EE:FF
+     * ex5: input is BluetoothDevice(AA:BB:CC:DD:EE:FF), output should be XX:XX:XX:XX:EE:FF
+     */
+    public static String maskBluetoothAddress(@Nullable Object address) {
+        if (address == null) {
+            return "";
+        }
+
+        if (address instanceof String) {
+            String originalAddress = (String) address;
+            String upperCasedAddress = Ascii.toUpperCase(originalAddress);
+            if (!BluetoothAdapter.checkBluetoothAddress(upperCasedAddress)) {
+                return originalAddress;
+            }
+            return convert(upperCasedAddress);
+        } else if (address instanceof BluetoothDevice) {
+            return convert(((BluetoothDevice) address).getAddress());
+        }
+
+        // For others, returns toString().
+        return address.toString();
+    }
+
+    private static String convert(String address) {
+        return "XX:XX:XX:XX:" + address.substring(12);
+    }
+
+    private BluetoothAddress() {}
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAudioPairer.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAudioPairer.java
new file mode 100644
index 0000000..07306c1
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAudioPairer.java
@@ -0,0 +1,774 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static android.bluetooth.BluetoothDevice.BOND_BONDED;
+import static android.bluetooth.BluetoothDevice.BOND_BONDING;
+import static android.bluetooth.BluetoothDevice.BOND_NONE;
+import static android.bluetooth.BluetoothDevice.ERROR;
+import static android.bluetooth.BluetoothProfile.A2DP;
+import static android.bluetooth.BluetoothProfile.HEADSET;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress.maskBluetoothAddress;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+
+import android.Manifest.permission;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
+import androidx.core.content.ContextCompat;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.PasskeyCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.Profile;
+import com.android.server.nearby.common.bluetooth.fastpair.TimingLogger.ScopedTiming;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection.ChangeObserver;
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.ConnectErrorCode;
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.CreateBondErrorCode;
+import com.android.server.nearby.intdefs.NearbyEventIntDefs.EventCode;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.SettableFuture;
+
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Pairs to Bluetooth audio devices.
+ */
+public class BluetoothAudioPairer {
+
+    private static final String TAG = BluetoothAudioPairer.class.getSimpleName();
+
+    /**
+     * Hidden, see {@link BluetoothDevice}.
+     */
+    // TODO(b/202549655): remove Hidden usage.
+    private static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
+
+    /**
+     * Hidden, see {@link BluetoothDevice}.
+     */
+    // TODO(b/202549655): remove Hidden usage.
+    private static final int PAIRING_VARIANT_CONSENT = 3;
+
+    /**
+     * Hidden, see {@link BluetoothDevice}.
+     */
+    // TODO(b/202549655): remove Hidden usage.
+    public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
+
+    private static final int DISCOVERY_STATE_CHANGE_TIMEOUT_MS = 3000;
+
+    private final Context mContext;
+    private final Preferences mPreferences;
+    private final EventLoggerWrapper mEventLogger;
+    private final BluetoothDevice mDevice;
+    @Nullable
+    private final KeyBasedPairingInfo mKeyBasedPairingInfo;
+    @Nullable
+    private final PasskeyConfirmationHandler mPasskeyConfirmationHandler;
+    private final TimingLogger mTimingLogger;
+
+    private static boolean sTestMode = false;
+
+    static void enableTestMode() {
+        sTestMode = true;
+    }
+
+    static class KeyBasedPairingInfo {
+
+        private final byte[] mSecret;
+        private final GattConnectionManager mGattConnectionManager;
+        private final boolean mProviderInitiatesBonding;
+
+        /**
+         * @param secret The secret negotiated during the initial BLE handshake for Key-based
+         * Pairing. See {@link FastPairConnection#handshake}.
+         * @param gattConnectionManager A manager that knows how to get and create Gatt connections
+         * to the remote device.
+         */
+        KeyBasedPairingInfo(
+                byte[] secret,
+                GattConnectionManager gattConnectionManager,
+                boolean providerInitiatesBonding) {
+            this.mSecret = secret;
+            this.mGattConnectionManager = gattConnectionManager;
+            this.mProviderInitiatesBonding = providerInitiatesBonding;
+        }
+    }
+
+    public BluetoothAudioPairer(
+            Context context,
+            BluetoothDevice device,
+            Preferences preferences,
+            EventLoggerWrapper eventLogger,
+            @Nullable KeyBasedPairingInfo keyBasedPairingInfo,
+            @Nullable PasskeyConfirmationHandler passkeyConfirmationHandler,
+            TimingLogger timingLogger)
+            throws PairingException {
+        this.mContext = context;
+        this.mDevice = device;
+        this.mPreferences = preferences;
+        this.mEventLogger = eventLogger;
+        this.mKeyBasedPairingInfo = keyBasedPairingInfo;
+        this.mPasskeyConfirmationHandler = passkeyConfirmationHandler;
+        this.mTimingLogger = timingLogger;
+
+        // TODO(b/203455314): follow up with the following comments.
+        // The OS should give the user some UI to choose if they want to allow access, but there
+        // seems to be a bug where if we don't reject access, it's auto-granted in some cases
+        // (Plantronics headset gets contacts access when pairing with my Taimen via Bluetooth
+        // Settings, without me seeing any UI about it). b/64066631
+        //
+        // If that OS bug doesn't get fixed, we can flip these flags to force-reject the
+        // permissions.
+        if (preferences.getRejectPhonebookAccess() && (sTestMode ? false :
+                !device.setPhonebookAccessPermission(BluetoothDevice.ACCESS_REJECTED))) {
+            throw new PairingException("Failed to deny contacts (phonebook) access.");
+        }
+        if (preferences.getRejectMessageAccess()
+                && (sTestMode ? false :
+                !device.setMessageAccessPermission(BluetoothDevice.ACCESS_REJECTED))) {
+            throw new PairingException("Failed to deny message access.");
+        }
+        if (preferences.getRejectSimAccess()
+                && (sTestMode ? false :
+                !device.setSimAccessPermission(BluetoothDevice.ACCESS_REJECTED))) {
+            throw new PairingException("Failed to deny SIM access.");
+        }
+    }
+
+    boolean isPaired() {
+        return (sTestMode ? false : mDevice.getBondState() == BOND_BONDED);
+    }
+
+    /**
+     * Unpairs from the device. Throws an exception if any error occurs.
+     */
+    @WorkerThread
+    void unpair()
+            throws InterruptedException, ExecutionException, TimeoutException, PairingException {
+        int bondState =  sTestMode ? BOND_NONE : mDevice.getBondState();
+        try (UnbondedReceiver unbondedReceiver = new UnbondedReceiver();
+                ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger,
+                        "Unpair for state: " + bondState)) {
+            // We'll only get a state change broadcast if we're actually unbonding (method returns
+            // true).
+            if (bondState == BluetoothDevice.BOND_BONDED) {
+                mEventLogger.setCurrentEvent(EventCode.REMOVE_BOND);
+                Log.i(TAG,  "removeBond with " + maskBluetoothAddress(mDevice));
+                mDevice.removeBond();
+                unbondedReceiver.await(
+                        mPreferences.getRemoveBondTimeoutSeconds(), TimeUnit.SECONDS);
+            } else if (bondState == BluetoothDevice.BOND_BONDING) {
+                mEventLogger.setCurrentEvent(EventCode.CANCEL_BOND);
+                Log.i(TAG,  "cancelBondProcess with " + maskBluetoothAddress(mDevice));
+                mDevice.cancelBondProcess();
+                unbondedReceiver.await(
+                        mPreferences.getRemoveBondTimeoutSeconds(), TimeUnit.SECONDS);
+            } else {
+                // The OS may have beaten us in a race, unbonding before we called the method. So if
+                // we're (somehow) in the desired state then we're happy, if not then bail.
+                if (bondState != BluetoothDevice.BOND_NONE) {
+                    throw new PairingException("returned false, state=%s", bondState);
+                }
+            }
+        }
+
+        // This seems to improve the probability that createBond will succeed after removeBond.
+        SystemClock.sleep(mPreferences.getRemoveBondSleepMillis());
+        mEventLogger.logCurrentEventSucceeded();
+    }
+
+    /**
+     * Pairs with the device. Throws an exception if any error occurs.
+     */
+    @WorkerThread
+    void pair()
+            throws InterruptedException, ExecutionException, TimeoutException, PairingException {
+        // Unpair first, because if we have a bond, but the other device has forgotten its bond,
+        // it can send us a pairing request that we're not ready for (which can pop up a dialog).
+        // Or, if we're in the middle of a (too-long) bonding attempt, we want to cancel.
+        unpair();
+
+        mEventLogger.setCurrentEvent(EventCode.CREATE_BOND);
+        try (BondedReceiver bondedReceiver = new BondedReceiver();
+                ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger, "Create bond")) {
+            // If the provider's initiating the bond, we do nothing but wait for broadcasts.
+            if (mKeyBasedPairingInfo == null || !mKeyBasedPairingInfo.mProviderInitiatesBonding) {
+                if (!sTestMode) {
+                    Log.i(TAG, "createBond with " + maskBluetoothAddress(mDevice) + ", type="
+                        + mDevice.getType());
+                    if (mPreferences.getSpecifyCreateBondTransportType()) {
+                        mDevice.createBond(mPreferences.getCreateBondTransportType());
+                    } else {
+                        mDevice.createBond();
+                    }
+                }
+            }
+            try {
+                bondedReceiver.await(mPreferences.getCreateBondTimeoutSeconds(), TimeUnit.SECONDS);
+            } catch (TimeoutException e) {
+                Log.w(TAG, "bondedReceiver time out after " + mPreferences
+                        .getCreateBondTimeoutSeconds() + " seconds");
+                if (mPreferences.getIgnoreUuidTimeoutAfterBonded() && isPaired()) {
+                    Log.w(TAG, "Created bond but never received UUIDs, attempting to continue.");
+                } else {
+                    // Rethrow e to cause the pairing to fail and be retried if necessary.
+                    throw e;
+                }
+            }
+        }
+        mEventLogger.logCurrentEventSucceeded();
+    }
+
+    /**
+     * Connects to the given profile. Throws an exception if any error occurs.
+     *
+     * <p>If remote device clears the link key, the BOND_BONDED state would transit to BOND_BONDING
+     * (and go through the pairing process again) when directly connecting the profile. By enabling
+     * enablePairingBehavior, we provide both pairing and connecting behaviors at the same time. See
+     * b/145699390 for more details.
+     */
+    // Suppression for possible null from ImmutableMap#get. See go/lsc-get-nullable
+    @SuppressWarnings("nullness:argument")
+    @WorkerThread
+    public void connect(short profileUuid, boolean enablePairingBehavior)
+            throws InterruptedException, ReflectionException, TimeoutException, ExecutionException,
+            ConnectException {
+        if (!mPreferences.isSupportedProfile(profileUuid)) {
+            throw new ConnectException(
+                    ConnectErrorCode.UNSUPPORTED_PROFILE, "Unsupported profile=%s", profileUuid);
+        }
+        Profile profile = Constants.PROFILES.get(profileUuid);
+        Log.i(TAG,
+                "Connecting to profile=" + profile + " on device=" + maskBluetoothAddress(mDevice));
+        try (BondedReceiver bondedReceiver = enablePairingBehavior ? new BondedReceiver() : null;
+                ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger,
+                        "Connect: " + profile)) {
+            connectByProfileProxy(profile);
+        }
+    }
+
+    private void connectByProfileProxy(Profile profile)
+            throws ReflectionException, InterruptedException, ExecutionException, TimeoutException,
+            ConnectException {
+        try (BluetoothProfileWrapper autoClosingProxy = new BluetoothProfileWrapper(profile);
+                ConnectedReceiver connectedReceiver = new ConnectedReceiver(profile)) {
+            BluetoothProfile proxy = autoClosingProxy.mProxy;
+
+            // Try to connect via reflection
+            Log.v(TAG, "Connect to proxy=" + proxy);
+
+            if (!sTestMode) {
+                if (!(Boolean) Reflect.on(proxy).withMethod("connect", BluetoothDevice.class)
+                        .get(mDevice)) {
+                    // If we're already connecting, connect() may return false. :/
+                    Log.w(TAG, "connect returned false, expected if connecting, state="
+                            + proxy.getConnectionState(mDevice));
+                }
+            }
+
+            // If we're already connected, the OS may not send the connection state broadcast, so
+            // return immediately for that case.
+            if (!sTestMode) {
+                if (proxy.getConnectionState(mDevice) == BluetoothProfile.STATE_CONNECTED) {
+                    Log.v(TAG, "connectByProfileProxy: already connected to device="
+                            + maskBluetoothAddress(mDevice));
+                    return;
+                }
+            }
+
+            try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger, "Wait connection")) {
+                // Wait for connecting to succeed or fail (via event or timeout).
+                connectedReceiver
+                        .await(mPreferences.getCreateBondTimeoutSeconds(), TimeUnit.SECONDS);
+            }
+        }
+    }
+
+    private class BluetoothProfileWrapper implements AutoCloseable {
+
+        // incompatible types in assignment.
+        @SuppressWarnings("nullness:assignment")
+        private final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+
+        private final Profile mProfile;
+        private final BluetoothProfile mProxy;
+
+        /**
+         * Blocks until we get the proxy. Throws on error.
+         */
+        private BluetoothProfileWrapper(Profile profile)
+                throws InterruptedException, ExecutionException, TimeoutException,
+                ConnectException {
+            this.mProfile = profile;
+            mProxy = getProfileProxy(profile);
+        }
+
+        @Override
+        public void close() {
+            try (ScopedTiming scopedTiming =
+                    new ScopedTiming(mTimingLogger, "Close profile: " + mProfile)) {
+                if (!sTestMode) {
+                    mBluetoothAdapter.closeProfileProxy(mProfile.type, mProxy);
+                }
+            }
+        }
+
+        private BluetoothProfile getProfileProxy(BluetoothProfileWrapper this, Profile profile)
+                throws InterruptedException, ExecutionException, TimeoutException,
+                ConnectException {
+            if (profile.type != A2DP && profile.type != HEADSET) {
+                throw new IllegalArgumentException("Unsupported profile type=" + profile.type);
+            }
+
+            SettableFuture<BluetoothProfile> proxyFuture = SettableFuture.create();
+            BluetoothProfile.ServiceListener listener =
+                    new BluetoothProfile.ServiceListener() {
+                        @UiThread
+                        @Override
+                        public void onServiceConnected(int profileType, BluetoothProfile proxy) {
+                            proxyFuture.set(proxy);
+                        }
+
+                        @Override
+                        public void onServiceDisconnected(int profileType) {
+                            Log.v(TAG, "proxy disconnected for profile=" + profile);
+                        }
+                    };
+
+            if (!mBluetoothAdapter.getProfileProxy(mContext, listener, profile.type)) {
+                throw new ConnectException(
+                        ConnectErrorCode.GET_PROFILE_PROXY_FAILED,
+                        "getProfileProxy failed immediately");
+            }
+
+            return proxyFuture.get(mPreferences.getProxyTimeoutSeconds(), TimeUnit.SECONDS);
+        }
+    }
+
+    private class UnbondedReceiver extends DeviceIntentReceiver {
+
+        private UnbondedReceiver() {
+            super(mContext, mPreferences, mDevice, BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        }
+
+        @Override
+        protected void onReceiveDeviceIntent(Intent intent) throws Exception {
+            if (mDevice.getBondState() == BOND_NONE) {
+                try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger,
+                        "Close UnbondedReceiver")) {
+                    close();
+                }
+            }
+        }
+    }
+
+    /**
+     * Receiver that closes after bonding has completed.
+     */
+    class BondedReceiver extends DeviceIntentReceiver {
+
+        private boolean mReceivedUuids = false;
+        private boolean mReceivedPasskey = false;
+
+        private BondedReceiver() {
+            super(
+                    mContext,
+                    mPreferences,
+                    mDevice,
+                    BluetoothDevice.ACTION_PAIRING_REQUEST,
+                    BluetoothDevice.ACTION_BOND_STATE_CHANGED,
+                    BluetoothDevice.ACTION_UUID);
+        }
+
+        // switching on a possibly-null value (intent.getAction())
+        // incompatible types in argument.
+        @SuppressWarnings({"nullness:switching.nullable", "nullness:argument"})
+        @Override
+        protected void onReceiveDeviceIntent(Intent intent)
+                throws PairingException, InterruptedException, ExecutionException, TimeoutException,
+                BluetoothException, GeneralSecurityException {
+            switch (intent.getAction()) {
+                case BluetoothDevice.ACTION_PAIRING_REQUEST:
+                    int variant = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, ERROR);
+                    int passkey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, ERROR);
+                    handlePairingRequest(variant, passkey);
+                    break;
+                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
+                    // Use the state in the intent, not device.getBondState(), to avoid a race where
+                    // we log the wrong failure reason during a rapid transition.
+                    int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, ERROR);
+                    int reason = intent.getIntExtra(EXTRA_REASON, ERROR);
+                    handleBondStateChanged(bondState, reason);
+                    break;
+                case BluetoothDevice.ACTION_UUID:
+                    // According to eisenbach@ and pavlin@, there's always a UUID broadcast when
+                    // pairing (it can happen either before or after the transition to BONDED).
+                    if (mPreferences.getWaitForUuidsAfterBonding()) {
+                        Parcelable[] uuids = intent
+                                .getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
+                        handleUuids(uuids);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        private void handlePairingRequest(int variant, int passkey) {
+            Log.i(TAG, "Pairing request, variant=" + variant + ", passkey=" + (passkey == ERROR
+                    ? "(none)" : String.valueOf(passkey)));
+            if (mPreferences.getMoreEventLogForQuality()) {
+                mEventLogger.setCurrentEvent(EventCode.HANDLE_PAIRING_REQUEST);
+            }
+
+            if (mPreferences.getSupportHidDevice() && variant == PAIRING_VARIANT_DISPLAY_PASSKEY) {
+                mReceivedPasskey = true;
+                extendAwaitSecond(
+                        mPreferences.getHidCreateBondTimeoutSeconds()
+                                - mPreferences.getCreateBondTimeoutSeconds());
+                triggerDiscoverStateChange();
+                if (mPreferences.getMoreEventLogForQuality()) {
+                    mEventLogger.logCurrentEventSucceeded();
+                }
+                return;
+
+            } else {
+                // Prevent Bluetooth Settings from getting the pairing request and showing its own
+                // UI.
+                abortBroadcast();
+
+                if (variant == PAIRING_VARIANT_CONSENT
+                        && mKeyBasedPairingInfo == null // Fast Pair 1.0 device
+                        && mPreferences.getAcceptConsentForFastPairOne()) {
+                    // Previously, if Bluetooth decided to use the Just Works variant (e.g. Fast
+                    // Pair 1.0), we don't get a pairing request broadcast at all.
+                    // However, after CVE-2019-2225, Bluetooth will decide to ask consent from
+                    // users. Details:
+                    // https://source.android.com/security/bulletin/2019-12-01#system
+                    // Since we've certified the Fast Pair 1.0 devices, and user taps to pair it
+                    // (with the device's image), we could help user to accept the consent.
+                    if (!sTestMode) {
+                        mDevice.setPairingConfirmation(true);
+                    }
+                    if (mPreferences.getMoreEventLogForQuality()) {
+                        mEventLogger.logCurrentEventSucceeded();
+                    }
+                    return;
+                } else if (variant != BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION) {
+                    if (!sTestMode) {
+                        mDevice.setPairingConfirmation(false);
+                    }
+                    if (mPreferences.getMoreEventLogForQuality()) {
+                        mEventLogger.logCurrentEventFailed(
+                                new CreateBondException(
+                                        CreateBondErrorCode.INCORRECT_VARIANT, 0,
+                                        "Incorrect variant for FastPair"));
+                    }
+                    return;
+                }
+                mReceivedPasskey = true;
+
+                if (mKeyBasedPairingInfo == null) {
+                    if (mPreferences.getAcceptPasskey()) {
+                        // Must be the simulator using FP 1.0 (no Key-based Pairing). Real
+                        // headphones using FP 1.0 use Just Works instead (and maybe we should
+                        // disable this flag for them).
+                        if (!sTestMode) {
+                            mDevice.setPairingConfirmation(true);
+                        }
+                    }
+                    if (mPreferences.getMoreEventLogForQuality()) {
+                        if (!sTestMode) {
+                            mEventLogger.logCurrentEventSucceeded();
+                        }
+                    }
+                    return;
+                }
+            }
+
+            if (mPreferences.getMoreEventLogForQuality()) {
+                mEventLogger.logCurrentEventSucceeded();
+            }
+
+            newSingleThreadExecutor()
+                    .execute(
+                            () -> {
+                                try (ScopedTiming scopedTiming1 =
+                                        new ScopedTiming(mTimingLogger, "Exchange passkey")) {
+                                    mEventLogger.setCurrentEvent(EventCode.PASSKEY_EXCHANGE);
+
+                                    // We already check above, but the static analyzer's not
+                                    // convinced without this.
+                                    Preconditions.checkNotNull(mKeyBasedPairingInfo);
+                                    BluetoothGattConnection connection =
+                                            mKeyBasedPairingInfo.mGattConnectionManager
+                                                    .getConnection();
+                                    UUID characteristicUuid =
+                                            PasskeyCharacteristic.getId(connection);
+                                    ChangeObserver remotePasskeyObserver =
+                                            connection.enableNotification(FastPairService.ID,
+                                                    characteristicUuid);
+                                    Log.i(TAG, "Sending local passkey.");
+                                    byte[] encryptedData;
+                                    try (ScopedTiming scopedTiming2 =
+                                            new ScopedTiming(mTimingLogger, "Encrypt passkey")) {
+                                        encryptedData =
+                                                PasskeyCharacteristic.encrypt(
+                                                        PasskeyCharacteristic.Type.SEEKER,
+                                                        mKeyBasedPairingInfo.mSecret, passkey);
+                                    }
+                                    try (ScopedTiming scopedTiming3 =
+                                            new ScopedTiming(mTimingLogger,
+                                                    "Send passkey to remote")) {
+                                        connection.writeCharacteristic(
+                                                FastPairService.ID, characteristicUuid,
+                                                encryptedData);
+                                    }
+                                    Log.i(TAG, "Waiting for remote passkey.");
+                                    byte[] encryptedRemotePasskey;
+                                    try (ScopedTiming scopedTiming4 =
+                                            new ScopedTiming(mTimingLogger,
+                                                    "Wait for remote passkey")) {
+                                        encryptedRemotePasskey =
+                                                remotePasskeyObserver.waitForUpdate(
+                                                        TimeUnit.SECONDS.toMillis(mPreferences
+                                                                .getGattOperationTimeoutSeconds()));
+                                    }
+                                    int remotePasskey;
+                                    try (ScopedTiming scopedTiming5 =
+                                            new ScopedTiming(mTimingLogger, "Decrypt passkey")) {
+                                        remotePasskey =
+                                                PasskeyCharacteristic.decrypt(
+                                                        PasskeyCharacteristic.Type.PROVIDER,
+                                                        mKeyBasedPairingInfo.mSecret,
+                                                        encryptedRemotePasskey);
+                                    }
+
+                                    // We log success if we made it through with no exceptions.
+                                    // If the passkey was wrong, pairing will fail and we'll log
+                                    // BOND_BROKEN with reason = AUTH_FAILED.
+                                    mEventLogger.logCurrentEventSucceeded();
+
+                                    boolean isPasskeyCorrect = passkey == remotePasskey;
+                                    if (isPasskeyCorrect) {
+                                        Log.i(TAG, "Passkey correct.");
+                                    } else {
+                                        Log.e(TAG, "Passkey incorrect, local= " + passkey
+                                                + ", remote=" + remotePasskey);
+                                    }
+
+                                    // Don't estimate the {@code ScopedTiming} because the
+                                    // passkey confirmation is done by UI.
+                                    if (isPasskeyCorrect
+                                            && mPreferences.getHandlePasskeyConfirmationByUi()
+                                            && mPasskeyConfirmationHandler != null) {
+                                        Log.i(TAG, "Callback the passkey to UI for confirmation.");
+                                        mPasskeyConfirmationHandler
+                                                .onPasskeyConfirmation(mDevice, passkey);
+                                    } else {
+                                        try (ScopedTiming scopedTiming6 =
+                                                new ScopedTiming(
+                                                        mTimingLogger, "Confirm the pairing: "
+                                                        + isPasskeyCorrect)) {
+                                            mDevice.setPairingConfirmation(isPasskeyCorrect);
+                                        }
+                                    }
+                                } catch (BluetoothException
+                                        | GeneralSecurityException
+                                        | InterruptedException
+                                        | ExecutionException
+                                        | TimeoutException e) {
+                                    mEventLogger.logCurrentEventFailed(e);
+                                    closeWithError(e);
+                                }
+                            });
+        }
+
+        /**
+         * Workaround to let Settings popup a pairing dialog instead of notification. When pairing
+         * request intent passed to Settings, it'll check several conditions to decide that it
+         * should show a dialog or a notification. One of those conditions is to check if the device
+         * is in discovery mode recently, which can be fulfilled by calling {@link
+         * BluetoothAdapter#startDiscovery()}. This method aims to fulfill the condition, and block
+         * the pairing broadcast for at most
+         * {@link BluetoothAudioPairer#DISCOVERY_STATE_CHANGE_TIMEOUT_MS}
+         * to make sure that we fulfill the condition first and successful.
+         */
+        // dereference of possibly-null reference bluetoothAdapter
+        @SuppressWarnings("nullness:dereference.of.nullable")
+        private void triggerDiscoverStateChange() {
+            BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+
+            if (bluetoothAdapter.isDiscovering()) {
+                return;
+            }
+
+            HandlerThread backgroundThread = new HandlerThread("TriggerDiscoverStateChangeThread");
+            backgroundThread.start();
+
+            AtomicBoolean result = new AtomicBoolean(false);
+            SimpleBroadcastReceiver receiver =
+                    new SimpleBroadcastReceiver(
+                            mContext,
+                            mPreferences,
+                            new Handler(backgroundThread.getLooper()),
+                            BluetoothAdapter.ACTION_DISCOVERY_STARTED,
+                            BluetoothAdapter.ACTION_DISCOVERY_FINISHED) {
+
+                        @Override
+                        protected void onReceive(Intent intent) throws Exception {
+                            result.set(true);
+                            close();
+                        }
+                    };
+
+            Log.i(TAG, "triggerDiscoverStateChange call startDiscovery.");
+            // Uses startDiscovery to trigger Settings show pairing dialog instead of notification.
+            if (!sTestMode) {
+                bluetoothAdapter.startDiscovery();
+                bluetoothAdapter.cancelDiscovery();
+            }
+            try {
+                receiver.await(DISCOVERY_STATE_CHANGE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException | ExecutionException | TimeoutException e) {
+                Log.w(TAG, "triggerDiscoverStateChange failed!");
+            }
+
+            backgroundThread.quitSafely();
+            try {
+                backgroundThread.join();
+            } catch (InterruptedException e) {
+                Log.i(TAG, "triggerDiscoverStateChange backgroundThread.join meet exception!", e);
+            }
+
+            if (result.get()) {
+                Log.i(TAG, "triggerDiscoverStateChange successful.");
+            }
+        }
+
+        private void handleBondStateChanged(int bondState, int reason)
+                throws PairingException, InterruptedException, ExecutionException,
+                TimeoutException {
+            Log.i(TAG, "Bond state changed to " + bondState + ", reason=" + reason);
+            switch (bondState) {
+                case BOND_BONDED:
+                    if (mKeyBasedPairingInfo != null && !mReceivedPasskey) {
+                        // The device bonded with Just Works, although we did the Key-based Pairing
+                        // GATT handshake and agreed on a pairing secret. It might be a Person In
+                        // The Middle Attack!
+                        try (ScopedTiming scopedTiming =
+                                new ScopedTiming(mTimingLogger,
+                                        "Close BondedReceiver: POSSIBLE_MITM")) {
+                            closeWithError(
+                                    new CreateBondException(
+                                            CreateBondErrorCode.POSSIBLE_MITM,
+                                            reason,
+                                            "Unexpectedly bonded without a passkey. It might be a "
+                                                    + "Person In The Middle Attack! Unbonding!"));
+                        }
+                        unpair();
+                    } else if (!mPreferences.getWaitForUuidsAfterBonding()
+                            || (mPreferences.getReceiveUuidsAndBondedEventBeforeClose()
+                            && mReceivedUuids)) {
+                        try (ScopedTiming scopedTiming =
+                                new ScopedTiming(mTimingLogger, "Close BondedReceiver")) {
+                            close();
+                        }
+                    }
+                    break;
+                case BOND_NONE:
+                    throw new CreateBondException(
+                            CreateBondErrorCode.BOND_BROKEN, reason, "Bond broken, reason=%d",
+                            reason);
+                case BOND_BONDING:
+                default:
+                    break;
+            }
+        }
+
+        private void handleUuids(Parcelable[] uuids) {
+            Log.i(TAG, "Got UUIDs for " + maskBluetoothAddress(mDevice) + ": "
+                    + Arrays.toString(uuids));
+            mReceivedUuids = true;
+            if (!mPreferences.getReceiveUuidsAndBondedEventBeforeClose() || isPaired()) {
+                try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger,
+                        "Close BondedReceiver")) {
+                    close();
+                }
+            }
+        }
+    }
+
+    private class ConnectedReceiver extends DeviceIntentReceiver {
+
+        private ConnectedReceiver(Profile profile) throws ConnectException {
+            super(mContext, mPreferences, mDevice, profile.connectionStateAction);
+        }
+
+        @Override
+        public void onReceiveDeviceIntent(Intent intent) throws PairingException {
+            int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, ERROR);
+            Log.i(TAG, "Connection state changed to " + state);
+            switch (state) {
+                case BluetoothAdapter.STATE_CONNECTED:
+                    try (ScopedTiming scopedTiming =
+                            new ScopedTiming(mTimingLogger, "Close ConnectedReceiver")) {
+                        close();
+                    }
+                    break;
+                case BluetoothAdapter.STATE_DISCONNECTED:
+                    throw new ConnectException(ConnectErrorCode.DISCONNECTED, "Disconnected");
+                case BluetoothAdapter.STATE_CONNECTING:
+                case BluetoothAdapter.STATE_DISCONNECTING:
+                default:
+                    break;
+            }
+        }
+    }
+
+    private boolean hasPermission(String permission) {
+        return ContextCompat.checkSelfPermission(mContext, permission) == PERMISSION_GRANTED;
+    }
+
+    public BluetoothDevice getDevice() {
+        return mDevice;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothClassicPairer.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothClassicPairer.java
new file mode 100644
index 0000000..6c467d3
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothClassicPairer.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static android.bluetooth.BluetoothDevice.BOND_BONDED;
+import static android.bluetooth.BluetoothDevice.BOND_BONDING;
+import static android.bluetooth.BluetoothDevice.BOND_NONE;
+import static android.bluetooth.BluetoothDevice.ERROR;
+import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress.maskBluetoothAddress;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import android.annotation.SuppressLint;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import androidx.annotation.WorkerThread;
+
+import com.google.common.base.Strings;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Pairs to Bluetooth classic devices with passkey confirmation.
+ */
+// TODO(b/202524672): Add class unit test.
+public class BluetoothClassicPairer {
+
+    private static final String TAG = BluetoothClassicPairer.class.getSimpleName();
+    /**
+     * Hidden, see {@link BluetoothDevice}.
+     */
+    private static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
+
+    private final Context mContext;
+    private final BluetoothDevice mDevice;
+    private final Preferences mPreferences;
+    private final PasskeyConfirmationHandler mPasskeyConfirmationHandler;
+
+    public BluetoothClassicPairer(
+            Context context,
+            BluetoothDevice device,
+            Preferences preferences,
+            PasskeyConfirmationHandler passkeyConfirmationHandler) {
+        this.mContext = context;
+        this.mDevice = device;
+        this.mPreferences = preferences;
+        this.mPasskeyConfirmationHandler = passkeyConfirmationHandler;
+    }
+
+    /**
+     * Pairs with the device. Throws a {@link PairingException} if any error occurs.
+     */
+    @WorkerThread
+    public void pair() throws PairingException {
+        Log.i(TAG, "BluetoothClassicPairer, createBond with " + maskBluetoothAddress(mDevice)
+                + ", type=" + mDevice.getType());
+        try (BondedReceiver bondedReceiver = new BondedReceiver()) {
+            if (mDevice.createBond()) {
+                bondedReceiver.await(mPreferences.getCreateBondTimeoutSeconds(), SECONDS);
+            } else {
+                throw new PairingException(
+                        "BluetoothClassicPairer, createBond got immediate error");
+            }
+        } catch (TimeoutException | InterruptedException | ExecutionException e) {
+            throw new PairingException("BluetoothClassicPairer, createBond failed", e);
+        }
+    }
+
+    protected boolean isPaired() {
+        return mDevice.getBondState() == BOND_BONDED;
+    }
+
+    /**
+     * Receiver that closes after bonding has completed.
+     */
+    private class BondedReceiver extends DeviceIntentReceiver {
+
+        private BondedReceiver() {
+            super(
+                    mContext,
+                    mPreferences,
+                    mDevice,
+                    BluetoothDevice.ACTION_PAIRING_REQUEST,
+                    BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        }
+
+        /**
+         * Called with ACTION_PAIRING_REQUEST and ACTION_BOND_STATE_CHANGED about the interesting
+         * device (see {@link DeviceIntentReceiver}).
+         *
+         * <p>The ACTION_PAIRING_REQUEST intent provides the passkey which will be sent to the
+         * {@link PasskeyConfirmationHandler} for showing the UI, and the ACTION_BOND_STATE_CHANGED
+         * will provide the result of the bonding.
+         */
+        @Override
+        protected void onReceiveDeviceIntent(Intent intent) {
+            String intentAction = intent.getAction();
+            BluetoothDevice remoteDevice = intent.getParcelableExtra(EXTRA_DEVICE);
+            if (Strings.isNullOrEmpty(intentAction)
+                    || remoteDevice == null
+                    || !remoteDevice.getAddress().equals(mDevice.getAddress())) {
+                Log.w(TAG,
+                        "BluetoothClassicPairer, receives " + intentAction
+                                + " from unexpected device " + maskBluetoothAddress(remoteDevice));
+                return;
+            }
+            switch (intentAction) {
+                case BluetoothDevice.ACTION_PAIRING_REQUEST:
+                    handlePairingRequest(
+                            remoteDevice,
+                            intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, ERROR),
+                            intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, ERROR));
+                    break;
+                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
+                    handleBondStateChanged(
+                            intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, ERROR),
+                            intent.getIntExtra(EXTRA_REASON, ERROR));
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        private void handlePairingRequest(BluetoothDevice device, int variant, int passkey) {
+            Log.i(TAG,
+                    "BluetoothClassicPairer, pairing request, " + device + ", " + variant + ", "
+                            + passkey);
+            // Prevent Bluetooth Settings from getting the pairing request and showing its own UI.
+            abortBroadcast();
+            mPasskeyConfirmationHandler.onPasskeyConfirmation(device, passkey);
+        }
+
+        private void handleBondStateChanged(int bondState, int reason) {
+            Log.i(TAG,
+                    "BluetoothClassicPairer, bond state changed to " + bondState + ", reason="
+                            + reason);
+            switch (bondState) {
+                case BOND_BONDING:
+                    // Don't close!
+                    return;
+                case BOND_BONDED:
+                    close();
+                    return;
+                case BOND_NONE:
+                default:
+                    closeWithError(
+                            new PairingException(
+                                    "BluetoothClassicPairer, createBond failed, reason:" + reason));
+            }
+        }
+    }
+
+    // Applies UsesPermission annotation will create circular dependency.
+    @SuppressLint("MissingPermission")
+    static void setPairingConfirmation(BluetoothDevice device, boolean confirm) {
+        Log.i(TAG, "BluetoothClassicPairer: setPairingConfirmation " + maskBluetoothAddress(device)
+                + ", confirm: " + confirm);
+        device.setPairingConfirmation(confirm);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothUuids.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothUuids.java
new file mode 100644
index 0000000..c5475a6
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BluetoothUuids.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import java.util.UUID;
+
+/**
+ * Utilities for dealing with UUIDs assigned by the Bluetooth SIG. Has a lot in common with
+ * com.android.BluetoothUuid, but that class is hidden.
+ */
+public class BluetoothUuids {
+
+    /**
+     * The Base UUID is used for calculating 128-bit UUIDs from "short UUIDs" (16- and 32-bit).
+     *
+     * @see {https://www.bluetooth.com/specifications/assigned-numbers/service-discovery}
+     */
+    private static final UUID BASE_UUID = UUID.fromString("00000000-0000-1000-8000-00805F9B34FB");
+
+    /**
+     * Fast Pair custom GATT characteristics 128-bit UUIDs base.
+     *
+     * <p>Notes: The 16-bit value locates at the 3rd and 4th bytes.
+     *
+     * @see {go/fastpair-128bit-gatt}
+     */
+    private static final UUID FAST_PAIR_BASE_UUID =
+            UUID.fromString("FE2C0000-8366-4814-8EB0-01DE32100BEA");
+
+    private static final int BIT_INDEX_OF_16_BIT_UUID = 32;
+
+    private BluetoothUuids() {}
+
+    /**
+     * Returns the 16-bit version of the UUID. If this is not a 16-bit UUID, throws
+     * IllegalArgumentException.
+     */
+    public static short get16BitUuid(UUID uuid) {
+        if (!is16BitUuid(uuid)) {
+            throw new IllegalArgumentException("Not a 16-bit Bluetooth UUID: " + uuid);
+        }
+        return (short) (uuid.getMostSignificantBits() >> BIT_INDEX_OF_16_BIT_UUID);
+    }
+
+    /** Checks whether the UUID is 16 bit */
+    public static boolean is16BitUuid(UUID uuid) {
+        // See Service Discovery Protocol in the Bluetooth Core Specification. Bits at index 32-48
+        // are the 16-bit UUID, and the rest must match the Base UUID.
+        return uuid.getLeastSignificantBits() == BASE_UUID.getLeastSignificantBits()
+                && (uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL)
+                == BASE_UUID.getMostSignificantBits();
+    }
+
+    /** Converts short UUID to 128 bit UUID */
+    public static UUID to128BitUuid(short shortUuid) {
+        return new UUID(
+                ((shortUuid & 0xFFFFL) << BIT_INDEX_OF_16_BIT_UUID)
+                        | BASE_UUID.getMostSignificantBits(), BASE_UUID.getLeastSignificantBits());
+    }
+
+    /** Transfers the 16-bit Fast Pair custom GATT characteristics to 128-bit. */
+    public static UUID toFastPair128BitUuid(short shortUuid) {
+        return new UUID(
+                ((shortUuid & 0xFFFFL) << BIT_INDEX_OF_16_BIT_UUID)
+                        | FAST_PAIR_BASE_UUID.getMostSignificantBits(),
+                FAST_PAIR_BASE_UUID.getLeastSignificantBits());
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BroadcastConstants.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BroadcastConstants.java
new file mode 100644
index 0000000..c26c6ad
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/BroadcastConstants.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+/**
+ * Constants to share with the cloud syncing process.
+ */
+public class BroadcastConstants {
+
+    // TODO: Set right value for AOSP.
+    /** Package name of the cloud syncing logic. */
+    public static final String PACKAGE_NAME = "PACKAGE_NAME";
+    /** Service name of the cloud syncing instance. */
+    public static final String SERVICE_NAME = PACKAGE_NAME + ".SERVICE_NAME";
+    private static final String PREFIX = PACKAGE_NAME + ".PREFIX_NAME.";
+
+    /** Action when a fast pair device is added. */
+    public static final String ACTION_FAST_PAIR_DEVICE_ADDED =
+            PREFIX + "ACTION_FAST_PAIR_DEVICE_ADDED";
+    /**
+     * The BLE address of a device. BLE is used here instead of public because the caller of the
+     * library never knows what the device's public address is.
+     */
+    public static final String EXTRA_ADDRESS = PREFIX + "BLE_ADDRESS";
+    /** The public address of a device. */
+    public static final String EXTRA_PUBLIC_ADDRESS = PREFIX + "PUBLIC_ADDRESS";
+    /** Account key. */
+    public static final String EXTRA_ACCOUNT_KEY = PREFIX + "ACCOUNT_KEY";
+    /** Whether a paring is retroactive. */
+    public static final String EXTRA_RETROACTIVE_PAIR = PREFIX + "EXTRA_RETROACTIVE_PAIR";
+
+    private BroadcastConstants() {
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Bytes.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Bytes.java
new file mode 100644
index 0000000..637cd03
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Bytes.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import androidx.annotation.Nullable;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.ShortBuffer;
+import java.util.Arrays;
+
+/** Represents a block of bytes, with hashCode and equals. */
+public abstract class Bytes {
+    private static final char[] sHexDigits = "0123456789abcdef".toCharArray();
+    private final byte[] mBytes;
+
+    /**
+     * A logical value consisting of one or more bytes in the given order (little-endian, i.e.
+     * LSO...MSO, or big-endian, i.e. MSO...LSO). E.g. the Fast Pair Model ID is a 3-byte value,
+     * and a Bluetooth device address is a 6-byte value.
+     */
+    public static class Value extends Bytes {
+        private final ByteOrder mByteOrder;
+
+        /**
+         * Constructor.
+         */
+        public Value(byte[] bytes, ByteOrder byteOrder) {
+            super(bytes);
+            this.mByteOrder = byteOrder;
+        }
+
+        /**
+         * Gets bytes.
+         */
+        public byte[] getBytes(ByteOrder byteOrder) {
+            return this.mByteOrder.equals(byteOrder) ? getBytes() : reverse(getBytes());
+        }
+
+        private static byte[] reverse(byte[] bytes) {
+            byte[] reversedBytes = new byte[bytes.length];
+            for (int i = 0; i < bytes.length; i++) {
+                reversedBytes[i] = bytes[bytes.length - i - 1];
+            }
+            return reversedBytes;
+        }
+    }
+
+    Bytes(byte[] bytes) {
+        mBytes = bytes;
+    }
+
+    private static String toHexString(byte[] bytes) {
+        StringBuilder sb = new StringBuilder(2 * bytes.length);
+        for (byte b : bytes) {
+            sb.append(sHexDigits[(b >> 4) & 0xf]).append(sHexDigits[b & 0xf]);
+        }
+        return sb.toString();
+    }
+
+    /** Returns 2-byte values in the same order, each using the given byte order. */
+    public static byte[] toBytes(ByteOrder byteOrder, short... shorts) {
+        ByteBuffer byteBuffer = ByteBuffer.allocate(shorts.length * 2).order(byteOrder);
+        for (short s : shorts) {
+            byteBuffer.putShort(s);
+        }
+        return byteBuffer.array();
+    }
+
+    /** Returns the shorts in the same order, each converted using the given byte order. */
+    static short[] toShorts(ByteOrder byteOrder, byte[] bytes) {
+        ShortBuffer shortBuffer = ByteBuffer.wrap(bytes).order(byteOrder).asShortBuffer();
+        short[] shorts = new short[shortBuffer.remaining()];
+        shortBuffer.get(shorts);
+        return shorts;
+    }
+
+    /** @return The bytes. */
+    public byte[] getBytes() {
+        return mBytes;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof Bytes)) {
+            return false;
+        }
+        Bytes that = (Bytes) o;
+        return Arrays.equals(mBytes, that.mBytes);
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(mBytes);
+    }
+
+    @Override
+    public String toString() {
+        return toHexString(mBytes);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ConnectException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ConnectException.java
new file mode 100644
index 0000000..9c8d292
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ConnectException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.ConnectErrorCode;
+
+
+/** Thrown when connecting to a bluetooth device fails. */
+public class ConnectException extends PairingException {
+    final @ConnectErrorCode int mErrorCode;
+
+    ConnectException(@ConnectErrorCode int errorCode, String format, Object... objects) {
+        super(format, objects);
+        this.mErrorCode = errorCode;
+    }
+
+    /** Returns error code. */
+    public @ConnectErrorCode int getErrorCode() {
+        return mErrorCode;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Constants.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Constants.java
new file mode 100644
index 0000000..cfecd2f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Constants.java
@@ -0,0 +1,703 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static android.bluetooth.BluetoothProfile.A2DP;
+import static android.bluetooth.BluetoothProfile.HEADSET;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothUuids.to128BitUuid;
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothUuids.toFastPair128BitUuid;
+
+import static com.google.common.primitives.Bytes.concat;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothHeadset;
+import android.util.Log;
+
+import androidx.annotation.IntDef;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.primitives.Shorts;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+import java.util.Random;
+import java.util.UUID;
+
+/**
+ * Fast Pair and Transport Discovery Service constants.
+ *
+ * <p>Unless otherwise specified, these numbers come from
+ * {https://www.bluetooth.com/specifications/gatt}.
+ */
+public final class Constants {
+
+    /** A2DP sink service uuid. */
+    public static final short A2DP_SINK_SERVICE_UUID = 0x110B;
+
+    /** Headset service uuid. */
+    public static final short HEADSET_SERVICE_UUID = 0x1108;
+
+    /** Hands free sink service uuid. */
+    public static final short HANDS_FREE_SERVICE_UUID = 0x111E;
+
+    /** Bluetooth address length. */
+    public static final int BLUETOOTH_ADDRESS_LENGTH = 6;
+
+    private static final String TAG = Constants.class.getSimpleName();
+
+    /**
+     * Defined by https://developers.google.com/nearby/fast-pair/spec.
+     */
+    public static final class FastPairService {
+
+        /** Fast Pair service UUID. */
+        public static final UUID ID = to128BitUuid((short) 0xFE2C);
+
+        /**
+         * Characteristic to write verification bytes to during the key handshake.
+         */
+        public static final class KeyBasedPairingCharacteristic {
+
+            private static final short SHORT_UUID = 0x1234;
+
+            /**
+             * Gets the new 128-bit UUID of this characteristic.
+             *
+             * <p>Note: For GATT server only. GATT client should use {@link
+             * KeyBasedPairingCharacteristic#getId(BluetoothGattConnection)}.
+             */
+            public static final UUID CUSTOM_128_BIT_UUID = toFastPair128BitUuid(SHORT_UUID);
+
+            /**
+             * Gets the {@link UUID} of this characteristic.
+             *
+             * <p>This method is designed for being backward compatible with old version of UUID
+             * therefore needs the {@link BluetoothGattConnection} parameter to check the supported
+             * status of the Fast Pair provider.
+             */
+            public static UUID getId(BluetoothGattConnection gattConnection) {
+                return getSupportedUuid(gattConnection, SHORT_UUID);
+            }
+
+            /**
+             * Constants related to the decrypted request written to this characteristic.
+             */
+            public static final class Request {
+
+                /**
+                 * The size of this message.
+                 */
+                public static final int SIZE = 16;
+
+                /**
+                 * The index of this message for indicating the type byte.
+                 */
+                public static final int TYPE_INDEX = 0;
+
+                /**
+                 * The index of this message for indicating the flags byte.
+                 */
+                public static final int FLAGS_INDEX = 1;
+
+                /**
+                 * The index of this message for indicating the verification data start from.
+                 */
+                public static final int VERIFICATION_DATA_INDEX = 2;
+
+                /**
+                 * The length of verification data, it is Provider’s current BLE address or public
+                 * address.
+                 */
+                public static final int VERIFICATION_DATA_LENGTH = BLUETOOTH_ADDRESS_LENGTH;
+
+                /**
+                 * The index of this message for indicating the seeker's public address start from.
+                 */
+                public static final int SEEKER_PUBLIC_ADDRESS_INDEX = 8;
+
+                /**
+                 * The index of this message for indicating event group.
+                 */
+                public static final int EVENT_GROUP_INDEX = 8;
+
+                /**
+                 * The index of this message for indicating event code.
+                 */
+                public static final int EVENT_CODE_INDEX = 9;
+
+                /**
+                 * The index of this message for indicating the length of additional data of the
+                 * event.
+                 */
+                public static final int EVENT_ADDITIONAL_DATA_LENGTH_INDEX = 10;
+
+                /**
+                 * The index of this message for indicating the event additional data start from.
+                 */
+                public static final int EVENT_ADDITIONAL_DATA_INDEX = 11;
+
+                /**
+                 * The index of this message for indicating the additional data type used in the
+                 * following Additional Data characteristic.
+                 */
+                public static final int ADDITIONAL_DATA_TYPE_INDEX = 10;
+
+                /**
+                 * The type of this message for Key-based Pairing Request.
+                 */
+                public static final byte TYPE_KEY_BASED_PAIRING_REQUEST = 0x00;
+
+                /**
+                 * The bit indicating that the Fast Pair device should temporarily become
+                 * discoverable.
+                 */
+                public static final byte REQUEST_DISCOVERABLE = (byte) (1 << 7);
+
+                /**
+                 * The bit indicating that the requester (Seeker) has included their public address
+                 * in bytes [7,12] of the request, and the Provider should initiate bonding to that
+                 * address.
+                 */
+                public static final byte PROVIDER_INITIATES_BONDING = (byte) (1 << 6);
+
+                /**
+                 * The bit indicating that Seeker requests Provider shall return the existing name.
+                 */
+                public static final byte REQUEST_DEVICE_NAME = (byte) (1 << 5);
+
+                /**
+                 * The bit to request retroactive pairing.
+                 */
+                public static final byte REQUEST_RETROACTIVE_PAIR = (byte) (1 << 4);
+
+                /**
+                 * The type of this message for action over BLE.
+                 */
+                public static final byte TYPE_ACTION_OVER_BLE = 0x10;
+
+                private Request() {
+                }
+            }
+
+            /**
+             * Enumerates all flags of key-based pairing request.
+             */
+            @Retention(RetentionPolicy.SOURCE)
+            @IntDef(
+                    value = {
+                            KeyBasedPairingRequestFlag.REQUEST_DISCOVERABLE,
+                            KeyBasedPairingRequestFlag.PROVIDER_INITIATES_BONDING,
+                            KeyBasedPairingRequestFlag.REQUEST_DEVICE_NAME,
+                            KeyBasedPairingRequestFlag.REQUEST_RETROACTIVE_PAIR,
+                    })
+            public @interface KeyBasedPairingRequestFlag {
+                /**
+                 * The bit indicating that the Fast Pair device should temporarily become
+                 * discoverable.
+                 */
+                int REQUEST_DISCOVERABLE = (byte) (1 << 7);
+                /**
+                 * The bit indicating that the requester (Seeker) has included their public address
+                 * in bytes [7,12] of the request, and the Provider should initiate bonding to that
+                 * address.
+                 */
+                int PROVIDER_INITIATES_BONDING = (byte) (1 << 6);
+                /**
+                 * The bit indicating that Seeker requests Provider shall return the existing name.
+                 */
+                int REQUEST_DEVICE_NAME = (byte) (1 << 5);
+                /**
+                 * The bit indicating that the Seeker request retroactive pairing.
+                 */
+                int REQUEST_RETROACTIVE_PAIR = (byte) (1 << 4);
+            }
+
+            /**
+             * Enumerates all flags of action over BLE request, see Fast Pair spec for details.
+             */
+            @IntDef(
+                    value = {
+                            ActionOverBleFlag.DEVICE_ACTION,
+                            ActionOverBleFlag.ADDITIONAL_DATA_CHARACTERISTIC,
+                    })
+            public @interface ActionOverBleFlag {
+                /**
+                 * The bit indicating that the handshaking is for Device Action.
+                 */
+                int DEVICE_ACTION = (byte) (1 << 7);
+                /**
+                 * The bit indicating that this handshake will be followed by Additional Data
+                 * characteristic.
+                 */
+                int ADDITIONAL_DATA_CHARACTERISTIC = (byte) (1 << 6);
+            }
+
+
+            /**
+             * Constants related to the decrypted response sent back in a notify.
+             */
+            public static final class Response {
+
+                /**
+                 * The type of this message = Key-based Pairing Response.
+                 */
+                public static final byte TYPE = 0x01;
+
+                private Response() {
+                }
+            }
+
+            private KeyBasedPairingCharacteristic() {
+            }
+        }
+
+        /**
+         * Characteristic used during Key-based Pairing, to exchange the encrypted passkey.
+         */
+        public static final class PasskeyCharacteristic {
+
+            private static final short SHORT_UUID = 0x1235;
+
+            /**
+             * Gets the new 128-bit UUID of this characteristic.
+             *
+             * <p>Note: For GATT server only. GATT client should use {@link
+             * PasskeyCharacteristic#getId(BluetoothGattConnection)}.
+             */
+            public static final UUID CUSTOM_128_BIT_UUID = toFastPair128BitUuid(SHORT_UUID);
+
+            /**
+             * Gets the {@link UUID} of this characteristic.
+             *
+             * <p>This method is designed for being backward compatible with old version of UUID
+             * therefore
+             * needs the {@link BluetoothGattConnection} parameter to check the supported status of
+             * the Fast Pair provider.
+             */
+            public static UUID getId(BluetoothGattConnection gattConnection) {
+                return getSupportedUuid(gattConnection, SHORT_UUID);
+            }
+
+            /**
+             * The type of the Passkey Block message.
+             */
+            @IntDef(
+                    value = {
+                            Type.SEEKER,
+                            Type.PROVIDER,
+                    })
+            public @interface Type {
+                /**
+                 * Seeker's Passkey.
+                 */
+                int SEEKER = (byte) 0x02;
+                /**
+                 * Provider's Passkey.
+                 */
+                int PROVIDER = (byte) 0x03;
+            }
+
+            /**
+             * Constructs the encrypted value to write to the characteristic.
+             */
+            public static byte[] encrypt(@Type int type, byte[] secret, int passkey)
+                    throws GeneralSecurityException {
+                Preconditions.checkArgument(
+                        0 < passkey && passkey < /*2^24=*/ 16777216,
+                        "Passkey %s must be positive and fit in 3 bytes",
+                        passkey);
+                byte[] passkeyBytes =
+                        new byte[]{(byte) (passkey >>> 16), (byte) (passkey >>> 8), (byte) passkey};
+                byte[] salt =
+                        new byte[AesEcbSingleBlockEncryption.AES_BLOCK_LENGTH - 1
+                                - passkeyBytes.length];
+                new Random().nextBytes(salt);
+                return AesEcbSingleBlockEncryption.encrypt(
+                        secret, concat(new byte[]{(byte) type}, passkeyBytes, salt));
+            }
+
+            /**
+             * Extracts the passkey from the encrypted characteristic value.
+             */
+            public static int decrypt(@Type int type, byte[] secret,
+                    byte[] passkeyCharacteristicValue)
+                    throws GeneralSecurityException {
+                byte[] decrypted = AesEcbSingleBlockEncryption
+                        .decrypt(secret, passkeyCharacteristicValue);
+                if (decrypted[0] != (byte) type) {
+                    throw new GeneralSecurityException(
+                            "Wrong Passkey Block type (expected " + type + ", got "
+                                    + decrypted[0] + ")");
+                }
+                return ByteBuffer.allocate(4)
+                        .put((byte) 0)
+                        .put(decrypted, /*offset=*/ 1, /*length=*/ 3)
+                        .getInt(0);
+            }
+
+            private PasskeyCharacteristic() {
+            }
+        }
+
+        /**
+         * Characteristic to write to during the key exchange.
+         */
+        public static final class AccountKeyCharacteristic {
+
+            private static final short SHORT_UUID = 0x1236;
+
+            /**
+             * Gets the new 128-bit UUID of this characteristic.
+             *
+             * <p>Note: For GATT server only. GATT client should use {@link
+             * AccountKeyCharacteristic#getId(BluetoothGattConnection)}.
+             */
+            public static final UUID CUSTOM_128_BIT_UUID = toFastPair128BitUuid(SHORT_UUID);
+
+            /**
+             * Gets the {@link UUID} of this characteristic.
+             *
+             * <p>This method is designed for being backward compatible with old version of UUID
+             * therefore
+             * needs the {@link BluetoothGattConnection} parameter to check the supported status of
+             * the Fast Pair provider.
+             */
+            public static UUID getId(BluetoothGattConnection gattConnection) {
+                return getSupportedUuid(gattConnection, SHORT_UUID);
+            }
+
+            /**
+             * The type for this message, account key request.
+             */
+            public static final byte TYPE = 0x04;
+
+            private AccountKeyCharacteristic() {
+            }
+        }
+
+        /**
+         * Characteristic to write to and notify on for handling personalized name, see {@link
+         * NamingEncoder}.
+         */
+        public static final class NameCharacteristic {
+
+            private static final short SHORT_UUID = 0x1237;
+
+            /**
+             * Gets the new 128-bit UUID of this characteristic.
+             *
+             * <p>Note: For GATT server only. GATT client should use {@link
+             * NameCharacteristic#getId(BluetoothGattConnection)}.
+             */
+            public static final UUID CUSTOM_128_BIT_UUID = toFastPair128BitUuid(SHORT_UUID);
+
+            /**
+             * Gets the {@link UUID} of this characteristic.
+             *
+             * <p>This method is designed for being backward compatible with old version of UUID
+             * therefore
+             * needs the {@link BluetoothGattConnection} parameter to check the supported status of
+             * the Fast Pair provider.
+             */
+            public static UUID getId(BluetoothGattConnection gattConnection) {
+                return getSupportedUuid(gattConnection, SHORT_UUID);
+            }
+
+            private NameCharacteristic() {
+            }
+        }
+
+        /**
+         * Characteristic to write to and notify on for handling additional data, see
+         * https://developers.google.com/nearby/fast-pair/early-access/spec#AdditionalData
+         */
+        public static final class AdditionalDataCharacteristic {
+
+            private static final short SHORT_UUID = 0x1237;
+
+            public static final int DATA_ID_INDEX = 0;
+            public static final int DATA_LENGTH_INDEX = 1;
+            public static final int DATA_START_INDEX = 2;
+
+            /**
+             * Gets the new 128-bit UUID of this characteristic.
+             *
+             * <p>Note: For GATT server only. GATT client should use {@link
+             * AdditionalDataCharacteristic#getId(BluetoothGattConnection)}.
+             */
+            public static final UUID CUSTOM_128_BIT_UUID = toFastPair128BitUuid(SHORT_UUID);
+
+            /**
+             * Gets the {@link UUID} of this characteristic.
+             *
+             * <p>This method is designed for being backward compatible with old version of UUID
+             * therefore
+             * needs the {@link BluetoothGattConnection} parameter to check the supported status of
+             * the Fast Pair provider.
+             */
+            public static UUID getId(BluetoothGattConnection gattConnection) {
+                return getSupportedUuid(gattConnection, SHORT_UUID);
+            }
+
+            /**
+             * Enumerates all types of additional data.
+             */
+            @Retention(RetentionPolicy.SOURCE)
+            @IntDef(
+                    value = {
+                            AdditionalDataType.PERSONALIZED_NAME,
+                            AdditionalDataType.UNKNOWN,
+                    })
+            public @interface AdditionalDataType {
+                /**
+                 * The value indicating that the type is for personalized name.
+                 */
+                int PERSONALIZED_NAME = (byte) 0x01;
+                int UNKNOWN = (byte) 0x00; // and all others.
+            }
+        }
+
+        /**
+         * Characteristic to control the beaconing feature (FastPair+Eddystone).
+         */
+        public static final class BeaconActionsCharacteristic {
+
+            private static final short SHORT_UUID = 0x1238;
+
+            /**
+             * Gets the new 128-bit UUID of this characteristic.
+             *
+             * <p>Note: For GATT server only. GATT client should use {@link
+             * BeaconActionsCharacteristic#getId(BluetoothGattConnection)}.
+             */
+            public static final UUID CUSTOM_128_BIT_UUID = toFastPair128BitUuid(SHORT_UUID);
+
+            /**
+             * Gets the {@link UUID} of this characteristic.
+             *
+             * <p>This method is designed for being backward compatible with old version of UUID
+             * therefore
+             * needs the {@link BluetoothGattConnection} parameter to check the supported status of
+             * the Fast Pair provider.
+             */
+            public static UUID getId(BluetoothGattConnection gattConnection) {
+                return getSupportedUuid(gattConnection, SHORT_UUID);
+            }
+
+            /**
+             * Enumerates all types of beacon actions.
+             */
+            /** Fast Pair Bond State. */
+            @Retention(RetentionPolicy.SOURCE)
+            @IntDef(
+                    value = {
+                            BeaconActionType.READ_BEACON_PARAMETERS,
+                            BeaconActionType.READ_PROVISIONING_STATE,
+                            BeaconActionType.SET_EPHEMERAL_IDENTITY_KEY,
+                            BeaconActionType.CLEAR_EPHEMERAL_IDENTITY_KEY,
+                            BeaconActionType.READ_EPHEMERAL_IDENTITY_KEY,
+                            BeaconActionType.RING,
+                            BeaconActionType.READ_RINGING_STATE,
+                            BeaconActionType.UNKNOWN,
+                    })
+            public @interface BeaconActionType {
+                int READ_BEACON_PARAMETERS = (byte) 0x00;
+                int READ_PROVISIONING_STATE = (byte) 0x01;
+                int SET_EPHEMERAL_IDENTITY_KEY = (byte) 0x02;
+                int CLEAR_EPHEMERAL_IDENTITY_KEY = (byte) 0x03;
+                int READ_EPHEMERAL_IDENTITY_KEY = (byte) 0x04;
+                int RING = (byte) 0x05;
+                int READ_RINGING_STATE = (byte) 0x06;
+                int UNKNOWN = (byte) 0xFF; // and all others
+            }
+
+            /** Converts value to enum. */
+            public static @BeaconActionType int valueOf(byte value) {
+                switch(value) {
+                    case BeaconActionType.READ_BEACON_PARAMETERS:
+                    case BeaconActionType.READ_PROVISIONING_STATE:
+                    case BeaconActionType.SET_EPHEMERAL_IDENTITY_KEY:
+                    case BeaconActionType.CLEAR_EPHEMERAL_IDENTITY_KEY:
+                    case BeaconActionType.READ_EPHEMERAL_IDENTITY_KEY:
+                    case BeaconActionType.RING:
+                    case BeaconActionType.READ_RINGING_STATE:
+                    case BeaconActionType.UNKNOWN:
+                        return value;
+                    default:
+                        return BeaconActionType.UNKNOWN;
+                }
+            }
+        }
+
+
+        /**
+         * Characteristic to read for checking firmware version. 0X2A26 is assigned number from
+         * bluetooth SIG website.
+         */
+        public static final class FirmwareVersionCharacteristic {
+
+            /** UUID for firmware version. */
+            public static final UUID ID = to128BitUuid((short) 0x2A26);
+
+            private FirmwareVersionCharacteristic() {
+            }
+        }
+
+        private FastPairService() {
+        }
+    }
+
+    /**
+     * Defined by the BR/EDR Handover Profile. Pre-release version here:
+     * {https://jfarfel.users.x20web.corp.google.com/Bluetooth%20Handover%20d09.pdf}
+     */
+    public interface TransportDiscoveryService {
+
+        UUID ID = to128BitUuid((short) 0x1824);
+
+        byte BLUETOOTH_SIG_ORGANIZATION_ID = 0x01;
+        byte SERVICE_UUIDS_16_BIT_LIST_TYPE = 0x01;
+        byte SERVICE_UUIDS_32_BIT_LIST_TYPE = 0x02;
+        byte SERVICE_UUIDS_128_BIT_LIST_TYPE = 0x03;
+
+        /**
+         * Writing to this allows you to activate the BR/EDR transport.
+         */
+        interface ControlPointCharacteristic {
+
+            UUID ID = to128BitUuid((short) 0x2ABC);
+            byte ACTIVATE_TRANSPORT_OP_CODE = 0x01;
+        }
+
+        /**
+         * Info necessary to pair (mostly the Bluetooth Address).
+         */
+        interface BrHandoverDataCharacteristic {
+
+            UUID ID = to128BitUuid((short) 0x2C01);
+
+            /**
+             * All bits are reserved for future use.
+             */
+            byte BR_EDR_FEATURES = 0x00;
+        }
+
+        /**
+         * This characteristic exists only to wrap the descriptor.
+         */
+        interface BluetoothSigDataCharacteristic {
+
+            UUID ID = to128BitUuid((short) 0x2C02);
+
+            /**
+             * The entire Transport Block data (e.g. supported Bluetooth services).
+             */
+            interface BrTransportBlockDataDescriptor {
+
+                UUID ID = to128BitUuid((short) 0x2C03);
+            }
+        }
+    }
+
+    public static final UUID CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR_UUID =
+            to128BitUuid((short) 0x2902);
+
+    /**
+     * Wrapper for Bluetooth profile
+     */
+    public static class Profile {
+
+        public final int type;
+        public final String name;
+        public final String connectionStateAction;
+
+        private Profile(int type, String name, String connectionStateAction) {
+            this.type = type;
+            this.name = name;
+            this.connectionStateAction = connectionStateAction;
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+    }
+
+    /**
+     * {@link BluetoothHeadset} is used for both Headset and HandsFree (HFP).
+     */
+    private static final Profile HEADSET_AND_HANDS_FREE_PROFILE =
+            new Profile(
+                    HEADSET, "HEADSET_AND_HANDS_FREE",
+                    BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+
+    /** Fast Pair supported profiles. */
+    public static final ImmutableMap<Short, Profile> PROFILES =
+            ImmutableMap.<Short, Profile>builder()
+                    .put(
+                            Constants.A2DP_SINK_SERVICE_UUID,
+                            new Profile(A2DP, "A2DP",
+                                    BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED))
+                    .put(Constants.HEADSET_SERVICE_UUID, HEADSET_AND_HANDS_FREE_PROFILE)
+                    .put(Constants.HANDS_FREE_SERVICE_UUID, HEADSET_AND_HANDS_FREE_PROFILE)
+                    .build();
+
+    static short[] getSupportedProfiles() {
+        return Shorts.toArray(PROFILES.keySet());
+    }
+
+    /**
+     * Helper method of getting 128-bit UUID for Fast Pair custom GATT characteristics.
+     *
+     * <p>This method is designed for being backward compatible with old version of UUID therefore
+     * needs the {@link BluetoothGattConnection} parameter to check the supported status of the Fast
+     * Pair provider.
+     *
+     * <p>Note: For new custom GATT characteristics, don't need to use this helper and please just
+     * call {@code toFastPair128BitUuid(shortUuid)} to get the UUID. Which also implies that callers
+     * don't need to provide {@link BluetoothGattConnection} to get the UUID anymore.
+     */
+    private static UUID getSupportedUuid(BluetoothGattConnection gattConnection, short shortUuid) {
+        // In worst case (new characteristic not found), this method's performance impact is about
+        // 6ms
+        // by using Pixel2 + JBL LIVE220. And the impact should be less and less along with more and
+        // more devices adopt the new characteristics.
+        try {
+            // Checks the new UUID first.
+            if (gattConnection
+                    .getCharacteristic(FastPairService.ID, toFastPair128BitUuid(shortUuid))
+                    != null) {
+                Log.d(TAG, "Uses new KeyBasedPairingCharacteristic.ID");
+                return toFastPair128BitUuid(shortUuid);
+            }
+        } catch (BluetoothException e) {
+            Log.d(TAG, "Uses old KeyBasedPairingCharacteristic.ID");
+        }
+        // Returns the old UUID for default.
+        return to128BitUuid(shortUuid);
+    }
+
+    private Constants() {
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/CreateBondException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/CreateBondException.java
new file mode 100644
index 0000000..d6aa3b2
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/CreateBondException.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.CreateBondErrorCode;
+
+/** Thrown when binding (pairing) with a bluetooth device fails. */
+public class CreateBondException extends PairingException {
+    final @CreateBondErrorCode int mErrorCode;
+    int mReason;
+
+    CreateBondException(@CreateBondErrorCode int errorCode, int reason, String format,
+            Object... objects) {
+        super(format, objects);
+        this.mErrorCode = errorCode;
+        this.mReason = reason;
+    }
+
+    /** Returns error code. */
+    public @CreateBondErrorCode int getErrorCode() {
+        return mErrorCode;
+    }
+
+    /** Returns reason. */
+    public int getReason() {
+        return mReason;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/DeviceIntentReceiver.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/DeviceIntentReceiver.java
new file mode 100644
index 0000000..5bcf10a
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/DeviceIntentReceiver.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress.maskBluetoothAddress;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+/**
+ * Like {@link SimpleBroadcastReceiver}, but for intents about a certain {@link BluetoothDevice}.
+ */
+abstract class DeviceIntentReceiver extends SimpleBroadcastReceiver {
+
+    private static final String TAG = DeviceIntentReceiver.class.getSimpleName();
+
+    private final BluetoothDevice mDevice;
+
+    static DeviceIntentReceiver oneShotReceiver(
+            Context context, Preferences preferences, BluetoothDevice device, String... actions) {
+        return new DeviceIntentReceiver(context, preferences, device, actions) {
+            @Override
+            protected void onReceiveDeviceIntent(Intent intent) throws Exception {
+                close();
+            }
+        };
+    }
+
+    /**
+     * @param context The context to use to register / unregister the receiver.
+     * @param device The interesting device. We ignore intents about other devices.
+     * @param actions The actions to include in our intent filter.
+     */
+    protected DeviceIntentReceiver(
+            Context context, Preferences preferences, BluetoothDevice device, String... actions) {
+        super(context, preferences, actions);
+        this.mDevice = device;
+    }
+
+    /**
+     * Called with intents about the interesting device (see {@link #DeviceIntentReceiver}). Any
+     * exception thrown by this method will be delivered via {@link #await}.
+     */
+    protected abstract void onReceiveDeviceIntent(Intent intent) throws Exception;
+
+    // incompatible types in argument.
+    @Override
+    protected void onReceive(Intent intent) throws Exception {
+        BluetoothDevice intentDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+        if (mDevice == null || mDevice.equals(intentDevice)) {
+            onReceiveDeviceIntent(intent);
+        } else {
+            Log.v(TAG,
+                    "Ignoring intent for device=" + maskBluetoothAddress(intentDevice)
+                            + "(expected "
+                            + maskBluetoothAddress(mDevice) + ")");
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/EllipticCurveDiffieHellmanExchange.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/EllipticCurveDiffieHellmanExchange.java
new file mode 100644
index 0000000..dbcdf07
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/EllipticCurveDiffieHellmanExchange.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.primitives.Bytes.concat;
+
+import androidx.annotation.Nullable;
+
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
+import java.util.Arrays;
+
+import javax.crypto.KeyAgreement;
+
+/**
+ * Helper for generating keys based off of the Elliptic-Curve Diffie-Hellman algorithm (ECDH).
+ */
+public final class EllipticCurveDiffieHellmanExchange {
+
+    public static final int PUBLIC_KEY_LENGTH = 64;
+    static final int PRIVATE_KEY_LENGTH = 32;
+
+    private static final String[] PROVIDERS = {"GmsCore_OpenSSL", "AndroidOpenSSL", "SC", "BC"};
+
+    private static final String EC_ALGORITHM = "EC";
+
+    /**
+     * Also known as prime256v1 or NIST P-256.
+     */
+    private static final ECGenParameterSpec EC_GEN_PARAMS = new ECGenParameterSpec("secp256r1");
+
+    @Nullable
+    private final ECPublicKey mPublicKey;
+    private final ECPrivateKey mPrivateKey;
+
+    /**
+     * Creates a new EllipticCurveDiffieHellmanExchange object.
+     */
+    public static EllipticCurveDiffieHellmanExchange create() throws GeneralSecurityException {
+        KeyPair keyPair = generateKeyPair();
+        return new EllipticCurveDiffieHellmanExchange(
+                (ECPublicKey) keyPair.getPublic(), (ECPrivateKey) keyPair.getPrivate());
+    }
+
+    /**
+     * Creates a new EllipticCurveDiffieHellmanExchange object.
+     */
+    public static EllipticCurveDiffieHellmanExchange create(byte[] privateKey)
+            throws GeneralSecurityException {
+        ECPrivateKey ecPrivateKey = (ECPrivateKey) generatePrivateKey(privateKey);
+        return new EllipticCurveDiffieHellmanExchange(/*publicKey=*/ null, ecPrivateKey);
+    }
+
+    private EllipticCurveDiffieHellmanExchange(
+            @Nullable ECPublicKey publicKey, ECPrivateKey privateKey) {
+        this.mPublicKey = publicKey;
+        this.mPrivateKey = privateKey;
+    }
+
+    /**
+     * @param otherPublicKey Another party's public key. See {@link #getPublicKey()} for format.
+     * @return The shared secret. Given our public key (and its private key), the other party can
+     * generate the same secret. This is a key meant for symmetric encryption.
+     */
+    public byte[] generateSecret(byte[] otherPublicKey) throws GeneralSecurityException {
+        KeyAgreement agreement = keyAgreement();
+        agreement.init(mPrivateKey);
+        agreement.doPhase(generatePublicKey(otherPublicKey), /*lastPhase=*/ true);
+        byte[] secret = agreement.generateSecret();
+        // Headsets only support AES with 128-bit keys. So, hash the secret so that the entropy is
+        // high and then take only the first 128-bits.
+        secret = MessageDigest.getInstance("SHA-256").digest(secret);
+        return Arrays.copyOf(secret, 16);
+    }
+
+    /**
+     * Returns a public point W on the NIST P-256 elliptic curve. First 32 bytes are the X
+     * coordinate, next 32 bytes are the Y coordinate. Each coordinate is an unsigned big-endian
+     * integer.
+     */
+    public @Nullable byte[] getPublicKey() {
+        if (mPublicKey == null) {
+            return null;
+        }
+        ECPoint w = mPublicKey.getW();
+        // See getPrivateKey for why we're resizing.
+        byte[] x = resizeWithLeadingZeros(w.getAffineX().toByteArray(), 32);
+        byte[] y = resizeWithLeadingZeros(w.getAffineY().toByteArray(), 32);
+        return concat(x, y);
+    }
+
+    /**
+     * Returns a private value S, an unsigned big-endian integer.
+     */
+    public byte[] getPrivateKey() {
+        // Note that BigInteger.toByteArray() returns a signed representation, so it will add an
+        // extra zero byte to the front if the first bit is 1.
+        // We must remove that leading zero (we know the number is unsigned). We must also add
+        // leading zeros if the number is too small.
+        return resizeWithLeadingZeros(mPrivateKey.getS().toByteArray(), 32);
+    }
+
+    /**
+     * Removes or adds leading zeros until we have an array of size {@code n}.
+     */
+    private static byte[] resizeWithLeadingZeros(byte[] x, int n) {
+        if (n < x.length) {
+            int start = x.length - n;
+            for (int i = 0; i < start; i++) {
+                if (x[i] != 0) {
+                    throw new IllegalArgumentException(
+                            "More than " + n + " non-zero bytes in " + Arrays.toString(x));
+                }
+            }
+            return Arrays.copyOfRange(x, start, x.length);
+        }
+        return concat(new byte[n - x.length], x);
+    }
+
+    /**
+     * @param publicKey See {@link #getPublicKey()} for format.
+     */
+    private static PublicKey generatePublicKey(byte[] publicKey) throws GeneralSecurityException {
+        if (publicKey.length != PUBLIC_KEY_LENGTH) {
+            throw new GeneralSecurityException("Public key length incorrect: " + publicKey.length);
+        }
+        byte[] x = Arrays.copyOf(publicKey, publicKey.length / 2);
+        byte[] y = Arrays.copyOfRange(publicKey, publicKey.length / 2, publicKey.length);
+        return keyFactory()
+                .generatePublic(
+                        new ECPublicKeySpec(
+                                new ECPoint(new BigInteger(/*signum=*/ 1, x),
+                                        new BigInteger(/*signum=*/ 1, y)),
+                                ecParameterSpec()));
+    }
+
+    /**
+     * @param privateKey See {@link #getPrivateKey()} for format.
+     */
+    private static PrivateKey generatePrivateKey(byte[] privateKey)
+            throws GeneralSecurityException {
+        if (privateKey.length != PRIVATE_KEY_LENGTH) {
+            throw new GeneralSecurityException("Private key length incorrect: "
+                    + privateKey.length);
+        }
+        return keyFactory()
+                .generatePrivate(
+                        new ECPrivateKeySpec(new BigInteger(/*signum=*/ 1, privateKey),
+                                ecParameterSpec()));
+    }
+
+    private static ECParameterSpec ecParameterSpec() throws GeneralSecurityException {
+        // This seems to be the simplest way to get the curve's ECParameterSpec. Verified that it's
+        // the same whether you get it from the public or private key, and that it's the same as the
+        // raw params in SecAggEcUtil.getNistP256Params().
+        return ((ECPublicKey) generateKeyPair().getPublic()).getParams();
+    }
+
+    private static KeyPair generateKeyPair() throws GeneralSecurityException {
+        KeyPairGenerator generator = findProvider(p -> KeyPairGenerator.getInstance(EC_ALGORITHM,
+                p));
+        generator.initialize(EC_GEN_PARAMS);
+        return generator.generateKeyPair();
+    }
+
+    private static KeyAgreement keyAgreement() throws NoSuchProviderException {
+        return findProvider(p -> KeyAgreement.getInstance("ECDH", p));
+    }
+
+    private static KeyFactory keyFactory() throws NoSuchProviderException {
+        return findProvider(p -> KeyFactory.getInstance(EC_ALGORITHM, p));
+    }
+
+    private interface ProviderConsumer<T> {
+
+        T tryProvider(String provider) throws NoSuchAlgorithmException, NoSuchProviderException;
+    }
+
+    private static <T> T findProvider(ProviderConsumer<T> providerConsumer)
+            throws NoSuchProviderException {
+        for (String provider : PROVIDERS) {
+            try {
+                return providerConsumer.tryProvider(provider);
+            } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+                // No-op
+            }
+        }
+        throw new NoSuchProviderException();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Event.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Event.java
new file mode 100644
index 0000000..0b50dfd
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Event.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import android.bluetooth.BluetoothDevice;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.server.nearby.intdefs.NearbyEventIntDefs.EventCode;
+
+import java.util.Objects;
+
+import javax.annotation.Nullable;
+
+/**
+ * Describes events that are happening during fast pairing. EventCode is required, everything else
+ * is optional.
+ */
+public class Event implements Parcelable {
+
+    private final @EventCode int mEventCode;
+    private final long mTimestamp;
+    private final Short mProfile;
+    private final BluetoothDevice mBluetoothDevice;
+    private final Exception mException;
+
+    private Event(@EventCode int eventCode, long timestamp, @Nullable Short profile,
+            @Nullable BluetoothDevice bluetoothDevice, @Nullable Exception exception) {
+        mEventCode = eventCode;
+        mTimestamp = timestamp;
+        mProfile = profile;
+        mBluetoothDevice = bluetoothDevice;
+        mException = exception;
+    }
+
+    /**
+     * Returns event code.
+     */
+    public @EventCode int getEventCode() {
+        return mEventCode;
+    }
+
+    /**
+     * Returns timestamp.
+     */
+    public long getTimestamp() {
+        return mTimestamp;
+    }
+
+    /**
+     * Returns profile.
+     */
+    @Nullable
+    public Short getProfile() {
+        return mProfile;
+    }
+
+    /**
+     * Returns Bluetooth device.
+     */
+    @Nullable
+    public BluetoothDevice getBluetoothDevice() {
+        return mBluetoothDevice;
+    }
+
+    /**
+     * Returns exception.
+     */
+    @Nullable
+    public Exception getException() {
+        return mException;
+    }
+
+    /**
+     * Returns whether profile is not null.
+     */
+    public boolean hasProfile() {
+        return getProfile() != null;
+    }
+
+    /**
+     * Returns whether Bluetooth device is not null.
+     */
+    public boolean hasBluetoothDevice() {
+        return getBluetoothDevice() != null;
+    }
+
+    /**
+     * Returns a builder.
+     */
+    public static Builder builder() {
+        return new Event.Builder();
+    }
+
+    /**
+     * Returns whether it fails.
+     */
+    public boolean isFailure() {
+        return getException() != null;
+    }
+
+    @Override
+    public String toString() {
+        return "Event{"
+                + "eventCode=" + mEventCode + ", "
+                + "timestamp=" + mTimestamp + ", "
+                + "profile=" + mProfile + ", "
+                + "bluetoothDevice=" + mBluetoothDevice + ", "
+                + "exception=" + mException
+                + "}";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof Event) {
+            Event that = (Event) o;
+            return this.mEventCode == that.getEventCode()
+                    && this.mTimestamp == that.getTimestamp()
+                    && (this.mProfile == null
+                        ? that.getProfile() == null : this.mProfile.equals(that.getProfile()))
+                    && (this.mBluetoothDevice == null
+                        ? that.getBluetoothDevice() == null :
+                            this.mBluetoothDevice.equals(that.getBluetoothDevice()))
+                    && (this.mException == null
+                        ?  that.getException() == null :
+                            this.mException.equals(that.getException()));
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mEventCode, mTimestamp, mProfile, mBluetoothDevice, mException);
+    }
+
+
+    /**
+     * Builder
+     */
+    public static class Builder {
+        private @EventCode int mEventCode;
+        private long mTimestamp;
+        private Short mProfile;
+        private BluetoothDevice mBluetoothDevice;
+        private Exception mException;
+
+        /**
+         * Set event code.
+         */
+        public Builder setEventCode(@EventCode int eventCode) {
+            this.mEventCode = eventCode;
+            return this;
+        }
+
+        /**
+         * Set timestamp.
+         */
+        public Builder setTimestamp(long timestamp) {
+            this.mTimestamp = timestamp;
+            return this;
+        }
+
+        /**
+         * Set profile.
+         */
+        public Builder setProfile(@Nullable Short profile) {
+            this.mProfile = profile;
+            return this;
+        }
+
+        /**
+         * Set Bluetooth device.
+         */
+        public Builder setBluetoothDevice(@Nullable BluetoothDevice device) {
+            this.mBluetoothDevice = device;
+            return this;
+        }
+
+        /**
+         * Set exception.
+         */
+        public Builder setException(@Nullable Exception exception) {
+            this.mException = exception;
+            return this;
+        }
+
+        /**
+         * Builds event.
+         */
+        public Event build() {
+            return new Event(mEventCode, mTimestamp, mProfile, mBluetoothDevice, mException);
+        }
+    }
+
+    @Override
+    public final void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(getEventCode());
+        dest.writeLong(getTimestamp());
+        dest.writeValue(getProfile());
+        dest.writeParcelable(getBluetoothDevice(), 0);
+        dest.writeSerializable(getException());
+    }
+
+    @Override
+    public final int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Event Creator instance.
+     */
+    public static final Creator<Event> CREATOR =
+            new Creator<Event>() {
+                @Override
+                /** Creates Event from Parcel. */
+                public Event createFromParcel(Parcel in) {
+                    return Event.builder()
+                            .setEventCode(in.readInt())
+                            .setTimestamp(in.readLong())
+                            .setProfile((Short) in.readValue(Short.class.getClassLoader()))
+                            .setBluetoothDevice(
+                                    in.readParcelable(BluetoothDevice.class.getClassLoader()))
+                            .setException((Exception) in.readSerializable())
+                            .build();
+                }
+
+                @Override
+                /** Returns Event array. */
+                public Event[] newArray(int size) {
+                    return new Event[size];
+                }
+            };
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/EventLogger.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/EventLogger.java
new file mode 100644
index 0000000..4fc1917
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/EventLogger.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+/** Logs events triggered during Fast Pairing. */
+public interface EventLogger {
+
+    /** Log successful event. */
+    void logEventSucceeded(Event event);
+
+    /** Log failed event. */
+    void logEventFailed(Event event, Exception e);
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/EventLoggerWrapper.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/EventLoggerWrapper.java
new file mode 100644
index 0000000..024bfde
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/EventLoggerWrapper.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+
+import com.android.server.nearby.common.bluetooth.fastpair.Preferences.ExtraLoggingInformation;
+import com.android.server.nearby.intdefs.NearbyEventIntDefs.EventCode;
+
+import javax.annotation.Nullable;
+
+/**
+ * Convenience wrapper around EventLogger.
+ */
+// TODO(b/202559985): cleanup EventLoggerWrapper.
+class EventLoggerWrapper {
+
+    EventLoggerWrapper(@Nullable EventLogger eventLogger) {
+    }
+
+    /**
+     * Binds to the logging service. This operation blocks until binding has completed or timed
+     * out.
+     */
+    void bind(
+            Context context, String address,
+            @Nullable ExtraLoggingInformation extraLoggingInformation) {
+    }
+
+    boolean isBound() {
+        return false;
+    }
+
+    void unbind(Context context) {
+    }
+
+    void setCurrentEvent(@EventCode int code) {
+    }
+
+    void setCurrentProfile(short profile) {
+    }
+
+    void logCurrentEventFailed(Exception e) {
+    }
+
+    void logCurrentEventSucceeded() {
+    }
+
+    void setDevice(@Nullable BluetoothDevice device) {
+    }
+
+    boolean isCurrentEvent() {
+        return false;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairConnection.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairConnection.java
new file mode 100644
index 0000000..c963aa6
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairConnection.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import android.annotation.WorkerThread;
+import android.bluetooth.BluetoothDevice;
+
+import androidx.annotation.Nullable;
+import androidx.core.util.Consumer;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+/** Abstract class for pairing or connecting via FastPair. */
+public abstract class FastPairConnection {
+    @Nullable protected OnPairedCallback mPairedCallback;
+    @Nullable protected OnGetBluetoothAddressCallback mOnGetBluetoothAddressCallback;
+    @Nullable protected PasskeyConfirmationHandler mPasskeyConfirmationHandler;
+    @Nullable protected FastPairSignalChecker mFastPairSignalChecker;
+    @Nullable protected Consumer<Integer> mRescueFromError;
+    @Nullable protected Runnable mPrepareCreateBondCallback;
+    protected boolean mPasskeyIsGotten;
+
+    /** Sets a callback to be invoked once the device is paired. */
+    public void setOnPairedCallback(OnPairedCallback callback) {
+        this.mPairedCallback = callback;
+    }
+
+    /** Sets a callback to be invoked while the target bluetooth address is decided. */
+    public void setOnGetBluetoothAddressCallback(OnGetBluetoothAddressCallback callback) {
+        this.mOnGetBluetoothAddressCallback = callback;
+    }
+
+    /** Sets a callback to be invoked while handling the passkey confirmation. */
+    public void setPasskeyConfirmationHandler(
+            PasskeyConfirmationHandler passkeyConfirmationHandler) {
+        this.mPasskeyConfirmationHandler = passkeyConfirmationHandler;
+    }
+
+    public void setFastPairSignalChecker(FastPairSignalChecker fastPairSignalChecker) {
+        this.mFastPairSignalChecker = fastPairSignalChecker;
+    }
+
+    public void setRescueFromError(Consumer<Integer> rescueFromError) {
+        this.mRescueFromError = rescueFromError;
+    }
+
+    public void setPrepareCreateBondCallback(Runnable runnable) {
+        this.mPrepareCreateBondCallback = runnable;
+    }
+
+    @VisibleForTesting
+    @Nullable
+    public Runnable getPrepareCreateBondCallback() {
+        return mPrepareCreateBondCallback;
+    }
+
+    /**
+     * Sets the fast pair history for identifying whether or not the provider has paired with the
+     * primary account on other phones before.
+     */
+    @WorkerThread
+    public abstract void setFastPairHistory(List<FastPairHistoryItem> fastPairHistoryItem);
+
+    /** Sets the device name to the Provider. */
+    public abstract void setProviderDeviceName(String deviceName);
+
+    /** Gets the device name from the Provider. */
+    @Nullable
+    public abstract String getProviderDeviceName();
+
+    /**
+     * Gets the existing account key of the Provider.
+     *
+     * @return the existing account key if the Provider has paired with the account, null otherwise
+     */
+    @WorkerThread
+    @Nullable
+    public abstract byte[] getExistingAccountKey();
+
+    /**
+     * Pairs with Provider. Synchronous: Blocks until paired and connected. Throws on any error.
+     *
+     * @return the secret key for the user's account, if written
+     */
+    @WorkerThread
+    @Nullable
+    public abstract SharedSecret pair()
+            throws BluetoothException, InterruptedException, TimeoutException, ExecutionException,
+            PairingException, ReflectionException;
+
+    /**
+     * Pairs with Provider. Synchronous: Blocks until paired and connected. Throws on any error.
+     *
+     * @param key can be in two different formats. If it is 16 bytes long, then it is an AES account
+     *    key. Otherwise, it's a public key generated by {@link EllipticCurveDiffieHellmanExchange}.
+     *    See go/fast-pair-2-spec for how each of these keys are used.
+     * @return the secret key for the user's account, if written
+     */
+    @WorkerThread
+    @Nullable
+    public abstract SharedSecret pair(@Nullable byte[] key)
+            throws BluetoothException, InterruptedException, TimeoutException, ExecutionException,
+            PairingException, GeneralSecurityException, ReflectionException;
+
+    /** Unpairs with Provider. Synchronous: Blocks until unpaired. Throws on any error. */
+    @WorkerThread
+    public abstract void unpair(BluetoothDevice device)
+            throws InterruptedException, TimeoutException, ExecutionException, PairingException,
+            ReflectionException;
+
+    /** Gets the public address of the Provider. */
+    @Nullable
+    public abstract String getPublicAddress();
+
+
+    /** Callback for getting notifications when pairing has completed. */
+    public interface OnPairedCallback {
+        /** Called when the device at address has finished pairing. */
+        void onPaired(String address);
+    }
+
+    /** Callback for getting bluetooth address Bisto oobe need this information */
+    public interface OnGetBluetoothAddressCallback {
+        /** Called when the device has received bluetooth address. */
+        void onGetBluetoothAddress(String address);
+    }
+
+    /** Holds the exchanged secret key and the public mac address of the device. */
+    public static class SharedSecret {
+        private final byte[] mKey;
+        private final String mAddress;
+        private SharedSecret(byte[] key, String address) {
+            mKey = key;
+            mAddress = address;
+        }
+
+        /** Creates Shared Secret. */
+        public static SharedSecret create(byte[] key, String address) {
+            return new SharedSecret(key, address);
+        }
+
+        /** Gets Shared Secret Key. */
+        public byte[] getKey() {
+            return mKey;
+        }
+
+        /** Gets Shared Secret Address. */
+        public String getAddress() {
+            return mAddress;
+        }
+
+        @Override
+        public String toString() {
+            return "SharedSecret{"
+                    + "key=" + Arrays.toString(mKey) + ", "
+                    + "address=" + mAddress
+                    + "}";
+        }
+
+        @Override
+        public boolean equals(@Nullable Object o) {
+            if (o == this) {
+                return true;
+            }
+            if (o instanceof SharedSecret) {
+                SharedSecret that = (SharedSecret) o;
+                return Arrays.equals(this.mKey, that.getKey())
+                        && this.mAddress.equals(that.getAddress());
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(Arrays.hashCode(mKey), mAddress);
+        }
+    }
+
+    /** Invokes if gotten the passkey. */
+    public void setPasskeyIsGotten() {
+        mPasskeyIsGotten = true;
+    }
+
+    /** Returns the value of passkeyIsGotten. */
+    public boolean getPasskeyIsGotten() {
+        return mPasskeyIsGotten;
+    }
+
+    /** Interface to get latest address of ModelId. */
+    public interface FastPairSignalChecker {
+        /** Gets address of ModelId. */
+        String getValidAddressForModelId(String currentDevice);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairConstants.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairConstants.java
new file mode 100644
index 0000000..0ff1bf2
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairConstants.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import android.bluetooth.BluetoothDevice;
+
+/** Constants to share with other team. */
+public class FastPairConstants {
+    private static final String PACKAGE_NAME = "com.android.server.nearby";
+    private static final String PREFIX = PACKAGE_NAME + ".common.bluetooth.fastpair.";
+
+    /** MODEL_ID item name for extended intent field. */
+    public static final String EXTRA_MODEL_ID = PREFIX + "MODEL_ID";
+    /** CONNECTION_ID item name for extended intent field. */
+    public static final String EXTRA_CONNECTION_ID = PREFIX + "CONNECTION_ID";
+    /** BLUETOOTH_MAC_ADDRESS item name for extended intent field. */
+    public static final String EXTRA_BLUETOOTH_MAC_ADDRESS = PREFIX + "BLUETOOTH_MAC_ADDRESS";
+    /** COMPANION_SCAN_ITEM item name for extended intent field. */
+    public static final String EXTRA_SCAN_ITEM = PREFIX + "COMPANION_SCAN_ITEM";
+    /** BOND_RESULT item name for extended intent field. */
+    public static final String EXTRA_BOND_RESULT = PREFIX + "EXTRA_BOND_RESULT";
+
+    /**
+     * The bond result of the {@link BluetoothDevice} when FastPair launches the companion app, it
+     * means device is BONDED but the pairing process is not triggered by FastPair.
+     */
+    public static final int BOND_RESULT_SUCCESS_WITHOUT_FP = 0;
+
+    /**
+     * The bond result of the {@link BluetoothDevice} when FastPair launches the companion app, it
+     * means device is BONDED and the pairing process is triggered by FastPair.
+     */
+    public static final int BOND_RESULT_SUCCESS_WITH_FP = 1;
+
+    /**
+     * The bond result of the {@link BluetoothDevice} when FastPair launches the companion app, it
+     * means the pairing process triggered by FastPair is failed due to the lack of PIN code.
+     */
+    public static final int BOND_RESULT_FAIL_WITH_FP_WITHOUT_PIN = 2;
+
+    /**
+     * The bond result of the {@link BluetoothDevice} when FastPair launches the companion app, it
+     * means the pairing process triggered by FastPair is failed due to the PIN code is not
+     * confirmed by the user.
+     */
+    public static final int BOND_RESULT_FAIL_WITH_FP_WITH_PIN_NOT_CONFIRMED = 3;
+
+    /**
+     * The bond result of the {@link BluetoothDevice} when FastPair launches the companion app, it
+     * means the pairing process triggered by FastPair is failed due to the user thinks the PIN is
+     * wrong.
+     */
+    public static final int BOND_RESULT_FAIL_WITH_FP_WITH_PIN_WRONG = 4;
+
+    /**
+     * The bond result of the {@link BluetoothDevice} when FastPair launches the companion app, it
+     * means the pairing process triggered by FastPair is failed even after the user confirmed the
+     * PIN code is correct.
+     */
+    public static final int BOND_RESULT_FAIL_WITH_FP_WITH_PIN_CORRECT = 5;
+
+    private FastPairConstants() {}
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnection.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnection.java
new file mode 100644
index 0000000..789ef59
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnection.java
@@ -0,0 +1,2127 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static android.bluetooth.BluetoothDevice.BOND_BONDED;
+import static android.bluetooth.BluetoothDevice.BOND_BONDING;
+import static android.bluetooth.BluetoothDevice.BOND_NONE;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress.maskBluetoothAddress;
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothUuids.get16BitUuid;
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothUuids.to128BitUuid;
+import static com.android.server.nearby.common.bluetooth.fastpair.Bytes.toBytes;
+import static com.android.server.nearby.common.bluetooth.fastpair.Bytes.toShorts;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Verify.verifyNotNull;
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.primitives.Bytes.concat;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.ParcelUuid;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.BluetoothTimeoutException;
+import com.android.server.nearby.common.bluetooth.fastpair.BluetoothAudioPairer.KeyBasedPairingInfo;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.AccountKeyCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.AdditionalDataCharacteristic.AdditionalDataType;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.FirmwareVersionCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.KeyBasedPairingRequestFlag;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.NameCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.TransportDiscoveryService;
+import com.android.server.nearby.common.bluetooth.fastpair.HandshakeHandler.ActionOverBle;
+import com.android.server.nearby.common.bluetooth.fastpair.HandshakeHandler.HandshakeException;
+import com.android.server.nearby.common.bluetooth.fastpair.HandshakeHandler.HandshakeMessage;
+import com.android.server.nearby.common.bluetooth.fastpair.HandshakeHandler.KeyBasedPairingRequest;
+import com.android.server.nearby.common.bluetooth.fastpair.Ltv.ParseException;
+import com.android.server.nearby.common.bluetooth.fastpair.TimingLogger.ScopedTiming;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection.ChangeObserver;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothAdapter;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.BluetoothOperationTimeoutException;
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.fastpair.FastPairController;
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.BrEdrHandoverErrorCode;
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.ConnectErrorCode;
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.CreateBondErrorCode;
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.ErrorCode;
+import com.android.server.nearby.intdefs.NearbyEventIntDefs.EventCode;
+
+import com.google.common.base.Ascii;
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Shorts;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteOrder;
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Supports Fast Pair pairing with certain Bluetooth headphones, Auto, etc.
+ *
+ * <p>Based on https://developers.google.com/nearby/fast-pair/spec, the pairing is constructed by
+ * both BLE and BREDR connections. Example state transitions for Fast Pair 2, ie a pairing key is
+ * included in the request (note: timeouts and retries are governed by flags, may change):
+ *
+ * <pre>
+ * {@code
+ *   Connect GATT
+ *     A) Success -> Handshake
+ *     B) Failure (3s timeout) -> Retry 2x -> end
+ *
+ *   Handshake
+ *     A) Generate a shared secret with the headset (either using anti-spoofing key or account key)
+ *       1) Account key is used directly as the key
+ *       2) Anti-spoofing key is used by combining out private key with the headset's public and
+ *          sending our public to the headset to combine with their private to generate a shared
+ *          key. Sending our public key to headset takes ~3s.
+ *     B) Write an encrypted packet to the headset containing their BLE address for verification
+ *        that both sides have the same key (headset decodes this packet and checks it against their
+ *        own address) (~250ms).
+ *     C) Receive a response from the headset containing their public address (~250ms).
+ *
+ *   Discovery (for devices < Oreo)
+ *     A) Success -> Create Bond
+ *     B) Failure (10s timeout) -> Sleep 1s, Retry 3x -> end
+ *
+ *   Connect to device
+ *     A) If already bonded
+ *       1) Attempt directly connecting to supported profiles (A2DP, etc)
+ *         a) Success -> Write Account Key
+ *         b) Failure (15s timeout, usually fails within a ~2s) -> Remove bond (~1s) -> Create bond
+ *     B) If not already bonded
+ *       1) Create bond
+ *         a) Success -> Connect profile
+ *         b) Failure (15s timeout) -> Retry 2x -> end
+ *       2) Connect profile
+ *         a) Success -> Write account key
+ *         b) Failure -> Retry -> end
+ *
+ *   Write account key
+ *     A) Callback that pairing succeeded
+ *     B) Disconnect GATT
+ *     C) Reconnect GATT for secure connection
+ *     D) Write account key (~3s)
+ * }
+ * </pre>
+ *
+ * The performance profiling result by {@link TimingLogger}:
+ *
+ * <pre>
+ *   FastPairDualConnection [Exclusive time] / [Total time] ([Timestamp])
+ *     Connect GATT #1 3054ms (0)
+ *     Handshake 32ms / 740ms (3054)
+ *       Generate key via ECDH 10ms (3054)
+ *       Add salt 1ms (3067)
+ *       Encrypt request 3ms (3068)
+ *       Write data to GATT 692ms (3097)
+ *       Wait response from GATT 0ms (3789)
+ *       Decrypt response 2ms (3789)
+ *     Get BR/EDR handover information via SDP 1ms (3795)
+ *     Pair device #1 6ms / 4887ms (3805)
+ *       Create bond 3965ms / 4881ms (3809)
+ *         Exchange passkey 587ms / 915ms (7124)
+ *           Encrypt passkey 6ms (7694)
+ *           Send passkey to remote 290ms (7700)
+ *           Wait for remote passkey 0ms (7993)
+ *           Decrypt passkey 18ms (7994)
+ *           Confirm the pairing: true 14ms (8025)
+ *         Close BondedReceiver 1ms (8688)
+ *     Connect: A2DP 19ms / 370ms (8701)
+ *       Wait connection 348ms / 349ms (8720)
+ *         Close ConnectedReceiver 1ms (9068)
+ *       Close profile: A2DP 2ms (9069)
+ *     Write account key 2ms / 789ms (9163)
+ *       Encrypt key 0ms (9164)
+ *       Write key via GATT #1 777ms / 783ms (9164)
+ *         Close GATT 6ms (9941)
+ *       Start CloudSyncing 2ms (9947)
+ *       Broadcast Validator 2ms (9949)
+ *   FastPairDualConnection end, 9952ms
+ * </pre>
+ */
+// TODO(b/203441105): break down FastPairDualConnection into smaller classes.
+public class FastPairDualConnection extends FastPairConnection {
+
+    private static final String TAG = FastPairDualConnection.class.getSimpleName();
+
+    @VisibleForTesting
+    static final int GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST = 10000;
+    @VisibleForTesting
+    static final int GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED = 20000;
+    @VisibleForTesting
+    static final int GATT_ERROR_CODE_USER_RETRY = 30000;
+    @VisibleForTesting
+    static final int GATT_ERROR_CODE_PAIR_WITH_SAME_MODEL_ID_COUNT = 40000;
+    @VisibleForTesting
+    static final int GATT_ERROR_CODE_TIMEOUT = 1000;
+
+    @Nullable
+    private static String sInitialConnectionFirmwareVersion;
+    private static final byte[] REQUESTED_SERVICES_LTV =
+            new Ltv(
+                    TransportDiscoveryService.SERVICE_UUIDS_16_BIT_LIST_TYPE,
+                    toBytes(
+                            ByteOrder.LITTLE_ENDIAN,
+                            Constants.A2DP_SINK_SERVICE_UUID,
+                            Constants.HANDS_FREE_SERVICE_UUID,
+                            Constants.HEADSET_SERVICE_UUID))
+                    .getBytes();
+    private static final byte[] TDS_CONTROL_POINT_REQUEST =
+            concat(
+                    new byte[]{
+                            TransportDiscoveryService.ControlPointCharacteristic
+                                    .ACTIVATE_TRANSPORT_OP_CODE,
+                            TransportDiscoveryService.BLUETOOTH_SIG_ORGANIZATION_ID
+                    },
+                    REQUESTED_SERVICES_LTV);
+
+    private static boolean sTestMode = false;
+
+    static void enableTestMode() {
+        sTestMode = true;
+    }
+
+    /**
+     * Operation Result Code.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            value = {
+                    ResultCode.UNKNOWN,
+                    ResultCode.SUCCESS,
+                    ResultCode.OP_CODE_NOT_SUPPORTED,
+                    ResultCode.INVALID_PARAMETER,
+                    ResultCode.UNSUPPORTED_ORGANIZATION_ID,
+                    ResultCode.OPERATION_FAILED,
+            })
+
+    public @interface ResultCode {
+
+        int UNKNOWN = (byte) 0xFF;
+        int SUCCESS = (byte) 0x00;
+        int OP_CODE_NOT_SUPPORTED = (byte) 0x01;
+        int INVALID_PARAMETER = (byte) 0x02;
+        int UNSUPPORTED_ORGANIZATION_ID = (byte) 0x03;
+        int OPERATION_FAILED = (byte) 0x04;
+    }
+
+
+    private static @ResultCode int fromTdsControlPointIndication(byte[] response) {
+        return response == null || response.length < 2 ? ResultCode.UNKNOWN : from(response[1]);
+    }
+
+    private static @ResultCode int from(byte byteValue) {
+        switch (byteValue) {
+            case ResultCode.UNKNOWN:
+            case ResultCode.SUCCESS:
+            case ResultCode.OP_CODE_NOT_SUPPORTED:
+            case ResultCode.INVALID_PARAMETER:
+            case ResultCode.UNSUPPORTED_ORGANIZATION_ID:
+            case ResultCode.OPERATION_FAILED:
+                return byteValue;
+            default:
+                return ResultCode.UNKNOWN;
+        }
+    }
+
+    private static class BrEdrHandoverInformation {
+
+        private final byte[] mBluetoothAddress;
+        private final short[] mProfiles;
+
+        private BrEdrHandoverInformation(byte[] bluetoothAddress, short[] profiles) {
+            this.mBluetoothAddress = bluetoothAddress;
+
+            // For now, since we only connect to one profile, prefer A2DP Sink over headset/HFP.
+            // TODO(b/37167120): Connect to more than one profile.
+            Set<Short> profileSet = new HashSet<>(Shorts.asList(profiles));
+            if (profileSet.contains(Constants.A2DP_SINK_SERVICE_UUID)) {
+                profileSet.remove(Constants.HEADSET_SERVICE_UUID);
+                profileSet.remove(Constants.HANDS_FREE_SERVICE_UUID);
+            }
+            this.mProfiles = Shorts.toArray(profileSet);
+        }
+
+        @Override
+        public String toString() {
+            return "BrEdrHandoverInformation{"
+                    + maskBluetoothAddress(BluetoothAddress.encode(mBluetoothAddress))
+                    + ", profiles="
+                    + (mProfiles.length > 0 ? Shorts.join(",", mProfiles) : "(none)")
+                    + "}";
+        }
+    }
+
+    private final Context mContext;
+    private final Preferences mPreferences;
+    private final EventLoggerWrapper mEventLogger;
+    private final BluetoothAdapter mBluetoothAdapter =
+            checkNotNull(BluetoothAdapter.getDefaultAdapter());
+    private String mBleAddress;
+
+    private final TimingLogger mTimingLogger;
+    private GattConnectionManager mGattConnectionManager;
+    private boolean mProviderInitiatesBonding;
+    private @Nullable
+    byte[] mPairingSecret;
+    private @Nullable
+    byte[] mPairingKey;
+    @Nullable
+    private String mPublicAddress;
+    @VisibleForTesting
+    @Nullable
+    FastPairHistoryFinder mPairedHistoryFinder;
+    @Nullable
+    private String mProviderDeviceName = null;
+    private boolean mNeedUpdateProviderName = false;
+    @Nullable
+    DeviceNameReceiver mDeviceNameReceiver;
+    @Nullable
+    private HandshakeHandler mHandshakeHandlerForTest;
+    @Nullable
+    private Runnable mBeforeDirectlyConnectProfileFromCacheForTest;
+
+    public FastPairDualConnection(
+            Context context,
+            String bleAddress,
+            Preferences preferences,
+            @Nullable EventLogger eventLogger) {
+        this(context, bleAddress, preferences, eventLogger,
+                new TimingLogger("FastPairDualConnection", preferences));
+    }
+
+    @VisibleForTesting
+    FastPairDualConnection(
+            Context context,
+            String bleAddress,
+            Preferences preferences,
+            @Nullable EventLogger eventLogger,
+            TimingLogger timingLogger) {
+        this.mContext = context;
+        this.mPreferences = preferences;
+        this.mEventLogger = new EventLoggerWrapper(eventLogger);
+        this.mBleAddress = bleAddress;
+        this.mTimingLogger = timingLogger;
+    }
+
+    /**
+     * Unpairs with headphones. Synchronous: Blocks until unpaired. Throws on any error.
+     */
+    @WorkerThread
+    public void unpair(BluetoothDevice device)
+            throws ReflectionException, InterruptedException, ExecutionException, TimeoutException,
+            PairingException {
+        if (mPreferences.getExtraLoggingInformation() != null) {
+            mEventLogger
+                    .bind(mContext, device.getAddress(), mPreferences.getExtraLoggingInformation());
+        }
+        new BluetoothAudioPairer(
+                mContext,
+                device,
+                mPreferences,
+                mEventLogger,
+                /* keyBasedPairingInfo= */ null,
+                /* passkeyConfirmationHandler= */ null,
+                mTimingLogger)
+                .unpair();
+        if (mEventLogger.isBound()) {
+            mEventLogger.unbind(mContext);
+        }
+    }
+
+    /**
+     * Sets the fast pair history for identifying the provider which has paired (without being
+     * forgotten) with the primary account on the device, i.e. the history is not limited on this
+     * phone, can be on other phones with the same account. If they have already paired, Fast Pair
+     * should not generate new account key and default personalized name for it after initial pair.
+     */
+    @WorkerThread
+    public void setFastPairHistory(List<FastPairHistoryItem> fastPairHistoryItem) {
+        Log.i(TAG, "Paired history has been set.");
+        this.mPairedHistoryFinder = new FastPairHistoryFinder(fastPairHistoryItem);
+    }
+
+    /**
+     * Update the provider device name when we take provider default name and account based name
+     * into consideration.
+     */
+    public void setProviderDeviceName(String deviceName) {
+        Log.i(TAG, "Update provider device name = " + deviceName);
+        mProviderDeviceName = deviceName;
+        mNeedUpdateProviderName = true;
+    }
+
+    /**
+     * Gets the device name from the Provider (via GATT notify).
+     */
+    @Nullable
+    public String getProviderDeviceName() {
+        if (mDeviceNameReceiver == null) {
+            Log.i(TAG, "getProviderDeviceName failed, deviceNameReceiver == null.");
+            return null;
+        }
+        if (mPairingSecret == null) {
+            Log.i(TAG, "getProviderDeviceName failed, pairingSecret == null.");
+            return null;
+        }
+        String deviceName = mDeviceNameReceiver.getParsedResult(mPairingSecret);
+        Log.i(TAG, "getProviderDeviceName = " + deviceName);
+
+        return deviceName;
+    }
+
+    /**
+     * Get the existing account key of the provider, this API can be called after handshake.
+     *
+     * @return the existing account key if the provider has paired with the account before.
+     * Otherwise, return null, i.e. it is a real initial pairing.
+     */
+    @WorkerThread
+    @Nullable
+    public byte[] getExistingAccountKey() {
+        return mPairedHistoryFinder == null ? null : mPairedHistoryFinder.getExistingAccountKey();
+    }
+
+    /**
+     * Pairs with headphones. Synchronous: Blocks until paired and connected. Throws on any error.
+     *
+     * @return the secret key for the user's account, if written.
+     */
+    @WorkerThread
+    @Nullable
+    public SharedSecret pair()
+            throws BluetoothException, InterruptedException, ReflectionException, TimeoutException,
+            ExecutionException, PairingException {
+        try {
+            return pair(/*key=*/ null);
+        } catch (GeneralSecurityException e) {
+            throw new RuntimeException("Should never happen, no security key!", e);
+        }
+    }
+
+    /**
+     * Pairs with headphones. Synchronous: Blocks until paired and connected. Throws on any error.
+     *
+     * @param key can be in two different formats. If it is 16 bytes long, then it is an AES account
+     * key. Otherwise, it's a public key generated by {@link EllipticCurveDiffieHellmanExchange}.
+     * See go/fast-pair-2-spec for how each of these keys are used.
+     * @return the secret key for the user's account, if written
+     */
+    @WorkerThread
+    @Nullable
+    public SharedSecret pair(@Nullable byte[] key)
+            throws BluetoothException, InterruptedException, ReflectionException, TimeoutException,
+            ExecutionException, PairingException, GeneralSecurityException {
+        mPairingKey = key;
+        if (key != null) {
+            Log.i(TAG, "Starting to pair " + maskBluetoothAddress(mBleAddress) + ": key["
+                    + key.length + "], " + mPreferences);
+        } else {
+            Log.i(TAG, "Pairing " + maskBluetoothAddress(mBleAddress) + ": " + mPreferences);
+        }
+        if (mPreferences.getExtraLoggingInformation() != null) {
+            this.mEventLogger.bind(
+                    mContext, mBleAddress, mPreferences.getExtraLoggingInformation());
+        }
+        // Provider never initiates if key is null (Fast Pair 1.0).
+        if (key != null && mPreferences.getProviderInitiatesBondingIfSupported()) {
+            // Provider can't initiate if we can't get our own public address, so check.
+            this.mEventLogger.setCurrentEvent(EventCode.GET_LOCAL_PUBLIC_ADDRESS);
+            if (BluetoothAddress.getPublicAddress(mContext) != null) {
+                this.mEventLogger.logCurrentEventSucceeded();
+                mProviderInitiatesBonding = true;
+            } else {
+                this.mEventLogger
+                        .logCurrentEventFailed(new IllegalStateException("null bluetooth_address"));
+                Log.e(TAG,
+                        "Want provider to initiate bonding, but cannot access Bluetooth public "
+                                + "address. Falling back to initiating bonding ourselves.");
+            }
+        }
+
+        // User might be pairing with a bonded device. In this case, we just connect profile
+        // directly and finish pairing.
+        if (directConnectProfileWithCachedAddress()) {
+            callbackOnPaired();
+            mTimingLogger.dump();
+            if (mEventLogger.isBound()) {
+                mEventLogger.unbind(mContext);
+            }
+            return null;
+        }
+
+        // Lazily initialize a new connection manager for each pairing request.
+        initGattConnectionManager();
+        boolean isSecretHandshakeCompleted = true;
+
+        try {
+            if (key != null && key.length > 0) {
+                // GATT_CONNECTION_AND_SECRET_HANDSHAKE start.
+                mEventLogger.setCurrentEvent(EventCode.GATT_CONNECTION_AND_SECRET_HANDSHAKE);
+                isSecretHandshakeCompleted = false;
+                Exception lastException = null;
+                boolean lastExceptionFromHandshake = false;
+                long startTime = SystemClock.elapsedRealtime();
+                // We communicate over this connection twice for Key-based Pairing: once before
+                // bonding begins, and once during (to transfer the passkey). Empirically, keeping
+                // it alive throughout is far more reliable than disconnecting and reconnecting for
+                // each step. The while loop is for retry of GATT connection and handshake only.
+                do {
+                    boolean isHandshaking = false;
+                    try (BluetoothGattConnection connection =
+                            mGattConnectionManager
+                                    .getConnectionWithSignalLostCheck(mRescueFromError)) {
+                        mEventLogger.setCurrentEvent(EventCode.SECRET_HANDSHAKE);
+                        if (lastException != null && !lastExceptionFromHandshake) {
+                            logRetrySuccessEvent(EventCode.RECOVER_BY_RETRY_GATT, lastException,
+                                    mEventLogger);
+                            lastException = null;
+                        }
+                        try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger,
+                                "Handshake")) {
+                            isHandshaking = true;
+                            handshakeForKeyBasedPairing(key);
+                            // After handshake, Fast Pair has the public address of the provider, so
+                            // we can check if it has paired with the account.
+                            if (mPublicAddress != null && mPairedHistoryFinder != null) {
+                                if (mPairedHistoryFinder.isInPairedHistory(mPublicAddress)) {
+                                    Log.i(TAG, "The provider is found in paired history.");
+                                } else {
+                                    Log.i(TAG, "The provider is not found in paired history.");
+                                }
+                            }
+                        }
+                        isHandshaking = false;
+                        // SECRET_HANDSHAKE end.
+                        mEventLogger.logCurrentEventSucceeded();
+                        isSecretHandshakeCompleted = true;
+                        if (mPrepareCreateBondCallback != null) {
+                            mPrepareCreateBondCallback.run();
+                        }
+                        if (lastException != null && lastExceptionFromHandshake) {
+                            logRetrySuccessEvent(EventCode.RECOVER_BY_RETRY_HANDSHAKE_RECONNECT,
+                                    lastException, mEventLogger);
+                        }
+                        logManualRetryCounts(/* success= */ true);
+                        // GATT_CONNECTION_AND_SECRET_HANDSHAKE end.
+                        mEventLogger.logCurrentEventSucceeded();
+                        return pair(mPreferences.getEnableBrEdrHandover());
+                    } catch (SignalLostException e) {
+                        long spentTime = SystemClock.elapsedRealtime() - startTime;
+                        if (spentTime > mPreferences.getAddressRotateRetryMaxSpentTimeMs()) {
+                            Log.w(TAG, "Signal lost but already spend too much time " + spentTime
+                                    + "ms");
+                            throw e;
+                        }
+
+                        logCurrentEventFailedBySignalLost(e);
+                        lastException = (Exception) e.getCause();
+                        lastExceptionFromHandshake = isHandshaking;
+                        if (mRescueFromError != null && isHandshaking) {
+                            mRescueFromError.accept(ErrorCode.SUCCESS_SECRET_HANDSHAKE_RECONNECT);
+                        }
+                        Log.i(TAG, "Signal lost, retry");
+                        // In case we meet some GATT error which is not recoverable and fail very
+                        // quick.
+                        SystemClock.sleep(mPreferences.getPairingRetryDelayMs());
+                    } catch (SignalRotatedException e) {
+                        long spentTime = SystemClock.elapsedRealtime() - startTime;
+                        if (spentTime > mPreferences.getAddressRotateRetryMaxSpentTimeMs()) {
+                            Log.w(TAG, "Address rotated but already spend too much time "
+                                    + spentTime + "ms");
+                            throw e;
+                        }
+
+                        logCurrentEventFailedBySignalRotated(e);
+                        setBleAddress(e.getNewAddress());
+                        lastException = (Exception) e.getCause();
+                        lastExceptionFromHandshake = isHandshaking;
+                        if (mRescueFromError != null) {
+                            mRescueFromError.accept(ErrorCode.SUCCESS_ADDRESS_ROTATE);
+                        }
+                        Log.i(TAG, "Address rotated, retry");
+                    } catch (HandshakeException e) {
+                        long spentTime = SystemClock.elapsedRealtime() - startTime;
+                        if (spentTime > mPreferences
+                                .getSecretHandshakeRetryGattConnectionMaxSpentTimeMs()) {
+                            Log.w(TAG, "Secret handshake failed but already spend too much time "
+                                    + spentTime + "ms");
+                            throw e.getOriginalException();
+                        }
+                        if (mEventLogger.isCurrentEvent()) {
+                            mEventLogger.logCurrentEventFailed(e.getOriginalException());
+                        }
+                        initGattConnectionManager();
+                        lastException = e.getOriginalException();
+                        lastExceptionFromHandshake = true;
+                        if (mRescueFromError != null) {
+                            mRescueFromError.accept(ErrorCode.SUCCESS_SECRET_HANDSHAKE_RECONNECT);
+                        }
+                        Log.i(TAG, "Handshake failed, retry GATT connection");
+                    }
+                } while (mPreferences.getRetryGattConnectionAndSecretHandshake());
+            }
+            if (mPrepareCreateBondCallback != null) {
+                mPrepareCreateBondCallback.run();
+            }
+            return pair(mPreferences.getEnableBrEdrHandover());
+        } catch (SignalLostException e) {
+            logCurrentEventFailedBySignalLost(e);
+            // GATT_CONNECTION_AND_SECRET_HANDSHAKE end.
+            if (!isSecretHandshakeCompleted) {
+                logManualRetryCounts(/* success= */ false);
+                logCurrentEventFailedBySignalLost(e);
+            }
+            throw e;
+        } catch (SignalRotatedException e) {
+            logCurrentEventFailedBySignalRotated(e);
+            // GATT_CONNECTION_AND_SECRET_HANDSHAKE end.
+            if (!isSecretHandshakeCompleted) {
+                logManualRetryCounts(/* success= */ false);
+                logCurrentEventFailedBySignalRotated(e);
+            }
+            throw e;
+        } catch (BluetoothException
+                | InterruptedException
+                | ReflectionException
+                | TimeoutException
+                | ExecutionException
+                | PairingException
+                | GeneralSecurityException e) {
+            if (mEventLogger.isCurrentEvent()) {
+                mEventLogger.logCurrentEventFailed(e);
+            }
+            // GATT_CONNECTION_AND_SECRET_HANDSHAKE end.
+            if (!isSecretHandshakeCompleted) {
+                logManualRetryCounts(/* success= */ false);
+                if (mEventLogger.isCurrentEvent()) {
+                    mEventLogger.logCurrentEventFailed(e);
+                }
+            }
+            throw e;
+        } finally {
+            mTimingLogger.dump();
+            if (mEventLogger.isBound()) {
+                mEventLogger.unbind(mContext);
+            }
+        }
+    }
+
+    private boolean directConnectProfileWithCachedAddress() throws ReflectionException {
+        if (TextUtils.isEmpty(mPreferences.getCachedDeviceAddress())
+                || !mPreferences.getDirectConnectProfileIfModelIdInCache()
+                || mPreferences.getSkipConnectingProfiles()) {
+            return false;
+        }
+        Log.i(TAG, "Try to direct connect profile with cached address "
+                + maskBluetoothAddress(mPreferences.getCachedDeviceAddress()));
+        mEventLogger.setCurrentEvent(EventCode.DIRECTLY_CONNECT_PROFILE_WITH_CACHED_ADDRESS);
+        BluetoothDevice device =
+                mBluetoothAdapter.getRemoteDevice(mPreferences.getCachedDeviceAddress()).unwrap();
+        AtomicBoolean interruptConnection = new AtomicBoolean(false);
+        BroadcastReceiver receiver =
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        if (intent == null
+                                || !BluetoothDevice.ACTION_PAIRING_REQUEST
+                                .equals(intent.getAction())) {
+                            return;
+                        }
+                        BluetoothDevice pairingDevice = intent
+                                .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                        if (pairingDevice == null || !device.getAddress()
+                                .equals(pairingDevice.getAddress())) {
+                            return;
+                        }
+                        abortBroadcast();
+                        // Should be the clear link key case, make it fail directly to go back to
+                        // initial pairing process.
+                        pairingDevice.setPairingConfirmation(/* confirm= */ false);
+                        Log.w(TAG, "Get pairing request broadcast for device "
+                                + maskBluetoothAddress(device.getAddress())
+                                + " while try to direct connect profile with cached address, reject"
+                                + " and to go back to initial pairing process");
+                        interruptConnection.set(true);
+                    }
+                };
+        mContext.registerReceiver(receiver,
+                new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST));
+        try (ScopedTiming scopedTiming =
+                new ScopedTiming(mTimingLogger,
+                        "Connect to profile with cached address directly")) {
+            if (mBeforeDirectlyConnectProfileFromCacheForTest != null) {
+                mBeforeDirectlyConnectProfileFromCacheForTest.run();
+            }
+            attemptConnectProfiles(
+                    new BluetoothAudioPairer(
+                            mContext,
+                            device,
+                            mPreferences,
+                            mEventLogger,
+                            /* keyBasedPairingInfo= */ null,
+                            /* passkeyConfirmationHandler= */ null,
+                            mTimingLogger),
+                    maskBluetoothAddress(device),
+                    getSupportedProfiles(device),
+                    /* numConnectionAttempts= */ 1,
+                    /* enablePairingBehavior= */ false,
+                    interruptConnection);
+            Log.i(TAG,
+                    "Directly connected to " + maskBluetoothAddress(device)
+                            + "with cached address.");
+            mEventLogger.logCurrentEventSucceeded();
+            mEventLogger.setDevice(device);
+            logPairWithPossibleCachedAddress(device.getAddress());
+            return true;
+        } catch (PairingException e) {
+            if (interruptConnection.get()) {
+                Log.w(TAG, "Fail to connected to " + maskBluetoothAddress(device)
+                        + " with cached address due to link key is cleared.", e);
+                mEventLogger.logCurrentEventFailed(
+                        new ConnectException(ConnectErrorCode.LINK_KEY_CLEARED,
+                                "Link key is cleared"));
+            } else {
+                Log.w(TAG, "Fail to connected to " + maskBluetoothAddress(device)
+                        + " with cached address.", e);
+                mEventLogger.logCurrentEventFailed(e);
+            }
+            return false;
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    /**
+     * Logs for user retry, check go/fastpairquality21q3 for more details.
+     */
+    private void logManualRetryCounts(boolean success) {
+        if (!mPreferences.getLogUserManualRetry()) {
+            return;
+        }
+
+        // We don't want to be the final event on analytics.
+        if (!mEventLogger.isCurrentEvent()) {
+            return;
+        }
+
+        mEventLogger.setCurrentEvent(EventCode.GATT_HANDSHAKE_MANUAL_RETRY_ATTEMPTS);
+        if (mPreferences.getPairFailureCounts() <= 0 && success) {
+            mEventLogger.logCurrentEventSucceeded();
+        } else {
+            int errorCode = mPreferences.getPairFailureCounts();
+            if (errorCode > 99) {
+                errorCode = 99;
+            }
+            errorCode += success ? 0 : 100;
+            // To not conflict with current error codes.
+            errorCode += GATT_ERROR_CODE_USER_RETRY;
+            mEventLogger.logCurrentEventFailed(
+                    new BluetoothGattException("Error for manual retry", errorCode));
+        }
+    }
+
+    static void logRetrySuccessEvent(
+            @EventCode int eventCode,
+            @Nullable Exception recoverFromException,
+            EventLoggerWrapper eventLogger) {
+        if (recoverFromException == null) {
+            return;
+        }
+        eventLogger.setCurrentEvent(eventCode);
+        eventLogger.logCurrentEventFailed(recoverFromException);
+    }
+
+    private void initGattConnectionManager() {
+        mGattConnectionManager =
+                new GattConnectionManager(
+                        mContext,
+                        mPreferences,
+                        mEventLogger,
+                        mBluetoothAdapter,
+                        this::toggleBluetooth,
+                        mBleAddress,
+                        mTimingLogger,
+                        mFastPairSignalChecker,
+                        isPairingWithAntiSpoofingPublicKey());
+    }
+
+    private void logCurrentEventFailedBySignalRotated(SignalRotatedException e) {
+        if (!mEventLogger.isCurrentEvent()) {
+            return;
+        }
+
+        Log.w(TAG, "BLE Address for pairing device might rotated!");
+        mEventLogger.logCurrentEventFailed(
+                new BluetoothGattException(
+                        "BLE Address for pairing device might rotated",
+                        appendMoreErrorCode(GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED,
+                                e.getCause()),
+                        e));
+    }
+
+    private void logCurrentEventFailedBySignalLost(SignalLostException e) {
+        if (!mEventLogger.isCurrentEvent()) {
+            return;
+        }
+
+        Log.w(TAG, "BLE signal for pairing device might lost!");
+        mEventLogger.logCurrentEventFailed(
+                new BluetoothGattException(
+                        "BLE signal for pairing device might lost",
+                        appendMoreErrorCode(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST, e.getCause()),
+                        e));
+    }
+
+    @VisibleForTesting
+    static int appendMoreErrorCode(int masterErrorCode, @Nullable Throwable cause) {
+        if (cause instanceof BluetoothGattException) {
+            return masterErrorCode + ((BluetoothGattException) cause).getGattErrorCode();
+        } else if (cause instanceof TimeoutException
+                || cause instanceof BluetoothTimeoutException
+                || cause instanceof BluetoothOperationTimeoutException) {
+            return masterErrorCode + GATT_ERROR_CODE_TIMEOUT;
+        } else {
+            return masterErrorCode;
+        }
+    }
+
+    private void setBleAddress(String newAddress) {
+        if (TextUtils.isEmpty(newAddress) || Ascii.equalsIgnoreCase(newAddress, mBleAddress)) {
+            return;
+        }
+
+        mBleAddress = newAddress;
+
+        // Recreates a GattConnectionManager with the new address for establishing a new GATT
+        // connection later.
+        initGattConnectionManager();
+
+        mEventLogger.setDevice(mBluetoothAdapter.getRemoteDevice(mBleAddress).unwrap());
+    }
+
+    /**
+     * Gets the public address of the headset used in the connection. Before the handshake, this
+     * could be null.
+     */
+    @Nullable
+    public String getPublicAddress() {
+        return mPublicAddress;
+    }
+
+    /**
+     * Pairs with a Bluetooth device. In general, this process goes through the following steps:
+     *
+     * <ol>
+     *   <li>Get BrEdr handover information if requested
+     *   <li>Discover the device (on Android N and lower to work around a bug)
+     *   <li>Connect to the device
+     *       <ul>
+     *         <li>Attempt a direct connection to a supported profile if we're already bonded
+     *         <li>Create a new bond with the not bonded device and then connect to a supported
+     *             profile
+     *       </ul>
+     *   <li>Write the account secret
+     * </ol>
+     *
+     * <p>Blocks until paired. May take 10+ seconds, so run on a background thread.
+     */
+    @Nullable
+    private SharedSecret pair(boolean enableBrEdrHandover)
+            throws BluetoothException, InterruptedException, ReflectionException, TimeoutException,
+            ExecutionException, PairingException, GeneralSecurityException {
+        BrEdrHandoverInformation brEdrHandoverInformation = null;
+        if (enableBrEdrHandover) {
+            try (ScopedTiming scopedTiming =
+                    new ScopedTiming(mTimingLogger, "Get BR/EDR handover information via GATT")) {
+                brEdrHandoverInformation =
+                        getBrEdrHandoverInformation(mGattConnectionManager.getConnection());
+            } catch (BluetoothException | TdsException e) {
+                Log.w(TAG,
+                        "Couldn't get BR/EDR Handover info via TDS. Trying direct connect.", e);
+                mEventLogger.logCurrentEventFailed(e);
+            }
+        }
+
+        if (brEdrHandoverInformation == null) {
+            // Pair directly to the BLE address. Works if the BLE and Bluetooth Classic addresses
+            // are the same, or if we can do BLE cross-key transport.
+            brEdrHandoverInformation =
+                    new BrEdrHandoverInformation(
+                            BluetoothAddress
+                                    .decode(mPublicAddress != null ? mPublicAddress : mBleAddress),
+                            attemptGetBluetoothClassicProfiles(
+                                    mBluetoothAdapter.getRemoteDevice(mBleAddress).unwrap(),
+                                    mPreferences.getNumSdpAttempts()));
+        }
+
+        BluetoothDevice device =
+                mBluetoothAdapter.getRemoteDevice(brEdrHandoverInformation.mBluetoothAddress)
+                        .unwrap();
+        callbackOnGetAddress(device.getAddress());
+        mEventLogger.setDevice(device);
+
+        Log.i(TAG, "Pairing with " + brEdrHandoverInformation);
+        KeyBasedPairingInfo keyBasedPairingInfo =
+                mPairingSecret == null
+                        ? null
+                        : new KeyBasedPairingInfo(
+                                mPairingSecret, mGattConnectionManager, mProviderInitiatesBonding);
+
+        BluetoothAudioPairer pairer =
+                new BluetoothAudioPairer(
+                        mContext,
+                        device,
+                        mPreferences,
+                        mEventLogger,
+                        keyBasedPairingInfo,
+                        mPasskeyConfirmationHandler,
+                        mTimingLogger);
+
+        logPairWithPossibleCachedAddress(device.getAddress());
+        logPairWithModelIdInCacheAndDiscoveryFailForCachedAddress(device);
+
+        // In the case where we are already bonded, we should first just try connecting to supported
+        // profiles. If successful, then this will be much faster than recreating the bond like we
+        // normally do and we can finish early. It is also more reliable than tearing down the bond
+        // and recreating it.
+        try {
+            if (!sTestMode) {
+                attemptDirectConnectionIfBonded(device, pairer);
+            }
+            callbackOnPaired();
+            return maybeWriteAccountKey(device);
+        } catch (PairingException e) {
+            Log.i(TAG, "Failed to directly connect to supported profiles: " + e.getMessage());
+            // Catches exception when we fail to connect support profile. And makes the flow to go
+            // through step to write account key when device is bonded.
+            if (mPreferences.getEnablePairFlowShowUiWithoutProfileConnection()
+                    && device.getBondState() == BluetoothDevice.BOND_BONDED) {
+                if (mPreferences.getSkipConnectingProfiles()
+                        && !mPreferences.getCheckBondStateWhenSkipConnectingProfiles()) {
+                    Log.i(TAG, "For notCheckBondStateWhenSkipConnectingProfiles case should do "
+                            + "re-bond");
+                } else {
+                    Log.i(TAG, "Fail to connect profile when device is bonded, still call back on"
+                            + "pair callback to show ui");
+                    callbackOnPaired();
+                    return maybeWriteAccountKey(device);
+                }
+            }
+        }
+
+        if (mPreferences.getMoreEventLogForQuality()) {
+            switch (device.getBondState()) {
+                case BOND_BONDED:
+                    mEventLogger.setCurrentEvent(EventCode.BEFORE_CREATE_BOND_BONDED);
+                    break;
+                case BOND_BONDING:
+                    mEventLogger.setCurrentEvent(EventCode.BEFORE_CREATE_BOND_BONDING);
+                    break;
+                case BOND_NONE:
+                default:
+                    mEventLogger.setCurrentEvent(EventCode.BEFORE_CREATE_BOND);
+            }
+        }
+
+        for (int i = 1; i <= mPreferences.getNumCreateBondAttempts(); i++) {
+            try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger, "Pair device #" + i)) {
+                pairer.pair();
+                if (mPreferences.getMoreEventLogForQuality()) {
+                    // For EventCode.BEFORE_CREATE_BOND
+                    mEventLogger.logCurrentEventSucceeded();
+                }
+                break;
+            } catch (Exception e) {
+                mEventLogger.logCurrentEventFailed(e);
+                if (mPasskeyIsGotten) {
+                    Log.w(TAG,
+                            "createBond() failed because of " + e.getMessage()
+                                    + " after getting the passkey. Skip retry.");
+                    if (mPreferences.getMoreEventLogForQuality()) {
+                        // For EventCode.BEFORE_CREATE_BOND
+                        mEventLogger.logCurrentEventFailed(
+                                new CreateBondException(
+                                        CreateBondErrorCode.FAILED_BUT_ALREADY_RECEIVE_PASS_KEY,
+                                        0,
+                                        "Already get the passkey"));
+                    }
+                    break;
+                }
+                Log.e(TAG,
+                        "removeBond() or createBond() failed, attempt " + i + " of " + mPreferences
+                                .getNumCreateBondAttempts() + ". Bond state "
+                                + device.getBondState(), e);
+                if (i < mPreferences.getNumCreateBondAttempts()) {
+                    toggleBluetooth();
+
+                    // We've seen 3 createBond() failures within 100ms (!). And then success again
+                    // later (even without turning on/off bluetooth). So create some minimum break
+                    // time.
+                    Log.i(TAG, "Sleeping 1 sec after createBond() failure.");
+                    SystemClock.sleep(1000);
+                } else if (mPreferences.getMoreEventLogForQuality()) {
+                    // For EventCode.BEFORE_CREATE_BOND
+                    mEventLogger.logCurrentEventFailed(e);
+                }
+            }
+        }
+        boolean deviceCreateBondFailWithNullSecret = false;
+        if (!pairer.isPaired()) {
+            if (mPairingSecret != null) {
+                // Bonding could fail for a few different reasons here. It could be an error, an
+                // attacker may have tried to bond, or the device may not be up to spec.
+                throw new PairingException("createBond() failed, exiting connection process.");
+            } else if (mPreferences.getSkipConnectingProfiles()) {
+                throw new PairingException(
+                        "createBond() failed and skipping connecting to a profile.");
+            } else {
+                // When bond creation has failed, connecting a profile will still work most of the
+                // time for Fast Pair 1.0 devices (ie, pairing secret is null), so continue on with
+                // the spec anyways and attempt to connect supported profiles.
+                Log.w(TAG, "createBond() failed, will try connecting profiles anyway.");
+                deviceCreateBondFailWithNullSecret = true;
+            }
+        } else if (mPreferences.getEnablePairFlowShowUiWithoutProfileConnection()) {
+            Log.i(TAG, "new flow to call on paired callback for ui when pairing step is finished");
+            callbackOnPaired();
+        }
+
+        if (!mPreferences.getSkipConnectingProfiles()) {
+            if (mPreferences.getWaitForUuidsAfterBonding()
+                    && brEdrHandoverInformation.mProfiles.length == 0) {
+                short[] supportedProfiles = getCachedUuids(device);
+                if (supportedProfiles.length == 0
+                        && mPreferences.getNumSdpAttemptsAfterBonded() > 0) {
+                    Log.i(TAG, "Found no supported profiles in UUID cache, manually trigger SDP.");
+                    attemptGetBluetoothClassicProfiles(device,
+                            mPreferences.getNumSdpAttemptsAfterBonded());
+                }
+                brEdrHandoverInformation =
+                        new BrEdrHandoverInformation(
+                                brEdrHandoverInformation.mBluetoothAddress, supportedProfiles);
+            }
+            short[] profiles = brEdrHandoverInformation.mProfiles;
+            if (profiles.length == 0) {
+                profiles = Constants.getSupportedProfiles();
+                Log.w(TAG,
+                        "Attempting to connect constants profiles, " + Arrays.toString(profiles));
+            } else {
+                Log.i(TAG, "Attempting to connect device profiles, " + Arrays.toString(profiles));
+            }
+
+            try {
+                attemptConnectProfiles(
+                        pairer,
+                        maskBluetoothAddress(device),
+                        profiles,
+                        mPreferences.getNumConnectAttempts(),
+                        /* enablePairingBehavior= */ false);
+            } catch (PairingException e) {
+                // For new pair flow to show ui, we already show success ui when finishing the
+                // createBond step. So we should catch the exception from connecting profile to
+                // avoid showing fail ui for user.
+                if (mPreferences.getEnablePairFlowShowUiWithoutProfileConnection()
+                        && !deviceCreateBondFailWithNullSecret) {
+                    Log.i(TAG, "Fail to connect profile when device is bonded");
+                } else {
+                    throw e;
+                }
+            }
+        }
+        if (!mPreferences.getEnablePairFlowShowUiWithoutProfileConnection()) {
+            Log.i(TAG, "original flow to call on paired callback for ui");
+            callbackOnPaired();
+        } else if (deviceCreateBondFailWithNullSecret) {
+            // This paired callback is called for device which create bond fail with null secret
+            // such as FastPair 1.0 device when directly connecting to any supported profile.
+            Log.i(TAG, "call on paired callback for ui for device with null secret without bonded "
+                    + "state");
+            callbackOnPaired();
+        }
+        if (mPreferences.getEnableFirmwareVersionCharacteristic()
+                && validateBluetoothGattCharacteristic(
+                mGattConnectionManager.getConnection(), FirmwareVersionCharacteristic.ID)) {
+            try {
+                sInitialConnectionFirmwareVersion = readFirmwareVersion();
+            } catch (BluetoothException e) {
+                Log.i(TAG, "Fast Pair: head phone does not support firmware read", e);
+            }
+        }
+
+        // Catch exception when writing account key or name fail to avoid showing pairing failure
+        // notice for user. Because device is already paired successfully based on paring step.
+        SharedSecret secret = null;
+        try {
+            secret = maybeWriteAccountKey(device);
+        } catch (InterruptedException
+                | ExecutionException
+                | TimeoutException
+                | NoSuchAlgorithmException
+                | BluetoothException e) {
+            Log.w(TAG, "Fast Pair: Got exception when writing account key or name to provider", e);
+        }
+
+        return secret;
+    }
+
+    private void logPairWithPossibleCachedAddress(String brEdrAddressForBonding) {
+        if (TextUtils.isEmpty(mPreferences.getPossibleCachedDeviceAddress())
+                || !mPreferences.getLogPairWithCachedModelId()) {
+            return;
+        }
+        mEventLogger.setCurrentEvent(EventCode.PAIR_WITH_CACHED_MODEL_ID);
+        if (Ascii.equalsIgnoreCase(
+                mPreferences.getPossibleCachedDeviceAddress(), brEdrAddressForBonding)) {
+            mEventLogger.logCurrentEventSucceeded();
+            Log.i(TAG, "Repair with possible cached device "
+                    + maskBluetoothAddress(mPreferences.getPossibleCachedDeviceAddress()));
+        } else {
+            mEventLogger.logCurrentEventFailed(
+                    new PairingException("Pairing with 2nd device with same model ID"));
+            Log.i(TAG, "Pair with a new device " + maskBluetoothAddress(brEdrAddressForBonding)
+                    + " with model ID in cache "
+                    + maskBluetoothAddress(mPreferences.getPossibleCachedDeviceAddress()));
+        }
+    }
+
+    /**
+     * Logs two type of events. First, why cachedAddress mechanism doesn't work if it's repair with
+     * bonded device case. Second, if it's not the case, log how many devices with the same model Id
+     * is already paired.
+     */
+    private void logPairWithModelIdInCacheAndDiscoveryFailForCachedAddress(BluetoothDevice device) {
+        if (!mPreferences.getLogPairWithCachedModelId()) {
+            return;
+        }
+
+        if (device.getBondState() == BOND_BONDED) {
+            if (mPreferences.getSameModelIdPairedDeviceCount() <= 0) {
+                Log.i(TAG, "Device is bonded but we don't have this model Id in cache.");
+            } else if (TextUtils.isEmpty(mPreferences.getCachedDeviceAddress())
+                    && mPreferences.getDirectConnectProfileIfModelIdInCache()
+                    && !mPreferences.getSkipConnectingProfiles()) {
+                // Pair with bonded device case. Log why the cached address is not found.
+                mEventLogger.setCurrentEvent(
+                        EventCode.DIRECTLY_CONNECT_PROFILE_WITH_CACHED_ADDRESS);
+                mEventLogger.logCurrentEventFailed(
+                        mPreferences.getIsDeviceFinishCheckAddressFromCache()
+                                ? new ConnectException(ConnectErrorCode.FAIL_TO_DISCOVERY,
+                                "Failed to discovery")
+                                : new ConnectException(
+                                        ConnectErrorCode.DISCOVERY_NOT_FINISHED,
+                                        "Discovery not finished"));
+                Log.i(TAG, "Failed to get cached address due to "
+                        + (mPreferences.getIsDeviceFinishCheckAddressFromCache()
+                        ? "Failed to discovery"
+                        : "Discovery not finished"));
+            }
+        } else if (device.getBondState() == BOND_NONE) {
+            // Pair with new device case, log how many devices with the same model id is in FastPair
+            // cache already.
+            mEventLogger.setCurrentEvent(EventCode.PAIR_WITH_NEW_MODEL);
+            if (mPreferences.getSameModelIdPairedDeviceCount() <= 0) {
+                mEventLogger.logCurrentEventSucceeded();
+            } else {
+                mEventLogger.logCurrentEventFailed(
+                        new BluetoothGattException(
+                                "Already have this model ID in cache",
+                                GATT_ERROR_CODE_PAIR_WITH_SAME_MODEL_ID_COUNT
+                                        + mPreferences.getSameModelIdPairedDeviceCount()));
+            }
+            Log.i(TAG, "This device already has " + mPreferences.getSameModelIdPairedDeviceCount()
+                    + " peripheral with the same model Id");
+        }
+    }
+
+    /**
+     * Attempts to directly connect to any supported profile if we're already bonded, this will save
+     * time over tearing down the bond and recreating it.
+     */
+    private void attemptDirectConnectionIfBonded(BluetoothDevice device,
+            BluetoothAudioPairer pairer)
+            throws PairingException {
+        if (mPreferences.getSkipConnectingProfiles()) {
+            if (mPreferences.getCheckBondStateWhenSkipConnectingProfiles()
+                    && device.getBondState() == BluetoothDevice.BOND_BONDED) {
+                Log.i(TAG, "Skipping connecting to profiles by preferences.");
+                return;
+            }
+            throw new PairingException(
+                    "Skipping connecting to profiles, no direct connection possible.");
+        } else if (!mPreferences.getAttemptDirectConnectionWhenPreviouslyBonded()
+                || device.getBondState() != BluetoothDevice.BOND_BONDED) {
+            throw new PairingException(
+                    "Not previously bonded skipping direct connection, %s", device.getBondState());
+        }
+        short[] supportedProfiles = getSupportedProfiles(device);
+        mEventLogger.setCurrentEvent(EventCode.DIRECTLY_CONNECTED_TO_PROFILE);
+        try (ScopedTiming scopedTiming =
+                new ScopedTiming(mTimingLogger, "Connect to profile directly")) {
+            attemptConnectProfiles(
+                    pairer,
+                    maskBluetoothAddress(device),
+                    supportedProfiles,
+                    mPreferences.getEnablePairFlowShowUiWithoutProfileConnection()
+                            ? mPreferences.getNumConnectAttempts()
+                            : 1,
+                    mPreferences.getEnablePairingWhileDirectlyConnecting());
+            Log.i(TAG, "Directly connected to " + maskBluetoothAddress(device));
+            mEventLogger.logCurrentEventSucceeded();
+        } catch (PairingException e) {
+            mEventLogger.logCurrentEventFailed(e);
+            // Rethrow e so that the exception bubbles up and we continue the normal pairing
+            // process.
+            throw e;
+        }
+    }
+
+    @VisibleForTesting
+    void attemptConnectProfiles(
+            BluetoothAudioPairer pairer,
+            String deviceMaskedBluetoothAddress,
+            short[] profiles,
+            int numConnectionAttempts,
+            boolean enablePairingBehavior)
+            throws PairingException {
+        attemptConnectProfiles(
+                pairer,
+                deviceMaskedBluetoothAddress,
+                profiles,
+                numConnectionAttempts,
+                enablePairingBehavior,
+                new AtomicBoolean(false));
+    }
+
+    private void attemptConnectProfiles(
+            BluetoothAudioPairer pairer,
+            String deviceMaskedBluetoothAddress,
+            short[] profiles,
+            int numConnectionAttempts,
+            boolean enablePairingBehavior,
+            AtomicBoolean interruptConnection)
+            throws PairingException {
+        if (mPreferences.getMoreEventLogForQuality()) {
+            mEventLogger.setCurrentEvent(EventCode.BEFORE_CONNECT_PROFILE);
+        }
+        Exception lastException = null;
+        for (short profile : profiles) {
+            if (interruptConnection.get()) {
+                Log.w(TAG, "attemptConnectProfiles interrupted");
+                break;
+            }
+            if (!mPreferences.isSupportedProfile(profile)) {
+                Log.w(TAG, "Ignoring unsupported profile=" + profile);
+                continue;
+            }
+            for (int i = 1; i <= numConnectionAttempts; i++) {
+                if (interruptConnection.get()) {
+                    Log.w(TAG, "attemptConnectProfiles interrupted");
+                    break;
+                }
+                mEventLogger.setCurrentEvent(EventCode.CONNECT_PROFILE);
+                mEventLogger.setCurrentProfile(profile);
+                try {
+                    pairer.connect(profile, enablePairingBehavior);
+                    mEventLogger.logCurrentEventSucceeded();
+                    if (mPreferences.getMoreEventLogForQuality()) {
+                        // For EventCode.BEFORE_CONNECT_PROFILE
+                        mEventLogger.logCurrentEventSucceeded();
+                    }
+                    // If successful, we're done.
+                    // TODO(b/37167120): Connect to more than one profile.
+                    return;
+                } catch (InterruptedException
+                        | ReflectionException
+                        | TimeoutException
+                        | ExecutionException
+                        | ConnectException e) {
+                    Log.w(TAG,
+                            "Error connecting to profile=" + profile
+                                    + " for device=" + deviceMaskedBluetoothAddress
+                                    + " (attempt " + i + " of " + mPreferences
+                                    .getNumConnectAttempts(), e);
+                    mEventLogger.logCurrentEventFailed(e);
+                    lastException = e;
+                }
+            }
+        }
+        if (mPreferences.getMoreEventLogForQuality()) {
+            // For EventCode.BEFORE_CONNECT_PROFILE
+            if (lastException != null) {
+                mEventLogger.logCurrentEventFailed(lastException);
+            } else {
+                mEventLogger.logCurrentEventSucceeded();
+            }
+        }
+        throw new PairingException(
+                "Unable to connect to any profiles in: %s", Arrays.toString(profiles));
+    }
+
+    /**
+     * Checks whether or not an account key should be written to the device and writes it if so.
+     * This is called after handle notifying the pairedCallback that we've finished pairing, because
+     * at this point the headset is ready to use.
+     */
+    @Nullable
+    private SharedSecret maybeWriteAccountKey(BluetoothDevice device)
+            throws InterruptedException, ExecutionException, TimeoutException,
+            NoSuchAlgorithmException,
+            BluetoothException {
+        if (!sTestMode) {
+            Locator.get(mContext, FastPairController.class).setShouldUpload(false);
+        }
+        if (!shouldWriteAccountKey()) {
+            // For FastPair 2.0, here should be a subsequent pairing case.
+            return null;
+        }
+
+        // Check if it should be a subsequent pairing but go through initial pairing. If there is an
+        // existed paired history found, use the same account key instead of creating a new one.
+        byte[] accountKey =
+                mPairedHistoryFinder == null ? null : mPairedHistoryFinder.getExistingAccountKey();
+        if (accountKey == null) {
+            // It is a real initial pairing, generate a new account key for the headset.
+            try (ScopedTiming scopedTiming1 =
+                    new ScopedTiming(mTimingLogger, "Write account key")) {
+                accountKey = doWriteAccountKey(createAccountKey(), device.getAddress());
+                if (accountKey == null) {
+                    // Without writing account key back to provider, close the connection.
+                    mGattConnectionManager.closeConnection();
+                    return null;
+                }
+                if (!mPreferences.getIsRetroactivePairing()) {
+                    try (ScopedTiming scopedTiming2 = new ScopedTiming(mTimingLogger,
+                            "Start CloudSyncing")) {
+                        // Start to sync to the footprint
+                        Locator.get(mContext, FastPairController.class).setShouldUpload(true);
+                        //mContext.startService(createCloudSyncingIntent(accountKey));
+                    } catch (SecurityException e) {
+                        Log.w(TAG, "Error adding device.", e);
+                    }
+                }
+            }
+        } else if (shouldWriteAccountKeyForExistingCase(accountKey)) {
+            // There is an existing account key, but go through initial pairing, and still write the
+            // existing account key.
+            doWriteAccountKey(accountKey, device.getAddress());
+        }
+
+        // When finish writing account key in initial pairing, write new device name back to
+        // provider.
+        UUID characteristicUuid = NameCharacteristic.getId(mGattConnectionManager.getConnection());
+        if (mPreferences.getEnableNamingCharacteristic()
+                && mNeedUpdateProviderName
+                && validateBluetoothGattCharacteristic(
+                mGattConnectionManager.getConnection(), characteristicUuid)) {
+            try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger,
+                    "WriteNameToProvider")) {
+                writeNameToProvider(this.mProviderDeviceName, device.getAddress());
+            }
+        }
+
+        // When finish writing account key and name back to provider, close the connection.
+        mGattConnectionManager.closeConnection();
+        return SharedSecret.create(accountKey, device.getAddress());
+    }
+
+    private boolean shouldWriteAccountKey() {
+        return isWritingAccountKeyEnabled() && isPairingWithAntiSpoofingPublicKey();
+    }
+
+    private boolean isWritingAccountKeyEnabled() {
+        return mPreferences.getNumWriteAccountKeyAttempts() > 0;
+    }
+
+    private boolean isPairingWithAntiSpoofingPublicKey() {
+        return isPairingWithAntiSpoofingPublicKey(mPairingKey);
+    }
+
+    private boolean isPairingWithAntiSpoofingPublicKey(@Nullable byte[] key) {
+        return key != null && key.length == EllipticCurveDiffieHellmanExchange.PUBLIC_KEY_LENGTH;
+    }
+
+    /**
+     * Creates and writes an account key to the provided mac address.
+     */
+    @Nullable
+    private byte[] doWriteAccountKey(byte[] accountKey, String macAddress)
+            throws InterruptedException, ExecutionException, TimeoutException, BluetoothException {
+        byte[] localPairingSecret = mPairingSecret;
+        if (localPairingSecret == null) {
+            Log.w(TAG, "Pairing secret was null, account key couldn't be encrypted or written.");
+            return null;
+        }
+        if (!mPreferences.getSkipDisconnectingGattBeforeWritingAccountKey()) {
+            try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger,
+                    "Close GATT and sleep")) {
+                // Make a new connection instead of reusing gattConnection, because this is
+                // post-pairing and we need an encrypted connection.
+                mGattConnectionManager.closeConnection();
+                // Sleep before re-connecting to gatt, for writing account key, could increase
+                // stability.
+                Thread.sleep(mPreferences.getWriteAccountKeySleepMillis());
+            }
+        }
+
+        byte[] encryptedKey;
+        try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger, "Encrypt key")) {
+            encryptedKey = AesEcbSingleBlockEncryption.encrypt(localPairingSecret, accountKey);
+        } catch (GeneralSecurityException e) {
+            Log.w("Failed to encrypt key.", e);
+            return null;
+        }
+
+        for (int i = 1; i <= mPreferences.getNumWriteAccountKeyAttempts(); i++) {
+            mEventLogger.setCurrentEvent(EventCode.WRITE_ACCOUNT_KEY);
+            try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger,
+                    "Write key via GATT #" + i)) {
+                writeAccountKey(encryptedKey, macAddress);
+                mEventLogger.logCurrentEventSucceeded();
+                return accountKey;
+            } catch (BluetoothException e) {
+                Log.w("Error writing account key attempt " + i + " of " + mPreferences
+                        .getNumWriteAccountKeyAttempts(), e);
+                mEventLogger.logCurrentEventFailed(e);
+                // Retry with a while for stability.
+                Thread.sleep(mPreferences.getWriteAccountKeySleepMillis());
+            }
+        }
+        return null;
+    }
+
+    private byte[] createAccountKey() throws NoSuchAlgorithmException {
+        return AccountKeyGenerator.createAccountKey();
+    }
+
+    @VisibleForTesting
+    boolean shouldWriteAccountKeyForExistingCase(byte[] existingAccountKey) {
+        if (!mPreferences.getKeepSameAccountKeyWrite()) {
+            Log.i(TAG,
+                    "The provider has already paired with the account, skip writing account key.");
+            return false;
+        }
+        if (existingAccountKey[0] != AccountKeyCharacteristic.TYPE) {
+            Log.i(TAG,
+                    "The provider has already paired with the account, but accountKey[0] != 0x04."
+                            + " Forget the device from the account and re-try");
+
+            return false;
+        }
+        Log.i(TAG, "The provider has already paired with the account, still write the same account "
+                + "key.");
+        return true;
+    }
+
+    /**
+     * Performs a key-based pairing request handshake to authenticate and get the remote device's
+     * public address.
+     *
+     * @param key is described in {@link #pair(byte[])}
+     */
+    @VisibleForTesting
+    SharedSecret handshakeForKeyBasedPairing(byte[] key)
+            throws InterruptedException, ExecutionException, TimeoutException, BluetoothException,
+            GeneralSecurityException, PairingException {
+        // We may also initialize gattConnectionManager of prepareForHandshake() that will be used
+        // in registerNotificationForNamePacket(), so we need to call it here.
+        HandshakeHandler handshakeHandler = prepareForHandshake();
+        KeyBasedPairingRequest.Builder keyBasedPairingRequestBuilder =
+                new KeyBasedPairingRequest.Builder()
+                        .setVerificationData(BluetoothAddress.decode(mBleAddress));
+        if (mProviderInitiatesBonding) {
+            keyBasedPairingRequestBuilder
+                    .addFlag(KeyBasedPairingRequestFlag.PROVIDER_INITIATES_BONDING);
+        }
+        // Seeker only request provider device name in initial pairing.
+        if (mPreferences.getEnableNamingCharacteristic() && isPairingWithAntiSpoofingPublicKey(
+                key)) {
+            keyBasedPairingRequestBuilder.addFlag(KeyBasedPairingRequestFlag.REQUEST_DEVICE_NAME);
+            // Register listener to receive name characteristic response from provider.
+            registerNotificationForNamePacket();
+        }
+        if (mPreferences.getIsRetroactivePairing()) {
+            keyBasedPairingRequestBuilder
+                    .addFlag(KeyBasedPairingRequestFlag.REQUEST_RETROACTIVE_PAIR);
+            keyBasedPairingRequestBuilder.setSeekerPublicAddress(
+                    Preconditions.checkNotNull(BluetoothAddress.getPublicAddress(mContext)));
+        }
+
+        return performHandshakeWithRetryAndSignalLostCheck(
+                handshakeHandler, key, keyBasedPairingRequestBuilder.build(), /* withRetry= */
+                true);
+    }
+
+    /**
+     * Performs an action-over-BLE request handshake for authentication, i.e. to identify the shared
+     * secret. The given key should be the account key.
+     */
+    private SharedSecret handshakeForActionOverBle(byte[] key,
+            @AdditionalDataType int additionalDataType)
+            throws InterruptedException, ExecutionException, TimeoutException, BluetoothException,
+            GeneralSecurityException, PairingException {
+        HandshakeHandler handshakeHandler = prepareForHandshake();
+        return performHandshakeWithRetryAndSignalLostCheck(
+                handshakeHandler,
+                key,
+                new ActionOverBle.Builder()
+                        .setVerificationData(BluetoothAddress.decode(mBleAddress))
+                        .setAdditionalDataType(additionalDataType)
+                        .build(),
+                /* withRetry= */ false);
+    }
+
+    private HandshakeHandler prepareForHandshake() {
+        if (mGattConnectionManager == null) {
+            mGattConnectionManager =
+                    new GattConnectionManager(
+                            mContext,
+                            mPreferences,
+                            mEventLogger,
+                            mBluetoothAdapter,
+                            this::toggleBluetooth,
+                            mBleAddress,
+                            mTimingLogger,
+                            mFastPairSignalChecker,
+                            isPairingWithAntiSpoofingPublicKey());
+        }
+        if (mHandshakeHandlerForTest != null) {
+            Log.w(TAG, "Use handshakeHandlerForTest!");
+            return verifyNotNull(mHandshakeHandlerForTest);
+        }
+        return new HandshakeHandler(
+                mGattConnectionManager, mBleAddress, mPreferences, mEventLogger,
+                mFastPairSignalChecker);
+    }
+
+    @VisibleForTesting
+    void setHandshakeHandlerForTest(@Nullable HandshakeHandler handshakeHandlerForTest) {
+        this.mHandshakeHandlerForTest = handshakeHandlerForTest;
+    }
+
+    private SharedSecret performHandshakeWithRetryAndSignalLostCheck(
+            HandshakeHandler handshakeHandler,
+            byte[] key,
+            HandshakeMessage handshakeMessage,
+            boolean withRetry)
+            throws GeneralSecurityException, ExecutionException, BluetoothException,
+            InterruptedException, TimeoutException, PairingException {
+        SharedSecret handshakeResult =
+                withRetry
+                        ? handshakeHandler.doHandshakeWithRetryAndSignalLostCheck(
+                        key, handshakeMessage, mRescueFromError)
+                        : handshakeHandler.doHandshake(key, handshakeMessage);
+        // TODO: Try to remove these two global variables, publicAddress and pairingSecret.
+        mPublicAddress = handshakeResult.getAddress();
+        mPairingSecret = handshakeResult.getKey();
+        return handshakeResult;
+    }
+
+    private void toggleBluetooth()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        if (!mPreferences.getToggleBluetoothOnFailure()) {
+            return;
+        }
+
+        Log.i(TAG, "Turning Bluetooth off.");
+        mEventLogger.setCurrentEvent(EventCode.DISABLE_BLUETOOTH);
+        mBluetoothAdapter.unwrap().disable();
+        disableBle(mBluetoothAdapter.unwrap());
+        try {
+            waitForBluetoothState(android.bluetooth.BluetoothAdapter.STATE_OFF);
+            mEventLogger.logCurrentEventSucceeded();
+        } catch (TimeoutException e) {
+            mEventLogger.logCurrentEventFailed(e);
+            // Soldier on despite failing to turn off Bluetooth. We can't control whether other
+            // clients (even inside GCore) kept it enabled in BLE-only mode.
+            Log.w(TAG, "Bluetooth still on. BluetoothAdapter state="
+                    + getBleState(mBluetoothAdapter.unwrap()), e);
+        }
+
+        // Note: Intentionally don't re-enable BLE-only mode, because we don't know which app
+        // enabled it. The client app should listen to Bluetooth events and enable as necessary
+        // (because the user can toggle at any time; e.g. via Airplane mode).
+        Log.i(TAG, "Turning Bluetooth on.");
+        mEventLogger.setCurrentEvent(EventCode.ENABLE_BLUETOOTH);
+        mBluetoothAdapter.unwrap().enable();
+        waitForBluetoothState(android.bluetooth.BluetoothAdapter.STATE_ON);
+        mEventLogger.logCurrentEventSucceeded();
+    }
+
+    private void waitForBluetoothState(int state)
+            throws TimeoutException, ExecutionException, InterruptedException {
+        waitForBluetoothStateUsingPolling(state);
+    }
+
+    private void waitForBluetoothStateUsingPolling(int state) throws TimeoutException {
+        // There's a bug where we (pretty often!) never get the broadcast for STATE_ON or STATE_OFF.
+        // So poll instead.
+        long start = SystemClock.elapsedRealtime();
+        long timeoutMillis = mPreferences.getBluetoothToggleTimeoutSeconds() * 1000L;
+        while (SystemClock.elapsedRealtime() - start < timeoutMillis) {
+            if (state == getBleState(mBluetoothAdapter.unwrap())) {
+                break;
+            }
+            SystemClock.sleep(mPreferences.getBluetoothStatePollingMillis());
+        }
+
+        if (state != getBleState(mBluetoothAdapter.unwrap())) {
+            throw new TimeoutException(
+                    String.format(
+                            Locale.getDefault(),
+                            "Timed out waiting for state %d, current state is %d",
+                            state,
+                            getBleState(mBluetoothAdapter.unwrap())));
+        }
+    }
+
+    private BrEdrHandoverInformation getBrEdrHandoverInformation(BluetoothGattConnection connection)
+            throws BluetoothException, TdsException, InterruptedException, ExecutionException,
+            TimeoutException {
+        Log.i(TAG, "Connecting GATT server to BLE address=" + maskBluetoothAddress(mBleAddress));
+        Log.i(TAG, "Telling device to become discoverable");
+        mEventLogger.setCurrentEvent(EventCode.BR_EDR_HANDOVER_WRITE_CONTROL_POINT_REQUEST);
+        ChangeObserver changeObserver =
+                connection.enableNotification(
+                        TransportDiscoveryService.ID,
+                        TransportDiscoveryService.ControlPointCharacteristic.ID);
+        connection.writeCharacteristic(
+                TransportDiscoveryService.ID,
+                TransportDiscoveryService.ControlPointCharacteristic.ID,
+                TDS_CONTROL_POINT_REQUEST);
+
+        byte[] response =
+                changeObserver.waitForUpdate(
+                        TimeUnit.SECONDS.toMillis(mPreferences.getGattOperationTimeoutSeconds()));
+        @ResultCode int resultCode = fromTdsControlPointIndication(response);
+        if (resultCode != ResultCode.SUCCESS) {
+            throw new TdsException(
+                    BrEdrHandoverErrorCode.CONTROL_POINT_RESULT_CODE_NOT_SUCCESS,
+                    "TDS Control Point result code (%s) was not success in response %s",
+                    resultCode,
+                    base16().lowerCase().encode(response));
+        }
+        mEventLogger.logCurrentEventSucceeded();
+        return new BrEdrHandoverInformation(
+                getAddressFromBrEdrConnection(connection),
+                getProfilesFromBrEdrConnection(connection));
+    }
+
+    private byte[] getAddressFromBrEdrConnection(BluetoothGattConnection connection)
+            throws BluetoothException, TdsException {
+        Log.i(TAG, "Getting Bluetooth MAC");
+        mEventLogger.setCurrentEvent(EventCode.BR_EDR_HANDOVER_READ_BLUETOOTH_MAC);
+        byte[] brHandoverData =
+                connection.readCharacteristic(
+                        TransportDiscoveryService.ID,
+                        to128BitUuid(mPreferences.getBrHandoverDataCharacteristicId()));
+        if (brHandoverData == null || brHandoverData.length < 7) {
+            throw new TdsException(
+                    BrEdrHandoverErrorCode.BLUETOOTH_MAC_INVALID,
+                    "Bluetooth MAC not contained in BR handover data: %s",
+                    brHandoverData != null ? base16().lowerCase().encode(brHandoverData)
+                            : "(none)");
+        }
+        byte[] bluetoothAddress =
+                new Bytes.Value(Arrays.copyOfRange(brHandoverData, 1, 7), ByteOrder.LITTLE_ENDIAN)
+                        .getBytes(ByteOrder.BIG_ENDIAN);
+        mEventLogger.logCurrentEventSucceeded();
+        return bluetoothAddress;
+    }
+
+    private short[] getProfilesFromBrEdrConnection(BluetoothGattConnection connection) {
+        mEventLogger.setCurrentEvent(EventCode.BR_EDR_HANDOVER_READ_TRANSPORT_BLOCK);
+        try {
+            byte[] transportBlock =
+                    connection.readDescriptor(
+                            TransportDiscoveryService.ID,
+                            to128BitUuid(mPreferences.getBluetoothSigDataCharacteristicId()),
+                            to128BitUuid(mPreferences.getBrTransportBlockDataDescriptorId()));
+            Log.i(TAG, "Got transport block: " + base16().lowerCase().encode(transportBlock));
+            short[] profiles = getSupportedProfiles(transportBlock);
+            mEventLogger.logCurrentEventSucceeded();
+            return profiles;
+        } catch (BluetoothException | TdsException | ParseException e) {
+            Log.w(TAG, "Failed to get supported profiles from transport block.", e);
+            mEventLogger.logCurrentEventFailed(e);
+        }
+        return new short[0];
+    }
+
+    @VisibleForTesting
+    boolean writeNameToProvider(@Nullable String deviceName, @Nullable String address)
+            throws InterruptedException, TimeoutException, ExecutionException {
+        if (deviceName == null || address == null) {
+            Log.i(TAG, "writeNameToProvider fail because provider name or address is null.");
+            return false;
+        }
+        if (mPairingSecret == null) {
+            Log.i(TAG, "writeNameToProvider fail because no pairingSecret.");
+            return false;
+        }
+        byte[] encryptedDeviceNamePacket;
+        try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger, "Encode device name")) {
+            encryptedDeviceNamePacket =
+                    NamingEncoder.encodeNamingPacket(mPairingSecret, deviceName);
+        } catch (GeneralSecurityException e) {
+            Log.w(TAG, "Failed to encrypt device name.", e);
+            return false;
+        }
+
+        for (int i = 1; i <= mPreferences.getNumWriteAccountKeyAttempts(); i++) {
+            mEventLogger.setCurrentEvent(EventCode.WRITE_DEVICE_NAME);
+            try {
+                writeDeviceName(encryptedDeviceNamePacket, address);
+                mEventLogger.logCurrentEventSucceeded();
+                return true;
+            } catch (BluetoothException e) {
+                Log.w(TAG, "Error writing name attempt " + i + " of "
+                        + mPreferences.getNumWriteAccountKeyAttempts());
+                mEventLogger.logCurrentEventFailed(e);
+                // Reuses the existing preference because the same usage.
+                Thread.sleep(mPreferences.getWriteAccountKeySleepMillis());
+            }
+        }
+        return false;
+    }
+
+    private void writeAccountKey(byte[] encryptedAccountKey, String address)
+            throws BluetoothException, InterruptedException, ExecutionException, TimeoutException {
+        Log.i(TAG, "Writing account key to address=" + maskBluetoothAddress(address));
+        BluetoothGattConnection connection = mGattConnectionManager.getConnection();
+        connection.setOperationTimeout(
+                TimeUnit.SECONDS.toMillis(mPreferences.getGattOperationTimeoutSeconds()));
+        UUID characteristicUuid = AccountKeyCharacteristic.getId(connection);
+        connection.writeCharacteristic(FastPairService.ID, characteristicUuid, encryptedAccountKey);
+        Log.i(TAG,
+                "Finished writing encrypted account key=" + base16().encode(encryptedAccountKey));
+    }
+
+    private void writeDeviceName(byte[] naming, String address)
+            throws BluetoothException, InterruptedException, ExecutionException, TimeoutException {
+        Log.i(TAG, "Writing new device name to address=" + maskBluetoothAddress(address));
+        BluetoothGattConnection connection = mGattConnectionManager.getConnection();
+        connection.setOperationTimeout(
+                TimeUnit.SECONDS.toMillis(mPreferences.getGattOperationTimeoutSeconds()));
+        UUID characteristicUuid = NameCharacteristic.getId(connection);
+        connection.writeCharacteristic(FastPairService.ID, characteristicUuid, naming);
+        Log.i(TAG, "Finished writing new device name=" + base16().encode(naming));
+    }
+
+    /**
+     * Reads firmware version after write account key to provider since simulator is more stable to
+     * read firmware version in initial gatt connection. This function will also read firmware when
+     * detect bloomfilter. Need to verify this after real device come out. TODO(b/130592473)
+     */
+    @Nullable
+    public String readFirmwareVersion()
+            throws BluetoothException, InterruptedException, ExecutionException, TimeoutException {
+        if (!TextUtils.isEmpty(sInitialConnectionFirmwareVersion)) {
+            String result = sInitialConnectionFirmwareVersion;
+            sInitialConnectionFirmwareVersion = null;
+            return result;
+        }
+        if (mGattConnectionManager == null) {
+            mGattConnectionManager =
+                    new GattConnectionManager(
+                            mContext,
+                            mPreferences,
+                            mEventLogger,
+                            mBluetoothAdapter,
+                            this::toggleBluetooth,
+                            mBleAddress,
+                            mTimingLogger,
+                            mFastPairSignalChecker,
+                            /* setMtu= */ true);
+            mGattConnectionManager.closeConnection();
+        }
+        if (sTestMode) {
+            return null;
+        }
+        BluetoothGattConnection connection = mGattConnectionManager.getConnection();
+        connection.setOperationTimeout(
+                TimeUnit.SECONDS.toMillis(mPreferences.getGattOperationTimeoutSeconds()));
+
+        try {
+            String firmwareVersion =
+                    new String(
+                            connection.readCharacteristic(
+                                    FastPairService.ID,
+                                    to128BitUuid(
+                                            mPreferences.getFirmwareVersionCharacteristicId())));
+            Log.i(TAG, "FastPair: Got the firmware info version number = " + firmwareVersion);
+            mGattConnectionManager.closeConnection();
+            return firmwareVersion;
+        } catch (BluetoothException e) {
+            Log.i(TAG, "FastPair: can't read firmware characteristic.", e);
+            mGattConnectionManager.closeConnection();
+            return null;
+        }
+    }
+
+    @VisibleForTesting
+    @Nullable
+    String getInitialConnectionFirmware() {
+        return sInitialConnectionFirmwareVersion;
+    }
+
+    private void registerNotificationForNamePacket()
+            throws BluetoothException, InterruptedException, ExecutionException, TimeoutException {
+        Log.i(TAG,
+                "register for the device name response from address=" + maskBluetoothAddress(
+                        mBleAddress));
+
+        BluetoothGattConnection gattConnection = mGattConnectionManager.getConnection();
+        gattConnection.setOperationTimeout(
+                TimeUnit.SECONDS.toMillis(mPreferences.getGattOperationTimeoutSeconds()));
+        try {
+            mDeviceNameReceiver = new DeviceNameReceiver(gattConnection);
+        } catch (BluetoothException e) {
+            Log.i(TAG, "Can't register for device name response, no naming characteristic.");
+            return;
+        }
+    }
+
+    private short[] getSupportedProfiles(BluetoothDevice device) {
+        short[] supportedProfiles = getCachedUuids(device);
+        if (supportedProfiles.length == 0 && mPreferences.getNumSdpAttemptsAfterBonded() > 0) {
+            supportedProfiles =
+                    attemptGetBluetoothClassicProfiles(device,
+                            mPreferences.getNumSdpAttemptsAfterBonded());
+        }
+        if (supportedProfiles.length == 0) {
+            supportedProfiles = Constants.getSupportedProfiles();
+            Log.w(TAG, "Attempting to connect constants profiles, "
+                    + Arrays.toString(supportedProfiles));
+        } else {
+            Log.i(TAG,
+                    "Attempting to connect device profiles, " + Arrays.toString(supportedProfiles));
+        }
+        return supportedProfiles;
+    }
+
+    private static short[] getSupportedProfiles(byte[] transportBlock)
+            throws TdsException, ParseException {
+        if (transportBlock == null || transportBlock.length < 4) {
+            throw new TdsException(
+                    BrEdrHandoverErrorCode.TRANSPORT_BLOCK_INVALID,
+                    "Transport Block null or too short: %s",
+                    base16().lowerCase().encode(transportBlock));
+        }
+        int transportDataLength = transportBlock[2];
+        if (transportBlock.length < 3 + transportDataLength) {
+            throw new TdsException(
+                    BrEdrHandoverErrorCode.TRANSPORT_BLOCK_INVALID,
+                    "Transport Block has wrong length byte: %s",
+                    base16().lowerCase().encode(transportBlock));
+        }
+        byte[] transportData = Arrays.copyOfRange(transportBlock, 3, 3 + transportDataLength);
+        for (Ltv ltv : Ltv.parse(transportData)) {
+            int uuidLength = uuidLength(ltv.mType);
+            // We currently only support a single list of 2-byte UUIDs.
+            // TODO(b/37539535): Support multiple lists, and longer (32-bit, 128-bit) IDs?
+            if (uuidLength == 2) {
+                return toShorts(ByteOrder.LITTLE_ENDIAN, ltv.mValue);
+            }
+        }
+        return new short[0];
+    }
+
+    /**
+     * Returns 0 if the type is not one of the UUID list types; otherwise returns length in bytes.
+     */
+    private static int uuidLength(byte dataType) {
+        switch (dataType) {
+            case TransportDiscoveryService.SERVICE_UUIDS_16_BIT_LIST_TYPE:
+                return 2;
+            case TransportDiscoveryService.SERVICE_UUIDS_32_BIT_LIST_TYPE:
+                return 4;
+            case TransportDiscoveryService.SERVICE_UUIDS_128_BIT_LIST_TYPE:
+                return 16;
+            default:
+                return 0;
+        }
+    }
+
+    private short[] attemptGetBluetoothClassicProfiles(BluetoothDevice device, int numSdpAttempts) {
+        // The docs say that if fetchUuidsWithSdp() has an error or "takes a long time", we get an
+        // intent containing only the stuff in the cache (i.e. nothing). Retry a few times.
+        short[] supportedProfiles = null;
+        for (int i = 1; i <= numSdpAttempts; i++) {
+            mEventLogger.setCurrentEvent(EventCode.GET_PROFILES_VIA_SDP);
+            try (ScopedTiming scopedTiming =
+                    new ScopedTiming(mTimingLogger,
+                            "Get BR/EDR handover information via SDP #" + i)) {
+                supportedProfiles = getSupportedProfilesViaBluetoothClassic(device);
+            } catch (ExecutionException | InterruptedException | TimeoutException e) {
+                // Ignores and retries if needed.
+            }
+            if (supportedProfiles != null && supportedProfiles.length != 0) {
+                mEventLogger.logCurrentEventSucceeded();
+                break;
+            } else {
+                mEventLogger.logCurrentEventFailed(new TimeoutException());
+                Log.w(TAG, "SDP returned no UUIDs from " + maskBluetoothAddress(device.getAddress())
+                        + ", assuming timeout (attempt " + i + " of " + numSdpAttempts + ").");
+            }
+        }
+        return (supportedProfiles == null) ? new short[0] : supportedProfiles;
+    }
+
+    private short[] getSupportedProfilesViaBluetoothClassic(BluetoothDevice device)
+            throws ExecutionException, InterruptedException, TimeoutException {
+        Log.i(TAG, "Getting supported profiles via SDP (Bluetooth Classic) for "
+                + maskBluetoothAddress(device.getAddress()));
+        try (DeviceIntentReceiver supportedProfilesReceiver =
+                DeviceIntentReceiver.oneShotReceiver(
+                        mContext, mPreferences, device, BluetoothDevice.ACTION_UUID)) {
+            device.fetchUuidsWithSdp();
+            supportedProfilesReceiver.await(mPreferences.getSdpTimeoutSeconds(), TimeUnit.SECONDS);
+        }
+        return getCachedUuids(device);
+    }
+
+    private static short[] getCachedUuids(BluetoothDevice device) {
+        ParcelUuid[] parcelUuids = device.getUuids();
+        Log.i(TAG, "Got supported UUIDs: " + Arrays.toString(parcelUuids));
+        if (parcelUuids == null) {
+            // The OS can return null.
+            parcelUuids = new ParcelUuid[0];
+        }
+
+        List<Short> shortUuids = new ArrayList<>(parcelUuids.length);
+        for (ParcelUuid parcelUuid : parcelUuids) {
+            UUID uuid = parcelUuid.getUuid();
+            if (BluetoothUuids.is16BitUuid(uuid)) {
+                shortUuids.add(get16BitUuid(uuid));
+            }
+        }
+        return Shorts.toArray(shortUuids);
+    }
+
+    private void callbackOnPaired() {
+        if (mPairedCallback != null) {
+            mPairedCallback.onPaired(mPublicAddress != null ? mPublicAddress : mBleAddress);
+        }
+    }
+
+    private void callbackOnGetAddress(String address) {
+        if (mOnGetBluetoothAddressCallback != null) {
+            mOnGetBluetoothAddressCallback.onGetBluetoothAddress(address);
+        }
+    }
+
+    private boolean validateBluetoothGattCharacteristic(
+            BluetoothGattConnection connection, UUID characteristicUUID) {
+        try (ScopedTiming scopedTiming =
+                new ScopedTiming(mTimingLogger, "Get service characteristic list")) {
+            List<BluetoothGattCharacteristic> serviceCharacteristicList =
+                    connection.getService(FastPairService.ID).getCharacteristics();
+            for (BluetoothGattCharacteristic characteristic : serviceCharacteristicList) {
+                if (characteristicUUID.equals(characteristic.getUuid())) {
+                    Log.i(TAG, "characteristic is exists, uuid = " + characteristicUUID);
+                    return true;
+                }
+            }
+        } catch (BluetoothException e) {
+            Log.w(TAG, "Can't get service characteristic list.", e);
+        }
+        Log.i(TAG, "can't find characteristic, uuid = " + characteristicUUID);
+        return false;
+    }
+
+    // This method is only for testing to make test method block until get name response or time
+    // out.
+    /**
+     * Set name response countdown latch.
+     */
+    public void setNameResponseCountDownLatch(CountDownLatch countDownLatch) {
+        if (mDeviceNameReceiver != null) {
+            mDeviceNameReceiver.setCountDown(countDownLatch);
+            Log.v(TAG, "set up nameResponseCountDown");
+        }
+    }
+
+    private static int getBleState(android.bluetooth.BluetoothAdapter bluetoothAdapter) {
+        // Can't use the public isLeEnabled() API, because it returns false for
+        // STATE_BLE_TURNING_(ON|OFF). So if we assume false == STATE_OFF, that can be
+        // very wrong.
+        return getLeState(bluetoothAdapter);
+    }
+
+    private static int getLeState(android.bluetooth.BluetoothAdapter adapter) {
+        try {
+            return (Integer) Reflect.on(adapter).withMethod("getLeState").get();
+        } catch (ReflectionException e) {
+            Log.i(TAG, "Can't call getLeState", e);
+        }
+        return adapter.getState();
+    }
+
+    private static void disableBle(android.bluetooth.BluetoothAdapter adapter) {
+        adapter.disableBLE();
+    }
+
+    /**
+     * Handle the searching of Fast Pair history. Since there is only one public address using
+     * during Fast Pair connection, {@link #isInPairedHistory(String)} only needs to be called once,
+     * then the result is kept, and call {@link #getExistingAccountKey()} to get the result.
+     */
+    @VisibleForTesting
+    static final class FastPairHistoryFinder {
+
+        private @Nullable
+        byte[] mExistingAccountKey;
+        @Nullable
+        private final List<FastPairHistoryItem> mHistoryItems;
+
+        FastPairHistoryFinder(List<FastPairHistoryItem> historyItems) {
+            this.mHistoryItems = historyItems;
+        }
+
+        @WorkerThread
+        @VisibleForTesting
+        boolean isInPairedHistory(String publicAddress) {
+            if (mHistoryItems == null || mHistoryItems.isEmpty()) {
+                return false;
+            }
+            for (FastPairHistoryItem item : mHistoryItems) {
+                if (item.isMatched(BluetoothAddress.decode(publicAddress))) {
+                    mExistingAccountKey = item.accountKey().toByteArray();
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        // This function should be called after isInPairedHistory(). Or it will just return null.
+        @WorkerThread
+        @VisibleForTesting
+        @Nullable
+        byte[] getExistingAccountKey() {
+            return mExistingAccountKey;
+        }
+    }
+
+    private static final class DeviceNameReceiver {
+
+        @GuardedBy("this")
+        private @Nullable
+        byte[] mEncryptedResponse;
+
+        @GuardedBy("this")
+        @Nullable
+        private String mDecryptedDeviceName;
+
+        @Nullable
+        private CountDownLatch mResponseCountDown;
+
+        DeviceNameReceiver(BluetoothGattConnection gattConnection) throws BluetoothException {
+            UUID characteristicUuid = NameCharacteristic.getId(gattConnection);
+            ChangeObserver observer =
+                    gattConnection.enableNotification(FastPairService.ID, characteristicUuid);
+            observer.setListener(
+                    (byte[] value) -> {
+                        synchronized (DeviceNameReceiver.this) {
+                            Log.i(TAG, "DeviceNameReceiver: device name response size = "
+                                    + value.length);
+                            // We don't decrypt it here because we may not finish handshaking and
+                            // the pairing
+                            // secret is not available.
+                            mEncryptedResponse = value;
+                        }
+                        // For testing to know we get the device name from provider.
+                        if (mResponseCountDown != null) {
+                            mResponseCountDown.countDown();
+                            Log.v(TAG, "Finish nameResponseCountDown.");
+                        }
+                    });
+        }
+
+        void setCountDown(CountDownLatch countDownLatch) {
+            this.mResponseCountDown = countDownLatch;
+        }
+
+        synchronized @Nullable String getParsedResult(byte[] secret) {
+            if (mDecryptedDeviceName != null) {
+                return mDecryptedDeviceName;
+            }
+            if (mEncryptedResponse == null) {
+                Log.i(TAG, "DeviceNameReceiver: no device name sent from the Provider.");
+                return null;
+            }
+            try {
+                mDecryptedDeviceName = NamingEncoder.decodeNamingPacket(secret, mEncryptedResponse);
+                Log.i(TAG, "DeviceNameReceiver: decrypted provider's name from naming response, "
+                        + "name = " + mDecryptedDeviceName);
+            } catch (GeneralSecurityException e) {
+                Log.w(TAG, "DeviceNameReceiver: fail to parse the NameCharacteristic from provider"
+                        + ".", e);
+                return null;
+            }
+            return mDecryptedDeviceName;
+        }
+    }
+
+    static void checkFastPairSignal(
+            FastPairSignalChecker fastPairSignalChecker,
+            String currentAddress,
+            Exception originalException)
+            throws SignalLostException, SignalRotatedException {
+        String newAddress = fastPairSignalChecker.getValidAddressForModelId(currentAddress);
+        if (TextUtils.isEmpty(newAddress)) {
+            throw new SignalLostException("Signal lost", originalException);
+        } else if (!Ascii.equalsIgnoreCase(currentAddress, newAddress)) {
+            throw new SignalRotatedException("Address rotated", newAddress, originalException);
+        }
+    }
+
+    @VisibleForTesting
+    public Preferences getPreferences() {
+        return mPreferences;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairHistoryItem.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairHistoryItem.java
new file mode 100644
index 0000000..e774886
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairHistoryItem.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.primitives.Bytes.concat;
+
+import com.google.common.hash.Hashing;
+import com.google.protobuf.ByteString;
+
+import java.util.Arrays;
+
+/**
+ * It contains the sha256 of "account key + headset's public address" to identify the headset which
+ * has paired with the account. Previously, account key is the only information for Fast Pair to
+ * identify the headset, but Fast Pair can't identify the headset in initial pairing, there is no
+ * account key data advertising from headset.
+ */
+public class FastPairHistoryItem {
+
+    private final ByteString mAccountKey;
+    private final ByteString mSha256AccountKeyPublicAddress;
+
+    FastPairHistoryItem(ByteString accountkey, ByteString sha256AccountKeyPublicAddress) {
+        mAccountKey = accountkey;
+        mSha256AccountKeyPublicAddress = sha256AccountKeyPublicAddress;
+    }
+
+    /**
+     * Creates an instance of {@link FastPairHistoryItem}.
+     *
+     * @param accountKey key of an account that has paired with the headset.
+     * @param sha256AccountKeyPublicAddress hash value of account key and headset's public address.
+     */
+    public static FastPairHistoryItem create(
+            ByteString accountKey, ByteString sha256AccountKeyPublicAddress) {
+        return new FastPairHistoryItem(accountKey, sha256AccountKeyPublicAddress);
+    }
+
+    ByteString accountKey() {
+        return mAccountKey;
+    }
+
+    ByteString sha256AccountKeyPublicAddress() {
+        return mSha256AccountKeyPublicAddress;
+    }
+
+    // Return true if the input public address is considered the same as this history item. Because
+    // of privacy concern, Fast Pair does not really store the public address, it is identified by
+    // the SHA256 of the account key and the public key.
+    final boolean isMatched(byte[] publicAddress) {
+        return Arrays.equals(
+                sha256AccountKeyPublicAddress().toByteArray(),
+                Hashing.sha256().hashBytes(concat(accountKey().toByteArray(), publicAddress))
+                        .asBytes());
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/GattConnectionManager.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/GattConnectionManager.java
new file mode 100644
index 0000000..e7ce4bf
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/GattConnectionManager.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption.AES_BLOCK_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress.maskBluetoothAddress;
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.logRetrySuccessEvent;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import android.content.Context;
+import android.os.SystemClock;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.core.util.Consumer;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.BluetoothTimeoutException;
+import com.android.server.nearby.common.bluetooth.fastpair.TimingLogger.ScopedTiming;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.ConnectionOptions;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothAdapter;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.BluetoothOperationTimeoutException;
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.ErrorCode;
+import com.android.server.nearby.intdefs.NearbyEventIntDefs.EventCode;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Manager for working with Gatt connections.
+ *
+ * <p>This helper class allows for opening and closing GATT connections to a provided address.
+ * Optionally, it can also support automatically reopening a connection in the case that it has been
+ * closed when it's next needed through {@link Preferences#getAutomaticallyReconnectGattWhenNeeded}.
+ */
+// TODO(b/202524672): Add class unit test.
+final class GattConnectionManager {
+
+    private static final String TAG = GattConnectionManager.class.getSimpleName();
+
+    private final Context mContext;
+    private final Preferences mPreferences;
+    private final EventLoggerWrapper mEventLogger;
+    private final BluetoothAdapter mBluetoothAdapter;
+    private final ToggleBluetoothTask mToggleBluetooth;
+    private final String mAddress;
+    private final TimingLogger mTimingLogger;
+    private final boolean mSetMtu;
+    @Nullable
+    private final FastPairConnection.FastPairSignalChecker mFastPairSignalChecker;
+    @Nullable
+    private BluetoothGattConnection mGattConnection;
+    private static boolean sTestMode = false;
+
+    static void enableTestMode() {
+        sTestMode = true;
+    }
+
+    GattConnectionManager(
+            Context context,
+            Preferences preferences,
+            EventLoggerWrapper eventLogger,
+            BluetoothAdapter bluetoothAdapter,
+            ToggleBluetoothTask toggleBluetooth,
+            String address,
+            TimingLogger timingLogger,
+            @Nullable FastPairConnection.FastPairSignalChecker fastPairSignalChecker,
+            boolean setMtu) {
+        this.mContext = context;
+        this.mPreferences = preferences;
+        this.mEventLogger = eventLogger;
+        this.mBluetoothAdapter = bluetoothAdapter;
+        this.mToggleBluetooth = toggleBluetooth;
+        this.mAddress = address;
+        this.mTimingLogger = timingLogger;
+        this.mFastPairSignalChecker = fastPairSignalChecker;
+        this.mSetMtu = setMtu;
+    }
+
+    /**
+     * Gets a gatt connection to address. If this connection does not exist, it creates one.
+     */
+    BluetoothGattConnection getConnection()
+            throws InterruptedException, ExecutionException, TimeoutException, BluetoothException {
+        if (mGattConnection == null) {
+            try {
+                mGattConnection =
+                        connect(mAddress, /* checkSignalWhenFail= */ false,
+                                /* rescueFromError= */ null);
+            } catch (SignalLostException | SignalRotatedException e) {
+                // Impossible to happen here because we didn't do signal check.
+                throw new ExecutionException("getConnection throws SignalLostException", e);
+            }
+        }
+        return mGattConnection;
+    }
+
+    BluetoothGattConnection getConnectionWithSignalLostCheck(
+            @Nullable Consumer<Integer> rescueFromError)
+            throws InterruptedException, ExecutionException, TimeoutException, BluetoothException,
+            SignalLostException, SignalRotatedException {
+        if (mGattConnection == null) {
+            mGattConnection = connect(mAddress, /* checkSignalWhenFail= */ true,
+                    rescueFromError);
+        }
+        return mGattConnection;
+    }
+
+    /**
+     * Closes the gatt connection when it is open.
+     */
+    void closeConnection() throws BluetoothException {
+        if (mGattConnection != null) {
+            try (ScopedTiming scopedTiming = new ScopedTiming(mTimingLogger, "Close GATT")) {
+                mGattConnection.close();
+                mGattConnection = null;
+            }
+        }
+    }
+
+    private BluetoothGattConnection connect(
+            String address, boolean checkSignalWhenFail,
+            @Nullable Consumer<Integer> rescueFromError)
+            throws InterruptedException, ExecutionException, TimeoutException, BluetoothException,
+            SignalLostException, SignalRotatedException {
+        int i = 1;
+        boolean isRecoverable = true;
+        long startElapsedRealtime = SystemClock.elapsedRealtime();
+        BluetoothException lastException = null;
+        mEventLogger.setCurrentEvent(EventCode.GATT_CONNECT);
+        while (isRecoverable) {
+            try (ScopedTiming scopedTiming =
+                    new ScopedTiming(mTimingLogger, "Connect GATT #" + i)) {
+                Log.i(TAG, "Connecting to GATT server at " + maskBluetoothAddress(address));
+                if (sTestMode) {
+                    return null;
+                }
+                BluetoothGattConnection connection =
+                        new BluetoothGattHelper(mContext, mBluetoothAdapter)
+                                .connect(
+                                        mBluetoothAdapter.getRemoteDevice(address),
+                                        getConnectionOptions(startElapsedRealtime));
+                connection.setOperationTimeout(
+                        TimeUnit.SECONDS.toMillis(mPreferences.getGattOperationTimeoutSeconds()));
+                if (mPreferences.getAutomaticallyReconnectGattWhenNeeded()) {
+                    connection.addCloseListener(
+                            () -> {
+                                Log.i(TAG, "Gatt connection with " + maskBluetoothAddress(address)
+                                        + " closed.");
+                                mGattConnection = null;
+                            });
+                }
+                mEventLogger.logCurrentEventSucceeded();
+                if (lastException != null) {
+                    logRetrySuccessEvent(EventCode.RECOVER_BY_RETRY_GATT, lastException,
+                            mEventLogger);
+                }
+                return connection;
+            } catch (BluetoothException e) {
+                lastException = e;
+
+                boolean ableToRetry;
+                if (mPreferences.getGattConnectRetryTimeoutMillis() > 0) {
+                    ableToRetry =
+                            (SystemClock.elapsedRealtime() - startElapsedRealtime)
+                                    < mPreferences.getGattConnectRetryTimeoutMillis();
+                    Log.i(TAG, "Retry connecting GATT by timeout: " + ableToRetry);
+                } else {
+                    ableToRetry = i < mPreferences.getNumAttempts();
+                }
+
+                if (mPreferences.getRetryGattConnectionAndSecretHandshake()) {
+                    if (isNoRetryError(mPreferences, e)) {
+                        ableToRetry = false;
+                    }
+
+                    if (ableToRetry) {
+                        if (rescueFromError != null) {
+                            rescueFromError.accept(
+                                    e instanceof BluetoothOperationTimeoutException
+                                            ? ErrorCode.SUCCESS_RETRY_GATT_TIMEOUT
+                                            : ErrorCode.SUCCESS_RETRY_GATT_ERROR);
+                        }
+                        if (mFastPairSignalChecker != null && checkSignalWhenFail) {
+                            FastPairDualConnection
+                                    .checkFastPairSignal(mFastPairSignalChecker, address, e);
+                        }
+                    }
+                    isRecoverable = ableToRetry;
+                    if (ableToRetry && mPreferences.getPairingRetryDelayMs() > 0) {
+                        SystemClock.sleep(mPreferences.getPairingRetryDelayMs());
+                    }
+                } else {
+                    isRecoverable =
+                            ableToRetry
+                                    && (e instanceof BluetoothOperationTimeoutException
+                                    || e instanceof BluetoothTimeoutException
+                                    || (e instanceof BluetoothGattException
+                                    && ((BluetoothGattException) e).getGattErrorCode() == 133));
+                }
+                Log.w(TAG, "GATT connect attempt " + i + "of " + mPreferences.getNumAttempts()
+                        + " failed, " + (isRecoverable ? "recovering" : "permanently"), e);
+                if (isRecoverable) {
+                    // If we're going to retry, log failure here. If we throw, an upper level will
+                    // log it.
+                    mToggleBluetooth.toggleBluetooth();
+                    i++;
+                    mEventLogger.logCurrentEventFailed(e);
+                    mEventLogger.setCurrentEvent(EventCode.GATT_CONNECT);
+                }
+            }
+        }
+        throw checkNotNull(lastException);
+    }
+
+    static boolean isNoRetryError(Preferences preferences, BluetoothException e) {
+        return e instanceof BluetoothGattException
+                && preferences
+                .getGattConnectionAndSecretHandshakeNoRetryGattError()
+                .contains(((BluetoothGattException) e).getGattErrorCode());
+    }
+
+    @VisibleForTesting
+    long getTimeoutMs(long spentTime) {
+        long timeoutInMs;
+        if (mPreferences.getRetryGattConnectionAndSecretHandshake()) {
+            timeoutInMs =
+                    spentTime < mPreferences.getGattConnectShortTimeoutRetryMaxSpentTimeMs()
+                            ? mPreferences.getGattConnectShortTimeoutMs()
+                            : mPreferences.getGattConnectLongTimeoutMs();
+        } else {
+            timeoutInMs = TimeUnit.SECONDS.toMillis(mPreferences.getGattConnectionTimeoutSeconds());
+        }
+        return timeoutInMs;
+    }
+
+    private ConnectionOptions getConnectionOptions(long startElapsedRealtime) {
+        return createConnectionOptions(
+                mSetMtu,
+                getTimeoutMs(SystemClock.elapsedRealtime() - startElapsedRealtime));
+    }
+
+    public static ConnectionOptions createConnectionOptions(boolean setMtu, long timeoutInMs) {
+        ConnectionOptions.Builder builder = ConnectionOptions.builder();
+        if (setMtu) {
+            // There are 3 overhead bytes added to BLE packets.
+            builder.setMtu(
+                    AES_BLOCK_LENGTH + EllipticCurveDiffieHellmanExchange.PUBLIC_KEY_LENGTH + 3);
+        }
+        builder.setConnectionTimeoutMillis(timeoutInMs);
+        return builder.build();
+    }
+
+    @VisibleForTesting
+    void setGattConnection(BluetoothGattConnection gattConnection) {
+        this.mGattConnection = gattConnection;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/HandshakeHandler.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/HandshakeHandler.java
new file mode 100644
index 0000000..984133b
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/HandshakeHandler.java
@@ -0,0 +1,560 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption.AES_BLOCK_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption.decrypt;
+import static com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption.encrypt;
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress.maskBluetoothAddress;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.BLUETOOTH_ADDRESS_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.ActionOverBleFlag.ADDITIONAL_DATA_CHARACTERISTIC;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.ActionOverBleFlag.DEVICE_ACTION;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.ADDITIONAL_DATA_TYPE_INDEX;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.EVENT_ADDITIONAL_DATA_INDEX;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.EVENT_ADDITIONAL_DATA_LENGTH_INDEX;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.EVENT_CODE_INDEX;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.EVENT_GROUP_INDEX;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.FLAGS_INDEX;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.SEEKER_PUBLIC_ADDRESS_INDEX;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.TYPE_ACTION_OVER_BLE;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.TYPE_INDEX;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.TYPE_KEY_BASED_PAIRING_REQUEST;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.VERIFICATION_DATA_INDEX;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.VERIFICATION_DATA_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.logRetrySuccessEvent;
+import static com.android.server.nearby.common.bluetooth.fastpair.GattConnectionManager.isNoRetryError;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.primitives.Bytes.concat;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import android.os.SystemClock;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.core.util.Consumer;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothTimeoutException;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.AdditionalDataCharacteristic.AdditionalDataType;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.ActionOverBleFlag;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.KeyBasedPairingRequestFlag;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request;
+import com.android.server.nearby.common.bluetooth.fastpair.FastPairConnection.SharedSecret;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection.ChangeObserver;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.BluetoothOperationTimeoutException;
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.ErrorCode;
+import com.android.server.nearby.intdefs.NearbyEventIntDefs.EventCode;
+
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Handles the handshake step of Fast Pair, the Provider's public address and the shared secret will
+ * be disclosed during this step. It is the first step of all key-based operations, e.g. key-based
+ * pairing and action over BLE.
+ *
+ * @see <a href="https://developers.google.com/nearby/fast-pair/spec#procedure">
+ *     Fastpair Spec Procedure</a>
+ */
+public class HandshakeHandler {
+
+    private static final String TAG = HandshakeHandler.class.getSimpleName();
+    private final GattConnectionManager mGattConnectionManager;
+    private final String mProviderBleAddress;
+    private final Preferences mPreferences;
+    private final EventLoggerWrapper mEventLogger;
+    @Nullable
+    private final FastPairConnection.FastPairSignalChecker mFastPairSignalChecker;
+
+    /**
+     * Keeps the keys used during handshaking, generated by {@link #createKey(byte[])}.
+     */
+    private static final class Keys {
+
+        private final byte[] mSharedSecret;
+        private final byte[] mPublicKey;
+
+        private Keys(byte[] sharedSecret, byte[] publicKey) {
+            this.mSharedSecret = sharedSecret;
+            this.mPublicKey = publicKey;
+        }
+    }
+
+    public HandshakeHandler(
+            GattConnectionManager gattConnectionManager,
+            String bleAddress,
+            Preferences preferences,
+            EventLoggerWrapper eventLogger,
+            @Nullable FastPairConnection.FastPairSignalChecker fastPairSignalChecker) {
+        this.mGattConnectionManager = gattConnectionManager;
+        this.mProviderBleAddress = bleAddress;
+        this.mPreferences = preferences;
+        this.mEventLogger = eventLogger;
+        this.mFastPairSignalChecker = fastPairSignalChecker;
+    }
+
+    /**
+     * Performs a handshake to authenticate and get the remote device's public address. Returns the
+     * AES-128 key as the shared secret for this pairing session.
+     */
+    public SharedSecret doHandshake(byte[] key, HandshakeMessage message)
+            throws GeneralSecurityException, InterruptedException, ExecutionException,
+            TimeoutException, BluetoothException, PairingException {
+        Keys keys = createKey(key);
+        Log.i(TAG,
+                "Handshake " + maskBluetoothAddress(mProviderBleAddress) + ", flags "
+                        + message.mFlags);
+        byte[] handshakeResponse =
+                processGattCommunication(
+                        createPacket(keys, message),
+                        SECONDS.toMillis(mPreferences.getGattOperationTimeoutSeconds()));
+        String providerPublicAddress = decodeResponse(keys.mSharedSecret, handshakeResponse);
+
+        return SharedSecret.create(keys.mSharedSecret, providerPublicAddress);
+    }
+
+    /**
+     * Performs a handshake to authenticate and get the remote device's public address. Returns the
+     * AES-128 key as the shared secret for this pairing session. Will retry and also performs
+     * FastPair signal check if fails.
+     */
+    public SharedSecret doHandshakeWithRetryAndSignalLostCheck(
+            byte[] key, HandshakeMessage message, @Nullable Consumer<Integer> rescueFromError)
+            throws GeneralSecurityException, InterruptedException, ExecutionException,
+            TimeoutException, BluetoothException, PairingException {
+        Keys keys = createKey(key);
+        Log.i(TAG,
+                "Handshake " + maskBluetoothAddress(mProviderBleAddress) + ", flags "
+                        + message.mFlags);
+        int retryCount = 0;
+        byte[] handshakeResponse = null;
+        long startTime = SystemClock.elapsedRealtime();
+        BluetoothException lastException = null;
+        do {
+            try {
+                mEventLogger.setCurrentEvent(EventCode.SECRET_HANDSHAKE_GATT_COMMUNICATION);
+                handshakeResponse =
+                        processGattCommunication(
+                                createPacket(keys, message),
+                                getTimeoutMs(SystemClock.elapsedRealtime() - startTime));
+                mEventLogger.logCurrentEventSucceeded();
+                if (lastException != null) {
+                    logRetrySuccessEvent(EventCode.RECOVER_BY_RETRY_HANDSHAKE, lastException,
+                            mEventLogger);
+                }
+            } catch (BluetoothException e) {
+                lastException = e;
+                long spentTime = SystemClock.elapsedRealtime() - startTime;
+                Log.w(TAG, "Secret handshake failed, address="
+                        + maskBluetoothAddress(mProviderBleAddress)
+                        + ", spent time=" + spentTime + "ms, retryCount=" + retryCount);
+                mEventLogger.logCurrentEventFailed(e);
+
+                if (!mPreferences.getRetryGattConnectionAndSecretHandshake()) {
+                    throw e;
+                }
+
+                if (spentTime > mPreferences.getSecretHandshakeLongTimeoutRetryMaxSpentTimeMs()) {
+                    Log.w(TAG, "Spent too long time for handshake, timeInMs=" + spentTime);
+                    throw e;
+                }
+                if (isNoRetryError(mPreferences, e)) {
+                    throw e;
+                }
+
+                if (mFastPairSignalChecker != null) {
+                    FastPairDualConnection
+                            .checkFastPairSignal(mFastPairSignalChecker, mProviderBleAddress, e);
+                }
+                retryCount++;
+                if (retryCount > mPreferences.getSecretHandshakeRetryAttempts()
+                        || ((e instanceof BluetoothOperationTimeoutException)
+                        && !mPreferences.getRetrySecretHandshakeTimeout())) {
+                    throw new HandshakeException("Fail on handshake!", e);
+                }
+                if (rescueFromError != null) {
+                    rescueFromError.accept(
+                            (e instanceof BluetoothTimeoutException
+                                    || e instanceof BluetoothOperationTimeoutException)
+                                    ? ErrorCode.SUCCESS_RETRY_SECRET_HANDSHAKE_TIMEOUT
+                                    : ErrorCode.SUCCESS_RETRY_SECRET_HANDSHAKE_ERROR);
+                }
+            }
+        } while (mPreferences.getRetryGattConnectionAndSecretHandshake()
+                && handshakeResponse == null);
+        if (retryCount > 0) {
+            Log.i(TAG, "Secret handshake failed but restored by retry, retry count=" + retryCount);
+        }
+        String providerPublicAddress =
+                decodeResponse(keys.mSharedSecret, verifyNotNull(handshakeResponse));
+
+        return SharedSecret.create(keys.mSharedSecret, providerPublicAddress);
+    }
+
+    @VisibleForTesting
+    long getTimeoutMs(long spentTime) {
+        if (!mPreferences.getRetryGattConnectionAndSecretHandshake()) {
+            return SECONDS.toMillis(mPreferences.getGattOperationTimeoutSeconds());
+        } else {
+            return spentTime < mPreferences.getSecretHandshakeShortTimeoutRetryMaxSpentTimeMs()
+                    ? mPreferences.getSecretHandshakeShortTimeoutMs()
+                    : mPreferences.getSecretHandshakeLongTimeoutMs();
+        }
+    }
+
+    /**
+     * If the given key is an ecc-256 public key (currently, we are using secp256r1), the shared
+     * secret is generated by ECDH; if the input key is AES-128 key (should be the account key),
+     * then it is the shared secret.
+     */
+    private Keys createKey(byte[] key) throws GeneralSecurityException {
+        if (key.length == EllipticCurveDiffieHellmanExchange.PUBLIC_KEY_LENGTH) {
+            EllipticCurveDiffieHellmanExchange exchange = EllipticCurveDiffieHellmanExchange
+                    .create();
+            byte[] publicKey = exchange.getPublicKey();
+            if (publicKey != null) {
+                Log.i(TAG, "Handshake " + maskBluetoothAddress(mProviderBleAddress)
+                        + ", generates key by ECDH.");
+            } else {
+                throw new GeneralSecurityException("Failed to do ECDH.");
+            }
+            return new Keys(exchange.generateSecret(key), publicKey);
+        } else if (key.length == AesEcbSingleBlockEncryption.KEY_LENGTH) {
+            Log.i(TAG, "Handshake " + maskBluetoothAddress(mProviderBleAddress)
+                    + ", using the given secret.");
+            return new Keys(key, new byte[0]);
+        } else {
+            throw new GeneralSecurityException("Key length is not correct: " + key.length);
+        }
+    }
+
+    private static byte[] createPacket(Keys keys, HandshakeMessage message)
+            throws GeneralSecurityException {
+        byte[] encryptedMessage = encrypt(keys.mSharedSecret, message.getBytes());
+        return concat(encryptedMessage, keys.mPublicKey);
+    }
+
+    private byte[] processGattCommunication(byte[] packet, long gattOperationTimeoutMS)
+            throws BluetoothException, InterruptedException, ExecutionException, TimeoutException {
+        BluetoothGattConnection gattConnection = mGattConnectionManager.getConnection();
+        gattConnection.setOperationTimeout(gattOperationTimeoutMS);
+        UUID characteristicUuid = KeyBasedPairingCharacteristic.getId(gattConnection);
+        ChangeObserver changeObserver =
+                gattConnection.enableNotification(FastPairService.ID, characteristicUuid);
+
+        Log.i(TAG,
+                "Writing handshake packet to address=" + maskBluetoothAddress(mProviderBleAddress));
+        gattConnection.writeCharacteristic(FastPairService.ID, characteristicUuid, packet);
+        Log.i(TAG, "Waiting handshake packet from address=" + maskBluetoothAddress(
+                mProviderBleAddress));
+        return changeObserver.waitForUpdate(gattOperationTimeoutMS);
+    }
+
+    private String decodeResponse(byte[] sharedSecret, byte[] response)
+            throws PairingException, GeneralSecurityException {
+        if (response.length != AES_BLOCK_LENGTH) {
+            throw new PairingException(
+                    "Handshake failed because of incorrect response: " + base16().encode(response));
+        }
+        // 1 byte type, 6 bytes public address, remainder random salt.
+        byte[] decryptedResponse = decrypt(sharedSecret, response);
+        if (decryptedResponse[0] != KeyBasedPairingCharacteristic.Response.TYPE) {
+            throw new PairingException(
+                    "Handshake response type incorrect: " + decryptedResponse[0]);
+        }
+        String address = BluetoothAddress.encode(Arrays.copyOfRange(decryptedResponse, 1, 7));
+        Log.i(TAG, "Handshake success with public " + maskBluetoothAddress(address) + ", ble "
+                + maskBluetoothAddress(mProviderBleAddress));
+        return address;
+    }
+
+    /**
+     * The base class for handshake message that contains the common data: message type, flags and
+     * verification data.
+     */
+    abstract static class HandshakeMessage {
+
+        final byte mType;
+        final byte mFlags;
+        private final byte[] mVerificationData;
+
+        HandshakeMessage(Builder<?> builder) {
+            this.mType = builder.mType;
+            this.mVerificationData = builder.mVerificationData;
+            this.mFlags = builder.mFlags;
+        }
+
+        abstract static class Builder<T extends Builder<T>> {
+
+            byte mType;
+            byte mFlags;
+            private byte[] mVerificationData;
+
+            abstract T getThis();
+
+            T setVerificationData(byte[] verificationData) {
+                if (verificationData.length != BLUETOOTH_ADDRESS_LENGTH) {
+                    throw new IllegalArgumentException(
+                            "Incorrect verification data length: " + verificationData.length + ".");
+                }
+                this.mVerificationData = verificationData;
+                return getThis();
+            }
+        }
+
+        /**
+         * Constructs the base handshake message according to the format of Fast Pair spec.
+         */
+        byte[] constructBaseBytes() {
+            byte[] rawMessage = new byte[Request.SIZE];
+            new SecureRandom().nextBytes(rawMessage);
+            rawMessage[TYPE_INDEX] = mType;
+            rawMessage[FLAGS_INDEX] = mFlags;
+
+            System.arraycopy(
+                    mVerificationData,
+                    /* srcPos= */ 0,
+                    rawMessage,
+                    VERIFICATION_DATA_INDEX,
+                    VERIFICATION_DATA_LENGTH);
+            return rawMessage;
+        }
+
+        /**
+         * Returns the raw handshake message.
+         */
+        abstract byte[] getBytes();
+    }
+
+    /**
+     * Extends {@link HandshakeMessage} and contains the required data for key-based pairing
+     * request.
+     */
+    public static class KeyBasedPairingRequest extends HandshakeMessage {
+
+        @Nullable
+        private final byte[] mSeekerPublicAddress;
+
+        private KeyBasedPairingRequest(Builder builder) {
+            super(builder);
+            this.mSeekerPublicAddress = builder.mSeekerPublicAddress;
+        }
+
+        @Override
+        byte[] getBytes() {
+            byte[] rawMessage = constructBaseBytes();
+            if (mSeekerPublicAddress != null) {
+                System.arraycopy(
+                        mSeekerPublicAddress,
+                        /* srcPos= */ 0,
+                        rawMessage,
+                        SEEKER_PUBLIC_ADDRESS_INDEX,
+                        BLUETOOTH_ADDRESS_LENGTH);
+            }
+            Log.i(TAG,
+                    "Handshake Message: type (" + rawMessage[TYPE_INDEX] + "), flag ("
+                            + rawMessage[FLAGS_INDEX] + ").");
+            return rawMessage;
+        }
+
+        /**
+         * Builder class for key-based pairing request.
+         */
+        public static class Builder extends HandshakeMessage.Builder<Builder> {
+
+            @Nullable
+            private byte[] mSeekerPublicAddress;
+
+            /**
+             * Adds flags without changing other flags.
+             */
+            public Builder addFlag(@KeyBasedPairingRequestFlag int flag) {
+                this.mFlags |= (byte) flag;
+                return this;
+            }
+
+            /**
+             * Set seeker's public address.
+             */
+            public Builder setSeekerPublicAddress(byte[] seekerPublicAddress) {
+                this.mSeekerPublicAddress = seekerPublicAddress;
+                return this;
+            }
+
+            /**
+             * Buulds KeyBasedPairigRequest.
+             */
+            public KeyBasedPairingRequest build() {
+                mType = TYPE_KEY_BASED_PAIRING_REQUEST;
+                return new KeyBasedPairingRequest(this);
+            }
+
+            @Override
+            Builder getThis() {
+                return this;
+            }
+        }
+    }
+
+    /**
+     * Extends {@link HandshakeMessage} and contains the required data for action over BLE request.
+     */
+    public static class ActionOverBle extends HandshakeMessage {
+
+        private final byte mEventGroup;
+        private final byte mEventCode;
+        @Nullable
+        private final byte[] mEventData;
+        private final byte mAdditionalDataType;
+
+        private ActionOverBle(Builder builder) {
+            super(builder);
+            this.mEventGroup = builder.mEventGroup;
+            this.mEventCode = builder.mEventCode;
+            this.mEventData = builder.mEventData;
+            this.mAdditionalDataType = builder.mAdditionalDataType;
+        }
+
+        @Override
+        byte[] getBytes() {
+            byte[] rawMessage = constructBaseBytes();
+            StringBuilder stringBuilder =
+                    new StringBuilder(
+                            String.format(
+                                    "type (%02X), flag (%02X)", rawMessage[TYPE_INDEX],
+                                    rawMessage[FLAGS_INDEX]));
+            if ((mFlags & (byte) DEVICE_ACTION) != 0) {
+                rawMessage[EVENT_GROUP_INDEX] = mEventGroup;
+                rawMessage[EVENT_CODE_INDEX] = mEventCode;
+
+                if (mEventData != null) {
+                    rawMessage[EVENT_ADDITIONAL_DATA_LENGTH_INDEX] = (byte) mEventData.length;
+                    System.arraycopy(
+                            mEventData,
+                            /* srcPos= */ 0,
+                            rawMessage,
+                            EVENT_ADDITIONAL_DATA_INDEX,
+                            mEventData.length);
+                } else {
+                    rawMessage[EVENT_ADDITIONAL_DATA_LENGTH_INDEX] = (byte) 0;
+                }
+                stringBuilder.append(
+                        String.format(
+                                ", group(%02X), code(%02X), length(%02X)",
+                                rawMessage[EVENT_GROUP_INDEX],
+                                rawMessage[EVENT_CODE_INDEX],
+                                rawMessage[EVENT_ADDITIONAL_DATA_LENGTH_INDEX]));
+            }
+            if ((mFlags & (byte) ADDITIONAL_DATA_CHARACTERISTIC) != 0) {
+                rawMessage[ADDITIONAL_DATA_TYPE_INDEX] = mAdditionalDataType;
+                stringBuilder.append(
+                        String.format(", data id(%02X)", rawMessage[ADDITIONAL_DATA_TYPE_INDEX]));
+            }
+            Log.i(TAG, "Handshake Message: " + stringBuilder);
+            return rawMessage;
+        }
+
+        /**
+         * Builder class for action over BLE request.
+         */
+        public static class Builder extends HandshakeMessage.Builder<Builder> {
+
+            private byte mEventGroup;
+            private byte mEventCode;
+            @Nullable
+            private byte[] mEventData;
+            private byte mAdditionalDataType;
+
+            // Adds a flag to this handshake message. This can be called repeatedly for adding
+            // different preference.
+
+            /**
+             * Adds flag without changing other flags.
+             */
+            public Builder addFlag(@ActionOverBleFlag int flag) {
+                this.mFlags |= (byte) flag;
+                return this;
+            }
+
+            /**
+             * Set event group and event code.
+             */
+            public Builder setEvent(int eventGroup, int eventCode) {
+                this.mFlags |= (byte) DEVICE_ACTION;
+                this.mEventGroup = (byte) (eventGroup & 0xFF);
+                this.mEventCode = (byte) (eventCode & 0xFF);
+                return this;
+            }
+
+            /**
+             * Set event additional data.
+             */
+            public Builder setEventAdditionalData(byte[] data) {
+                this.mEventData = data;
+                return this;
+            }
+
+            /**
+             * Set event additional data type.
+             */
+            public Builder setAdditionalDataType(@AdditionalDataType int additionalDataType) {
+                this.mFlags |= (byte) ADDITIONAL_DATA_CHARACTERISTIC;
+                this.mAdditionalDataType = (byte) additionalDataType;
+                return this;
+            }
+
+            @Override
+            Builder getThis() {
+                return this;
+            }
+
+            ActionOverBle build() {
+                mType = TYPE_ACTION_OVER_BLE;
+                return new ActionOverBle(this);
+            }
+        }
+    }
+
+    /**
+     * Exception for handshake failure.
+     */
+    public static class HandshakeException extends PairingException {
+
+        private final BluetoothException mOriginalException;
+
+        @VisibleForTesting
+        HandshakeException(String format, BluetoothException e) {
+            super(format);
+            mOriginalException = e;
+        }
+
+        public BluetoothException getOriginalException() {
+            return mOriginalException;
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/HeadsetPiece.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/HeadsetPiece.java
new file mode 100644
index 0000000..26ff79f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/HeadsetPiece.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.Nullable;
+import androidx.core.content.FileProvider;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * This class is subclass of real headset. It contains image url, battery value and charging
+ * status.
+ */
+public class HeadsetPiece implements Parcelable {
+    private int mLowLevelThreshold;
+    private int mBatteryLevel;
+    private String mImageUrl;
+    private boolean mCharging;
+    private Uri mImageContentUri;
+
+    private HeadsetPiece(
+            int lowLevelThreshold,
+            int batteryLevel,
+            String imageUrl,
+            boolean charging,
+            @Nullable Uri imageContentUri) {
+        this.mLowLevelThreshold = lowLevelThreshold;
+        this.mBatteryLevel = batteryLevel;
+        this.mImageUrl = imageUrl;
+        this.mCharging = charging;
+        this.mImageContentUri = imageContentUri;
+    }
+
+    /**
+     * Returns a builder of HeadsetPiece.
+     */
+    public static HeadsetPiece.Builder builder() {
+        return new HeadsetPiece.Builder();
+    }
+
+    /**
+     * The low level threshold.
+     */
+    public int lowLevelThreshold() {
+        return mLowLevelThreshold;
+    }
+
+    /**
+     * The battery level.
+     */
+    public int batteryLevel() {
+        return mBatteryLevel;
+    }
+
+    /**
+     * The web URL of the image.
+     */
+    public String imageUrl() {
+        return mImageUrl;
+    }
+
+    /**
+     * Whether the headset is charging.
+     */
+    public boolean charging() {
+        return mCharging;
+    }
+
+    /**
+     * The content Uri of the image if it could be downloaded from the web URL and generated through
+     * {@link FileProvider#getUriForFile} successfully, otherwise null.
+     */
+    @Nullable
+    public Uri imageContentUri() {
+        return mImageContentUri;
+    }
+
+    /**
+     * @return whether battery is low or not.
+     */
+    public boolean isBatteryLow() {
+        return batteryLevel() <= lowLevelThreshold() && batteryLevel() >= 0 && !charging();
+    }
+
+    @Override
+    public String toString() {
+        return "HeadsetPiece{"
+                + "lowLevelThreshold=" + mLowLevelThreshold + ", "
+                + "batteryLevel=" + mBatteryLevel + ", "
+                + "imageUrl=" + mImageUrl + ", "
+                + "charging=" + mCharging + ", "
+                + "imageContentUri=" + mImageContentUri
+                + "}";
+    }
+
+    /**
+     * Builder function for headset piece.
+     */
+    public static class Builder {
+        private int mLowLevelThreshold;
+        private int mBatteryLevel;
+        private String mImageUrl;
+        private boolean mCharging;
+        private Uri mImageContentUri;
+
+        /**
+         * Set low level threshold.
+         */
+        public HeadsetPiece.Builder setLowLevelThreshold(int lowLevelThreshold) {
+            this.mLowLevelThreshold = lowLevelThreshold;
+            return this;
+        }
+
+        /**
+         * Set battery level.
+         */
+        public HeadsetPiece.Builder setBatteryLevel(int level) {
+            this.mBatteryLevel = level;
+            return this;
+        }
+
+        /**
+         * Set image url.
+         */
+        public HeadsetPiece.Builder setImageUrl(String url) {
+            this.mImageUrl = url;
+            return this;
+        }
+
+        /**
+         * Set charging.
+         */
+        public HeadsetPiece.Builder setCharging(boolean charging) {
+            this.mCharging = charging;
+            return this;
+        }
+
+        /**
+         * Set image content Uri.
+         */
+        public HeadsetPiece.Builder setImageContentUri(Uri uri) {
+            this.mImageContentUri = uri;
+            return this;
+        }
+
+        /**
+         * Builds HeadSetPiece.
+         */
+        public HeadsetPiece build() {
+            return new HeadsetPiece(mLowLevelThreshold, mBatteryLevel, mImageUrl, mCharging,
+                    mImageContentUri);
+        }
+    }
+
+    @Override
+    public final void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(imageUrl());
+        dest.writeInt(lowLevelThreshold());
+        dest.writeInt(batteryLevel());
+        // Writes 1 if charging, otherwise 0.
+        dest.writeByte((byte) (charging() ? 1 : 0));
+        dest.writeParcelable(imageContentUri(), flags);
+    }
+
+    @Override
+    public final int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<HeadsetPiece> CREATOR =
+            new Creator<HeadsetPiece>() {
+                @Override
+                public HeadsetPiece createFromParcel(Parcel in) {
+                    String imageUrl = in.readString();
+                    return HeadsetPiece.builder()
+                            .setImageUrl(imageUrl != null ? imageUrl : "")
+                            .setLowLevelThreshold(in.readInt())
+                            .setBatteryLevel(in.readInt())
+                            .setCharging(in.readByte() != 0)
+                            .setImageContentUri(in.readParcelable(Uri.class.getClassLoader()))
+                            .build();
+                }
+
+                @Override
+                public HeadsetPiece[] newArray(int size) {
+                    return new HeadsetPiece[size];
+                }
+            };
+
+    @Override
+    public final int hashCode() {
+        return Arrays.hashCode(
+                new Object[]{
+                        lowLevelThreshold(), batteryLevel(), imageUrl(), charging(),
+                        imageContentUri()
+                });
+    }
+
+    @Override
+    public final boolean equals(@Nullable Object other) {
+        if (other == null) {
+            return false;
+        }
+
+        if (this == other) {
+            return true;
+        }
+
+        if (!(other instanceof HeadsetPiece)) {
+            return false;
+        }
+
+        HeadsetPiece that = (HeadsetPiece) other;
+        return lowLevelThreshold() == that.lowLevelThreshold()
+                && batteryLevel() == that.batteryLevel()
+                && Objects.equals(imageUrl(), that.imageUrl())
+                && charging() == that.charging()
+                && Objects.equals(imageContentUri(), that.imageContentUri());
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/HmacSha256.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/HmacSha256.java
new file mode 100644
index 0000000..cc7a300
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/HmacSha256.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.KEY_LENGTH;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.security.GeneralSecurityException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * HMAC-SHA256 utility used to generate key-SHA256 based message authentication code. This is
+ * specific for Fast Pair GATT connection exchanging data to verify both the data integrity and the
+ * authentication of a message. It is defined as:
+ *
+ * <ol>
+ *   <li>SHA256(concat((key ^ opad),SHA256(concat((key ^ ipad), data)))), where
+ *   <li>key is the given secret extended to 64 bytes by concat(secret, ZEROS).
+ *   <li>opad is 64 bytes outer padding, consisting of repeated bytes valued 0x5c.
+ *   <li>ipad is 64 bytes inner padding, consisting of repeated bytes valued 0x36.
+ * </ol>
+ *
+ */
+final class HmacSha256 {
+    @VisibleForTesting static final int HMAC_SHA256_BLOCK_SIZE = 64;
+
+    private HmacSha256() {}
+
+    /**
+     * Generates the HMAC for given parameters, this is specific for Fast Pair GATT connection
+     * exchanging data which is encrypted using AES-CTR.
+     *
+     * @param secret 16 bytes shared secret.
+     * @param data the data encrypted using AES-CTR and the given nonce.
+     * @return HMAC-SHA256 result.
+     */
+    static byte[] build(byte[] secret, byte[] data) throws GeneralSecurityException {
+        // Currently we only accept AES-128 key here, the second check is to secure we won't
+        // modify KEY_LENGTH to > HMAC_SHA256_BLOCK_SIZE by mistake.
+        if (secret.length != KEY_LENGTH) {
+            throw new GeneralSecurityException("Incorrect key length, should be the AES-128 key.");
+        }
+        if (KEY_LENGTH > HMAC_SHA256_BLOCK_SIZE) {
+            throw new GeneralSecurityException("KEY_LENGTH > HMAC_SHA256_BLOCK_SIZE!");
+        }
+
+        return buildWith64BytesKey(secret, data);
+    }
+
+    /**
+     * Generates the HMAC for given parameters, this is specific for Fast Pair GATT connection
+     * exchanging data which is encrypted using AES-CTR.
+     *
+     * @param secret 16 bytes shared secret.
+     * @param data the data encrypted using AES-CTR and the given nonce.
+     * @return HMAC-SHA256 result.
+     */
+    static byte[] buildWith64BytesKey(byte[] secret, byte[] data) throws GeneralSecurityException {
+        if (secret.length > HMAC_SHA256_BLOCK_SIZE) {
+            throw new GeneralSecurityException("KEY_LENGTH > HMAC_SHA256_BLOCK_SIZE!");
+        }
+
+        Mac mac = Mac.getInstance("HmacSHA256");
+        SecretKeySpec keySpec = new SecretKeySpec(secret, "HmacSHA256");
+        mac.init(keySpec);
+
+        return mac.doFinal(data);
+    }
+
+    /**
+     * Constant-time HMAC comparison to prevent a possible timing attack, e.g. time the same MAC
+     * with all different first byte for a given ciphertext, the right one will take longer as it
+     * will fail on the second byte's verification.
+     *
+     * @param hmac1 HMAC want to be compared with.
+     * @param hmac2 HMAC want to be compared with.
+     * @return true if and ony if the give 2 HMACs are identical and non-null.
+     */
+    static boolean compareTwoHMACs(byte[] hmac1, byte[] hmac2) {
+        if (hmac1 == null || hmac2 == null) {
+            return false;
+        }
+
+        if (hmac1.length != hmac2.length) {
+            return false;
+        }
+        // This is for constant-time comparison, don't optimize it.
+        int res = 0;
+        for (int i = 0; i < hmac1.length; i++) {
+            res |= hmac1[i] ^ hmac2[i];
+        }
+        return res == 0;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Ltv.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Ltv.java
new file mode 100644
index 0000000..88c9484
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Ltv.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.io.BaseEncoding.base16;
+
+import com.google.common.primitives.Bytes;
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A length, type, value (LTV) data block.
+ */
+public class Ltv {
+
+    private static final int SIZE_OF_LEN_TYPE = 2;
+
+    final byte mType;
+    final byte[] mValue;
+
+    /**
+     * Thrown if there's an error during {@link #parse}.
+     */
+    public static class ParseException extends Exception {
+
+        @FormatMethod
+        private ParseException(@FormatString String format, Object... objects) {
+            super(String.format(format, objects));
+        }
+    }
+
+    /**
+     * Constructor.
+     */
+    public Ltv(byte type, byte... value) {
+        this.mType = type;
+        this.mValue = value;
+    }
+
+    /**
+     * Parses a list of LTV blocks out of the input byte block.
+     */
+    static List<Ltv> parse(byte[] bytes) throws ParseException {
+        List<Ltv> ltvs = new ArrayList<>();
+        // The "+ 2" is for the length and type bytes.
+        for (int valueLength, i = 0; i < bytes.length; i += SIZE_OF_LEN_TYPE + valueLength) {
+            // - 1 since the length in the packet includes the type byte.
+            valueLength = bytes[i] - 1;
+            if (valueLength < 0 || bytes.length < i + SIZE_OF_LEN_TYPE + valueLength) {
+                throw new ParseException(
+                        "Wrong length=%d at index=%d in LTVs=%s", bytes[i], i,
+                        base16().encode(bytes));
+            }
+            ltvs.add(new Ltv(bytes[i + 1], Arrays.copyOfRange(bytes, i + SIZE_OF_LEN_TYPE,
+                    i + SIZE_OF_LEN_TYPE + valueLength)));
+        }
+        return ltvs;
+    }
+
+    /**
+     * Returns an LTV block, where length is mValue.length + 1 (for the type byte).
+     */
+    public byte[] getBytes() {
+        return Bytes.concat(new byte[]{(byte) (mValue.length + 1), mType}, mValue);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/MessageStreamHmacEncoder.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/MessageStreamHmacEncoder.java
new file mode 100644
index 0000000..b04cf73
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/MessageStreamHmacEncoder.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.generateNonce;
+
+import static com.google.common.primitives.Bytes.concat;
+
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+
+/**
+ * Message stream utilities for encoding raw packet with HMAC.
+ *
+ * <p>Encoded packet is:
+ *
+ * <ol>
+ *   <li>Packet[0 - (data length - 1)]: the raw data.
+ *   <li>Packet[data length - (data length + 7)]: the 8-byte message nonce.
+ *   <li>Packet[(data length + 8) - (data length + 15)]: the 8-byte of HMAC.
+ * </ol>
+ */
+public class MessageStreamHmacEncoder {
+    public static final int EXTRACT_HMAC_SIZE = 8;
+    public static final int SECTION_NONCE_LENGTH = 8;
+
+    private MessageStreamHmacEncoder() {}
+
+    /** Encodes Message Packet. */
+    public static byte[] encodeMessagePacket(byte[] accountKey, byte[] sectionNonce, byte[] data)
+            throws GeneralSecurityException {
+        checkAccountKeyAndSectionNonce(accountKey, sectionNonce);
+
+        if (data == null || data.length == 0) {
+            throw new GeneralSecurityException("No input data for encodeMessagePacket");
+        }
+
+        byte[] messageNonce = generateNonce();
+        byte[] extractedHmac =
+                Arrays.copyOf(
+                        HmacSha256.buildWith64BytesKey(
+                                accountKey, concat(sectionNonce, messageNonce, data)),
+                        EXTRACT_HMAC_SIZE);
+
+        return concat(data, messageNonce, extractedHmac);
+    }
+
+    /** Verifies Hmac. */
+    public static boolean verifyHmac(byte[] accountKey, byte[] sectionNonce, byte[] data)
+            throws GeneralSecurityException {
+        checkAccountKeyAndSectionNonce(accountKey, sectionNonce);
+        if (data == null) {
+            throw new GeneralSecurityException("data is null");
+        }
+        if (data.length <= EXTRACT_HMAC_SIZE + SECTION_NONCE_LENGTH) {
+            throw new GeneralSecurityException("data.length too short");
+        }
+
+        byte[] hmac = Arrays.copyOfRange(data, data.length - EXTRACT_HMAC_SIZE, data.length);
+        byte[] messageNonce =
+                Arrays.copyOfRange(
+                        data,
+                        data.length - EXTRACT_HMAC_SIZE - SECTION_NONCE_LENGTH,
+                        data.length - EXTRACT_HMAC_SIZE);
+        byte[] rawData = Arrays.copyOf(
+                data, data.length - EXTRACT_HMAC_SIZE - SECTION_NONCE_LENGTH);
+        return Arrays.equals(
+                Arrays.copyOf(
+                        HmacSha256.buildWith64BytesKey(
+                                accountKey, concat(sectionNonce, messageNonce, rawData)),
+                        EXTRACT_HMAC_SIZE),
+                hmac);
+    }
+
+    private static void checkAccountKeyAndSectionNonce(byte[] accountKey, byte[] sectionNonce)
+            throws GeneralSecurityException {
+        if (accountKey == null || accountKey.length == 0) {
+            throw new GeneralSecurityException(
+                    "Incorrect accountKey for encoding message packet, accountKey.length = "
+                            + (accountKey == null ? "NULL" : accountKey.length));
+        }
+
+        if (sectionNonce == null || sectionNonce.length != SECTION_NONCE_LENGTH) {
+            throw new GeneralSecurityException(
+                    "Incorrect sectionNonce for encoding message packet, sectionNonce.length = "
+                            + (sectionNonce == null ? "NULL" : sectionNonce.length));
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/NamingEncoder.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/NamingEncoder.java
new file mode 100644
index 0000000..1521be6
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/NamingEncoder.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.NONCE_SIZE;
+
+import static com.google.common.primitives.Bytes.concat;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import android.annotation.TargetApi;
+import android.os.Build.VERSION_CODES;
+
+import com.google.common.base.Utf8;
+
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+
+/**
+ * Naming utilities for encoding naming packet, decoding naming packet and verifying both the data
+ * integrity and the authentication of a message by checking HMAC.
+ *
+ * <p>Naming packet is:
+ *
+ * <ol>
+ *   <li>Naming_Packet[0 - 7]: the first 8-byte of HMAC.
+ *   <li>Naming_Packet[8 - var]: the encrypted name (with 8-byte nonce appended to the front).
+ * </ol>
+ */
+@TargetApi(VERSION_CODES.M)
+public final class NamingEncoder {
+
+    static final int EXTRACT_HMAC_SIZE = 8;
+    static final int MAX_LENGTH_OF_NAME = 48;
+
+    private NamingEncoder() {
+    }
+
+    /**
+     * Encodes the name to naming packet by the given secret.
+     *
+     * @param secret AES-128 key for encryption.
+     * @param name the given name to be encoded.
+     * @return the encrypted data with the 8-byte extracted HMAC appended to the front.
+     * @throws GeneralSecurityException if the given key or name is invalid for encoding.
+     */
+    public static byte[] encodeNamingPacket(byte[] secret, String name)
+            throws GeneralSecurityException {
+        if (secret == null || secret.length != AesCtrMultipleBlockEncryption.KEY_LENGTH) {
+            throw new GeneralSecurityException(
+                    "Incorrect secret for encoding name packet, secret.length = "
+                            + (secret == null ? "NULL" : secret.length));
+        }
+
+        if ((name == null) || (name.length() == 0) || (Utf8.encodedLength(name)
+                > MAX_LENGTH_OF_NAME)) {
+            throw new GeneralSecurityException(
+                    "Invalid name for encoding name packet, Utf8.encodedLength(name) = "
+                            + (name == null ? "NULL" : Utf8.encodedLength(name)));
+        }
+
+        byte[] encryptedData = AesCtrMultipleBlockEncryption.encrypt(secret, name.getBytes(UTF_8));
+        byte[] extractedHmac =
+                Arrays.copyOf(HmacSha256.build(secret, encryptedData), EXTRACT_HMAC_SIZE);
+
+        return concat(extractedHmac, encryptedData);
+    }
+
+    /**
+     * Decodes the name from naming packet by the given secret.
+     *
+     * @param secret AES-128 key used in the encryption to decrypt data.
+     * @param namingPacket naming packet which is encoded by the given secret..
+     * @return the name decoded from the given packet.
+     * @throws GeneralSecurityException if the given key or naming packet is invalid for decoding.
+     */
+    public static String decodeNamingPacket(byte[] secret, byte[] namingPacket)
+            throws GeneralSecurityException {
+        if (secret == null || secret.length != AesCtrMultipleBlockEncryption.KEY_LENGTH) {
+            throw new GeneralSecurityException(
+                    "Incorrect secret for decoding name packet, secret.length = "
+                            + (secret == null ? "NULL" : secret.length));
+        }
+        if (namingPacket == null
+                || namingPacket.length <= EXTRACT_HMAC_SIZE
+                || namingPacket.length > (MAX_LENGTH_OF_NAME + EXTRACT_HMAC_SIZE + NONCE_SIZE)) {
+            throw new GeneralSecurityException(
+                    "Naming packet size is incorrect, namingPacket.length is "
+                            + (namingPacket == null ? "NULL" : namingPacket.length));
+        }
+
+        if (!verifyHmac(secret, namingPacket)) {
+            throw new GeneralSecurityException(
+                    "Verify HMAC failed, could be incorrect key or naming packet.");
+        }
+        byte[] encryptedData = Arrays
+                .copyOfRange(namingPacket, EXTRACT_HMAC_SIZE, namingPacket.length);
+        return new String(AesCtrMultipleBlockEncryption.decrypt(secret, encryptedData), UTF_8);
+    }
+
+    // Computes the HMAC of the given key and name, and compares the first 8-byte of the HMAC result
+    // with the one from name packet. Must call constant-time comparison to prevent a possible
+    // timing attack, e.g. time the same MAC with all different first byte for a given ciphertext,
+    // the right one will take longer as it will fail on the second byte's verification.
+    private static boolean verifyHmac(byte[] key, byte[] namingPacket)
+            throws GeneralSecurityException {
+        byte[] packetHmac = Arrays.copyOfRange(namingPacket, /* from= */ 0, EXTRACT_HMAC_SIZE);
+        byte[] encryptedData = Arrays
+                .copyOfRange(namingPacket, EXTRACT_HMAC_SIZE, namingPacket.length);
+        byte[] computedHmac = Arrays
+                .copyOf(HmacSha256.build(key, encryptedData), EXTRACT_HMAC_SIZE);
+
+        return HmacSha256.compareTwoHMACs(packetHmac, computedHmac);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PairingException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PairingException.java
new file mode 100644
index 0000000..722dc85
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PairingException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+/** Base class for pairing exceptions. */
+// TODO(b/200594968): convert exceptions into error codes to save memory.
+public class PairingException extends Exception {
+    PairingException(String format, Object... objects) {
+        super(String.format(format, objects));
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PairingProgressListener.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PairingProgressListener.java
new file mode 100644
index 0000000..270cb42
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PairingProgressListener.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Callback interface for pairing progress. */
+public interface PairingProgressListener {
+
+    /** Fast Pair Bond State. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            value = {
+                    PairingEvent.START,
+                    PairingEvent.SUCCESS,
+                    PairingEvent.FAILED,
+                    PairingEvent.UNKNOWN,
+            })
+    public @interface PairingEvent {
+        int START = 0;
+        int SUCCESS = 1;
+        int FAILED = 2;
+        int UNKNOWN = 3;
+    }
+
+    /** Returns enum based on the ordinal index. */
+    static @PairingEvent int fromOrdinal(int ordinal) {
+        switch (ordinal) {
+            case 0:
+                return PairingEvent.START;
+            case 1:
+                return PairingEvent.SUCCESS;
+            case 2:
+                return PairingEvent.FAILED;
+            case 3:
+                return PairingEvent.UNKNOWN;
+            default:
+                return PairingEvent.UNKNOWN;
+        }
+    }
+
+    /** Callback function upon pairing progress update. */
+    void onPairingProgressUpdating(@PairingEvent int event, String message);
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PasskeyConfirmationHandler.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PasskeyConfirmationHandler.java
new file mode 100644
index 0000000..f5807a3
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PasskeyConfirmationHandler.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import android.bluetooth.BluetoothDevice;
+
+/** Interface for getting the passkey confirmation request. */
+public interface PasskeyConfirmationHandler {
+    /** Called when getting the passkey confirmation request while pairing. */
+    void onPasskeyConfirmation(BluetoothDevice device, int passkey);
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Preferences.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Preferences.java
new file mode 100644
index 0000000..bb7b71b
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Preferences.java
@@ -0,0 +1,2309 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothUuids.get16BitUuid;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.FirmwareVersionCharacteristic;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.primitives.Shorts;
+
+import java.nio.ByteOrder;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Preferences that tweak the Fast Pairing process: timeouts, number of retries... All preferences
+ * have default values which should be reasonable for all clients.
+ */
+public class Preferences {
+
+    private final int mGattOperationTimeoutSeconds;
+    private final int mGattConnectionTimeoutSeconds;
+    private final int mBluetoothToggleTimeoutSeconds;
+    private final int mBluetoothToggleSleepSeconds;
+    private final int mClassicDiscoveryTimeoutSeconds;
+    private final int mNumDiscoverAttempts;
+    private final int mDiscoveryRetrySleepSeconds;
+    private final boolean mIgnoreDiscoveryError;
+    private final int mSdpTimeoutSeconds;
+    private final int mNumSdpAttempts;
+    private final int mNumCreateBondAttempts;
+    private final int mNumConnectAttempts;
+    private final int mNumWriteAccountKeyAttempts;
+    private final boolean mToggleBluetoothOnFailure;
+    private final boolean mBluetoothStateUsesPolling;
+    private final int mBluetoothStatePollingMillis;
+    private final int mNumAttempts;
+    private final boolean mEnableBrEdrHandover;
+    private final short mBrHandoverDataCharacteristicId;
+    private final short mBluetoothSigDataCharacteristicId;
+    private final short mFirmwareVersionCharacteristicId;
+    private final short mBrTransportBlockDataDescriptorId;
+    private final boolean mWaitForUuidsAfterBonding;
+    private final boolean mReceiveUuidsAndBondedEventBeforeClose;
+    private final int mRemoveBondTimeoutSeconds;
+    private final int mRemoveBondSleepMillis;
+    private final int mCreateBondTimeoutSeconds;
+    private final int mHidCreateBondTimeoutSeconds;
+    private final int mProxyTimeoutSeconds;
+    private final boolean mRejectPhonebookAccess;
+    private final boolean mRejectMessageAccess;
+    private final boolean mRejectSimAccess;
+    private final int mWriteAccountKeySleepMillis;
+    private final boolean mSkipDisconnectingGattBeforeWritingAccountKey;
+    private final boolean mMoreEventLogForQuality;
+    private final boolean mRetryGattConnectionAndSecretHandshake;
+    private final long mGattConnectShortTimeoutMs;
+    private final long mGattConnectLongTimeoutMs;
+    private final long mGattConnectShortTimeoutRetryMaxSpentTimeMs;
+    private final long mAddressRotateRetryMaxSpentTimeMs;
+    private final long mPairingRetryDelayMs;
+    private final long mSecretHandshakeShortTimeoutMs;
+    private final long mSecretHandshakeLongTimeoutMs;
+    private final long mSecretHandshakeShortTimeoutRetryMaxSpentTimeMs;
+    private final long mSecretHandshakeLongTimeoutRetryMaxSpentTimeMs;
+    private final long mSecretHandshakeRetryAttempts;
+    private final long mSecretHandshakeRetryGattConnectionMaxSpentTimeMs;
+    private final long mSignalLostRetryMaxSpentTimeMs;
+    private final ImmutableSet<Integer> mGattConnectionAndSecretHandshakeNoRetryGattError;
+    private final boolean mRetrySecretHandshakeTimeout;
+    private final boolean mLogUserManualRetry;
+    private final int mPairFailureCounts;
+    private final String mCachedDeviceAddress;
+    private final String mPossibleCachedDeviceAddress;
+    private final int mSameModelIdPairedDeviceCount;
+    private final boolean mIsDeviceFinishCheckAddressFromCache;
+    private final boolean mLogPairWithCachedModelId;
+    private final boolean mDirectConnectProfileIfModelIdInCache;
+    private final boolean mAcceptPasskey;
+    private final byte[] mSupportedProfileUuids;
+    private final boolean mProviderInitiatesBondingIfSupported;
+    private final boolean mAttemptDirectConnectionWhenPreviouslyBonded;
+    private final boolean mAutomaticallyReconnectGattWhenNeeded;
+    private final boolean mSkipConnectingProfiles;
+    private final boolean mIgnoreUuidTimeoutAfterBonded;
+    private final boolean mSpecifyCreateBondTransportType;
+    private final int mCreateBondTransportType;
+    private final boolean mIncreaseIntentFilterPriority;
+    private final boolean mEvaluatePerformance;
+    private final Preferences.ExtraLoggingInformation mExtraLoggingInformation;
+    private final boolean mEnableNamingCharacteristic;
+    private final boolean mEnableFirmwareVersionCharacteristic;
+    private final boolean mKeepSameAccountKeyWrite;
+    private final boolean mIsRetroactivePairing;
+    private final int mNumSdpAttemptsAfterBonded;
+    private final boolean mSupportHidDevice;
+    private final boolean mEnablePairingWhileDirectlyConnecting;
+    private final boolean mAcceptConsentForFastPairOne;
+    private final int mGattConnectRetryTimeoutMillis;
+    private final boolean mEnable128BitCustomGattCharacteristicsId;
+    private final boolean mEnableSendExceptionStepToValidator;
+    private final boolean mEnableAdditionalDataTypeWhenActionOverBle;
+    private final boolean mCheckBondStateWhenSkipConnectingProfiles;
+    private final boolean mHandlePasskeyConfirmationByUi;
+    private final boolean mEnablePairFlowShowUiWithoutProfileConnection;
+
+    private Preferences(
+            int gattOperationTimeoutSeconds,
+            int gattConnectionTimeoutSeconds,
+            int bluetoothToggleTimeoutSeconds,
+            int bluetoothToggleSleepSeconds,
+            int classicDiscoveryTimeoutSeconds,
+            int numDiscoverAttempts,
+            int discoveryRetrySleepSeconds,
+            boolean ignoreDiscoveryError,
+            int sdpTimeoutSeconds,
+            int numSdpAttempts,
+            int numCreateBondAttempts,
+            int numConnectAttempts,
+            int numWriteAccountKeyAttempts,
+            boolean toggleBluetoothOnFailure,
+            boolean bluetoothStateUsesPolling,
+            int bluetoothStatePollingMillis,
+            int numAttempts,
+            boolean enableBrEdrHandover,
+            short brHandoverDataCharacteristicId,
+            short bluetoothSigDataCharacteristicId,
+            short firmwareVersionCharacteristicId,
+            short brTransportBlockDataDescriptorId,
+            boolean waitForUuidsAfterBonding,
+            boolean receiveUuidsAndBondedEventBeforeClose,
+            int removeBondTimeoutSeconds,
+            int removeBondSleepMillis,
+            int createBondTimeoutSeconds,
+            int hidCreateBondTimeoutSeconds,
+            int proxyTimeoutSeconds,
+            boolean rejectPhonebookAccess,
+            boolean rejectMessageAccess,
+            boolean rejectSimAccess,
+            int writeAccountKeySleepMillis,
+            boolean skipDisconnectingGattBeforeWritingAccountKey,
+            boolean moreEventLogForQuality,
+            boolean retryGattConnectionAndSecretHandshake,
+            long gattConnectShortTimeoutMs,
+            long gattConnectLongTimeoutMs,
+            long gattConnectShortTimeoutRetryMaxSpentTimeMs,
+            long addressRotateRetryMaxSpentTimeMs,
+            long pairingRetryDelayMs,
+            long secretHandshakeShortTimeoutMs,
+            long secretHandshakeLongTimeoutMs,
+            long secretHandshakeShortTimeoutRetryMaxSpentTimeMs,
+            long secretHandshakeLongTimeoutRetryMaxSpentTimeMs,
+            long secretHandshakeRetryAttempts,
+            long secretHandshakeRetryGattConnectionMaxSpentTimeMs,
+            long signalLostRetryMaxSpentTimeMs,
+            ImmutableSet<Integer> gattConnectionAndSecretHandshakeNoRetryGattError,
+            boolean retrySecretHandshakeTimeout,
+            boolean logUserManualRetry,
+            int pairFailureCounts,
+            String cachedDeviceAddress,
+            String possibleCachedDeviceAddress,
+            int sameModelIdPairedDeviceCount,
+            boolean isDeviceFinishCheckAddressFromCache,
+            boolean logPairWithCachedModelId,
+            boolean directConnectProfileIfModelIdInCache,
+            boolean acceptPasskey,
+            byte[] supportedProfileUuids,
+            boolean providerInitiatesBondingIfSupported,
+            boolean attemptDirectConnectionWhenPreviouslyBonded,
+            boolean automaticallyReconnectGattWhenNeeded,
+            boolean skipConnectingProfiles,
+            boolean ignoreUuidTimeoutAfterBonded,
+            boolean specifyCreateBondTransportType,
+            int createBondTransportType,
+            boolean increaseIntentFilterPriority,
+            boolean evaluatePerformance,
+            @Nullable Preferences.ExtraLoggingInformation extraLoggingInformation,
+            boolean enableNamingCharacteristic,
+            boolean enableFirmwareVersionCharacteristic,
+            boolean keepSameAccountKeyWrite,
+            boolean isRetroactivePairing,
+            int numSdpAttemptsAfterBonded,
+            boolean supportHidDevice,
+            boolean enablePairingWhileDirectlyConnecting,
+            boolean acceptConsentForFastPairOne,
+            int gattConnectRetryTimeoutMillis,
+            boolean enable128BitCustomGattCharacteristicsId,
+            boolean enableSendExceptionStepToValidator,
+            boolean enableAdditionalDataTypeWhenActionOverBle,
+            boolean checkBondStateWhenSkipConnectingProfiles,
+            boolean handlePasskeyConfirmationByUi,
+            boolean enablePairFlowShowUiWithoutProfileConnection) {
+        this.mGattOperationTimeoutSeconds = gattOperationTimeoutSeconds;
+        this.mGattConnectionTimeoutSeconds = gattConnectionTimeoutSeconds;
+        this.mBluetoothToggleTimeoutSeconds = bluetoothToggleTimeoutSeconds;
+        this.mBluetoothToggleSleepSeconds = bluetoothToggleSleepSeconds;
+        this.mClassicDiscoveryTimeoutSeconds = classicDiscoveryTimeoutSeconds;
+        this.mNumDiscoverAttempts = numDiscoverAttempts;
+        this.mDiscoveryRetrySleepSeconds = discoveryRetrySleepSeconds;
+        this.mIgnoreDiscoveryError = ignoreDiscoveryError;
+        this.mSdpTimeoutSeconds = sdpTimeoutSeconds;
+        this.mNumSdpAttempts = numSdpAttempts;
+        this.mNumCreateBondAttempts = numCreateBondAttempts;
+        this.mNumConnectAttempts = numConnectAttempts;
+        this.mNumWriteAccountKeyAttempts = numWriteAccountKeyAttempts;
+        this.mToggleBluetoothOnFailure = toggleBluetoothOnFailure;
+        this.mBluetoothStateUsesPolling = bluetoothStateUsesPolling;
+        this.mBluetoothStatePollingMillis = bluetoothStatePollingMillis;
+        this.mNumAttempts = numAttempts;
+        this.mEnableBrEdrHandover = enableBrEdrHandover;
+        this.mBrHandoverDataCharacteristicId = brHandoverDataCharacteristicId;
+        this.mBluetoothSigDataCharacteristicId = bluetoothSigDataCharacteristicId;
+        this.mFirmwareVersionCharacteristicId = firmwareVersionCharacteristicId;
+        this.mBrTransportBlockDataDescriptorId = brTransportBlockDataDescriptorId;
+        this.mWaitForUuidsAfterBonding = waitForUuidsAfterBonding;
+        this.mReceiveUuidsAndBondedEventBeforeClose = receiveUuidsAndBondedEventBeforeClose;
+        this.mRemoveBondTimeoutSeconds = removeBondTimeoutSeconds;
+        this.mRemoveBondSleepMillis = removeBondSleepMillis;
+        this.mCreateBondTimeoutSeconds = createBondTimeoutSeconds;
+        this.mHidCreateBondTimeoutSeconds = hidCreateBondTimeoutSeconds;
+        this.mProxyTimeoutSeconds = proxyTimeoutSeconds;
+        this.mRejectPhonebookAccess = rejectPhonebookAccess;
+        this.mRejectMessageAccess = rejectMessageAccess;
+        this.mRejectSimAccess = rejectSimAccess;
+        this.mWriteAccountKeySleepMillis = writeAccountKeySleepMillis;
+        this.mSkipDisconnectingGattBeforeWritingAccountKey =
+                skipDisconnectingGattBeforeWritingAccountKey;
+        this.mMoreEventLogForQuality = moreEventLogForQuality;
+        this.mRetryGattConnectionAndSecretHandshake = retryGattConnectionAndSecretHandshake;
+        this.mGattConnectShortTimeoutMs = gattConnectShortTimeoutMs;
+        this.mGattConnectLongTimeoutMs = gattConnectLongTimeoutMs;
+        this.mGattConnectShortTimeoutRetryMaxSpentTimeMs =
+                gattConnectShortTimeoutRetryMaxSpentTimeMs;
+        this.mAddressRotateRetryMaxSpentTimeMs = addressRotateRetryMaxSpentTimeMs;
+        this.mPairingRetryDelayMs = pairingRetryDelayMs;
+        this.mSecretHandshakeShortTimeoutMs = secretHandshakeShortTimeoutMs;
+        this.mSecretHandshakeLongTimeoutMs = secretHandshakeLongTimeoutMs;
+        this.mSecretHandshakeShortTimeoutRetryMaxSpentTimeMs =
+                secretHandshakeShortTimeoutRetryMaxSpentTimeMs;
+        this.mSecretHandshakeLongTimeoutRetryMaxSpentTimeMs =
+                secretHandshakeLongTimeoutRetryMaxSpentTimeMs;
+        this.mSecretHandshakeRetryAttempts = secretHandshakeRetryAttempts;
+        this.mSecretHandshakeRetryGattConnectionMaxSpentTimeMs =
+                secretHandshakeRetryGattConnectionMaxSpentTimeMs;
+        this.mSignalLostRetryMaxSpentTimeMs = signalLostRetryMaxSpentTimeMs;
+        this.mGattConnectionAndSecretHandshakeNoRetryGattError =
+                gattConnectionAndSecretHandshakeNoRetryGattError;
+        this.mRetrySecretHandshakeTimeout = retrySecretHandshakeTimeout;
+        this.mLogUserManualRetry = logUserManualRetry;
+        this.mPairFailureCounts = pairFailureCounts;
+        this.mCachedDeviceAddress = cachedDeviceAddress;
+        this.mPossibleCachedDeviceAddress = possibleCachedDeviceAddress;
+        this.mSameModelIdPairedDeviceCount = sameModelIdPairedDeviceCount;
+        this.mIsDeviceFinishCheckAddressFromCache = isDeviceFinishCheckAddressFromCache;
+        this.mLogPairWithCachedModelId = logPairWithCachedModelId;
+        this.mDirectConnectProfileIfModelIdInCache = directConnectProfileIfModelIdInCache;
+        this.mAcceptPasskey = acceptPasskey;
+        this.mSupportedProfileUuids = supportedProfileUuids;
+        this.mProviderInitiatesBondingIfSupported = providerInitiatesBondingIfSupported;
+        this.mAttemptDirectConnectionWhenPreviouslyBonded =
+                attemptDirectConnectionWhenPreviouslyBonded;
+        this.mAutomaticallyReconnectGattWhenNeeded = automaticallyReconnectGattWhenNeeded;
+        this.mSkipConnectingProfiles = skipConnectingProfiles;
+        this.mIgnoreUuidTimeoutAfterBonded = ignoreUuidTimeoutAfterBonded;
+        this.mSpecifyCreateBondTransportType = specifyCreateBondTransportType;
+        this.mCreateBondTransportType = createBondTransportType;
+        this.mIncreaseIntentFilterPriority = increaseIntentFilterPriority;
+        this.mEvaluatePerformance = evaluatePerformance;
+        this.mExtraLoggingInformation = extraLoggingInformation;
+        this.mEnableNamingCharacteristic = enableNamingCharacteristic;
+        this.mEnableFirmwareVersionCharacteristic = enableFirmwareVersionCharacteristic;
+        this.mKeepSameAccountKeyWrite = keepSameAccountKeyWrite;
+        this.mIsRetroactivePairing = isRetroactivePairing;
+        this.mNumSdpAttemptsAfterBonded = numSdpAttemptsAfterBonded;
+        this.mSupportHidDevice = supportHidDevice;
+        this.mEnablePairingWhileDirectlyConnecting = enablePairingWhileDirectlyConnecting;
+        this.mAcceptConsentForFastPairOne = acceptConsentForFastPairOne;
+        this.mGattConnectRetryTimeoutMillis = gattConnectRetryTimeoutMillis;
+        this.mEnable128BitCustomGattCharacteristicsId = enable128BitCustomGattCharacteristicsId;
+        this.mEnableSendExceptionStepToValidator = enableSendExceptionStepToValidator;
+        this.mEnableAdditionalDataTypeWhenActionOverBle = enableAdditionalDataTypeWhenActionOverBle;
+        this.mCheckBondStateWhenSkipConnectingProfiles = checkBondStateWhenSkipConnectingProfiles;
+        this.mHandlePasskeyConfirmationByUi = handlePasskeyConfirmationByUi;
+        this.mEnablePairFlowShowUiWithoutProfileConnection =
+                enablePairFlowShowUiWithoutProfileConnection;
+    }
+
+    /**
+     * Timeout for each GATT operation (not for the whole pairing process).
+     */
+    public int getGattOperationTimeoutSeconds() {
+        return mGattOperationTimeoutSeconds;
+    }
+
+    /**
+     * Timeout for Gatt connection operation.
+     */
+    public int getGattConnectionTimeoutSeconds() {
+        return mGattConnectionTimeoutSeconds;
+    }
+
+    /**
+     * Timeout for Bluetooth toggle.
+     */
+    public int getBluetoothToggleTimeoutSeconds() {
+        return mBluetoothToggleTimeoutSeconds;
+    }
+
+    /**
+     * Sleep time for Bluetooth toggle.
+     */
+    public int getBluetoothToggleSleepSeconds() {
+        return mBluetoothToggleSleepSeconds;
+    }
+
+    /**
+     * Timeout for classic discovery.
+     */
+    public int getClassicDiscoveryTimeoutSeconds() {
+        return mClassicDiscoveryTimeoutSeconds;
+    }
+
+    /**
+     * Number of discovery attempts allowed.
+     */
+    public int getNumDiscoverAttempts() {
+        return mNumDiscoverAttempts;
+    }
+
+    /**
+     * Sleep time between discovery retry.
+     */
+    public int getDiscoveryRetrySleepSeconds() {
+        return mDiscoveryRetrySleepSeconds;
+    }
+
+    /**
+     * Whether to ignore error incurred during discovery.
+     */
+    public boolean getIgnoreDiscoveryError() {
+        return mIgnoreDiscoveryError;
+    }
+
+    /**
+     * Timeout for Sdp.
+     */
+    public int getSdpTimeoutSeconds() {
+        return mSdpTimeoutSeconds;
+    }
+
+    /**
+     * Number of Sdp attempts allowed.
+     */
+    public int getNumSdpAttempts() {
+        return mNumSdpAttempts;
+    }
+
+    /**
+     * Number of create bond attempts allowed.
+     */
+    public int getNumCreateBondAttempts() {
+        return mNumCreateBondAttempts;
+    }
+
+    /**
+     * Number of connect attempts allowed.
+     */
+    public int getNumConnectAttempts() {
+        return mNumConnectAttempts;
+    }
+
+    /**
+     * Number of write account key attempts allowed.
+     */
+    public int getNumWriteAccountKeyAttempts() {
+        return mNumWriteAccountKeyAttempts;
+    }
+
+    /**
+     * Returns whether it is OK toggle bluetooth to retry upon failure.
+     */
+    public boolean getToggleBluetoothOnFailure() {
+        return mToggleBluetoothOnFailure;
+    }
+
+    /**
+     * Whether to get Bluetooth state using polling.
+     */
+    public boolean getBluetoothStateUsesPolling() {
+        return mBluetoothStateUsesPolling;
+    }
+
+    /**
+     * Polling time when retrieving Bluetooth state.
+     */
+    public int getBluetoothStatePollingMillis() {
+        return mBluetoothStatePollingMillis;
+    }
+
+    /**
+     * The number of times to attempt a generic operation, before giving up.
+     */
+    public int getNumAttempts() {
+        return mNumAttempts;
+    }
+
+    /**
+     * Returns whether BrEdr handover is enabled.
+     */
+    public boolean getEnableBrEdrHandover() {
+        return mEnableBrEdrHandover;
+    }
+
+    /**
+     * Returns characteristic Id for Br Handover data.
+     */
+    public short getBrHandoverDataCharacteristicId() {
+        return mBrHandoverDataCharacteristicId;
+    }
+
+    /**
+     * Returns characteristic Id for Bluethoth Sig data.
+     */
+    public short getBluetoothSigDataCharacteristicId() {
+        return mBluetoothSigDataCharacteristicId;
+    }
+
+    /**
+     * Returns characteristic Id for Firmware version.
+     */
+    public short getFirmwareVersionCharacteristicId() {
+        return mFirmwareVersionCharacteristicId;
+    }
+
+    /**
+     * Returns descripter Id for Br transport block data.
+     */
+    public short getBrTransportBlockDataDescriptorId() {
+        return mBrTransportBlockDataDescriptorId;
+    }
+
+    /**
+     * Whether to wait for Uuids after bonding.
+     */
+    public boolean getWaitForUuidsAfterBonding() {
+        return mWaitForUuidsAfterBonding;
+    }
+
+    /**
+     * Whether to get received Uuids and bonded events before close.
+     */
+    public boolean getReceiveUuidsAndBondedEventBeforeClose() {
+        return mReceiveUuidsAndBondedEventBeforeClose;
+    }
+
+    /**
+     * Timeout for remove bond operation.
+     */
+    public int getRemoveBondTimeoutSeconds() {
+        return mRemoveBondTimeoutSeconds;
+    }
+
+    /**
+     * Sleep time for remove bond operation.
+     */
+    public int getRemoveBondSleepMillis() {
+        return mRemoveBondSleepMillis;
+    }
+
+    /**
+     * This almost always succeeds (or fails) in 2-10 seconds (Taimen running O -> Nexus 6P sim).
+     */
+    public int getCreateBondTimeoutSeconds() {
+        return mCreateBondTimeoutSeconds;
+    }
+
+    /**
+     * Timeout for creating bond with Hid devices.
+     */
+    public int getHidCreateBondTimeoutSeconds() {
+        return mHidCreateBondTimeoutSeconds;
+    }
+
+    /**
+     * Timeout for get proxy operation.
+     */
+    public int getProxyTimeoutSeconds() {
+        return mProxyTimeoutSeconds;
+    }
+
+    /**
+     * Whether to reject phone book access.
+     */
+    public boolean getRejectPhonebookAccess() {
+        return mRejectPhonebookAccess;
+    }
+
+    /**
+     * Whether to reject message access.
+     */
+    public boolean getRejectMessageAccess() {
+        return mRejectMessageAccess;
+    }
+
+    /**
+     * Whether to reject sim access.
+     */
+    public boolean getRejectSimAccess() {
+        return mRejectSimAccess;
+    }
+
+    /**
+     * Sleep time for write account key operation.
+     */
+    public int getWriteAccountKeySleepMillis() {
+        return mWriteAccountKeySleepMillis;
+    }
+
+    /**
+     * Whether to skip disconneting gatt before writing account key.
+     */
+    public boolean getSkipDisconnectingGattBeforeWritingAccountKey() {
+        return mSkipDisconnectingGattBeforeWritingAccountKey;
+    }
+
+    /**
+     * Whether to get more event log for quality improvement.
+     */
+    public boolean getMoreEventLogForQuality() {
+        return mMoreEventLogForQuality;
+    }
+
+    /**
+     * Whether to retry gatt connection and secrete handshake.
+     */
+    public boolean getRetryGattConnectionAndSecretHandshake() {
+        return mRetryGattConnectionAndSecretHandshake;
+    }
+
+    /**
+     * Short Gatt connection timeoout.
+     */
+    public long getGattConnectShortTimeoutMs() {
+        return mGattConnectShortTimeoutMs;
+    }
+
+    /**
+     * Long Gatt connection timeout.
+     */
+    public long getGattConnectLongTimeoutMs() {
+        return mGattConnectLongTimeoutMs;
+    }
+
+    /**
+     * Short Timeout for Gatt connection, including retry.
+     */
+    public long getGattConnectShortTimeoutRetryMaxSpentTimeMs() {
+        return mGattConnectShortTimeoutRetryMaxSpentTimeMs;
+    }
+
+    /**
+     * Timeout for address rotation, including retry.
+     */
+    public long getAddressRotateRetryMaxSpentTimeMs() {
+        return mAddressRotateRetryMaxSpentTimeMs;
+    }
+
+    /**
+     * Returns pairing retry delay time.
+     */
+    public long getPairingRetryDelayMs() {
+        return mPairingRetryDelayMs;
+    }
+
+    /**
+     * Short timeout for secrete handshake.
+     */
+    public long getSecretHandshakeShortTimeoutMs() {
+        return mSecretHandshakeShortTimeoutMs;
+    }
+
+    /**
+     * Long timeout for secret handshake.
+     */
+    public long getSecretHandshakeLongTimeoutMs() {
+        return mSecretHandshakeLongTimeoutMs;
+    }
+
+    /**
+     * Short timeout for secret handshake, including retry.
+     */
+    public long getSecretHandshakeShortTimeoutRetryMaxSpentTimeMs() {
+        return mSecretHandshakeShortTimeoutRetryMaxSpentTimeMs;
+    }
+
+    /**
+     * Long timeout for secret handshake, including retry.
+     */
+    public long getSecretHandshakeLongTimeoutRetryMaxSpentTimeMs() {
+        return mSecretHandshakeLongTimeoutRetryMaxSpentTimeMs;
+    }
+
+    /**
+     * Number of secrete handshake retry allowed.
+     */
+    public long getSecretHandshakeRetryAttempts() {
+        return mSecretHandshakeRetryAttempts;
+    }
+
+    /**
+     * Timeout for secrete handshake and gatt connection, including retry.
+     */
+    public long getSecretHandshakeRetryGattConnectionMaxSpentTimeMs() {
+        return mSecretHandshakeRetryGattConnectionMaxSpentTimeMs;
+    }
+
+    /**
+     * Timeout for signal lost handling, including retry.
+     */
+    public long getSignalLostRetryMaxSpentTimeMs() {
+        return mSignalLostRetryMaxSpentTimeMs;
+    }
+
+    /**
+     * Returns error for gatt connection and secrete handshake, without retry.
+     */
+    public ImmutableSet<Integer> getGattConnectionAndSecretHandshakeNoRetryGattError() {
+        return mGattConnectionAndSecretHandshakeNoRetryGattError;
+    }
+
+    /**
+     * Whether to retry upon secrete handshake timeout.
+     */
+    public boolean getRetrySecretHandshakeTimeout() {
+        return mRetrySecretHandshakeTimeout;
+    }
+
+    /**
+     * Wehther to log user manual retry.
+     */
+    public boolean getLogUserManualRetry() {
+        return mLogUserManualRetry;
+    }
+
+    /**
+     * Returns number of pairing failure counts.
+     */
+    public int getPairFailureCounts() {
+        return mPairFailureCounts;
+    }
+
+    /**
+     * Returns cached device address.
+     */
+    public String getCachedDeviceAddress() {
+        return mCachedDeviceAddress;
+    }
+
+    /**
+     * Returns possible cached device address.
+     */
+    public String getPossibleCachedDeviceAddress() {
+        return mPossibleCachedDeviceAddress;
+    }
+
+    /**
+     * Returns count of paired devices from the same model Id.
+     */
+    public int getSameModelIdPairedDeviceCount() {
+        return mSameModelIdPairedDeviceCount;
+    }
+
+    /**
+     * Whether the bonded device address is in the Cache .
+     */
+    public boolean getIsDeviceFinishCheckAddressFromCache() {
+        return mIsDeviceFinishCheckAddressFromCache;
+    }
+
+    /**
+     * Whether to log pairing info when cached model Id is hit.
+     */
+    public boolean getLogPairWithCachedModelId() {
+        return mLogPairWithCachedModelId;
+    }
+
+    /**
+     * Whether to directly connnect to a profile of a device, whose model Id is in cache.
+     */
+    public boolean getDirectConnectProfileIfModelIdInCache() {
+        return mDirectConnectProfileIfModelIdInCache;
+    }
+
+    /**
+     * Whether to auto-accept
+     * {@link android.bluetooth.BluetoothDevice#PAIRING_VARIANT_PASSKEY_CONFIRMATION}.
+     * Only the Fast Pair Simulator (which runs on an Android device) sends this. Since real
+     * Bluetooth headphones don't have displays, they use secure simple pairing (no pin code
+     * confirmation; we get no pairing request broadcast at all). So we may want to turn this off in
+     * prod.
+     */
+    public boolean getAcceptPasskey() {
+        return mAcceptPasskey;
+    }
+
+    /**
+     * Returns Uuids for supported profiles.
+     */
+    @SuppressWarnings("mutable")
+    public byte[] getSupportedProfileUuids() {
+        return mSupportedProfileUuids;
+    }
+
+    /**
+     * If true, after the Key-based Pairing BLE handshake, we wait for the headphones to send a
+     * pairing request to us; if false, we send the request to them.
+     */
+    public boolean getProviderInitiatesBondingIfSupported() {
+        return mProviderInitiatesBondingIfSupported;
+    }
+
+    /**
+     * If true, the first step will be attempting to connect directly to our supported profiles when
+     * a device has previously been bonded. This will help with performance on subsequent bondings
+     * and help to increase reliability in some cases.
+     */
+    public boolean getAttemptDirectConnectionWhenPreviouslyBonded() {
+        return mAttemptDirectConnectionWhenPreviouslyBonded;
+    }
+
+    /**
+     * If true, closed Gatt connections will be reopened when they are needed again. Otherwise, they
+     * will remain closed until they are explicitly reopened.
+     */
+    public boolean getAutomaticallyReconnectGattWhenNeeded() {
+        return mAutomaticallyReconnectGattWhenNeeded;
+    }
+
+    /**
+     * If true, we'll finish the pairing process after we've created a bond instead of after
+     * connecting a profile.
+     */
+    public boolean getSkipConnectingProfiles() {
+        return mSkipConnectingProfiles;
+    }
+
+    /**
+     * If true, continues the pairing process if we've timed out due to not receiving UUIDs from the
+     * headset. We can still attempt to connect to A2DP afterwards. If false, Fast Pair will fail
+     * after this step since we're expecting to receive the UUIDs.
+     */
+    public boolean getIgnoreUuidTimeoutAfterBonded() {
+        return mIgnoreUuidTimeoutAfterBonded;
+    }
+
+    /**
+     * If true, a specific transport type will be included in the create bond request, which will be
+     * used for dual mode devices. Otherwise, we'll use the platform defined default which is
+     * BluetoothDevice.TRANSPORT_AUTO. See {@link #getCreateBondTransportType()}.
+     */
+    public boolean getSpecifyCreateBondTransportType() {
+        return mSpecifyCreateBondTransportType;
+    }
+
+    /**
+     * The transport type to use when creating a bond when
+     * {@link #getSpecifyCreateBondTransportType() is true. This should be one of
+     * BluetoothDevice.TRANSPORT_AUTO, BluetoothDevice.TRANSPORT_BREDR,
+     * or BluetoothDevice.TRANSPORT_LE.
+     */
+    public int getCreateBondTransportType() {
+        return mCreateBondTransportType;
+    }
+
+    /**
+     * Whether to increase intent filter priority.
+     */
+    public boolean getIncreaseIntentFilterPriority() {
+        return mIncreaseIntentFilterPriority;
+    }
+
+    /**
+     * Whether to evaluate performance.
+     */
+    public boolean getEvaluatePerformance() {
+        return mEvaluatePerformance;
+    }
+
+    /**
+     * Returns extra logging information.
+     */
+    @Nullable
+    public ExtraLoggingInformation getExtraLoggingInformation() {
+        return mExtraLoggingInformation;
+    }
+
+    /**
+     * Whether to enable naming characteristic.
+     */
+    public boolean getEnableNamingCharacteristic() {
+        return mEnableNamingCharacteristic;
+    }
+
+    /**
+     * Whether to enable firmware version characteristic.
+     */
+    public boolean getEnableFirmwareVersionCharacteristic() {
+        return mEnableFirmwareVersionCharacteristic;
+    }
+
+    /**
+     * If true, even Fast Pair identifies a provider have paired with the account, still writes the
+     * identified account key to the provider.
+     */
+    public boolean getKeepSameAccountKeyWrite() {
+        return mKeepSameAccountKeyWrite;
+    }
+
+    /**
+     * If true, run retroactive pairing.
+     */
+    public boolean getIsRetroactivePairing() {
+        return mIsRetroactivePairing;
+    }
+
+    /**
+     * If it's larger than 0, {@link android.bluetooth.BluetoothDevice#fetchUuidsWithSdp} would be
+     * triggered with number of attempts after device is bonded and no profiles were automatically
+     * discovered".
+     */
+    public int getNumSdpAttemptsAfterBonded() {
+        return mNumSdpAttemptsAfterBonded;
+    }
+
+    /**
+     * If true, supports HID device for fastpair.
+     */
+    public boolean getSupportHidDevice() {
+        return mSupportHidDevice;
+    }
+
+    /**
+     * If true, we'll enable the pairing behavior to handle the state transition from BOND_BONDED to
+     * BOND_BONDING when directly connecting profiles.
+     */
+    public boolean getEnablePairingWhileDirectlyConnecting() {
+        return mEnablePairingWhileDirectlyConnecting;
+    }
+
+    /**
+     * If true, we will accept the user confirmation when bonding with FastPair 1.0 devices.
+     */
+    public boolean getAcceptConsentForFastPairOne() {
+        return mAcceptConsentForFastPairOne;
+    }
+
+    /**
+     * If it's larger than 0, we will retry connecting GATT within the timeout.
+     */
+    public int getGattConnectRetryTimeoutMillis() {
+        return mGattConnectRetryTimeoutMillis;
+    }
+
+    /**
+     * If true, then uses the new custom GATT characteristics {go/fastpair-128bit-gatt}.
+     */
+    public boolean getEnable128BitCustomGattCharacteristicsId() {
+        return mEnable128BitCustomGattCharacteristicsId;
+    }
+
+    /**
+     * If true, then sends the internal pair step or Exception to Validator by Intent.
+     */
+    public boolean getEnableSendExceptionStepToValidator() {
+        return mEnableSendExceptionStepToValidator;
+    }
+
+    /**
+     * If true, then adds the additional data type in the handshake packet when action over BLE.
+     */
+    public boolean getEnableAdditionalDataTypeWhenActionOverBle() {
+        return mEnableAdditionalDataTypeWhenActionOverBle;
+    }
+
+    /**
+     * If true, then checks the bond state when skips connecting profiles in the pairing shortcut.
+     */
+    public boolean getCheckBondStateWhenSkipConnectingProfiles() {
+        return mCheckBondStateWhenSkipConnectingProfiles;
+    }
+
+    /**
+     * If true, the passkey confirmation will be handled by the half-sheet UI.
+     */
+    public boolean getHandlePasskeyConfirmationByUi() {
+        return mHandlePasskeyConfirmationByUi;
+    }
+
+    /**
+     * If true, then use pair flow to show ui when pairing is finished without connecting profile.
+     */
+    public boolean getEnablePairFlowShowUiWithoutProfileConnection() {
+        return mEnablePairFlowShowUiWithoutProfileConnection;
+    }
+
+    @Override
+    public String toString() {
+        return "Preferences{"
+                + "gattOperationTimeoutSeconds=" + mGattOperationTimeoutSeconds + ", "
+                + "gattConnectionTimeoutSeconds=" + mGattConnectionTimeoutSeconds + ", "
+                + "bluetoothToggleTimeoutSeconds=" + mBluetoothToggleTimeoutSeconds + ", "
+                + "bluetoothToggleSleepSeconds=" + mBluetoothToggleSleepSeconds + ", "
+                + "classicDiscoveryTimeoutSeconds=" + mClassicDiscoveryTimeoutSeconds + ", "
+                + "numDiscoverAttempts=" + mNumDiscoverAttempts + ", "
+                + "discoveryRetrySleepSeconds=" + mDiscoveryRetrySleepSeconds + ", "
+                + "ignoreDiscoveryError=" + mIgnoreDiscoveryError + ", "
+                + "sdpTimeoutSeconds=" + mSdpTimeoutSeconds + ", "
+                + "numSdpAttempts=" + mNumSdpAttempts + ", "
+                + "numCreateBondAttempts=" + mNumCreateBondAttempts + ", "
+                + "numConnectAttempts=" + mNumConnectAttempts + ", "
+                + "numWriteAccountKeyAttempts=" + mNumWriteAccountKeyAttempts + ", "
+                + "toggleBluetoothOnFailure=" + mToggleBluetoothOnFailure + ", "
+                + "bluetoothStateUsesPolling=" + mBluetoothStateUsesPolling + ", "
+                + "bluetoothStatePollingMillis=" + mBluetoothStatePollingMillis + ", "
+                + "numAttempts=" + mNumAttempts + ", "
+                + "enableBrEdrHandover=" + mEnableBrEdrHandover + ", "
+                + "brHandoverDataCharacteristicId=" + mBrHandoverDataCharacteristicId + ", "
+                + "bluetoothSigDataCharacteristicId=" + mBluetoothSigDataCharacteristicId + ", "
+                + "firmwareVersionCharacteristicId=" + mFirmwareVersionCharacteristicId + ", "
+                + "brTransportBlockDataDescriptorId=" + mBrTransportBlockDataDescriptorId + ", "
+                + "waitForUuidsAfterBonding=" + mWaitForUuidsAfterBonding + ", "
+                + "receiveUuidsAndBondedEventBeforeClose=" + mReceiveUuidsAndBondedEventBeforeClose
+                + ", "
+                + "removeBondTimeoutSeconds=" + mRemoveBondTimeoutSeconds + ", "
+                + "removeBondSleepMillis=" + mRemoveBondSleepMillis + ", "
+                + "createBondTimeoutSeconds=" + mCreateBondTimeoutSeconds + ", "
+                + "hidCreateBondTimeoutSeconds=" + mHidCreateBondTimeoutSeconds + ", "
+                + "proxyTimeoutSeconds=" + mProxyTimeoutSeconds + ", "
+                + "rejectPhonebookAccess=" + mRejectPhonebookAccess + ", "
+                + "rejectMessageAccess=" + mRejectMessageAccess + ", "
+                + "rejectSimAccess=" + mRejectSimAccess + ", "
+                + "writeAccountKeySleepMillis=" + mWriteAccountKeySleepMillis + ", "
+                + "skipDisconnectingGattBeforeWritingAccountKey="
+                + mSkipDisconnectingGattBeforeWritingAccountKey + ", "
+                + "moreEventLogForQuality=" + mMoreEventLogForQuality + ", "
+                + "retryGattConnectionAndSecretHandshake=" + mRetryGattConnectionAndSecretHandshake
+                + ", "
+                + "gattConnectShortTimeoutMs=" + mGattConnectShortTimeoutMs + ", "
+                + "gattConnectLongTimeoutMs=" + mGattConnectLongTimeoutMs + ", "
+                + "gattConnectShortTimeoutRetryMaxSpentTimeMs="
+                + mGattConnectShortTimeoutRetryMaxSpentTimeMs + ", "
+                + "addressRotateRetryMaxSpentTimeMs=" + mAddressRotateRetryMaxSpentTimeMs + ", "
+                + "pairingRetryDelayMs=" + mPairingRetryDelayMs + ", "
+                + "secretHandshakeShortTimeoutMs=" + mSecretHandshakeShortTimeoutMs + ", "
+                + "secretHandshakeLongTimeoutMs=" + mSecretHandshakeLongTimeoutMs + ", "
+                + "secretHandshakeShortTimeoutRetryMaxSpentTimeMs="
+                + mSecretHandshakeShortTimeoutRetryMaxSpentTimeMs + ", "
+                + "secretHandshakeLongTimeoutRetryMaxSpentTimeMs="
+                + mSecretHandshakeLongTimeoutRetryMaxSpentTimeMs + ", "
+                + "secretHandshakeRetryAttempts=" + mSecretHandshakeRetryAttempts + ", "
+                + "secretHandshakeRetryGattConnectionMaxSpentTimeMs="
+                + mSecretHandshakeRetryGattConnectionMaxSpentTimeMs + ", "
+                + "signalLostRetryMaxSpentTimeMs=" + mSignalLostRetryMaxSpentTimeMs + ", "
+                + "gattConnectionAndSecretHandshakeNoRetryGattError="
+                + mGattConnectionAndSecretHandshakeNoRetryGattError + ", "
+                + "retrySecretHandshakeTimeout=" + mRetrySecretHandshakeTimeout + ", "
+                + "logUserManualRetry=" + mLogUserManualRetry + ", "
+                + "pairFailureCounts=" + mPairFailureCounts + ", "
+                + "cachedDeviceAddress=" + mCachedDeviceAddress + ", "
+                + "possibleCachedDeviceAddress=" + mPossibleCachedDeviceAddress + ", "
+                + "sameModelIdPairedDeviceCount=" + mSameModelIdPairedDeviceCount + ", "
+                + "isDeviceFinishCheckAddressFromCache=" + mIsDeviceFinishCheckAddressFromCache
+                + ", "
+                + "logPairWithCachedModelId=" + mLogPairWithCachedModelId + ", "
+                + "directConnectProfileIfModelIdInCache=" + mDirectConnectProfileIfModelIdInCache
+                + ", "
+                + "acceptPasskey=" + mAcceptPasskey + ", "
+                + "supportedProfileUuids=" + Arrays.toString(mSupportedProfileUuids) + ", "
+                + "providerInitiatesBondingIfSupported=" + mProviderInitiatesBondingIfSupported
+                + ", "
+                + "attemptDirectConnectionWhenPreviouslyBonded="
+                + mAttemptDirectConnectionWhenPreviouslyBonded + ", "
+                + "automaticallyReconnectGattWhenNeeded=" + mAutomaticallyReconnectGattWhenNeeded
+                + ", "
+                + "skipConnectingProfiles=" + mSkipConnectingProfiles + ", "
+                + "ignoreUuidTimeoutAfterBonded=" + mIgnoreUuidTimeoutAfterBonded + ", "
+                + "specifyCreateBondTransportType=" + mSpecifyCreateBondTransportType + ", "
+                + "createBondTransportType=" + mCreateBondTransportType + ", "
+                + "increaseIntentFilterPriority=" + mIncreaseIntentFilterPriority + ", "
+                + "evaluatePerformance=" + mEvaluatePerformance + ", "
+                + "extraLoggingInformation=" + mExtraLoggingInformation + ", "
+                + "enableNamingCharacteristic=" + mEnableNamingCharacteristic + ", "
+                + "enableFirmwareVersionCharacteristic=" + mEnableFirmwareVersionCharacteristic
+                + ", "
+                + "keepSameAccountKeyWrite=" + mKeepSameAccountKeyWrite + ", "
+                + "isRetroactivePairing=" + mIsRetroactivePairing + ", "
+                + "numSdpAttemptsAfterBonded=" + mNumSdpAttemptsAfterBonded + ", "
+                + "supportHidDevice=" + mSupportHidDevice + ", "
+                + "enablePairingWhileDirectlyConnecting=" + mEnablePairingWhileDirectlyConnecting
+                + ", "
+                + "acceptConsentForFastPairOne=" + mAcceptConsentForFastPairOne + ", "
+                + "gattConnectRetryTimeoutMillis=" + mGattConnectRetryTimeoutMillis + ", "
+                + "enable128BitCustomGattCharacteristicsId="
+                + mEnable128BitCustomGattCharacteristicsId + ", "
+                + "enableSendExceptionStepToValidator=" + mEnableSendExceptionStepToValidator + ", "
+                + "enableAdditionalDataTypeWhenActionOverBle="
+                + mEnableAdditionalDataTypeWhenActionOverBle + ", "
+                + "checkBondStateWhenSkipConnectingProfiles="
+                + mCheckBondStateWhenSkipConnectingProfiles + ", "
+                + "handlePasskeyConfirmationByUi=" + mHandlePasskeyConfirmationByUi + ", "
+                + "enablePairFlowShowUiWithoutProfileConnection="
+                + mEnablePairFlowShowUiWithoutProfileConnection
+                + "}";
+    }
+
+    /**
+     * Converts an instance to a builder.
+     */
+    public Builder toBuilder() {
+        return new Preferences.Builder(this);
+    }
+
+    /**
+     * Constructs a builder.
+     */
+    public static Builder builder() {
+        return new Preferences.Builder()
+                .setGattOperationTimeoutSeconds(3)
+                .setGattConnectionTimeoutSeconds(15)
+                .setBluetoothToggleTimeoutSeconds(10)
+                .setBluetoothToggleSleepSeconds(2)
+                .setClassicDiscoveryTimeoutSeconds(10)
+                .setNumDiscoverAttempts(3)
+                .setDiscoveryRetrySleepSeconds(1)
+                .setIgnoreDiscoveryError(false)
+                .setSdpTimeoutSeconds(10)
+                .setNumSdpAttempts(3)
+                .setNumCreateBondAttempts(3)
+                .setNumConnectAttempts(1)
+                .setNumWriteAccountKeyAttempts(3)
+                .setToggleBluetoothOnFailure(false)
+                .setBluetoothStateUsesPolling(true)
+                .setBluetoothStatePollingMillis(1000)
+                .setNumAttempts(2)
+                .setEnableBrEdrHandover(false)
+                .setBrHandoverDataCharacteristicId(get16BitUuid(
+                        Constants.TransportDiscoveryService.BrHandoverDataCharacteristic.ID))
+                .setBluetoothSigDataCharacteristicId(get16BitUuid(
+                        Constants.TransportDiscoveryService.BluetoothSigDataCharacteristic.ID))
+                .setFirmwareVersionCharacteristicId(get16BitUuid(FirmwareVersionCharacteristic.ID))
+                .setBrTransportBlockDataDescriptorId(
+                        get16BitUuid(
+                                Constants.TransportDiscoveryService.BluetoothSigDataCharacteristic
+                                        .BrTransportBlockDataDescriptor.ID))
+                .setWaitForUuidsAfterBonding(true)
+                .setReceiveUuidsAndBondedEventBeforeClose(true)
+                .setRemoveBondTimeoutSeconds(5)
+                .setRemoveBondSleepMillis(1000)
+                .setCreateBondTimeoutSeconds(15)
+                .setHidCreateBondTimeoutSeconds(40)
+                .setProxyTimeoutSeconds(2)
+                .setRejectPhonebookAccess(false)
+                .setRejectMessageAccess(false)
+                .setRejectSimAccess(false)
+                .setAcceptPasskey(true)
+                .setSupportedProfileUuids(Constants.getSupportedProfiles())
+                .setWriteAccountKeySleepMillis(2000)
+                .setProviderInitiatesBondingIfSupported(false)
+                .setAttemptDirectConnectionWhenPreviouslyBonded(false)
+                .setAutomaticallyReconnectGattWhenNeeded(false)
+                .setSkipDisconnectingGattBeforeWritingAccountKey(false)
+                .setSkipConnectingProfiles(false)
+                .setIgnoreUuidTimeoutAfterBonded(false)
+                .setSpecifyCreateBondTransportType(false)
+                .setCreateBondTransportType(0 /*BluetoothDevice.TRANSPORT_AUTO*/)
+                .setIncreaseIntentFilterPriority(true)
+                .setEvaluatePerformance(false)
+                .setKeepSameAccountKeyWrite(true)
+                .setEnableNamingCharacteristic(false)
+                .setEnableFirmwareVersionCharacteristic(false)
+                .setIsRetroactivePairing(false)
+                .setNumSdpAttemptsAfterBonded(1)
+                .setSupportHidDevice(false)
+                .setEnablePairingWhileDirectlyConnecting(true)
+                .setAcceptConsentForFastPairOne(true)
+                .setGattConnectRetryTimeoutMillis(0)
+                .setEnable128BitCustomGattCharacteristicsId(true)
+                .setEnableSendExceptionStepToValidator(true)
+                .setEnableAdditionalDataTypeWhenActionOverBle(true)
+                .setCheckBondStateWhenSkipConnectingProfiles(true)
+                .setHandlePasskeyConfirmationByUi(false)
+                .setMoreEventLogForQuality(true)
+                .setRetryGattConnectionAndSecretHandshake(true)
+                .setGattConnectShortTimeoutMs(7000)
+                .setGattConnectLongTimeoutMs(15000)
+                .setGattConnectShortTimeoutRetryMaxSpentTimeMs(10000)
+                .setAddressRotateRetryMaxSpentTimeMs(15000)
+                .setPairingRetryDelayMs(100)
+                .setSecretHandshakeShortTimeoutMs(3000)
+                .setSecretHandshakeLongTimeoutMs(10000)
+                .setSecretHandshakeShortTimeoutRetryMaxSpentTimeMs(5000)
+                .setSecretHandshakeLongTimeoutRetryMaxSpentTimeMs(7000)
+                .setSecretHandshakeRetryAttempts(3)
+                .setSecretHandshakeRetryGattConnectionMaxSpentTimeMs(15000)
+                .setSignalLostRetryMaxSpentTimeMs(15000)
+                .setGattConnectionAndSecretHandshakeNoRetryGattError(ImmutableSet.of())
+                .setRetrySecretHandshakeTimeout(false)
+                .setLogUserManualRetry(true)
+                .setPairFailureCounts(0)
+                .setEnablePairFlowShowUiWithoutProfileConnection(true)
+                .setPairFailureCounts(0)
+                .setLogPairWithCachedModelId(true)
+                .setDirectConnectProfileIfModelIdInCache(false)
+                .setCachedDeviceAddress("")
+                .setPossibleCachedDeviceAddress("")
+                .setSameModelIdPairedDeviceCount(0)
+                .setIsDeviceFinishCheckAddressFromCache(true);
+    }
+
+    /**
+     * Constructs a builder from GmsLog.
+     */
+    // TODO(b/206668142): remove this builder once api is ready.
+    public static Builder builderFromGmsLog() {
+        return new Preferences.Builder()
+                .setGattOperationTimeoutSeconds(10)
+                .setGattConnectionTimeoutSeconds(15)
+                .setBluetoothToggleTimeoutSeconds(10)
+                .setBluetoothToggleSleepSeconds(2)
+                .setClassicDiscoveryTimeoutSeconds(13)
+                .setNumDiscoverAttempts(3)
+                .setDiscoveryRetrySleepSeconds(1)
+                .setIgnoreDiscoveryError(true)
+                .setSdpTimeoutSeconds(10)
+                .setNumSdpAttempts(0)
+                .setNumCreateBondAttempts(3)
+                .setNumConnectAttempts(2)
+                .setNumWriteAccountKeyAttempts(3)
+                .setToggleBluetoothOnFailure(false)
+                .setBluetoothStateUsesPolling(true)
+                .setBluetoothStatePollingMillis(1000)
+                .setNumAttempts(2)
+                .setEnableBrEdrHandover(false)
+                .setBrHandoverDataCharacteristicId((short) 11265)
+                .setBluetoothSigDataCharacteristicId((short) 11266)
+                .setFirmwareVersionCharacteristicId((short) 10790)
+                .setBrTransportBlockDataDescriptorId((short) 11267)
+                .setWaitForUuidsAfterBonding(true)
+                .setReceiveUuidsAndBondedEventBeforeClose(true)
+                .setRemoveBondTimeoutSeconds(5)
+                .setRemoveBondSleepMillis(1000)
+                .setCreateBondTimeoutSeconds(15)
+                .setHidCreateBondTimeoutSeconds(40)
+                .setProxyTimeoutSeconds(2)
+                .setRejectPhonebookAccess(false)
+                .setRejectMessageAccess(false)
+                .setRejectSimAccess(false)
+                .setAcceptPasskey(true)
+                .setSupportedProfileUuids(Constants.getSupportedProfiles())
+                .setWriteAccountKeySleepMillis(2000)
+                .setProviderInitiatesBondingIfSupported(false)
+                .setAttemptDirectConnectionWhenPreviouslyBonded(true)
+                .setAutomaticallyReconnectGattWhenNeeded(true)
+                .setSkipDisconnectingGattBeforeWritingAccountKey(true)
+                .setSkipConnectingProfiles(false)
+                .setIgnoreUuidTimeoutAfterBonded(true)
+                .setSpecifyCreateBondTransportType(false)
+                .setCreateBondTransportType(0 /*BluetoothDevice.TRANSPORT_AUTO*/)
+                .setIncreaseIntentFilterPriority(true)
+                .setEvaluatePerformance(true)
+                .setKeepSameAccountKeyWrite(true)
+                .setEnableNamingCharacteristic(true)
+                .setEnableFirmwareVersionCharacteristic(true)
+                .setIsRetroactivePairing(false)
+                .setNumSdpAttemptsAfterBonded(1)
+                .setSupportHidDevice(false)
+                .setEnablePairingWhileDirectlyConnecting(true)
+                .setAcceptConsentForFastPairOne(true)
+                .setGattConnectRetryTimeoutMillis(18000)
+                .setEnable128BitCustomGattCharacteristicsId(true)
+                .setEnableSendExceptionStepToValidator(true)
+                .setEnableAdditionalDataTypeWhenActionOverBle(true)
+                .setCheckBondStateWhenSkipConnectingProfiles(true)
+                .setHandlePasskeyConfirmationByUi(false)
+                .setMoreEventLogForQuality(true)
+                .setRetryGattConnectionAndSecretHandshake(true)
+                .setGattConnectShortTimeoutMs(7000)
+                .setGattConnectLongTimeoutMs(15000)
+                .setGattConnectShortTimeoutRetryMaxSpentTimeMs(10000)
+                .setAddressRotateRetryMaxSpentTimeMs(15000)
+                .setPairingRetryDelayMs(100)
+                .setSecretHandshakeShortTimeoutMs(3000)
+                .setSecretHandshakeLongTimeoutMs(10000)
+                .setSecretHandshakeShortTimeoutRetryMaxSpentTimeMs(5000)
+                .setSecretHandshakeLongTimeoutRetryMaxSpentTimeMs(7000)
+                .setSecretHandshakeRetryAttempts(3)
+                .setSecretHandshakeRetryGattConnectionMaxSpentTimeMs(15000)
+                .setSignalLostRetryMaxSpentTimeMs(15000)
+                .setGattConnectionAndSecretHandshakeNoRetryGattError(ImmutableSet.of(257))
+                .setRetrySecretHandshakeTimeout(false)
+                .setLogUserManualRetry(true)
+                .setPairFailureCounts(0)
+                .setEnablePairFlowShowUiWithoutProfileConnection(true)
+                .setPairFailureCounts(0)
+                .setLogPairWithCachedModelId(true)
+                .setDirectConnectProfileIfModelIdInCache(true)
+                .setCachedDeviceAddress("")
+                .setPossibleCachedDeviceAddress("")
+                .setSameModelIdPairedDeviceCount(0)
+                .setIsDeviceFinishCheckAddressFromCache(true);
+    }
+
+    /**
+     * Preferences builder.
+     */
+    public static class Builder {
+
+        private int mGattOperationTimeoutSeconds;
+        private int mGattConnectionTimeoutSeconds;
+        private int mBluetoothToggleTimeoutSeconds;
+        private int mBluetoothToggleSleepSeconds;
+        private int mClassicDiscoveryTimeoutSeconds;
+        private int mNumDiscoverAttempts;
+        private int mDiscoveryRetrySleepSeconds;
+        private boolean mIgnoreDiscoveryError;
+        private int mSdpTimeoutSeconds;
+        private int mNumSdpAttempts;
+        private int mNumCreateBondAttempts;
+        private int mNumConnectAttempts;
+        private int mNumWriteAccountKeyAttempts;
+        private boolean mToggleBluetoothOnFailure;
+        private boolean mBluetoothStateUsesPolling;
+        private int mBluetoothStatePollingMillis;
+        private int mNumAttempts;
+        private boolean mEnableBrEdrHandover;
+        private short mBrHandoverDataCharacteristicId;
+        private short mBluetoothSigDataCharacteristicId;
+        private short mFirmwareVersionCharacteristicId;
+        private short mBrTransportBlockDataDescriptorId;
+        private boolean mWaitForUuidsAfterBonding;
+        private boolean mReceiveUuidsAndBondedEventBeforeClose;
+        private int mRemoveBondTimeoutSeconds;
+        private int mRemoveBondSleepMillis;
+        private int mCreateBondTimeoutSeconds;
+        private int mHidCreateBondTimeoutSeconds;
+        private int mProxyTimeoutSeconds;
+        private boolean mRejectPhonebookAccess;
+        private boolean mRejectMessageAccess;
+        private boolean mRejectSimAccess;
+        private int mWriteAccountKeySleepMillis;
+        private boolean mSkipDisconnectingGattBeforeWritingAccountKey;
+        private boolean mMoreEventLogForQuality;
+        private boolean mRetryGattConnectionAndSecretHandshake;
+        private long mGattConnectShortTimeoutMs;
+        private long mGattConnectLongTimeoutMs;
+        private long mGattConnectShortTimeoutRetryMaxSpentTimeMs;
+        private long mAddressRotateRetryMaxSpentTimeMs;
+        private long mPairingRetryDelayMs;
+        private long mSecretHandshakeShortTimeoutMs;
+        private long mSecretHandshakeLongTimeoutMs;
+        private long mSecretHandshakeShortTimeoutRetryMaxSpentTimeMs;
+        private long mSecretHandshakeLongTimeoutRetryMaxSpentTimeMs;
+        private long mSecretHandshakeRetryAttempts;
+        private long mSecretHandshakeRetryGattConnectionMaxSpentTimeMs;
+        private long mSignalLostRetryMaxSpentTimeMs;
+        private ImmutableSet<Integer> mGattConnectionAndSecretHandshakeNoRetryGattError;
+        private boolean mRetrySecretHandshakeTimeout;
+        private boolean mLogUserManualRetry;
+        private int mPairFailureCounts;
+        private String mCachedDeviceAddress;
+        private String mPossibleCachedDeviceAddress;
+        private int mSameModelIdPairedDeviceCount;
+        private boolean mIsDeviceFinishCheckAddressFromCache;
+        private boolean mLogPairWithCachedModelId;
+        private boolean mDirectConnectProfileIfModelIdInCache;
+        private boolean mAcceptPasskey;
+        private byte[] mSupportedProfileUuids;
+        private boolean mProviderInitiatesBondingIfSupported;
+        private boolean mAttemptDirectConnectionWhenPreviouslyBonded;
+        private boolean mAutomaticallyReconnectGattWhenNeeded;
+        private boolean mSkipConnectingProfiles;
+        private boolean mIgnoreUuidTimeoutAfterBonded;
+        private boolean mSpecifyCreateBondTransportType;
+        private int mCreateBondTransportType;
+        private boolean mIncreaseIntentFilterPriority;
+        private boolean mEvaluatePerformance;
+        private Preferences.ExtraLoggingInformation mExtraLoggingInformation;
+        private boolean mEnableNamingCharacteristic;
+        private boolean mEnableFirmwareVersionCharacteristic;
+        private boolean mKeepSameAccountKeyWrite;
+        private boolean mIsRetroactivePairing;
+        private int mNumSdpAttemptsAfterBonded;
+        private boolean mSupportHidDevice;
+        private boolean mEnablePairingWhileDirectlyConnecting;
+        private boolean mAcceptConsentForFastPairOne;
+        private int mGattConnectRetryTimeoutMillis;
+        private boolean mEnable128BitCustomGattCharacteristicsId;
+        private boolean mEnableSendExceptionStepToValidator;
+        private boolean mEnableAdditionalDataTypeWhenActionOverBle;
+        private boolean mCheckBondStateWhenSkipConnectingProfiles;
+        private boolean mHandlePasskeyConfirmationByUi;
+        private boolean mEnablePairFlowShowUiWithoutProfileConnection;
+
+        private Builder() {
+        }
+
+        private Builder(Preferences source) {
+            this.mGattOperationTimeoutSeconds = source.getGattOperationTimeoutSeconds();
+            this.mGattConnectionTimeoutSeconds = source.getGattConnectionTimeoutSeconds();
+            this.mBluetoothToggleTimeoutSeconds = source.getBluetoothToggleTimeoutSeconds();
+            this.mBluetoothToggleSleepSeconds = source.getBluetoothToggleSleepSeconds();
+            this.mClassicDiscoveryTimeoutSeconds = source.getClassicDiscoveryTimeoutSeconds();
+            this.mNumDiscoverAttempts = source.getNumDiscoverAttempts();
+            this.mDiscoveryRetrySleepSeconds = source.getDiscoveryRetrySleepSeconds();
+            this.mIgnoreDiscoveryError = source.getIgnoreDiscoveryError();
+            this.mSdpTimeoutSeconds = source.getSdpTimeoutSeconds();
+            this.mNumSdpAttempts = source.getNumSdpAttempts();
+            this.mNumCreateBondAttempts = source.getNumCreateBondAttempts();
+            this.mNumConnectAttempts = source.getNumConnectAttempts();
+            this.mNumWriteAccountKeyAttempts = source.getNumWriteAccountKeyAttempts();
+            this.mToggleBluetoothOnFailure = source.getToggleBluetoothOnFailure();
+            this.mBluetoothStateUsesPolling = source.getBluetoothStateUsesPolling();
+            this.mBluetoothStatePollingMillis = source.getBluetoothStatePollingMillis();
+            this.mNumAttempts = source.getNumAttempts();
+            this.mEnableBrEdrHandover = source.getEnableBrEdrHandover();
+            this.mBrHandoverDataCharacteristicId = source.getBrHandoverDataCharacteristicId();
+            this.mBluetoothSigDataCharacteristicId = source.getBluetoothSigDataCharacteristicId();
+            this.mFirmwareVersionCharacteristicId = source.getFirmwareVersionCharacteristicId();
+            this.mBrTransportBlockDataDescriptorId = source.getBrTransportBlockDataDescriptorId();
+            this.mWaitForUuidsAfterBonding = source.getWaitForUuidsAfterBonding();
+            this.mReceiveUuidsAndBondedEventBeforeClose = source
+                    .getReceiveUuidsAndBondedEventBeforeClose();
+            this.mRemoveBondTimeoutSeconds = source.getRemoveBondTimeoutSeconds();
+            this.mRemoveBondSleepMillis = source.getRemoveBondSleepMillis();
+            this.mCreateBondTimeoutSeconds = source.getCreateBondTimeoutSeconds();
+            this.mHidCreateBondTimeoutSeconds = source.getHidCreateBondTimeoutSeconds();
+            this.mProxyTimeoutSeconds = source.getProxyTimeoutSeconds();
+            this.mRejectPhonebookAccess = source.getRejectPhonebookAccess();
+            this.mRejectMessageAccess = source.getRejectMessageAccess();
+            this.mRejectSimAccess = source.getRejectSimAccess();
+            this.mWriteAccountKeySleepMillis = source.getWriteAccountKeySleepMillis();
+            this.mSkipDisconnectingGattBeforeWritingAccountKey = source
+                    .getSkipDisconnectingGattBeforeWritingAccountKey();
+            this.mMoreEventLogForQuality = source.getMoreEventLogForQuality();
+            this.mRetryGattConnectionAndSecretHandshake = source
+                    .getRetryGattConnectionAndSecretHandshake();
+            this.mGattConnectShortTimeoutMs = source.getGattConnectShortTimeoutMs();
+            this.mGattConnectLongTimeoutMs = source.getGattConnectLongTimeoutMs();
+            this.mGattConnectShortTimeoutRetryMaxSpentTimeMs = source
+                    .getGattConnectShortTimeoutRetryMaxSpentTimeMs();
+            this.mAddressRotateRetryMaxSpentTimeMs = source.getAddressRotateRetryMaxSpentTimeMs();
+            this.mPairingRetryDelayMs = source.getPairingRetryDelayMs();
+            this.mSecretHandshakeShortTimeoutMs = source.getSecretHandshakeShortTimeoutMs();
+            this.mSecretHandshakeLongTimeoutMs = source.getSecretHandshakeLongTimeoutMs();
+            this.mSecretHandshakeShortTimeoutRetryMaxSpentTimeMs = source
+                    .getSecretHandshakeShortTimeoutRetryMaxSpentTimeMs();
+            this.mSecretHandshakeLongTimeoutRetryMaxSpentTimeMs = source
+                    .getSecretHandshakeLongTimeoutRetryMaxSpentTimeMs();
+            this.mSecretHandshakeRetryAttempts = source.getSecretHandshakeRetryAttempts();
+            this.mSecretHandshakeRetryGattConnectionMaxSpentTimeMs = source
+                    .getSecretHandshakeRetryGattConnectionMaxSpentTimeMs();
+            this.mSignalLostRetryMaxSpentTimeMs = source.getSignalLostRetryMaxSpentTimeMs();
+            this.mGattConnectionAndSecretHandshakeNoRetryGattError = source
+                    .getGattConnectionAndSecretHandshakeNoRetryGattError();
+            this.mRetrySecretHandshakeTimeout = source.getRetrySecretHandshakeTimeout();
+            this.mLogUserManualRetry = source.getLogUserManualRetry();
+            this.mPairFailureCounts = source.getPairFailureCounts();
+            this.mCachedDeviceAddress = source.getCachedDeviceAddress();
+            this.mPossibleCachedDeviceAddress = source.getPossibleCachedDeviceAddress();
+            this.mSameModelIdPairedDeviceCount = source.getSameModelIdPairedDeviceCount();
+            this.mIsDeviceFinishCheckAddressFromCache = source
+                    .getIsDeviceFinishCheckAddressFromCache();
+            this.mLogPairWithCachedModelId = source.getLogPairWithCachedModelId();
+            this.mDirectConnectProfileIfModelIdInCache = source
+                    .getDirectConnectProfileIfModelIdInCache();
+            this.mAcceptPasskey = source.getAcceptPasskey();
+            this.mSupportedProfileUuids = source.getSupportedProfileUuids();
+            this.mProviderInitiatesBondingIfSupported = source
+                    .getProviderInitiatesBondingIfSupported();
+            this.mAttemptDirectConnectionWhenPreviouslyBonded = source
+                    .getAttemptDirectConnectionWhenPreviouslyBonded();
+            this.mAutomaticallyReconnectGattWhenNeeded = source
+                    .getAutomaticallyReconnectGattWhenNeeded();
+            this.mSkipConnectingProfiles = source.getSkipConnectingProfiles();
+            this.mIgnoreUuidTimeoutAfterBonded = source.getIgnoreUuidTimeoutAfterBonded();
+            this.mSpecifyCreateBondTransportType = source.getSpecifyCreateBondTransportType();
+            this.mCreateBondTransportType = source.getCreateBondTransportType();
+            this.mIncreaseIntentFilterPriority = source.getIncreaseIntentFilterPriority();
+            this.mEvaluatePerformance = source.getEvaluatePerformance();
+            this.mExtraLoggingInformation = source.getExtraLoggingInformation();
+            this.mEnableNamingCharacteristic = source.getEnableNamingCharacteristic();
+            this.mEnableFirmwareVersionCharacteristic = source
+                    .getEnableFirmwareVersionCharacteristic();
+            this.mKeepSameAccountKeyWrite = source.getKeepSameAccountKeyWrite();
+            this.mIsRetroactivePairing = source.getIsRetroactivePairing();
+            this.mNumSdpAttemptsAfterBonded = source.getNumSdpAttemptsAfterBonded();
+            this.mSupportHidDevice = source.getSupportHidDevice();
+            this.mEnablePairingWhileDirectlyConnecting = source
+                    .getEnablePairingWhileDirectlyConnecting();
+            this.mAcceptConsentForFastPairOne = source.getAcceptConsentForFastPairOne();
+            this.mGattConnectRetryTimeoutMillis = source.getGattConnectRetryTimeoutMillis();
+            this.mEnable128BitCustomGattCharacteristicsId = source
+                    .getEnable128BitCustomGattCharacteristicsId();
+            this.mEnableSendExceptionStepToValidator = source
+                    .getEnableSendExceptionStepToValidator();
+            this.mEnableAdditionalDataTypeWhenActionOverBle = source
+                    .getEnableAdditionalDataTypeWhenActionOverBle();
+            this.mCheckBondStateWhenSkipConnectingProfiles = source
+                    .getCheckBondStateWhenSkipConnectingProfiles();
+            this.mHandlePasskeyConfirmationByUi = source.getHandlePasskeyConfirmationByUi();
+            this.mEnablePairFlowShowUiWithoutProfileConnection = source
+                    .getEnablePairFlowShowUiWithoutProfileConnection();
+        }
+
+        /**
+         * Set gatt operation timeout.
+         */
+        public Builder setGattOperationTimeoutSeconds(int value) {
+            this.mGattOperationTimeoutSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set gatt connection timeout.
+         */
+        public Builder setGattConnectionTimeoutSeconds(int value) {
+            this.mGattConnectionTimeoutSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set bluetooth toggle timeout.
+         */
+        public Builder setBluetoothToggleTimeoutSeconds(int value) {
+            this.mBluetoothToggleTimeoutSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set bluetooth toggle sleep time.
+         */
+        public Builder setBluetoothToggleSleepSeconds(int value) {
+            this.mBluetoothToggleSleepSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set classic discovery timeout.
+         */
+        public Builder setClassicDiscoveryTimeoutSeconds(int value) {
+            this.mClassicDiscoveryTimeoutSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set number of discover attempts allowed.
+         */
+        public Builder setNumDiscoverAttempts(int value) {
+            this.mNumDiscoverAttempts = value;
+            return this;
+        }
+
+        /**
+         * Set discovery retry sleep time.
+         */
+        public Builder setDiscoveryRetrySleepSeconds(int value) {
+            this.mDiscoveryRetrySleepSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set whether to ignore discovery error.
+         */
+        public Builder setIgnoreDiscoveryError(boolean value) {
+            this.mIgnoreDiscoveryError = value;
+            return this;
+        }
+
+        /**
+         * Set sdp timeout.
+         */
+        public Builder setSdpTimeoutSeconds(int value) {
+            this.mSdpTimeoutSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set number of sdp attempts allowed.
+         */
+        public Builder setNumSdpAttempts(int value) {
+            this.mNumSdpAttempts = value;
+            return this;
+        }
+
+        /**
+         * Set number of allowed attempts to create bond.
+         */
+        public Builder setNumCreateBondAttempts(int value) {
+            this.mNumCreateBondAttempts = value;
+            return this;
+        }
+
+        /**
+         * Set number of connect attempts allowed.
+         */
+        public Builder setNumConnectAttempts(int value) {
+            this.mNumConnectAttempts = value;
+            return this;
+        }
+
+        /**
+         * Set number of write account key attempts allowed.
+         */
+        public Builder setNumWriteAccountKeyAttempts(int value) {
+            this.mNumWriteAccountKeyAttempts = value;
+            return this;
+        }
+
+        /**
+         * Set whether to retry by bluetooth toggle on failure.
+         */
+        public Builder setToggleBluetoothOnFailure(boolean value) {
+            this.mToggleBluetoothOnFailure = value;
+            return this;
+        }
+
+        /**
+         * Set whether to use polling to set bluetooth status.
+         */
+        public Builder setBluetoothStateUsesPolling(boolean value) {
+            this.mBluetoothStateUsesPolling = value;
+            return this;
+        }
+
+        /**
+         * Set Bluetooth state polling timeout.
+         */
+        public Builder setBluetoothStatePollingMillis(int value) {
+            this.mBluetoothStatePollingMillis = value;
+            return this;
+        }
+
+        /**
+         * Set number of attempts.
+         */
+        public Builder setNumAttempts(int value) {
+            this.mNumAttempts = value;
+            return this;
+        }
+
+        /**
+         * Set whether to enable BrEdr handover.
+         */
+        public Builder setEnableBrEdrHandover(boolean value) {
+            this.mEnableBrEdrHandover = value;
+            return this;
+        }
+
+        /**
+         * Set Br handover data characteristic Id.
+         */
+        public Builder setBrHandoverDataCharacteristicId(short value) {
+            this.mBrHandoverDataCharacteristicId = value;
+            return this;
+        }
+
+        /**
+         * Set Bluetooth Sig data characteristic Id.
+         */
+        public Builder setBluetoothSigDataCharacteristicId(short value) {
+            this.mBluetoothSigDataCharacteristicId = value;
+            return this;
+        }
+
+        /**
+         * Set Firmware version characteristic id.
+         */
+        public Builder setFirmwareVersionCharacteristicId(short value) {
+            this.mFirmwareVersionCharacteristicId = value;
+            return this;
+        }
+
+        /**
+         * Set Br transport block data descriptor id.
+         */
+        public Builder setBrTransportBlockDataDescriptorId(short value) {
+            this.mBrTransportBlockDataDescriptorId = value;
+            return this;
+        }
+
+        /**
+         * Set whether to wait for Uuids after bonding.
+         */
+        public Builder setWaitForUuidsAfterBonding(boolean value) {
+            this.mWaitForUuidsAfterBonding = value;
+            return this;
+        }
+
+        /**
+         * Set whether to receive Uuids and bonded event before close.
+         */
+        public Builder setReceiveUuidsAndBondedEventBeforeClose(boolean value) {
+            this.mReceiveUuidsAndBondedEventBeforeClose = value;
+            return this;
+        }
+
+        /**
+         * Set remove bond timeout.
+         */
+        public Builder setRemoveBondTimeoutSeconds(int value) {
+            this.mRemoveBondTimeoutSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set remove bound sleep time.
+         */
+        public Builder setRemoveBondSleepMillis(int value) {
+            this.mRemoveBondSleepMillis = value;
+            return this;
+        }
+
+        /**
+         * Set create bond timeout.
+         */
+        public Builder setCreateBondTimeoutSeconds(int value) {
+            this.mCreateBondTimeoutSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set Hid create bond timeout.
+         */
+        public Builder setHidCreateBondTimeoutSeconds(int value) {
+            this.mHidCreateBondTimeoutSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set proxy timeout.
+         */
+        public Builder setProxyTimeoutSeconds(int value) {
+            this.mProxyTimeoutSeconds = value;
+            return this;
+        }
+
+        /**
+         * Set whether to reject phone book access.
+         */
+        public Builder setRejectPhonebookAccess(boolean value) {
+            this.mRejectPhonebookAccess = value;
+            return this;
+        }
+
+        /**
+         * Set whether to reject message access.
+         */
+        public Builder setRejectMessageAccess(boolean value) {
+            this.mRejectMessageAccess = value;
+            return this;
+        }
+
+        /**
+         * Set whether to reject slim access.
+         */
+        public Builder setRejectSimAccess(boolean value) {
+            this.mRejectSimAccess = value;
+            return this;
+        }
+
+        /**
+         * Set whether to accept passkey.
+         */
+        public Builder setAcceptPasskey(boolean value) {
+            this.mAcceptPasskey = value;
+            return this;
+        }
+
+        /**
+         * Set supported profile Uuids.
+         */
+        public Builder setSupportedProfileUuids(byte[] value) {
+            this.mSupportedProfileUuids = value;
+            return this;
+        }
+
+        /**
+         * Set whether to collect more event log for quality.
+         */
+        public Builder setMoreEventLogForQuality(boolean value) {
+            this.mMoreEventLogForQuality = value;
+            return this;
+        }
+
+        /**
+         * Set supported profile Uuids.
+         */
+        public Builder setSupportedProfileUuids(short... uuids) {
+            return setSupportedProfileUuids(Bytes.toBytes(ByteOrder.BIG_ENDIAN, uuids));
+        }
+
+        /**
+         * Set write account key sleep time.
+         */
+        public Builder setWriteAccountKeySleepMillis(int value) {
+            this.mWriteAccountKeySleepMillis = value;
+            return this;
+        }
+
+        /**
+         * Set whether to do provider initialized bonding if supported.
+         */
+        public Builder setProviderInitiatesBondingIfSupported(boolean value) {
+            this.mProviderInitiatesBondingIfSupported = value;
+            return this;
+        }
+
+        /**
+         * Set whether to try direct connection when the device is previously bonded.
+         */
+        public Builder setAttemptDirectConnectionWhenPreviouslyBonded(boolean value) {
+            this.mAttemptDirectConnectionWhenPreviouslyBonded = value;
+            return this;
+        }
+
+        /**
+         * Set whether to automatically reconnect gatt when needed.
+         */
+        public Builder setAutomaticallyReconnectGattWhenNeeded(boolean value) {
+            this.mAutomaticallyReconnectGattWhenNeeded = value;
+            return this;
+        }
+
+        /**
+         * Set whether to skip disconnecting gatt before writing account key.
+         */
+        public Builder setSkipDisconnectingGattBeforeWritingAccountKey(boolean value) {
+            this.mSkipDisconnectingGattBeforeWritingAccountKey = value;
+            return this;
+        }
+
+        /**
+         * Set whether to skip connecting profiles.
+         */
+        public Builder setSkipConnectingProfiles(boolean value) {
+            this.mSkipConnectingProfiles = value;
+            return this;
+        }
+
+        /**
+         * Set whether to ignore Uuid timeout after bonded.
+         */
+        public Builder setIgnoreUuidTimeoutAfterBonded(boolean value) {
+            this.mIgnoreUuidTimeoutAfterBonded = value;
+            return this;
+        }
+
+        /**
+         * Set whether to include transport type in create bound request.
+         */
+        public Builder setSpecifyCreateBondTransportType(boolean value) {
+            this.mSpecifyCreateBondTransportType = value;
+            return this;
+        }
+
+        /**
+         * Set transport type used in create bond request.
+         */
+        public Builder setCreateBondTransportType(int value) {
+            this.mCreateBondTransportType = value;
+            return this;
+        }
+
+        /**
+         * Set whether to increase intent filter priority.
+         */
+        public Builder setIncreaseIntentFilterPriority(boolean value) {
+            this.mIncreaseIntentFilterPriority = value;
+            return this;
+        }
+
+        /**
+         * Set whether to evaluate performance.
+         */
+        public Builder setEvaluatePerformance(boolean value) {
+            this.mEvaluatePerformance = value;
+            return this;
+        }
+
+        /**
+         * Set extra logging info.
+         */
+        public Builder setExtraLoggingInformation(ExtraLoggingInformation value) {
+            this.mExtraLoggingInformation = value;
+            return this;
+        }
+
+        /**
+         * Set whether to enable naming characteristic.
+         */
+        public Builder setEnableNamingCharacteristic(boolean value) {
+            this.mEnableNamingCharacteristic = value;
+            return this;
+        }
+
+        /**
+         * Set whether to keep writing the account key to the provider, that has already paired with
+         * the account.
+         */
+        public Builder setKeepSameAccountKeyWrite(boolean value) {
+            this.mKeepSameAccountKeyWrite = value;
+            return this;
+        }
+
+        /**
+         * Set whether to enable firmware version characteristic.
+         */
+        public Builder setEnableFirmwareVersionCharacteristic(boolean value) {
+            this.mEnableFirmwareVersionCharacteristic = value;
+            return this;
+        }
+
+        /**
+         * Set whether it is retroactive pairing.
+         */
+        public Builder setIsRetroactivePairing(boolean value) {
+            this.mIsRetroactivePairing = value;
+            return this;
+        }
+
+        /**
+         * Set number of allowed sdp attempts after bonded.
+         */
+        public Builder setNumSdpAttemptsAfterBonded(int value) {
+            this.mNumSdpAttemptsAfterBonded = value;
+            return this;
+        }
+
+        /**
+         * Set whether to support Hid device.
+         */
+        public Builder setSupportHidDevice(boolean value) {
+            this.mSupportHidDevice = value;
+            return this;
+        }
+
+        /**
+         * Set wehther to enable the pairing behavior to handle the state transition from
+         * BOND_BONDED to BOND_BONDING when directly connecting profiles.
+         */
+        public Builder setEnablePairingWhileDirectlyConnecting(boolean value) {
+            this.mEnablePairingWhileDirectlyConnecting = value;
+            return this;
+        }
+
+        /**
+         * Set whether to accept consent for fast pair one.
+         */
+        public Builder setAcceptConsentForFastPairOne(boolean value) {
+            this.mAcceptConsentForFastPairOne = value;
+            return this;
+        }
+
+        /**
+         * Set Gatt connect retry timeout.
+         */
+        public Builder setGattConnectRetryTimeoutMillis(int value) {
+            this.mGattConnectRetryTimeoutMillis = value;
+            return this;
+        }
+
+        /**
+         * Set whether to enable 128 bit custom gatt characteristic Id.
+         */
+        public Builder setEnable128BitCustomGattCharacteristicsId(boolean value) {
+            this.mEnable128BitCustomGattCharacteristicsId = value;
+            return this;
+        }
+
+        /**
+         * Set whether to send exception step to validator.
+         */
+        public Builder setEnableSendExceptionStepToValidator(boolean value) {
+            this.mEnableSendExceptionStepToValidator = value;
+            return this;
+        }
+
+        /**
+         * Set wehther to add the additional data type in the handshake when action over BLE.
+         */
+        public Builder setEnableAdditionalDataTypeWhenActionOverBle(boolean value) {
+            this.mEnableAdditionalDataTypeWhenActionOverBle = value;
+            return this;
+        }
+
+        /**
+         * Set whether to check bond state when skip connecting profiles.
+         */
+        public Builder setCheckBondStateWhenSkipConnectingProfiles(boolean value) {
+            this.mCheckBondStateWhenSkipConnectingProfiles = value;
+            return this;
+        }
+
+        /**
+         * Set whether to handle passkey confirmation by UI.
+         */
+        public Builder setHandlePasskeyConfirmationByUi(boolean value) {
+            this.mHandlePasskeyConfirmationByUi = value;
+            return this;
+        }
+
+        /**
+         * Set wehther to retry gatt connection and secret handshake.
+         */
+        public Builder setRetryGattConnectionAndSecretHandshake(boolean value) {
+            this.mRetryGattConnectionAndSecretHandshake = value;
+            return this;
+        }
+
+        /**
+         * Set gatt connect short timeout.
+         */
+        public Builder setGattConnectShortTimeoutMs(long value) {
+            this.mGattConnectShortTimeoutMs = value;
+            return this;
+        }
+
+        /**
+         * Set gatt connect long timeout.
+         */
+        public Builder setGattConnectLongTimeoutMs(long value) {
+            this.mGattConnectLongTimeoutMs = value;
+            return this;
+        }
+
+        /**
+         * Set gatt connection short timoutout, including retry.
+         */
+        public Builder setGattConnectShortTimeoutRetryMaxSpentTimeMs(long value) {
+            this.mGattConnectShortTimeoutRetryMaxSpentTimeMs = value;
+            return this;
+        }
+
+        /**
+         * Set address rotate timeout, including retry.
+         */
+        public Builder setAddressRotateRetryMaxSpentTimeMs(long value) {
+            this.mAddressRotateRetryMaxSpentTimeMs = value;
+            return this;
+        }
+
+        /**
+         * Set pairing retry delay time.
+         */
+        public Builder setPairingRetryDelayMs(long value) {
+            this.mPairingRetryDelayMs = value;
+            return this;
+        }
+
+        /**
+         * Set secret handshake short timeout.
+         */
+        public Builder setSecretHandshakeShortTimeoutMs(long value) {
+            this.mSecretHandshakeShortTimeoutMs = value;
+            return this;
+        }
+
+        /**
+         * Set secret handshake long timeout.
+         */
+        public Builder setSecretHandshakeLongTimeoutMs(long value) {
+            this.mSecretHandshakeLongTimeoutMs = value;
+            return this;
+        }
+
+        /**
+         * Set secret handshake short timeout retry max spent time.
+         */
+        public Builder setSecretHandshakeShortTimeoutRetryMaxSpentTimeMs(long value) {
+            this.mSecretHandshakeShortTimeoutRetryMaxSpentTimeMs = value;
+            return this;
+        }
+
+        /**
+         * Set secret handshake long timeout retry max spent time.
+         */
+        public Builder setSecretHandshakeLongTimeoutRetryMaxSpentTimeMs(long value) {
+            this.mSecretHandshakeLongTimeoutRetryMaxSpentTimeMs = value;
+            return this;
+        }
+
+        /**
+         * Set secret handshake retry attempts allowed.
+         */
+        public Builder setSecretHandshakeRetryAttempts(long value) {
+            this.mSecretHandshakeRetryAttempts = value;
+            return this;
+        }
+
+        /**
+         * Set secret handshake retry gatt connection max spent time.
+         */
+        public Builder setSecretHandshakeRetryGattConnectionMaxSpentTimeMs(long value) {
+            this.mSecretHandshakeRetryGattConnectionMaxSpentTimeMs = value;
+            return this;
+        }
+
+        /**
+         * Set signal loss retry max spent time.
+         */
+        public Builder setSignalLostRetryMaxSpentTimeMs(long value) {
+            this.mSignalLostRetryMaxSpentTimeMs = value;
+            return this;
+        }
+
+        /**
+         * Set gatt connection and secret handshake no retry gatt error.
+         */
+        public Builder setGattConnectionAndSecretHandshakeNoRetryGattError(
+                ImmutableSet<Integer> value) {
+            this.mGattConnectionAndSecretHandshakeNoRetryGattError = value;
+            return this;
+        }
+
+        /**
+         * Set retry secret handshake timeout.
+         */
+        public Builder setRetrySecretHandshakeTimeout(boolean value) {
+            this.mRetrySecretHandshakeTimeout = value;
+            return this;
+        }
+
+        /**
+         * Set whether to log user manual retry.
+         */
+        public Builder setLogUserManualRetry(boolean value) {
+            this.mLogUserManualRetry = value;
+            return this;
+        }
+
+        /**
+         * Set pair falure counts.
+         */
+        public Builder setPairFailureCounts(int counts) {
+            this.mPairFailureCounts = counts;
+            return this;
+        }
+
+        /**
+         * Set whether to use pair flow to show ui when pairing is finished without connecting
+         * profile..
+         */
+        public Builder setEnablePairFlowShowUiWithoutProfileConnection(boolean value) {
+            this.mEnablePairFlowShowUiWithoutProfileConnection = value;
+            return this;
+        }
+
+        /**
+         * Set whether to log pairing with cached module Id.
+         */
+        public Builder setLogPairWithCachedModelId(boolean value) {
+            this.mLogPairWithCachedModelId = value;
+            return this;
+        }
+
+        /**
+         * Set possible cached device address.
+         */
+        public Builder setPossibleCachedDeviceAddress(String value) {
+            this.mPossibleCachedDeviceAddress = value;
+            return this;
+        }
+
+        /**
+         * Set paired device count from the same module Id.
+         */
+        public Builder setSameModelIdPairedDeviceCount(int value) {
+            this.mSameModelIdPairedDeviceCount = value;
+            return this;
+        }
+
+        /**
+         * Set whether the bonded device address is from cache.
+         */
+        public Builder setIsDeviceFinishCheckAddressFromCache(boolean value) {
+            this.mIsDeviceFinishCheckAddressFromCache = value;
+            return this;
+        }
+
+        /**
+         * Set whether to directly connect profile if modelId is in cache.
+         */
+        public Builder setDirectConnectProfileIfModelIdInCache(boolean value) {
+            this.mDirectConnectProfileIfModelIdInCache = value;
+            return this;
+        }
+
+        /**
+         * Set cached device address.
+         */
+        public Builder setCachedDeviceAddress(String value) {
+            this.mCachedDeviceAddress = value;
+            return this;
+        }
+
+        /**
+         * Builds a Preferences instance.
+         */
+        public Preferences build() {
+            return new Preferences(
+                    this.mGattOperationTimeoutSeconds,
+                    this.mGattConnectionTimeoutSeconds,
+                    this.mBluetoothToggleTimeoutSeconds,
+                    this.mBluetoothToggleSleepSeconds,
+                    this.mClassicDiscoveryTimeoutSeconds,
+                    this.mNumDiscoverAttempts,
+                    this.mDiscoveryRetrySleepSeconds,
+                    this.mIgnoreDiscoveryError,
+                    this.mSdpTimeoutSeconds,
+                    this.mNumSdpAttempts,
+                    this.mNumCreateBondAttempts,
+                    this.mNumConnectAttempts,
+                    this.mNumWriteAccountKeyAttempts,
+                    this.mToggleBluetoothOnFailure,
+                    this.mBluetoothStateUsesPolling,
+                    this.mBluetoothStatePollingMillis,
+                    this.mNumAttempts,
+                    this.mEnableBrEdrHandover,
+                    this.mBrHandoverDataCharacteristicId,
+                    this.mBluetoothSigDataCharacteristicId,
+                    this.mFirmwareVersionCharacteristicId,
+                    this.mBrTransportBlockDataDescriptorId,
+                    this.mWaitForUuidsAfterBonding,
+                    this.mReceiveUuidsAndBondedEventBeforeClose,
+                    this.mRemoveBondTimeoutSeconds,
+                    this.mRemoveBondSleepMillis,
+                    this.mCreateBondTimeoutSeconds,
+                    this.mHidCreateBondTimeoutSeconds,
+                    this.mProxyTimeoutSeconds,
+                    this.mRejectPhonebookAccess,
+                    this.mRejectMessageAccess,
+                    this.mRejectSimAccess,
+                    this.mWriteAccountKeySleepMillis,
+                    this.mSkipDisconnectingGattBeforeWritingAccountKey,
+                    this.mMoreEventLogForQuality,
+                    this.mRetryGattConnectionAndSecretHandshake,
+                    this.mGattConnectShortTimeoutMs,
+                    this.mGattConnectLongTimeoutMs,
+                    this.mGattConnectShortTimeoutRetryMaxSpentTimeMs,
+                    this.mAddressRotateRetryMaxSpentTimeMs,
+                    this.mPairingRetryDelayMs,
+                    this.mSecretHandshakeShortTimeoutMs,
+                    this.mSecretHandshakeLongTimeoutMs,
+                    this.mSecretHandshakeShortTimeoutRetryMaxSpentTimeMs,
+                    this.mSecretHandshakeLongTimeoutRetryMaxSpentTimeMs,
+                    this.mSecretHandshakeRetryAttempts,
+                    this.mSecretHandshakeRetryGattConnectionMaxSpentTimeMs,
+                    this.mSignalLostRetryMaxSpentTimeMs,
+                    this.mGattConnectionAndSecretHandshakeNoRetryGattError,
+                    this.mRetrySecretHandshakeTimeout,
+                    this.mLogUserManualRetry,
+                    this.mPairFailureCounts,
+                    this.mCachedDeviceAddress,
+                    this.mPossibleCachedDeviceAddress,
+                    this.mSameModelIdPairedDeviceCount,
+                    this.mIsDeviceFinishCheckAddressFromCache,
+                    this.mLogPairWithCachedModelId,
+                    this.mDirectConnectProfileIfModelIdInCache,
+                    this.mAcceptPasskey,
+                    this.mSupportedProfileUuids,
+                    this.mProviderInitiatesBondingIfSupported,
+                    this.mAttemptDirectConnectionWhenPreviouslyBonded,
+                    this.mAutomaticallyReconnectGattWhenNeeded,
+                    this.mSkipConnectingProfiles,
+                    this.mIgnoreUuidTimeoutAfterBonded,
+                    this.mSpecifyCreateBondTransportType,
+                    this.mCreateBondTransportType,
+                    this.mIncreaseIntentFilterPriority,
+                    this.mEvaluatePerformance,
+                    this.mExtraLoggingInformation,
+                    this.mEnableNamingCharacteristic,
+                    this.mEnableFirmwareVersionCharacteristic,
+                    this.mKeepSameAccountKeyWrite,
+                    this.mIsRetroactivePairing,
+                    this.mNumSdpAttemptsAfterBonded,
+                    this.mSupportHidDevice,
+                    this.mEnablePairingWhileDirectlyConnecting,
+                    this.mAcceptConsentForFastPairOne,
+                    this.mGattConnectRetryTimeoutMillis,
+                    this.mEnable128BitCustomGattCharacteristicsId,
+                    this.mEnableSendExceptionStepToValidator,
+                    this.mEnableAdditionalDataTypeWhenActionOverBle,
+                    this.mCheckBondStateWhenSkipConnectingProfiles,
+                    this.mHandlePasskeyConfirmationByUi,
+                    this.mEnablePairFlowShowUiWithoutProfileConnection);
+        }
+    }
+
+    /**
+     * Whether a given Uuid is supported.
+     */
+    public boolean isSupportedProfile(short profileUuid) {
+        return Constants.PROFILES.containsKey(profileUuid)
+                && Shorts.contains(
+                Bytes.toShorts(ByteOrder.BIG_ENDIAN, getSupportedProfileUuids()), profileUuid);
+    }
+
+    /**
+     * Information that will be used for logging.
+     */
+    public static class ExtraLoggingInformation {
+
+        private final String mModelId;
+
+        private ExtraLoggingInformation(String modelId) {
+            this.mModelId = modelId;
+        }
+
+        /**
+         * Returns model Id.
+         */
+        public String getModelId() {
+            return mModelId;
+        }
+
+        /**
+         * Converts an instance to a builder.
+         */
+        public Builder toBuilder() {
+            return new Builder(this);
+        }
+
+        /**
+         * Creates a builder for ExtraLoggingInformation.
+         */
+        public static Builder builder() {
+            return new ExtraLoggingInformation.Builder();
+        }
+
+        @Override
+        public String toString() {
+            return "ExtraLoggingInformation{" + "modelId=" + mModelId + "}";
+        }
+
+        @Override
+        public boolean equals(@Nullable Object o) {
+            if (o == this) {
+                return true;
+            }
+            if (o instanceof ExtraLoggingInformation) {
+                Preferences.ExtraLoggingInformation that = (Preferences.ExtraLoggingInformation) o;
+                return this.mModelId.equals(that.getModelId());
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mModelId);
+        }
+
+        /**
+         * Extra logging information builder.
+         */
+        public static class Builder {
+
+            private String mModelId;
+
+            private Builder() {
+            }
+
+            private Builder(ExtraLoggingInformation source) {
+                this.mModelId = source.getModelId();
+            }
+
+            /**
+             * Set model ID.
+             */
+            public Builder setModelId(String modelId) {
+                this.mModelId = modelId;
+                return this;
+            }
+
+            /**
+             * Builds extra logging information.
+             */
+            public ExtraLoggingInformation build() {
+                return new ExtraLoggingInformation(mModelId);
+            }
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Reflect.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Reflect.java
new file mode 100644
index 0000000..a2603b5
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Reflect.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Utilities for calling methods using reflection. The main benefit of using this helper is to avoid
+ * complications around exception handling when calling methods reflectively. It's not safe to use
+ * Java 8's multicatch on such exceptions, because the java compiler converts multicatch into
+ * ReflectiveOperationException in some instances, which doesn't work on older sdk versions.
+ * Instead, use these utilities and catch ReflectionException.
+ *
+ * <p>Example usage:
+ *
+ * <pre>{@code
+ * try {
+ *   Reflect.on(btAdapter)
+ *       .withMethod("setScanMode", int.class)
+ *       .invoke(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)
+ * } catch (ReflectionException e) { }
+ * }</pre>
+ */
+// TODO(b/202549655): remove existing Reflect usage. New usage is not allowed! No exception!
+public final class Reflect {
+    private final Object mTargetObject;
+
+    private Reflect(Object targetObject) {
+        this.mTargetObject = targetObject;
+    }
+
+    /** Creates an instance of this helper to invoke methods on the given target object. */
+    public static Reflect on(Object targetObject) {
+        return new Reflect(targetObject);
+    }
+
+    /** Finds a method with the given name and parameter types. */
+    public ReflectionMethod withMethod(String methodName, Class<?>... paramTypes)
+            throws ReflectionException {
+        try {
+            return new ReflectionMethod(mTargetObject.getClass().getMethod(methodName, paramTypes));
+        } catch (NoSuchMethodException e) {
+            throw new ReflectionException(e);
+        }
+    }
+
+    /** Represents an invokable method found reflectively. */
+    public final class ReflectionMethod {
+        private final Method mMethod;
+
+        private ReflectionMethod(Method method) {
+            this.mMethod = method;
+        }
+
+        /**
+         * Invokes this instance method with the given parameters. The called method does not return
+         * a value.
+         */
+        public void invoke(Object... parameters) throws ReflectionException {
+            try {
+                mMethod.invoke(mTargetObject, parameters);
+            } catch (IllegalAccessException e) {
+                throw new ReflectionException(e);
+            } catch (InvocationTargetException e) {
+                throw new ReflectionException(e);
+            }
+        }
+
+        /**
+         * Invokes this instance method with the given parameters. The called method returns a non
+         * null value.
+         */
+        public Object get(Object... parameters) throws ReflectionException {
+            Object value;
+            try {
+                value = mMethod.invoke(mTargetObject, parameters);
+            } catch (IllegalAccessException e) {
+                throw new ReflectionException(e);
+            } catch (InvocationTargetException e) {
+                throw new ReflectionException(e);
+            }
+            if (value == null) {
+                throw new ReflectionException(new NullPointerException());
+            }
+            return value;
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ReflectionException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ReflectionException.java
new file mode 100644
index 0000000..1c20c55
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ReflectionException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+/**
+ * An exception thrown during a reflection operation. Like ReflectiveOperationException, except
+ * compatible on older API versions.
+ */
+public final class ReflectionException extends Exception {
+    ReflectionException(Throwable cause) {
+        super(cause.getMessage(), cause);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/SignalLostException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/SignalLostException.java
new file mode 100644
index 0000000..244ee66
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/SignalLostException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+/** Base class for fast pair signal lost exceptions. */
+public class SignalLostException extends PairingException {
+    SignalLostException(String message, Exception e) {
+        super(message);
+        initCause(e);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/SignalRotatedException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/SignalRotatedException.java
new file mode 100644
index 0000000..d0d2a5d
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/SignalRotatedException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+/** Base class for fast pair signal rotated exceptions. */
+public class SignalRotatedException extends PairingException {
+    private final String mNewAddress;
+
+    SignalRotatedException(String message, String newAddress, Exception e) {
+        super(message);
+        this.mNewAddress = newAddress;
+        initCause(e);
+    }
+
+    /** Returns the new BLE address for the model ID. */
+    public String getNewAddress() {
+        return mNewAddress;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/SimpleBroadcastReceiver.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/SimpleBroadcastReceiver.java
new file mode 100644
index 0000000..7f525a7
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/SimpleBroadcastReceiver.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import android.annotation.TargetApi;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build.VERSION_CODES;
+import android.os.Handler;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.google.common.util.concurrent.SettableFuture;
+
+import java.util.Arrays;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Like {@link BroadcastReceiver}, but:
+ *
+ * <ul>
+ *   <li>Simpler to create and register, with a list of actions.
+ *   <li>Implements AutoCloseable. If used as a resource in try-with-resources (available on
+ *       KitKat+), unregisters itself automatically.
+ *   <li>Lets you block waiting for your state transition with {@link #await}.
+ * </ul>
+ */
+// AutoCloseable only available on KitKat+.
+@TargetApi(VERSION_CODES.KITKAT)
+public abstract class SimpleBroadcastReceiver extends BroadcastReceiver implements AutoCloseable {
+
+    private static final String TAG = SimpleBroadcastReceiver.class.getSimpleName();
+
+    /**
+     * Creates a one shot receiver.
+     */
+    public static SimpleBroadcastReceiver oneShotReceiver(
+            Context context, Preferences preferences, String... actions) {
+        return new SimpleBroadcastReceiver(context, preferences, actions) {
+            @Override
+            protected void onReceive(Intent intent) {
+                close();
+            }
+        };
+    }
+
+    private final Context mContext;
+    private final SettableFuture<Void> mIsClosedFuture = SettableFuture.create();
+    private long mAwaitExtendSecond;
+
+    // Nullness checker complains about 'this' being @UnderInitialization
+    @SuppressWarnings("nullness")
+    public SimpleBroadcastReceiver(
+            Context context, Preferences preferences, @Nullable Handler handler,
+            String... actions) {
+        Log.v(TAG, this + " listening for actions " + Arrays.toString(actions));
+        this.mContext = context;
+        IntentFilter intentFilter = new IntentFilter();
+        if (preferences.getIncreaseIntentFilterPriority()) {
+            intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+        }
+        for (String action : actions) {
+            intentFilter.addAction(action);
+        }
+        context.registerReceiver(this, intentFilter, /* broadcastPermission= */ null, handler);
+    }
+
+    public SimpleBroadcastReceiver(Context context, Preferences preferences, String... actions) {
+        this(context, preferences, /* handler= */ null, actions);
+    }
+
+    /**
+     * Any exception thrown by this method will be delivered via {@link #await}.
+     */
+    protected abstract void onReceive(Intent intent) throws Exception;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.v(TAG, "Got intent with action= " + intent.getAction());
+        try {
+            onReceive(intent);
+        } catch (Exception e) {
+            closeWithError(e);
+        }
+    }
+
+    @Override
+    public void close() {
+        closeWithError(null);
+    }
+
+    void closeWithError(@Nullable Exception e) {
+        try {
+            mContext.unregisterReceiver(this);
+        } catch (IllegalArgumentException ignored) {
+            // Ignore. Happens if you unregister twice.
+        }
+        if (e == null) {
+            mIsClosedFuture.set(null);
+        } else {
+            mIsClosedFuture.setException(e);
+        }
+    }
+
+    /**
+     * Extends the awaiting time.
+     */
+    public void extendAwaitSecond(int awaitExtendSecond) {
+        this.mAwaitExtendSecond = awaitExtendSecond;
+    }
+
+    /**
+     * Blocks until this receiver has closed (i.e. the state transition that this receiver is
+     * interested in has completed). Throws an exception on any error.
+     */
+    public void await(long timeout, TimeUnit timeUnit)
+            throws InterruptedException, ExecutionException, TimeoutException {
+        Log.v(TAG, this + " waiting on future for " + timeout + " " + timeUnit);
+        try {
+            mIsClosedFuture.get(timeout, timeUnit);
+        } catch (TimeoutException e) {
+            if (mAwaitExtendSecond <= 0) {
+                throw e;
+            }
+            Log.i(TAG, "Extend timeout for " + mAwaitExtendSecond + " seconds");
+            mIsClosedFuture.get(mAwaitExtendSecond, TimeUnit.SECONDS);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/TdsException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/TdsException.java
new file mode 100644
index 0000000..7382ff3
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/TdsException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import com.android.server.nearby.intdefs.FastPairEventIntDefs.BrEdrHandoverErrorCode;
+
+import com.google.errorprone.annotations.FormatMethod;
+
+/**
+ * Thrown when BR/EDR Handover fails.
+ */
+public class TdsException extends Exception {
+
+    final @BrEdrHandoverErrorCode int mErrorCode;
+
+    @FormatMethod
+    TdsException(@BrEdrHandoverErrorCode int errorCode, String format, Object... objects) {
+        super(String.format(format, objects));
+        this.mErrorCode = errorCode;
+    }
+
+    /** Returns error code. */
+    public @BrEdrHandoverErrorCode int getErrorCode() {
+        return mErrorCode;
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/TimingLogger.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/TimingLogger.java
new file mode 100644
index 0000000..83ee309
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/TimingLogger.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import android.os.SystemClock;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.util.ArrayDeque;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * A profiler for performance metrics.
+ *
+ * <p>This class aim to break down the execution time for each steps of process to figure out the
+ * bottleneck.
+ */
+public class TimingLogger {
+
+    private static final String TAG = TimingLogger.class.getSimpleName();
+
+    /**
+     * The name of this session.
+     */
+    private final String mName;
+
+    private final Preferences mPreference;
+
+    /**
+     * The ordered timing sequence data. It's composed by a paired {@link Timing} generated from
+     * {@link #start} and {@link #end}.
+     */
+    private final List<Timing> mTimings;
+
+    private final long mStartTimestampMs;
+
+    /** Constructor. */
+    public TimingLogger(String name, Preferences mPreference) {
+        this.mName = name;
+        this.mPreference = mPreference;
+        mTimings = new CopyOnWriteArrayList<>();
+        mStartTimestampMs = SystemClock.elapsedRealtime();
+    }
+
+    @VisibleForTesting
+    List<Timing> getTimings() {
+        return mTimings;
+    }
+
+    /**
+     * Start a new paired timing.
+     *
+     * @param label The split name of paired timing.
+     */
+    public void start(String label) {
+        if (mPreference.getEvaluatePerformance()) {
+            mTimings.add(new Timing(label));
+        }
+    }
+
+    /**
+     * End a paired timing.
+     */
+    public void end() {
+        if (mPreference.getEvaluatePerformance()) {
+            mTimings.add(new Timing(Timing.END_LABEL));
+        }
+    }
+
+    /**
+     * Print out the timing data.
+     */
+    public void dump() {
+        if (!mPreference.getEvaluatePerformance()) {
+            return;
+        }
+
+        calculateTiming();
+        Log.i(TAG, mName + "[Exclusive time] / [Total time] ([Timestamp])");
+        int indentCount = 0;
+        for (Timing timing : mTimings) {
+            if (timing.isEndTiming()) {
+                indentCount--;
+                continue;
+            }
+            indentCount++;
+            if (timing.mExclusiveTime == timing.mTotalTime) {
+                Log.i(TAG, getIndentString(indentCount) + timing.mName + " " + timing.mExclusiveTime
+                        + "ms (" + getRelativeTimestamp(timing.getTimestamp()) + ")");
+            } else {
+                Log.i(TAG, getIndentString(indentCount) + timing.mName + " " + timing.mExclusiveTime
+                        + "ms / " + timing.mTotalTime + "ms (" + getRelativeTimestamp(
+                        timing.getTimestamp()) + ")");
+            }
+        }
+        Log.i(TAG, mName + "end, " + getTotalTime() + "ms");
+    }
+
+    private void calculateTiming() {
+        ArrayDeque<Timing> arrayDeque = new ArrayDeque<>();
+        for (Timing timing : mTimings) {
+            if (timing.isStartTiming()) {
+                arrayDeque.addFirst(timing);
+                continue;
+            }
+
+            Timing timingStart = arrayDeque.removeFirst();
+            final long time = timing.mTimestamp - timingStart.mTimestamp;
+            timingStart.mExclusiveTime += time;
+            timingStart.mTotalTime += time;
+            if (!arrayDeque.isEmpty()) {
+                arrayDeque.peekFirst().mExclusiveTime -= time;
+            }
+        }
+    }
+
+    private String getIndentString(int indentCount) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < indentCount; i++) {
+            sb.append("  ");
+        }
+        return sb.toString();
+    }
+
+    private long getRelativeTimestamp(long timestamp) {
+        return timestamp - mTimings.get(0).mTimestamp;
+    }
+
+    @VisibleForTesting
+    long getTotalTime() {
+        return mTimings.get(mTimings.size() - 1).mTimestamp - mTimings.get(0).mTimestamp;
+    }
+
+    /**
+     * Gets the current latency since this object was created.
+     */
+    public long getLatencyMs() {
+        return SystemClock.elapsedRealtime() - mStartTimestampMs;
+    }
+
+    @VisibleForTesting
+    static class Timing {
+
+        private static final String END_LABEL = "END_LABEL";
+
+        /**
+         * The name of this paired timing.
+         */
+        private final String mName;
+
+        /**
+         * System uptime in millisecond.
+         */
+        private final long mTimestamp;
+
+        /**
+         * The execution time exclude inner split timings.
+         */
+        private long mExclusiveTime;
+
+        /**
+         * The execution time within a start and an end timing.
+         */
+        private long mTotalTime;
+
+        private Timing(String name) {
+            this.mName = name;
+            mTimestamp = SystemClock.elapsedRealtime();
+            mExclusiveTime = 0;
+            mTotalTime = 0;
+        }
+
+        @VisibleForTesting
+        String getName() {
+            return mName;
+        }
+
+        @VisibleForTesting
+        long getTimestamp() {
+            return mTimestamp;
+        }
+
+        @VisibleForTesting
+        long getExclusiveTime() {
+            return mExclusiveTime;
+        }
+
+        @VisibleForTesting
+        long getTotalTime() {
+            return mTotalTime;
+        }
+
+        @VisibleForTesting
+        boolean isStartTiming() {
+            return !isEndTiming();
+        }
+
+        @VisibleForTesting
+        boolean isEndTiming() {
+            return END_LABEL.equals(mName);
+        }
+    }
+
+    /**
+     * This class ensures each split timing is paired with a start and an end timing.
+     */
+    public static class ScopedTiming implements AutoCloseable {
+
+        private final TimingLogger mTimingLogger;
+
+        public ScopedTiming(TimingLogger logger, String label) {
+            mTimingLogger = logger;
+            mTimingLogger.start(label);
+        }
+
+        @Override
+        public void close() {
+            mTimingLogger.end();
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ToggleBluetoothTask.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ToggleBluetoothTask.java
new file mode 100644
index 0000000..41ac9f5
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ToggleBluetoothTask.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+/** Task for toggling Bluetooth on and back off again. */
+interface ToggleBluetoothTask {
+
+    /**
+     * Toggles the bluetooth adapter off and back on again to help improve connection reliability.
+     *
+     * @throws InterruptedException when waiting for the bluetooth adapter's state to be set has
+     *     been interrupted.
+     * @throws ExecutionException when waiting for the bluetooth adapter's state to be set has
+     *     failed.
+     * @throws TimeoutException when the bluetooth adapter's state fails to be set on or off.
+     */
+    void toggleBluetooth() throws InterruptedException, ExecutionException, TimeoutException;
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnection.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnection.java
new file mode 100644
index 0000000..de131e4
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnection.java
@@ -0,0 +1,781 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.gatt;
+
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothStatusCodes;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.server.nearby.common.bluetooth.BluetoothConsts;
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.BluetoothTimeoutException;
+import com.android.server.nearby.common.bluetooth.ReservedUuids;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.ConnectionOptions;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.OperationType;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattWrapper;
+import com.android.server.nearby.common.bluetooth.util.BluetoothGattUtils;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.Operation;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.SynchronousOperation;
+
+import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * Gatt connection to a Bluetooth device.
+ */
+public class BluetoothGattConnection implements AutoCloseable {
+
+    private static final String TAG = BluetoothGattConnection.class.getSimpleName();
+
+    @VisibleForTesting
+    static final long OPERATION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(1);
+    @VisibleForTesting
+    static final long SLOW_OPERATION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(10);
+
+    @VisibleForTesting
+    static final int GATT_INTERNAL_ERROR = 129;
+    @VisibleForTesting
+    static final int GATT_ERROR = 133;
+
+    private final BluetoothGattWrapper mGatt;
+    private final BluetoothOperationExecutor mBluetoothOperationExecutor;
+    private final ConnectionOptions mConnectionOptions;
+
+    private volatile boolean mServicesDiscovered = false;
+
+    private volatile boolean mIsConnected = false;
+
+    private volatile int mMtu = BluetoothConsts.DEFAULT_MTU;
+
+    private final ConcurrentMap<BluetoothGattCharacteristic, ChangeObserver> mChangeObservers =
+            new ConcurrentHashMap<>();
+
+    private final List<ConnectionCloseListener> mCloseListeners = new ArrayList<>();
+
+    private long mOperationTimeoutMillis = OPERATION_TIMEOUT_MILLIS;
+
+    BluetoothGattConnection(
+            BluetoothGattWrapper gatt,
+            BluetoothOperationExecutor bluetoothOperationExecutor,
+            ConnectionOptions connectionOptions) {
+        mGatt = gatt;
+        mBluetoothOperationExecutor = bluetoothOperationExecutor;
+        mConnectionOptions = connectionOptions;
+    }
+
+    /**
+     * Set operation timeout.
+     */
+    public void setOperationTimeout(long timeoutMillis) {
+        Preconditions.checkArgument(timeoutMillis > 0, "invalid time out value");
+        mOperationTimeoutMillis = timeoutMillis;
+    }
+
+    /**
+     * Returns connected device.
+     */
+    public BluetoothDevice getDevice() {
+        return mGatt.getDevice();
+    }
+
+    public ConnectionOptions getConnectionOptions() {
+        return mConnectionOptions;
+    }
+
+    public boolean isConnected() {
+        return mIsConnected;
+    }
+
+    /**
+     * Get service.
+     */
+    public BluetoothGattService getService(UUID uuid) throws BluetoothException {
+        Log.d(TAG, String.format("Getting service %s.", uuid));
+        if (!mServicesDiscovered) {
+            discoverServices();
+        }
+        BluetoothGattService match = null;
+        for (BluetoothGattService service : mGatt.getServices()) {
+            if (service.getUuid().equals(uuid)) {
+                if (match != null) {
+                    throw new BluetoothException(
+                            String.format("More than one service %s found on device %s.",
+                                    uuid,
+                                    mGatt.getDevice()));
+                }
+                match = service;
+            }
+        }
+        if (match == null) {
+            throw new BluetoothException(String.format("Service %s not found on device %s.",
+                    uuid,
+                    mGatt.getDevice()));
+        }
+        Log.d(TAG, "Service found.");
+        return match;
+    }
+
+    /**
+     * Returns a list of all characteristics under a given service UUID.
+     */
+    private List<BluetoothGattCharacteristic> getCharacteristics(UUID serviceUuid)
+            throws BluetoothException {
+        if (!mServicesDiscovered) {
+            discoverServices();
+        }
+        ArrayList<BluetoothGattCharacteristic> characteristics = new ArrayList<>();
+        for (BluetoothGattService service : mGatt.getServices()) {
+            // Add all characteristics under this service if its service UUID matches.
+            if (service.getUuid().equals(serviceUuid)) {
+                characteristics.addAll(service.getCharacteristics());
+            }
+        }
+        return characteristics;
+    }
+
+    /**
+     * Get characteristic.
+     */
+    public BluetoothGattCharacteristic getCharacteristic(UUID serviceUuid,
+            UUID characteristicUuid) throws BluetoothException {
+        Log.d(TAG, String.format("Getting characteristic %s on service %s.", characteristicUuid,
+                serviceUuid));
+        BluetoothGattCharacteristic match = null;
+        for (BluetoothGattCharacteristic characteristic : getCharacteristics(serviceUuid)) {
+            if (characteristic.getUuid().equals(characteristicUuid)) {
+                if (match != null) {
+                    throw new BluetoothException(String.format(
+                            "More than one characteristic %s found on service %s on device %s.",
+                            characteristicUuid,
+                            serviceUuid,
+                            mGatt.getDevice()));
+                }
+                match = characteristic;
+            }
+        }
+        if (match == null) {
+            throw new BluetoothException(String.format(
+                    "Characteristic %s not found on service %s of device %s.",
+                    characteristicUuid,
+                    serviceUuid,
+                    mGatt.getDevice()));
+        }
+        Log.d(TAG, "Characteristic found.");
+        return match;
+    }
+
+    /**
+     * Get descriptor.
+     */
+    public BluetoothGattDescriptor getDescriptor(UUID serviceUuid,
+            UUID characteristicUuid, UUID descriptorUuid) throws BluetoothException {
+        Log.d(TAG, String.format("Getting descriptor %s on characteristic %s on service %s.",
+                descriptorUuid, characteristicUuid, serviceUuid));
+        BluetoothGattDescriptor match = null;
+        for (BluetoothGattDescriptor descriptor :
+                getCharacteristic(serviceUuid, characteristicUuid).getDescriptors()) {
+            if (descriptor.getUuid().equals(descriptorUuid)) {
+                if (match != null) {
+                    throw new BluetoothException(String.format("More than one descriptor %s found "
+                                    + "on characteristic %s service %s on device %s.",
+                            descriptorUuid,
+                            characteristicUuid,
+                            serviceUuid,
+                            mGatt.getDevice()));
+                }
+                match = descriptor;
+            }
+        }
+        if (match == null) {
+            throw new BluetoothException(String.format(
+                    "Descriptor %s not found on characteristic %s on service %s of device %s.",
+                    descriptorUuid,
+                    characteristicUuid,
+                    serviceUuid,
+                    mGatt.getDevice()));
+        }
+        Log.d(TAG, "Descriptor found.");
+        return match;
+    }
+
+    /**
+     * Discover services.
+     */
+    public void discoverServices() throws BluetoothException {
+        mBluetoothOperationExecutor.execute(
+                new SynchronousOperation<Void>(OperationType.DISCOVER_SERVICES) {
+                    @Nullable
+                    @Override
+                    public Void call() throws BluetoothException {
+                        if (mServicesDiscovered) {
+                            return null;
+                        }
+                        boolean forceRefresh = false;
+                        try {
+                            discoverServicesInternal();
+                        } catch (BluetoothException e) {
+                            if (!(e instanceof BluetoothGattException)) {
+                                throw e;
+                            }
+                            int errorCode = ((BluetoothGattException) e).getGattErrorCode();
+                            if (errorCode != GATT_ERROR && errorCode != GATT_INTERNAL_ERROR) {
+                                throw e;
+                            }
+                            Log.e(TAG, e.getMessage()
+                                    + "\n Ignore the gatt error for post MNC apis and force "
+                                    + "a refresh");
+                            forceRefresh = true;
+                        }
+
+                        forceRefreshServiceCacheIfNeeded(forceRefresh);
+
+                        mServicesDiscovered = true;
+
+                        return null;
+                    }
+                });
+    }
+
+    private void discoverServicesInternal() throws BluetoothException {
+        Log.i(TAG, "Starting services discovery.");
+        long startTimeMillis = System.currentTimeMillis();
+        try {
+            mBluetoothOperationExecutor.execute(
+                    new Operation<Void>(OperationType.DISCOVER_SERVICES_INTERNAL, mGatt) {
+                        @Override
+                        public void run() throws BluetoothException {
+                            boolean success = mGatt.discoverServices();
+                            if (!success) {
+                                throw new BluetoothException(
+                                        "gatt.discoverServices returned false.");
+                            }
+                        }
+                    },
+                    SLOW_OPERATION_TIMEOUT_MILLIS);
+            Log.i(TAG, String.format("Services discovered successfully in %s ms.",
+                    System.currentTimeMillis() - startTimeMillis));
+        } catch (BluetoothException e) {
+            if (e instanceof BluetoothGattException) {
+                throw new BluetoothGattException(String.format(
+                        "Failed to discover services on device: %s.",
+                        mGatt.getDevice()), ((BluetoothGattException) e).getGattErrorCode(), e);
+            } else {
+                throw new BluetoothException(String.format(
+                        "Failed to discover services on device: %s.",
+                        mGatt.getDevice()), e);
+            }
+        }
+    }
+
+    private boolean hasDynamicServices() {
+        BluetoothGattService gattService =
+                mGatt.getService(ReservedUuids.Services.GENERIC_ATTRIBUTE);
+        if (gattService != null) {
+            BluetoothGattCharacteristic serviceChange =
+                    gattService.getCharacteristic(ReservedUuids.Characteristics.SERVICE_CHANGE);
+            if (serviceChange != null) {
+                return true;
+            }
+        }
+
+        // Check whether the server contains a self defined service dynamic characteristic.
+        gattService = mGatt.getService(BluetoothConsts.SERVICE_DYNAMIC_SERVICE);
+        if (gattService != null) {
+            BluetoothGattCharacteristic serviceChange =
+                    gattService.getCharacteristic(BluetoothConsts.SERVICE_DYNAMIC_CHARACTERISTIC);
+            if (serviceChange != null) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private void forceRefreshServiceCacheIfNeeded(boolean forceRefresh) throws BluetoothException {
+        if (mGatt.getDevice().getBondState() != BluetoothDevice.BOND_BONDED) {
+            // Device is not bonded, so services should not have been cached.
+            return;
+        }
+
+        if (!forceRefresh && !hasDynamicServices()) {
+            return;
+        }
+        Log.i(TAG, "Forcing a refresh of local cache of GATT services");
+        boolean success = mGatt.refresh();
+        if (!success) {
+            throw new BluetoothException("gatt.refresh returned false.");
+        }
+        discoverServicesInternal();
+    }
+
+    /**
+     * Read characteristic.
+     */
+    public byte[] readCharacteristic(UUID serviceUuid, UUID characteristicUuid)
+            throws BluetoothException {
+        return readCharacteristic(getCharacteristic(serviceUuid, characteristicUuid));
+    }
+
+    /**
+     * Read characteristic.
+     */
+    public byte[] readCharacteristic(final BluetoothGattCharacteristic characteristic)
+            throws BluetoothException {
+        try {
+            return mBluetoothOperationExecutor.executeNonnull(
+                    new Operation<byte[]>(OperationType.READ_CHARACTERISTIC, mGatt,
+                            characteristic) {
+                        @Override
+                        public void run() throws BluetoothException {
+                            boolean success = mGatt.readCharacteristic(characteristic);
+                            if (!success) {
+                                throw new BluetoothException(
+                                        "gatt.readCharacteristic returned false.");
+                            }
+                        }
+                    },
+                    mOperationTimeoutMillis);
+        } catch (BluetoothException e) {
+            throw new BluetoothException(String.format(
+                    "Failed to read %s on device %s.",
+                    BluetoothGattUtils.toString(characteristic),
+                    mGatt.getDevice()), e);
+        }
+    }
+
+    /**
+     * Writes Characteristic.
+     */
+    public void writeCharacteristic(UUID serviceUuid, UUID characteristicUuid, byte[] value)
+            throws BluetoothException {
+        writeCharacteristic(getCharacteristic(serviceUuid, characteristicUuid), value);
+    }
+
+    /**
+     * Writes Characteristic.
+     */
+    public void writeCharacteristic(final BluetoothGattCharacteristic characteristic,
+            final byte[] value) throws BluetoothException {
+        Log.d(TAG, String.format("Writing %d bytes on %s on device %s.",
+                value.length,
+                BluetoothGattUtils.toString(characteristic),
+                mGatt.getDevice()));
+        if ((characteristic.getProperties() & (BluetoothGattCharacteristic.PROPERTY_WRITE
+                | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) == 0) {
+            throw new BluetoothException(String.format("%s is not writable!", characteristic));
+        }
+        try {
+            mBluetoothOperationExecutor.execute(
+                    new Operation<Void>(OperationType.WRITE_CHARACTERISTIC, mGatt, characteristic) {
+                        @Override
+                        public void run() throws BluetoothException {
+                            int writeCharacteristicResponseCode = mGatt.writeCharacteristic(
+                                    characteristic, value, characteristic.getWriteType());
+                            if (writeCharacteristicResponseCode != BluetoothStatusCodes.SUCCESS) {
+                                throw new BluetoothException(
+                                        "gatt.writeCharacteristic returned "
+                                        + writeCharacteristicResponseCode);
+                            }
+                        }
+                    },
+                    mOperationTimeoutMillis);
+        } catch (BluetoothException e) {
+            throw new BluetoothException(String.format(
+                    "Failed to write %s on device %s.",
+                    BluetoothGattUtils.toString(characteristic),
+                    mGatt.getDevice()), e);
+        }
+        Log.d(TAG, "Writing characteristic done.");
+    }
+
+    /**
+     * Reads descriptor.
+     */
+    public byte[] readDescriptor(UUID serviceUuid, UUID characteristicUuid, UUID descriptorUuid)
+            throws BluetoothException {
+        return readDescriptor(getDescriptor(serviceUuid, characteristicUuid, descriptorUuid));
+    }
+
+    /**
+     * Reads descriptor.
+     */
+    public byte[] readDescriptor(final BluetoothGattDescriptor descriptor)
+            throws BluetoothException {
+        try {
+            return mBluetoothOperationExecutor.executeNonnull(
+                    new Operation<byte[]>(OperationType.READ_DESCRIPTOR, mGatt, descriptor) {
+                        @Override
+                        public void run() throws BluetoothException {
+                            boolean success = mGatt.readDescriptor(descriptor);
+                            if (!success) {
+                                throw new BluetoothException("gatt.readDescriptor returned false.");
+                            }
+                        }
+                    },
+                    mOperationTimeoutMillis);
+        } catch (BluetoothException e) {
+            throw new BluetoothException(String.format(
+                    "Failed to read %s on %s on device %s.",
+                    descriptor.getUuid(),
+                    BluetoothGattUtils.toString(descriptor),
+                    mGatt.getDevice()), e);
+        }
+    }
+
+    /**
+     * Writes descriptor.
+     */
+    public void writeDescriptor(UUID serviceUuid, UUID characteristicUuid, UUID descriptorUuid,
+            byte[] value) throws BluetoothException {
+        writeDescriptor(getDescriptor(serviceUuid, characteristicUuid, descriptorUuid), value);
+    }
+
+    /**
+     * Writes descriptor.
+     */
+    public void writeDescriptor(final BluetoothGattDescriptor descriptor, final byte[] value)
+            throws BluetoothException {
+        Log.d(TAG, String.format(
+                "Writing %d bytes on %s on device %s.",
+                value.length,
+                BluetoothGattUtils.toString(descriptor),
+                mGatt.getDevice()));
+        long startTimeMillis = System.currentTimeMillis();
+        try {
+            mBluetoothOperationExecutor.execute(
+                    new Operation<Void>(OperationType.WRITE_DESCRIPTOR, mGatt, descriptor) {
+                        @Override
+                        public void run() throws BluetoothException {
+                            int writeDescriptorResponseCode = mGatt.writeDescriptor(descriptor,
+                                    value);
+                            if (writeDescriptorResponseCode != BluetoothStatusCodes.SUCCESS) {
+                                throw new BluetoothException(
+                                        "gatt.writeDescriptor returned "
+                                        + writeDescriptorResponseCode);
+                            }
+                        }
+                    },
+                    mOperationTimeoutMillis);
+            Log.d(TAG, String.format("Writing descriptor done in %s ms.",
+                    System.currentTimeMillis() - startTimeMillis));
+        } catch (BluetoothException e) {
+            throw new BluetoothException(String.format(
+                    "Failed to write %s on device %s.",
+                    BluetoothGattUtils.toString(descriptor),
+                    mGatt.getDevice()), e);
+        }
+    }
+
+    /**
+     * Reads remote Rssi.
+     */
+    public int readRemoteRssi() throws BluetoothException {
+        try {
+            return mBluetoothOperationExecutor.executeNonnull(
+                    new Operation<Integer>(OperationType.READ_RSSI, mGatt) {
+                        @Override
+                        public void run() throws BluetoothException {
+                            boolean success = mGatt.readRemoteRssi();
+                            if (!success) {
+                                throw new BluetoothException("gatt.readRemoteRssi returned false.");
+                            }
+                        }
+                    },
+                    mOperationTimeoutMillis);
+        } catch (BluetoothException e) {
+            throw new BluetoothException(
+                    String.format("Failed to read rssi on device %s.", mGatt.getDevice()), e);
+        }
+    }
+
+    public int getMtu() {
+        return mMtu;
+    }
+
+    /**
+     * Get max data packet size.
+     */
+    public int getMaxDataPacketSize() {
+        // Per BT specs (3.2.9), only MTU - 3 bytes can be used to transmit data
+        return mMtu - 3;
+    }
+
+    /** Set notification enabled or disabled. */
+    @VisibleForTesting
+    public void setNotificationEnabled(BluetoothGattCharacteristic characteristic, boolean enabled)
+            throws BluetoothException {
+        boolean isIndication;
+        int properties = characteristic.getProperties();
+        if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
+            isIndication = false;
+        } else if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
+            isIndication = true;
+        } else {
+            throw new BluetoothException(String.format(
+                    "%s on device %s supports neither notifications nor indications.",
+                    BluetoothGattUtils.toString(characteristic),
+                    mGatt.getDevice()));
+        }
+        BluetoothGattDescriptor clientConfigDescriptor =
+                characteristic.getDescriptor(
+                        ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION);
+        if (clientConfigDescriptor == null) {
+            throw new BluetoothException(String.format(
+                    "%s on device %s is missing client config descriptor.",
+                    BluetoothGattUtils.toString(characteristic),
+                    mGatt.getDevice()));
+        }
+        long startTime = System.currentTimeMillis();
+        Log.d(TAG, String.format("%s %s on characteristic %s.", enabled ? "Enabling" : "Disabling",
+                isIndication ? "indication" : "notification", characteristic.getUuid()));
+
+        if (enabled) {
+            mGatt.setCharacteristicNotification(characteristic, enabled);
+        }
+        writeDescriptor(clientConfigDescriptor,
+                enabled
+                        ? (isIndication
+                        ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE :
+                        BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)
+                        : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
+        if (!enabled) {
+            mGatt.setCharacteristicNotification(characteristic, enabled);
+        }
+
+        Log.d(TAG, String.format("Done in %d ms.", System.currentTimeMillis() - startTime));
+    }
+
+    /**
+     * Enables notification.
+     */
+    public ChangeObserver enableNotification(UUID serviceUuid, UUID characteristicUuid)
+            throws BluetoothException {
+        return enableNotification(getCharacteristic(serviceUuid, characteristicUuid));
+    }
+
+    /**
+     * Enables notification.
+     */
+    public ChangeObserver enableNotification(final BluetoothGattCharacteristic characteristic)
+            throws BluetoothException {
+        return mBluetoothOperationExecutor.executeNonnull(
+                new SynchronousOperation<ChangeObserver>(
+                        OperationType.NOTIFICATION_CHANGE,
+                        characteristic) {
+                    @Override
+                    public ChangeObserver call() throws BluetoothException {
+                        ChangeObserver changeObserver = new ChangeObserver();
+                        mChangeObservers.put(characteristic, changeObserver);
+                        setNotificationEnabled(characteristic, true);
+                        return changeObserver;
+                    }
+                });
+    }
+
+    /**
+     * Disables notification.
+     */
+    public void disableNotification(UUID serviceUuid, UUID characteristicUuid)
+            throws BluetoothException {
+        disableNotification(getCharacteristic(serviceUuid, characteristicUuid));
+    }
+
+    /**
+     * Disables notification.
+     */
+    public void disableNotification(final BluetoothGattCharacteristic characteristic)
+            throws BluetoothException {
+        mBluetoothOperationExecutor.execute(
+                new SynchronousOperation<Void>(
+                        OperationType.NOTIFICATION_CHANGE,
+                        characteristic) {
+                    @Nullable
+                    @Override
+                    public Void call() throws BluetoothException {
+                        setNotificationEnabled(characteristic, false);
+                        mChangeObservers.remove(characteristic);
+                        return null;
+                    }
+                });
+    }
+
+    /**
+     * Adds a close listener.
+     */
+    public void addCloseListener(ConnectionCloseListener listener) {
+        mCloseListeners.add(listener);
+        if (!mIsConnected) {
+            listener.onClose();
+            return;
+        }
+    }
+
+    /**
+     * Removes a close listener.
+     */
+    public void removeCloseListener(ConnectionCloseListener listener) {
+        mCloseListeners.remove(listener);
+    }
+
+    /** onCharacteristicChanged callback. */
+    public void onCharacteristicChanged(BluetoothGattCharacteristic characteristic, byte[] value) {
+        ChangeObserver observer = mChangeObservers.get(characteristic);
+        if (observer == null) {
+            return;
+        }
+        observer.onValueChange(value);
+    }
+
+    @Override
+    public void close() throws BluetoothException {
+        Log.d(TAG, "close");
+        try {
+            if (!mIsConnected) {
+                // Don't call disconnect on a closed connection, since Android framework won't
+                // provide any feedback.
+                return;
+            }
+            mBluetoothOperationExecutor.execute(
+                    new Operation<Void>(OperationType.DISCONNECT, mGatt.getDevice()) {
+                        @Override
+                        public void run() throws BluetoothException {
+                            mGatt.disconnect();
+                        }
+                    }, mOperationTimeoutMillis);
+        } finally {
+            mGatt.close();
+        }
+    }
+
+    /** onConnected callback. */
+    public void onConnected() {
+        Log.d(TAG, "onConnected");
+        mIsConnected = true;
+    }
+
+    /** onClosed callback. */
+    public void onClosed() {
+        Log.d(TAG, "onClosed");
+        if (!mIsConnected) {
+            return;
+        }
+        mIsConnected = false;
+        for (ConnectionCloseListener listener : mCloseListeners) {
+            listener.onClose();
+        }
+        mGatt.close();
+    }
+
+    /**
+     * Observer to wait or be called back when value change.
+     */
+    public static class ChangeObserver {
+
+        private final BlockingDeque<byte[]> mValues = new LinkedBlockingDeque<byte[]>();
+
+        @GuardedBy("mValues")
+        @Nullable
+        private volatile CharacteristicChangeListener mListener;
+
+        /**
+         * Set listener.
+         */
+        public void setListener(@Nullable CharacteristicChangeListener listener) {
+            synchronized (mValues) {
+                mListener = listener;
+                if (listener != null) {
+                    byte[] value;
+                    while ((value = mValues.poll()) != null) {
+                        listener.onValueChange(value);
+                    }
+                }
+            }
+        }
+
+        /**
+         * onValueChange callback.
+         */
+        public void onValueChange(byte[] newValue) {
+            synchronized (mValues) {
+                CharacteristicChangeListener listener = mListener;
+                if (listener == null) {
+                    mValues.add(newValue);
+                } else {
+                    listener.onValueChange(newValue);
+                }
+            }
+        }
+
+        /**
+         * Waits for update for a given time.
+         */
+        public byte[] waitForUpdate(long timeoutMillis) throws BluetoothException {
+            byte[] result;
+            try {
+                result = mValues.poll(timeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                throw new BluetoothException("Operation interrupted.");
+            }
+            if (result == null) {
+                throw new BluetoothTimeoutException(
+                        String.format("Operation timed out after %dms", timeoutMillis));
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Listener for characteristic data changes over notifications or indications.
+     */
+    public interface CharacteristicChangeListener {
+
+        /**
+         * onValueChange callback.
+         */
+        void onValueChange(byte[] newValue);
+    }
+
+    /**
+     * Listener for connection close events.
+     */
+    public interface ConnectionCloseListener {
+
+        /**
+         * onClose callback.
+         */
+        void onClose();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelper.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelper.java
new file mode 100644
index 0000000..18a9f5f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelper.java
@@ -0,0 +1,690 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.gatt;
+
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanSettings;
+import android.content.Context;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothAdapter;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattCallback;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattWrapper;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.BluetoothLeScanner;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.ScanCallback;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.ScanResult;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.BluetoothOperationTimeoutException;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.Operation;
+
+import com.google.common.base.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * Wrapper of {@link BluetoothGattWrapper} that provides blocking methods, errors and timeout
+ * handling.
+ */
+@SuppressWarnings("Guava") // java.util.Optional is not available until API 24
+public class BluetoothGattHelper {
+
+    private static final String TAG = BluetoothGattHelper.class.getSimpleName();
+
+    @VisibleForTesting
+    static final long LOW_LATENCY_SCAN_MILLIS = TimeUnit.SECONDS.toMillis(5);
+    private static final long POLL_INTERVAL_MILLIS = 5L /* milliseconds */;
+
+    /**
+     * BT operation types that can be in flight.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            value = {
+                    OperationType.SCAN,
+                    OperationType.CONNECT,
+                    OperationType.DISCOVER_SERVICES,
+                    OperationType.DISCOVER_SERVICES_INTERNAL,
+                    OperationType.NOTIFICATION_CHANGE,
+                    OperationType.READ_CHARACTERISTIC,
+                    OperationType.WRITE_CHARACTERISTIC,
+                    OperationType.READ_DESCRIPTOR,
+                    OperationType.WRITE_DESCRIPTOR,
+                    OperationType.READ_RSSI,
+                    OperationType.WRITE_RELIABLE,
+                    OperationType.CHANGE_MTU,
+                    OperationType.DISCONNECT,
+            })
+    public @interface OperationType {
+        int SCAN = 0;
+        int CONNECT = 1;
+        int DISCOVER_SERVICES = 2;
+        int DISCOVER_SERVICES_INTERNAL = 3;
+        int NOTIFICATION_CHANGE = 4;
+        int READ_CHARACTERISTIC = 5;
+        int WRITE_CHARACTERISTIC = 6;
+        int READ_DESCRIPTOR = 7;
+        int WRITE_DESCRIPTOR = 8;
+        int READ_RSSI = 9;
+        int WRITE_RELIABLE = 10;
+        int CHANGE_MTU = 11;
+        int DISCONNECT = 12;
+    }
+
+    @VisibleForTesting
+    final ScanCallback mScanCallback = new InternalScanCallback();
+    @VisibleForTesting
+    final BluetoothGattCallback mBluetoothGattCallback =
+            new InternalBluetoothGattCallback();
+    @VisibleForTesting
+    final ConcurrentMap<BluetoothGattWrapper, BluetoothGattConnection> mConnections =
+            new ConcurrentHashMap<>();
+
+    private final Context mApplicationContext;
+    private final BluetoothAdapter mBluetoothAdapter;
+    private final BluetoothOperationExecutor mBluetoothOperationExecutor;
+
+    @VisibleForTesting
+    BluetoothGattHelper(
+            Context applicationContext,
+            BluetoothAdapter bluetoothAdapter,
+            BluetoothOperationExecutor bluetoothOperationExecutor) {
+        mApplicationContext = applicationContext;
+        mBluetoothAdapter = bluetoothAdapter;
+        mBluetoothOperationExecutor = bluetoothOperationExecutor;
+    }
+
+    public BluetoothGattHelper(Context applicationContext, BluetoothAdapter bluetoothAdapter) {
+        this(
+                Preconditions.checkNotNull(applicationContext),
+                Preconditions.checkNotNull(bluetoothAdapter),
+                new BluetoothOperationExecutor(5));
+    }
+
+    /**
+     * Auto-connects a serice Uuid.
+     */
+    public BluetoothGattConnection autoConnect(final UUID serviceUuid) throws BluetoothException {
+        Log.d(TAG, String.format("Starting autoconnection to a device advertising service %s.",
+                serviceUuid));
+        BluetoothDevice device = null;
+        int retries = 3;
+        final BluetoothLeScanner scanner = mBluetoothAdapter.getBluetoothLeScanner();
+        if (scanner == null) {
+            throw new BluetoothException("Bluetooth is disabled or LE is not supported.");
+        }
+        final ScanFilter serviceFilter = new ScanFilter.Builder()
+                .setServiceUuid(new ParcelUuid(serviceUuid))
+                .build();
+        ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder()
+                .setReportDelay(0);
+        final ScanSettings scanSettingsLowLatency = scanSettingsBuilder
+                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
+                .build();
+        final ScanSettings scanSettingsLowPower = scanSettingsBuilder
+                .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
+                .build();
+        while (true) {
+            long startTimeMillis = System.currentTimeMillis();
+            try {
+                Log.d(TAG, "Starting low latency scanning.");
+                device =
+                        mBluetoothOperationExecutor.executeNonnull(
+                                new Operation<BluetoothDevice>(OperationType.SCAN) {
+                                    @Override
+                                    public void run() throws BluetoothException {
+                                        scanner.startScan(Arrays.asList(serviceFilter),
+                                                scanSettingsLowLatency, mScanCallback);
+                                    }
+                                }, LOW_LATENCY_SCAN_MILLIS);
+            } catch (BluetoothOperationTimeoutException e) {
+                Log.d(TAG, String.format(
+                        "Cannot find a nearby device in low latency scanning after %s ms.",
+                        LOW_LATENCY_SCAN_MILLIS));
+            } finally {
+                scanner.stopScan(mScanCallback);
+            }
+            if (device == null) {
+                Log.d(TAG, "Starting low power scanning.");
+                try {
+                    device = mBluetoothOperationExecutor.executeNonnull(
+                            new Operation<BluetoothDevice>(OperationType.SCAN) {
+                                @Override
+                                public void run() throws BluetoothException {
+                                    scanner.startScan(Arrays.asList(serviceFilter),
+                                            scanSettingsLowPower, mScanCallback);
+                                }
+                            });
+                } finally {
+                    scanner.stopScan(mScanCallback);
+                }
+            }
+            Log.d(TAG, String.format("Scanning done in %d ms. Found device %s.",
+                    System.currentTimeMillis() - startTimeMillis, device));
+
+            try {
+                return connect(device);
+            } catch (BluetoothException e) {
+                retries--;
+                if (retries == 0) {
+                    throw e;
+                } else {
+                    Log.d(TAG, String.format(
+                            "Connection failed: %s. Retrying %d more times.", e, retries));
+                }
+            }
+        }
+    }
+
+    /**
+     * Connects to a device using default connection options.
+     */
+    public BluetoothGattConnection connect(BluetoothDevice bluetoothDevice)
+            throws BluetoothException {
+        return connect(bluetoothDevice, ConnectionOptions.builder().build());
+    }
+
+    /**
+     * Connects to a device using specifies connection options.
+     */
+    public BluetoothGattConnection connect(
+            BluetoothDevice bluetoothDevice, ConnectionOptions options) throws BluetoothException {
+        Log.d(TAG, String.format("Connecting to device %s.", bluetoothDevice));
+        long startTimeMillis = System.currentTimeMillis();
+
+        Operation<BluetoothGattConnection> connectOperation =
+                new Operation<BluetoothGattConnection>(OperationType.CONNECT, bluetoothDevice) {
+                    private final Object mLock = new Object();
+
+                    @GuardedBy("mLock")
+                    private boolean mIsCanceled = false;
+
+                    @GuardedBy("mLock")
+                    @Nullable(/* null before operation is executed */)
+                    private BluetoothGattWrapper mBluetoothGatt;
+
+                    @Override
+                    public void run() throws BluetoothException {
+                        synchronized (mLock) {
+                            if (mIsCanceled) {
+                                return;
+                            }
+                            BluetoothGattWrapper bluetoothGattWrapper;
+                            Log.d(TAG, "Use LE transport");
+                            bluetoothGattWrapper =
+                                    bluetoothDevice.connectGatt(
+                                            mApplicationContext,
+                                            options.autoConnect(),
+                                            mBluetoothGattCallback,
+                                            android.bluetooth.BluetoothDevice.TRANSPORT_LE);
+                            if (bluetoothGattWrapper == null) {
+                                throw new BluetoothException("connectGatt() returned null.");
+                            }
+
+                            try {
+                                // Set connection priority without waiting for connection callback.
+                                // Per code, btif_gatt_client.c, when priority is set before
+                                // connection, this sets preferred connection parameters that will
+                                // be used during the connection establishment.
+                                Optional<Integer> connectionPriorityOption =
+                                        options.connectionPriority();
+                                if (connectionPriorityOption.isPresent()) {
+                                    // requestConnectionPriority can only be called when
+                                    // BluetoothGatt is connected to the system BluetoothGatt
+                                    // service (see android/bluetooth/BluetoothGatt.java code).
+                                    // However, there is no callback to the app to inform when this
+                                    // is done. requestConnectionPriority will returns false with no
+                                    // side-effect before the service is connected, so we just poll
+                                    // here until true is returned.
+                                    int connectionPriority = connectionPriorityOption.get();
+                                    long startTimeMillis = System.currentTimeMillis();
+                                    while (!bluetoothGattWrapper.requestConnectionPriority(
+                                            connectionPriority)) {
+                                        if (System.currentTimeMillis() - startTimeMillis
+                                                > options.connectionTimeoutMillis()) {
+                                            throw new BluetoothException(
+                                                    String.format(
+                                                            Locale.US,
+                                                            "Failed to set connectionPriority "
+                                                                    + "after %dms.",
+                                                            options.connectionTimeoutMillis()));
+                                        }
+                                        try {
+                                            Thread.sleep(POLL_INTERVAL_MILLIS);
+                                        } catch (InterruptedException e) {
+                                            Thread.currentThread().interrupt();
+                                            throw new BluetoothException(
+                                                    "connect() operation interrupted.");
+                                        }
+                                    }
+                                }
+                            } catch (Exception e) {
+                                // Make sure to clean connection.
+                                bluetoothGattWrapper.disconnect();
+                                bluetoothGattWrapper.close();
+                                throw e;
+                            }
+
+                            BluetoothGattConnection connection = new BluetoothGattConnection(
+                                    bluetoothGattWrapper, mBluetoothOperationExecutor, options);
+                            mConnections.put(bluetoothGattWrapper, connection);
+                            mBluetoothGatt = bluetoothGattWrapper;
+                        }
+                    }
+
+                    @Override
+                    public void cancel() {
+                        // Clean connection if connection times out.
+                        synchronized (mLock) {
+                            if (mIsCanceled) {
+                                return;
+                            }
+                            mIsCanceled = true;
+                            BluetoothGattWrapper bluetoothGattWrapper = mBluetoothGatt;
+                            if (bluetoothGattWrapper == null) {
+                                return;
+                            }
+                            mConnections.remove(bluetoothGattWrapper);
+                            bluetoothGattWrapper.disconnect();
+                            bluetoothGattWrapper.close();
+                        }
+                    }
+                };
+        BluetoothGattConnection result;
+        if (options.autoConnect()) {
+            result = mBluetoothOperationExecutor.executeNonnull(connectOperation);
+        } else {
+            result =
+                    mBluetoothOperationExecutor.executeNonnull(
+                            connectOperation, options.connectionTimeoutMillis());
+        }
+        Log.d(TAG, String.format("Connection success in %d ms.",
+                System.currentTimeMillis() - startTimeMillis));
+        return result;
+    }
+
+    private BluetoothGattConnection getConnectionByGatt(BluetoothGattWrapper gatt)
+            throws BluetoothException {
+        BluetoothGattConnection connection = mConnections.get(gatt);
+        if (connection == null) {
+            throw new BluetoothException("Receive callback on unexpected device: " + gatt);
+        }
+        return connection;
+    }
+
+    private class InternalBluetoothGattCallback extends BluetoothGattCallback {
+
+        @Override
+        public void onConnectionStateChange(BluetoothGattWrapper gatt, int status, int newState) {
+            BluetoothGattConnection connection;
+            BluetoothDevice device = gatt.getDevice();
+            switch (newState) {
+                case BluetoothGatt.STATE_CONNECTED: {
+                    connection = mConnections.get(gatt);
+                    if (connection == null) {
+                        Log.w(TAG, String.format(
+                                "Received unexpected successful connection for dev %s! Ignoring.",
+                                device));
+                        break;
+                    }
+
+                    Operation<BluetoothGattConnection> operation =
+                            new Operation<>(OperationType.CONNECT, device);
+                    if (status != BluetoothGatt.GATT_SUCCESS) {
+                        mConnections.remove(gatt);
+                        gatt.disconnect();
+                        gatt.close();
+                        mBluetoothOperationExecutor.notifyCompletion(operation, status, null);
+                        break;
+                    }
+
+                    // Process connection options
+                    ConnectionOptions options = connection.getConnectionOptions();
+                    Optional<Integer> mtuOption = options.mtu();
+                    if (mtuOption.isPresent()) {
+                        // Requesting MTU and waiting for MTU callback.
+                        boolean success = gatt.requestMtu(mtuOption.get());
+                        if (!success) {
+                            mBluetoothOperationExecutor.notifyFailure(operation,
+                                    new BluetoothException(String.format(Locale.US,
+                                            "Failed to request MTU of %d for dev %s: "
+                                                    + "returned false.",
+                                            mtuOption.get(), device)));
+                            // Make sure to clean connection.
+                            mConnections.remove(gatt);
+                            gatt.disconnect();
+                            gatt.close();
+                        }
+                        break;
+                    }
+
+                    // Connection successful
+                    connection.onConnected();
+                    mBluetoothOperationExecutor.notifyCompletion(operation, status, connection);
+                    break;
+                }
+                case BluetoothGatt.STATE_DISCONNECTED: {
+                    connection = mConnections.remove(gatt);
+                    if (connection == null) {
+                        Log.w(TAG, String.format("Received unexpected disconnection"
+                                + " for device %s! Ignoring.", device));
+                        break;
+                    }
+                    if (!connection.isConnected()) {
+                        // This is a failed connection attempt
+                        if (status == BluetoothGatt.GATT_SUCCESS) {
+                            // This is weird... considering this as a failure
+                            Log.w(TAG, String.format(
+                                    "Received a success for a failed connection "
+                                            + "attempt for device %s! Ignoring.", device));
+                            status = BluetoothGatt.GATT_FAILURE;
+                        }
+                        mBluetoothOperationExecutor
+                                .notifyCompletion(new Operation<BluetoothGattConnection>(
+                                        OperationType.CONNECT, device), status, null);
+                        // Clean Gatt object in every case.
+                        gatt.disconnect();
+                        gatt.close();
+                        break;
+                    }
+                    connection.onClosed();
+                    mBluetoothOperationExecutor.notifyCompletion(
+                            new Operation<>(OperationType.DISCONNECT, device), status);
+                    break;
+                }
+                default:
+                    Log.e(TAG, "Unexpected connection state: " + newState);
+            }
+        }
+
+        @Override
+        public void onMtuChanged(BluetoothGattWrapper gatt, int mtu, int status) {
+            BluetoothGattConnection connection = mConnections.get(gatt);
+            BluetoothDevice device = gatt.getDevice();
+            if (connection == null) {
+                Log.w(TAG, String.format(
+                        "Received unexpected MTU change for device %s! Ignoring.", device));
+                return;
+            }
+            if (connection.isConnected()) {
+                // This is the callback for the deprecated BluetoothGattConnection.requestMtu.
+                mBluetoothOperationExecutor.notifyCompletion(
+                        new Operation<>(OperationType.CHANGE_MTU, gatt), status, mtu);
+            } else {
+                // This is the callback when requesting MTU right after connecting.
+                connection.onConnected();
+                mBluetoothOperationExecutor.notifyCompletion(
+                        new Operation<>(OperationType.CONNECT, device), status, connection);
+                if (status != BluetoothGatt.GATT_SUCCESS) {
+                    Log.w(TAG, String.format(
+                            "%s responds MTU change failed, status %s.", device, status));
+                    // Clean connection if it's failed.
+                    mConnections.remove(gatt);
+                    gatt.disconnect();
+                    gatt.close();
+                    return;
+                }
+            }
+        }
+
+        @Override
+        public void onServicesDiscovered(BluetoothGattWrapper gatt, int status) {
+            mBluetoothOperationExecutor.notifyCompletion(
+                    new Operation<Void>(OperationType.DISCOVER_SERVICES_INTERNAL, gatt), status);
+        }
+
+        @Override
+        public void onCharacteristicRead(BluetoothGattWrapper gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            mBluetoothOperationExecutor.notifyCompletion(
+                    new Operation<byte[]>(OperationType.READ_CHARACTERISTIC, gatt, characteristic),
+                    status, characteristic.getValue());
+        }
+
+        @Override
+        public void onCharacteristicWrite(BluetoothGattWrapper gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            mBluetoothOperationExecutor.notifyCompletion(new Operation<Void>(
+                    OperationType.WRITE_CHARACTERISTIC, gatt, characteristic), status);
+        }
+
+        @Override
+        public void onDescriptorRead(BluetoothGattWrapper gatt, BluetoothGattDescriptor descriptor,
+                int status) {
+            mBluetoothOperationExecutor.notifyCompletion(
+                    new Operation<byte[]>(OperationType.READ_DESCRIPTOR, gatt, descriptor), status,
+                    descriptor.getValue());
+        }
+
+        @Override
+        public void onDescriptorWrite(BluetoothGattWrapper gatt, BluetoothGattDescriptor descriptor,
+                int status) {
+            Log.d(TAG, String.format("onDescriptorWrite %s, %s, %d",
+                    gatt.getDevice(), descriptor.getUuid(), status));
+            mBluetoothOperationExecutor.notifyCompletion(
+                    new Operation<Void>(OperationType.WRITE_DESCRIPTOR, gatt, descriptor), status);
+        }
+
+        @Override
+        public void onReadRemoteRssi(BluetoothGattWrapper gatt, int rssi, int status) {
+            mBluetoothOperationExecutor.notifyCompletion(
+                    new Operation<Integer>(OperationType.READ_RSSI, gatt), status, rssi);
+        }
+
+        @Override
+        public void onReliableWriteCompleted(BluetoothGattWrapper gatt, int status) {
+            mBluetoothOperationExecutor.notifyCompletion(
+                    new Operation<Void>(OperationType.WRITE_RELIABLE, gatt), status);
+        }
+
+        @Override
+        public void onCharacteristicChanged(BluetoothGattWrapper gatt,
+                BluetoothGattCharacteristic characteristic) {
+            byte[] value = characteristic.getValue();
+            if (value == null) {
+                // Value is not supposed to be null, but just to be safe...
+                value = new byte[0];
+            }
+            Log.d(TAG, String.format("Characteristic %s changed, Gatt device: %s",
+                    characteristic.getUuid(), gatt.getDevice()));
+            try {
+                getConnectionByGatt(gatt).onCharacteristicChanged(characteristic, value);
+            } catch (BluetoothException e) {
+                Log.e(TAG, "Error in onCharacteristicChanged", e);
+            }
+        }
+    }
+
+    private class InternalScanCallback extends ScanCallback {
+
+        @Override
+        public void onScanFailed(int errorCode) {
+            String errorMessage;
+            switch (errorCode) {
+                case ScanCallback.SCAN_FAILED_ALREADY_STARTED:
+                    errorMessage = "SCAN_FAILED_ALREADY_STARTED";
+                    break;
+                case ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED:
+                    errorMessage = "SCAN_FAILED_APPLICATION_REGISTRATION_FAILED";
+                    break;
+                case ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED:
+                    errorMessage = "SCAN_FAILED_FEATURE_UNSUPPORTED";
+                    break;
+                case ScanCallback.SCAN_FAILED_INTERNAL_ERROR:
+                    errorMessage = "SCAN_FAILED_INTERNAL_ERROR";
+                    break;
+                default:
+                    errorMessage = "Unknown error code - " + errorCode;
+            }
+            mBluetoothOperationExecutor.notifyFailure(
+                    new Operation<BluetoothDevice>(OperationType.SCAN),
+                    new BluetoothException("Scan failed: " + errorMessage));
+        }
+
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            mBluetoothOperationExecutor.notifySuccess(
+                    new Operation<BluetoothDevice>(OperationType.SCAN), result.getDevice());
+        }
+    }
+
+    /**
+     * Options for {@link #connect}.
+     */
+    public static class ConnectionOptions {
+
+        private boolean mAutoConnect;
+        private long mConnectionTimeoutMillis;
+        private Optional<Integer> mConnectionPriority;
+        private Optional<Integer> mMtu;
+
+        private ConnectionOptions(boolean autoConnect, long connectionTimeoutMillis,
+                Optional<Integer> connectionPriority,
+                Optional<Integer> mtu) {
+            this.mAutoConnect = autoConnect;
+            this.mConnectionTimeoutMillis = connectionTimeoutMillis;
+            this.mConnectionPriority = connectionPriority;
+            this.mMtu = mtu;
+        }
+
+        boolean autoConnect() {
+            return mAutoConnect;
+        }
+
+        long connectionTimeoutMillis() {
+            return mConnectionTimeoutMillis;
+        }
+
+        Optional<Integer> connectionPriority() {
+            return mConnectionPriority;
+        }
+
+        Optional<Integer> mtu() {
+            return mMtu;
+        }
+
+        @Override
+        public String toString() {
+            return "ConnectionOptions{"
+                    + "autoConnect=" + mAutoConnect + ", "
+                    + "connectionTimeoutMillis=" + mConnectionTimeoutMillis + ", "
+                    + "connectionPriority=" + mConnectionPriority + ", "
+                    + "mtu=" + mMtu
+                    + "}";
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o instanceof ConnectionOptions) {
+                ConnectionOptions that = (ConnectionOptions) o;
+                return this.mAutoConnect == that.autoConnect()
+                        && this.mConnectionTimeoutMillis == that.connectionTimeoutMillis()
+                        && this.mConnectionPriority.equals(that.connectionPriority())
+                        && this.mMtu.equals(that.mtu());
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mAutoConnect, mConnectionTimeoutMillis, mConnectionPriority, mMtu);
+        }
+
+        /**
+         * Creates a builder of ConnectionOptions.
+         */
+        public static Builder builder() {
+            return new ConnectionOptions.Builder()
+                    .setAutoConnect(false)
+                    .setConnectionTimeoutMillis(TimeUnit.SECONDS.toMillis(5));
+        }
+
+        /**
+         * Builder for {@link ConnectionOptions}.
+         */
+        public static class Builder {
+
+            private boolean mAutoConnect;
+            private long mConnectionTimeoutMillis;
+            private Optional<Integer> mConnectionPriority = Optional.empty();
+            private Optional<Integer> mMtu = Optional.empty();
+
+            /**
+             * See {@link android.bluetooth.BluetoothDevice#connectGatt}.
+             */
+            public Builder setAutoConnect(boolean autoConnect) {
+                this.mAutoConnect = autoConnect;
+                return this;
+            }
+
+            /**
+             * See {@link android.bluetooth.BluetoothGatt#requestConnectionPriority(int)}.
+             */
+            public Builder setConnectionPriority(int connectionPriority) {
+                this.mConnectionPriority = Optional.of(connectionPriority);
+                return this;
+            }
+
+            /**
+             * See {@link android.bluetooth.BluetoothGatt#requestMtu(int)}.
+             */
+            public Builder setMtu(int mtu) {
+                this.mMtu = Optional.of(mtu);
+                return this;
+            }
+
+            /**
+             * Sets the timeout for the GATT connection.
+             */
+            public Builder setConnectionTimeoutMillis(long connectionTimeoutMillis) {
+                this.mConnectionTimeoutMillis = connectionTimeoutMillis;
+                return this;
+            }
+
+            /**
+             * Builds ConnectionOptions.
+             */
+            public ConnectionOptions build() {
+                return new ConnectionOptions(mAutoConnect, mConnectionTimeoutMillis,
+                        mConnectionPriority, mMtu);
+            }
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/NonnullProvider.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/NonnullProvider.java
new file mode 100644
index 0000000..16abd99
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/NonnullProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability;
+
+/**
+ * Provider that returns non-null instances.
+ *
+ * @param <T> Type of provided instance.
+ */
+public interface NonnullProvider<T> {
+    /** Get a non-null instance. */
+    T get();
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/Testability.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/Testability.java
new file mode 100644
index 0000000..6cfdd78
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/Testability.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability;
+
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothAdapter;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
+
+import javax.annotation.Nullable;
+
+/** Util class to convert from or to testable classes. */
+public class Testability {
+    /** Wraps a Bluetooth device. */
+    public static BluetoothDevice wrap(android.bluetooth.BluetoothDevice bluetoothDevice) {
+        return BluetoothDevice.wrap(bluetoothDevice);
+    }
+
+    /** Wraps a Bluetooth adapter. */
+    @Nullable
+    public static BluetoothAdapter wrap(
+            @Nullable android.bluetooth.BluetoothAdapter bluetoothAdapter) {
+        return BluetoothAdapter.wrap(bluetoothAdapter);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/TimeProvider.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/TimeProvider.java
new file mode 100644
index 0000000..a4de913
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/TimeProvider.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability;
+
+/** Provider of time for testability. */
+public class TimeProvider {
+    public long getTimeMillis() {
+        return System.currentTimeMillis();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/VersionProvider.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/VersionProvider.java
new file mode 100644
index 0000000..f46ea7a
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/VersionProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability;
+
+import android.os.Build.VERSION;
+
+/**
+ * Provider of android sdk version for testability
+ */
+public class VersionProvider {
+    public int getSdkInt() {
+        return VERSION.SDK_INT;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothAdapter.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothAdapter.java
new file mode 100644
index 0000000..afa2a1b
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothAdapter.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.BluetoothLeAdvertiser;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.BluetoothLeScanner;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+/**
+ * Mockable wrapper of {@link android.bluetooth.BluetoothAdapter}.
+ */
+public class BluetoothAdapter {
+    /** See {@link android.bluetooth.BluetoothAdapter#ACTION_REQUEST_ENABLE}. */
+    public static final String ACTION_REQUEST_ENABLE =
+            android.bluetooth.BluetoothAdapter.ACTION_REQUEST_ENABLE;
+
+    /** See {@link android.bluetooth.BluetoothAdapter#ACTION_STATE_CHANGED}. */
+    public static final String ACTION_STATE_CHANGED =
+            android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
+
+    /** See {@link android.bluetooth.BluetoothAdapter#EXTRA_STATE}. */
+    public static final String EXTRA_STATE =
+            android.bluetooth.BluetoothAdapter.EXTRA_STATE;
+
+    /** See {@link android.bluetooth.BluetoothAdapter#STATE_OFF}. */
+    public static final int STATE_OFF =
+            android.bluetooth.BluetoothAdapter.STATE_OFF;
+
+    /** See {@link android.bluetooth.BluetoothAdapter#STATE_ON}. */
+    public static final int STATE_ON =
+            android.bluetooth.BluetoothAdapter.STATE_ON;
+
+    /** See {@link android.bluetooth.BluetoothAdapter#STATE_TURNING_OFF}. */
+    public static final int STATE_TURNING_OFF =
+            android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF;
+
+    /** See {@link android.bluetooth.BluetoothAdapter#STATE_TURNING_ON}. */
+    public static final int STATE_TURNING_ON =
+            android.bluetooth.BluetoothAdapter.STATE_TURNING_ON;
+
+    private final android.bluetooth.BluetoothAdapter mWrappedBluetoothAdapter;
+
+    private BluetoothAdapter(android.bluetooth.BluetoothAdapter bluetoothAdapter) {
+        mWrappedBluetoothAdapter = bluetoothAdapter;
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#disable()}. */
+    public boolean disable() {
+        return mWrappedBluetoothAdapter.disable();
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#enable()}. */
+    public boolean enable() {
+        return mWrappedBluetoothAdapter.enable();
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#getBluetoothLeScanner}. */
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    @Nullable
+    public BluetoothLeScanner getBluetoothLeScanner() {
+        return BluetoothLeScanner.wrap(mWrappedBluetoothAdapter.getBluetoothLeScanner());
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#getBluetoothLeAdvertiser()}. */
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    @Nullable
+    public BluetoothLeAdvertiser getBluetoothLeAdvertiser() {
+        return BluetoothLeAdvertiser.wrap(mWrappedBluetoothAdapter.getBluetoothLeAdvertiser());
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#getBondedDevices()}. */
+    @Nullable
+    public Set<BluetoothDevice> getBondedDevices() {
+        Set<android.bluetooth.BluetoothDevice> bondedDevices =
+                mWrappedBluetoothAdapter.getBondedDevices();
+        if (bondedDevices == null) {
+            return null;
+        }
+        Set<BluetoothDevice> result = new HashSet<BluetoothDevice>();
+        for (android.bluetooth.BluetoothDevice device : bondedDevices) {
+            if (device == null) {
+                continue;
+            }
+            result.add(BluetoothDevice.wrap(device));
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#getRemoteDevice(byte[])}. */
+    public BluetoothDevice getRemoteDevice(byte[] address) {
+        return BluetoothDevice.wrap(mWrappedBluetoothAdapter.getRemoteDevice(address));
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#getRemoteDevice(String)}. */
+    public BluetoothDevice getRemoteDevice(String address) {
+        return BluetoothDevice.wrap(mWrappedBluetoothAdapter.getRemoteDevice(address));
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#isEnabled()}. */
+    public boolean isEnabled() {
+        return mWrappedBluetoothAdapter.isEnabled();
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#isDiscovering()}. */
+    public boolean isDiscovering() {
+        return mWrappedBluetoothAdapter.isDiscovering();
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#startDiscovery()}. */
+    public boolean startDiscovery() {
+        return mWrappedBluetoothAdapter.startDiscovery();
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#cancelDiscovery()}. */
+    public boolean cancelDiscovery() {
+        return mWrappedBluetoothAdapter.cancelDiscovery();
+    }
+
+    /** See {@link android.bluetooth.BluetoothAdapter#getDefaultAdapter()}. */
+    @Nullable
+    public static BluetoothAdapter getDefaultAdapter() {
+        android.bluetooth.BluetoothAdapter adapter =
+                android.bluetooth.BluetoothAdapter.getDefaultAdapter();
+        if (adapter == null) {
+            return null;
+        }
+        return new BluetoothAdapter(adapter);
+    }
+
+    /** Wraps a Bluetooth adapter. */
+    @Nullable
+    public static BluetoothAdapter wrap(
+            @Nullable android.bluetooth.BluetoothAdapter bluetoothAdapter) {
+        if (bluetoothAdapter == null) {
+            return null;
+        }
+        return new BluetoothAdapter(bluetoothAdapter);
+    }
+
+    /** Unwraps a Bluetooth adapter. */
+    public android.bluetooth.BluetoothAdapter unwrap() {
+        return mWrappedBluetoothAdapter;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothDevice.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothDevice.java
new file mode 100644
index 0000000..5b45f61
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothDevice.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth;
+
+import android.annotation.TargetApi;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothSocket;
+import android.content.Context;
+import android.os.ParcelUuid;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+/**
+ * Mockable wrapper of {@link android.bluetooth.BluetoothDevice}.
+ */
+@TargetApi(18)
+public class BluetoothDevice {
+    /** See {@link android.bluetooth.BluetoothDevice#BOND_BONDED}. */
+    public static final int BOND_BONDED = android.bluetooth.BluetoothDevice.BOND_BONDED;
+
+    /** See {@link android.bluetooth.BluetoothDevice#BOND_BONDING}. */
+    public static final int BOND_BONDING = android.bluetooth.BluetoothDevice.BOND_BONDING;
+
+    /** See {@link android.bluetooth.BluetoothDevice#BOND_NONE}. */
+    public static final int BOND_NONE = android.bluetooth.BluetoothDevice.BOND_NONE;
+
+    /** See {@link android.bluetooth.BluetoothDevice#ACTION_ACL_CONNECTED}. */
+    public static final String ACTION_ACL_CONNECTED =
+            android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED;
+
+    /** See {@link android.bluetooth.BluetoothDevice#ACTION_ACL_DISCONNECT_REQUESTED}. */
+    public static final String ACTION_ACL_DISCONNECT_REQUESTED =
+            android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED;
+
+    /** See {@link android.bluetooth.BluetoothDevice#ACTION_ACL_DISCONNECTED}. */
+    public static final String ACTION_ACL_DISCONNECTED =
+            android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECTED;
+
+    /** See {@link android.bluetooth.BluetoothDevice#ACTION_BOND_STATE_CHANGED}. */
+    public static final String ACTION_BOND_STATE_CHANGED =
+            android.bluetooth.BluetoothDevice.ACTION_BOND_STATE_CHANGED;
+
+    /** See {@link android.bluetooth.BluetoothDevice#ACTION_CLASS_CHANGED}. */
+    public static final String ACTION_CLASS_CHANGED =
+            android.bluetooth.BluetoothDevice.ACTION_CLASS_CHANGED;
+
+    /** See {@link android.bluetooth.BluetoothDevice#ACTION_FOUND}. */
+    public static final String ACTION_FOUND = android.bluetooth.BluetoothDevice.ACTION_FOUND;
+
+    /** See {@link android.bluetooth.BluetoothDevice#ACTION_NAME_CHANGED}. */
+    public static final String ACTION_NAME_CHANGED =
+            android.bluetooth.BluetoothDevice.ACTION_NAME_CHANGED;
+
+    /** See {@link android.bluetooth.BluetoothDevice#ACTION_PAIRING_REQUEST}. */
+    // API 19 only
+    public static final String ACTION_PAIRING_REQUEST =
+            "android.bluetooth.device.action.PAIRING_REQUEST";
+
+    /** See {@link android.bluetooth.BluetoothDevice#ACTION_UUID}. */
+    public static final String ACTION_UUID = android.bluetooth.BluetoothDevice.ACTION_UUID;
+
+    /** See {@link android.bluetooth.BluetoothDevice#DEVICE_TYPE_CLASSIC}. */
+    public static final int DEVICE_TYPE_CLASSIC =
+            android.bluetooth.BluetoothDevice.DEVICE_TYPE_CLASSIC;
+
+    /** See {@link android.bluetooth.BluetoothDevice#DEVICE_TYPE_DUAL}. */
+    public static final int DEVICE_TYPE_DUAL = android.bluetooth.BluetoothDevice.DEVICE_TYPE_DUAL;
+
+    /** See {@link android.bluetooth.BluetoothDevice#DEVICE_TYPE_LE}. */
+    public static final int DEVICE_TYPE_LE = android.bluetooth.BluetoothDevice.DEVICE_TYPE_LE;
+
+    /** See {@link android.bluetooth.BluetoothDevice#DEVICE_TYPE_UNKNOWN}. */
+    public static final int DEVICE_TYPE_UNKNOWN =
+            android.bluetooth.BluetoothDevice.DEVICE_TYPE_UNKNOWN;
+
+    /** See {@link android.bluetooth.BluetoothDevice#ERROR}. */
+    public static final int ERROR = android.bluetooth.BluetoothDevice.ERROR;
+
+    /** See {@link android.bluetooth.BluetoothDevice#EXTRA_BOND_STATE}. */
+    public static final String EXTRA_BOND_STATE =
+            android.bluetooth.BluetoothDevice.EXTRA_BOND_STATE;
+
+    /** See {@link android.bluetooth.BluetoothDevice#EXTRA_CLASS}. */
+    public static final String EXTRA_CLASS = android.bluetooth.BluetoothDevice.EXTRA_CLASS;
+
+    /** See {@link android.bluetooth.BluetoothDevice#EXTRA_DEVICE}. */
+    public static final String EXTRA_DEVICE = android.bluetooth.BluetoothDevice.EXTRA_DEVICE;
+
+    /** See {@link android.bluetooth.BluetoothDevice#EXTRA_NAME}. */
+    public static final String EXTRA_NAME = android.bluetooth.BluetoothDevice.EXTRA_NAME;
+
+    /** See {@link android.bluetooth.BluetoothDevice#EXTRA_PAIRING_KEY}. */
+    // API 19 only
+    public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
+
+    /** See {@link android.bluetooth.BluetoothDevice#EXTRA_PAIRING_VARIANT}. */
+    // API 19 only
+    public static final String EXTRA_PAIRING_VARIANT =
+            "android.bluetooth.device.extra.PAIRING_VARIANT";
+
+    /** See {@link android.bluetooth.BluetoothDevice#EXTRA_PREVIOUS_BOND_STATE}. */
+    public static final String EXTRA_PREVIOUS_BOND_STATE =
+            android.bluetooth.BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE;
+
+    /** See {@link android.bluetooth.BluetoothDevice#EXTRA_RSSI}. */
+    public static final String EXTRA_RSSI = android.bluetooth.BluetoothDevice.EXTRA_RSSI;
+
+    /** See {@link android.bluetooth.BluetoothDevice#EXTRA_UUID}. */
+    public static final String EXTRA_UUID = android.bluetooth.BluetoothDevice.EXTRA_UUID;
+
+    /** See {@link android.bluetooth.BluetoothDevice#PAIRING_VARIANT_PASSKEY_CONFIRMATION}. */
+    // API 19 only
+    public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
+
+    /** See {@link android.bluetooth.BluetoothDevice#PAIRING_VARIANT_PIN}. */
+    // API 19 only
+    public static final int PAIRING_VARIANT_PIN = 0;
+
+    private final android.bluetooth.BluetoothDevice mWrappedBluetoothDevice;
+
+    private BluetoothDevice(android.bluetooth.BluetoothDevice bluetoothDevice) {
+        mWrappedBluetoothDevice = bluetoothDevice;
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothDevice#connectGatt(Context, boolean,
+     * android.bluetooth.BluetoothGattCallback)}.
+     */
+    @Nullable(/* when bt service is not available */)
+    public BluetoothGattWrapper connectGatt(Context context, boolean autoConnect,
+            BluetoothGattCallback callback) {
+        android.bluetooth.BluetoothGatt gatt =
+                mWrappedBluetoothDevice.connectGatt(context, autoConnect, callback.unwrap());
+        if (gatt == null) {
+            return null;
+        }
+        return BluetoothGattWrapper.wrap(gatt);
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothDevice#connectGatt(Context, boolean,
+     * android.bluetooth.BluetoothGattCallback, int)}.
+     */
+    @TargetApi(23)
+    @Nullable(/* when bt service is not available */)
+    public BluetoothGattWrapper connectGatt(Context context, boolean autoConnect,
+            BluetoothGattCallback callback, int transport) {
+        android.bluetooth.BluetoothGatt gatt =
+                mWrappedBluetoothDevice.connectGatt(
+                        context, autoConnect, callback.unwrap(), transport);
+        if (gatt == null) {
+            return null;
+        }
+        return BluetoothGattWrapper.wrap(gatt);
+    }
+
+
+    /**
+     * See {@link android.bluetooth.BluetoothDevice#createRfcommSocketToServiceRecord(UUID)}.
+     */
+    public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
+        return mWrappedBluetoothDevice.createRfcommSocketToServiceRecord(uuid);
+    }
+
+    /**
+     * See
+     * {@link android.bluetooth.BluetoothDevice#createInsecureRfcommSocketToServiceRecord(UUID)}.
+     */
+    public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException {
+        return mWrappedBluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#setPin(byte[])}. */
+    @TargetApi(19)
+    public boolean setPairingConfirmation(byte[] pin) {
+        return mWrappedBluetoothDevice.setPin(pin);
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#setPairingConfirmation(boolean)}. */
+    public boolean setPairingConfirmation(boolean confirm) {
+        return mWrappedBluetoothDevice.setPairingConfirmation(confirm);
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#fetchUuidsWithSdp()}. */
+    public boolean fetchUuidsWithSdp() {
+        return mWrappedBluetoothDevice.fetchUuidsWithSdp();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#createBond()}. */
+    public boolean createBond() {
+        return mWrappedBluetoothDevice.createBond();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#getUuids()}. */
+    @Nullable(/* on error */)
+    public ParcelUuid[] getUuids() {
+        return mWrappedBluetoothDevice.getUuids();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#getBondState()}. */
+    public int getBondState() {
+        return mWrappedBluetoothDevice.getBondState();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#getAddress()}. */
+    public String getAddress() {
+        return mWrappedBluetoothDevice.getAddress();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#getBluetoothClass()}. */
+    @Nullable(/* on error */)
+    public BluetoothClass getBluetoothClass() {
+        return mWrappedBluetoothDevice.getBluetoothClass();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#getType()}. */
+    public int getType() {
+        return mWrappedBluetoothDevice.getType();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#getName()}. */
+    @Nullable(/* on error */)
+    public String getName() {
+        return mWrappedBluetoothDevice.getName();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#toString()}. */
+    @Override
+    public String toString() {
+        return mWrappedBluetoothDevice.toString();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#hashCode()}. */
+    @Override
+    public int hashCode() {
+        return mWrappedBluetoothDevice.hashCode();
+    }
+
+    /** See {@link android.bluetooth.BluetoothDevice#equals(Object)}. */
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (o ==  this) {
+            return true;
+        }
+        if (!(o instanceof BluetoothDevice)) {
+            return false;
+        }
+        return mWrappedBluetoothDevice.equals(((BluetoothDevice) o).unwrap());
+    }
+
+    /** Unwraps a Bluetooth device. */
+    public android.bluetooth.BluetoothDevice unwrap() {
+        return mWrappedBluetoothDevice;
+    }
+
+    /** Wraps a Bluetooth device. */
+    public static BluetoothDevice wrap(android.bluetooth.BluetoothDevice bluetoothDevice) {
+        return new BluetoothDevice(bluetoothDevice);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattCallback.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattCallback.java
new file mode 100644
index 0000000..d36cfa2
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattCallback.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth;
+
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+
+/**
+ * Wrapper of {@link android.bluetooth.BluetoothGattCallback} that uses mockable objects.
+ */
+public abstract class BluetoothGattCallback {
+
+    private final android.bluetooth.BluetoothGattCallback mWrappedBluetoothGattCallback =
+            new InternalBluetoothGattCallback();
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattCallback#onConnectionStateChange(
+     * android.bluetooth.BluetoothGatt, int, int)}
+     */
+    public void onConnectionStateChange(BluetoothGattWrapper gatt, int status, int newState) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattCallback#onServicesDiscovered(
+     * android.bluetooth.BluetoothGatt,int)}
+     */
+    public void onServicesDiscovered(BluetoothGattWrapper gatt, int status) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattCallback#onCharacteristicRead(
+     * android.bluetooth.BluetoothGatt, BluetoothGattCharacteristic, int)}
+     */
+    public void onCharacteristicRead(BluetoothGattWrapper gatt, BluetoothGattCharacteristic
+            characteristic, int status) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattCallback#onCharacteristicWrite(
+     * android.bluetooth.BluetoothGatt, BluetoothGattCharacteristic, int)}
+     */
+    public void onCharacteristicWrite(BluetoothGattWrapper gatt,
+            BluetoothGattCharacteristic characteristic, int status) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattCallback#onDescriptorRead(
+     * android.bluetooth.BluetoothGatt, BluetoothGattDescriptor, int)}
+     */
+    public void onDescriptorRead(
+            BluetoothGattWrapper gatt, BluetoothGattDescriptor descriptor, int status) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattCallback#onDescriptorWrite(
+     * android.bluetooth.BluetoothGatt, BluetoothGattDescriptor, int)}
+     */
+    public void onDescriptorWrite(BluetoothGattWrapper gatt, BluetoothGattDescriptor descriptor,
+            int status) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattCallback#onReadRemoteRssi(
+     * android.bluetooth.BluetoothGatt, int, int)}
+     */
+    public void onReadRemoteRssi(BluetoothGattWrapper gatt, int rssi, int status) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattCallback#onReliableWriteCompleted(
+     * android.bluetooth.BluetoothGatt, int)}
+     */
+    public void onReliableWriteCompleted(BluetoothGattWrapper gatt, int status) {}
+
+    /**
+     * See
+     * {@link android.bluetooth.BluetoothGattCallback#onMtuChanged(android.bluetooth.BluetoothGatt,
+     * int, int)}
+     */
+    public void onMtuChanged(BluetoothGattWrapper gatt, int mtu, int status) {}
+
+    /**
+     * See
+     * {@link android.bluetooth.BluetoothGattCallback#onCharacteristicChanged(
+     * android.bluetooth.BluetoothGatt, BluetoothGattCharacteristic)}
+     */
+    public void onCharacteristicChanged(BluetoothGattWrapper gatt,
+            BluetoothGattCharacteristic characteristic) {}
+
+    /** Unwraps a Bluetooth Gatt callback. */
+    public android.bluetooth.BluetoothGattCallback unwrap() {
+        return mWrappedBluetoothGattCallback;
+    }
+
+    /** Forward callback to testable instance. */
+    private class InternalBluetoothGattCallback extends android.bluetooth.BluetoothGattCallback {
+        @Override
+        public void onConnectionStateChange(android.bluetooth.BluetoothGatt gatt, int status,
+                int newState) {
+            BluetoothGattCallback.this.onConnectionStateChange(BluetoothGattWrapper.wrap(gatt),
+                    status, newState);
+        }
+
+        @Override
+        public void onServicesDiscovered(android.bluetooth.BluetoothGatt gatt, int status) {
+            BluetoothGattCallback.this.onServicesDiscovered(BluetoothGattWrapper.wrap(gatt),
+                    status);
+        }
+
+        @Override
+        public void onCharacteristicRead(android.bluetooth.BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            BluetoothGattCallback.this.onCharacteristicRead(
+                    BluetoothGattWrapper.wrap(gatt), characteristic, status);
+        }
+
+        @Override
+        public void onCharacteristicWrite(android.bluetooth.BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            BluetoothGattCallback.this.onCharacteristicWrite(
+                    BluetoothGattWrapper.wrap(gatt), characteristic, status);
+        }
+
+        @Override
+        public void onDescriptorRead(android.bluetooth.BluetoothGatt gatt,
+                BluetoothGattDescriptor descriptor, int status) {
+            BluetoothGattCallback.this.onDescriptorRead(
+                    BluetoothGattWrapper.wrap(gatt), descriptor, status);
+        }
+
+        @Override
+        public void onDescriptorWrite(android.bluetooth.BluetoothGatt gatt,
+                BluetoothGattDescriptor descriptor, int status) {
+            BluetoothGattCallback.this.onDescriptorWrite(
+                    BluetoothGattWrapper.wrap(gatt), descriptor, status);
+        }
+
+        @Override
+        public void onReadRemoteRssi(android.bluetooth.BluetoothGatt gatt, int rssi, int status) {
+            BluetoothGattCallback.this.onReadRemoteRssi(BluetoothGattWrapper.wrap(gatt), rssi,
+                    status);
+        }
+
+        @Override
+        public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt gatt, int status) {
+            BluetoothGattCallback.this.onReliableWriteCompleted(BluetoothGattWrapper.wrap(gatt),
+                    status);
+        }
+
+        @Override
+        public void onMtuChanged(android.bluetooth.BluetoothGatt gatt, int mtu, int status) {
+            BluetoothGattCallback.this.onMtuChanged(BluetoothGattWrapper.wrap(gatt), mtu, status);
+        }
+
+        @Override
+        public void onCharacteristicChanged(android.bluetooth.BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic) {
+            BluetoothGattCallback.this.onCharacteristicChanged(
+                    BluetoothGattWrapper.wrap(gatt), characteristic);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattServer.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattServer.java
new file mode 100644
index 0000000..3f6f361
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattServer.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth;
+
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattService;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+/**
+ * Mockable wrapper of {@link android.bluetooth.BluetoothGattServer}.
+ */
+public class BluetoothGattServer {
+
+    /** See {@link android.bluetooth.BluetoothGattServer#STATE_CONNECTED}. */
+    public static final int STATE_CONNECTED = android.bluetooth.BluetoothGattServer.STATE_CONNECTED;
+
+    /** See {@link android.bluetooth.BluetoothGattServer#STATE_DISCONNECTED}. */
+    public static final int STATE_DISCONNECTED =
+            android.bluetooth.BluetoothGattServer.STATE_DISCONNECTED;
+
+    private android.bluetooth.BluetoothGattServer mWrappedInstance;
+
+    private BluetoothGattServer(android.bluetooth.BluetoothGattServer instance) {
+        mWrappedInstance = instance;
+    }
+
+    /** Wraps a Bluetooth Gatt server. */
+    @Nullable
+    public static BluetoothGattServer wrap(
+            @Nullable android.bluetooth.BluetoothGattServer instance) {
+        if (instance == null) {
+            return null;
+        }
+        return new BluetoothGattServer(instance);
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServer#connect(
+     * android.bluetooth.BluetoothDevice, boolean)}
+     */
+    public boolean connect(BluetoothDevice device, boolean autoConnect) {
+        return mWrappedInstance.connect(device.unwrap(), autoConnect);
+    }
+
+    /** See {@link android.bluetooth.BluetoothGattServer#addService(BluetoothGattService)}. */
+    public boolean addService(BluetoothGattService service) {
+        return mWrappedInstance.addService(service);
+    }
+
+    /** See {@link android.bluetooth.BluetoothGattServer#clearServices()}. */
+    public void clearServices() {
+        mWrappedInstance.clearServices();
+    }
+
+    /** See {@link android.bluetooth.BluetoothGattServer#close()}. */
+    public void close() {
+        mWrappedInstance.close();
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServer#notifyCharacteristicChanged(
+     * android.bluetooth.BluetoothDevice, BluetoothGattCharacteristic, boolean)}.
+     */
+    public boolean notifyCharacteristicChanged(BluetoothDevice device,
+            BluetoothGattCharacteristic characteristic, boolean confirm) {
+        return mWrappedInstance.notifyCharacteristicChanged(
+                device.unwrap(), characteristic, confirm);
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServer#sendResponse(
+     * android.bluetooth.BluetoothDevice, int, int, int, byte[])}.
+     */
+    public void sendResponse(BluetoothDevice device, int requestId, int status, int offset,
+            @Nullable byte[] value) {
+        mWrappedInstance.sendResponse(device.unwrap(), requestId, status, offset, value);
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServer#cancelConnection(
+     * android.bluetooth.BluetoothDevice)}.
+     */
+    public void cancelConnection(BluetoothDevice device) {
+        mWrappedInstance.cancelConnection(device.unwrap());
+    }
+
+    /** See {@link android.bluetooth.BluetoothGattServer#getService(UUID uuid)}. */
+    public BluetoothGattService getService(UUID uuid) {
+        return mWrappedInstance.getService(uuid);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattServerCallback.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattServerCallback.java
new file mode 100644
index 0000000..875dad5
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattServerCallback.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth;
+
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+
+/**
+ * Wrapper of {@link android.bluetooth.BluetoothGattServerCallback} that uses mockable objects.
+ */
+public abstract class BluetoothGattServerCallback {
+
+    private final android.bluetooth.BluetoothGattServerCallback mWrappedInstance =
+            new InternalBluetoothGattServerCallback();
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServerCallback#onCharacteristicReadRequest(
+     * android.bluetooth.BluetoothDevice, int, int, BluetoothGattCharacteristic)}
+     */
+    public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
+            int offset, BluetoothGattCharacteristic characteristic) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServerCallback#onCharacteristicWriteRequest(
+     * android.bluetooth.BluetoothDevice, int, BluetoothGattCharacteristic, boolean, boolean, int,
+     * byte[])}
+     */
+    public void onCharacteristicWriteRequest(BluetoothDevice device,
+            int requestId,
+            BluetoothGattCharacteristic characteristic,
+            boolean preparedWrite,
+            boolean responseNeeded,
+            int offset,
+            byte[] value) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServerCallback#onConnectionStateChange(
+     * android.bluetooth.BluetoothDevice, int, int)}
+     */
+    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServerCallback#onDescriptorReadRequest(
+     * android.bluetooth.BluetoothDevice, int, int, BluetoothGattDescriptor)}
+     */
+    public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset,
+            BluetoothGattDescriptor descriptor) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServerCallback#onDescriptorWriteRequest(
+     * android.bluetooth.BluetoothDevice, int, BluetoothGattDescriptor, boolean, boolean, int,
+     * byte[])}
+     */
+    public void onDescriptorWriteRequest(BluetoothDevice device,
+            int requestId,
+            BluetoothGattDescriptor descriptor,
+            boolean preparedWrite,
+            boolean responseNeeded,
+            int offset,
+            byte[] value) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServerCallback#onExecuteWrite(
+     * android.bluetooth.BluetoothDevice, int, boolean)}
+     */
+    public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServerCallback#onMtuChanged(
+     * android.bluetooth.BluetoothDevice, int)}
+     */
+    public void onMtuChanged(BluetoothDevice device, int mtu) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServerCallback#onNotificationSent(
+     * android.bluetooth.BluetoothDevice, int)}
+     */
+    public void onNotificationSent(BluetoothDevice device, int status) {}
+
+    /**
+     * See {@link android.bluetooth.BluetoothGattServerCallback#onServiceAdded(int,
+     * BluetoothGattService)}
+     */
+    public void onServiceAdded(int status, BluetoothGattService service) {}
+
+    /** Unwraps a Bluetooth Gatt server callback. */
+    public android.bluetooth.BluetoothGattServerCallback unwrap() {
+        return mWrappedInstance;
+    }
+
+    /** Forward callback to testable instance. */
+    private class InternalBluetoothGattServerCallback extends
+            android.bluetooth.BluetoothGattServerCallback {
+        @Override
+        public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice device,
+                int requestId, int offset, BluetoothGattCharacteristic characteristic) {
+            BluetoothGattServerCallback.this.onCharacteristicReadRequest(
+                    BluetoothDevice.wrap(device), requestId, offset, characteristic);
+        }
+
+        @Override
+        public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice device,
+                int requestId,
+                BluetoothGattCharacteristic characteristic,
+                boolean preparedWrite,
+                boolean responseNeeded,
+                int offset,
+                byte[] value) {
+            BluetoothGattServerCallback.this.onCharacteristicWriteRequest(
+                    BluetoothDevice.wrap(device),
+                    requestId,
+                    characteristic,
+                    preparedWrite,
+                    responseNeeded,
+                    offset,
+                    value);
+        }
+
+        @Override
+        public void onConnectionStateChange(android.bluetooth.BluetoothDevice device, int status,
+                int newState) {
+            BluetoothGattServerCallback.this.onConnectionStateChange(
+                    BluetoothDevice.wrap(device), status, newState);
+        }
+
+        @Override
+        public void onDescriptorReadRequest(android.bluetooth.BluetoothDevice device, int requestId,
+                int offset, BluetoothGattDescriptor descriptor) {
+            BluetoothGattServerCallback.this.onDescriptorReadRequest(BluetoothDevice.wrap(device),
+                    requestId, offset, descriptor);
+        }
+
+        @Override
+        public void onDescriptorWriteRequest(android.bluetooth.BluetoothDevice device,
+                int requestId,
+                BluetoothGattDescriptor descriptor,
+                boolean preparedWrite,
+                boolean responseNeeded,
+                int offset,
+                byte[] value) {
+            BluetoothGattServerCallback.this.onDescriptorWriteRequest(BluetoothDevice.wrap(device),
+                    requestId,
+                    descriptor,
+                    preparedWrite,
+                    responseNeeded,
+                    offset,
+                    value);
+        }
+
+        @Override
+        public void onExecuteWrite(android.bluetooth.BluetoothDevice device, int requestId,
+                boolean execute) {
+            BluetoothGattServerCallback.this.onExecuteWrite(BluetoothDevice.wrap(device), requestId,
+                    execute);
+        }
+
+        @Override
+        public void onMtuChanged(android.bluetooth.BluetoothDevice device, int mtu) {
+            BluetoothGattServerCallback.this.onMtuChanged(BluetoothDevice.wrap(device), mtu);
+        }
+
+        @Override
+        public void onNotificationSent(android.bluetooth.BluetoothDevice device, int status) {
+            BluetoothGattServerCallback.this.onNotificationSent(
+                    BluetoothDevice.wrap(device), status);
+        }
+
+        @Override
+        public void onServiceAdded(int status, BluetoothGattService service) {
+            BluetoothGattServerCallback.this.onServiceAdded(status, service);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattWrapper.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattWrapper.java
new file mode 100644
index 0000000..453ee5d
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattWrapper.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth;
+
+import android.annotation.TargetApi;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.os.Build;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+/** Mockable wrapper of {@link android.bluetooth.BluetoothGatt}. */
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
+public class BluetoothGattWrapper {
+    private final android.bluetooth.BluetoothGatt mWrappedBluetoothGatt;
+
+    private BluetoothGattWrapper(android.bluetooth.BluetoothGatt bluetoothGatt) {
+        mWrappedBluetoothGatt = bluetoothGatt;
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#getDevice()}. */
+    public BluetoothDevice getDevice() {
+        return BluetoothDevice.wrap(mWrappedBluetoothGatt.getDevice());
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#getServices()}. */
+    public List<BluetoothGattService> getServices() {
+        return mWrappedBluetoothGatt.getServices();
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#getService(UUID)}. */
+    @Nullable(/* null if service is not found */)
+    public BluetoothGattService getService(UUID uuid) {
+        return mWrappedBluetoothGatt.getService(uuid);
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#discoverServices()}. */
+    public boolean discoverServices() {
+        return mWrappedBluetoothGatt.discoverServices();
+    }
+
+    /**
+     * Hidden method. Clears the internal cache and forces a refresh of the services from the remote
+     * device.
+     */
+    // TODO(b/201300471): remove refresh call using reflection.
+    public boolean refresh() {
+        try {
+            Method refreshMethod = android.bluetooth.BluetoothGatt.class.getMethod("refresh");
+            return (Boolean) refreshMethod.invoke(mWrappedBluetoothGatt);
+        } catch (NoSuchMethodException
+            | IllegalAccessException
+            | IllegalArgumentException
+            | InvocationTargetException e) {
+            return false;
+        }
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)}.
+     */
+    public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
+        return mWrappedBluetoothGatt.readCharacteristic(characteristic);
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic,
+     * byte[], int)} .
+     */
+    public int writeCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value,
+            int writeType) {
+        return mWrappedBluetoothGatt.writeCharacteristic(characteristic, value, writeType);
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#readDescriptor(BluetoothGattDescriptor)}. */
+    public boolean readDescriptor(BluetoothGattDescriptor descriptor) {
+        return mWrappedBluetoothGatt.readDescriptor(descriptor);
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothGatt#writeDescriptor(BluetoothGattDescriptor,
+     * byte[])}.
+     */
+    public int writeDescriptor(BluetoothGattDescriptor descriptor, byte[] value) {
+        return mWrappedBluetoothGatt.writeDescriptor(descriptor, value);
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#readRemoteRssi()}. */
+    public boolean readRemoteRssi() {
+        return mWrappedBluetoothGatt.readRemoteRssi();
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#requestConnectionPriority(int)}. */
+    public boolean requestConnectionPriority(int connectionPriority) {
+        return mWrappedBluetoothGatt.requestConnectionPriority(connectionPriority);
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#requestMtu(int)}. */
+    public boolean requestMtu(int mtu) {
+        return mWrappedBluetoothGatt.requestMtu(mtu);
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#setCharacteristicNotification}. */
+    public boolean setCharacteristicNotification(
+            BluetoothGattCharacteristic characteristic, boolean enable) {
+        return mWrappedBluetoothGatt.setCharacteristicNotification(characteristic, enable);
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#disconnect()}. */
+    public void disconnect() {
+        mWrappedBluetoothGatt.disconnect();
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#close()}. */
+    public void close() {
+        mWrappedBluetoothGatt.close();
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#hashCode()}. */
+    @Override
+    public int hashCode() {
+        return mWrappedBluetoothGatt.hashCode();
+    }
+
+    /** See {@link android.bluetooth.BluetoothGatt#equals(Object)}. */
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (!(o instanceof BluetoothGattWrapper)) {
+            return false;
+        }
+        return mWrappedBluetoothGatt.equals(((BluetoothGattWrapper) o).unwrap());
+    }
+
+    /** Unwraps a Bluetooth Gatt instance. */
+    public android.bluetooth.BluetoothGatt unwrap() {
+        return mWrappedBluetoothGatt;
+    }
+
+    /** Wraps a Bluetooth Gatt instance. */
+    public static BluetoothGattWrapper wrap(android.bluetooth.BluetoothGatt gatt) {
+        return new BluetoothGattWrapper(gatt);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/BluetoothLeAdvertiser.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/BluetoothLeAdvertiser.java
new file mode 100644
index 0000000..6fe4432
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth.le;
+
+import android.annotation.TargetApi;
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.os.Build;
+
+import javax.annotation.Nullable;
+
+/**
+ * Mockable wrapper of {@link android.bluetooth.le.BluetoothLeAdvertiser}.
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class BluetoothLeAdvertiser {
+
+    private final android.bluetooth.le.BluetoothLeAdvertiser mWrappedInstance;
+
+    private BluetoothLeAdvertiser(
+            android.bluetooth.le.BluetoothLeAdvertiser bluetoothLeAdvertiser) {
+        mWrappedInstance = bluetoothLeAdvertiser;
+    }
+
+    /**
+     * See {@link android.bluetooth.le.BluetoothLeAdvertiser#startAdvertising(AdvertiseSettings,
+     * AdvertiseData, AdvertiseCallback)}.
+     */
+    public void startAdvertising(AdvertiseSettings settings, AdvertiseData advertiseData,
+            AdvertiseCallback callback) {
+        mWrappedInstance.startAdvertising(settings, advertiseData, callback);
+    }
+
+    /**
+     * See {@link android.bluetooth.le.BluetoothLeAdvertiser#startAdvertising(AdvertiseSettings,
+     * AdvertiseData, AdvertiseData, AdvertiseCallback)}.
+     */
+    public void startAdvertising(AdvertiseSettings settings, AdvertiseData advertiseData,
+            AdvertiseData scanResponse, AdvertiseCallback callback) {
+        mWrappedInstance.startAdvertising(settings, advertiseData, scanResponse, callback);
+    }
+
+    /**
+     * See {@link android.bluetooth.le.BluetoothLeAdvertiser#stopAdvertising(AdvertiseCallback)}.
+     */
+    public void stopAdvertising(AdvertiseCallback callback) {
+        mWrappedInstance.stopAdvertising(callback);
+    }
+
+    /** Wraps a Bluetooth LE advertiser. */
+    @Nullable
+    public static BluetoothLeAdvertiser wrap(
+            @Nullable android.bluetooth.le.BluetoothLeAdvertiser bluetoothLeAdvertiser) {
+        if (bluetoothLeAdvertiser == null) {
+            return null;
+        }
+        return new BluetoothLeAdvertiser(bluetoothLeAdvertiser);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/BluetoothLeScanner.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/BluetoothLeScanner.java
new file mode 100644
index 0000000..8a13abe
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/BluetoothLeScanner.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth.le;
+
+import android.annotation.TargetApi;
+import android.app.PendingIntent;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanSettings;
+import android.os.Build;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * Mockable wrapper of {@link android.bluetooth.le.BluetoothLeScanner}.
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class BluetoothLeScanner {
+
+    private final android.bluetooth.le.BluetoothLeScanner mWrappedBluetoothLeScanner;
+
+    private BluetoothLeScanner(android.bluetooth.le.BluetoothLeScanner bluetoothLeScanner) {
+        mWrappedBluetoothLeScanner = bluetoothLeScanner;
+    }
+
+    /**
+     * See {@link android.bluetooth.le.BluetoothLeScanner#startScan(List, ScanSettings,
+     * android.bluetooth.le.ScanCallback)}.
+     */
+    public void startScan(List<ScanFilter> filters, ScanSettings settings,
+            ScanCallback callback) {
+        mWrappedBluetoothLeScanner.startScan(filters, settings, callback.unwrap());
+    }
+
+    /**
+     * See {@link android.bluetooth.le.BluetoothLeScanner#startScan(List, ScanSettings,
+     * PendingIntent)}.
+     */
+    public void startScan(
+            List<ScanFilter> filters, ScanSettings settings, PendingIntent callbackIntent) {
+        mWrappedBluetoothLeScanner.startScan(filters, settings, callbackIntent);
+    }
+
+    /**
+     * See {@link
+     * android.bluetooth.le.BluetoothLeScanner#startScan(android.bluetooth.le.ScanCallback)}.
+     */
+    public void startScan(ScanCallback callback) {
+        mWrappedBluetoothLeScanner.startScan(callback.unwrap());
+    }
+
+    /**
+     * See
+     * {@link android.bluetooth.le.BluetoothLeScanner#stopScan(android.bluetooth.le.ScanCallback)}.
+     */
+    public void stopScan(ScanCallback callback) {
+        mWrappedBluetoothLeScanner.stopScan(callback.unwrap());
+    }
+
+    /** See {@link android.bluetooth.le.BluetoothLeScanner#stopScan(PendingIntent)}. */
+    public void stopScan(PendingIntent callbackIntent) {
+        mWrappedBluetoothLeScanner.stopScan(callbackIntent);
+    }
+
+    /** Wraps a Bluetooth LE scanner. */
+    @Nullable
+    public static BluetoothLeScanner wrap(
+            @Nullable android.bluetooth.le.BluetoothLeScanner bluetoothLeScanner) {
+        if (bluetoothLeScanner == null) {
+            return null;
+        }
+        return new BluetoothLeScanner(bluetoothLeScanner);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/ScanCallback.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/ScanCallback.java
new file mode 100644
index 0000000..70926a7
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/ScanCallback.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth.le;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Wrapper of {@link android.bluetooth.le.ScanCallback} that uses mockable objects.
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public abstract class ScanCallback {
+
+    /** See {@link android.bluetooth.le.ScanCallback#SCAN_FAILED_ALREADY_STARTED} */
+    public static final int SCAN_FAILED_ALREADY_STARTED =
+            android.bluetooth.le.ScanCallback.SCAN_FAILED_ALREADY_STARTED;
+
+    /** See {@link android.bluetooth.le.ScanCallback#SCAN_FAILED_APPLICATION_REGISTRATION_FAILED} */
+    public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED =
+            android.bluetooth.le.ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED;
+
+    /** See {@link android.bluetooth.le.ScanCallback#SCAN_FAILED_FEATURE_UNSUPPORTED} */
+    public static final int SCAN_FAILED_FEATURE_UNSUPPORTED =
+            android.bluetooth.le.ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED;
+
+    /** See {@link android.bluetooth.le.ScanCallback#SCAN_FAILED_INTERNAL_ERROR} */
+    public static final int SCAN_FAILED_INTERNAL_ERROR =
+            android.bluetooth.le.ScanCallback.SCAN_FAILED_INTERNAL_ERROR;
+
+    private final android.bluetooth.le.ScanCallback mWrappedScanCallback =
+            new InternalScanCallback();
+
+    /**
+     * See {@link android.bluetooth.le.ScanCallback#onScanFailed(int)}
+     */
+    public void onScanFailed(int errorCode) {}
+
+    /**
+     * See
+     * {@link android.bluetooth.le.ScanCallback#onScanResult(int, android.bluetooth.le.ScanResult)}.
+     */
+    public void onScanResult(int callbackType, ScanResult result) {}
+
+    /**
+     * See {@link
+     * android.bluetooth.le.ScanCallback#onBatchScanResult(List<android.bluetooth.le.ScanResult>)}.
+     */
+    public void onBatchScanResults(List<ScanResult> results) {}
+
+    /** Unwraps scan callback. */
+    public android.bluetooth.le.ScanCallback unwrap() {
+        return mWrappedScanCallback;
+    }
+
+    /** Forward callback to testable instance. */
+    private class InternalScanCallback extends android.bluetooth.le.ScanCallback {
+        @Override
+        public void onScanFailed(int errorCode) {
+            ScanCallback.this.onScanFailed(errorCode);
+        }
+
+        @Override
+        public void onScanResult(int callbackType, android.bluetooth.le.ScanResult result) {
+            ScanCallback.this.onScanResult(callbackType, ScanResult.wrap(result));
+        }
+
+        @Override
+        public void onBatchScanResults(List<android.bluetooth.le.ScanResult> results) {
+            List<ScanResult> wrappedScanResults = new ArrayList<>();
+            for (android.bluetooth.le.ScanResult result : results) {
+                wrappedScanResults.add(ScanResult.wrap(result));
+            }
+            ScanCallback.this.onBatchScanResults(wrappedScanResults);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/ScanResult.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/ScanResult.java
new file mode 100644
index 0000000..1a6b7b3
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/le/ScanResult.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.testability.android.bluetooth.le;
+
+import android.annotation.TargetApi;
+import android.bluetooth.le.ScanRecord;
+import android.os.Build;
+
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
+
+import javax.annotation.Nullable;
+
+/**
+ * Mockable wrapper of {@link android.bluetooth.le.ScanResult}.
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class ScanResult {
+
+    private final android.bluetooth.le.ScanResult mWrappedScanResult;
+
+    private ScanResult(android.bluetooth.le.ScanResult scanResult) {
+        mWrappedScanResult = scanResult;
+    }
+
+    /** See {@link android.bluetooth.le.ScanResult#getScanRecord()}. */
+    @Nullable
+    public ScanRecord getScanRecord() {
+        return mWrappedScanResult.getScanRecord();
+    }
+
+    /** See {@link android.bluetooth.le.ScanResult#getRssi()}. */
+    public int getRssi() {
+        return mWrappedScanResult.getRssi();
+    }
+
+    /** See {@link android.bluetooth.le.ScanResult#getTimestampNanos()}. */
+    public long getTimestampNanos() {
+        return mWrappedScanResult.getTimestampNanos();
+    }
+
+    /** See {@link android.bluetooth.le.ScanResult#getDevice()}. */
+    public BluetoothDevice getDevice() {
+        return BluetoothDevice.wrap(mWrappedScanResult.getDevice());
+    }
+
+    /** Creates a wrapper of scan result. */
+    public static ScanResult wrap(android.bluetooth.le.ScanResult scanResult) {
+        return new ScanResult(scanResult);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtils.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtils.java
new file mode 100644
index 0000000..bb51920
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtils.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.util;
+
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+
+import javax.annotation.Nullable;
+
+/**
+ * Utils for Gatt profile.
+ */
+public class BluetoothGattUtils {
+
+    /**
+     * Returns a string message for a BluetoothGatt status codes.
+     */
+    public static String getMessageForStatusCode(int statusCode) {
+        switch (statusCode) {
+            case BluetoothGatt.GATT_SUCCESS:
+                return "GATT_SUCCESS";
+            case BluetoothGatt.GATT_FAILURE:
+                return "GATT_FAILURE";
+            case BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION:
+                return "GATT_INSUFFICIENT_AUTHENTICATION";
+            case BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION:
+                return "GATT_INSUFFICIENT_AUTHORIZATION";
+            case BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION:
+                return "GATT_INSUFFICIENT_ENCRYPTION";
+            case BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH:
+                return "GATT_INVALID_ATTRIBUTE_LENGTH";
+            case BluetoothGatt.GATT_INVALID_OFFSET:
+                return "GATT_INVALID_OFFSET";
+            case BluetoothGatt.GATT_READ_NOT_PERMITTED:
+                return "GATT_READ_NOT_PERMITTED";
+            case BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED:
+                return "GATT_REQUEST_NOT_SUPPORTED";
+            case BluetoothGatt.GATT_WRITE_NOT_PERMITTED:
+                return "GATT_WRITE_NOT_PERMITTED";
+            case BluetoothGatt.GATT_CONNECTION_CONGESTED:
+                return "GATT_CONNECTION_CONGESTED";
+            default:
+                return "Unknown error code";
+        }
+    }
+
+    /** Creates a user-readable string from a {@link BluetoothGattDescriptor}. */
+    public static String toString(@Nullable BluetoothGattDescriptor descriptor) {
+        if (descriptor == null) {
+            return "null descriptor";
+        }
+        return String.format("descriptor %s on %s",
+                descriptor.getUuid(),
+                toString(descriptor.getCharacteristic()));
+    }
+
+    /** Creates a user-readable string from a {@link BluetoothGattCharacteristic}. */
+    public static String toString(@Nullable BluetoothGattCharacteristic characteristic) {
+        if (characteristic == null) {
+            return "null characteristic";
+        }
+        return String.format("characteristic %s on %s",
+                characteristic.getUuid(),
+                toString(characteristic.getService()));
+    }
+
+    /** Creates a user-readable string from a {@link BluetoothGattService}. */
+    public static String toString(@Nullable BluetoothGattService service) {
+        if (service == null) {
+            return "null service";
+        }
+        return String.format("service %s", service.getUuid());
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothOperationExecutor.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothOperationExecutor.java
new file mode 100644
index 0000000..fecf483
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothOperationExecutor.java
@@ -0,0 +1,548 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.util;
+
+import android.bluetooth.BluetoothGatt;
+import android.util.Log;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.testability.NonnullProvider;
+import com.android.server.nearby.common.bluetooth.testability.TimeProvider;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.annotation.Nullable;
+
+/**
+ * Scheduler to coordinate parallel bluetooth operations.
+ */
+public class BluetoothOperationExecutor {
+
+    private static final String TAG = BluetoothOperationExecutor.class.getSimpleName();
+
+    /**
+     * Special value to indicate that the result is null (since {@link BlockingQueue} doesn't allow
+     * null elements).
+     */
+    private static final Object NULL_RESULT = new Object();
+
+    /**
+     * Special value to indicate that there should be no timeout on the operation.
+     */
+    private static final long NO_TIMEOUT = -1;
+
+    private final NonnullProvider<BlockingQueue<Object>> mBlockingQueueProvider;
+    private final TimeProvider mTimeProvider;
+    @VisibleForTesting
+    final Map<Operation<?>, Queue<Object>> mOperationResultQueues = new HashMap<>();
+    private final Semaphore mOperationSemaphore;
+
+    /**
+     * New instance that limits concurrent operations to maxConcurrentOperations.
+     */
+    public BluetoothOperationExecutor(int maxConcurrentOperations) {
+        this(
+                new Semaphore(maxConcurrentOperations, true),
+                new TimeProvider(),
+                new NonnullProvider<BlockingQueue<Object>>() {
+                    @Override
+                    public BlockingQueue<Object> get() {
+                        return new LinkedBlockingDeque<Object>();
+                    }
+                });
+    }
+
+    /**
+     * Constructor for unit tests.
+     */
+    @VisibleForTesting
+    BluetoothOperationExecutor(Semaphore operationSemaphore,
+            TimeProvider timeProvider,
+            NonnullProvider<BlockingQueue<Object>> blockingQueueProvider) {
+        mOperationSemaphore = operationSemaphore;
+        mTimeProvider = timeProvider;
+        mBlockingQueueProvider = blockingQueueProvider;
+    }
+
+    /**
+     * Executes the operation and waits for its completion.
+     */
+    @Nullable
+    public <T> T execute(Operation<T> operation) throws BluetoothException {
+        return getResult(schedule(operation));
+    }
+
+    /**
+     * Executes the operation and waits for its completion and returns a non-null result.
+     */
+    public <T> T executeNonnull(Operation<T> operation) throws BluetoothException {
+        T result = getResult(schedule(operation));
+        if (result == null) {
+            throw new BluetoothException(
+                    String.format(Locale.US, "Operation %s returned a null result.", operation));
+        }
+        return result;
+    }
+
+    /**
+     * Executes the operation and waits for its completion with a timeout.
+     */
+    @Nullable
+    public <T> T execute(Operation<T> bluetoothOperation, long timeoutMillis)
+            throws BluetoothException, BluetoothOperationTimeoutException {
+        return getResult(schedule(bluetoothOperation), timeoutMillis);
+    }
+
+    /**
+     * Executes the operation and waits for its completion with a timeout and returns a non-null
+     * result.
+     */
+    public <T> T executeNonnull(Operation<T> bluetoothOperation, long timeoutMillis)
+            throws BluetoothException {
+        T result = getResult(schedule(bluetoothOperation), timeoutMillis);
+        if (result == null) {
+            throw new BluetoothException(
+                    String.format(Locale.US, "Operation %s returned a null result.",
+                            bluetoothOperation));
+        }
+        return result;
+    }
+
+    /**
+     * Schedules an operation and returns a {@link Future} that waits on operation completion and
+     * gets its result.
+     */
+    public <T> Future<T> schedule(Operation<T> bluetoothOperation) {
+        BlockingQueue<Object> resultQueue = mBlockingQueueProvider.get();
+        mOperationResultQueues.put(bluetoothOperation, resultQueue);
+
+        boolean semaphoreAcquired = mOperationSemaphore.tryAcquire();
+        Log.d(TAG, String.format(Locale.US,
+                "Scheduling operation %s; %d permits available; Semaphore acquired: %b",
+                bluetoothOperation,
+                mOperationSemaphore.availablePermits(),
+                semaphoreAcquired));
+
+        if (semaphoreAcquired) {
+            bluetoothOperation.execute(this);
+        }
+        return new BluetoothOperationFuture<T>(resultQueue, bluetoothOperation, semaphoreAcquired);
+    }
+
+    /**
+     * Notifies that this operation has completed with success.
+     */
+    public void notifySuccess(Operation<Void> bluetoothOperation) {
+        postResult(bluetoothOperation, null);
+    }
+
+    /**
+     * Notifies that this operation has completed with success and with a result.
+     */
+    public <T> void notifySuccess(Operation<T> bluetoothOperation, T result) {
+        postResult(bluetoothOperation, result);
+    }
+
+    /**
+     * Notifies that this operation has completed with the given BluetoothGatt status code (which
+     * may indicate success or failure).
+     */
+    public void notifyCompletion(Operation<Void> bluetoothOperation, int status) {
+        notifyCompletion(bluetoothOperation, status, null);
+    }
+
+    /**
+     * Notifies that this operation has completed with the given BluetoothGatt status code (which
+     * may indicate success or failure) and with a result.
+     */
+    public <T> void notifyCompletion(Operation<T> bluetoothOperation, int status,
+            @Nullable T result) {
+        if (status != BluetoothGatt.GATT_SUCCESS) {
+            notifyFailure(bluetoothOperation, new BluetoothGattException(
+                    String.format(Locale.US,
+                            "Operation %s failed: %d - %s.", bluetoothOperation, status,
+                            BluetoothGattUtils.getMessageForStatusCode(status)),
+                    status));
+            return;
+        }
+        postResult(bluetoothOperation, result);
+    }
+
+    /**
+     * Notifies that this operation has completed with failure.
+     */
+    public void notifyFailure(Operation<?> bluetoothOperation, BluetoothException exception) {
+        postResult(bluetoothOperation, exception);
+    }
+
+    private void postResult(Operation<?> bluetoothOperation, @Nullable Object result) {
+        Queue<Object> resultQueue = mOperationResultQueues.get(bluetoothOperation);
+        if (resultQueue == null) {
+            Log.e(TAG, String.format(Locale.US,
+                    "Receive completion for unexpected operation: %s.", bluetoothOperation));
+            return;
+        }
+        resultQueue.add(result == null ? NULL_RESULT : result);
+        mOperationResultQueues.remove(bluetoothOperation);
+        mOperationSemaphore.release();
+        Log.d(TAG, String.format(Locale.US,
+                "Released semaphore for operation %s. There are %d permits left",
+                bluetoothOperation, mOperationSemaphore.availablePermits()));
+    }
+
+    /**
+     * Waits for all future on the list to complete, ignoring the results.
+     */
+    public <T> void waitFor(List<Future<T>> futures) throws BluetoothException {
+        for (Future<T> future : futures) {
+            if (future == null) {
+                continue;
+            }
+            getResult(future);
+        }
+    }
+
+    /**
+     * Waits with timeout for all future on the list to complete, ignoring the results.
+     */
+    public <T> void waitFor(List<Future<T>> futures, long timeoutMillis)
+            throws BluetoothException {
+        long startTime = mTimeProvider.getTimeMillis();
+        for (Future<T> future : futures) {
+            if (future == null) {
+                continue;
+            }
+            getResult(future,
+                    timeoutMillis - (mTimeProvider.getTimeMillis() - startTime));
+        }
+    }
+
+    /**
+     * Waits for a future to complete and returns the result.
+     */
+    @Nullable
+    public static <T> T getResult(Future<T> future) throws BluetoothException {
+        return getResultInternal(future, NO_TIMEOUT);
+    }
+
+    /**
+     * Waits for a future to complete and returns the result with timeout.
+     */
+    @Nullable
+    public static <T> T getResult(Future<T> future, long timeoutMillis) throws BluetoothException {
+        return getResultInternal(future, Math.max(0, timeoutMillis));
+    }
+
+    @Nullable
+    private static <T> T getResultInternal(Future<T> future, long timeoutMillis)
+            throws BluetoothException {
+        try {
+            if (timeoutMillis == NO_TIMEOUT) {
+                return future.get();
+            } else {
+                return future.get(timeoutMillis, TimeUnit.MILLISECONDS);
+            }
+        } catch (InterruptedException e) {
+            try {
+                boolean cancelSuccess = future.cancel(true);
+                if (!cancelSuccess && future.isDone()) {
+                    // Operation has succeeded before we send cancel to it.
+                    return getResultInternal(future, NO_TIMEOUT);
+                }
+            } finally {
+                // Re-interrupt the thread last since we're recursively calling getResultInternal.
+                // We know the future is done, so there's no need to be interrupted while we call.
+                Thread.currentThread().interrupt();
+            }
+            throw new BluetoothException("Wait interrupted");
+        } catch (ExecutionException e) {
+            Throwable cause = e.getCause();
+            if (cause instanceof BluetoothException) {
+                throw (BluetoothException) cause;
+            }
+            throw new RuntimeException(e);
+        } catch (TimeoutException e) {
+            boolean cancelSuccess = future.cancel(true);
+            if (!cancelSuccess && future.isDone()) {
+                // Operation has succeeded before we send cancel to it.
+                return getResultInternal(future, NO_TIMEOUT);
+            }
+            throw new BluetoothOperationTimeoutException(
+                    String.format(Locale.US, "Wait timed out after %s ms.", timeoutMillis), e);
+        }
+    }
+
+    /**
+     * Asynchronous bluetooth operation to schedule.
+     *
+     * <p>An instance that doesn't implemented run() can be used to notify operation result.
+     *
+     * @param <T> Type of provided instance.
+     */
+    public static class Operation<T> {
+
+        private Object[] mElements;
+
+        public Operation(Object... elements) {
+            mElements = elements;
+        }
+
+        /**
+         * Executes operation using executor.
+         */
+        public void execute(BluetoothOperationExecutor executor) {
+            try {
+                run();
+            } catch (BluetoothException e) {
+                executor.postResult(this, e);
+            }
+        }
+
+        /**
+         * Run function. Not supported.
+         */
+        @SuppressWarnings("unused")
+        public void run() throws BluetoothException {
+            throw new RuntimeException("Not implemented");
+        }
+
+        /**
+         * Try to cancel operation when a timeout occurs.
+         */
+        public void cancel() {
+        }
+
+        @Override
+        public boolean equals(@Nullable Object o) {
+            if (o == null) {
+                return false;
+            }
+            if (!Operation.class.isInstance(o)) {
+                return false;
+            }
+            Operation<?> other = (Operation<?>) o;
+            return Arrays.equals(mElements, other.mElements);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(mElements);
+        }
+
+        @Override
+        public String toString() {
+            return Joiner.on('-').join(mElements);
+        }
+    }
+
+    /**
+     * Synchronous bluetooth operation to schedule.
+     *
+     * @param <T> Type of provided instance.
+     */
+    public static class SynchronousOperation<T> extends Operation<T> {
+
+        public SynchronousOperation(Object... elements) {
+            super(elements);
+        }
+
+        @Override
+        public void execute(BluetoothOperationExecutor executor) {
+            try {
+                Object result = call();
+                if (result == null) {
+                    result = NULL_RESULT;
+                }
+                executor.postResult(this, result);
+            } catch (BluetoothException e) {
+                executor.postResult(this, e);
+            }
+        }
+
+        /**
+         * Call function. Not supported.
+         */
+        @SuppressWarnings("unused")
+        @Nullable
+        public T call() throws BluetoothException {
+            throw new RuntimeException("Not implemented");
+        }
+    }
+
+    /**
+     * {@link Future} to wait / get result of an operation.
+     *
+     * <li>Waits for operation to complete
+     * <li>Handles timeouts if needed
+     * <li>Queues identical Bluetooth operations
+     * <li>Unwraps Exceptions and null values
+     */
+    private class BluetoothOperationFuture<T> implements Future<T> {
+
+        private final Object mLock = new Object();
+
+        /**
+         * Queue that will be used to store the result. It should normally contains one element
+         * maximum, but using a queue avoid some race conditions.
+         */
+        private final BlockingQueue<Object> mResultQueue;
+        private final Operation<T> mBluetoothOperation;
+        private final boolean mOperationExecuted;
+        private boolean mIsCancelled = false;
+        private boolean mIsDone = false;
+
+        BluetoothOperationFuture(BlockingQueue<Object> resultQueue,
+                Operation<T> bluetoothOperation, boolean operationExecuted) {
+            mResultQueue = resultQueue;
+            mBluetoothOperation = bluetoothOperation;
+            mOperationExecuted = operationExecuted;
+        }
+
+        @Override
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            synchronized (mLock) {
+                if (mIsDone) {
+                    return false;
+                }
+                if (mIsCancelled) {
+                    return true;
+                }
+                mBluetoothOperation.cancel();
+                mIsCancelled = true;
+                notifyFailure(mBluetoothOperation, new BluetoothException("Operation cancelled."));
+                return true;
+            }
+        }
+
+        @Override
+        public boolean isCancelled() {
+            synchronized (mLock) {
+                return mIsCancelled;
+            }
+        }
+
+        @Override
+        public boolean isDone() {
+            synchronized (mLock) {
+                return mIsDone;
+            }
+        }
+
+        @Override
+        @Nullable
+        public T get() throws InterruptedException, ExecutionException {
+            try {
+                return getInternal(NO_TIMEOUT, TimeUnit.MILLISECONDS);
+            } catch (TimeoutException e) {
+                throw new RuntimeException(e); // This is not supposed to be thrown
+            }
+        }
+
+        @Override
+        @Nullable
+        public T get(long timeoutMillis, TimeUnit unit)
+                throws InterruptedException, ExecutionException, TimeoutException {
+            return getInternal(Math.max(0, timeoutMillis), unit);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Nullable
+        private T getInternal(long timeoutMillis, TimeUnit unit)
+                throws ExecutionException, InterruptedException, TimeoutException {
+            // Prevent parallel executions of this method.
+            long startTime = mTimeProvider.getTimeMillis();
+            synchronized (this) {
+                synchronized (mLock) {
+                    if (mIsDone) {
+                        throw new ExecutionException(
+                                new BluetoothException("get() called twice..."));
+                    }
+                }
+                if (!mOperationExecuted) {
+                    if (timeoutMillis == NO_TIMEOUT) {
+                        mOperationSemaphore.acquire();
+                    } else {
+                        if (!mOperationSemaphore.tryAcquire(timeoutMillis
+                                - (mTimeProvider.getTimeMillis() - startTime), unit)) {
+                            throw new TimeoutException(String.format(Locale.US,
+                                    "A timeout occurred when processing %s after %s %s.",
+                                    mBluetoothOperation, timeoutMillis, unit));
+                        }
+                    }
+                    mBluetoothOperation.execute(BluetoothOperationExecutor.this);
+                }
+                Object result;
+
+                if (timeoutMillis == NO_TIMEOUT) {
+                    result = mResultQueue.take();
+                } else {
+                    result = mResultQueue.poll(
+                            timeoutMillis - (mTimeProvider.getTimeMillis() - startTime), unit);
+                }
+
+                if (result == null) {
+                    throw new TimeoutException(String.format(Locale.US,
+                            "A timeout occurred when processing %s after %s ms.",
+                            mBluetoothOperation, timeoutMillis));
+                }
+                synchronized (mLock) {
+                    mIsDone = true;
+                }
+                if (result instanceof BluetoothException) {
+                    throw new ExecutionException((BluetoothException) result);
+                }
+                if (result == NULL_RESULT) {
+                    result = null;
+                }
+                return (T) result;
+            }
+        }
+    }
+
+    /**
+     * Exception thrown when an operation execution times out. Since state of the system is unknown
+     * afterward (operation may still complete or not), it is recommended to disconnect and
+     * reconnect.
+     */
+    public static class BluetoothOperationTimeoutException extends BluetoothException {
+
+        public BluetoothOperationTimeoutException(String message) {
+            super(message);
+        }
+
+        public BluetoothOperationTimeoutException(String message, Throwable cause) {
+            super(message, cause);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/eventloop/Annotations.java b/nearby/service/java/com/android/server/nearby/common/eventloop/Annotations.java
new file mode 100644
index 0000000..44c9422
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/eventloop/Annotations.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 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.server.nearby.common.eventloop;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import androidx.annotation.AnyThread;
+import androidx.annotation.BinderThread;
+import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * A collection of threading annotations relating to EventLoop. These should be used in conjunction
+ * with {@link UiThread}, {@link BinderThread}, {@link WorkerThread}, and {@link AnyThread}.
+ */
+public class Annotations {
+
+    /**
+     * Denotes that the annotated method or constructor should only be called on the EventLoop
+     * thread.
+     */
+    @Retention(CLASS)
+    @Target({METHOD, CONSTRUCTOR, TYPE})
+    public @interface EventThread {
+    }
+
+    /** Denotes that the annotated method or constructor should only be called on a Network
+     * thread. */
+    @Retention(CLASS)
+    @Target({METHOD, CONSTRUCTOR, TYPE})
+    public @interface NetworkThread {
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/eventloop/EventLoop.java b/nearby/service/java/com/android/server/nearby/common/eventloop/EventLoop.java
new file mode 100644
index 0000000..c89366f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/eventloop/EventLoop.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 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.server.nearby.common.eventloop;
+
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * Handles executing runnables on a background thread.
+ *
+ * <p>Nearby services follow an event loop model where events can be queued and delivered in the
+ * future. All code that is run in this EventLoop is guaranteed to be run on this thread. The main
+ * advantage of this model is that all modules don't have to deal with synchronization and race
+ * conditions, while making it easy to handle the several asynchronous tasks that are expected to be
+ * needed for this type of provider (such as starting a WiFi scan and waiting for the result,
+ * starting BLE scans, doing a server request and waiting for the response etc.).
+ *
+ * <p>Code that needs to wait for an event should not spawn a new thread nor sleep. It should simply
+ * deliver a new message to the event queue when the reply of the event happens.
+ */
+// TODO(b/177675274): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+public class EventLoop {
+
+    private final Interface mImpl;
+
+    private EventLoop(Interface impl) {
+        this.mImpl = impl;
+    }
+
+    protected EventLoop(String name) {
+        this(new HandlerEventLoopImpl(name));
+    }
+
+    /** Creates an EventLoop. */
+    public static EventLoop newInstance(String name) {
+        return new EventLoop(name);
+    }
+
+    /** Creates an EventLoop. */
+    public static EventLoop newInstance(String name, Looper looper) {
+        return new EventLoop(new HandlerEventLoopImpl(name, looper));
+    }
+
+    /** Marks the EventLoop as destroyed. Any further messages received will be ignored. */
+    public void destroy() {
+        mImpl.destroy();
+    }
+
+    /**
+     * Posts a runnable to this event loop, blocking until the runnable has been executed. This
+     * should
+     * be used rarely. It could be useful, for example, for a runnable that initializes the system
+     * and
+     * must block the posting of all other runnables.
+     *
+     * @param runnable a Runnable to post. This method will not return until the run() method of the
+     *                 given runnable has executed on the background thread.
+     */
+    public void postAndWait(final NamedRunnable runnable) throws InterruptedException {
+        mImpl.postAndWait(runnable);
+    }
+
+    /**
+     * Posts a runnable to this to the front of the event loop, blocking until the runnable has been
+     * executed. This should be used rarely, as it can starve the event loop.
+     *
+     * @param runnable a Runnable to post. This method will not return until the run() method of the
+     *                 given runnable has executed on the background thread.
+     */
+    public void postToFrontAndWait(final NamedRunnable runnable) throws InterruptedException {
+        mImpl.postToFrontAndWait(runnable);
+    }
+
+    /** Checks if there are any pending posts of the Runnable in the queue. */
+    public boolean isPosted(NamedRunnable runnable) {
+        return mImpl.isPosted(runnable);
+    }
+
+    /**
+     * Run code on the event loop thread.
+     *
+     * @param runnable the runnable to execute.
+     */
+    public void postRunnable(NamedRunnable runnable) {
+        mImpl.postRunnable(runnable);
+    }
+
+    /**
+     * Run code to be executed when there is no runnable scheduled.
+     *
+     * @param runnable last runnable to execute.
+     */
+    public void postEmptyQueueRunnable(final NamedRunnable runnable) {
+        mImpl.postEmptyQueueRunnable(runnable);
+    }
+
+    /**
+     * Run code on the event loop thread after delayedMillis.
+     *
+     * @param runnable      the runnable to execute.
+     * @param delayedMillis the number of milliseconds before executing the runnable.
+     */
+    public void postRunnableDelayed(NamedRunnable runnable, long delayedMillis) {
+        mImpl.postRunnableDelayed(runnable, delayedMillis);
+    }
+
+    /**
+     * Removes and cancels the specified {@code runnable} if it had not posted/started yet. Calling
+     * with null does nothing.
+     */
+    public void removeRunnable(@Nullable NamedRunnable runnable) {
+        mImpl.removeRunnable(runnable);
+    }
+
+    /** Asserts that the current operation is being executed in the Event Loop's thread. */
+    public void checkThread() {
+        mImpl.checkThread();
+    }
+
+    public Handler getHandler() {
+        return mImpl.getHandler();
+    }
+
+    interface Interface {
+        void destroy();
+
+        void postAndWait(NamedRunnable runnable) throws InterruptedException;
+
+        void postToFrontAndWait(NamedRunnable runnable) throws InterruptedException;
+
+        boolean isPosted(NamedRunnable runnable);
+
+        void postRunnable(NamedRunnable runnable);
+
+        void postEmptyQueueRunnable(NamedRunnable runnable);
+
+        void postRunnableDelayed(NamedRunnable runnable, long delayedMillis);
+
+        void removeRunnable(NamedRunnable runnable);
+
+        void checkThread();
+
+        Handler getHandler();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/eventloop/HandlerEventLoopImpl.java b/nearby/service/java/com/android/server/nearby/common/eventloop/HandlerEventLoopImpl.java
new file mode 100644
index 0000000..018dcdb
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/eventloop/HandlerEventLoopImpl.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright 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.server.nearby.common.eventloop;
+
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+import android.os.Process;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * Handles executing runnables on a background thread.
+ *
+ * <p>Nearby services follow an event loop model where events can be queued and delivered in the
+ * future. All code that is run in this package is guaranteed to be run on this thread. The main
+ * advantage of this model is that all modules don't have to deal with synchronization and race
+ * conditions, while making it easy to handle the several asynchronous tasks that are expected to be
+ * needed for this type of provider (such as starting a WiFi scan and waiting for the result,
+ * starting BLE scans, doing a server request and waiting for the response etc.).
+ *
+ * <p>Code that needs to wait for an event should not spawn a new thread nor sleep. It should simply
+ * deliver a new message to the event queue when the reply of the event happens.
+ *
+ * <p>
+ */
+// TODO(b/203471261) use executor instead of handler
+// TODO(b/177675274): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+final class HandlerEventLoopImpl implements EventLoop.Interface {
+    /** The {@link Message#what} code for all messages that we post to the EventLoop. */
+    private static final int WHAT = 0;
+
+    private static final long ELAPSED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(5);
+    private static final long RUNNABLE_DELAY_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(2);
+    private static final String TAG = HandlerEventLoopImpl.class.getSimpleName();
+    private final MyHandler mHandler;
+
+    private volatile boolean mIsDestroyed = false;
+
+    /** Constructs an EventLoop. */
+    HandlerEventLoopImpl(String name) {
+        this(name, createHandlerThread(name));
+    }
+
+    HandlerEventLoopImpl(String name, Looper looper) {
+
+        mHandler = new MyHandler(looper);
+        Log.d(TAG,
+                "Created EventLoop for thread '" + looper.getThread().getName()
+                        + "(id: " + looper.getThread().getId() + ")'");
+    }
+
+    private static Looper createHandlerThread(String name) {
+        HandlerThread handlerThread = new HandlerThread(name, Process.THREAD_PRIORITY_BACKGROUND);
+        handlerThread.start();
+
+        return handlerThread.getLooper();
+    }
+
+    /**
+     * Wrapper to satisfy Android Lint. {@link Looper#getQueue()} is public and available since ICS,
+     * but was marked @hide until Marshmallow. Tested that this code doesn't crash pre-Marshmallow.
+     * /aosp-ics/frameworks/base/core/java/android/os/Looper.java?l=218
+     */
+    @SuppressLint("NewApi")
+    private static MessageQueue getQueue(Handler handler) {
+        return handler.getLooper().getQueue();
+    }
+
+    /** Marks the EventLoop as destroyed. Any further messages received will be ignored. */
+    @Override
+    public void destroy() {
+        Looper looper = mHandler.getLooper();
+        Log.d(TAG,
+                "Destroying EventLoop for thread " + looper.getThread().getName()
+                        + " (id: " + looper.getThread().getId() + ")");
+        looper.quit();
+        mIsDestroyed = true;
+    }
+
+    /**
+     * Posts a runnable to this event loop, blocking until the runnable has been executed. This
+     * should
+     * be used rarely. It could be useful, for example, for a runnable that initializes the system
+     * and
+     * must block the posting of all other runnables.
+     *
+     * @param runnable a Runnable to post. This method will not return until the run() method of the
+     *                 given runnable has executed on the background thread.
+     */
+    @Override
+    public void postAndWait(final NamedRunnable runnable) throws InterruptedException {
+        internalPostAndWait(runnable, false);
+    }
+
+    @Override
+    public void postToFrontAndWait(final NamedRunnable runnable) throws InterruptedException {
+        internalPostAndWait(runnable, true);
+    }
+
+    /** Checks if there are any pending posts of the Runnable in the queue. */
+    @Override
+    public boolean isPosted(NamedRunnable runnable) {
+        return mHandler.hasMessages(WHAT, runnable);
+    }
+
+    /**
+     * Run code on the event loop thread.
+     *
+     * @param runnable the runnable to execute.
+     */
+    @Override
+    public void postRunnable(NamedRunnable runnable) {
+        Log.d(TAG, "Posting " + runnable);
+        mHandler.post(runnable, 0L, false);
+    }
+
+    /**
+     * Run code to be executed when there is no runnable scheduled.
+     *
+     * @param runnable last runnable to execute.
+     */
+    @Override
+    public void postEmptyQueueRunnable(final NamedRunnable runnable) {
+        mHandler.post(
+                () ->
+                        getQueue(mHandler)
+                                .addIdleHandler(
+                                        () -> {
+                                            if (mHandler.hasMessages(WHAT)) {
+                                                return true;
+                                            } else {
+                                                // Only stop if start has not been called since
+                                                // this was queued
+                                                runnable.run();
+                                                return false;
+                                            }
+                                        }));
+    }
+
+    /**
+     * Run code on the event loop thread after delayedMillis.
+     *
+     * @param runnable      the runnable to execute.
+     * @param delayedMillis the number of milliseconds before executing the runnable.
+     */
+    @Override
+    public void postRunnableDelayed(NamedRunnable runnable, long delayedMillis) {
+        Log.d(TAG, "Posting " + runnable + " [delay " + delayedMillis + "]");
+        mHandler.post(runnable, delayedMillis, false);
+    }
+
+    /**
+     * Removes and cancels the specified {@code runnable} if it had not posted/started yet. Calling
+     * with null does nothing.
+     */
+    @Override
+    public void removeRunnable(@Nullable NamedRunnable runnable) {
+        if (runnable != null) {
+            // Removes any pending sent messages where what=WHAT and obj=runnable. We can't use
+            // removeCallbacks(runnable) because we're not posting the runnable directly, we're
+            // sending a Message with the runnable as its obj.
+            mHandler.removeMessages(WHAT, runnable);
+        }
+    }
+
+    /** Asserts that the current operation is being executed in the Event Loop's thread. */
+    @Override
+    public void checkThread() {
+
+        Thread currentThread = Looper.myLooper().getThread();
+        Thread expectedThread = mHandler.getLooper().getThread();
+        if (currentThread.getId() != expectedThread.getId()) {
+            throw new IllegalStateException(
+                    String.format(
+                            "This method must run in the EventLoop thread '%s (id: %s)'. "
+                                    + "Was called from thread '%s (id: %s)'.",
+                            expectedThread.getName(),
+                            expectedThread.getId(),
+                            currentThread.getName(),
+                            currentThread.getId()));
+        }
+
+    }
+
+    @Override
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    private void internalPostAndWait(final NamedRunnable runnable, boolean postToFront)
+            throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        NamedRunnable delegate =
+                new NamedRunnable(runnable.name) {
+                    @Override
+                    public void run() {
+                        try {
+                            runnable.run();
+                        } finally {
+                            latch.countDown();
+                        }
+                    }
+                };
+
+        Log.d(TAG, "Posting " + delegate + " and wait");
+        if (!mHandler.post(delegate, 0L, postToFront)) {
+            // Do not wait if delegate is not posted.
+            Log.d(TAG, delegate + " not posted");
+            latch.countDown();
+        }
+        latch.await();
+    }
+
+    /** Handler that executes code on a private event loop thread. */
+    private class MyHandler extends Handler {
+
+        MyHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            NamedRunnable runnable = (NamedRunnable) msg.obj;
+
+            if (mIsDestroyed) {
+                Log.w(TAG, "Runnable " + runnable
+                        + " attempted to run after the EventLoop was destroyed. Ignoring");
+                return;
+            }
+            Log.i(TAG, "Executing " + runnable);
+
+            // Did this runnable start much later than we expected it to? If so, then log.
+            long expectedStartTime = (long) msg.arg1 << 32 | (msg.arg2 & 0xFFFFFFFFL);
+            logIfExceedsThreshold(
+                    RUNNABLE_DELAY_THRESHOLD_MS, expectedStartTime, runnable, "was delayed for");
+
+            long startTimeMillis = SystemClock.elapsedRealtime();
+            try {
+                runnable.run();
+            } catch (Exception t) {
+                Log.e(TAG, runnable + "crashed.");
+                throw t;
+            } finally {
+                logIfExceedsThreshold(ELAPSED_THRESHOLD_MS, startTimeMillis, runnable, "ran for");
+            }
+        }
+
+        private boolean post(NamedRunnable runnable, long delayedMillis, boolean postToFront) {
+            if (mIsDestroyed) {
+                Log.w(TAG, runnable + " not posted since EventLoop is destroyed");
+                return false;
+            }
+            long expectedStartTime = SystemClock.elapsedRealtime() + delayedMillis;
+            int arg1 = (int) (expectedStartTime >> 32);
+            int arg2 = (int) expectedStartTime;
+            Message message = obtainMessage(WHAT, arg1, arg2, runnable /* obj */);
+            boolean sent =
+                    postToFront
+                            ? sendMessageAtFrontOfQueue(message)
+                            : sendMessageDelayed(message, delayedMillis);
+            if (!sent) {
+                Log.w(TAG, runnable + "not posted since looper is exiting");
+            }
+            return sent;
+        }
+
+        private void logIfExceedsThreshold(
+                long thresholdMillis, long startTimeMillis, NamedRunnable runnable,
+                String message) {
+            long elapsedMillis = SystemClock.elapsedRealtime() - startTimeMillis;
+            if (elapsedMillis > thresholdMillis) {
+                String elapsedFormatted =
+                        new SimpleDateFormat("mm:ss.SSS", Locale.US).format(elapsedMillis);
+                Log.w(TAG, runnable + " " + message + " " + elapsedFormatted);
+            }
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/eventloop/NamedRunnable.java b/nearby/service/java/com/android/server/nearby/common/eventloop/NamedRunnable.java
new file mode 100644
index 0000000..578e3f6
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/eventloop/NamedRunnable.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 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.server.nearby.common.eventloop;
+
+/** A Runnable with a name, for logging purposes. */
+public abstract class NamedRunnable implements Runnable {
+    public final String name;
+
+    public NamedRunnable(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        return "Runnable[" + name + "]";
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/fastpair/IconUtils.java b/nearby/service/java/com/android/server/nearby/common/fastpair/IconUtils.java
new file mode 100644
index 0000000..35a1a9f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/fastpair/IconUtils.java
@@ -0,0 +1,113 @@
+/*
+ * 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.server.nearby.common.fastpair;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.core.graphics.ColorUtils;
+
+/** Utility methods for icon size verification. */
+public class IconUtils {
+    private static final int MIN_ICON_SIZE = 16;
+    private static final int DESIRED_ICON_SIZE = 32;
+    private static final double NOTIFICATION_BACKGROUND_PADDING_PERCENTAGE = 0.125;
+    private static final double NOTIFICATION_BACKGROUND_ALPHA = 0.7;
+
+    /**
+     * Verify that the icon is non null and falls in the small bucket. Just because an icon isn't
+     * small doesn't guarantee it is large or exists.
+     */
+    @VisibleForTesting
+    static boolean isIconSizedSmall(@Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return false;
+        }
+        int min = MIN_ICON_SIZE;
+        int desired = DESIRED_ICON_SIZE;
+        return bitmap.getWidth() >= min
+                && bitmap.getWidth() < desired
+                && bitmap.getHeight() >= min
+                && bitmap.getHeight() < desired;
+    }
+
+    /**
+     * Verify that the icon is non null and falls in the regular / default size bucket. Doesn't
+     * guarantee if not regular then it is small.
+     */
+    @VisibleForTesting
+    static boolean isIconSizedRegular(@Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return false;
+        }
+        return bitmap.getWidth() >= DESIRED_ICON_SIZE
+                && bitmap.getHeight() >= DESIRED_ICON_SIZE;
+    }
+
+    // All icons that are sized correctly (larger than the min icon size) are resize on the server
+    // to the desired icon size so that they appear correct in notifications.
+
+    /**
+     * All icons that are sized correctly (larger than the min icon size) are resize on the server
+     * to the desired icon size so that they appear correct in notifications.
+     */
+    public static boolean isIconSizeCorrect(@Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return false;
+        }
+        return isIconSizedSmall(bitmap) || isIconSizedRegular(bitmap);
+    }
+
+    /** Adds a circular, white background to the bitmap. */
+    @Nullable
+    public static Bitmap addWhiteCircleBackground(Context context, @Nullable Bitmap bitmap) {
+        if (bitmap == null) {
+            return null;
+        }
+
+        if (bitmap.getWidth() != bitmap.getHeight()) {
+            return bitmap;
+        }
+
+        int padding = (int) (bitmap.getWidth() * NOTIFICATION_BACKGROUND_PADDING_PERCENTAGE);
+        Bitmap bitmapWithBackground =
+                Bitmap.createBitmap(
+                        bitmap.getWidth() + (2 * padding),
+                        bitmap.getHeight() + (2 * padding),
+                        bitmap.getConfig());
+        Canvas canvas = new Canvas(bitmapWithBackground);
+        Paint paint = new Paint();
+        paint.setColor(
+                ColorUtils.setAlphaComponent(
+                        Color.WHITE, (int) (255 * NOTIFICATION_BACKGROUND_ALPHA)));
+        paint.setStyle(Paint.Style.FILL);
+        paint.setAntiAlias(true);
+        canvas.drawCircle(
+                bitmapWithBackground.getWidth() / 2f,
+                bitmapWithBackground.getHeight() / 2f,
+                bitmapWithBackground.getWidth() / 2f,
+                paint);
+        canvas.drawBitmap(bitmap, padding, padding, null);
+        return bitmapWithBackground;
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/fastpair/service/UserActionHandlerBase.java b/nearby/service/java/com/android/server/nearby/common/fastpair/service/UserActionHandlerBase.java
new file mode 100644
index 0000000..67d87e3
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/fastpair/service/UserActionHandlerBase.java
@@ -0,0 +1,29 @@
+/*
+ * 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.server.nearby.common.fastpair.service;
+
+/** Handles intents to {@link com.android.server.nearby.fastpair.FastPairManager}. */
+public class UserActionHandlerBase {
+    public static final String PREFIX = "com.android.server.nearby.fastpair.";
+    public static final String ACTION_PREFIX = "com.android.server.nearby:";
+
+    public static final String EXTRA_ITEM_ID = PREFIX + "EXTRA_ITEM_ID";
+    public static final String EXTRA_COMPANION_APP = ACTION_PREFIX + "EXTRA_COMPANION_APP";
+    public static final String EXTRA_MAC_ADDRESS = PREFIX + "EXTRA_MAC_ADDRESS";
+
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/locator/Locator.java b/nearby/service/java/com/android/server/nearby/common/locator/Locator.java
new file mode 100644
index 0000000..f8b43a6
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/locator/Locator.java
@@ -0,0 +1,298 @@
+/*
+ * 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.server.nearby.common.locator;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Collection of bindings that map service types to their respective implementation(s). */
+public class Locator {
+    private static final Object UNBOUND = new Object();
+    private final Context mContext;
+    @Nullable
+    private Locator mParent;
+    private final String mTag; // For debugging
+    private final Map<Class<?>, Object> mBindings = new HashMap<>();
+    private final ArrayList<Module> mModules = new ArrayList<>();
+
+    /** Thrown upon attempt to bind an interface twice. */
+    public static class DuplicateBindingException extends RuntimeException {
+        DuplicateBindingException(String msg) {
+            super(msg);
+        }
+    }
+
+    /** Constructor with a null parent. */
+    public Locator(Context context) {
+        this(context, null);
+    }
+
+    /**
+     * Constructor. Supply a valid context and the Locator's parent.
+     *
+     * <p>To find a suitable parent you may want to use findLocator.
+     */
+    public Locator(Context context, @Nullable Locator parent) {
+        this.mContext = context;
+        this.mParent = parent;
+        this.mTag = context.getClass().getName();
+    }
+
+    /** Attaches the parent to the locator. */
+    public void attachParent(Locator parent) {
+        this.mParent = parent;
+    }
+
+    /** Associates the specified type with the supplied instance. */
+    public <T extends Object> Locator bind(Class<T> type, T instance) {
+        bindKeyValue(type, instance);
+        return this;
+    }
+
+    /** For tests only. Disassociates the specified type from any instance. */
+    @VisibleForTesting
+    public <T extends Object> Locator overrideBindingForTest(Class<T> type, T instance) {
+        mBindings.remove(type);
+        return bind(type, instance);
+    }
+
+    /** For tests only. Force Locator to return null when try to get an instance. */
+    @VisibleForTesting
+    public <T> Locator removeBindingForTest(Class<T> type) {
+        Locator locator = this;
+        do {
+            locator.mBindings.put(type, UNBOUND);
+            locator = locator.mParent;
+        } while (locator != null);
+        return this;
+    }
+
+    /** Binds a module. */
+    public synchronized Locator bind(Module module) {
+        mModules.add(module);
+        return this;
+    }
+
+    /**
+     * Searches the chain of locators for a binding for the given type.
+     *
+     * @throws IllegalStateException if no binding is found.
+     */
+    public <T> T get(Class<T> type) {
+        T instance = getOptional(type);
+        if (instance != null) {
+            return instance;
+        }
+
+        String errorMessage = getUnboundErrorMessage(type);
+        throw new IllegalStateException(errorMessage);
+    }
+
+    private String getUnboundErrorMessage(Class<?> type) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Unbound type: ").append(type.getName()).append("\n").append(
+                "Searched locators:\n");
+        Locator locator = this;
+        while (true) {
+            sb.append(locator.mTag);
+            locator = locator.mParent;
+            if (locator == null) {
+                break;
+            }
+            sb.append(" ->\n");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Searches the chain of locators for a binding for the given type. Returns null if no locator
+     * was
+     * found.
+     */
+    @Nullable
+    public <T> T getOptional(Class<T> type) {
+        Locator locator = this;
+        do {
+            T instance = locator.getInstance(type);
+            if (instance != null) {
+                return instance;
+            }
+            locator = locator.mParent;
+        } while (locator != null);
+        return null;
+    }
+
+    private synchronized <T extends Object> void bindKeyValue(Class<T> key, T value) {
+        Object boundInstance = mBindings.get(key);
+        if (boundInstance != null) {
+            if (boundInstance == UNBOUND) {
+                Log.w(mTag, "Bind call too late - someone already tried to get: " + key);
+            } else {
+                throw new DuplicateBindingException("Duplicate binding: " + key);
+            }
+        }
+        mBindings.put(key, value);
+    }
+
+    // Suppress warning of cast from Object -> T
+    @SuppressWarnings("unchecked")
+    @Nullable
+    private synchronized <T> T getInstance(Class<T> type) {
+        if (mContext == null) {
+            throw new IllegalStateException("Locator not initialized yet.");
+        }
+
+        T instance = (T) mBindings.get(type);
+        if (instance != null) {
+            return instance != UNBOUND ? instance : null;
+        }
+
+        // Ask modules to supply a binding
+        int moduleCount = mModules.size();
+        for (int i = 0; i < moduleCount; i++) {
+            mModules.get(i).configure(mContext, type, this);
+        }
+
+        instance = (T) mBindings.get(type);
+        if (instance == null) {
+            mBindings.put(type, UNBOUND);
+        }
+        return instance;
+    }
+
+    /**
+     * Iterates over all bound objects and gives the modules a chance to clean up the objects they
+     * have created.
+     */
+    public synchronized void destroy() {
+        for (Class<?> type : mBindings.keySet()) {
+            Object instance = mBindings.get(type);
+            if (instance == UNBOUND) {
+                continue;
+            }
+
+            for (Module module : mModules) {
+                module.destroy(mContext, type, instance);
+            }
+        }
+        mBindings.clear();
+    }
+
+    /** Returns true if there are no bindings. */
+    public boolean isEmpty() {
+        return mBindings.isEmpty();
+    }
+
+    /** Returns the parent locator or null if no parent. */
+    @Nullable
+    public Locator getParent() {
+        return mParent;
+    }
+
+    /**
+     * Finds the first locator, then searches the chain of locators for a binding for the given
+     * type.
+     *
+     * @throws IllegalStateException if no binding is found.
+     */
+    public static <T> T get(Context context, Class<T> type) {
+        Locator locator = findLocator(context);
+        if (locator == null) {
+            throw new IllegalStateException("No locator found in context " + context);
+        }
+        return locator.get(type);
+    }
+
+    /**
+     * Find the first locator from the context wrapper.
+     */
+    public static <T> T getFromContextWrapper(LocatorContextWrapper wrapper, Class<T> type) {
+        Locator locator = wrapper.getLocator();
+        if (locator == null) {
+            throw new IllegalStateException("No locator found in context wrapper");
+        }
+        return locator.get(type);
+    }
+
+    /**
+     * Finds the first locator, then searches the chain of locators for a binding for the given
+     * type.
+     * Returns null if no binding was found.
+     */
+    @Nullable
+    public static <T> T getOptional(Context context, Class<T> type) {
+        Locator locator = findLocator(context);
+        if (locator == null) {
+            return null;
+        }
+        return locator.getOptional(type);
+    }
+
+    /** Finds the first locator in the context hierarchy. */
+    @Nullable
+    public static Locator findLocator(Context context) {
+        Context applicationContext = context.getApplicationContext();
+        boolean applicationContextVisited = false;
+
+        Context searchContext = context;
+        do {
+            Locator locator = tryGetLocator(searchContext);
+            if (locator != null) {
+                return locator;
+            }
+
+            applicationContextVisited |= (searchContext == applicationContext);
+
+            if (searchContext instanceof ContextWrapper) {
+                searchContext = ((ContextWrapper) context).getBaseContext();
+
+                if (searchContext == null) {
+                    throw new IllegalStateException(
+                            "Invalid ContextWrapper -- If this is a Robolectric test, "
+                                    + "have you called ActivityController.create()?");
+                }
+            } else if (!applicationContextVisited) {
+                searchContext = applicationContext;
+            } else {
+                searchContext = null;
+            }
+        } while (searchContext != null);
+
+        return null;
+    }
+
+    @Nullable
+    private static Locator tryGetLocator(Object object) {
+        if (object instanceof LocatorContext) {
+            Locator locator = ((LocatorContext) object).getLocator();
+            if (locator == null) {
+                throw new IllegalStateException(
+                        "LocatorContext must not return null Locator: " + object);
+            }
+            return locator;
+        }
+        return null;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/locator/LocatorContext.java b/nearby/service/java/com/android/server/nearby/common/locator/LocatorContext.java
new file mode 100644
index 0000000..06eef8a
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/locator/LocatorContext.java
@@ -0,0 +1,26 @@
+/*
+ * 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.server.nearby.common.locator;
+
+/**
+ * An object that has a {@link Locator}. The locator can be used to resolve service types to their
+ * respective implementation(s).
+ */
+public interface LocatorContext {
+    /** Returns the locator. May not return null. */
+    Locator getLocator();
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/locator/LocatorContextWrapper.java b/nearby/service/java/com/android/server/nearby/common/locator/LocatorContextWrapper.java
new file mode 100644
index 0000000..03df33f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/locator/LocatorContextWrapper.java
@@ -0,0 +1,57 @@
+/*
+ * 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.server.nearby.common.locator;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.ContextWrapper;
+
+/**
+ * Wraps a Context and associates it with a Locator, optionally linking it with a parent locator.
+ */
+public class LocatorContextWrapper extends ContextWrapper implements LocatorContext {
+    private final Locator mLocator;
+    private final Context mContext;
+    /** Constructs a context wrapper with a Locator linked to the passed locator. */
+    public LocatorContextWrapper(Context context, @Nullable Locator parentLocator) {
+        super(context);
+        mContext = context;
+        // Assigning under initialization object, but it's safe, since locator is used lazily.
+        this.mLocator = new Locator(this, parentLocator);
+    }
+
+    /**
+     * Constructs a context wrapper.
+     *
+     * <p>Uses the Locator associated with the passed context as the parent.
+     */
+    public LocatorContextWrapper(Context context) {
+        this(context, Locator.findLocator(context));
+    }
+
+    /**
+     * Get the context of the context wrapper.
+     */
+    public Context getContext() {
+        return mContext;
+    }
+
+    @Override
+    public Locator getLocator() {
+        return mLocator;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/locator/Module.java b/nearby/service/java/com/android/server/nearby/common/locator/Module.java
new file mode 100644
index 0000000..0131c44
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/locator/Module.java
@@ -0,0 +1,57 @@
+/*
+ * 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.server.nearby.common.locator;
+
+import android.content.Context;
+
+/** Configures late bindings of service types to their concrete implementations. */
+public abstract class Module {
+    /**
+     * Configures the binding between the {@code type} and its implementation by calling methods on
+     * the {@code locator}, for example:
+     *
+     * <pre>{@code
+     * void configure(Context context, Class<?> type, Locator locator) {
+     *   if (type == MyService.class) {
+     *     locator.bind(MyService.class, new MyImplementation(context));
+     *   }
+     * }
+     * }</pre>
+     *
+     * <p>If the module does not recognize the specified type, the method does not have to do
+     * anything.
+     */
+    public abstract void configure(Context context, Class<?> type, Locator locator);
+
+    /**
+     * Notifies you that a binding of class {@code type} is no longer needed and can now release
+     * everything it was holding on to, such as a database connection.
+     *
+     * <pre>{@code
+     * void destroy(Context context, Class<?> type, Object instance) {
+     *   if (type == MyService.class) {
+     *     ((MyService) instance).destroy();
+     *   }
+     * }
+     * }</pre>
+     *
+     * <p>If the module does not recognize the specified type, the method does not have to do
+     * anything.
+     */
+    public void destroy(Context context, Class<?> type, Object instance) {}
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/common/servicemonitor/CurrentUserServiceProvider.java b/nearby/service/java/com/android/server/nearby/common/servicemonitor/CurrentUserServiceProvider.java
new file mode 100644
index 0000000..80248e8
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/servicemonitor/CurrentUserServiceProvider.java
@@ -0,0 +1,217 @@
+/*
+ * 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.server.nearby.common.servicemonitor;
+
+import static android.content.pm.PackageManager.GET_META_DATA;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+
+import com.android.internal.util.Preconditions;
+import com.android.server.nearby.common.servicemonitor.ServiceMonitor.ServiceChangedListener;
+import com.android.server.nearby.common.servicemonitor.ServiceMonitor.ServiceProvider;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * This is mostly borrowed from frameworks CurrentUserServiceSupplier.
+ * Provides services based on the current active user and version as defined in the service
+ * manifest. This implementation uses {@link android.content.pm.PackageManager#MATCH_SYSTEM_ONLY} to
+ * ensure only system (ie, privileged) services are matched. It also handles services that are not
+ * direct boot aware, and will automatically pick the best service as the user's direct boot state
+ * changes.
+ */
+public final class CurrentUserServiceProvider extends BroadcastReceiver implements
+        ServiceProvider<CurrentUserServiceProvider.BoundServiceInfo> {
+
+    private static final String TAG = "CurrentUserServiceProvider";
+
+    private static final String EXTRA_SERVICE_VERSION = "serviceVersion";
+
+    // This is equal to the hidden Intent.ACTION_USER_SWITCHED.
+    private static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED";
+    // This is equal to the hidden Intent.EXTRA_USER_HANDLE.
+    private static final String EXTRA_USER_HANDLE = "android.intent.extra.user_handle";
+    // This is equal to the hidden UserHandle.USER_NULL.
+    private static final int USER_NULL = -10000;
+
+    private static final Comparator<BoundServiceInfo> sBoundServiceInfoComparator = (o1, o2) -> {
+        if (o1 == o2) {
+            return 0;
+        } else if (o1 == null) {
+            return -1;
+        } else if (o2 == null) {
+            return 1;
+        }
+
+        // ServiceInfos with higher version numbers always win.
+        return Integer.compare(o1.getVersion(), o2.getVersion());
+    };
+
+    /** Bound service information with version information. */
+    public static class BoundServiceInfo extends ServiceMonitor.BoundServiceInfo {
+
+        private static int parseUid(ResolveInfo resolveInfo) {
+            return resolveInfo.serviceInfo.applicationInfo.uid;
+        }
+
+        private static int parseVersion(ResolveInfo resolveInfo) {
+            int version = Integer.MIN_VALUE;
+            if (resolveInfo.serviceInfo.metaData != null) {
+                version = resolveInfo.serviceInfo.metaData.getInt(EXTRA_SERVICE_VERSION, version);
+            }
+            return version;
+        }
+
+        private final int mVersion;
+
+        protected BoundServiceInfo(String action, ResolveInfo resolveInfo) {
+            this(
+                    action,
+                    parseUid(resolveInfo),
+                    new ComponentName(
+                            resolveInfo.serviceInfo.packageName,
+                            resolveInfo.serviceInfo.name),
+                    parseVersion(resolveInfo));
+        }
+
+        protected BoundServiceInfo(String action, int uid, ComponentName componentName,
+                int version) {
+            super(action, uid, componentName);
+            mVersion = version;
+        }
+
+        public int getVersion() {
+            return mVersion;
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + "@" + mVersion;
+        }
+    }
+
+    /**
+     * Creates an instance with the specific service details.
+     *
+     * @param context the context the provider is to use
+     * @param action the action the service must declare in its intent-filter
+     */
+    public static CurrentUserServiceProvider create(Context context, String action) {
+        return new CurrentUserServiceProvider(context, action);
+    }
+
+    private final Context mContext;
+    private final Intent mIntent;
+    private volatile ServiceChangedListener mListener;
+
+    private CurrentUserServiceProvider(Context context, String action) {
+        mContext = context;
+        mIntent = new Intent(action);
+    }
+
+    @Override
+    public boolean hasMatchingService() {
+        int intentQueryFlags =
+                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE | MATCH_SYSTEM_ONLY;
+        List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServicesAsUser(
+                mIntent, intentQueryFlags, UserHandle.SYSTEM);
+        return !resolveInfos.isEmpty();
+    }
+
+    @Override
+    public void register(ServiceChangedListener listener) {
+        Preconditions.checkState(mListener == null);
+
+        mListener = listener;
+
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ACTION_USER_SWITCHED);
+        intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
+        mContext.registerReceiverForAllUsers(this, intentFilter, null,
+                ForegroundThread.getHandler());
+    }
+
+    @Override
+    public void unregister() {
+        Preconditions.checkArgument(mListener != null);
+
+        mListener = null;
+        mContext.unregisterReceiver(this);
+    }
+
+    @Override
+    public BoundServiceInfo getServiceInfo() {
+        BoundServiceInfo bestServiceInfo = null;
+
+        // only allow services in the correct direct boot state to match
+        int intentQueryFlags = MATCH_DIRECT_BOOT_AUTO | GET_META_DATA | MATCH_SYSTEM_ONLY;
+        List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServicesAsUser(
+                mIntent, intentQueryFlags, UserHandle.of(ActivityManager.getCurrentUser()));
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            BoundServiceInfo serviceInfo =
+                    new BoundServiceInfo(mIntent.getAction(), resolveInfo);
+
+            if (sBoundServiceInfoComparator.compare(serviceInfo, bestServiceInfo) > 0) {
+                bestServiceInfo = serviceInfo;
+            }
+        }
+
+        return bestServiceInfo;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        if (action == null) {
+            return;
+        }
+        int userId = intent.getIntExtra(EXTRA_USER_HANDLE, USER_NULL);
+        if (userId == USER_NULL) {
+            return;
+        }
+        ServiceChangedListener listener = mListener;
+        if (listener == null) {
+            return;
+        }
+
+        switch (action) {
+            case ACTION_USER_SWITCHED:
+                listener.onServiceChanged();
+                break;
+            case Intent.ACTION_USER_UNLOCKED:
+                // user unlocked implies direct boot mode may have changed
+                if (userId == ActivityManager.getCurrentUser()) {
+                    listener.onServiceChanged();
+                }
+                break;
+            default:
+                break;
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/servicemonitor/ForegroundThread.java b/nearby/service/java/com/android/server/nearby/common/servicemonitor/ForegroundThread.java
new file mode 100644
index 0000000..2c363f8
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/servicemonitor/ForegroundThread.java
@@ -0,0 +1,77 @@
+/*
+ * 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.server.nearby.common.servicemonitor;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+import com.android.modules.utils.HandlerExecutor;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Thread for asynchronous event processing. This thread is configured as
+ * {@link android.os.Process#THREAD_PRIORITY_FOREGROUND}, which means more CPU
+ * resources will be dedicated to it, and it will be treated like "a user
+ * interface that the user is interacting with."
+ * <p>
+ * This thread is best suited for tasks that the user is actively waiting for,
+ * or for tasks that the user expects to be executed immediately.
+ *
+ */
+public final class ForegroundThread extends HandlerThread {
+    private static ForegroundThread sInstance;
+    private static Handler sHandler;
+    private static HandlerExecutor sHandlerExecutor;
+
+    private ForegroundThread() {
+        super("nearbyfg", android.os.Process.THREAD_PRIORITY_FOREGROUND);
+    }
+
+    private static void ensureThreadLocked() {
+        if (sInstance == null) {
+            sInstance = new ForegroundThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+            sHandlerExecutor = new HandlerExecutor(sHandler);
+        }
+    }
+
+    /** Get ForegroundThread singleton instance. */
+    public static ForegroundThread get() {
+        synchronized (ForegroundThread.class) {
+            ensureThreadLocked();
+            return sInstance;
+        }
+    }
+
+    /** Get ForegroundThread singleton handler. */
+    public static Handler getHandler() {
+        synchronized (ForegroundThread.class) {
+            ensureThreadLocked();
+            return sHandler;
+        }
+    }
+
+    /** Get ForegroundThread singleton executor. */
+    public static Executor getExecutor() {
+        synchronized (ForegroundThread.class) {
+            ensureThreadLocked();
+            return sHandlerExecutor;
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/servicemonitor/PackageWatcher.java b/nearby/service/java/com/android/server/nearby/common/servicemonitor/PackageWatcher.java
new file mode 100644
index 0000000..7d1db57
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/servicemonitor/PackageWatcher.java
@@ -0,0 +1,130 @@
+/*
+ * 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.server.nearby.common.servicemonitor;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+
+import com.android.modules.utils.BackgroundThread;
+
+import java.util.Objects;
+
+/**
+ * This is mostly from frameworks PackageMonitor.
+ * Helper class for watching somePackagesChanged.
+ */
+public abstract class PackageWatcher extends BroadcastReceiver {
+    static final String TAG = "PackageWatcher";
+    static final IntentFilter sPackageFilt = new IntentFilter();
+    static final IntentFilter sNonDataFilt = new IntentFilter();
+    static final IntentFilter sExternalFilt = new IntentFilter();
+
+    static {
+        sPackageFilt.addAction(Intent.ACTION_PACKAGE_ADDED);
+        sPackageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        sPackageFilt.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        sPackageFilt.addDataScheme("package");
+        sNonDataFilt.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
+        sNonDataFilt.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
+        sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
+        sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
+    }
+
+    Context mRegisteredContext;
+    Handler mRegisteredHandler;
+    boolean mSomePackagesChanged;
+
+    public PackageWatcher() {
+    }
+
+    void register(Context context, Looper thread, boolean externalStorage) {
+        register(context, externalStorage,
+                (thread == null) ? BackgroundThread.getHandler() : new Handler(thread));
+    }
+
+    void register(Context context, boolean externalStorage, Handler handler) {
+        if (mRegisteredContext != null) {
+            throw new IllegalStateException("Already registered");
+        }
+        mRegisteredContext = context;
+        mRegisteredHandler = Objects.requireNonNull(handler);
+        context.registerReceiverForAllUsers(this, sPackageFilt, null, mRegisteredHandler);
+        context.registerReceiverForAllUsers(this, sNonDataFilt, null, mRegisteredHandler);
+        if (externalStorage) {
+            context.registerReceiverForAllUsers(this, sExternalFilt, null, mRegisteredHandler);
+        }
+    }
+
+    void unregister() {
+        if (mRegisteredContext == null) {
+            throw new IllegalStateException("Not registered");
+        }
+        mRegisteredContext.unregisterReceiver(this);
+        mRegisteredContext = null;
+    }
+
+    // Called when some package has been changed.
+    abstract void onSomePackagesChanged();
+
+    String getPackageName(Intent intent) {
+        Uri uri = intent.getData();
+        String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
+        return pkg;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        mSomePackagesChanged = false;
+
+        String action = intent.getAction();
+        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+            // We consider something to have changed regardless of whether
+            // this is just an update, because the update is now finished
+            // and the contents of the package may have changed.
+            mSomePackagesChanged = true;
+        } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+            String pkg = getPackageName(intent);
+            if (pkg != null) {
+                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                    mSomePackagesChanged = true;
+                }
+            }
+        } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
+            String pkg = getPackageName(intent);
+            if (pkg != null) {
+                mSomePackagesChanged = true;
+            }
+        } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
+            mSomePackagesChanged = true;
+        } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
+            mSomePackagesChanged = true;
+        } else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) {
+            mSomePackagesChanged = true;
+        } else if (Intent.ACTION_PACKAGES_UNSUSPENDED.equals(action)) {
+            mSomePackagesChanged = true;
+        }
+
+        if (mSomePackagesChanged) {
+            onSomePackagesChanged();
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/servicemonitor/ServiceMonitor.java b/nearby/service/java/com/android/server/nearby/common/servicemonitor/ServiceMonitor.java
new file mode 100644
index 0000000..a86af85
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/servicemonitor/ServiceMonitor.java
@@ -0,0 +1,249 @@
+/*
+ * 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.server.nearby.common.servicemonitor;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import java.io.PrintWriter;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * This is exported from frameworks ServiceWatcher.
+ * A ServiceMonitor is responsible for continuously maintaining an active binding to a service
+ * selected by it's {@link ServiceProvider}. The {@link ServiceProvider} may change the service it
+ * selects over time, and the currently bound service may crash, restart, have a user change, have
+ * changes made to its package, and so on and so forth. The ServiceMonitor is responsible for
+ * maintaining the binding across all these changes.
+ *
+ * <p>Clients may invoke {@link BinderOperation}s on the ServiceMonitor, and it will make a best
+ * effort to run these on the currently bound service, but individual operations may fail (if there
+ * is no service currently bound for instance). In order to help clients maintain the correct state,
+ * clients may supply a {@link ServiceListener}, which is informed when the ServiceMonitor connects
+ * and disconnects from a service. This allows clients to bring a bound service back into a known
+ * state on connection, and then run binder operations from there. In order to help clients
+ * accomplish this, ServiceMonitor guarantees that {@link BinderOperation}s and the
+ * {@link ServiceListener} will always be run on the same thread, so that strong ordering guarantees
+ * can be established between them.
+ *
+ * There is never any guarantee of whether a ServiceMonitor is currently connected to a service, and
+ * whether any particular {@link BinderOperation} will succeed. Clients must ensure they do not rely
+ * on this, and instead use {@link ServiceListener} notifications as necessary to recover from
+ * failures.
+ */
+public interface ServiceMonitor {
+
+    /**
+     * Operation to run on a binder interface. All operations will be run on the thread used by the
+     * ServiceMonitor this is run with.
+     */
+    interface BinderOperation {
+        /** Invoked to run the operation. Run on the ServiceMonitor thread. */
+        void run(IBinder binder) throws RemoteException;
+
+        /**
+         * Invoked if {@link #run(IBinder)} could not be invoked because there was no current
+         * binding, or if {@link #run(IBinder)} threw an exception ({@link RemoteException} or
+         * {@link RuntimeException}). This callback is only intended for resource deallocation and
+         * cleanup in response to a single binder operation, it should not be used to propagate
+         * errors further. Run on the ServiceMonitor thread.
+         */
+        default void onError() {}
+    }
+
+    /**
+     * Listener for bind and unbind events. All operations will be run on the thread used by the
+     * ServiceMonitor this is run with.
+     *
+     * @param <TBoundServiceInfo> type of bound service
+     */
+    interface ServiceListener<TBoundServiceInfo extends BoundServiceInfo> {
+        /** Invoked when a service is bound. Run on the ServiceMonitor thread. */
+        void onBind(IBinder binder, TBoundServiceInfo service) throws RemoteException;
+
+        /** Invoked when a service is unbound. Run on the ServiceMonitor thread. */
+        void onUnbind();
+    }
+
+    /**
+     * A listener for when a {@link ServiceProvider} decides that the current service has changed.
+     */
+    interface ServiceChangedListener {
+        /**
+         * Should be invoked when the current service may have changed.
+         */
+        void onServiceChanged();
+    }
+
+    /**
+     * This provider encapsulates the logic of deciding what service a {@link ServiceMonitor} should
+     * be bound to at any given moment.
+     *
+     * @param <TBoundServiceInfo> type of bound service
+     */
+    interface ServiceProvider<TBoundServiceInfo extends BoundServiceInfo> {
+        /**
+         * Should return true if there exists at least one service capable of meeting the criteria
+         * of this provider. This does not imply that {@link #getServiceInfo()} will always return a
+         * non-null result, as any service may be disqualified for various reasons at any point in
+         * time. May be invoked at any time from any thread and thus should generally not have any
+         * dependency on the other methods in this interface.
+         */
+        boolean hasMatchingService();
+
+        /**
+         * Invoked when the provider should start monitoring for any changes that could result in a
+         * different service selection, and should invoke
+         * {@link ServiceChangedListener#onServiceChanged()} in that case. {@link #getServiceInfo()}
+         * may be invoked after this method is called.
+         */
+        void register(ServiceChangedListener listener);
+
+        /**
+         * Invoked when the provider should stop monitoring for any changes that could result in a
+         * different service selection, should no longer invoke
+         * {@link ServiceChangedListener#onServiceChanged()}. {@link #getServiceInfo()} will not be
+         * invoked after this method is called.
+         */
+        void unregister();
+
+        /**
+         * Must be implemented to return the current service selected by this provider. May return
+         * null if no service currently meets the criteria. Only invoked while registered.
+         */
+        @Nullable TBoundServiceInfo getServiceInfo();
+    }
+
+    /**
+     * Information on the service selected as the best option for binding.
+     */
+    class BoundServiceInfo {
+
+        protected final @Nullable String mAction;
+        protected final int mUid;
+        protected final ComponentName mComponentName;
+
+        protected BoundServiceInfo(String action, int uid, ComponentName componentName) {
+            mAction = action;
+            mUid = uid;
+            mComponentName = Objects.requireNonNull(componentName);
+        }
+
+        /** Returns the action associated with this bound service. */
+        public @Nullable String getAction() {
+            return mAction;
+        }
+
+        /** Returns the component of this bound service. */
+        public ComponentName getComponentName() {
+            return mComponentName;
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof BoundServiceInfo)) {
+                return false;
+            }
+
+            BoundServiceInfo that = (BoundServiceInfo) o;
+            return mUid == that.mUid
+                    && Objects.equals(mAction, that.mAction)
+                    && mComponentName.equals(that.mComponentName);
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(mAction, mUid, mComponentName);
+        }
+
+        @Override
+        public String toString() {
+            if (mComponentName == null) {
+                return "none";
+            } else {
+                return mUid + "/" + mComponentName.flattenToShortString();
+            }
+        }
+    }
+
+    /**
+     * Creates a new ServiceMonitor instance.
+     */
+    static <TBoundServiceInfo extends BoundServiceInfo> ServiceMonitor create(
+            Context context,
+            String tag,
+            ServiceProvider<TBoundServiceInfo> serviceProvider,
+            @Nullable ServiceListener<? super TBoundServiceInfo> serviceListener) {
+        return create(context, ForegroundThread.getHandler(), ForegroundThread.getExecutor(), tag,
+                serviceProvider, serviceListener);
+    }
+
+    /**
+     * Creates a new ServiceMonitor instance that runs on the given handler.
+     */
+    static <TBoundServiceInfo extends BoundServiceInfo> ServiceMonitor create(
+            Context context,
+            Handler handler,
+            Executor executor,
+            String tag,
+            ServiceProvider<TBoundServiceInfo> serviceProvider,
+            @Nullable ServiceListener<? super TBoundServiceInfo> serviceListener) {
+        return new ServiceMonitorImpl<>(context, handler, executor, tag, serviceProvider,
+                serviceListener);
+    }
+
+    /**
+     * Returns true if there is at least one service that the ServiceMonitor could hypothetically
+     * bind to, as selected by the {@link ServiceProvider}.
+     */
+    boolean checkServiceResolves();
+
+    /**
+     * Registers the ServiceMonitor, so that it will begin maintaining an active binding to the
+     * service selected by {@link ServiceProvider}, until {@link #unregister()} is called.
+     */
+    void register();
+
+    /**
+     * Unregisters the ServiceMonitor, so that it will release any active bindings. If the
+     * ServiceMonitor is currently bound, this will result in one final
+     * {@link ServiceListener#onUnbind()} invocation, which may happen after this method completes
+     * (but which is guaranteed to occur before any further
+     * {@link ServiceListener#onBind(IBinder, BoundServiceInfo)} invocation in response to a later
+     * call to {@link #register()}).
+     */
+    void unregister();
+
+    /**
+     * Runs the given binder operation on the currently bound service (if available). The operation
+     * will always fail if the ServiceMonitor is not currently registered.
+     */
+    void runOnBinder(BinderOperation operation);
+
+    /**
+     * Dumps ServiceMonitor information.
+     */
+    void dump(PrintWriter pw);
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/servicemonitor/ServiceMonitorImpl.java b/nearby/service/java/com/android/server/nearby/common/servicemonitor/ServiceMonitorImpl.java
new file mode 100644
index 0000000..d0d6c3b
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/servicemonitor/ServiceMonitorImpl.java
@@ -0,0 +1,305 @@
+/*
+ * 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.server.nearby.common.servicemonitor;
+
+import static android.content.Context.BIND_AUTO_CREATE;
+import static android.content.Context.BIND_NOT_FOREGROUND;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+import com.android.server.nearby.common.servicemonitor.ServiceMonitor.BoundServiceInfo;
+import com.android.server.nearby.common.servicemonitor.ServiceMonitor.ServiceChangedListener;
+
+import java.io.PrintWriter;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * Implementation of ServiceMonitor. Keeping the implementation separate from the interface allows
+ * us to store the generic relationship between the service provider and the service listener, while
+ * hiding the generics from clients, simplifying the API.
+ */
+class ServiceMonitorImpl<TBoundServiceInfo extends BoundServiceInfo> implements ServiceMonitor,
+        ServiceChangedListener {
+
+    private static final String TAG = "ServiceMonitor";
+    private static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
+    private static final long RETRY_DELAY_MS = 15 * 1000;
+
+    // This is the same as Context.BIND_NOT_VISIBLE.
+    private static final int BIND_NOT_VISIBLE = 0x40000000;
+
+    final Context mContext;
+    final Handler mHandler;
+    final Executor mExecutor;
+    final String mTag;
+    final ServiceProvider<TBoundServiceInfo> mServiceProvider;
+    final @Nullable ServiceListener<? super TBoundServiceInfo> mServiceListener;
+
+    private final PackageWatcher mPackageWatcher = new PackageWatcher() {
+        @Override
+        public void onSomePackagesChanged() {
+            onServiceChanged(false);
+        }
+    };
+
+    @GuardedBy("this")
+    private boolean mRegistered = false;
+    @GuardedBy("this")
+    private MyServiceConnection mServiceConnection = new MyServiceConnection(null);
+
+    ServiceMonitorImpl(Context context, Handler handler, Executor executor, String tag,
+            ServiceProvider<TBoundServiceInfo> serviceProvider,
+            ServiceListener<? super TBoundServiceInfo> serviceListener) {
+        mContext = context;
+        mExecutor = executor;
+        mHandler = handler;
+        mTag = tag;
+        mServiceProvider = serviceProvider;
+        mServiceListener = serviceListener;
+    }
+
+    @Override
+    public boolean checkServiceResolves() {
+        return mServiceProvider.hasMatchingService();
+    }
+
+    @Override
+    public synchronized void register() {
+        Preconditions.checkState(!mRegistered);
+
+        mRegistered = true;
+        mPackageWatcher.register(mContext, /*externalStorage=*/ true, mHandler);
+        mServiceProvider.register(this);
+
+        onServiceChanged(false);
+    }
+
+    @Override
+    public synchronized void unregister() {
+        Preconditions.checkState(mRegistered);
+
+        mServiceProvider.unregister();
+        mPackageWatcher.unregister();
+        mRegistered = false;
+
+        onServiceChanged(false);
+    }
+
+    @Override
+    public synchronized void onServiceChanged() {
+        onServiceChanged(false);
+    }
+
+    @Override
+    public synchronized void runOnBinder(BinderOperation operation) {
+        MyServiceConnection serviceConnection = mServiceConnection;
+        mHandler.post(() -> serviceConnection.runOnBinder(operation));
+    }
+
+    synchronized void onServiceChanged(boolean forceRebind) {
+        TBoundServiceInfo newBoundServiceInfo;
+        if (mRegistered) {
+            newBoundServiceInfo = mServiceProvider.getServiceInfo();
+        } else {
+            newBoundServiceInfo = null;
+        }
+
+        if (forceRebind || !Objects.equals(mServiceConnection.getBoundServiceInfo(),
+                newBoundServiceInfo)) {
+            Log.i(TAG, "[" + mTag + "] chose new implementation " + newBoundServiceInfo);
+            MyServiceConnection oldServiceConnection = mServiceConnection;
+            MyServiceConnection newServiceConnection = new MyServiceConnection(newBoundServiceInfo);
+            mServiceConnection = newServiceConnection;
+            mHandler.post(() -> {
+                oldServiceConnection.unbind();
+                newServiceConnection.bind();
+            });
+        }
+    }
+
+    @Override
+    public String toString() {
+        MyServiceConnection serviceConnection;
+        synchronized (this) {
+            serviceConnection = mServiceConnection;
+        }
+
+        return serviceConnection.getBoundServiceInfo().toString();
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        MyServiceConnection serviceConnection;
+        synchronized (this) {
+            serviceConnection = mServiceConnection;
+        }
+
+        pw.println("target service=" + serviceConnection.getBoundServiceInfo());
+        pw.println("connected=" + serviceConnection.isConnected());
+    }
+
+    // runs on the handler thread, and expects most of its methods to be called from that thread
+    private class MyServiceConnection implements ServiceConnection {
+
+        private final @Nullable TBoundServiceInfo mBoundServiceInfo;
+
+        // volatile so that isConnected can be called from any thread easily
+        private volatile @Nullable IBinder mBinder;
+        private @Nullable Runnable mRebinder;
+
+        MyServiceConnection(@Nullable TBoundServiceInfo boundServiceInfo) {
+            mBoundServiceInfo = boundServiceInfo;
+        }
+
+        // may be called from any thread
+        @Nullable TBoundServiceInfo getBoundServiceInfo() {
+            return mBoundServiceInfo;
+        }
+
+        // may be called from any thread
+        boolean isConnected() {
+            return mBinder != null;
+        }
+
+        void bind() {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            if (mBoundServiceInfo == null) {
+                return;
+            }
+
+            if (D) {
+                Log.d(TAG, "[" + mTag + "] binding to " + mBoundServiceInfo);
+            }
+
+            Intent bindIntent = new Intent(mBoundServiceInfo.getAction())
+                    .setComponent(mBoundServiceInfo.getComponentName());
+            if (!mContext.bindService(bindIntent,
+                    BIND_AUTO_CREATE | BIND_NOT_FOREGROUND | BIND_NOT_VISIBLE,
+                    mExecutor, this)) {
+                Log.e(TAG, "[" + mTag + "] unexpected bind failure - retrying later");
+                mRebinder = this::bind;
+                mHandler.postDelayed(mRebinder, RETRY_DELAY_MS);
+            } else {
+                mRebinder = null;
+            }
+        }
+
+        void unbind() {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            if (mBoundServiceInfo == null) {
+                return;
+            }
+
+            if (D) {
+                Log.d(TAG, "[" + mTag + "] unbinding from " + mBoundServiceInfo);
+            }
+
+            if (mRebinder != null) {
+                mHandler.removeCallbacks(mRebinder);
+                mRebinder = null;
+            } else {
+                mContext.unbindService(this);
+            }
+
+            onServiceDisconnected(mBoundServiceInfo.getComponentName());
+        }
+
+        void runOnBinder(BinderOperation operation) {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            if (mBinder == null) {
+                operation.onError();
+                return;
+            }
+
+            try {
+                operation.run(mBinder);
+            } catch (RuntimeException | RemoteException e) {
+                // binders may propagate some specific non-RemoteExceptions from the other side
+                // through the binder as well - we cannot allow those to crash the system server
+                Log.e(TAG, "[" + mTag + "] error running operation on " + mBoundServiceInfo, e);
+                operation.onError();
+            }
+        }
+
+        @Override
+        public final void onServiceConnected(ComponentName component, IBinder binder) {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+            Preconditions.checkState(mBinder == null);
+
+            Log.i(TAG, "[" + mTag + "] connected to " + component.toShortString());
+
+            mBinder = binder;
+
+            if (mServiceListener != null) {
+                try {
+                    mServiceListener.onBind(binder, mBoundServiceInfo);
+                } catch (RuntimeException | RemoteException e) {
+                    // binders may propagate some specific non-RemoteExceptions from the other side
+                    // through the binder as well - we cannot allow those to crash the system server
+                    Log.e(TAG, "[" + mTag + "] error running operation on " + mBoundServiceInfo, e);
+                }
+            }
+        }
+
+        @Override
+        public final void onServiceDisconnected(ComponentName component) {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            if (mBinder == null) {
+                return;
+            }
+
+            Log.i(TAG, "[" + mTag + "] disconnected from " + mBoundServiceInfo);
+
+            mBinder = null;
+            if (mServiceListener != null) {
+                mServiceListener.onUnbind();
+            }
+        }
+
+        @Override
+        public final void onBindingDied(ComponentName component) {
+            Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
+
+            Log.w(TAG, "[" + mTag + "] " + mBoundServiceInfo + " died");
+
+            // introduce a small delay to prevent spamming binding over and over, since the likely
+            // cause of a binding dying is some package event that may take time to recover from
+            mHandler.postDelayed(() -> onServiceChanged(true), 500);
+        }
+
+        @Override
+        public final void onNullBinding(ComponentName component) {
+            Log.e(TAG, "[" + mTag + "] " + mBoundServiceInfo + " has null binding");
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/Constant.java b/nearby/service/java/com/android/server/nearby/fastpair/Constant.java
new file mode 100644
index 0000000..0695b5f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/Constant.java
@@ -0,0 +1,43 @@
+/*
+ * 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.server.nearby.fastpair;
+
+/**
+ * String constant for half sheet.
+ */
+public class Constant {
+
+    /**
+     * Value represents true for {@link android.provider.Settings.Secure}
+     */
+    public static final int SETTINGS_TRUE_VALUE = 1;
+
+    /**
+     * Tag for Fast Pair service related logs.
+     */
+    public static final String TAG = "FastPairService";
+
+    public static final String EXTRA_BINDER = "com.android.server.nearby.fastpair.BINDER";
+    public static final String EXTRA_BUNDLE = "com.android.server.nearby.fastpair.BUNDLE_EXTRA";
+    public static final String ACTION_FAST_PAIR_HALF_SHEET_CANCEL =
+            "com.android.nearby.ACTION_FAST_PAIR_HALF_SHEET_CANCEL";
+    public static final String EXTRA_HALF_SHEET_INFO =
+            "com.android.nearby.halfsheet.HALF_SHEET";
+    public static final String EXTRA_HALF_SHEET_TYPE =
+            "com.android.nearby.halfsheet.HALF_SHEET_TYPE";
+    public static final String DEVICE_PAIRING_FRAGMENT_TYPE = "DEVICE_PAIRING";
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
new file mode 100644
index 0000000..b175234
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.fastpair;
+
+import static com.android.server.nearby.fastpair.Constant.TAG;
+
+import static com.google.common.primitives.Bytes.concat;
+
+import android.accounts.Account;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.nearby.FastPairDevice;
+import android.nearby.NearbyDevice;
+import android.util.Log;
+
+import com.android.server.nearby.common.ble.decode.FastPairDecoder;
+import com.android.server.nearby.common.bloomfilter.BloomFilter;
+import com.android.server.nearby.common.bloomfilter.FastPairBloomFilterHasher;
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+import com.android.server.nearby.fastpair.cache.FastPairCacheManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+import com.android.server.nearby.provider.FastPairDataProvider;
+import com.android.server.nearby.util.DataUtils;
+import com.android.server.nearby.util.Hex;
+
+import java.util.List;
+
+import service.proto.Cache;
+import service.proto.Data;
+import service.proto.Rpcs;
+
+/**
+ * Handler that handle fast pair related broadcast.
+ */
+public class FastPairAdvHandler {
+    Context mContext;
+    String mBleAddress;
+    // Need to be deleted after notification manager in use.
+    private boolean mIsFirst = false;
+
+    /** The types about how the bloomfilter is processed. */
+    public enum ProcessBloomFilterType {
+        IGNORE, // The bloomfilter is not handled. e.g. distance is too far away.
+        CACHE, // The bloomfilter is recognized in the local cache.
+        FOOTPRINT, // Need to check the bloomfilter from the footprints.
+        ACCOUNT_KEY_HIT // The specified account key was hit the bloom filter.
+    }
+
+    /**
+     * Constructor function.
+     */
+    public FastPairAdvHandler(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Handles all of the scanner result. Fast Pair will handle model id broadcast bloomfilter
+     * broadcast and battery level broadcast.
+     */
+    public void handleBroadcast(NearbyDevice device) {
+        FastPairDevice fastPairDevice = (FastPairDevice) device;
+        mBleAddress = fastPairDevice.getBluetoothAddress();
+        FastPairDataProvider dataProvider = FastPairDataProvider.getInstance();
+        if (dataProvider == null) {
+            return;
+        }
+        List<Account> accountList = dataProvider.loadFastPairEligibleAccounts();
+        if (FastPairDecoder.checkModelId(fastPairDevice.getData())) {
+            byte[] model = FastPairDecoder.getModelId(fastPairDevice.getData());
+            Log.d(TAG, "On discovery model id " + Hex.bytesToStringLowercase(model));
+            // Use api to get anti spoofing key from model id.
+            try {
+                Rpcs.GetObservedDeviceResponse response =
+                        dataProvider.loadFastPairAntispoofKeyDeviceMetadata(model);
+                if (response == null) {
+                    Log.e(TAG, "server does not have model id "
+                            + Hex.bytesToStringLowercase(model));
+                    return;
+                }
+                Locator.get(mContext, FastPairHalfSheetManager.class).showHalfSheet(
+                        DataUtils.toScanFastPairStoreItem(
+                                response, mBleAddress,
+                                accountList.isEmpty() ? null : accountList.get(0).name));
+            } catch (IllegalStateException e) {
+                Log.e(TAG, "OEM does not construct fast pair data proxy correctly");
+            }
+        } else {
+            // Start to process bloom filter
+            try {
+                byte[] bloomFilterByteArray = FastPairDecoder
+                        .getBloomFilter(fastPairDevice.getData());
+                byte[] bloomFilterSalt = FastPairDecoder
+                        .getBloomFilterSalt(fastPairDevice.getData());
+                if (bloomFilterByteArray == null || bloomFilterByteArray.length == 0) {
+                    return;
+                }
+                for (Account account : accountList) {
+                    List<Data.FastPairDeviceWithAccountKey> listDevices =
+                            dataProvider.loadFastPairDeviceWithAccountKey(account);
+                    Data.FastPairDeviceWithAccountKey recognizedDevice =
+                            findRecognizedDevice(listDevices,
+                                    new BloomFilter(bloomFilterByteArray,
+                                            new FastPairBloomFilterHasher()), bloomFilterSalt);
+
+                    if (recognizedDevice != null) {
+                        Log.d(TAG, "find matched device show notification to remind"
+                                + " user to pair");
+                        // Check if the device is already paired
+                        List<Cache.StoredFastPairItem> storedFastPairItemList =
+                                Locator.get(mContext, FastPairCacheManager.class)
+                                        .getAllSavedStoredFastPairItem();
+                        Cache.StoredFastPairItem recognizedStoredFastPairItem =
+                                findRecognizedDeviceFromCachedItem(storedFastPairItemList,
+                                        new BloomFilter(bloomFilterByteArray,
+                                                new FastPairBloomFilterHasher()), bloomFilterSalt);
+                        if (recognizedStoredFastPairItem != null) {
+                            // The bloomfilter is recognized in the cache so the device is paired
+                            // before
+                            Log.d(TAG, "bloom filter is recognized in the cache");
+                            continue;
+                        } else {
+                            Log.d(TAG, "bloom filter is recognized not paired before should"
+                                    + "show subsequent pairing notification");
+                            if (mIsFirst) {
+                                mIsFirst = false;
+                                // Get full info from api the initial request will only return
+                                // part of the info due to size limit.
+                                List<Data.FastPairDeviceWithAccountKey> resList =
+                                        dataProvider.loadFastPairDeviceWithAccountKey(account,
+                                        List.of(recognizedDevice.getAccountKey().toByteArray()));
+                                if (resList != null && resList.size() > 0) {
+                                    //Saved device from footprint does not have ble address so
+                                    // fill ble address with current scan result.
+                                    Cache.StoredDiscoveryItem storedDiscoveryItem =
+                                            resList.get(0).getDiscoveryItem().toBuilder()
+                                                    .setMacAddress(
+                                                            fastPairDevice.getBluetoothAddress())
+                                                    .build();
+                                    Locator.get(mContext, FastPairController.class).pair(
+                                            new DiscoveryItem(mContext, storedDiscoveryItem),
+                                            resList.get(0).getAccountKey().toByteArray(),
+                                            /** companionApp=*/ null);
+                                }
+                            }
+                        }
+
+                        return;
+                    }
+                }
+            } catch (IllegalStateException e) {
+                Log.e(TAG, "OEM does not construct fast pair data proxy correctly");
+            }
+
+        }
+    }
+
+    /**
+     * Checks the bloom filter to see if any of the devices are recognized and should have a
+     * notification displayed for them. A device is recognized if the account key + salt combination
+     * is inside the bloom filter.
+     */
+    @Nullable
+    static Data.FastPairDeviceWithAccountKey findRecognizedDevice(
+            List<Data.FastPairDeviceWithAccountKey> devices, BloomFilter bloomFilter, byte[] salt) {
+        Log.d(TAG, "saved devices size in the account is " + devices.size());
+        for (Data.FastPairDeviceWithAccountKey device : devices) {
+            if (device.getAccountKey().toByteArray() == null || salt == null) {
+                return null;
+            }
+            byte[] rotatedKey = concat(device.getAccountKey().toByteArray(), salt);
+            StringBuilder sb = new StringBuilder();
+            for (byte b : rotatedKey) {
+                sb.append(b);
+            }
+            if (bloomFilter.possiblyContains(rotatedKey)) {
+                Log.d(TAG, "match " + sb.toString());
+                return device;
+            } else {
+                Log.d(TAG, "not match " + sb.toString());
+            }
+        }
+        return null;
+    }
+
+    @Nullable
+    static Cache.StoredFastPairItem findRecognizedDeviceFromCachedItem(
+            List<Cache.StoredFastPairItem> devices, BloomFilter bloomFilter, byte[] salt) {
+        for (Cache.StoredFastPairItem device : devices) {
+            if (device.getAccountKey().toByteArray() == null || salt == null) {
+                return null;
+            }
+            byte[] rotatedKey = concat(device.getAccountKey().toByteArray(), salt);
+            if (bloomFilter.possiblyContains(rotatedKey)) {
+                return device;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairController.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairController.java
new file mode 100644
index 0000000..e1db7e5
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairController.java
@@ -0,0 +1,323 @@
+/*
+ * 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.server.nearby.fastpair;
+
+import static com.google.common.primitives.Bytes.concat;
+
+import android.accounts.Account;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.nearby.FastPairDevice;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.WorkerThread;
+
+import com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress;
+import com.android.server.nearby.common.eventloop.Annotations;
+import com.android.server.nearby.common.eventloop.EventLoop;
+import com.android.server.nearby.common.eventloop.NamedRunnable;
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+import com.android.server.nearby.fastpair.cache.FastPairCacheManager;
+import com.android.server.nearby.fastpair.footprint.FastPairUploadInfo;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+import com.android.server.nearby.fastpair.notification.FastPairNotificationManager;
+import com.android.server.nearby.fastpair.pairinghandler.PairingProgressHandlerBase;
+import com.android.server.nearby.provider.FastPairDataProvider;
+
+import com.google.common.hash.Hashing;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import service.proto.Cache;
+
+/**
+ * FastPair controller after get the info from intent handler Fast Pair controller is responsible
+ * for pairing control.
+ */
+public class FastPairController {
+    private static final String TAG = "FastPairController";
+    private final Context mContext;
+    private final EventLoop mEventLoop;
+    private final FastPairCacheManager mFastPairCacheManager;
+    private final FootprintsDeviceManager mFootprintsDeviceManager;
+    private boolean mIsFastPairing = false;
+    // boolean flag whether upload to footprint or not.
+    private boolean mShouldUpload = false;
+    @Nullable
+    private Callback mCallback;
+
+    public FastPairController(Context context) {
+        mContext = context;
+        mEventLoop = Locator.get(mContext, EventLoop.class);
+        mFastPairCacheManager = Locator.get(mContext, FastPairCacheManager.class);
+        mFootprintsDeviceManager = Locator.get(mContext, FootprintsDeviceManager.class);
+    }
+
+    /**
+     * Should be called on create lifecycle.
+     */
+    @WorkerThread
+    public void onCreate() {
+        mEventLoop.postRunnable(new NamedRunnable("FastPairController::InitializeScanner") {
+            @Override
+            public void run() {
+                // init scanner here and start scan.
+            }
+        });
+    }
+
+    /**
+     * Should be called on destroy lifecycle.
+     */
+    @WorkerThread
+    public void onDestroy() {
+        mEventLoop.postRunnable(new NamedRunnable("FastPairController::DestroyScanner") {
+            @Override
+            public void run() {
+                // Unregister scanner from here
+            }
+        });
+    }
+
+    /**
+     * Pairing function.
+     */
+    public void pair(FastPairDevice fastPairDevice) {
+        byte[] discoveryItem = fastPairDevice.getData();
+        String modelId = fastPairDevice.getModelId();
+
+        Log.v(TAG, "pair: fastPairDevice " + fastPairDevice);
+        mEventLoop.postRunnable(
+                new NamedRunnable("fastPairWith=" + modelId) {
+                    @Override
+                    public void run() {
+                        try {
+                            DiscoveryItem item = new DiscoveryItem(mContext,
+                                    Cache.StoredDiscoveryItem.parseFrom(discoveryItem));
+                            if (TextUtils.isEmpty(item.getMacAddress())) {
+                                Log.w(TAG, "There is no mac address in the DiscoveryItem,"
+                                        + " ignore pairing");
+                                return;
+                            }
+                            // Check enabled state to prevent multiple pair attempts if we get the
+                            // intent more than once (this can happen due to an Android platform
+                            // bug - b/31459521).
+                            if (item.getState()
+                                    != Cache.StoredDiscoveryItem.State.STATE_ENABLED) {
+                                Log.d(TAG, "Incorrect state, ignore pairing");
+                                return;
+                            }
+                            boolean useLargeNotifications =
+                                    item.getAuthenticationPublicKeySecp256R1() != null;
+                            FastPairNotificationManager fastPairNotificationManager =
+                                    new FastPairNotificationManager(mContext, item,
+                                            useLargeNotifications);
+                            FastPairHalfSheetManager fastPairHalfSheetManager =
+                                    Locator.get(mContext, FastPairHalfSheetManager.class);
+                            mFastPairCacheManager.saveDiscoveryItem(item);
+
+                            PairingProgressHandlerBase pairingProgressHandlerBase =
+                                    PairingProgressHandlerBase.create(
+                                            mContext,
+                                            item,
+                                            /* companionApp= */ null,
+                                            /* accountKey= */ null,
+                                            mFootprintsDeviceManager,
+                                            fastPairNotificationManager,
+                                            fastPairHalfSheetManager,
+                                            /* isRetroactivePair= */ false);
+
+                            pair(item,
+                                    /* accountKey= */ null,
+                                    /* companionApp= */ null,
+                                    pairingProgressHandlerBase);
+                        } catch (InvalidProtocolBufferException e) {
+                            Log.w(TAG,
+                                    "Error parsing serialized discovery item with size "
+                                            + discoveryItem.length);
+                        }
+                    }
+                });
+    }
+
+    /**
+     * Subsequent pairing entry.
+     */
+    public void pair(DiscoveryItem item,
+            @Nullable byte[] accountKey,
+            @Nullable String companionApp) {
+        FastPairNotificationManager fastPairNotificationManager =
+                new FastPairNotificationManager(mContext, item, false);
+        FastPairHalfSheetManager fastPairHalfSheetManager =
+                Locator.get(mContext, FastPairHalfSheetManager.class);
+        PairingProgressHandlerBase pairingProgressHandlerBase =
+                PairingProgressHandlerBase.create(
+                        mContext,
+                        item,
+                        /* companionApp= */ null,
+                        /* accountKey= */ accountKey,
+                        mFootprintsDeviceManager,
+                        fastPairNotificationManager,
+                        fastPairHalfSheetManager,
+                        /* isRetroactivePair= */ false);
+        pair(item, accountKey, companionApp, pairingProgressHandlerBase);
+    }
+    /**
+     * Pairing function
+     */
+    @Annotations.EventThread
+    public void pair(
+            DiscoveryItem item,
+            @Nullable byte[] accountKey,
+            @Nullable String companionApp,
+            PairingProgressHandlerBase pairingProgressHandlerBase) {
+        if (mIsFastPairing) {
+            Log.d(TAG, "FastPair: fastpairing, skip pair request");
+            return;
+        }
+        mIsFastPairing = true;
+        Log.d(TAG, "FastPair: start pair");
+
+        // Hide all "tap to pair" notifications until after the flow completes.
+        mEventLoop.removeRunnable(mReEnableAllDeviceItemsRunnable);
+        if (mCallback != null) {
+            mCallback.fastPairUpdateDeviceItemsEnabled(false);
+        }
+
+        Future<Void> task =
+                FastPairManager.pair(
+                        Executors.newSingleThreadExecutor(),
+                        mContext,
+                        item,
+                        accountKey,
+                        companionApp,
+                        mFootprintsDeviceManager,
+                        pairingProgressHandlerBase);
+        mIsFastPairing = false;
+    }
+
+    /** Fixes a companion app package name with extra spaces. */
+    private static String trimCompanionApp(String companionApp) {
+        return companionApp == null ? null : companionApp.trim();
+    }
+
+    /**
+     * Function to handle when scanner find bloomfilter.
+     */
+    @Annotations.EventThread
+    public FastPairAdvHandler.ProcessBloomFilterType onBloomFilterDetect(FastPairAdvHandler handler,
+            boolean advertiseInRange) {
+        if (mIsFastPairing) {
+            return FastPairAdvHandler.ProcessBloomFilterType.IGNORE;
+        }
+        // Check if the device is in the cache or footprint.
+        return FastPairAdvHandler.ProcessBloomFilterType.CACHE;
+    }
+
+    /**
+     * Add newly paired device info to footprint
+     */
+    @WorkerThread
+    public void addDeviceToFootprint(String publicAddress, byte[] accountKey,
+            DiscoveryItem discoveryItem) {
+        if (!mShouldUpload) {
+            return;
+        }
+        Log.d(TAG, "upload device to footprint");
+        FastPairManager.processBackgroundTask(() -> {
+            Cache.StoredDiscoveryItem storedDiscoveryItem =
+                    prepareStoredDiscoveryItemForFootprints(discoveryItem);
+            byte[] hashValue =
+                    Hashing.sha256()
+                            .hashBytes(
+                                    concat(accountKey, BluetoothAddress.decode(publicAddress)))
+                            .asBytes();
+            FastPairUploadInfo uploadInfo =
+                    new FastPairUploadInfo(storedDiscoveryItem, ByteString.copyFrom(accountKey),
+                            ByteString.copyFrom(hashValue));
+            // account data place holder here
+            try {
+                FastPairDataProvider fastPairDataProvider = FastPairDataProvider.getInstance();
+                if (fastPairDataProvider == null) {
+                    return;
+                }
+                List<Account> accountList = fastPairDataProvider.loadFastPairEligibleAccounts();
+                if (accountList.size() > 0) {
+                    fastPairDataProvider.optIn(accountList.get(0));
+                    fastPairDataProvider.upload(accountList.get(0), uploadInfo);
+                }
+            } catch (IllegalStateException e) {
+                Log.e(TAG, "OEM does not construct fast pair data proxy correctly");
+            }
+        });
+    }
+
+    @Nullable
+    private Cache.StoredDiscoveryItem getStoredDiscoveryItemFromAddressForFootprints(
+            String bleAddress) {
+
+        List<DiscoveryItem> discoveryItems = new ArrayList<>();
+        //cacheManager.getAllDiscoveryItems();
+        for (DiscoveryItem discoveryItem : discoveryItems) {
+            if (bleAddress.equals(discoveryItem.getMacAddress())) {
+                return prepareStoredDiscoveryItemForFootprints(discoveryItem);
+            }
+        }
+        return null;
+    }
+
+    static Cache.StoredDiscoveryItem prepareStoredDiscoveryItemForFootprints(
+            DiscoveryItem discoveryItem) {
+        Cache.StoredDiscoveryItem.Builder storedDiscoveryItem =
+                discoveryItem.getCopyOfStoredItem().toBuilder();
+        // Strip the mac address so we aren't storing it in the cloud and ensure the item always
+        // starts as enabled and in a good state.
+        storedDiscoveryItem.clearMacAddress();
+
+        return storedDiscoveryItem.build();
+    }
+
+    /**
+     * FastPairConnection will check whether write account key result if the account key is
+     * generated change the parameter.
+     */
+    public void setShouldUpload(boolean shouldUpload) {
+        mShouldUpload = shouldUpload;
+    }
+
+    private final NamedRunnable mReEnableAllDeviceItemsRunnable =
+            new NamedRunnable("reEnableAllDeviceItems") {
+                @Override
+                public void run() {
+                    if (mCallback != null) {
+                        mCallback.fastPairUpdateDeviceItemsEnabled(true);
+                    }
+                }
+            };
+
+    interface Callback {
+        void fastPairUpdateDeviceItemsEnabled(boolean enabled);
+    }
+}
\ No newline at end of file
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
new file mode 100644
index 0000000..16c04de
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
@@ -0,0 +1,460 @@
+/*
+ * 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.server.nearby.fastpair;
+
+import static com.android.server.nearby.fastpair.Constant.TAG;
+
+import android.annotation.Nullable;
+import android.annotation.WorkerThread;
+import android.app.KeyguardManager;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.nearby.FastPairDevice;
+import android.nearby.NearbyDevice;
+import android.nearby.NearbyManager;
+import android.nearby.ScanCallback;
+import android.nearby.ScanRequest;
+import android.net.Uri;
+import android.provider.Settings;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.nearby.common.ble.decode.FastPairDecoder;
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.fastpair.FastPairConnection;
+import com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection;
+import com.android.server.nearby.common.bluetooth.fastpair.PairingException;
+import com.android.server.nearby.common.bluetooth.fastpair.Preferences;
+import com.android.server.nearby.common.bluetooth.fastpair.ReflectionException;
+import com.android.server.nearby.common.bluetooth.fastpair.SimpleBroadcastReceiver;
+import com.android.server.nearby.common.eventloop.Annotations;
+import com.android.server.nearby.common.eventloop.EventLoop;
+import com.android.server.nearby.common.eventloop.NamedRunnable;
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+import com.android.server.nearby.fastpair.cache.FastPairCacheManager;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+import com.android.server.nearby.fastpair.pairinghandler.PairingProgressHandlerBase;
+import com.android.server.nearby.util.ForegroundThread;
+import com.android.server.nearby.util.Hex;
+
+import com.google.common.collect.ImmutableList;
+import com.google.protobuf.ByteString;
+
+import java.security.GeneralSecurityException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import service.proto.Cache;
+import service.proto.Rpcs;
+
+/**
+ * FastPairManager is the class initiated in nearby service to handle Fast Pair related
+ * work.
+ */
+
+public class FastPairManager {
+
+    private static final String ACTION_PREFIX = UserActionHandler.PREFIX;
+    private static final int WAIT_FOR_UNLOCK_MILLIS = 5000;
+
+    /** A notification ID which should be dismissed */
+    public static final String EXTRA_NOTIFICATION_ID = ACTION_PREFIX + "EXTRA_NOTIFICATION_ID";
+    public static final String ACTION_RESOURCES_APK = "android.nearby.SHOW_HALFSHEET";
+
+    private static Executor sFastPairExecutor;
+
+    private ContentObserver mFastPairScanChangeContentObserver = null;
+
+    final LocatorContextWrapper mLocatorContextWrapper;
+    final IntentFilter mIntentFilter;
+    final Locator mLocator;
+    private boolean mScanEnabled;
+
+    private final BroadcastReceiver mScreenBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
+                Log.d(TAG, "onReceive: ACTION_SCREEN_ON.");
+                invalidateScan();
+            } else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
+                processBluetoothConnectionEvent(intent);
+            }
+        }
+    };
+
+    public FastPairManager(LocatorContextWrapper contextWrapper) {
+        mLocatorContextWrapper = contextWrapper;
+        mIntentFilter = new IntentFilter();
+        mLocator = mLocatorContextWrapper.getLocator();
+        mLocator.bind(new FastPairModule());
+        Rpcs.GetObservedDeviceResponse getObservedDeviceResponse =
+                Rpcs.GetObservedDeviceResponse.newBuilder().build();
+    }
+
+    final ScanCallback mScanCallback = new ScanCallback() {
+        @Override
+        public void onDiscovered(@NonNull NearbyDevice device) {
+            Locator.get(mLocatorContextWrapper, FastPairAdvHandler.class).handleBroadcast(device);
+        }
+
+        @Override
+        public void onUpdated(@NonNull NearbyDevice device) {
+            FastPairDevice fastPairDevice = (FastPairDevice) device;
+            byte[] modelArray = FastPairDecoder.getModelId(fastPairDevice.getData());
+            Log.d(TAG, "update model id" + Hex.bytesToStringLowercase(modelArray));
+        }
+
+        @Override
+        public void onLost(@NonNull NearbyDevice device) {
+            FastPairDevice fastPairDevice = (FastPairDevice) device;
+            byte[] modelArray = FastPairDecoder.getModelId(fastPairDevice.getData());
+            Log.d(TAG, "lost model id" + Hex.bytesToStringLowercase(modelArray));
+        }
+    };
+
+    /**
+     * Function called when nearby service start.
+     */
+    public void initiate() {
+        mIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
+        mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+        mIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+
+        mLocatorContextWrapper.getContext()
+                .registerReceiver(mScreenBroadcastReceiver, mIntentFilter);
+
+        Locator.getFromContextWrapper(mLocatorContextWrapper, FastPairCacheManager.class);
+        // Default false for now.
+        mScanEnabled = NearbyManager.getFastPairScanEnabled(mLocatorContextWrapper.getContext());
+        registerFastPairScanChangeContentObserver(mLocatorContextWrapper.getContentResolver());
+    }
+
+    /**
+     * Function to free up fast pair resource.
+     */
+    public void cleanUp() {
+        mLocatorContextWrapper.getContext().unregisterReceiver(mScreenBroadcastReceiver);
+        if (mFastPairScanChangeContentObserver != null) {
+            mLocatorContextWrapper.getContentResolver().unregisterContentObserver(
+                    mFastPairScanChangeContentObserver);
+        }
+    }
+
+    /**
+     * Starts fast pair process.
+     */
+    @Annotations.EventThread
+    public static Future<Void> pair(
+            ExecutorService executor,
+            Context context,
+            DiscoveryItem item,
+            @Nullable byte[] accountKey,
+            @Nullable String companionApp,
+            FootprintsDeviceManager footprints,
+            PairingProgressHandlerBase pairingProgressHandlerBase) {
+        return executor.submit(
+                () -> pairInternal(context, item, companionApp, accountKey, footprints,
+                        pairingProgressHandlerBase), /* result= */ null);
+    }
+
+    /**
+     * Starts fast pair
+     */
+    @WorkerThread
+    public static void pairInternal(
+            Context context,
+            DiscoveryItem item,
+            @Nullable String companionApp,
+            @Nullable byte[] accountKey,
+            FootprintsDeviceManager footprints,
+            PairingProgressHandlerBase pairingProgressHandlerBase) {
+        FastPairHalfSheetManager fastPairHalfSheetManager =
+                Locator.get(context, FastPairHalfSheetManager.class);
+        try {
+            pairingProgressHandlerBase.onPairingStarted();
+            if (pairingProgressHandlerBase.skipWaitingScreenUnlock()) {
+                // Do nothing due to we are not showing the status notification in some pairing
+                // types, e.g. the retroactive pairing.
+            } else {
+                // If the screen is locked when the user taps to pair, the screen will unlock. We
+                // must wait for the unlock to complete before showing the status notification, or
+                // it won't be heads-up.
+                pairingProgressHandlerBase.onWaitForScreenUnlock();
+                waitUntilScreenIsUnlocked(context);
+                pairingProgressHandlerBase.onScreenUnlocked();
+            }
+            BluetoothAdapter bluetoothAdapter = getBluetoothAdapter(context);
+
+            boolean isBluetoothEnabled = bluetoothAdapter != null && bluetoothAdapter.isEnabled();
+            if (!isBluetoothEnabled) {
+                if (bluetoothAdapter == null || !bluetoothAdapter.enable()) {
+                    Log.d(TAG, "FastPair: Failed to enable bluetooth");
+                    return;
+                }
+                Log.v(TAG, "FastPair: Enabling bluetooth for fast pair");
+
+                Locator.get(context, EventLoop.class)
+                        .postRunnable(
+                                new NamedRunnable("enableBluetoothToast") {
+                                    @Override
+                                    public void run() {
+                                        Log.d(TAG, "Enable bluetooth toast test");
+                                    }
+                                });
+                // Set up call back to call this function again once bluetooth has been
+                // enabled; this does not seem to be a problem as the device connects without a
+                // problem, but in theory the timeout also includes turning on bluetooth now.
+            }
+
+            pairingProgressHandlerBase.onReadyToPair();
+
+            String modelId = item.getTriggerId();
+            Preferences.Builder prefsBuilder =
+                    Preferences.builderFromGmsLog()
+                            .setEnableBrEdrHandover(false)
+                            .setIgnoreDiscoveryError(true);
+            pairingProgressHandlerBase.onSetupPreferencesBuilder(prefsBuilder);
+            if (item.getFastPairInformation() != null) {
+                prefsBuilder.setSkipConnectingProfiles(
+                        item.getFastPairInformation().getDataOnlyConnection());
+            }
+            // When add watch and auto device needs to change the config
+            prefsBuilder.setRejectMessageAccess(true);
+            prefsBuilder.setRejectPhonebookAccess(true);
+            prefsBuilder.setHandlePasskeyConfirmationByUi(false);
+
+            FastPairConnection connection = new FastPairDualConnection(
+                    context, item.getMacAddress(),
+                    prefsBuilder.build(),
+                    null);
+            pairingProgressHandlerBase.onPairingSetupCompleted();
+
+            FastPairConnection.SharedSecret sharedSecret;
+            if ((accountKey != null || item.getAuthenticationPublicKeySecp256R1() != null)) {
+                sharedSecret =
+                        connection.pair(
+                                accountKey != null ? accountKey
+                                        : item.getAuthenticationPublicKeySecp256R1());
+                if (accountKey == null) {
+                    // Account key is null so it is initial pairing
+                    if (sharedSecret != null) {
+                        Locator.get(context, FastPairController.class).addDeviceToFootprint(
+                                connection.getPublicAddress(), sharedSecret.getKey(), item);
+                        cacheFastPairDevice(context, connection.getPublicAddress(),
+                                sharedSecret.getKey(), item);
+                    }
+                }
+            } else {
+                // Fast Pair one
+                connection.pair();
+            }
+            // TODO(b/213373051): Merge logic with pairingProgressHandlerBase or delete the
+            // pairingProgressHandlerBase class.
+            fastPairHalfSheetManager.showPairingSuccessHalfSheet(connection.getPublicAddress());
+            pairingProgressHandlerBase.onPairingSuccess(connection.getPublicAddress());
+        } catch (BluetoothException
+                | InterruptedException
+                | ReflectionException
+                | TimeoutException
+                | ExecutionException
+                | PairingException
+                | GeneralSecurityException e) {
+            Log.e(TAG, "Failed to pair.", e);
+
+            // TODO(b/213373051): Merge logic with pairingProgressHandlerBase or delete the
+            // pairingProgressHandlerBase class.
+            fastPairHalfSheetManager.showPairingFailed();
+            pairingProgressHandlerBase.onPairingFailed(e);
+        }
+    }
+
+    private static void cacheFastPairDevice(Context context, String publicAddress, byte[] key,
+            DiscoveryItem item) {
+        try {
+            Locator.get(context, EventLoop.class).postAndWait(
+                    new NamedRunnable("FastPairCacheDevice") {
+                        @Override
+                        public void run() {
+                            Cache.StoredFastPairItem storedFastPairItem =
+                                    Cache.StoredFastPairItem.newBuilder()
+                                            .setMacAddress(publicAddress)
+                                            .setAccountKey(ByteString.copyFrom(key))
+                                            .setModelId(item.getTriggerId())
+                                            .addAllFeatures(item.getFastPairInformation() == null
+                                                    ? ImmutableList.of() :
+                                                    item.getFastPairInformation().getFeaturesList())
+                                            .setDiscoveryItem(item.getCopyOfStoredItem())
+                                            .build();
+                            Locator.get(context, FastPairCacheManager.class)
+                                    .putStoredFastPairItem(storedFastPairItem);
+                        }
+                    }
+            );
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Fail to insert paired device into cache");
+        }
+    }
+
+    /** Checks if the pairing is initial pairing with fast pair 2.0 design. */
+    public static boolean isThroughFastPair2InitialPairing(
+            DiscoveryItem item, @Nullable byte[] accountKey) {
+        return accountKey == null && item.getAuthenticationPublicKeySecp256R1() != null;
+    }
+
+    private static void waitUntilScreenIsUnlocked(Context context)
+            throws InterruptedException, ExecutionException, TimeoutException {
+        KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
+
+        // KeyguardManager's isScreenLocked() counterintuitively returns false when the lock screen
+        // is showing if the user has set "swipe to unlock" (i.e. no required password, PIN, or
+        // pattern) So we use this method instead, which returns true when on the lock screen
+        // regardless.
+        if (keyguardManager.isKeyguardLocked()) {
+            Log.v(TAG, "FastPair: Screen is locked, waiting until unlocked "
+                    + "to show status notifications.");
+            try (SimpleBroadcastReceiver isUnlockedReceiver =
+                         SimpleBroadcastReceiver.oneShotReceiver(
+                                 context, FlagUtils.getPreferencesBuilder().build(),
+                                 Intent.ACTION_USER_PRESENT)) {
+                isUnlockedReceiver.await(WAIT_FOR_UNLOCK_MILLIS, TimeUnit.MILLISECONDS);
+            }
+        }
+    }
+
+    private void registerFastPairScanChangeContentObserver(ContentResolver resolver) {
+        mFastPairScanChangeContentObserver = new ContentObserver(ForegroundThread.getHandler()) {
+            @Override
+            public void onChange(boolean selfChange, Uri uri) {
+                super.onChange(selfChange, uri);
+                setScanEnabled(
+                        NearbyManager.getFastPairScanEnabled(mLocatorContextWrapper.getContext()));
+            }
+        };
+        try {
+            resolver.registerContentObserver(
+                    Settings.Secure.getUriFor(NearbyManager.FAST_PAIR_SCAN_ENABLED),
+                    /* notifyForDescendants= */ false,
+                    mFastPairScanChangeContentObserver);
+        } catch (SecurityException e) {
+            Log.e(TAG, "Failed to register content observer for fast pair scan.", e);
+        }
+    }
+
+    /**
+     * Processed task in a background thread
+     */
+    @Annotations.EventThread
+    public static void processBackgroundTask(Runnable runnable) {
+        getExecutor().execute(runnable);
+    }
+
+    /**
+     * This function should only be called on main thread since there is no lock
+     */
+    private static Executor getExecutor() {
+        if (sFastPairExecutor != null) {
+            return sFastPairExecutor;
+        }
+        sFastPairExecutor = Executors.newSingleThreadExecutor();
+        return sFastPairExecutor;
+    }
+
+    /**
+     * Null when the Nearby Service is not available.
+     */
+    @Nullable
+    private NearbyManager getNearbyManager() {
+        return (NearbyManager) mLocatorContextWrapper
+                .getApplicationContext().getSystemService(Context.NEARBY_SERVICE);
+    }
+    private void setScanEnabled(boolean scanEnabled) {
+        if (mScanEnabled == scanEnabled) {
+            return;
+        }
+        mScanEnabled = scanEnabled;
+        invalidateScan();
+    }
+
+    /**
+     * Starts or stops scanning according to mAllowScan value.
+     */
+    private void invalidateScan() {
+        NearbyManager nearbyManager = getNearbyManager();
+        if (nearbyManager == null) {
+            Log.w(TAG, "invalidateScan: "
+                    + "failed to start or stop scannning because NearbyManager is null.");
+            return;
+        }
+        if (mScanEnabled) {
+            nearbyManager.startScan(new ScanRequest.Builder()
+                            .setScanType(ScanRequest.SCAN_TYPE_FAST_PAIR).build(),
+                    ForegroundThread.getExecutor(),
+                    mScanCallback);
+        } else {
+            nearbyManager.stopScan(mScanCallback);
+        }
+    }
+
+    /**
+     * When certain device is forgotten we need to remove the info from database because the info
+     * is no longer useful.
+     */
+    private void processBluetoothConnectionEvent(Intent intent) {
+        int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+                BluetoothDevice.ERROR);
+        if (bondState == BluetoothDevice.BOND_NONE) {
+            BluetoothDevice device =
+                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+            if (device != null) {
+                Log.d("FastPairService", "Forget device detect");
+                processBackgroundTask(new Runnable() {
+                    @Override
+                    public void run() {
+                        mLocatorContextWrapper.getLocator().get(FastPairCacheManager.class)
+                                .removeStoredFastPairItem(device.getAddress());
+                    }
+                });
+            }
+
+        }
+    }
+
+    /**
+     * Helper function to get bluetooth adapter.
+     */
+    @Nullable
+    public static BluetoothAdapter getBluetoothAdapter(Context context) {
+        BluetoothManager manager = context.getSystemService(BluetoothManager.class);
+        return manager == null ? null : manager.getAdapter();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairModule.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairModule.java
new file mode 100644
index 0000000..d7946d1
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairModule.java
@@ -0,0 +1,83 @@
+/*
+ * 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.server.nearby.fastpair;
+
+import android.content.Context;
+
+import com.android.server.nearby.common.eventloop.EventLoop;
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.Module;
+import com.android.server.nearby.fastpair.cache.FastPairCacheManager;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+
+/**
+ * Module that associates all of the fast pair related singleton class
+ */
+public class FastPairModule extends Module {
+    /**
+     * Initiate the class that needs to be singleton.
+     */
+    @Override
+    public void configure(Context context, Class<?> type, Locator locator) {
+        if (type.equals(FastPairCacheManager.class)) {
+            locator.bind(FastPairCacheManager.class, new FastPairCacheManager(context));
+        } else if (type.equals(FootprintsDeviceManager.class)) {
+            locator.bind(FootprintsDeviceManager.class, new FootprintsDeviceManager());
+        } else if (type.equals(EventLoop.class)) {
+            locator.bind(EventLoop.class, EventLoop.newInstance("NearbyFastPair"));
+        } else if (type.equals(FastPairController.class)) {
+            locator.bind(FastPairController.class, new FastPairController(context));
+        } else if (type.equals(FastPairCacheManager.class)) {
+            locator.bind(FastPairCacheManager.class, new FastPairCacheManager(context));
+        } else if (type.equals(FastPairHalfSheetManager.class)) {
+            locator.bind(FastPairHalfSheetManager.class, new FastPairHalfSheetManager(context));
+        } else if (type.equals(FastPairAdvHandler.class)) {
+            locator.bind(FastPairAdvHandler.class, new FastPairAdvHandler(context));
+        } else if (type.equals(Clock.class)) {
+            locator.bind(Clock.class, new Clock() {
+                @Override
+                public ZoneId getZone() {
+                    return null;
+                }
+
+                @Override
+                public Clock withZone(ZoneId zone) {
+                    return null;
+                }
+
+                @Override
+                public Instant instant() {
+                    return null;
+                }
+            });
+        }
+
+    }
+
+    /**
+     * Clean up the singleton classes.
+     */
+    @Override
+    public void destroy(Context context, Class<?> type, Object instance) {
+        super.destroy(context, type, instance);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FlagUtils.java b/nearby/service/java/com/android/server/nearby/fastpair/FlagUtils.java
new file mode 100644
index 0000000..883a1f8
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FlagUtils.java
@@ -0,0 +1,202 @@
+/*
+ * 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.server.nearby.fastpair;
+
+import android.text.TextUtils;
+
+import com.android.server.nearby.common.bluetooth.fastpair.Preferences;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This is fast pair connection preference
+ */
+public class FlagUtils {
+    private static final int GATT_OPERATION_TIME_OUT_SECOND = 10;
+    private static final int GATT_CONNECTION_TIME_OUT_SECOND = 15;
+    private static final int BLUETOOTH_TOGGLE_TIME_OUT_SECOND = 10;
+    private static final int BLUETOOTH_TOGGLE_SLEEP_TIME_OUT_SECOND = 2;
+    private static final int CLASSIC_DISCOVERY_TIME_OUT_SECOND = 13;
+    private static final int NUM_DISCOVER_ATTEMPTS = 3;
+    private static final int DISCOVERY_RETRY_SLEEP_SECONDS = 1;
+    private static final int SDP_TIME_OUT_SECONDS = 10;
+    private static final int NUM_SDP_ATTEMPTS = 0;
+    private static final int NUM_CREATED_BOND_ATTEMPTS = 3;
+    private static final int NUM_CONNECT_ATTEMPT = 2;
+    private static final int NUM_WRITE_ACCOUNT_KEY_ATTEMPT = 3;
+    private static final boolean TOGGLE_BLUETOOTH_ON_FAILURE = false;
+    private static final boolean BLUETOOTH_STATE_POOLING = true;
+    private static final int BLUETOOTH_STATE_POOLING_MILLIS = 1000;
+    private static final int NUM_ATTEMPTS = 2;
+    private static final short BREDR_HANDOVER_DATA_CHARACTERISTIC_ID = 11265; // 0x2c01
+    private static final short BLUETOOTH_SIG_DATA_CHARACTERISTIC_ID = 11266; // 0x2c02
+    private static final short TRANSPORT_BLOCK_DATA_CHARACTERISTIC_ID = 11267; // 0x2c03
+    private static final boolean WAIT_FOR_UUID_AFTER_BONDING = true;
+    private static final boolean RECEIVE_UUID_AND_BONDED_EVENT_BEFORE_CLOSE = true;
+    private static final int REMOVE_BOND_TIME_OUT_SECONDS = 5;
+    private static final int REMOVE_BOND_SLEEP_MILLIS = 1000;
+    private static final int CREATE_BOND_TIME_OUT_SECONDS = 15;
+    private static final int HIDE_CREATED_BOND_TIME_OUT_SECONDS = 40;
+    private static final int PROXY_TIME_OUT_SECONDS = 2;
+    private static final boolean REJECT_ACCESS = false;
+    private static final boolean ACCEPT_PASSKEY = true;
+    private static final int WRITE_ACCOUNT_KEY_SLEEP_MILLIS = 2000;
+    private static final boolean PROVIDER_INITIATE_BONDING = false;
+    private static final boolean SPECIFY_CREATE_BOND_TRANSPORT_TYPE = false;
+    private static final int CREATE_BOND_TRANSPORT_TYPE = 0;
+    private static final boolean KEEP_SAME_ACCOUNT_KEY_WRITE = true;
+    private static final boolean ENABLE_NAMING_CHARACTERISTIC = true;
+    private static final boolean CHECK_FIRMWARE_VERSION = true;
+    private static final int SDP_ATTEMPTS_AFTER_BONDED = 1;
+    private static final boolean SUPPORT_HID = false;
+    private static final boolean ENABLE_PAIRING_WHILE_DIRECTLY_CONNECTING = true;
+    private static final boolean ACCEPT_CONSENT_FOR_FP_ONE = true;
+    private static final int GATT_CONNECT_RETRY_TIMEOUT_MILLIS = 18000;
+    private static final boolean ENABLE_128BIT_CUSTOM_GATT_CHARACTERISTIC = true;
+    private static final boolean ENABLE_SEND_EXCEPTION_STEP_TO_VALIDATOR = true;
+    private static final boolean ENABLE_ADDITIONAL_DATA_TYPE_WHEN_ACTION_OVER_BLE = true;
+    private static final boolean CHECK_BOND_STATE_WHEN_SKIP_CONNECTING_PROFILE = true;
+    private static final boolean MORE_LOG_FOR_QUALITY = true;
+    private static final boolean RETRY_GATT_CONNECTION_AND_SECRET_HANDSHAKE = true;
+    private static final int GATT_CONNECT_SHORT_TIMEOUT_MS = 7000;
+    private static final int GATT_CONNECTION_LONG_TIME_OUT_MS = 15000;
+    private static final int GATT_CONNECT_SHORT_TIMEOUT_RETRY_MAX_SPENT_TIME_MS = 1000;
+    private static final int ADDRESS_ROTATE_RETRY_MAX_SPENT_TIME_MS = 15000;
+    private static final int PAIRING_RETRY_DELAY_MS = 100;
+    private static final int HANDSHAKE_SHORT_TIMEOUT_MS = 3000;
+    private static final int HANDSHAKE_LONG_TIMEOUT_MS = 1000;
+    private static final int SECRET_HANDSHAKE_SHORT_TIMEOUT_RETRY_MAX_SPENT_TIME_MS = 5000;
+    private static final int SECRET_HANDSHAKE_LONG_TIMEOUT_RETRY_MAX_SPENT_TIME_MS = 7000;
+    private static final int SECRET_HANDSHAKE_RETRY_ATTEMPTS = 3;
+    private static final int SECRET_HANDSHAKE_RETRY_GATT_CONNECTION_MAX_SPENT_TIME_MS = 15000;
+    private static final int SIGNAL_LOST_RETRY_MAX_SPENT_TIME_MS = 15000;
+    private static final boolean RETRY_SECRET_HANDSHAKE_TIMEOUT = false;
+    private static final boolean LOG_USER_MANUAL_RETRY = true;
+    private static final boolean ENABLE_PAIR_FLOW_SHOW_UI_WITHOUT_PROFILE_CONNECTION = false;
+    private static final boolean LOG_USER_MANUAL_CITY = true;
+    private static final boolean LOG_PAIR_WITH_CACHED_MODEL_ID = true;
+    private static final boolean DIRECT_CONNECT_PROFILE_IF_MODEL_ID_IN_CACHE = false;
+
+    public static Preferences.Builder getPreferencesBuilder() {
+        return Preferences.builder()
+                .setGattOperationTimeoutSeconds(GATT_OPERATION_TIME_OUT_SECOND)
+                .setGattConnectionTimeoutSeconds(GATT_CONNECTION_TIME_OUT_SECOND)
+                .setBluetoothToggleTimeoutSeconds(BLUETOOTH_TOGGLE_TIME_OUT_SECOND)
+                .setBluetoothToggleSleepSeconds(BLUETOOTH_TOGGLE_SLEEP_TIME_OUT_SECOND)
+                .setClassicDiscoveryTimeoutSeconds(CLASSIC_DISCOVERY_TIME_OUT_SECOND)
+                .setNumDiscoverAttempts(NUM_DISCOVER_ATTEMPTS)
+                .setDiscoveryRetrySleepSeconds(DISCOVERY_RETRY_SLEEP_SECONDS)
+                .setSdpTimeoutSeconds(SDP_TIME_OUT_SECONDS)
+                .setNumSdpAttempts(NUM_SDP_ATTEMPTS)
+                .setNumCreateBondAttempts(NUM_CREATED_BOND_ATTEMPTS)
+                .setNumConnectAttempts(NUM_CONNECT_ATTEMPT)
+                .setNumWriteAccountKeyAttempts(NUM_WRITE_ACCOUNT_KEY_ATTEMPT)
+                .setToggleBluetoothOnFailure(TOGGLE_BLUETOOTH_ON_FAILURE)
+                .setBluetoothStateUsesPolling(BLUETOOTH_STATE_POOLING)
+                .setBluetoothStatePollingMillis(BLUETOOTH_STATE_POOLING_MILLIS)
+                .setNumAttempts(NUM_ATTEMPTS)
+                .setBrHandoverDataCharacteristicId(BREDR_HANDOVER_DATA_CHARACTERISTIC_ID)
+                .setBluetoothSigDataCharacteristicId(BLUETOOTH_SIG_DATA_CHARACTERISTIC_ID)
+                .setBrTransportBlockDataDescriptorId(TRANSPORT_BLOCK_DATA_CHARACTERISTIC_ID)
+                .setWaitForUuidsAfterBonding(WAIT_FOR_UUID_AFTER_BONDING)
+                .setReceiveUuidsAndBondedEventBeforeClose(
+                        RECEIVE_UUID_AND_BONDED_EVENT_BEFORE_CLOSE)
+                .setRemoveBondTimeoutSeconds(REMOVE_BOND_TIME_OUT_SECONDS)
+                .setRemoveBondSleepMillis(REMOVE_BOND_SLEEP_MILLIS)
+                .setCreateBondTimeoutSeconds(CREATE_BOND_TIME_OUT_SECONDS)
+                .setHidCreateBondTimeoutSeconds(HIDE_CREATED_BOND_TIME_OUT_SECONDS)
+                .setProxyTimeoutSeconds(PROXY_TIME_OUT_SECONDS)
+                .setRejectPhonebookAccess(REJECT_ACCESS)
+                .setRejectMessageAccess(REJECT_ACCESS)
+                .setRejectSimAccess(REJECT_ACCESS)
+                .setAcceptPasskey(ACCEPT_PASSKEY)
+                .setWriteAccountKeySleepMillis(WRITE_ACCOUNT_KEY_SLEEP_MILLIS)
+                .setProviderInitiatesBondingIfSupported(PROVIDER_INITIATE_BONDING)
+                .setAttemptDirectConnectionWhenPreviouslyBonded(true)
+                .setAutomaticallyReconnectGattWhenNeeded(true)
+                .setSkipDisconnectingGattBeforeWritingAccountKey(true)
+                .setIgnoreUuidTimeoutAfterBonded(true)
+                .setSpecifyCreateBondTransportType(SPECIFY_CREATE_BOND_TRANSPORT_TYPE)
+                .setCreateBondTransportType(CREATE_BOND_TRANSPORT_TYPE)
+                .setIncreaseIntentFilterPriority(true)
+                .setEvaluatePerformance(false)
+                .setKeepSameAccountKeyWrite(KEEP_SAME_ACCOUNT_KEY_WRITE)
+                .setEnableNamingCharacteristic(ENABLE_NAMING_CHARACTERISTIC)
+                .setEnableFirmwareVersionCharacteristic(CHECK_FIRMWARE_VERSION)
+                .setNumSdpAttemptsAfterBonded(SDP_ATTEMPTS_AFTER_BONDED)
+                .setSupportHidDevice(SUPPORT_HID)
+                .setEnablePairingWhileDirectlyConnecting(
+                        ENABLE_PAIRING_WHILE_DIRECTLY_CONNECTING)
+                .setAcceptConsentForFastPairOne(ACCEPT_CONSENT_FOR_FP_ONE)
+                .setGattConnectRetryTimeoutMillis(GATT_CONNECT_RETRY_TIMEOUT_MILLIS)
+                .setEnable128BitCustomGattCharacteristicsId(
+                        ENABLE_128BIT_CUSTOM_GATT_CHARACTERISTIC)
+                .setEnableSendExceptionStepToValidator(ENABLE_SEND_EXCEPTION_STEP_TO_VALIDATOR)
+                .setEnableAdditionalDataTypeWhenActionOverBle(
+                        ENABLE_ADDITIONAL_DATA_TYPE_WHEN_ACTION_OVER_BLE)
+                .setCheckBondStateWhenSkipConnectingProfiles(
+                        CHECK_BOND_STATE_WHEN_SKIP_CONNECTING_PROFILE)
+                .setMoreEventLogForQuality(MORE_LOG_FOR_QUALITY)
+                .setRetryGattConnectionAndSecretHandshake(
+                        RETRY_GATT_CONNECTION_AND_SECRET_HANDSHAKE)
+                .setGattConnectShortTimeoutMs(GATT_CONNECT_SHORT_TIMEOUT_MS)
+                .setGattConnectLongTimeoutMs(GATT_CONNECTION_LONG_TIME_OUT_MS)
+                .setGattConnectShortTimeoutRetryMaxSpentTimeMs(
+                        GATT_CONNECT_SHORT_TIMEOUT_RETRY_MAX_SPENT_TIME_MS)
+                .setAddressRotateRetryMaxSpentTimeMs(ADDRESS_ROTATE_RETRY_MAX_SPENT_TIME_MS)
+                .setPairingRetryDelayMs(PAIRING_RETRY_DELAY_MS)
+                .setSecretHandshakeShortTimeoutMs(HANDSHAKE_SHORT_TIMEOUT_MS)
+                .setSecretHandshakeLongTimeoutMs(HANDSHAKE_LONG_TIMEOUT_MS)
+                .setSecretHandshakeShortTimeoutRetryMaxSpentTimeMs(
+                        SECRET_HANDSHAKE_SHORT_TIMEOUT_RETRY_MAX_SPENT_TIME_MS)
+                .setSecretHandshakeLongTimeoutRetryMaxSpentTimeMs(
+                        SECRET_HANDSHAKE_LONG_TIMEOUT_RETRY_MAX_SPENT_TIME_MS)
+                .setSecretHandshakeRetryAttempts(SECRET_HANDSHAKE_RETRY_ATTEMPTS)
+                .setSecretHandshakeRetryGattConnectionMaxSpentTimeMs(
+                        SECRET_HANDSHAKE_RETRY_GATT_CONNECTION_MAX_SPENT_TIME_MS)
+                .setSignalLostRetryMaxSpentTimeMs(SIGNAL_LOST_RETRY_MAX_SPENT_TIME_MS)
+                .setGattConnectionAndSecretHandshakeNoRetryGattError(
+                        getGattConnectionAndSecretHandshakeNoRetryGattError())
+                .setRetrySecretHandshakeTimeout(RETRY_SECRET_HANDSHAKE_TIMEOUT)
+                .setLogUserManualRetry(LOG_USER_MANUAL_RETRY)
+                .setEnablePairFlowShowUiWithoutProfileConnection(
+                        ENABLE_PAIR_FLOW_SHOW_UI_WITHOUT_PROFILE_CONNECTION)
+                .setLogUserManualRetry(LOG_USER_MANUAL_CITY)
+                .setLogPairWithCachedModelId(LOG_PAIR_WITH_CACHED_MODEL_ID)
+                .setDirectConnectProfileIfModelIdInCache(
+                        DIRECT_CONNECT_PROFILE_IF_MODEL_ID_IN_CACHE);
+    }
+
+    private static ImmutableSet<Integer> getGattConnectionAndSecretHandshakeNoRetryGattError() {
+        ImmutableSet.Builder<Integer> noRetryGattErrorsBuilder = ImmutableSet.builder();
+        // When GATT connection fail we will not retry on error code 257
+        for (String errorCode :
+                Splitter.on(",").split("257,")) {
+            if (!TextUtils.isDigitsOnly(errorCode)) {
+                continue;
+            }
+
+            try {
+                noRetryGattErrorsBuilder.add(Integer.parseInt(errorCode));
+            } catch (NumberFormatException e) {
+                // Ignore
+            }
+        }
+        return noRetryGattErrorsBuilder.build();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/UserActionHandler.java b/nearby/service/java/com/android/server/nearby/fastpair/UserActionHandler.java
new file mode 100644
index 0000000..674633d
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/UserActionHandler.java
@@ -0,0 +1,31 @@
+/*
+ * 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.server.nearby.fastpair;
+
+import com.android.server.nearby.common.fastpair.service.UserActionHandlerBase;
+
+/**
+ * User action handler class.
+ */
+public class UserActionHandler extends UserActionHandlerBase {
+
+    public static final String EXTRA_DISCOVERY_ITEM = PREFIX + "EXTRA_DISCOVERY_ITEM";
+    public static final String EXTRA_FAST_PAIR_SECRET = PREFIX + "EXTRA_FAST_PAIR_SECRET";
+    public static final String ACTION_FAST_PAIR = ACTION_PREFIX + "ACTION_FAST_PAIR";
+    public static final String EXTRA_PRIVATE_BLE_ADDRESS =
+            ACTION_PREFIX + "EXTRA_PRIVATE_BLE_ADDRESS";
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItem.java b/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItem.java
new file mode 100644
index 0000000..b8a9796
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItem.java
@@ -0,0 +1,608 @@
+/*
+ * 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.server.nearby.fastpair.cache;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress.maskBluetoothAddress;
+import static com.android.server.nearby.fastpair.UserActionHandler.EXTRA_FAST_PAIR_SECRET;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.server.nearby.common.ble.util.RangingUtils;
+import com.android.server.nearby.common.fastpair.IconUtils;
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.URISyntaxException;
+import java.time.Clock;
+import java.util.Objects;
+
+import service.proto.Cache;
+
+/**
+ * Wrapper class around StoredDiscoveryItem. A centralized place for methods related to
+ * updating/parsing StoredDiscoveryItem.
+ */
+public class DiscoveryItem implements Comparable<DiscoveryItem> {
+
+    private static final String  ACTION_FAST_PAIR =
+            "com.android.server.nearby:ACTION_FAST_PAIR";
+    private static final int BEACON_STALENESS_MILLIS = 120000;
+    private static final int ITEM_EXPIRATION_MILLIS = 20000;
+    private static final int APP_INSTALL_EXPIRATION_MILLIS = 600000;
+    private static final int ITEM_DELETABLE_MILLIS = 15000;
+
+    private final FastPairCacheManager mFastPairCacheManager;
+    private final Clock mClock;
+
+    private Cache.StoredDiscoveryItem mStoredDiscoveryItem;
+
+    /** IntDef for StoredDiscoveryItem.State */
+    @IntDef({
+            Cache.StoredDiscoveryItem.State.STATE_ENABLED_VALUE,
+            Cache.StoredDiscoveryItem.State.STATE_MUTED_VALUE,
+            Cache.StoredDiscoveryItem.State.STATE_DISABLED_BY_SYSTEM_VALUE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ItemState {}
+
+    public DiscoveryItem(LocatorContextWrapper locatorContextWrapper,
+            Cache.StoredDiscoveryItem mStoredDiscoveryItem) {
+        this.mFastPairCacheManager =
+                locatorContextWrapper.getLocator().get(FastPairCacheManager.class);
+        this.mClock =
+            locatorContextWrapper.getLocator().get(Clock.class);
+        this.mStoredDiscoveryItem = mStoredDiscoveryItem;
+    }
+
+    public DiscoveryItem(Context context, Cache.StoredDiscoveryItem mStoredDiscoveryItem) {
+        this.mFastPairCacheManager = Locator.get(context, FastPairCacheManager.class);
+        this.mClock = Locator.get(context, Clock.class);
+        this.mStoredDiscoveryItem = mStoredDiscoveryItem;
+    }
+
+    /** @return A new StoredDiscoveryItem with state fields set to their defaults. */
+    public static Cache.StoredDiscoveryItem newStoredDiscoveryItem() {
+        Cache.StoredDiscoveryItem.Builder storedDiscoveryItem =
+                Cache.StoredDiscoveryItem.newBuilder();
+        storedDiscoveryItem.setState(Cache.StoredDiscoveryItem.State.STATE_ENABLED);
+        return storedDiscoveryItem.build();
+    }
+
+    /** @return True if the item is currently nearby. */
+    public boolean isNearby() {
+        return isNearby(mStoredDiscoveryItem, mClock.millis());
+    }
+
+    /**
+     * Checks if the item is Nearby
+     */
+    static boolean isNearby(Cache.StoredDiscoveryItem item, long currentTimeMillis) {
+        // A notification may disappear early, if we get a lost callback from Messages.
+        // But regardless, if we haven't detected the thing in Xmin, consider it gone.
+        return !isLost(item)
+                && !isExpired(
+                currentTimeMillis,
+                item.getLastObservationTimestampMillis());
+    }
+
+    /**
+     * Checks if store discovery item support fast pair or not.
+     */
+    public boolean isFastPair() {
+        Intent intent = parseIntentScheme(mStoredDiscoveryItem.getActionUrl());
+        if (intent == null) {
+            Log.w("FastPairDiscovery", "FastPair: fail to parse action url"
+                    + mStoredDiscoveryItem.getActionUrl());
+            return false;
+        }
+        return ACTION_FAST_PAIR.equals(intent.getAction());
+    }
+
+    /**
+     * Sets the pairing result to done.
+     */
+    public void setPairingProcessDone(boolean success) {
+        setLastUserExperience(success ? Cache.StoredDiscoveryItem.ExperienceType.EXPERIENCE_GOOD
+                : Cache.StoredDiscoveryItem.ExperienceType.EXPERIENCE_BAD);
+        setLostMillis(mClock.millis());
+        Log.d("FastPairDiscovery",
+                "FastPair: set Lost when pairing process done, " + getId());
+    }
+
+    /**
+     * Sets the store discovery item lost time.
+     */
+    public void setLostMillis(long lostMillis) {
+        mStoredDiscoveryItem = mStoredDiscoveryItem.toBuilder().setLostMillis(lostMillis).build();
+
+        mStoredDiscoveryItem = mStoredDiscoveryItem.toBuilder().clearRssi().build();
+
+        mFastPairCacheManager.saveDiscoveryItem(this);
+    }
+
+    /**
+     * Sets the store discovery item mac address.
+     */
+    public void setMacAddress(String address) {
+        mStoredDiscoveryItem = mStoredDiscoveryItem.toBuilder().setMacAddress(address).build();
+
+        mFastPairCacheManager.saveDiscoveryItem(this);
+    }
+
+    /**
+     * Sets the user experience to be good or bad.
+     */
+    public void setLastUserExperience(Cache.StoredDiscoveryItem.ExperienceType experienceType) {
+        mStoredDiscoveryItem = mStoredDiscoveryItem.toBuilder()
+                .setLastUserExperience(experienceType).build();
+        mFastPairCacheManager.saveDiscoveryItem(this);
+    }
+    /**
+     * Gets the user experience to be good or bad.
+     */
+    public Cache.StoredDiscoveryItem.ExperienceType getLastUserExperience() {
+        return mStoredDiscoveryItem.getLastUserExperience();
+    }
+
+    /**
+     * Checks if the item is lost.
+     */
+    private static boolean isLost(Cache.StoredDiscoveryItem item) {
+        return item.getLastObservationTimestampMillis() <= item.getLostMillis();
+    }
+
+    /**
+     * Checks if the item is expired. Expired items are those over getItemExpirationMillis() eg. 2
+     * minutes
+     */
+    public static boolean isExpired(
+            long currentTimestampMillis, @Nullable Long lastObservationTimestampMillis) {
+        if (lastObservationTimestampMillis == null) {
+            return true;
+        }
+        return (currentTimestampMillis - lastObservationTimestampMillis)
+                >= ITEM_EXPIRATION_MILLIS;
+    }
+
+    /**
+     * Checks if the item is deletable for saving disk space. Deletable items are those over
+     * getItemDeletableMillis eg. over 25 hrs.
+     */
+    public static boolean isDeletable(
+            long currentTimestampMillis, @Nullable Long lastObservationTimestampMillis) {
+        if (lastObservationTimestampMillis == null) {
+            return true;
+        }
+        return currentTimestampMillis - lastObservationTimestampMillis
+                >= ITEM_DELETABLE_MILLIS;
+    }
+
+    /** Checks if the item has a pending app install */
+    public boolean isPendingAppInstallValid() {
+        return isPendingAppInstallValid(mClock.millis());
+    }
+
+    /**
+     * Checks if pending app valid.
+     */
+    public boolean isPendingAppInstallValid(long appInstallMillis) {
+        return isPendingAppInstallValid(appInstallMillis, mStoredDiscoveryItem);
+    }
+
+    /**
+     * Checks if the app install time expired.
+     */
+    public static boolean isPendingAppInstallValid(
+            long currentMillis, Cache.StoredDiscoveryItem storedItem) {
+        return currentMillis - storedItem.getPendingAppInstallTimestampMillis()
+                < APP_INSTALL_EXPIRATION_MILLIS;
+    }
+
+
+    /** Checks if the item has enough data to be shown */
+    public boolean isReadyForDisplay() {
+        if (isOffline()) {
+            return true;
+        }
+        boolean hasUrlOrPopularApp = !mStoredDiscoveryItem.getActionUrl().isEmpty();
+
+        return !TextUtils.isEmpty(mStoredDiscoveryItem.getTitle()) && hasUrlOrPopularApp;
+    }
+
+    /** Checks if the item has server error */
+    public boolean isDisabledByServer() {
+        return mStoredDiscoveryItem.getDebugCategory()
+                == Cache.StoredDiscoveryItem.DebugMessageCategory.STATUS_DISABLED_BY_SERVER;
+    }
+
+    private boolean isOffline() {
+        return isOfflineType(getType());
+    }
+
+    /** Checks if the item can be generated on client side. */
+    private static boolean isOfflineType(Cache.NearbyType type) {
+        return type == Cache.NearbyType.NEARBY_CHROMECAST || type == Cache.NearbyType.NEARBY_WEAR;
+    }
+
+    /** Checks if the action url is app install */
+    public boolean isApp() {
+        return mStoredDiscoveryItem.getActionUrlType() == Cache.ResolvedUrlType.APP;
+    }
+
+    /** Checks if it's device item. e.g. Chromecast / Wear */
+    public boolean isDevice() {
+        return isDeviceType(mStoredDiscoveryItem.getType());
+    }
+
+    /** Returns true if an item is muted, or if state is unavailable. */
+    public boolean isMuted() {
+        return mStoredDiscoveryItem.getState() != Cache.StoredDiscoveryItem.State.STATE_ENABLED;
+    }
+
+    /**
+     * Returns the state of store discovery item.
+     */
+    public Cache.StoredDiscoveryItem.State getState() {
+        return mStoredDiscoveryItem.getState();
+    }
+
+    /** Checks if it's device item. e.g. Chromecast / Wear */
+    public static boolean isDeviceType(Cache.NearbyType type) {
+        return type == Cache.NearbyType.NEARBY_CHROMECAST
+                || type == Cache.NearbyType.NEARBY_WEAR
+                || type == Cache.NearbyType.NEARBY_DEVICE;
+    }
+
+    /**
+     * Check if the type is supported.
+     */
+    public static boolean isTypeEnabled(Cache.NearbyType type) {
+        switch (type) {
+            case NEARBY_WEAR:
+            case NEARBY_CHROMECAST:
+            case NEARBY_DEVICE:
+                return true;
+            default:
+                Log.e("FastPairDiscoveryItem", "Invalid item type " + type.name());
+                return false;
+        }
+    }
+
+    /** Gets hash code of UI related data so we can collapse identical items. */
+    public int getUiHashCode() {
+        switch (mStoredDiscoveryItem.getType()) {
+            case NEARBY_CHROMECAST:
+            case NEARBY_WEAR:
+                // For the special-case device types, show one item per type.
+                return Objects.hashCode(mStoredDiscoveryItem.getType());
+            case NEARBY_DEVICE:
+            case NEARBY_TYPE_UNKNOWN:
+            default:
+                return Objects.hash(
+                        mStoredDiscoveryItem.getType(),
+                        mStoredDiscoveryItem.getTitle(),
+                        mStoredDiscoveryItem.getDescription(),
+                        mStoredDiscoveryItem.getAppName(),
+                        mStoredDiscoveryItem.getDisplayUrl(),
+                        mStoredDiscoveryItem.getMacAddress());
+        }
+    }
+
+    // Getters below
+    /**
+     * Returns the id of store discovery item.
+     */
+    @Nullable
+    public String getId() {
+        return mStoredDiscoveryItem.getId();
+    }
+
+    /**
+     * Returns the type of store discovery item.
+     */
+    @Nullable
+    public Cache.NearbyType getType() {
+        return mStoredDiscoveryItem.getType();
+    }
+
+    /**
+     * Returns the title of discovery item.
+     */
+    @Nullable
+    public String getTitle() {
+        return mStoredDiscoveryItem.getTitle();
+    }
+
+    /**
+     * Returns the description of discovery item.
+     */
+    @Nullable
+    public String getDescription() {
+        return mStoredDiscoveryItem.getDescription();
+    }
+
+    /**
+     * Returns the mac address of discovery item.
+     */
+    @Nullable
+    public String getMacAddress() {
+        return mStoredDiscoveryItem.getMacAddress();
+    }
+
+    /**
+     * Returns the display url of discovery item.
+     */
+    @Nullable
+    public String getDisplayUrl() {
+        return mStoredDiscoveryItem.getDisplayUrl();
+    }
+
+    /**
+     * Returns the public key of discovery item.
+     */
+    @Nullable
+    public byte[] getAuthenticationPublicKeySecp256R1() {
+        return mStoredDiscoveryItem.getAuthenticationPublicKeySecp256R1().toByteArray();
+    }
+
+    /**
+     * Returns the pairing secret.
+     */
+    @Nullable
+    public String getFastPairSecretKey() {
+        Intent intent = parseIntentScheme(mStoredDiscoveryItem.getActionUrl());
+        if (intent == null) {
+            Log.d("FastPairDiscoveryItem", "FastPair: fail to parse action url "
+                            + mStoredDiscoveryItem.getActionUrl());
+            return null;
+        }
+        return intent.getStringExtra(EXTRA_FAST_PAIR_SECRET);
+    }
+
+    /**
+     * Returns the fast pair info of discovery item.
+     */
+    @Nullable
+    public Cache.FastPairInformation getFastPairInformation() {
+        return mStoredDiscoveryItem.hasFastPairInformation()
+                ? mStoredDiscoveryItem.getFastPairInformation() : null;
+    }
+
+    /**
+     * Returns the app name of discovery item.
+     */
+    @Nullable
+    private String getAppName() {
+        return mStoredDiscoveryItem.getAppName();
+    }
+
+    /**
+     * Returns the package name of discovery item.
+     */
+    @Nullable
+    public String getAppPackageName() {
+        return mStoredDiscoveryItem.getPackageName();
+    }
+
+
+    /**
+     * Returns the feature graph url of discovery item.
+     */
+    @Nullable
+    private String getHeroImage() {
+        return mStoredDiscoveryItem.getFeatureGraphicUrl();
+    }
+
+    /**
+     * Returns the action url of discovery item.
+     */
+    @Nullable
+    public String getActionUrl() {
+        return mStoredDiscoveryItem.getActionUrl();
+    }
+
+    /**
+     * Returns the rssi value of discovery item.
+     */
+    @Nullable
+    public Integer getRssi() {
+        return mStoredDiscoveryItem.getRssi();
+    }
+
+    /**
+     * Returns the ble record of discovery item.
+     */
+    @Nullable
+    public byte[] getBleRecordBytes() {
+        return mStoredDiscoveryItem.getBleRecordBytes().toByteArray();
+    }
+
+    /**
+     * Returns the TX power of discovery item.
+     */
+    @Nullable
+    public Integer getTxPower() {
+        return mStoredDiscoveryItem.getTxPower();
+    }
+
+    /**
+     * Returns the first observed time stamp of discovery item.
+     */
+    @Nullable
+    public Long getFirstObservationTimestampMillis() {
+        return mStoredDiscoveryItem.getFirstObservationTimestampMillis();
+    }
+
+    /**
+     * Returns the last observed time stamp of discovery item.
+     */
+    @Nullable
+    public Long getLastObservationTimestampMillis() {
+        return mStoredDiscoveryItem.getLastObservationTimestampMillis();
+    }
+
+    /**
+     * Calculates an estimated distance for the item, computed from the TX power (at 1m) and RSSI.
+     *
+     * @return estimated distance, or null if there is no RSSI or no TX power.
+     */
+    @Nullable
+    public Double getEstimatedDistance() {
+        // In the future, we may want to do a foreground subscription to leverage onDistanceChanged.
+        return RangingUtils.distanceFromRssi(mStoredDiscoveryItem.getRssi(),
+                mStoredDiscoveryItem.getTxPower());
+    }
+
+    /**
+     * Gets icon Bitmap from icon store.
+     *
+     * @return null if no icon or icon size is incorrect.
+     */
+    @Nullable
+    public Bitmap getIcon() {
+        Bitmap icon =
+                BitmapFactory.decodeByteArray(
+                        mStoredDiscoveryItem.getIconPng().toByteArray(),
+                        0 /* offset */, mStoredDiscoveryItem.getIconPng().size());
+        if (IconUtils.isIconSizeCorrect(icon)) {
+            return icon;
+        } else {
+            return null;
+        }
+    }
+
+    /** Gets a FIFE URL of the icon. */
+    @Nullable
+    public String getIconFifeUrl() {
+        return mStoredDiscoveryItem.getIconFifeUrl();
+    }
+
+    /**
+     * Gets group id of storedDiscoveryItem.
+     */
+    @Nullable
+    public String getGroupId() {
+        return mStoredDiscoveryItem.getGroupId();
+    }
+
+
+    /**
+     * Compares this object to the specified object: 1. By device type. Device setups are 'greater
+     * than' beacons. 2. By relevance. More relevant items are 'greater than' less relevant items.
+     * 3.By distance. Nearer items are 'greater than' further items.
+     *
+     * <p>In the list view, we sort in descending order, i.e. we put the most relevant items first.
+     */
+    @Override
+    public int compareTo(DiscoveryItem another) {
+        if (getType() != another.getType()) {
+            // For device type v.s. beacon type, rank device item higher.
+            return isDevice() ? 1 : -1;
+        }
+        // For items of the same relevance, compare distance.
+        Double distance1 = getEstimatedDistance();
+        Double distance2 = another.getEstimatedDistance();
+        distance1 = distance1 != null ? distance1 : Double.MAX_VALUE;
+        distance2 = distance2 != null ? distance2 : Double.MAX_VALUE;
+        // Negate because closer items are better ("greater than") further items.
+        return -distance1.compareTo(distance2);
+    }
+
+
+    public Integer getTriggerIdAttachmentTypeHash() {
+        return Objects.hash(mStoredDiscoveryItem.getTriggerId(),
+                mStoredDiscoveryItem.getAttachmentType());
+    }
+
+    @Nullable
+    public String getTriggerId() {
+        return mStoredDiscoveryItem.getTriggerId();
+    }
+
+    @Override
+    public boolean equals(Object another) {
+        if (another instanceof DiscoveryItem) {
+            return ((DiscoveryItem) another).mStoredDiscoveryItem.equals(mStoredDiscoveryItem);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return mStoredDiscoveryItem.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "[type=%s], [triggerId=%s], [id=%s], [title=%s], [url=%s], "
+                        + "[ready=%s], [macAddress=%s]",
+                getType().name(),
+                getTriggerId(),
+                getId(),
+                getTitle(),
+                getActionUrl(),
+                isReadyForDisplay(),
+                maskBluetoothAddress(getMacAddress()));
+    }
+
+    /**
+     * Gets a copy of the StoredDiscoveryItem proto backing this DiscoveryItem. Currently needed for
+     * Fast Pair 2.0: We store the item in the cloud associated with a user's account, to enable
+     * pairing with other devices owned by the user.
+     */
+    public Cache.StoredDiscoveryItem getCopyOfStoredItem() {
+        return mStoredDiscoveryItem;
+    }
+
+    /**
+     * Gets the StoredDiscoveryItem represented by this DiscoveryItem. This lets tests manipulate
+     * values that production code should not manipulate.
+     */
+
+    public Cache.StoredDiscoveryItem getStoredItemForTest() {
+        return mStoredDiscoveryItem;
+    }
+
+    /**
+     * Sets the StoredDiscoveryItem represented by this DiscoveryItem. This lets tests manipulate
+     * values that production code should not manipulate.
+     */
+    public void setStoredItemForTest(Cache.StoredDiscoveryItem s) {
+        mStoredDiscoveryItem = s;
+    }
+
+    /**
+     * Parse the intent from item url.
+     */
+    public static Intent parseIntentScheme(String uri) {
+        try {
+            return Intent.parseUri(uri, Intent.URI_INTENT_SCHEME);
+        } catch (URISyntaxException e) {
+            return null;
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItemContract.java b/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItemContract.java
new file mode 100644
index 0000000..61ca3fd
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItemContract.java
@@ -0,0 +1,35 @@
+/*
+ * 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.server.nearby.fastpair.cache;
+
+import android.provider.BaseColumns;
+
+/**
+ * Defines DiscoveryItem database schema.
+ */
+public class DiscoveryItemContract {
+    private DiscoveryItemContract() {}
+
+    /**
+     * Discovery item entry related info.
+     */
+    public static class DiscoveryItemEntry implements BaseColumns {
+        public static final String TABLE_NAME = "SCAN_RESULT";
+        public static final String COLUMN_MODEL_ID = "MODEL_ID";
+        public static final String COLUMN_SCAN_BYTE = "SCAN_RESULT_BYTE";
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/cache/FastPairCacheManager.java b/nearby/service/java/com/android/server/nearby/fastpair/cache/FastPairCacheManager.java
new file mode 100644
index 0000000..b840091
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/cache/FastPairCacheManager.java
@@ -0,0 +1,282 @@
+/*
+ * 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.server.nearby.fastpair.cache;
+
+import android.bluetooth.le.ScanResult;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.Log;
+
+import com.android.server.nearby.common.eventloop.Annotations;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import service.proto.Cache;
+import service.proto.Rpcs;
+
+
+/**
+ * Save FastPair device info to database to avoid multiple requesting.
+ */
+public class FastPairCacheManager {
+    private final Context mContext;
+    private final FastPairDbHelper mFastPairDbHelper;
+
+    public FastPairCacheManager(Context context) {
+        mContext = context;
+        mFastPairDbHelper = new FastPairDbHelper(context);
+    }
+
+    /**
+     * Clean up function to release db
+     */
+    public void cleanUp() {
+        mFastPairDbHelper.close();
+    }
+
+    /**
+     * Saves the response to the db
+     */
+    private void saveDevice() {
+    }
+
+    Cache.ServerResponseDbItem getDeviceFromScanResult(ScanResult scanResult) {
+        return Cache.ServerResponseDbItem.newBuilder().build();
+    }
+
+    /**
+     * Checks if the entry can be auto deleted from the cache
+     */
+    public boolean isDeletable(Cache.ServerResponseDbItem entry) {
+        if (!entry.getExpirable()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Save discovery item into database. Discovery item is item that discovered through Ble before
+     * pairing success.
+     */
+    public boolean saveDiscoveryItem(DiscoveryItem item) {
+
+        SQLiteDatabase db = mFastPairDbHelper.getWritableDatabase();
+        ContentValues values = new ContentValues();
+        values.put(DiscoveryItemContract.DiscoveryItemEntry.COLUMN_MODEL_ID, item.getTriggerId());
+        values.put(DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE,
+                item.getCopyOfStoredItem().toByteArray());
+        db.insert(DiscoveryItemContract.DiscoveryItemEntry.TABLE_NAME, null, values);
+        return true;
+    }
+
+
+    @Annotations.EventThread
+    private Rpcs.GetObservedDeviceResponse getObservedDeviceInfo(ScanResult scanResult) {
+        return Rpcs.GetObservedDeviceResponse.getDefaultInstance();
+    }
+
+    /**
+     * Get discovery item from item id.
+     */
+    public DiscoveryItem getDiscoveryItem(String itemId) {
+        return new DiscoveryItem(mContext, getStoredDiscoveryItem(itemId));
+    }
+
+    /**
+     * Get discovery item from item id.
+     */
+    public Cache.StoredDiscoveryItem getStoredDiscoveryItem(String itemId) {
+        SQLiteDatabase db = mFastPairDbHelper.getReadableDatabase();
+        String[] projection = {
+                DiscoveryItemContract.DiscoveryItemEntry.COLUMN_MODEL_ID,
+                DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE
+        };
+        String selection = DiscoveryItemContract.DiscoveryItemEntry.COLUMN_MODEL_ID + " =? ";
+        String[] selectionArgs = {itemId};
+        Cursor cursor = db.query(
+                DiscoveryItemContract.DiscoveryItemEntry.TABLE_NAME,
+                projection,
+                selection,
+                selectionArgs,
+                null,
+                null,
+                null
+        );
+
+        if (cursor.moveToNext()) {
+            byte[] res = cursor.getBlob(cursor.getColumnIndexOrThrow(
+                    DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE));
+            try {
+                Cache.StoredDiscoveryItem item = Cache.StoredDiscoveryItem.parseFrom(res);
+                return item;
+            } catch (InvalidProtocolBufferException e) {
+                Log.e("FastPairCacheManager", "storediscovery has error");
+            }
+        }
+        cursor.close();
+        return Cache.StoredDiscoveryItem.getDefaultInstance();
+    }
+
+    /**
+     * Get all of the discovery item related info in the cache.
+     */
+    public List<Cache.StoredDiscoveryItem> getAllSavedStoreDiscoveryItem() {
+        List<Cache.StoredDiscoveryItem> storedDiscoveryItemList = new ArrayList<>();
+        SQLiteDatabase db = mFastPairDbHelper.getReadableDatabase();
+        String[] projection = {
+                DiscoveryItemContract.DiscoveryItemEntry.COLUMN_MODEL_ID,
+                DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE
+        };
+        Cursor cursor = db.query(
+                DiscoveryItemContract.DiscoveryItemEntry.TABLE_NAME,
+                projection,
+                null,
+                null,
+                null,
+                null,
+                null
+        );
+
+        while (cursor.moveToNext()) {
+            byte[] res = cursor.getBlob(cursor.getColumnIndexOrThrow(
+                    DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE));
+            try {
+                Cache.StoredDiscoveryItem item = Cache.StoredDiscoveryItem.parseFrom(res);
+                storedDiscoveryItemList.add(item);
+            } catch (InvalidProtocolBufferException e) {
+                Log.e("FastPairCacheManager", "storediscovery has error");
+            }
+
+        }
+        cursor.close();
+        return storedDiscoveryItemList;
+    }
+
+    /**
+     * Get scan result from local database use model id
+     */
+    public Cache.StoredScanResult getStoredScanResult(String modelId) {
+        return Cache.StoredScanResult.getDefaultInstance();
+    }
+
+    /**
+     * Gets the paired Fast Pair item that paired to the phone through mac address.
+     */
+    public Cache.StoredFastPairItem getStoredFastPairItemFromMacAddress(String macAddress) {
+        SQLiteDatabase db = mFastPairDbHelper.getReadableDatabase();
+        String[] projection = {
+                StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_ACCOUNT_KEY,
+                StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS,
+                StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_STORED_FAST_PAIR_BYTE
+        };
+        String selection =
+                StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS + " =? ";
+        String[] selectionArgs = {macAddress};
+        Cursor cursor = db.query(
+                StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME,
+                projection,
+                selection,
+                selectionArgs,
+                null,
+                null,
+                null
+        );
+
+        if (cursor.moveToNext()) {
+            byte[] res = cursor.getBlob(cursor.getColumnIndexOrThrow(
+                    StoredFastPairItemContract.StoredFastPairItemEntry
+                            .COLUMN_STORED_FAST_PAIR_BYTE));
+            try {
+                Cache.StoredFastPairItem item = Cache.StoredFastPairItem.parseFrom(res);
+                return item;
+            } catch (InvalidProtocolBufferException e) {
+                Log.e("FastPairCacheManager", "storediscovery has error");
+            }
+        }
+        cursor.close();
+        return Cache.StoredFastPairItem.getDefaultInstance();
+    }
+
+    /**
+     * Save paired fast pair item into the database.
+     */
+    public boolean putStoredFastPairItem(Cache.StoredFastPairItem storedFastPairItem) {
+        SQLiteDatabase db = mFastPairDbHelper.getWritableDatabase();
+        ContentValues values = new ContentValues();
+        values.put(StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS,
+                storedFastPairItem.getMacAddress());
+        values.put(StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_ACCOUNT_KEY,
+                storedFastPairItem.getAccountKey().toString());
+        values.put(StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_STORED_FAST_PAIR_BYTE,
+                storedFastPairItem.toByteArray());
+        db.insert(StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME, null, values);
+        return true;
+
+    }
+
+    /**
+     * Removes certain storedFastPairItem so that it can update timely.
+     */
+    public void removeStoredFastPairItem(String macAddress) {
+        SQLiteDatabase db = mFastPairDbHelper.getWritableDatabase();
+        int res = db.delete(StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME,
+                StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS + "=?",
+                new String[]{macAddress});
+
+    }
+
+    /**
+     * Get all of the store fast pair item related info in the cache.
+     */
+    public List<Cache.StoredFastPairItem> getAllSavedStoredFastPairItem() {
+        List<Cache.StoredFastPairItem> storedFastPairItemList = new ArrayList<>();
+        SQLiteDatabase db = mFastPairDbHelper.getReadableDatabase();
+        String[] projection = {
+                StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS,
+                StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_ACCOUNT_KEY,
+                StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_STORED_FAST_PAIR_BYTE
+        };
+        Cursor cursor = db.query(
+                StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME,
+                projection,
+                null,
+                null,
+                null,
+                null,
+                null
+        );
+
+        while (cursor.moveToNext()) {
+            byte[] res = cursor.getBlob(cursor.getColumnIndexOrThrow(StoredFastPairItemContract
+                    .StoredFastPairItemEntry.COLUMN_STORED_FAST_PAIR_BYTE));
+            try {
+                Cache.StoredFastPairItem item = Cache.StoredFastPairItem.parseFrom(res);
+                storedFastPairItemList.add(item);
+            } catch (InvalidProtocolBufferException e) {
+                Log.e("FastPairCacheManager", "storediscovery has error");
+            }
+
+        }
+        cursor.close();
+        return storedFastPairItemList;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/cache/FastPairDbHelper.java b/nearby/service/java/com/android/server/nearby/fastpair/cache/FastPairDbHelper.java
new file mode 100644
index 0000000..d950d8d
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/cache/FastPairDbHelper.java
@@ -0,0 +1,76 @@
+/*
+ * 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.server.nearby.fastpair.cache;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+/**
+ * Fast Pair db helper handle all of the db actions related Fast Pair.
+ */
+public class FastPairDbHelper extends SQLiteOpenHelper {
+
+    public static final int DATABASE_VERSION = 1;
+    public static final String DATABASE_NAME = "FastPair.db";
+    private static final String SQL_CREATE_DISCOVERY_ITEM_DB =
+            "CREATE TABLE IF NOT EXISTS " + DiscoveryItemContract.DiscoveryItemEntry.TABLE_NAME
+                    + " (" + DiscoveryItemContract.DiscoveryItemEntry._ID
+                    + "INTEGER PRIMARY KEY,"
+                    + DiscoveryItemContract.DiscoveryItemEntry.COLUMN_MODEL_ID
+                    + " TEXT," + DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE
+                    + " BLOB)";
+    private static final String SQL_DELETE_DISCOVERY_ITEM_DB =
+            "DROP TABLE IF EXISTS " + DiscoveryItemContract.DiscoveryItemEntry.TABLE_NAME;
+    private static final String SQL_CREATE_FAST_PAIR_ITEM_DB =
+            "CREATE TABLE IF NOT EXISTS "
+                    + StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME
+                    + " (" + StoredFastPairItemContract.StoredFastPairItemEntry._ID
+                    + "INTEGER PRIMARY KEY,"
+                    + StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS
+                    + " TEXT,"
+                    + StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_ACCOUNT_KEY
+                    + " TEXT,"
+                    + StoredFastPairItemContract
+                    .StoredFastPairItemEntry.COLUMN_STORED_FAST_PAIR_BYTE
+                    + " BLOB)";
+    private static final String SQL_DELETE_FAST_PAIR_ITEM_DB =
+            "DROP TABLE IF EXISTS " + StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME;
+
+    public FastPairDbHelper(Context context) {
+        super(context, DATABASE_NAME, null, DATABASE_VERSION);
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        db.execSQL(SQL_CREATE_DISCOVERY_ITEM_DB);
+        db.execSQL(SQL_CREATE_FAST_PAIR_ITEM_DB);
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        // Since the outdated data has no value so just remove the data.
+        db.execSQL(SQL_DELETE_DISCOVERY_ITEM_DB);
+        db.execSQL(SQL_DELETE_FAST_PAIR_ITEM_DB);
+        onCreate(db);
+    }
+
+    @Override
+    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        super.onDowngrade(db, oldVersion, newVersion);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/cache/StoredFastPairItemContract.java b/nearby/service/java/com/android/server/nearby/fastpair/cache/StoredFastPairItemContract.java
new file mode 100644
index 0000000..9980565
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/cache/StoredFastPairItemContract.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.fastpair.cache;
+
+import android.provider.BaseColumns;
+
+/**
+ * Defines fast pair item database schema.
+ */
+public class StoredFastPairItemContract {
+    private StoredFastPairItemContract() {}
+
+    /**
+     * StoredFastPairItem entry related info.
+     */
+    public static class StoredFastPairItemEntry implements BaseColumns {
+        public static final String TABLE_NAME = "STORED_FAST_PAIR_ITEM";
+        public static final String COLUMN_MAC_ADDRESS = "MAC_ADDRESS";
+        public static final String COLUMN_ACCOUNT_KEY = "ACCOUNT_KEY";
+
+        public static final String COLUMN_STORED_FAST_PAIR_BYTE = "STORED_FAST_PAIR_BYTE";
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/footprint/FastPairUploadInfo.java b/nearby/service/java/com/android/server/nearby/fastpair/footprint/FastPairUploadInfo.java
new file mode 100644
index 0000000..6c9aff0
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/footprint/FastPairUploadInfo.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.fastpair.footprint;
+
+
+import com.google.protobuf.ByteString;
+
+import service.proto.Cache;
+
+/**
+ * Wrapper class that upload the pair info to the footprint.
+ */
+public class FastPairUploadInfo {
+
+    private Cache.StoredDiscoveryItem mStoredDiscoveryItem;
+
+    private ByteString mAccountKey;
+
+    private  ByteString mSha256AccountKeyPublicAddress;
+
+
+    public FastPairUploadInfo(Cache.StoredDiscoveryItem storedDiscoveryItem, ByteString accountKey,
+            ByteString sha256AccountKeyPublicAddress) {
+        mStoredDiscoveryItem = storedDiscoveryItem;
+        mAccountKey = accountKey;
+        mSha256AccountKeyPublicAddress = sha256AccountKeyPublicAddress;
+    }
+
+    public Cache.StoredDiscoveryItem getStoredDiscoveryItem() {
+        return mStoredDiscoveryItem;
+    }
+
+    public ByteString getAccountKey() {
+        return mAccountKey;
+    }
+
+
+    public ByteString getSha256AccountKeyPublicAddress() {
+        return mSha256AccountKeyPublicAddress;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/footprint/FootprintsDeviceManager.java b/nearby/service/java/com/android/server/nearby/fastpair/footprint/FootprintsDeviceManager.java
new file mode 100644
index 0000000..68217c1
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/footprint/FootprintsDeviceManager.java
@@ -0,0 +1,25 @@
+/*
+ * 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.server.nearby.fastpair.footprint;
+
+/**
+ * FootprintDeviceManager is responsible for all of the foot print operation. Footprint will
+ * store all of device info that already paired with certain account. This class will call AOSP
+ * api to let OEM save certain device.
+ */
+public class FootprintsDeviceManager {
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
new file mode 100644
index 0000000..553d5ce
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
@@ -0,0 +1,214 @@
+/*
+ * 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.server.nearby.fastpair.halfsheet;
+
+import static com.android.server.nearby.fastpair.Constant.DEVICE_PAIRING_FRAGMENT_TYPE;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_BINDER;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_BUNDLE;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_INFO;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_TYPE;
+import static com.android.server.nearby.fastpair.FastPairManager.ACTION_RESOURCES_APK;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.nearby.FastPairDevice;
+import android.nearby.FastPairStatusCallback;
+import android.nearby.PairStatusMetadata;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+import com.android.server.nearby.fastpair.FastPairController;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+import com.android.server.nearby.util.Environment;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import service.proto.Cache;
+
+/**
+ * Fast Pair ux manager for half sheet.
+ */
+public class FastPairHalfSheetManager {
+    private static final String ACTIVITY_INTENT_ACTION = "android.nearby.SHOW_HALFSHEET";
+    private static final String HALF_SHEET_CLASS_NAME =
+            "com.android.nearby.halfsheet.HalfSheetActivity";
+    private static final String TAG = "FPHalfSheetManager";
+
+    private String mHalfSheetApkPkgName;
+    private final LocatorContextWrapper mLocatorContextWrapper;
+
+    FastPairUiServiceImpl mFastPairUiService;
+
+    public FastPairHalfSheetManager(Context context) {
+        this(new LocatorContextWrapper(context));
+    }
+
+    @VisibleForTesting
+    FastPairHalfSheetManager(LocatorContextWrapper locatorContextWrapper) {
+        mLocatorContextWrapper = locatorContextWrapper;
+        mFastPairUiService = new FastPairUiServiceImpl();
+    }
+
+    /**
+     * Invokes half sheet in the other apk. This function can only be called in Nearby because other
+     * app can't get the correct component name.
+     */
+    public void showHalfSheet(Cache.ScanFastPairStoreItem scanFastPairStoreItem) {
+        try {
+            if (mLocatorContextWrapper != null) {
+                String packageName = getHalfSheetApkPkgName();
+                if (packageName == null) {
+                    Log.e(TAG, "package name is null");
+                    return;
+                }
+                mFastPairUiService.setFastPairController(
+                        mLocatorContextWrapper.getLocator().get(FastPairController.class));
+                Bundle bundle = new Bundle();
+                bundle.putBinder(EXTRA_BINDER, mFastPairUiService);
+                mLocatorContextWrapper
+                        .startActivityAsUser(new Intent(ACTIVITY_INTENT_ACTION)
+                                        .putExtra(EXTRA_HALF_SHEET_INFO,
+                                                scanFastPairStoreItem.toByteArray())
+                                        .putExtra(EXTRA_HALF_SHEET_TYPE,
+                                                DEVICE_PAIRING_FRAGMENT_TYPE)
+                                        .putExtra(EXTRA_BUNDLE, bundle)
+                                        .setComponent(new ComponentName(packageName,
+                                                HALF_SHEET_CLASS_NAME)),
+                                UserHandle.CURRENT);
+            }
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't resolve package that contains half sheet");
+        }
+    }
+
+    /**
+     * Shows pairing fail half sheet.
+     */
+    public void showPairingFailed() {
+        FastPairStatusCallback pairStatusCallback = mFastPairUiService.getPairStatusCallback();
+        if (pairStatusCallback != null) {
+            Log.v(TAG, "showPairingFailed: pairStatusCallback not NULL");
+            pairStatusCallback.onPairUpdate(new FastPairDevice.Builder().build(),
+                    new PairStatusMetadata(PairStatusMetadata.Status.FAIL));
+        } else {
+            Log.w(TAG, "FastPairHalfSheetManager failed to show success half sheet because "
+                    + "the pairStatusCallback is null");
+        }
+    }
+
+    /**
+     * Get the half sheet status whether it is foreground or dismissed
+     */
+    public boolean getHalfSheetForegroundState() {
+        return true;
+    }
+
+    /**
+     * Show passkey confirmation info on half sheet
+     */
+    public void showPasskeyConfirmation(BluetoothDevice device, int passkey) {
+    }
+
+    /**
+     * This function will handle pairing steps for half sheet.
+     */
+    public void showPairingHalfSheet(DiscoveryItem item) {
+        Log.d(TAG, "show pairing half sheet");
+    }
+
+    /**
+     * Shows pairing success info.
+     */
+    public void showPairingSuccessHalfSheet(String address) {
+        FastPairStatusCallback pairStatusCallback = mFastPairUiService.getPairStatusCallback();
+        if (pairStatusCallback != null) {
+            pairStatusCallback.onPairUpdate(
+                    new FastPairDevice.Builder().setBluetoothAddress(address).build(),
+                    new PairStatusMetadata(PairStatusMetadata.Status.SUCCESS));
+        } else {
+            Log.w(TAG, "FastPairHalfSheetManager failed to show success half sheet because "
+                    + "the pairStatusCallback is null");
+        }
+    }
+
+    /**
+     * Removes dismiss runnable.
+     */
+    public void disableDismissRunnable() {
+    }
+
+    /**
+     * Destroys the bluetooth pairing controller.
+     */
+    public void destroyBluetoothPairController() {
+    }
+
+    /**
+     * Notify manager the pairing has finished.
+     */
+    public void notifyPairingProcessDone(boolean success, String address, DiscoveryItem item) {
+    }
+
+    /**
+     * Gets the package name of HalfSheet.apk
+     * getHalfSheetApkPkgName may invoke PackageManager multiple times and it does not have
+     * race condition check. Since there is no lock for mHalfSheetApkPkgName.
+     */
+    String getHalfSheetApkPkgName() {
+        if (mHalfSheetApkPkgName != null) {
+            return mHalfSheetApkPkgName;
+        }
+        List<ResolveInfo> resolveInfos = mLocatorContextWrapper
+                .getPackageManager().queryIntentActivities(
+                        new Intent(ACTION_RESOURCES_APK),
+                        PackageManager.MATCH_SYSTEM_ONLY);
+
+        // remove apps that don't live in the nearby apex
+        resolveInfos.removeIf(info ->
+                !Environment.isAppInNearbyApex(info.activityInfo.applicationInfo));
+
+        if (resolveInfos.isEmpty()) {
+            // Resource APK not loaded yet, print a stack trace to see where this is called from
+            Log.e("FastPairManager", "Attempted to fetch resources before halfsheet "
+                            + " APK is installed or package manager can't resolve correctly!",
+                    new IllegalStateException());
+            return null;
+        }
+
+        if (resolveInfos.size() > 1) {
+            // multiple apps found, log a warning, but continue
+            Log.w("FastPairManager", "Found > 1 APK that can resolve halfsheet APK intent: "
+                    + resolveInfos.stream()
+                    .map(info -> info.activityInfo.applicationInfo.packageName)
+                    .collect(Collectors.joining(", ")));
+        }
+
+        // Assume the first ResolveInfo is the one we're looking for
+        ResolveInfo info = resolveInfos.get(0);
+        mHalfSheetApkPkgName = info.activityInfo.applicationInfo.packageName;
+        Log.i("FastPairManager", "Found halfsheet APK at: " + mHalfSheetApkPkgName);
+        return mHalfSheetApkPkgName;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairUiServiceImpl.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairUiServiceImpl.java
new file mode 100644
index 0000000..3bd273e
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairUiServiceImpl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.fastpair.halfsheet;
+
+import static com.android.server.nearby.fastpair.Constant.TAG;
+
+import android.nearby.FastPairDevice;
+import android.nearby.FastPairStatusCallback;
+import android.nearby.PairStatusMetadata;
+import android.nearby.aidl.IFastPairStatusCallback;
+import android.nearby.aidl.IFastPairUiService;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.server.nearby.fastpair.FastPairController;
+
+/**
+ * Service implementing Fast Pair functionality.
+ *
+ * @hide
+ */
+public class FastPairUiServiceImpl extends IFastPairUiService.Stub {
+
+    private IBinder mStatusCallbackProxy;
+    private FastPairController mFastPairController;
+    private FastPairStatusCallback mFastPairStatusCallback;
+
+    /**
+     * Registers the Binder call back in the server notifies the proxy when there is an update
+     * in the server.
+     */
+    @Override
+    public void registerCallback(IFastPairStatusCallback iFastPairStatusCallback) {
+        mStatusCallbackProxy = iFastPairStatusCallback.asBinder();
+        mFastPairStatusCallback = new FastPairStatusCallback() {
+            @Override
+            public void onPairUpdate(FastPairDevice fastPairDevice,
+                    PairStatusMetadata pairStatusMetadata) {
+                try {
+                    iFastPairStatusCallback.onPairUpdate(fastPairDevice, pairStatusMetadata);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Failed to update pair status.", e);
+                }
+            }
+        };
+    }
+
+    /**
+     * Unregisters the Binder call back in the server.
+     */
+    @Override
+    public void unregisterCallback(IFastPairStatusCallback iFastPairStatusCallback) {
+        mStatusCallbackProxy = null;
+        mFastPairStatusCallback = null;
+    }
+
+    /**
+     * Asks the Fast Pair service to pair the device. initial pairing.
+     */
+    @Override
+    public void connect(FastPairDevice fastPairDevice) {
+        if (mFastPairController != null) {
+            mFastPairController.pair(fastPairDevice);
+        } else {
+            Log.w(TAG, "Failed to connect because there is no FastPairController.");
+        }
+    }
+
+    /**
+     * Cancels Fast Pair connection and dismisses half sheet.
+     */
+    @Override
+    public void cancel(FastPairDevice fastPairDevice) {
+    }
+
+    public FastPairStatusCallback getPairStatusCallback() {
+        return mFastPairStatusCallback;
+    }
+
+    /**
+     * Sets function for Fast Pair controller.
+     */
+    public void setFastPairController(FastPairController fastPairController) {
+        mFastPairController = fastPairController;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/notification/FastPairNotificationManager.java b/nearby/service/java/com/android/server/nearby/fastpair/notification/FastPairNotificationManager.java
new file mode 100644
index 0000000..b1ae573
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/notification/FastPairNotificationManager.java
@@ -0,0 +1,71 @@
+/*
+ * 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.server.nearby.fastpair.notification;
+
+
+import android.annotation.Nullable;
+import android.content.Context;
+
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+
+/**
+ * Responsible for show notification logic.
+ */
+public class FastPairNotificationManager {
+
+    /**
+     * FastPair notification manager that handle notification ui for fast pair.
+     */
+    public FastPairNotificationManager(Context context, DiscoveryItem item, boolean useLargeIcon,
+            int notificationId) {
+    }
+    /**
+     * FastPair notification manager that handle notification ui for fast pair.
+     */
+    public FastPairNotificationManager(Context context, DiscoveryItem item, boolean useLargeIcon) {
+
+    }
+
+    /**
+     * Shows pairing in progress notification.
+     */
+    public void showConnectingNotification() {}
+
+    /**
+     * Shows success notification
+     */
+    public void showPairingSucceededNotification(
+            @Nullable String companionApp,
+            int batteryLevel,
+            @Nullable String deviceName,
+            String address) {
+
+    }
+
+    /**
+     * Shows failed notification.
+     */
+    public void showPairingFailedNotification(byte[] accountKey) {
+
+    }
+
+    /**
+     * Notify the pairing process is done.
+     */
+    public void notifyPairingProcessDone(boolean success, boolean forceNotify,
+            String privateAddress, String publicAddress) {}
+}
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/HalfSheetPairingProgressHandler.java b/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/HalfSheetPairingProgressHandler.java
new file mode 100644
index 0000000..c95f74f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/HalfSheetPairingProgressHandler.java
@@ -0,0 +1,112 @@
+/*
+ * 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.server.nearby.fastpair.pairinghandler;
+
+
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+
+import com.android.server.nearby.common.bluetooth.fastpair.FastPairConnection;
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+import com.android.server.nearby.intdefs.NearbyEventIntDefs;
+
+/** Pairing progress handler that handle pairing come from half sheet. */
+public final class HalfSheetPairingProgressHandler extends PairingProgressHandlerBase {
+
+    private final FastPairHalfSheetManager mFastPairHalfSheetManager;
+    private final boolean mIsSubsequentPair;
+    private final DiscoveryItem mItemResurface;
+
+    HalfSheetPairingProgressHandler(
+            Context context,
+            DiscoveryItem item,
+            @Nullable String companionApp,
+            @Nullable byte[] accountKey) {
+        super(context, item);
+        this.mFastPairHalfSheetManager = Locator.get(context, FastPairHalfSheetManager.class);
+        this.mIsSubsequentPair =
+                item.getAuthenticationPublicKeySecp256R1() != null && accountKey != null;
+        this.mItemResurface = item;
+    }
+
+    @Override
+    protected int getPairStartEventCode() {
+        return mIsSubsequentPair ? NearbyEventIntDefs.EventCode.SUBSEQUENT_PAIR_START
+                : NearbyEventIntDefs.EventCode.MAGIC_PAIR_START;
+    }
+
+    @Override
+    protected int getPairEndEventCode() {
+        return mIsSubsequentPair ? NearbyEventIntDefs.EventCode.SUBSEQUENT_PAIR_END
+                : NearbyEventIntDefs.EventCode.MAGIC_PAIR_END;
+    }
+
+    @Override
+    public void onPairingStarted() {
+        super.onPairingStarted();
+        // Half sheet is not in the foreground reshow half sheet, also avoid showing HalfSheet on TV
+        if (!mFastPairHalfSheetManager.getHalfSheetForegroundState()) {
+            mFastPairHalfSheetManager.showPairingHalfSheet(mItemResurface);
+        }
+        mFastPairHalfSheetManager.disableDismissRunnable();
+    }
+
+    @Override
+    public void onHandlePasskeyConfirmation(BluetoothDevice device, int passkey) {
+        super.onHandlePasskeyConfirmation(device, passkey);
+        mFastPairHalfSheetManager.showPasskeyConfirmation(device, passkey);
+    }
+
+    @Nullable
+    @Override
+    public String onPairedCallbackCalled(
+            FastPairConnection connection,
+            byte[] accountKey,
+            FootprintsDeviceManager footprints,
+            String address) {
+        String deviceName = super.onPairedCallbackCalled(connection, accountKey,
+                footprints, address);
+        mFastPairHalfSheetManager.showPairingSuccessHalfSheet(address);
+        mFastPairHalfSheetManager.disableDismissRunnable();
+        return deviceName;
+    }
+
+    @Override
+    public void onPairingFailed(Throwable throwable) {
+        super.onPairingFailed(throwable);
+        mFastPairHalfSheetManager.disableDismissRunnable();
+        mFastPairHalfSheetManager.showPairingFailed();
+        mFastPairHalfSheetManager.notifyPairingProcessDone(
+                /* success= */ false, /* publicAddress= */ null, mItem);
+        // fix auto rebond issue
+        mFastPairHalfSheetManager.destroyBluetoothPairController();
+    }
+
+    @Override
+    public void onPairingSuccess(String address) {
+        super.onPairingSuccess(address);
+        mFastPairHalfSheetManager.disableDismissRunnable();
+        mFastPairHalfSheetManager
+                .notifyPairingProcessDone(/* success= */ true, address, mItem);
+        mFastPairHalfSheetManager.destroyBluetoothPairController();
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/NotificationPairingProgressHandler.java b/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/NotificationPairingProgressHandler.java
new file mode 100644
index 0000000..d469c45
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/NotificationPairingProgressHandler.java
@@ -0,0 +1,125 @@
+/*
+ * 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.server.nearby.fastpair.pairinghandler;
+
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.server.nearby.common.bluetooth.fastpair.FastPairConnection;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.notification.FastPairNotificationManager;
+import com.android.server.nearby.intdefs.NearbyEventIntDefs;
+
+/** Pairing progress handler for pairing coming from notifications. */
+@SuppressWarnings("nullness")
+public class NotificationPairingProgressHandler extends PairingProgressHandlerBase {
+    private final FastPairNotificationManager mFastPairNotificationManager;
+    @Nullable
+    private final String mCompanionApp;
+    @Nullable
+    private final byte[] mAccountKey;
+    private final boolean mIsSubsequentPair;
+
+    NotificationPairingProgressHandler(
+            Context context,
+            DiscoveryItem item,
+            @Nullable String companionApp,
+            @Nullable byte[] accountKey,
+            FastPairNotificationManager mFastPairNotificationManager) {
+        super(context, item);
+        this.mFastPairNotificationManager = mFastPairNotificationManager;
+        this.mCompanionApp = companionApp;
+        this.mAccountKey = accountKey;
+        this.mIsSubsequentPair =
+                item.getAuthenticationPublicKeySecp256R1() != null && accountKey != null;
+    }
+
+    @Override
+    public int getPairStartEventCode() {
+        return mIsSubsequentPair ? NearbyEventIntDefs.EventCode.SUBSEQUENT_PAIR_START
+                : NearbyEventIntDefs.EventCode.MAGIC_PAIR_START;
+    }
+
+    @Override
+    public int getPairEndEventCode() {
+        return mIsSubsequentPair ? NearbyEventIntDefs.EventCode.SUBSEQUENT_PAIR_END
+                : NearbyEventIntDefs.EventCode.MAGIC_PAIR_END;
+    }
+
+    @Override
+    public void onReadyToPair() {
+        super.onReadyToPair();
+        mFastPairNotificationManager.showConnectingNotification();
+    }
+
+    @Override
+    public String onPairedCallbackCalled(
+            FastPairConnection connection,
+            byte[] accountKey,
+            FootprintsDeviceManager footprints,
+            String address) {
+        String deviceName = super.onPairedCallbackCalled(connection, accountKey, footprints,
+                address);
+
+        int batteryLevel = -1;
+
+        BluetoothManager bluetoothManager = mContext.getSystemService(BluetoothManager.class);
+        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
+        if (bluetoothAdapter != null) {
+            // Need to check battery level here set that to -1 for now
+            batteryLevel = -1;
+        } else {
+            Log.v(
+                    "NotificationPairingProgressHandler",
+                    "onPairedCallbackCalled getBatteryLevel failed,"
+                            + " adapter is null");
+        }
+        mFastPairNotificationManager.showPairingSucceededNotification(
+                !TextUtils.isEmpty(mCompanionApp) ? mCompanionApp : null,
+                batteryLevel,
+                deviceName,
+                address);
+        return deviceName;
+    }
+
+    @Override
+    public void onPairingFailed(Throwable throwable) {
+        super.onPairingFailed(throwable);
+        mFastPairNotificationManager.showPairingFailedNotification(mAccountKey);
+        mFastPairNotificationManager.notifyPairingProcessDone(
+                /* success= */ false,
+                /* forceNotify= */ false,
+                /* privateAddress= */ mItem.getMacAddress(),
+                /* publicAddress= */ null);
+    }
+
+    @Override
+    public void onPairingSuccess(String address) {
+        super.onPairingSuccess(address);
+        mFastPairNotificationManager.notifyPairingProcessDone(
+                /* success= */ true,
+                /* forceNotify= */ false,
+                /* privateAddress= */ mItem.getMacAddress(),
+                /* publicAddress= */ address);
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBase.java b/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBase.java
new file mode 100644
index 0000000..ccd7e5e
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBase.java
@@ -0,0 +1,208 @@
+/*
+ * 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.server.nearby.fastpair.pairinghandler;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress.maskBluetoothAddress;
+import static com.android.server.nearby.fastpair.FastPairManager.isThroughFastPair2InitialPairing;
+
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.server.nearby.common.bluetooth.fastpair.FastPairConnection;
+import com.android.server.nearby.common.bluetooth.fastpair.Preferences;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+import com.android.server.nearby.fastpair.notification.FastPairNotificationManager;
+import com.android.server.nearby.intdefs.FastPairEventIntDefs;
+
+/** Base class for pairing progress handler. */
+public abstract class PairingProgressHandlerBase {
+    protected final Context mContext;
+    protected final DiscoveryItem mItem;
+    @Nullable
+    private FastPairEventIntDefs.ErrorCode mRescueFromError;
+
+    protected abstract int getPairStartEventCode();
+
+    protected abstract int getPairEndEventCode();
+
+    protected PairingProgressHandlerBase(Context context, DiscoveryItem item) {
+        this.mContext = context;
+        this.mItem = item;
+    }
+
+
+    /**
+     * Pairing progress init function.
+     */
+    public static PairingProgressHandlerBase create(
+            Context context,
+            DiscoveryItem item,
+            @Nullable String companionApp,
+            @Nullable byte[] accountKey,
+            FootprintsDeviceManager footprints,
+            FastPairNotificationManager notificationManager,
+            FastPairHalfSheetManager fastPairHalfSheetManager,
+            boolean isRetroactivePair) {
+        PairingProgressHandlerBase pairingProgressHandlerBase;
+        // Disable half sheet on subsequent pairing
+        if (item.getAuthenticationPublicKeySecp256R1() != null
+                && accountKey != null) {
+            // Subsequent pairing
+            pairingProgressHandlerBase =
+                    new NotificationPairingProgressHandler(
+                            context, item, companionApp, accountKey, notificationManager);
+        } else {
+            pairingProgressHandlerBase =
+                    new HalfSheetPairingProgressHandler(context, item, companionApp, accountKey);
+        }
+
+
+        Log.v("PairingHandler",
+                "PairingProgressHandler:Create "
+                        + item.getMacAddress() + " for pairing");
+        return pairingProgressHandlerBase;
+    }
+
+
+    /**
+     * Function calls when pairing start.
+     */
+    public void onPairingStarted() {
+        Log.v("PairingHandler", "PairingProgressHandler:onPairingStarted");
+    }
+
+    /**
+     * Waits for screen to unlock.
+     */
+    public void onWaitForScreenUnlock() {
+        Log.v("PairingHandler", "PairingProgressHandler:onWaitForScreenUnlock");
+    }
+
+    /**
+     * Function calls when screen unlock.
+     */
+    public void onScreenUnlocked() {
+        Log.v("PairingHandler", "PairingProgressHandler:onScreenUnlocked");
+    }
+
+    /**
+     * Calls when the handler is ready to pair.
+     */
+    public void onReadyToPair() {
+        Log.v("PairingHandler", "PairingProgressHandler:onReadyToPair");
+    }
+
+    /**
+     * Helps to set up pairing preference.
+     */
+    public void onSetupPreferencesBuilder(Preferences.Builder builder) {
+        Log.v("PairingHandler", "PairingProgressHandler:onSetupPreferencesBuilder");
+    }
+
+    /**
+     * Calls when pairing setup complete.
+     */
+    public void onPairingSetupCompleted() {
+        Log.v("PairingHandler", "PairingProgressHandler:onPairingSetupCompleted");
+    }
+
+    /** Called while pairing if needs to handle the passkey confirmation by Ui. */
+    public void onHandlePasskeyConfirmation(BluetoothDevice device, int passkey) {
+        Log.v("PairingHandler", "PairingProgressHandler:onHandlePasskeyConfirmation");
+    }
+
+    /**
+     * In this callback, we know if it is a real initial pairing by existing account key, and do
+     * following things:
+     * <li>1, optIn footprint for initial pairing.
+     * <li>2, write the device name to provider
+     * <li>2.1, generate default personalized name for initial pairing or get the personalized name
+     * from footprint for subsequent pairing.
+     * <li>2.2, set alias name for the bluetooth device.
+     * <li>2.3, update the device name for connection to write into provider for initial pair.
+     * <li>3, suppress battery notifications until oobe finishes.
+     *
+     * @return display name of the pairing device
+     */
+    @Nullable
+    public String onPairedCallbackCalled(
+            FastPairConnection connection,
+            byte[] accountKey,
+            FootprintsDeviceManager footprints,
+            String address) {
+        Log.v("PairingHandler",
+                "PairingProgressHandler:onPairedCallbackCalled with address: "
+                        + address);
+
+        byte[] existingAccountKey = connection.getExistingAccountKey();
+        optInFootprintsForInitialPairing(footprints, mItem, accountKey, existingAccountKey);
+        // Add support for naming the device
+        return null;
+    }
+
+    /**
+     * Gets the related info from db use account key.
+     */
+    @Nullable
+    public byte[] getKeyForLocalCache(
+            byte[] accountKey, FastPairConnection connection,
+            FastPairConnection.SharedSecret sharedSecret) {
+        Log.v("PairingHandler", "PairingProgressHandler:getKeyForLocalCache");
+        return accountKey != null ? accountKey : connection.getExistingAccountKey();
+    }
+
+    /**
+     * Function handles pairing fail.
+     */
+    public void onPairingFailed(Throwable throwable) {
+        Log.w("PairingHandler", "PairingProgressHandler:onPairingFailed");
+    }
+
+    /**
+     * Function handles pairing success.
+     */
+    public void onPairingSuccess(String address) {
+        Log.v("PairingHandler", "PairingProgressHandler:onPairingSuccess with address: "
+                + maskBluetoothAddress(address));
+    }
+
+    private static void optInFootprintsForInitialPairing(
+            FootprintsDeviceManager footprints,
+            DiscoveryItem item,
+            byte[] accountKey,
+            @Nullable byte[] existingAccountKey) {
+        if (isThroughFastPair2InitialPairing(item, accountKey) && existingAccountKey == null) {
+            // enable the save to footprint
+            Log.v("PairingHandler", "footprint should call opt in here");
+        }
+    }
+
+    /**
+     * Returns {@code true} if the PairingProgressHandler is running at the background.
+     *
+     * <p>In order to keep the following status notification shows as a heads up, we must wait for
+     * the screen unlocked to continue.
+     */
+    public boolean skipWaitingScreenUnlock() {
+        return false;
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/injector/ContextHubManagerAdapter.java b/nearby/service/java/com/android/server/nearby/injector/ContextHubManagerAdapter.java
new file mode 100644
index 0000000..9af0227
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/injector/ContextHubManagerAdapter.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.injector;
+
+import android.hardware.location.ContextHubClient;
+import android.hardware.location.ContextHubClientCallback;
+import android.hardware.location.ContextHubInfo;
+import android.hardware.location.ContextHubManager;
+import android.hardware.location.ContextHubTransaction;
+import android.hardware.location.NanoAppState;
+
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/** Wrap {@link ContextHubManager} for dependence injection. */
+public class ContextHubManagerAdapter {
+    private final ContextHubManager mManager;
+
+    public ContextHubManagerAdapter(ContextHubManager manager) {
+        mManager = manager;
+    }
+
+    /**
+     * Returns the list of ContextHubInfo objects describing the available Context Hubs.
+     *
+     * @return the list of ContextHubInfo objects
+     * @see ContextHubInfo
+     */
+    public List<ContextHubInfo> getContextHubs() {
+        return mManager.getContextHubs();
+    }
+
+    /**
+     * Requests a query for nanoapps loaded at the specified Context Hub.
+     *
+     * @param hubInfo the hub to query a list of nanoapps from
+     * @return the ContextHubTransaction of the request
+     * @throws NullPointerException if hubInfo is null
+     */
+    public ContextHubTransaction<List<NanoAppState>> queryNanoApps(ContextHubInfo hubInfo) {
+        return mManager.queryNanoApps(hubInfo);
+    }
+
+    /**
+     * Creates and registers a client and its callback with the Context Hub Service.
+     *
+     * <p>A client is registered with the Context Hub Service for a specified Context Hub. When the
+     * registration succeeds, the client can send messages to nanoapps through the returned {@link
+     * ContextHubClient} object, and receive notifications through the provided callback.
+     *
+     * @param hubInfo the hub to attach this client to
+     * @param executor the executor to invoke the callback
+     * @param callback the notification callback to register
+     * @return the registered client object
+     * @throws IllegalArgumentException if hubInfo does not represent a valid hub
+     * @throws IllegalStateException if there were too many registered clients at the service
+     * @throws NullPointerException if callback, hubInfo, or executor is null
+     */
+    public ContextHubClient createClient(
+            ContextHubInfo hubInfo, ContextHubClientCallback callback, Executor executor) {
+        return mManager.createClient(hubInfo, callback, executor);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/injector/Injector.java b/nearby/service/java/com/android/server/nearby/injector/Injector.java
new file mode 100644
index 0000000..f990dc9
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/injector/Injector.java
@@ -0,0 +1,32 @@
+/*
+ * 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.server.nearby.injector;
+
+import android.bluetooth.BluetoothAdapter;
+
+/**
+ * Nearby dependency injector. To be used for accessing various Nearby class instances and as a
+ * handle for mock injection.
+ */
+public interface Injector {
+
+    /** Get the BluetoothAdapter for BleDiscoveryProvider to scan. */
+    BluetoothAdapter getBluetoothAdapter();
+
+    /** Get the ContextHubManagerAdapter for ChreDiscoveryProvider to scan. */
+    ContextHubManagerAdapter getContextHubManagerAdapter();
+}
diff --git a/nearby/service/java/com/android/server/nearby/intdefs/FastPairEventIntDefs.java b/nearby/service/java/com/android/server/nearby/intdefs/FastPairEventIntDefs.java
new file mode 100644
index 0000000..8bb7980
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/intdefs/FastPairEventIntDefs.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 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.server.nearby.intdefs;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Holds integer definitions for FastPair. */
+public class FastPairEventIntDefs {
+
+    /** Fast Pair Bond State. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            value = {
+                    BondState.UNKNOWN_BOND_STATE,
+                    BondState.NONE,
+                    BondState.BONDING,
+                    BondState.BONDED,
+            })
+    public @interface BondState {
+        int UNKNOWN_BOND_STATE = 0;
+        int NONE = 10;
+        int BONDING = 11;
+        int BONDED = 12;
+    }
+
+    /** Fast Pair error code. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            value = {
+                    ErrorCode.UNKNOWN_ERROR_CODE,
+                    ErrorCode.OTHER_ERROR,
+                    ErrorCode.TIMEOUT,
+                    ErrorCode.INTERRUPTED,
+                    ErrorCode.REFLECTIVE_OPERATION_EXCEPTION,
+                    ErrorCode.EXECUTION_EXCEPTION,
+                    ErrorCode.PARSE_EXCEPTION,
+                    ErrorCode.MDH_REMOTE_EXCEPTION,
+                    ErrorCode.SUCCESS_RETRY_GATT_ERROR,
+                    ErrorCode.SUCCESS_RETRY_GATT_TIMEOUT,
+                    ErrorCode.SUCCESS_RETRY_SECRET_HANDSHAKE_ERROR,
+                    ErrorCode.SUCCESS_RETRY_SECRET_HANDSHAKE_TIMEOUT,
+                    ErrorCode.SUCCESS_SECRET_HANDSHAKE_RECONNECT,
+                    ErrorCode.SUCCESS_ADDRESS_ROTATE,
+                    ErrorCode.SUCCESS_SIGNAL_LOST,
+            })
+    public @interface ErrorCode {
+        int UNKNOWN_ERROR_CODE = 0;
+
+        // Check the other fields for a more specific error code.
+        int OTHER_ERROR = 1;
+
+        // The operation timed out.
+        int TIMEOUT = 2;
+
+        // The thread was interrupted.
+        int INTERRUPTED = 3;
+
+        // Some reflective call failed (should never happen).
+        int REFLECTIVE_OPERATION_EXCEPTION = 4;
+
+        // A Future threw an exception (should never happen).
+        int EXECUTION_EXCEPTION = 5;
+
+        // Parsing something (e.g. BR/EDR Handover data) failed.
+        int PARSE_EXCEPTION = 6;
+
+        // A failure at MDH.
+        int MDH_REMOTE_EXCEPTION = 7;
+
+        // For errors on GATT connection and retry success
+        int SUCCESS_RETRY_GATT_ERROR = 8;
+
+        // For timeout on GATT connection and retry success
+        int SUCCESS_RETRY_GATT_TIMEOUT = 9;
+
+        // For errors on secret handshake and retry success
+        int SUCCESS_RETRY_SECRET_HANDSHAKE_ERROR = 10;
+
+        // For timeout on secret handshake and retry success
+        int SUCCESS_RETRY_SECRET_HANDSHAKE_TIMEOUT = 11;
+
+        // For secret handshake fail and restart GATT connection success
+        int SUCCESS_SECRET_HANDSHAKE_RECONNECT = 12;
+
+        // For address rotate and retry with new address success
+        int SUCCESS_ADDRESS_ROTATE = 13;
+
+        // For signal lost and retry with old address still success
+        int SUCCESS_SIGNAL_LOST = 14;
+    }
+
+    /** Fast Pair BrEdrHandover Error Code. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            value = {
+                    BrEdrHandoverErrorCode.UNKNOWN_BR_EDR_HANDOVER_ERROR_CODE,
+                    BrEdrHandoverErrorCode.CONTROL_POINT_RESULT_CODE_NOT_SUCCESS,
+                    BrEdrHandoverErrorCode.BLUETOOTH_MAC_INVALID,
+                    BrEdrHandoverErrorCode.TRANSPORT_BLOCK_INVALID,
+            })
+    public @interface BrEdrHandoverErrorCode {
+        int UNKNOWN_BR_EDR_HANDOVER_ERROR_CODE = 0;
+        int CONTROL_POINT_RESULT_CODE_NOT_SUCCESS = 1;
+        int BLUETOOTH_MAC_INVALID = 2;
+        int TRANSPORT_BLOCK_INVALID = 3;
+    }
+
+    /** Fast Pair CreateBound Error Code. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            value = {
+                    CreateBondErrorCode.UNKNOWN_BOND_ERROR_CODE,
+                    CreateBondErrorCode.BOND_BROKEN,
+                    CreateBondErrorCode.POSSIBLE_MITM,
+                    CreateBondErrorCode.NO_PERMISSION,
+                    CreateBondErrorCode.INCORRECT_VARIANT,
+                    CreateBondErrorCode.FAILED_BUT_ALREADY_RECEIVE_PASS_KEY,
+            })
+    public @interface CreateBondErrorCode {
+        int UNKNOWN_BOND_ERROR_CODE = 0;
+        int BOND_BROKEN = 1;
+        int POSSIBLE_MITM = 2;
+        int NO_PERMISSION = 3;
+        int INCORRECT_VARIANT = 4;
+        int FAILED_BUT_ALREADY_RECEIVE_PASS_KEY = 5;
+    }
+
+    /** Fast Pair Connect Error Code. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            value = {
+                    ConnectErrorCode.UNKNOWN_CONNECT_ERROR_CODE,
+                    ConnectErrorCode.UNSUPPORTED_PROFILE,
+                    ConnectErrorCode.GET_PROFILE_PROXY_FAILED,
+                    ConnectErrorCode.DISCONNECTED,
+                    ConnectErrorCode.LINK_KEY_CLEARED,
+                    ConnectErrorCode.FAIL_TO_DISCOVERY,
+                    ConnectErrorCode.DISCOVERY_NOT_FINISHED,
+            })
+    public @interface ConnectErrorCode {
+        int UNKNOWN_CONNECT_ERROR_CODE = 0;
+        int UNSUPPORTED_PROFILE = 1;
+        int GET_PROFILE_PROXY_FAILED = 2;
+        int DISCONNECTED = 3;
+        int LINK_KEY_CLEARED = 4;
+        int FAIL_TO_DISCOVERY = 5;
+        int DISCOVERY_NOT_FINISHED = 6;
+    }
+
+    private FastPairEventIntDefs() {}
+}
diff --git a/nearby/service/java/com/android/server/nearby/intdefs/NearbyEventIntDefs.java b/nearby/service/java/com/android/server/nearby/intdefs/NearbyEventIntDefs.java
new file mode 100644
index 0000000..91bf49a
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/intdefs/NearbyEventIntDefs.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 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.server.nearby.intdefs;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Holds integer definitions for NearbyEvent. */
+public class NearbyEventIntDefs {
+
+    /** NearbyEvent Code. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            value = {
+                    EventCode.UNKNOWN_EVENT_TYPE,
+                    EventCode.MAGIC_PAIR_START,
+                    EventCode.WAIT_FOR_SCREEN_UNLOCK,
+                    EventCode.GATT_CONNECT,
+                    EventCode.BR_EDR_HANDOVER_WRITE_CONTROL_POINT_REQUEST,
+                    EventCode.BR_EDR_HANDOVER_READ_BLUETOOTH_MAC,
+                    EventCode.BR_EDR_HANDOVER_READ_TRANSPORT_BLOCK,
+                    EventCode.GET_PROFILES_VIA_SDP,
+                    EventCode.DISCOVER_DEVICE,
+                    EventCode.CANCEL_DISCOVERY,
+                    EventCode.REMOVE_BOND,
+                    EventCode.CANCEL_BOND,
+                    EventCode.CREATE_BOND,
+                    EventCode.CONNECT_PROFILE,
+                    EventCode.DISABLE_BLUETOOTH,
+                    EventCode.ENABLE_BLUETOOTH,
+                    EventCode.MAGIC_PAIR_END,
+                    EventCode.SECRET_HANDSHAKE,
+                    EventCode.WRITE_ACCOUNT_KEY,
+                    EventCode.WRITE_TO_FOOTPRINTS,
+                    EventCode.PASSKEY_EXCHANGE,
+                    EventCode.DEVICE_RECOGNIZED,
+                    EventCode.GET_LOCAL_PUBLIC_ADDRESS,
+                    EventCode.DIRECTLY_CONNECTED_TO_PROFILE,
+                    EventCode.DEVICE_ALIAS_CHANGED,
+                    EventCode.WRITE_DEVICE_NAME,
+                    EventCode.UPDATE_PROVIDER_NAME_START,
+                    EventCode.UPDATE_PROVIDER_NAME_END,
+                    EventCode.READ_FIRMWARE_VERSION,
+                    EventCode.RETROACTIVE_PAIR_START,
+                    EventCode.RETROACTIVE_PAIR_END,
+                    EventCode.SUBSEQUENT_PAIR_START,
+                    EventCode.SUBSEQUENT_PAIR_END,
+                    EventCode.BISTO_PAIR_START,
+                    EventCode.BISTO_PAIR_END,
+                    EventCode.REMOTE_PAIR_START,
+                    EventCode.REMOTE_PAIR_END,
+                    EventCode.BEFORE_CREATE_BOND,
+                    EventCode.BEFORE_CREATE_BOND_BONDING,
+                    EventCode.BEFORE_CREATE_BOND_BONDED,
+                    EventCode.BEFORE_CONNECT_PROFILE,
+                    EventCode.HANDLE_PAIRING_REQUEST,
+                    EventCode.SECRET_HANDSHAKE_GATT_COMMUNICATION,
+                    EventCode.GATT_CONNECTION_AND_SECRET_HANDSHAKE,
+                    EventCode.CHECK_SIGNAL_AFTER_HANDSHAKE,
+                    EventCode.RECOVER_BY_RETRY_GATT,
+                    EventCode.RECOVER_BY_RETRY_HANDSHAKE,
+                    EventCode.RECOVER_BY_RETRY_HANDSHAKE_RECONNECT,
+                    EventCode.GATT_HANDSHAKE_MANUAL_RETRY_ATTEMPTS,
+                    EventCode.PAIR_WITH_CACHED_MODEL_ID,
+                    EventCode.DIRECTLY_CONNECT_PROFILE_WITH_CACHED_ADDRESS,
+                    EventCode.PAIR_WITH_NEW_MODEL,
+            })
+    public @interface EventCode {
+        int UNKNOWN_EVENT_TYPE = 0;
+
+        // Codes for Magic Pair.
+        // Starting at 1000 to not conflict with other existing codes (e.g.
+        // DiscoveryEvent) that may be migrated to become official Event Codes.
+        int MAGIC_PAIR_START = 1010;
+        int WAIT_FOR_SCREEN_UNLOCK = 1020;
+        int GATT_CONNECT = 1030;
+        int BR_EDR_HANDOVER_WRITE_CONTROL_POINT_REQUEST = 1040;
+        int BR_EDR_HANDOVER_READ_BLUETOOTH_MAC = 1050;
+        int BR_EDR_HANDOVER_READ_TRANSPORT_BLOCK = 1060;
+        int GET_PROFILES_VIA_SDP = 1070;
+        int DISCOVER_DEVICE = 1080;
+        int CANCEL_DISCOVERY = 1090;
+        int REMOVE_BOND = 1100;
+        int CANCEL_BOND = 1110;
+        int CREATE_BOND = 1120;
+        int CONNECT_PROFILE = 1130;
+        int DISABLE_BLUETOOTH = 1140;
+        int ENABLE_BLUETOOTH = 1150;
+        int MAGIC_PAIR_END = 1160;
+        int SECRET_HANDSHAKE = 1170;
+        int WRITE_ACCOUNT_KEY = 1180;
+        int WRITE_TO_FOOTPRINTS = 1190;
+        int PASSKEY_EXCHANGE = 1200;
+        int DEVICE_RECOGNIZED = 1210;
+        int GET_LOCAL_PUBLIC_ADDRESS = 1220;
+        int DIRECTLY_CONNECTED_TO_PROFILE = 1230;
+        int DEVICE_ALIAS_CHANGED = 1240;
+        int WRITE_DEVICE_NAME = 1250;
+        int UPDATE_PROVIDER_NAME_START = 1260;
+        int UPDATE_PROVIDER_NAME_END = 1270;
+        int READ_FIRMWARE_VERSION = 1280;
+        int RETROACTIVE_PAIR_START = 1290;
+        int RETROACTIVE_PAIR_END = 1300;
+        int SUBSEQUENT_PAIR_START = 1310;
+        int SUBSEQUENT_PAIR_END = 1320;
+        int BISTO_PAIR_START = 1330;
+        int BISTO_PAIR_END = 1340;
+        int REMOTE_PAIR_START = 1350;
+        int REMOTE_PAIR_END = 1360;
+        int BEFORE_CREATE_BOND = 1370;
+        int BEFORE_CREATE_BOND_BONDING = 1380;
+        int BEFORE_CREATE_BOND_BONDED = 1390;
+        int BEFORE_CONNECT_PROFILE = 1400;
+        int HANDLE_PAIRING_REQUEST = 1410;
+        int SECRET_HANDSHAKE_GATT_COMMUNICATION = 1420;
+        int GATT_CONNECTION_AND_SECRET_HANDSHAKE = 1430;
+        int CHECK_SIGNAL_AFTER_HANDSHAKE = 1440;
+        int RECOVER_BY_RETRY_GATT = 1450;
+        int RECOVER_BY_RETRY_HANDSHAKE = 1460;
+        int RECOVER_BY_RETRY_HANDSHAKE_RECONNECT = 1470;
+        int GATT_HANDSHAKE_MANUAL_RETRY_ATTEMPTS = 1480;
+        int PAIR_WITH_CACHED_MODEL_ID = 1490;
+        int DIRECTLY_CONNECT_PROFILE_WITH_CACHED_ADDRESS = 1500;
+        int PAIR_WITH_NEW_MODEL = 1510;
+    }
+
+    private NearbyEventIntDefs() {}
+}
diff --git a/nearby/service/java/com/android/server/nearby/metrics/NearbyMetrics.java b/nearby/service/java/com/android/server/nearby/metrics/NearbyMetrics.java
new file mode 100644
index 0000000..75815f1
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/metrics/NearbyMetrics.java
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.metrics;
+
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.ScanRequest;
+import android.os.WorkSource;
+
+import com.android.server.nearby.proto.NearbyStatsLog;
+
+/**
+ * A class to collect and report Nearby metrics.
+ */
+public class NearbyMetrics {
+    /**
+     * Logs a scan started event.
+     */
+    public static void logScanStarted(int scanSessionId, ScanRequest scanRequest) {
+        NearbyStatsLog.write(
+                NearbyStatsLog.NEARBY_DEVICE_SCAN_STATE_CHANGED,
+                getUid(scanRequest),
+                scanSessionId,
+                NearbyStatsLog
+                        .NEARBY_DEVICE_SCAN_STATE_CHANGED__SCAN_STATE__NEARBY_SCAN_STATE_STARTED,
+                scanRequest.getScanType(),
+                0,
+                0,
+                "",
+                "");
+    }
+
+    /**
+     * Logs a scan stopped event.
+     */
+    public static void logScanStopped(int scanSessionId, ScanRequest scanRequest) {
+        NearbyStatsLog.write(
+                NearbyStatsLog.NEARBY_DEVICE_SCAN_STATE_CHANGED,
+                getUid(scanRequest),
+                scanSessionId,
+                NearbyStatsLog
+                        .NEARBY_DEVICE_SCAN_STATE_CHANGED__SCAN_STATE__NEARBY_SCAN_STATE_STOPPED,
+                scanRequest.getScanType(),
+                0,
+                0,
+                "",
+                "");
+    }
+
+    /**
+     * Logs a scan device discovered event.
+     */
+    public static void logScanDeviceDiscovered(int scanSessionId, ScanRequest scanRequest,
+            NearbyDeviceParcelable nearbyDevice) {
+        NearbyStatsLog.write(
+                NearbyStatsLog.NEARBY_DEVICE_SCAN_STATE_CHANGED,
+                getUid(scanRequest),
+                scanSessionId,
+                NearbyStatsLog
+                        .NEARBY_DEVICE_SCAN_STATE_CHANGED__SCAN_STATE__NEARBY_SCAN_STATE_DISCOVERED,
+                scanRequest.getScanType(),
+                nearbyDevice.getMedium(),
+                nearbyDevice.getRssi(),
+                nearbyDevice.getFastPairModelId(),
+                "");
+    }
+
+    private static int getUid(ScanRequest scanRequest) {
+        WorkSource workSource = scanRequest.getWorkSource();
+        return workSource.isEmpty() ? -1 : workSource.getUid(0);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/presence/FastAdvertisement.java b/nearby/service/java/com/android/server/nearby/presence/FastAdvertisement.java
new file mode 100644
index 0000000..e4df673
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/presence/FastAdvertisement.java
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.presence;
+
+import android.annotation.Nullable;
+import android.nearby.BroadcastRequest;
+import android.nearby.PresenceBroadcastRequest;
+import android.nearby.PresenceCredential;
+
+import com.android.internal.util.Preconditions;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+/**
+ * A Nearby Presence advertisement to be advertised on BT4.2 devices.
+ *
+ * <p>Serializable between Java object and bytes formats. Java object is used at the upper scanning
+ * and advertising interface as an abstraction of the actual bytes. Bytes format is used at the
+ * underlying BLE and mDNS stacks, which do necessary slicing and merging based on advertising
+ * capacities.
+ */
+// The fast advertisement is defined in the format below:
+// Header (1 byte) | salt (2 bytes) | identity (14 bytes) | tx_power (1 byte) | actions (1~ bytes)
+// The header contains:
+// version (3 bits) | provision_mode_flag (1 bit) | identity_type (3 bits) |
+// extended_advertisement_mode (1 bit)
+public class FastAdvertisement {
+
+    private static final int FAST_ADVERTISEMENT_MAX_LENGTH = 24;
+
+    static final byte INVALID_TX_POWER = (byte) 0xFF;
+
+    static final int HEADER_LENGTH = 1;
+
+    static final int SALT_LENGTH = 2;
+
+    static final int IDENTITY_LENGTH = 14;
+
+    static final int TX_POWER_LENGTH = 1;
+
+    private static final int MAX_ACTION_COUNT = 6;
+
+    /**
+     * Creates a {@link FastAdvertisement} from a Presence Broadcast Request.
+     */
+    public static FastAdvertisement createFromRequest(PresenceBroadcastRequest request) {
+        byte[] salt = request.getSalt();
+        byte[] identity = request.getCredential().getMetadataEncryptionKey();
+        List<Integer> actions = request.getActions();
+        Preconditions.checkArgument(
+                salt.length == SALT_LENGTH,
+                "FastAdvertisement's salt does not match correct length");
+        Preconditions.checkArgument(
+                identity.length == IDENTITY_LENGTH,
+                "FastAdvertisement's identity does not match correct length");
+        Preconditions.checkArgument(
+                !actions.isEmpty(), "FastAdvertisement must contain at least one action");
+        Preconditions.checkArgument(
+                actions.size() <= MAX_ACTION_COUNT,
+                "FastAdvertisement advertised actions cannot exceed max count " + MAX_ACTION_COUNT);
+
+        return new FastAdvertisement(
+                request.getCredential().getIdentityType(),
+                identity,
+                salt,
+                actions,
+                (byte) request.getTxPower());
+    }
+
+    /** Serialize an {@link FastAdvertisement} object into bytes. */
+    public byte[] toBytes() {
+        ByteBuffer buffer = ByteBuffer.allocate(getLength());
+
+        buffer.put(FastAdvertisementUtils.constructHeader(getVersion(), mIdentityType));
+        buffer.put(mSalt);
+        buffer.put(getIdentity());
+
+        buffer.put(mTxPower == null ? INVALID_TX_POWER : mTxPower);
+        for (int action : mActions) {
+            buffer.put((byte) action);
+        }
+        return buffer.array();
+    }
+
+    private final int mLength;
+
+    private final int mLtvFieldCount;
+
+    @PresenceCredential.IdentityType private final int mIdentityType;
+
+    private final byte[] mIdentity;
+
+    private final byte[] mSalt;
+
+    private final List<Integer> mActions;
+
+    @Nullable
+    private final Byte mTxPower;
+
+    FastAdvertisement(
+            @PresenceCredential.IdentityType int identityType,
+            byte[] identity,
+            byte[] salt,
+            List<Integer> actions,
+            @Nullable Byte txPower) {
+        this.mIdentityType = identityType;
+        this.mIdentity = identity;
+        this.mSalt = salt;
+        this.mActions = actions;
+        this.mTxPower = txPower;
+        int ltvFieldCount = 3;
+        int length =
+                HEADER_LENGTH // header
+                        + identity.length
+                        + salt.length
+                        + actions.size();
+        length += TX_POWER_LENGTH;
+        if (txPower != null) { // TX power
+            ltvFieldCount += 1;
+        }
+        this.mLength = length;
+        this.mLtvFieldCount = ltvFieldCount;
+        Preconditions.checkArgument(
+                length <= FAST_ADVERTISEMENT_MAX_LENGTH,
+                "FastAdvertisement exceeds maximum length");
+    }
+
+    /** Returns the version in the advertisement. */
+    @BroadcastRequest.BroadcastVersion
+    public int getVersion() {
+        return BroadcastRequest.PRESENCE_VERSION_V0;
+    }
+
+    /** Returns the identity type in the advertisement. */
+    @PresenceCredential.IdentityType
+    public int getIdentityType() {
+        return mIdentityType;
+    }
+
+    /** Returns the identity bytes in the advertisement. */
+    public byte[] getIdentity() {
+        return mIdentity.clone();
+    }
+
+    /** Returns the salt of the advertisement. */
+    public byte[] getSalt() {
+        return mSalt.clone();
+    }
+
+    /** Returns the actions in the advertisement. */
+    public List<Integer> getActions() {
+        return new ArrayList<>(mActions);
+    }
+
+    /** Returns the adjusted TX Power in the advertisement. Null if not available. */
+    @Nullable
+    public Byte getTxPower() {
+        return mTxPower;
+    }
+
+    /** Returns the length of the advertisement. */
+    public int getLength() {
+        return mLength;
+    }
+
+    /** Returns the count of LTV fields in the advertisement. */
+    public int getLtvFieldCount() {
+        return mLtvFieldCount;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "FastAdvertisement:<VERSION: %s, length: %s, ltvFieldCount: %s, identityType: %s,"
+                        + " identity: %s, salt: %s, actions: %s, txPower: %s",
+                getVersion(),
+                getLength(),
+                getLtvFieldCount(),
+                getIdentityType(),
+                Arrays.toString(getIdentity()),
+                Arrays.toString(getSalt()),
+                getActions(),
+                getTxPower());
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/presence/FastAdvertisementUtils.java b/nearby/service/java/com/android/server/nearby/presence/FastAdvertisementUtils.java
new file mode 100644
index 0000000..ab0a246
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/presence/FastAdvertisementUtils.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.presence;
+
+import android.nearby.BroadcastRequest;
+
+/**
+ * Provides serialization and deserialization util methods for {@link FastAdvertisement}.
+ */
+public final class FastAdvertisementUtils {
+
+    private static final int VERSION_MASK = 0b11100000;
+
+    private static final int IDENTITY_TYPE_MASK = 0b00001110;
+
+    /**
+     * Constructs the header of a {@link FastAdvertisement}.
+     */
+    public static byte constructHeader(@BroadcastRequest.BroadcastVersion int version,
+            int identityType) {
+        return (byte) (((version << 5) & VERSION_MASK) | ((identityType << 1)
+                & IDENTITY_TYPE_MASK));
+    }
+
+    private FastAdvertisementUtils() {}
+}
diff --git a/nearby/service/java/com/android/server/nearby/presence/PresenceConstants.java b/nearby/service/java/com/android/server/nearby/presence/PresenceConstants.java
new file mode 100644
index 0000000..c355df2
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/presence/PresenceConstants.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.presence;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothUuids.to128BitUuid;
+
+import java.util.UUID;
+
+/**
+ * Constants for Nearby Presence operations.
+ */
+public class PresenceConstants {
+
+    /** Presence advertisement service data uuid. */
+    public static final UUID PRESENCE_UUID = to128BitUuid((short) 0xFCF1);
+}
diff --git a/nearby/service/java/com/android/server/nearby/presence/PresenceDiscoveryResult.java b/nearby/service/java/com/android/server/nearby/presence/PresenceDiscoveryResult.java
new file mode 100644
index 0000000..80ad88d
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/presence/PresenceDiscoveryResult.java
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.presence;
+
+import android.nearby.NearbyDevice;
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.PresenceDevice;
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Represents a Presence discovery result. */
+public class PresenceDiscoveryResult {
+
+    /** Creates a {@link PresenceDiscoveryResult} from the scan data. */
+    public static PresenceDiscoveryResult fromDevice(NearbyDeviceParcelable device) {
+        return new PresenceDiscoveryResult.Builder()
+                .setTxPower(device.getTxPower())
+                .setRssi(device.getRssi())
+                .addPresenceAction(device.getAction())
+                .setPublicCredential(device.getPublicCredential())
+                .build();
+    }
+
+    private final int mTxPower;
+    private final int mRssi;
+    private final byte[] mSalt;
+    private final List<Integer> mPresenceActions;
+    private final PublicCredential mPublicCredential;
+
+    private PresenceDiscoveryResult(
+            int txPower,
+            int rssi,
+            byte[] salt,
+            List<Integer> presenceActions,
+            PublicCredential publicCredential) {
+        mTxPower = txPower;
+        mRssi = rssi;
+        mSalt = salt;
+        mPresenceActions = presenceActions;
+        mPublicCredential = publicCredential;
+    }
+
+    /** Returns whether the discovery result matches the scan filter. */
+    public boolean matches(PresenceScanFilter scanFilter) {
+        return pathLossMatches(scanFilter.getMaxPathLoss())
+                && actionMatches(scanFilter.getPresenceActions())
+                && credentialMatches(scanFilter.getCredentials());
+    }
+
+    private boolean pathLossMatches(int maxPathLoss) {
+        return (mTxPower - mRssi) <= maxPathLoss;
+    }
+
+    private boolean actionMatches(List<Integer> filterActions) {
+        if (filterActions.isEmpty()) {
+            return true;
+        }
+        return filterActions.stream().anyMatch(mPresenceActions::contains);
+    }
+
+    private boolean credentialMatches(List<PublicCredential> credentials) {
+        return credentials.contains(mPublicCredential);
+    }
+
+    /** Converts a presence device from the discovery result. */
+    public PresenceDevice toPresenceDevice() {
+        return new PresenceDevice.Builder(
+                // Use the public credential hash as the device Id.
+                String.valueOf(mPublicCredential.hashCode()),
+                mSalt,
+                mPublicCredential.getSecretId(),
+                mPublicCredential.getEncryptedMetadata())
+                .setRssi(mRssi)
+                .addMedium(NearbyDevice.Medium.BLE)
+                .build();
+    }
+
+    /** Builder for {@link PresenceDiscoveryResult}. */
+    public static class Builder {
+        private int mTxPower;
+        private int mRssi;
+        private byte[] mSalt;
+
+        private PublicCredential mPublicCredential;
+        private final List<Integer> mPresenceActions;
+
+        public Builder() {
+            mPresenceActions = new ArrayList<>();
+        }
+
+        /** Sets the calibrated tx power for the discovery result. */
+        public Builder setTxPower(int txPower) {
+            mTxPower = txPower;
+            return this;
+        }
+
+        /** Sets the rssi for the discovery result. */
+        public Builder setRssi(int rssi) {
+            mRssi = rssi;
+            return this;
+        }
+
+        /** Sets the salt for the discovery result. */
+        public Builder setSalt(byte[] salt) {
+            mSalt = salt;
+            return this;
+        }
+
+        /** Sets the public credential for the discovery result. */
+        public Builder setPublicCredential(PublicCredential publicCredential) {
+            mPublicCredential = publicCredential;
+            return this;
+        }
+
+        /** Adds presence action of the discovery result. */
+        public Builder addPresenceAction(int presenceAction) {
+            mPresenceActions.add(presenceAction);
+            return this;
+        }
+
+        /** Builds a {@link PresenceDiscoveryResult}. */
+        public PresenceDiscoveryResult build() {
+            return new PresenceDiscoveryResult(
+                    mTxPower, mRssi, mSalt, mPresenceActions, mPublicCredential);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/presence/PresenceManager.java b/nearby/service/java/com/android/server/nearby/presence/PresenceManager.java
new file mode 100644
index 0000000..382c47a
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/presence/PresenceManager.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.presence;
+
+import static com.android.server.nearby.NearbyService.TAG;
+
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nearby.NearbyDevice;
+import android.nearby.NearbyManager;
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
+import android.nearby.ScanCallback;
+import android.nearby.ScanRequest;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+
+import java.util.Locale;
+import java.util.concurrent.Executors;
+
+/** PresenceManager is the class initiated in nearby service to handle presence related work. */
+public class PresenceManager {
+
+    final LocatorContextWrapper mLocatorContextWrapper;
+    final Locator mLocator;
+    private final IntentFilter mIntentFilter;
+
+    private final ScanCallback mScanCallback =
+            new ScanCallback() {
+                @Override
+                public void onDiscovered(@NonNull NearbyDevice device) {
+                    Log.i(TAG, "[PresenceManager] discovered Device.");
+                }
+
+                @Override
+                public void onUpdated(@NonNull NearbyDevice device) {}
+
+                @Override
+                public void onLost(@NonNull NearbyDevice device) {}
+            };
+
+    private final BroadcastReceiver mScreenBroadcastReceiver =
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    NearbyManager manager = getNearbyManager();
+                    if (manager == null) {
+                        Log.e(TAG, "Nearby Manager is null");
+                        return;
+                    }
+                    if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
+                        Log.d(TAG, "Start CHRE scan.");
+                        byte[] secreteId = {1, 0, 0, 0};
+                        byte[] authenticityKey = {2, 0, 0, 0};
+                        byte[] publicKey = {3, 0, 0, 0};
+                        byte[] encryptedMetaData = {4, 0, 0, 0};
+                        byte[] encryptedMetaDataTag = {5, 0, 0, 0};
+                        PublicCredential publicCredential =
+                                new PublicCredential.Builder(
+                                                secreteId,
+                                                authenticityKey,
+                                                publicKey,
+                                                encryptedMetaData,
+                                                encryptedMetaDataTag)
+                                        .build();
+                        PresenceScanFilter presenceScanFilter =
+                                new PresenceScanFilter.Builder()
+                                        .setMaxPathLoss(3)
+                                        .addCredential(publicCredential)
+                                        .addPresenceAction(1)
+                                        .build();
+                        ScanRequest scanRequest =
+                                new ScanRequest.Builder()
+                                        .setScanType(ScanRequest.SCAN_TYPE_NEARBY_PRESENCE)
+                                        .addScanFilter(presenceScanFilter)
+                                        .build();
+                        Log.i(
+                                TAG,
+                                String.format(
+                                        Locale.getDefault(),
+                                        "[PresenceManager] Start Presence scan with request: %s",
+                                        scanRequest.toString()));
+                        manager.startScan(
+                                scanRequest, Executors.newSingleThreadExecutor(), mScanCallback);
+                    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
+                        Log.d(TAG, "Stop CHRE scan.");
+                        manager.stopScan(mScanCallback);
+                    }
+                }
+            };
+
+    public PresenceManager(LocatorContextWrapper contextWrapper) {
+        mLocatorContextWrapper = contextWrapper;
+        mLocator = mLocatorContextWrapper.getLocator();
+        mIntentFilter = new IntentFilter();
+    }
+
+    /** Null when the Nearby Service is not available. */
+    @Nullable
+    private NearbyManager getNearbyManager() {
+        return (NearbyManager)
+                mLocatorContextWrapper
+                        .getApplicationContext()
+                        .getSystemService(Context.NEARBY_SERVICE);
+    }
+
+    /** Function called when nearby service start. */
+    public void initiate() {
+        mIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
+        mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+        mLocatorContextWrapper
+                .getContext()
+                .registerReceiver(mScreenBroadcastReceiver, mIntentFilter);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/AbstractDiscoveryProvider.java b/nearby/service/java/com/android/server/nearby/provider/AbstractDiscoveryProvider.java
new file mode 100644
index 0000000..f136695
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/AbstractDiscoveryProvider.java
@@ -0,0 +1,144 @@
+/*
+ * 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.server.nearby.provider;
+
+import static com.android.server.nearby.NearbyService.TAG;
+
+import android.content.Context;
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.ScanFilter;
+import android.nearby.ScanRequest;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Base class for all discovery providers.
+ *
+ * @hide
+ */
+public abstract class AbstractDiscoveryProvider {
+
+    protected final Context mContext;
+    protected final DiscoveryProviderController mController;
+    protected final Executor mExecutor;
+    protected Listener mListener;
+    protected List<ScanFilter> mScanFilters;
+
+    /** Interface for listening to discovery providers. */
+    public interface Listener {
+        /**
+         * Called when a provider has a new nearby device available. May be invoked from any thread.
+         */
+        void onNearbyDeviceDiscovered(NearbyDeviceParcelable nearbyDevice);
+    }
+
+    protected AbstractDiscoveryProvider(Context context, Executor executor) {
+        mContext = context;
+        mExecutor = executor;
+        mController = new Controller();
+    }
+
+    /**
+     * Callback invoked when the provider is started, and signals that other callback invocations
+     * can now be expected. Always implies that the provider request is set to the empty request.
+     * Always invoked on the provider executor.
+     */
+    protected void onStart() {}
+
+    /**
+     * Callback invoked when the provider is stopped, and signals that no further callback
+     * invocations will occur (until a further call to {@link #onStart()}. Always invoked on the
+     * provider executor.
+     */
+    protected void onStop() {}
+
+    /**
+     * Callback invoked to inform the provider of a new provider request which replaces any prior
+     * provider request. Always invoked on the provider executor.
+     */
+    protected void invalidateScanMode() {}
+
+    /**
+     * Retrieves the controller for this discovery provider. Should never be invoked by subclasses,
+     * as a discovery provider should not be controlling itself. Using this method from subclasses
+     * could also result in deadlock.
+     */
+    protected DiscoveryProviderController getController() {
+        return mController;
+    }
+
+    private class Controller implements DiscoveryProviderController {
+
+        private boolean mStarted = false;
+        private @ScanRequest.ScanMode int mScanMode;
+
+        @Override
+        public void setListener(@Nullable Listener listener) {
+            mListener = listener;
+        }
+
+        @Override
+        public boolean isStarted() {
+            return mStarted;
+        }
+
+        @Override
+        public void start() {
+            if (mStarted) {
+                Log.d(TAG, "Provider already started.");
+                return;
+            }
+            mStarted = true;
+            mExecutor.execute(AbstractDiscoveryProvider.this::onStart);
+        }
+
+        @Override
+        public void stop() {
+            if (!mStarted) {
+                Log.d(TAG, "Provider already stopped.");
+                return;
+            }
+            mStarted = false;
+            mExecutor.execute(AbstractDiscoveryProvider.this::onStop);
+        }
+
+        @Override
+        public void setProviderScanMode(@ScanRequest.ScanMode int scanMode) {
+            if (mScanMode == scanMode) {
+                Log.d(TAG, "Provider already in desired scan mode.");
+                return;
+            }
+            mScanMode = scanMode;
+            mExecutor.execute(AbstractDiscoveryProvider.this::invalidateScanMode);
+        }
+
+        @ScanRequest.ScanMode
+        @Override
+        public int getProviderScanMode() {
+            return mScanMode;
+        }
+
+        @Override
+        public void setProviderScanFilters(List<ScanFilter> filters) {
+            mScanFilters = filters;
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java b/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java
new file mode 100644
index 0000000..3602787
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/BleBroadcastProvider.java
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.BluetoothLeAdvertiser;
+import android.nearby.BroadcastCallback;
+import android.os.ParcelUuid;
+
+import com.android.server.nearby.injector.Injector;
+import com.android.server.nearby.presence.PresenceConstants;
+
+import java.util.concurrent.Executor;
+
+/**
+ * A provider for Bluetooth Low Energy advertisement.
+ */
+public class BleBroadcastProvider extends AdvertiseCallback {
+
+    /**
+     * Listener for Broadcast status changes.
+     */
+    interface BroadcastListener {
+        void onStatusChanged(int status);
+    }
+
+    private final Injector mInjector;
+    private final Executor mExecutor;
+
+    private BroadcastListener mBroadcastListener;
+    private boolean mIsAdvertising;
+
+    BleBroadcastProvider(Injector injector, Executor executor) {
+        mInjector = injector;
+        mExecutor = executor;
+    }
+
+    void start(byte[] advertisementPackets, BroadcastListener listener) {
+        if (mIsAdvertising) {
+            stop();
+        }
+        boolean advertiseStarted = false;
+        BluetoothAdapter adapter = mInjector.getBluetoothAdapter();
+        if (adapter != null) {
+            BluetoothLeAdvertiser bluetoothLeAdvertiser =
+                    mInjector.getBluetoothAdapter().getBluetoothLeAdvertiser();
+            if (bluetoothLeAdvertiser != null) {
+                advertiseStarted = true;
+                AdvertiseSettings settings =
+                        new AdvertiseSettings.Builder()
+                                .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
+                                .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
+                                .setConnectable(true)
+                                .build();
+                AdvertiseData advertiseData =
+                        new AdvertiseData.Builder()
+                                .addServiceData(new ParcelUuid(PresenceConstants.PRESENCE_UUID),
+                                        advertisementPackets).build();
+
+                try {
+                    mBroadcastListener = listener;
+                    bluetoothLeAdvertiser.startAdvertising(settings, advertiseData, this);
+                } catch (NullPointerException | IllegalStateException | SecurityException e) {
+                    advertiseStarted = false;
+                }
+            }
+        }
+        if (!advertiseStarted) {
+            listener.onStatusChanged(BroadcastCallback.STATUS_FAILURE);
+        }
+    }
+
+    void stop() {
+        if (mIsAdvertising) {
+            BluetoothAdapter adapter = mInjector.getBluetoothAdapter();
+            if (adapter != null) {
+                BluetoothLeAdvertiser bluetoothLeAdvertiser =
+                        mInjector.getBluetoothAdapter().getBluetoothLeAdvertiser();
+                if (bluetoothLeAdvertiser != null) {
+                    bluetoothLeAdvertiser.stopAdvertising(this);
+                }
+            }
+            mBroadcastListener = null;
+            mIsAdvertising = false;
+        }
+    }
+
+    @Override
+    public void onStartSuccess(AdvertiseSettings settingsInEffect) {
+        mExecutor.execute(() -> {
+            if (mBroadcastListener != null) {
+                mBroadcastListener.onStatusChanged(BroadcastCallback.STATUS_OK);
+            }
+            mIsAdvertising = true;
+        });
+    }
+
+    @Override
+    public void onStartFailure(int errorCode) {
+        if (mBroadcastListener != null) {
+            mBroadcastListener.onStatusChanged(BroadcastCallback.STATUS_FAILURE);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java b/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
new file mode 100644
index 0000000..db58476
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
@@ -0,0 +1,202 @@
+/*
+ * 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.server.nearby.provider;
+
+import static com.android.server.nearby.NearbyService.TAG;
+
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.content.Context;
+import android.nearby.NearbyDevice;
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.ScanRequest;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import com.android.server.nearby.common.bluetooth.fastpair.Constants;
+import com.android.server.nearby.injector.Injector;
+import com.android.server.nearby.presence.PresenceConstants;
+import com.android.server.nearby.util.ForegroundThread;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * Discovery provider that uses Bluetooth Low Energy to do scanning.
+ */
+public class BleDiscoveryProvider extends AbstractDiscoveryProvider {
+
+    @VisibleForTesting
+    static final ParcelUuid FAST_PAIR_UUID = new ParcelUuid(Constants.FastPairService.ID);
+    private static final ParcelUuid PRESENCE_UUID = new ParcelUuid(PresenceConstants.PRESENCE_UUID);
+
+    // Don't block the thread as it may be used by other services.
+    private static final Executor NEARBY_EXECUTOR = ForegroundThread.getExecutor();
+    private final Injector mInjector;
+    private android.bluetooth.le.ScanCallback mScanCallback =
+            new android.bluetooth.le.ScanCallback() {
+                @Override
+                public void onScanResult(int callbackType, ScanResult scanResult) {
+                    NearbyDeviceParcelable.Builder builder = new NearbyDeviceParcelable.Builder();
+                    builder.setMedium(NearbyDevice.Medium.BLE)
+                            .setRssi(scanResult.getRssi())
+                            .setTxPower(scanResult.getTxPower())
+                            .setBluetoothAddress(scanResult.getDevice().getAddress());
+
+                    ScanRecord record = scanResult.getScanRecord();
+                    if (record != null) {
+                        String deviceName = record.getDeviceName();
+                        if (deviceName != null) {
+                            builder.setName(record.getDeviceName());
+                        }
+                        Map<ParcelUuid, byte[]> serviceDataMap = record.getServiceData();
+                        byte[] fastPairData = serviceDataMap.get(FAST_PAIR_UUID);
+                        if (fastPairData != null) {
+                            builder.setData(serviceDataMap.get(FAST_PAIR_UUID));
+                        } else {
+                            byte [] presenceData = serviceDataMap.get(PRESENCE_UUID);
+                            if (presenceData != null) {
+                                builder.setData(serviceDataMap.get(PRESENCE_UUID));
+                            }
+                        }
+                    }
+                    mExecutor.execute(() -> mListener.onNearbyDeviceDiscovered(builder.build()));
+                }
+
+                @Override
+                public void onScanFailed(int errorCode) {
+                    Log.w(TAG, "BLE Scan failed with error code " + errorCode);
+                }
+            };
+
+    public BleDiscoveryProvider(Context context, Injector injector) {
+        super(context, NEARBY_EXECUTOR);
+        mInjector = injector;
+    }
+
+    private static List<ScanFilter> getScanFilters() {
+        List<ScanFilter> scanFilterList = new ArrayList<>();
+        scanFilterList.add(
+                new ScanFilter.Builder()
+                        .setServiceData(FAST_PAIR_UUID, new byte[]{0}, new byte[]{0})
+                        .build());
+        return scanFilterList;
+    }
+
+    private boolean isBleAvailable() {
+        BluetoothAdapter adapter = mInjector.getBluetoothAdapter();
+        if (adapter == null) {
+            return false;
+        }
+
+        return adapter.getBluetoothLeScanner() != null;
+    }
+
+    @Nullable
+    private BluetoothLeScanner getBleScanner() {
+        BluetoothAdapter adapter = mInjector.getBluetoothAdapter();
+        if (adapter == null) {
+            return null;
+        }
+        return adapter.getBluetoothLeScanner();
+    }
+
+    @Override
+    protected void onStart() {
+        if (isBleAvailable()) {
+            Log.d(TAG, "BleDiscoveryProvider started.");
+            startScan(getScanFilters(), getScanSettings(), mScanCallback);
+            return;
+        }
+        Log.w(TAG, "Cannot start BleDiscoveryProvider because Ble is not available.");
+        mController.stop();
+    }
+
+    @Override
+    protected void onStop() {
+        BluetoothLeScanner bluetoothLeScanner = getBleScanner();
+        if (bluetoothLeScanner == null) {
+            Log.w(TAG, "BleDiscoveryProvider failed to stop BLE scanning "
+                    + "because BluetoothLeScanner is null.");
+            return;
+        }
+        bluetoothLeScanner.stopScan(mScanCallback);
+    }
+
+    @Override
+    protected void invalidateScanMode() {
+        onStop();
+        onStart();
+    }
+
+    private void startScan(
+            List<ScanFilter> scanFilters, ScanSettings scanSettings,
+            android.bluetooth.le.ScanCallback scanCallback) {
+        try {
+            BluetoothLeScanner bluetoothLeScanner = getBleScanner();
+            if (bluetoothLeScanner == null) {
+                Log.w(TAG, "BleDiscoveryProvider failed to start BLE scanning "
+                        + "because BluetoothLeScanner is null.");
+                return;
+            }
+            bluetoothLeScanner.startScan(scanFilters, scanSettings, scanCallback);
+        } catch (NullPointerException | IllegalStateException | SecurityException e) {
+            // NullPointerException:
+            //   - Commonly, on Blackberry devices. b/73299795
+            //   - Rarely, on other devices. b/75285249
+            // IllegalStateException:
+            // Caused if we call BluetoothLeScanner.startScan() after Bluetooth has turned off.
+            // SecurityException:
+            // refer to b/177380884
+            Log.w(TAG, "BleDiscoveryProvider failed to start BLE scanning.", e);
+        }
+    }
+
+    private ScanSettings getScanSettings() {
+        int bleScanMode = ScanSettings.SCAN_MODE_LOW_POWER;
+        switch (mController.getProviderScanMode()) {
+            case ScanRequest.SCAN_MODE_LOW_LATENCY:
+                bleScanMode = ScanSettings.SCAN_MODE_LOW_LATENCY;
+                break;
+            case ScanRequest.SCAN_MODE_BALANCED:
+                bleScanMode = ScanSettings.SCAN_MODE_BALANCED;
+                break;
+            case ScanRequest.SCAN_MODE_LOW_POWER:
+                bleScanMode = ScanSettings.SCAN_MODE_LOW_POWER;
+                break;
+            case ScanRequest.SCAN_MODE_NO_POWER:
+                bleScanMode = ScanSettings.SCAN_MODE_OPPORTUNISTIC;
+                break;
+        }
+        return new ScanSettings.Builder().setScanMode(bleScanMode).build();
+    }
+
+    @VisibleForTesting
+    ScanCallback getScanCallback() {
+        return mScanCallback;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/BroadcastProviderManager.java b/nearby/service/java/com/android/server/nearby/provider/BroadcastProviderManager.java
new file mode 100644
index 0000000..72fe29a
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/BroadcastProviderManager.java
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import android.content.Context;
+import android.nearby.BroadcastCallback;
+import android.nearby.BroadcastRequest;
+import android.nearby.IBroadcastListener;
+import android.nearby.PresenceBroadcastRequest;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.nearby.NearbyConfiguration;
+import com.android.server.nearby.injector.Injector;
+import com.android.server.nearby.presence.FastAdvertisement;
+import com.android.server.nearby.util.ForegroundThread;
+
+import java.util.concurrent.Executor;
+
+/**
+ * A manager for nearby broadcasts.
+ */
+public class BroadcastProviderManager implements BleBroadcastProvider.BroadcastListener {
+
+    private static final String TAG = "BroadcastProvider";
+
+    private final Object mLock;
+    private final BleBroadcastProvider mBleBroadcastProvider;
+    private final Executor mExecutor;
+    private final NearbyConfiguration mNearbyConfiguration;
+
+    private IBroadcastListener mBroadcastListener;
+
+    public BroadcastProviderManager(Context context, Injector injector) {
+        this(ForegroundThread.getExecutor(),
+                new BleBroadcastProvider(injector, ForegroundThread.getExecutor()));
+    }
+
+    @VisibleForTesting
+    BroadcastProviderManager(Executor executor, BleBroadcastProvider bleBroadcastProvider) {
+        mExecutor = executor;
+        mBleBroadcastProvider = bleBroadcastProvider;
+        mLock = new Object();
+        mNearbyConfiguration = new NearbyConfiguration();
+        mBroadcastListener = null;
+    }
+
+    /**
+     * Starts a nearby broadcast, the callback is sent through the given listener.
+     */
+    public void startBroadcast(BroadcastRequest broadcastRequest, IBroadcastListener listener) {
+        synchronized (mLock) {
+            NearbyConfiguration configuration = new NearbyConfiguration();
+            if (!configuration.isPresenceBroadcastLegacyEnabled()) {
+                reportBroadcastStatus(listener, BroadcastCallback.STATUS_FAILURE);
+                return;
+            }
+            if (broadcastRequest.getType() != BroadcastRequest.BROADCAST_TYPE_NEARBY_PRESENCE) {
+                reportBroadcastStatus(listener, BroadcastCallback.STATUS_FAILURE);
+                return;
+            }
+            PresenceBroadcastRequest presenceBroadcastRequest =
+                    (PresenceBroadcastRequest) broadcastRequest;
+            if (presenceBroadcastRequest.getVersion() != BroadcastRequest.PRESENCE_VERSION_V0) {
+                reportBroadcastStatus(listener, BroadcastCallback.STATUS_FAILURE);
+                return;
+            }
+            FastAdvertisement fastAdvertisement = FastAdvertisement.createFromRequest(
+                    presenceBroadcastRequest);
+            byte[] advertisementPackets = fastAdvertisement.toBytes();
+            mBroadcastListener = listener;
+            mExecutor.execute(() -> {
+                mBleBroadcastProvider.start(advertisementPackets, this);
+            });
+        }
+    }
+
+    /**
+     * Stops the nearby broadcast.
+     */
+    public void stopBroadcast(IBroadcastListener listener) {
+        synchronized (mLock) {
+            if (!mNearbyConfiguration.isPresenceBroadcastLegacyEnabled()) {
+                reportBroadcastStatus(listener, BroadcastCallback.STATUS_FAILURE);
+                return;
+            }
+            mBroadcastListener = null;
+            mExecutor.execute(() -> mBleBroadcastProvider.stop());
+        }
+    }
+
+    @Override
+    public void onStatusChanged(int status) {
+        IBroadcastListener listener = null;
+        synchronized (mLock) {
+            listener = mBroadcastListener;
+        }
+        // Don't invoke callback while holding the local lock, as this could cause deadlock.
+        if (listener != null) {
+            reportBroadcastStatus(listener, status);
+        }
+    }
+
+    private void reportBroadcastStatus(IBroadcastListener listener, int status) {
+        try {
+            listener.onStatusChanged(status);
+        } catch (RemoteException exception) {
+            Log.e(TAG, "remote exception when reporting status");
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/ChreCommunication.java b/nearby/service/java/com/android/server/nearby/provider/ChreCommunication.java
new file mode 100644
index 0000000..607c579
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/ChreCommunication.java
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import static com.android.server.nearby.NearbyService.TAG;
+
+import android.annotation.Nullable;
+import android.hardware.location.ContextHubClient;
+import android.hardware.location.ContextHubClientCallback;
+import android.hardware.location.ContextHubInfo;
+import android.hardware.location.ContextHubTransaction;
+import android.hardware.location.NanoAppMessage;
+import android.hardware.location.NanoAppState;
+import android.util.Log;
+
+import com.android.server.nearby.injector.ContextHubManagerAdapter;
+import com.android.server.nearby.injector.Injector;
+
+import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+/**
+ * Responsible for setting up communication with the appropriate contexthub on the device and
+ * handling nanoapp messages to / from it.
+ */
+public class ChreCommunication extends ContextHubClientCallback {
+
+    /** Callback that receives messages forwarded from the context hub. */
+    public interface ContextHubCommsCallback {
+        /** Indicates whether {@link ChreCommunication} was started successfully. */
+        void started(boolean success);
+
+        /** Indicates the ContextHub has been restarted. */
+        void onHubReset();
+
+        /**
+         * Indicates the given {@code nanoAppId} has been restarted. Either via code download or by
+         * being enabled by CHRE.
+         */
+        void onNanoAppRestart(long nanoAppId);
+
+        /** Indicates a new {@link NanoAppMessage} has been received. */
+        void onMessageFromNanoApp(NanoAppMessage message);
+    }
+
+    private final Injector mInjector;
+    private final Executor mExecutor;
+
+    private boolean mStarted = false;
+    @Nullable private ContextHubCommsCallback mCallback;
+    @Nullable private ContextHubClient mContextHubClient;
+
+    public ChreCommunication(Injector injector, Executor executor) {
+        mInjector = injector;
+        mExecutor = executor;
+    }
+
+    public boolean available() {
+        return mInjector.getContextHubManagerAdapter() != null;
+    }
+
+    /**
+     * Starts communication with the contexthub. This will invoke {@link
+     * ContextHubCommsCallback#start(boolean)} on completion.
+     *
+     * @param nanoAppIds - List of IDs that must have at least one match inside the chosen
+     *     contexthub.
+     */
+    public synchronized void start(ContextHubCommsCallback callback, Set<Long> nanoAppIds) {
+        ContextHubManagerAdapter manager = mInjector.getContextHubManagerAdapter();
+        if (manager == null) {
+            Log.e(TAG, "ContexHub not available in this device");
+            return;
+        } else {
+            Log.i(TAG, "Start ChreCommunication");
+        }
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkArgument(!nanoAppIds.isEmpty());
+        if (mStarted) {
+            Log.i(TAG, "ChreCommunication already started");
+            this.mCallback.started(true);
+            return;
+        }
+
+        // Use this to indicate whether stop was called before the transaction below
+        // completes.
+        mStarted = true;
+        this.mCallback = callback;
+
+        List<ContextHubInfo> contextHubs = manager.getContextHubs();
+
+        // Make a copy of the list so we can modify it during our async callbacks (in case the code
+        // is still iterating)
+        List<ContextHubInfo> validContextHubs = new ArrayList<>(contextHubs);
+
+        for (ContextHubInfo info : contextHubs) {
+            ContextHubTransaction<List<NanoAppState>> transaction = manager.queryNanoApps(info);
+            Log.i(TAG, "After query Nano Apps ");
+            transaction.setOnCompleteListener(
+                    new OnQueryCompleteListener(info, validContextHubs, nanoAppIds, manager),
+                    mExecutor);
+        }
+    }
+
+    /**
+     * Closes the connection to the {@link ContextHub} chosen during start.
+     *
+     * <p>NOTE: Do not invoke any other methods on this class after this returns.
+     */
+    public synchronized void stop() {
+        if (!mStarted) {
+            return;
+        }
+        mStarted = false;
+        if (mContextHubClient != null) {
+            mContextHubClient.close();
+            mContextHubClient = null;
+        }
+    }
+
+    /** Sends a {@link NanoAppMessage} to Context Hub Nearby nanoapp. */
+    public synchronized boolean sendMessageToNanoApp(NanoAppMessage message) {
+        if (mContextHubClient == null) {
+            Log.i(TAG, "Error sending message to nanoapp, contextHubClient is null");
+            return false;
+        }
+        int result = mContextHubClient.sendMessageToNanoApp(message);
+        if (result != ContextHubTransaction.RESULT_SUCCESS) {
+            Log.i(
+                    TAG,
+                    String.format(
+                            Locale.getDefault(),
+                            "Error sending message to nanoapp: %s",
+                            contextHubTransactionResultToString(result)));
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public synchronized void onMessageFromNanoApp(ContextHubClient client, NanoAppMessage message) {
+        mCallback.onMessageFromNanoApp(message);
+    }
+
+    @Override
+    public synchronized void onHubReset(ContextHubClient client) {
+        mCallback.onHubReset();
+    }
+
+    @Override
+    public synchronized void onNanoAppLoaded(ContextHubClient client, long nanoAppId) {
+        Log.i(TAG, String.format("Nanoapp ID loaded: %s", nanoAppId));
+        mCallback.onNanoAppRestart(nanoAppId);
+    }
+
+    private static String contextHubTransactionResultToString(int result) {
+        switch (result) {
+            case ContextHubTransaction.RESULT_SUCCESS:
+                return "RESULT_SUCCESS";
+            case ContextHubTransaction.RESULT_FAILED_UNKNOWN:
+                return "RESULT_FAILED_UNKNOWN";
+            case ContextHubTransaction.RESULT_FAILED_BAD_PARAMS:
+                return "RESULT_FAILED_BAD_PARAMS";
+            case ContextHubTransaction.RESULT_FAILED_UNINITIALIZED:
+                return "RESULT_FAILED_UNINITIALIZED";
+            case ContextHubTransaction.RESULT_FAILED_BUSY:
+                return "RESULT_FAILED_BUSY";
+            case ContextHubTransaction.RESULT_FAILED_AT_HUB:
+                return "RESULT_FAILED_AT_HUB";
+            case ContextHubTransaction.RESULT_FAILED_TIMEOUT:
+                return "RESULT_FAILED_TIMEOUT";
+            case ContextHubTransaction.RESULT_FAILED_SERVICE_INTERNAL_FAILURE:
+                return "RESULT_FAILED_SERVICE_INTERNAL_FAILURE";
+            case ContextHubTransaction.RESULT_FAILED_HAL_UNAVAILABLE:
+                return "RESULT_FAILED_HAL_UNAVAILABLE";
+            default:
+                return String.format(Locale.getDefault(), "UNKNOWN_RESULT value=%d", result);
+        }
+    }
+
+    /**
+     * Used when initializing the class to identify the appropriate {@link ContextHubInfo} to listen
+     * to.
+     */
+    class OnQueryCompleteListener
+            implements ContextHubTransaction.OnCompleteListener<List<NanoAppState>> {
+
+        private final ContextHubInfo mQueriedContextHub;
+        private final List<ContextHubInfo> mContextHubs;
+        private final Set<Long> mNanoAppIds;
+        private final ContextHubManagerAdapter mManager;
+
+        OnQueryCompleteListener(
+                ContextHubInfo queriedContextHub,
+                List<ContextHubInfo> contextHubs,
+                Set<Long> nanoAppIds,
+                ContextHubManagerAdapter manager) {
+            this.mQueriedContextHub = queriedContextHub;
+            this.mContextHubs = contextHubs;
+            this.mNanoAppIds = nanoAppIds;
+            this.mManager = manager;
+        }
+
+        @Override
+        public void onComplete(
+                ContextHubTransaction<List<NanoAppState>> transaction,
+                ContextHubTransaction.Response<List<NanoAppState>> response) {
+            Log.i(TAG, "query nano app onComplete");
+            // Ensure the class hasn't found a client already or stop hasn't been called before
+            // the transaction completed to avoid messing with state.
+            if (mContextHubClient != null || !mStarted) {
+                return;
+            }
+
+            if (response.getResult() == ContextHubTransaction.RESULT_SUCCESS) {
+                for (NanoAppState state : response.getContents()) {
+                    if (mNanoAppIds.contains(state.getNanoAppId())) {
+                        Log.i(
+                                TAG,
+                                String.format(
+                                        "Found valid contexthub: %s", mQueriedContextHub.getId()));
+                        mContextHubClient =
+                                mManager.createClient(
+                                        mQueriedContextHub, ChreCommunication.this, mExecutor);
+                        mCallback.started(true);
+                        return;
+                    }
+                }
+                Log.e(
+                        TAG,
+                        String.format(
+                                "Didn't find the nanoapp on contexthub: %s",
+                                mQueriedContextHub.getId()));
+            } else {
+                Log.e(
+                        TAG,
+                        String.format(
+                                "Failed to communicate with contexthub: %s",
+                                mQueriedContextHub.getId()));
+            }
+
+            mContextHubs.remove(mQueriedContextHub);
+            // If this is the last context hub response left to receive, indicate that
+            // there isn't a valid context available on this device.
+            if (mContextHubs.isEmpty()) {
+                mCallback.started(false);
+            }
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java b/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
new file mode 100644
index 0000000..a70ef13
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import static android.nearby.ScanRequest.SCAN_TYPE_NEARBY_PRESENCE;
+
+import static com.android.server.nearby.NearbyService.TAG;
+
+import android.content.Context;
+import android.hardware.location.NanoAppMessage;
+import android.nearby.NearbyDevice;
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
+import android.nearby.ScanFilter;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import service.proto.Blefilter;
+
+import java.util.Collections;
+import java.util.concurrent.Executor;
+
+/** Discovery provider that uses CHRE Nearby Nanoapp to do scanning. */
+public class ChreDiscoveryProvider extends AbstractDiscoveryProvider {
+    // Nanoapp ID reserved for Nearby Presence.
+    /** @hide */
+    @VisibleForTesting public static final long NANOAPP_ID = 0x476f6f676c001031L;
+    /** @hide */
+    @VisibleForTesting public static final int NANOAPP_MESSAGE_TYPE_FILTER = 3;
+    /** @hide */
+    @VisibleForTesting public static final int NANOAPP_MESSAGE_TYPE_FILTER_RESULT = 4;
+
+    private static final int PRESENCE_UUID = 0xFCF1;
+
+    private ChreCommunication mChreCommunication;
+    private ChreCallback mChreCallback;
+    private boolean mChreStarted = false;
+    private Blefilter.BleFilters mFilters = null;
+    private int mFilterId;
+
+    public ChreDiscoveryProvider(
+            Context context, ChreCommunication chreCommunication, Executor executor) {
+        super(context, executor);
+        mChreCommunication = chreCommunication;
+        mChreCallback = new ChreCallback();
+        mFilterId = 0;
+    }
+
+    @Override
+    protected void onStart() {
+        Log.d(TAG, "Start CHRE scan");
+        mChreCommunication.start(mChreCallback, Collections.singleton(NANOAPP_ID));
+        updateFilters();
+    }
+
+    @Override
+    protected void onStop() {
+        mChreStarted = false;
+        mChreCommunication.stop();
+    }
+
+    @Override
+    protected void invalidateScanMode() {
+        onStop();
+        onStart();
+    }
+
+    public boolean available() {
+        return mChreCommunication.available();
+    }
+
+    private synchronized void updateFilters() {
+        if (mScanFilters == null) {
+            Log.e(TAG, "ScanFilters not set.");
+            return;
+        }
+        Blefilter.BleFilters.Builder filtersBuilder = Blefilter.BleFilters.newBuilder();
+        for (ScanFilter scanFilter : mScanFilters) {
+            PresenceScanFilter presenceScanFilter = (PresenceScanFilter) scanFilter;
+            Blefilter.BleFilter filter =
+                    Blefilter.BleFilter.newBuilder()
+                            .setId(mFilterId)
+                            .setUuid(PRESENCE_UUID)
+                            .setIntent(presenceScanFilter.getPresenceActions().get(0))
+                            .build();
+            filtersBuilder.addFilter(filter);
+            mFilterId++;
+        }
+        mFilters = filtersBuilder.build();
+        if (mChreStarted) {
+            sendFilters(mFilters);
+            mFilters = null;
+        }
+    }
+
+    private void sendFilters(Blefilter.BleFilters filters) {
+        NanoAppMessage message =
+                NanoAppMessage.createMessageToNanoApp(
+                        NANOAPP_ID, NANOAPP_MESSAGE_TYPE_FILTER, filters.toByteArray());
+        if (!mChreCommunication.sendMessageToNanoApp(message)) {
+            Log.e(TAG, "Failed to send filters to CHRE.");
+        }
+    }
+
+    private class ChreCallback implements ChreCommunication.ContextHubCommsCallback {
+
+        @Override
+        public void started(boolean success) {
+            if (success) {
+                synchronized (ChreDiscoveryProvider.this) {
+                    Log.i(TAG, "CHRE communication started");
+                    mChreStarted = true;
+                    if (mFilters != null) {
+                        sendFilters(mFilters);
+                        mFilters = null;
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onHubReset() {
+            // TODO(b/221082271): hooked with upper level codes.
+            Log.i(TAG, "CHRE reset.");
+        }
+
+        @Override
+        public void onNanoAppRestart(long nanoAppId) {
+            // TODO(b/221082271): hooked with upper level codes.
+            Log.i(TAG, String.format("CHRE NanoApp %d restart.", nanoAppId));
+        }
+
+        @Override
+        public void onMessageFromNanoApp(NanoAppMessage message) {
+            if (message.getNanoAppId() != NANOAPP_ID) {
+                Log.e(TAG, "Received message from unknown nano app.");
+                return;
+            }
+            if (mListener == null) {
+                Log.e(TAG, "the listener is not set in ChreDiscoveryProvider.");
+                return;
+            }
+            if (message.getMessageType() == NANOAPP_MESSAGE_TYPE_FILTER_RESULT) {
+                try {
+                    Blefilter.BleFilterResults results =
+                            Blefilter.BleFilterResults.parseFrom(message.getMessageBody());
+                    for (Blefilter.BleFilterResult filterResult : results.getResultList()) {
+                        Blefilter.PublicCredential credential = filterResult.getPublicCredential();
+                        PublicCredential publicCredential =
+                                new PublicCredential.Builder(
+                                                credential.getSecretId().toByteArray(),
+                                                credential.getAuthenticityKey().toByteArray(),
+                                                credential.getPublicKey().toByteArray(),
+                                                credential.getEncryptedMetadata().toByteArray(),
+                                                credential.getEncryptedMetadataTag().toByteArray())
+                                        .build();
+                        NearbyDeviceParcelable device =
+                                new NearbyDeviceParcelable.Builder()
+                                        .setScanType(SCAN_TYPE_NEARBY_PRESENCE)
+                                        .setMedium(NearbyDevice.Medium.BLE)
+                                        .setTxPower(filterResult.getTxPower())
+                                        .setRssi(filterResult.getRssi())
+                                        .setAction(filterResult.getIntent())
+                                        .setPublicCredential(publicCredential)
+                                        .build();
+                        mExecutor.execute(() -> mListener.onNearbyDeviceDiscovered(device));
+                    }
+                } catch (InvalidProtocolBufferException e) {
+                    Log.e(
+                            TAG,
+                            String.format("Failed to decode the filter result %s", e.toString()));
+                }
+            }
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderController.java b/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderController.java
new file mode 100644
index 0000000..fa1a874
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderController.java
@@ -0,0 +1,59 @@
+/*
+ * 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.server.nearby.provider;
+
+import android.annotation.Nullable;
+import android.nearby.ScanFilter;
+import android.nearby.ScanRequest;
+
+import java.util.List;
+
+/** Interface for controlling discovery providers. */
+interface DiscoveryProviderController {
+
+    /**
+     * Sets the listener which can expect to receive all state updates from after this point. May be
+     * invoked at any time.
+     */
+    void setListener(@Nullable AbstractDiscoveryProvider.Listener listener);
+
+    /** Returns true if in the started state. */
+    boolean isStarted();
+
+    /**
+     * Starts the discovery provider. Must be invoked before any other method (except {@link
+     * #setListener(AbstractDiscoveryProvider.Listener)} (Listener)}).
+     */
+    void start();
+
+    /**
+     * Stops the discovery provider. No other methods may be invoked after this method (except
+     * {@link #setListener(AbstractDiscoveryProvider.Listener)} (Listener)}), until {@link #start()}
+     * is called again.
+     */
+    void stop();
+
+    /** Sets the desired scan mode. */
+    void setProviderScanMode(@ScanRequest.ScanMode int scanMode);
+
+    /** Gets the controller scan mode. */
+    @ScanRequest.ScanMode
+    int getProviderScanMode();
+
+    /** Sets the scan filters. */
+    void setProviderScanFilters(List<ScanFilter> filters);
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderManager.java b/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderManager.java
new file mode 100644
index 0000000..af1c0b5
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/DiscoveryProviderManager.java
@@ -0,0 +1,299 @@
+/*
+ * 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.server.nearby.provider;
+
+import static android.nearby.ScanRequest.SCAN_TYPE_NEARBY_PRESENCE;
+
+import static com.android.server.nearby.NearbyService.TAG;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.nearby.IScanListener;
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.PresenceScanFilter;
+import android.nearby.ScanFilter;
+import android.nearby.ScanRequest;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.nearby.injector.Injector;
+import com.android.server.nearby.metrics.NearbyMetrics;
+import com.android.server.nearby.presence.PresenceDiscoveryResult;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+
+/** Manages all aspects of discovery providers. */
+public class DiscoveryProviderManager implements AbstractDiscoveryProvider.Listener {
+
+    protected final Object mLock = new Object();
+    private final Context mContext;
+    private final BleDiscoveryProvider mBleDiscoveryProvider;
+    @Nullable private final ChreDiscoveryProvider mChreDiscoveryProvider;
+    private @ScanRequest.ScanMode int mScanMode;
+
+    @GuardedBy("mLock")
+    private Map<IBinder, ScanListenerRecord> mScanTypeScanListenerRecordMap;
+
+    @Override
+    public void onNearbyDeviceDiscovered(NearbyDeviceParcelable nearbyDevice) {
+        synchronized (mLock) {
+            for (IBinder listenerBinder : mScanTypeScanListenerRecordMap.keySet()) {
+                ScanListenerRecord record = mScanTypeScanListenerRecordMap.get(listenerBinder);
+                if (record == null) {
+                    Log.w(TAG, "DiscoveryProviderManager cannot find the scan record.");
+                    continue;
+                }
+                if (nearbyDevice.getScanType() == SCAN_TYPE_NEARBY_PRESENCE) {
+                    List<ScanFilter> presenceFilters =
+                            record.getScanRequest().getScanFilters().stream()
+                                    .filter(
+                                            scanFilter ->
+                                                    scanFilter.getType()
+                                                            == SCAN_TYPE_NEARBY_PRESENCE)
+                                    .collect(Collectors.toList());
+                    Log.i(
+                            TAG,
+                            String.format("match with filters size: %d", presenceFilters.size()));
+                    if (!presenceFilterMatches(nearbyDevice, presenceFilters)) {
+                        continue;
+                    }
+                }
+                try {
+                    record.getScanListener()
+                            .onDiscovered(
+                                    PrivacyFilter.filter(
+                                            record.getScanRequest().getScanType(), nearbyDevice));
+                    NearbyMetrics.logScanDeviceDiscovered(
+                            record.hashCode(), record.getScanRequest(), nearbyDevice);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "DiscoveryProviderManager failed to report onDiscovered.", e);
+                }
+            }
+        }
+    }
+
+    public DiscoveryProviderManager(Context context, Injector injector) {
+        mContext = context;
+        mBleDiscoveryProvider = new BleDiscoveryProvider(mContext, injector);
+        Executor executor = Executors.newSingleThreadExecutor();
+        mChreDiscoveryProvider =
+                new ChreDiscoveryProvider(
+                        mContext, new ChreCommunication(injector, executor), executor);
+        mScanTypeScanListenerRecordMap = new HashMap<>();
+    }
+
+    /**
+     * Registers the listener in the manager and starts scan according to the requested scan mode.
+     */
+    public boolean registerScanListener(ScanRequest scanRequest, IScanListener listener) {
+        Log.i(TAG, "DiscoveryProviderManager registerScanListener");
+        synchronized (mLock) {
+            IBinder listenerBinder = listener.asBinder();
+            if (mScanTypeScanListenerRecordMap.containsKey(listener.asBinder())) {
+                ScanRequest savedScanRequest =
+                        mScanTypeScanListenerRecordMap.get(listenerBinder).getScanRequest();
+                if (scanRequest.equals(savedScanRequest)) {
+                    Log.d(TAG, "Already registered the scanRequest: " + scanRequest);
+                    return true;
+                }
+            }
+            ScanListenerRecord scanListenerRecord = new ScanListenerRecord(scanRequest, listener);
+            mScanTypeScanListenerRecordMap.put(listenerBinder, scanListenerRecord);
+
+            if (!startProviders(scanRequest)) {
+                return false;
+            }
+
+            NearbyMetrics.logScanStarted(scanListenerRecord.hashCode(), scanRequest);
+            if (mScanMode < scanRequest.getScanMode()) {
+                mScanMode = scanRequest.getScanMode();
+                invalidateProviderScanMode();
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Unregisters the listener in the manager and adjusts the scan mode if necessary afterwards.
+     */
+    public void unregisterScanListener(IScanListener listener) {
+        IBinder listenerBinder = listener.asBinder();
+        synchronized (mLock) {
+            if (!mScanTypeScanListenerRecordMap.containsKey(listenerBinder)) {
+                Log.w(
+                        TAG,
+                        "Cannot unregister the scanRequest because the request is never "
+                                + "registered.");
+                return;
+            }
+
+            ScanListenerRecord removedRecord =
+                    mScanTypeScanListenerRecordMap.remove(listenerBinder);
+            NearbyMetrics.logScanStopped(removedRecord.hashCode(), removedRecord.getScanRequest());
+            if (mScanTypeScanListenerRecordMap.isEmpty()) {
+                stopProviders();
+                return;
+            }
+
+            // TODO(b/221082271): updates the scan with reduced filters.
+
+            // Removes current highest scan mode requested and sets the next highest scan mode.
+            if (removedRecord.getScanRequest().getScanMode() == mScanMode) {
+                @ScanRequest.ScanMode int highestScanModeRequested = ScanRequest.SCAN_MODE_NO_POWER;
+                // find the next highest scan mode;
+                for (ScanListenerRecord record : mScanTypeScanListenerRecordMap.values()) {
+                    @ScanRequest.ScanMode int scanMode = record.getScanRequest().getScanMode();
+                    if (scanMode > highestScanModeRequested) {
+                        highestScanModeRequested = scanMode;
+                    }
+                }
+                if (mScanMode != highestScanModeRequested) {
+                    mScanMode = highestScanModeRequested;
+                    invalidateProviderScanMode();
+                }
+            }
+        }
+    }
+
+    // Returns false when fail to start all the providers. Returns true if any one of the provider
+    // starts successfully.
+    private boolean startProviders(ScanRequest scanRequest) {
+        if (scanRequest.isBleEnabled()) {
+            if (mChreDiscoveryProvider.available()) {
+                startChreProvider();
+                return true;
+            } else {
+                startBleProvider(scanRequest);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void startBleProvider(ScanRequest scanRequest) {
+        if (!mBleDiscoveryProvider.getController().isStarted()) {
+            Log.d(TAG, "DiscoveryProviderManager starts Ble scanning.");
+            mBleDiscoveryProvider.getController().start();
+            mBleDiscoveryProvider.getController().setListener(this);
+            mBleDiscoveryProvider.getController().setProviderScanMode(scanRequest.getScanMode());
+        }
+    }
+
+    private void startChreProvider() {
+        Log.d(TAG, "DiscoveryProviderManager starts CHRE scanning.");
+        synchronized (mLock) {
+            mChreDiscoveryProvider.getController().setListener(this);
+            List<ScanFilter> scanFilters = new ArrayList();
+            for (IBinder listenerBinder : mScanTypeScanListenerRecordMap.keySet()) {
+                ScanListenerRecord record = mScanTypeScanListenerRecordMap.get(listenerBinder);
+                List<ScanFilter> presenceFilters =
+                        record.getScanRequest().getScanFilters().stream()
+                                .filter(
+                                        scanFilter ->
+                                                scanFilter.getType() == SCAN_TYPE_NEARBY_PRESENCE)
+                                .collect(Collectors.toList());
+                scanFilters.addAll(presenceFilters);
+            }
+            mChreDiscoveryProvider.getController().setProviderScanFilters(scanFilters);
+            mChreDiscoveryProvider.getController().setProviderScanMode(mScanMode);
+            mChreDiscoveryProvider.getController().start();
+        }
+    }
+
+    private void stopProviders() {
+        stopBleProvider();
+        stopChreProvider();
+    }
+
+    private void stopBleProvider() {
+        mBleDiscoveryProvider.getController().stop();
+    }
+
+    private void stopChreProvider() {
+        mChreDiscoveryProvider.getController().stop();
+    }
+
+    private void invalidateProviderScanMode() {
+        if (mBleDiscoveryProvider.getController().isStarted()) {
+            mBleDiscoveryProvider.getController().setProviderScanMode(mScanMode);
+        } else {
+            Log.d(
+                    TAG,
+                    "Skip invalidating BleDiscoveryProvider scan mode because the provider not "
+                            + "started.");
+        }
+    }
+
+    private static boolean presenceFilterMatches(
+            NearbyDeviceParcelable device, List<ScanFilter> scanFilters) {
+        if (scanFilters.isEmpty()) {
+            return true;
+        }
+        PresenceDiscoveryResult discoveryResult = PresenceDiscoveryResult.fromDevice(device);
+        for (ScanFilter scanFilter : scanFilters) {
+            PresenceScanFilter presenceScanFilter = (PresenceScanFilter) scanFilter;
+            if (discoveryResult.matches(presenceScanFilter)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static class ScanListenerRecord {
+
+        private final ScanRequest mScanRequest;
+
+        private final IScanListener mScanListener;
+
+        ScanListenerRecord(ScanRequest scanRequest, IScanListener iScanListener) {
+            mScanListener = iScanListener;
+            mScanRequest = scanRequest;
+        }
+
+        IScanListener getScanListener() {
+            return mScanListener;
+        }
+
+        ScanRequest getScanRequest() {
+            return mScanRequest;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof ScanListenerRecord) {
+                ScanListenerRecord otherScanListenerRecord = (ScanListenerRecord) other;
+                return Objects.equals(mScanRequest, otherScanListenerRecord.mScanRequest)
+                        && Objects.equals(mScanListener, otherScanListenerRecord.mScanListener);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mScanListener, mScanRequest);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java b/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
new file mode 100644
index 0000000..0f99a2f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
@@ -0,0 +1,199 @@
+/*
+ * 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.server.nearby.provider;
+
+import android.accounts.Account;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.nearby.FastPairDataProviderService;
+import android.nearby.aidl.ByteArrayParcel;
+import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel;
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataRequestParcel;
+import android.nearby.aidl.FastPairEligibleAccountsRequestParcel;
+import android.nearby.aidl.FastPairManageAccountDeviceRequestParcel;
+import android.nearby.aidl.FastPairManageAccountRequestParcel;
+import android.util.Log;
+
+import androidx.annotation.WorkerThread;
+
+import com.android.server.nearby.common.bloomfilter.BloomFilter;
+import com.android.server.nearby.fastpair.footprint.FastPairUploadInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import service.proto.Data;
+import service.proto.Rpcs;
+
+/**
+ * FastPairDataProvider is a singleton that implements APIs to get FastPair data.
+ */
+public class FastPairDataProvider {
+
+    private static final String TAG = "FastPairDataProvider";
+
+    private static FastPairDataProvider sInstance;
+
+    private ProxyFastPairDataProvider mProxyFastPairDataProvider;
+
+    /**
+     * Initializes FastPairDataProvider singleton.
+     */
+    public static synchronized FastPairDataProvider init(Context context) {
+        if (sInstance == null) {
+            sInstance = new FastPairDataProvider(context);
+        }
+        if (sInstance.mProxyFastPairDataProvider == null) {
+            Log.w(TAG, "no proxy fast pair data provider found");
+        } else {
+            sInstance.mProxyFastPairDataProvider.register();
+        }
+        return sInstance;
+    }
+
+    @Nullable
+    public static synchronized FastPairDataProvider getInstance() {
+        return sInstance;
+    }
+
+    private FastPairDataProvider(Context context) {
+        mProxyFastPairDataProvider = ProxyFastPairDataProvider.create(
+                context, FastPairDataProviderService.ACTION_FAST_PAIR_DATA_PROVIDER);
+        if (mProxyFastPairDataProvider == null) {
+            Log.d("FastPairService", "fail to initiate the fast pair proxy provider");
+        } else {
+            Log.d("FastPairService", "the fast pair proxy provider initiated");
+        }
+    }
+
+    /**
+     * Loads FastPairAntispoofKeyDeviceMetadata.
+     *
+     * @throws IllegalStateException If ProxyFastPairDataProvider is not available.
+     */
+    @WorkerThread
+    @Nullable
+    public Rpcs.GetObservedDeviceResponse loadFastPairAntispoofKeyDeviceMetadata(byte[] modelId) {
+        if (mProxyFastPairDataProvider != null) {
+            FastPairAntispoofKeyDeviceMetadataRequestParcel requestParcel =
+                    new FastPairAntispoofKeyDeviceMetadataRequestParcel();
+            requestParcel.modelId = modelId;
+            return Utils.convertToGetObservedDeviceResponse(
+                    mProxyFastPairDataProvider
+                            .loadFastPairAntispoofKeyDeviceMetadata(requestParcel));
+        }
+        throw new IllegalStateException("No ProxyFastPairDataProvider yet constructed");
+    }
+
+    /**
+     * Enrolls an account to Fast Pair.
+     *
+     * @throws IllegalStateException If ProxyFastPairDataProvider is not available.
+     */
+    public void optIn(Account account) {
+        if (mProxyFastPairDataProvider != null) {
+            FastPairManageAccountRequestParcel requestParcel =
+                    new FastPairManageAccountRequestParcel();
+            requestParcel.account = account;
+            requestParcel.requestType = FastPairDataProviderService.MANAGE_REQUEST_ADD;
+            mProxyFastPairDataProvider.manageFastPairAccount(requestParcel);
+            return;
+        }
+        throw new IllegalStateException("No ProxyFastPairDataProvider yet constructed");
+    }
+
+    /**
+     * Uploads the device info to Fast Pair account.
+     *
+     * @throws IllegalStateException If ProxyFastPairDataProvider is not available.
+     */
+    public void upload(Account account, FastPairUploadInfo uploadInfo) {
+        if (mProxyFastPairDataProvider != null) {
+            FastPairManageAccountDeviceRequestParcel requestParcel =
+                    new FastPairManageAccountDeviceRequestParcel();
+            requestParcel.account = account;
+            requestParcel.requestType = FastPairDataProviderService.MANAGE_REQUEST_ADD;
+            requestParcel.accountKeyDeviceMetadata =
+                    Utils.convertToFastPairAccountKeyDeviceMetadata(uploadInfo);
+            mProxyFastPairDataProvider.manageFastPairAccountDevice(requestParcel);
+            return;
+        }
+        throw new IllegalStateException("No ProxyFastPairDataProvider yet constructed");
+    }
+
+    /**
+     * Get recognized device from bloom filter.
+     */
+    public Data.FastPairDeviceWithAccountKey getRecognizedDevice(BloomFilter bloomFilter,
+            byte[] salt) {
+        return Data.FastPairDeviceWithAccountKey.newBuilder().build();
+    }
+
+    /**
+     * Loads FastPair device accountKeys for a given account, but not other detailed fields.
+     *
+     * @throws IllegalStateException If ProxyFastPairDataProvider is not available.
+     */
+    public List<Data.FastPairDeviceWithAccountKey> loadFastPairDeviceWithAccountKey(
+            Account account) {
+        return loadFastPairDeviceWithAccountKey(account, new ArrayList<byte[]>(0));
+    }
+
+    /**
+     * Loads FastPair devices for a list of accountKeys of a given account.
+     *
+     * @param account The account of the FastPair devices.
+     * @param deviceAccountKeys The allow list of FastPair devices if it is not empty. Otherwise,
+     *                    the function returns accountKeys of all FastPair devices under the
+     *                    account, without detailed fields.
+     *
+     * @throws IllegalStateException If ProxyFastPairDataProvider is not available.
+     */
+    public List<Data.FastPairDeviceWithAccountKey> loadFastPairDeviceWithAccountKey(
+            Account account, List<byte[]> deviceAccountKeys) {
+        if (mProxyFastPairDataProvider != null) {
+            FastPairAccountDevicesMetadataRequestParcel requestParcel =
+                    new FastPairAccountDevicesMetadataRequestParcel();
+            requestParcel.account = account;
+            requestParcel.deviceAccountKeys = new ByteArrayParcel[deviceAccountKeys.size()];
+            int i = 0;
+            for (byte[] deviceAccountKey : deviceAccountKeys) {
+                requestParcel.deviceAccountKeys[i] = new ByteArrayParcel();
+                requestParcel.deviceAccountKeys[i].byteArray = deviceAccountKey;
+                i = i + 1;
+            }
+            return Utils.convertToFastPairDevicesWithAccountKey(
+                    mProxyFastPairDataProvider.loadFastPairAccountDevicesMetadata(requestParcel));
+        }
+        throw new IllegalStateException("No ProxyFastPairDataProvider yet constructed");
+    }
+
+    /**
+     * Loads FastPair Eligible Accounts.
+     *
+     * @throws IllegalStateException If ProxyFastPairDataProvider is not available.
+     */
+    public List<Account> loadFastPairEligibleAccounts() {
+        if (mProxyFastPairDataProvider != null) {
+            FastPairEligibleAccountsRequestParcel requestParcel =
+                    new FastPairEligibleAccountsRequestParcel();
+            return Utils.convertToAccountList(
+                    mProxyFastPairDataProvider.loadFastPairEligibleAccounts(requestParcel));
+        }
+        throw new IllegalStateException("No ProxyFastPairDataProvider yet constructed");
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/PrivacyFilter.java b/nearby/service/java/com/android/server/nearby/provider/PrivacyFilter.java
new file mode 100644
index 0000000..5c37f68
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/PrivacyFilter.java
@@ -0,0 +1,37 @@
+/*
+ * 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.server.nearby.provider;
+
+import android.annotation.Nullable;
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.ScanRequest;
+
+/**
+ * Class strips out privacy sensitive data before delivering the callbacks to client.
+ */
+public class PrivacyFilter {
+
+    /**
+     * Strips sensitive data from {@link NearbyDeviceParcelable} according to
+     * different {@link android.nearby.ScanRequest.ScanType}s.
+     */
+    @Nullable
+    public static NearbyDeviceParcelable filter(@ScanRequest.ScanType int scanType,
+            NearbyDeviceParcelable scanResult) {
+        return scanResult;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/ProxyFastPairDataProvider.java b/nearby/service/java/com/android/server/nearby/provider/ProxyFastPairDataProvider.java
new file mode 100644
index 0000000..f0ade6c
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/ProxyFastPairDataProvider.java
@@ -0,0 +1,307 @@
+/*
+ * 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.server.nearby.provider;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel;
+import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataParcel;
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataRequestParcel;
+import android.nearby.aidl.FastPairEligibleAccountParcel;
+import android.nearby.aidl.FastPairEligibleAccountsRequestParcel;
+import android.nearby.aidl.FastPairManageAccountDeviceRequestParcel;
+import android.nearby.aidl.FastPairManageAccountRequestParcel;
+import android.nearby.aidl.IFastPairAccountDevicesMetadataCallback;
+import android.nearby.aidl.IFastPairAntispoofKeyDeviceMetadataCallback;
+import android.nearby.aidl.IFastPairDataProvider;
+import android.nearby.aidl.IFastPairEligibleAccountsCallback;
+import android.nearby.aidl.IFastPairManageAccountCallback;
+import android.nearby.aidl.IFastPairManageAccountDeviceCallback;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import androidx.annotation.WorkerThread;
+
+import com.android.server.nearby.common.servicemonitor.CurrentUserServiceProvider;
+import com.android.server.nearby.common.servicemonitor.CurrentUserServiceProvider.BoundServiceInfo;
+import com.android.server.nearby.common.servicemonitor.ServiceMonitor;
+import com.android.server.nearby.common.servicemonitor.ServiceMonitor.ServiceListener;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Proxy for IFastPairDataProvider implementations.
+ */
+public class ProxyFastPairDataProvider implements ServiceListener<BoundServiceInfo> {
+
+    private static final int TIME_OUT_MILLIS = 10000;
+
+    /**
+     * Creates and registers this proxy. If no suitable service is available for the proxy, returns
+     * null.
+     */
+    @Nullable
+    public static ProxyFastPairDataProvider create(Context context, String action) {
+        ProxyFastPairDataProvider proxy = new ProxyFastPairDataProvider(context, action);
+        if (proxy.checkServiceResolves()) {
+            return proxy;
+        } else {
+            return null;
+        }
+    }
+
+    private final ServiceMonitor mServiceMonitor;
+
+    private ProxyFastPairDataProvider(Context context, String action) {
+        // safe to use direct executor since our locks are not acquired in a code path invoked by
+        // our owning provider
+
+        mServiceMonitor = ServiceMonitor.create(context, "FAST_PAIR_DATA_PROVIDER",
+                CurrentUserServiceProvider.create(context, action), this);
+    }
+
+    private boolean checkServiceResolves() {
+        return mServiceMonitor.checkServiceResolves();
+    }
+
+    /**
+     * User service watch to connect to actually services implemented by OEMs.
+     */
+    public void register() {
+        mServiceMonitor.register();
+    }
+
+    // Fast Pair Data Provider doesn't maintain a long running state.
+    // Therefore, it doesn't need setup at bind time.
+    @Override
+    public void onBind(IBinder binder, BoundServiceInfo boundServiceInfo) throws RemoteException {
+    }
+
+    // Fast Pair Data Provider doesn't maintain a long running state.
+    // Therefore, it doesn't need tear down at unbind time.
+    @Override
+    public void onUnbind() {
+    }
+
+    /**
+     * Invokes system api loadFastPairEligibleAccounts.
+     *
+     * @return an array of acccounts and their opt in status.
+     */
+    @WorkerThread
+    @Nullable
+    public FastPairEligibleAccountParcel[] loadFastPairEligibleAccounts(
+            FastPairEligibleAccountsRequestParcel requestParcel) {
+        final CountDownLatch waitForCompletionLatch = new CountDownLatch(1);
+        final AtomicReference<FastPairEligibleAccountParcel[]> response = new AtomicReference<>();
+        mServiceMonitor.runOnBinder(new ServiceMonitor.BinderOperation() {
+            @Override
+            public void run(IBinder binder) throws RemoteException {
+                IFastPairDataProvider provider = IFastPairDataProvider.Stub.asInterface(binder);
+                IFastPairEligibleAccountsCallback callback =
+                        new IFastPairEligibleAccountsCallback.Stub() {
+                            public void onFastPairEligibleAccountsReceived(
+                                    FastPairEligibleAccountParcel[] accountParcels) {
+                                response.set(accountParcels);
+                                waitForCompletionLatch.countDown();
+                            }
+
+                            public void onError(int code, String message) {
+                                waitForCompletionLatch.countDown();
+                            }
+                        };
+                provider.loadFastPairEligibleAccounts(requestParcel, callback);
+            }
+
+            @Override
+            public void onError() {
+                waitForCompletionLatch.countDown();
+            }
+        });
+        try {
+            waitForCompletionLatch.await(TIME_OUT_MILLIS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            // skip.
+        }
+        return response.get();
+    }
+
+    /**
+     * Invokes system api manageFastPairAccount to opt in account, or opt out account.
+     */
+    @WorkerThread
+    public void manageFastPairAccount(FastPairManageAccountRequestParcel requestParcel) {
+        final CountDownLatch waitForCompletionLatch = new CountDownLatch(1);
+        mServiceMonitor.runOnBinder(new ServiceMonitor.BinderOperation() {
+            @Override
+            public void run(IBinder binder) throws RemoteException {
+                IFastPairDataProvider provider = IFastPairDataProvider.Stub.asInterface(binder);
+                IFastPairManageAccountCallback callback =
+                        new IFastPairManageAccountCallback.Stub() {
+                            public void onSuccess() {
+                                waitForCompletionLatch.countDown();
+                            }
+
+                            public void onError(int code, String message) {
+                                waitForCompletionLatch.countDown();
+                            }
+                        };
+                provider.manageFastPairAccount(requestParcel, callback);
+            }
+
+            @Override
+            public void onError() {
+                waitForCompletionLatch.countDown();
+            }
+        });
+        try {
+            waitForCompletionLatch.await(TIME_OUT_MILLIS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            // skip.
+        }
+        return;
+    }
+
+    /**
+     * Invokes system api manageFastPairAccountDevice to add or remove a device from a Fast Pair
+     * account.
+     */
+    @WorkerThread
+    public void manageFastPairAccountDevice(
+            FastPairManageAccountDeviceRequestParcel requestParcel) {
+        final CountDownLatch waitForCompletionLatch = new CountDownLatch(1);
+        mServiceMonitor.runOnBinder(new ServiceMonitor.BinderOperation() {
+            @Override
+            public void run(IBinder binder) throws RemoteException {
+                IFastPairDataProvider provider = IFastPairDataProvider.Stub.asInterface(binder);
+                IFastPairManageAccountDeviceCallback callback =
+                        new IFastPairManageAccountDeviceCallback.Stub() {
+                            public void onSuccess() {
+                                waitForCompletionLatch.countDown();
+                            }
+
+                            public void onError(int code, String message) {
+                                waitForCompletionLatch.countDown();
+                            }
+                        };
+                provider.manageFastPairAccountDevice(requestParcel, callback);
+            }
+
+            @Override
+            public void onError() {
+                waitForCompletionLatch.countDown();
+            }
+        });
+        try {
+            waitForCompletionLatch.await(TIME_OUT_MILLIS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            // skip.
+        }
+        return;
+    }
+
+    /**
+     * Invokes system api loadFastPairAntispoofKeyDeviceMetadata.
+     *
+     * @return the Fast Pair AntispoofKeyDeviceMetadata of a given device.
+     */
+    @WorkerThread
+    @Nullable
+    FastPairAntispoofKeyDeviceMetadataParcel loadFastPairAntispoofKeyDeviceMetadata(
+            FastPairAntispoofKeyDeviceMetadataRequestParcel requestParcel) {
+        final CountDownLatch waitForCompletionLatch = new CountDownLatch(1);
+        final AtomicReference<FastPairAntispoofKeyDeviceMetadataParcel> response =
+                new AtomicReference<>();
+        mServiceMonitor.runOnBinder(new ServiceMonitor.BinderOperation() {
+            @Override
+            public void run(IBinder binder) throws RemoteException {
+                IFastPairDataProvider provider = IFastPairDataProvider.Stub.asInterface(binder);
+                IFastPairAntispoofKeyDeviceMetadataCallback callback =
+                        new IFastPairAntispoofKeyDeviceMetadataCallback.Stub() {
+                            public void onFastPairAntispoofKeyDeviceMetadataReceived(
+                                    FastPairAntispoofKeyDeviceMetadataParcel metadata) {
+                                response.set(metadata);
+                                waitForCompletionLatch.countDown();
+                            }
+
+                            public void onError(int code, String message) {
+                                waitForCompletionLatch.countDown();
+                            }
+                        };
+                provider.loadFastPairAntispoofKeyDeviceMetadata(requestParcel, callback);
+            }
+
+            @Override
+            public void onError() {
+                waitForCompletionLatch.countDown();
+            }
+        });
+        try {
+            waitForCompletionLatch.await(TIME_OUT_MILLIS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            // skip.
+        }
+        return response.get();
+    }
+
+    /**
+     * Invokes loadFastPairAccountDevicesMetadata.
+     *
+     * @return the metadata of Fast Pair devices that are associated with a given account.
+     */
+    @WorkerThread
+    @Nullable
+    FastPairAccountKeyDeviceMetadataParcel[] loadFastPairAccountDevicesMetadata(
+            FastPairAccountDevicesMetadataRequestParcel requestParcel) {
+        final CountDownLatch waitForCompletionLatch = new CountDownLatch(1);
+        final AtomicReference<FastPairAccountKeyDeviceMetadataParcel[]> response =
+                new AtomicReference<>();
+        mServiceMonitor.runOnBinder(new ServiceMonitor.BinderOperation() {
+            @Override
+            public void run(IBinder binder) throws RemoteException {
+                IFastPairDataProvider provider = IFastPairDataProvider.Stub.asInterface(binder);
+                IFastPairAccountDevicesMetadataCallback callback =
+                        new IFastPairAccountDevicesMetadataCallback.Stub() {
+                            public void onFastPairAccountDevicesMetadataReceived(
+                                    FastPairAccountKeyDeviceMetadataParcel[] metadatas) {
+                                response.set(metadatas);
+                                waitForCompletionLatch.countDown();
+                            }
+
+                            public void onError(int code, String message) {
+                                waitForCompletionLatch.countDown();
+                            }
+                        };
+                provider.loadFastPairAccountDevicesMetadata(requestParcel, callback);
+            }
+
+            @Override
+            public void onError() {
+                waitForCompletionLatch.countDown();
+            }
+        });
+        try {
+            waitForCompletionLatch.await(TIME_OUT_MILLIS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            // skip.
+        }
+        return response.get();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/provider/Utils.java b/nearby/service/java/com/android/server/nearby/provider/Utils.java
new file mode 100644
index 0000000..22e31cd
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/provider/Utils.java
@@ -0,0 +1,601 @@
+/*
+ * 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.server.nearby.provider;
+
+import android.accounts.Account;
+import android.annotation.Nullable;
+import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataParcel;
+import android.nearby.aidl.FastPairDeviceMetadataParcel;
+import android.nearby.aidl.FastPairDiscoveryItemParcel;
+import android.nearby.aidl.FastPairEligibleAccountParcel;
+
+import com.android.server.nearby.fastpair.footprint.FastPairUploadInfo;
+
+import com.google.protobuf.ByteString;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import service.proto.Cache;
+import service.proto.Data;
+import service.proto.FastPairString.FastPairStrings;
+import service.proto.Rpcs;
+
+/**
+ * Utility functions to convert between different data classes.
+ */
+class Utils {
+
+    static List<Data.FastPairDeviceWithAccountKey> convertToFastPairDevicesWithAccountKey(
+            @Nullable FastPairAccountKeyDeviceMetadataParcel[] metadataParcels) {
+        if (metadataParcels == null) {
+            return new ArrayList<Data.FastPairDeviceWithAccountKey>(0);
+        }
+
+        List<Data.FastPairDeviceWithAccountKey> fpDeviceList =
+                new ArrayList<>(metadataParcels.length);
+        for (FastPairAccountKeyDeviceMetadataParcel metadataParcel : metadataParcels) {
+            if (metadataParcel == null) {
+                continue;
+            }
+            Data.FastPairDeviceWithAccountKey.Builder fpDeviceBuilder =
+                    Data.FastPairDeviceWithAccountKey.newBuilder();
+            if (metadataParcel.deviceAccountKey != null) {
+                fpDeviceBuilder.setAccountKey(
+                        ByteString.copyFrom(metadataParcel.deviceAccountKey));
+            }
+            if (metadataParcel.sha256DeviceAccountKeyPublicAddress != null) {
+                fpDeviceBuilder.setSha256AccountKeyPublicAddress(
+                        ByteString.copyFrom(metadataParcel.sha256DeviceAccountKeyPublicAddress));
+            }
+
+            Cache.StoredDiscoveryItem.Builder storedDiscoveryItemBuilder =
+                    Cache.StoredDiscoveryItem.newBuilder();
+
+            if (metadataParcel.discoveryItem != null) {
+                if (metadataParcel.discoveryItem.actionUrl != null) {
+                    storedDiscoveryItemBuilder.setActionUrl(metadataParcel.discoveryItem.actionUrl);
+                }
+                Cache.ResolvedUrlType urlType = Cache.ResolvedUrlType.forNumber(
+                        metadataParcel.discoveryItem.actionUrlType);
+                if (urlType != null) {
+                    storedDiscoveryItemBuilder.setActionUrlType(urlType);
+                }
+                if (metadataParcel.discoveryItem.appName != null) {
+                    storedDiscoveryItemBuilder.setAppName(metadataParcel.discoveryItem.appName);
+                }
+                Cache.DiscoveryAttachmentType attachmentType =
+                        Cache.DiscoveryAttachmentType.forNumber(
+                                metadataParcel.discoveryItem.attachmentType);
+                if (attachmentType != null) {
+                    storedDiscoveryItemBuilder.setAttachmentType(attachmentType);
+                }
+                if (metadataParcel.discoveryItem.authenticationPublicKeySecp256r1 != null) {
+                    storedDiscoveryItemBuilder.setAuthenticationPublicKeySecp256R1(
+                            ByteString.copyFrom(
+                                    metadataParcel.discoveryItem.authenticationPublicKeySecp256r1));
+                }
+                if (metadataParcel.discoveryItem.bleRecordBytes != null) {
+                    storedDiscoveryItemBuilder.setBleRecordBytes(
+                            ByteString.copyFrom(metadataParcel.discoveryItem.bleRecordBytes));
+                }
+                Cache.StoredDiscoveryItem.DebugMessageCategory debugMessageCategory =
+                        Cache.StoredDiscoveryItem.DebugMessageCategory.forNumber(
+                                metadataParcel.discoveryItem.debugCategory);
+                if (debugMessageCategory != null) {
+                    storedDiscoveryItemBuilder.setDebugCategory(debugMessageCategory);
+                }
+                if (metadataParcel.discoveryItem.debugMessage != null) {
+                    storedDiscoveryItemBuilder.setDebugMessage(
+                            metadataParcel.discoveryItem.debugMessage);
+                }
+                if (metadataParcel.discoveryItem.description != null) {
+                    storedDiscoveryItemBuilder.setDescription(
+                            metadataParcel.discoveryItem.description);
+                }
+                if (metadataParcel.discoveryItem.deviceName != null) {
+                    storedDiscoveryItemBuilder.setDeviceName(
+                            metadataParcel.discoveryItem.deviceName);
+                }
+                if (metadataParcel.discoveryItem.displayUrl != null) {
+                    storedDiscoveryItemBuilder.setDisplayUrl(
+                            metadataParcel.discoveryItem.displayUrl);
+                }
+                if (metadataParcel.discoveryItem.entityId != null) {
+                    storedDiscoveryItemBuilder.setEntityId(
+                            metadataParcel.discoveryItem.entityId);
+                }
+                if (metadataParcel.discoveryItem.featureGraphicUrl != null) {
+                    storedDiscoveryItemBuilder.setFeatureGraphicUrl(
+                            metadataParcel.discoveryItem.featureGraphicUrl);
+                }
+                storedDiscoveryItemBuilder.setFirstObservationTimestampMillis(
+                        metadataParcel.discoveryItem.firstObservationTimestampMillis);
+                if (metadataParcel.discoveryItem.groupId != null) {
+                    storedDiscoveryItemBuilder.setGroupId(metadataParcel.discoveryItem.groupId);
+                }
+                if (metadataParcel.discoveryItem.iconFifeUrl != null) {
+                    storedDiscoveryItemBuilder.setIconFifeUrl(
+                            metadataParcel.discoveryItem.iconFifeUrl);
+                }
+                if (metadataParcel.discoveryItem.iconPng != null) {
+                    storedDiscoveryItemBuilder.setIconPng(
+                            ByteString.copyFrom(metadataParcel.discoveryItem.iconPng));
+                }
+                if (metadataParcel.discoveryItem.id != null) {
+                    storedDiscoveryItemBuilder.setId(metadataParcel.discoveryItem.id);
+                }
+                storedDiscoveryItemBuilder.setLastObservationTimestampMillis(
+                        metadataParcel.discoveryItem.lastObservationTimestampMillis);
+                Cache.StoredDiscoveryItem.ExperienceType experienceType =
+                        Cache.StoredDiscoveryItem.ExperienceType.forNumber(
+                                metadataParcel.discoveryItem.lastUserExperience);
+                if (experienceType != null) {
+                    storedDiscoveryItemBuilder.setLastUserExperience(experienceType);
+                }
+                storedDiscoveryItemBuilder.setLostMillis(metadataParcel.discoveryItem.lostMillis);
+                if (metadataParcel.discoveryItem.macAddress != null) {
+                    storedDiscoveryItemBuilder.setMacAddress(
+                            metadataParcel.discoveryItem.macAddress);
+                }
+                if (metadataParcel.discoveryItem.packageName != null) {
+                    storedDiscoveryItemBuilder.setPackageName(
+                            metadataParcel.discoveryItem.packageName);
+                }
+                storedDiscoveryItemBuilder.setPendingAppInstallTimestampMillis(
+                        metadataParcel.discoveryItem.pendingAppInstallTimestampMillis);
+                storedDiscoveryItemBuilder.setRssi(metadataParcel.discoveryItem.rssi);
+                Cache.StoredDiscoveryItem.State state =
+                        Cache.StoredDiscoveryItem.State.forNumber(
+                                metadataParcel.discoveryItem.state);
+                if (state != null) {
+                    storedDiscoveryItemBuilder.setState(state);
+                }
+                if (metadataParcel.discoveryItem.title != null) {
+                    storedDiscoveryItemBuilder.setTitle(metadataParcel.discoveryItem.title);
+                }
+                if (metadataParcel.discoveryItem.triggerId != null) {
+                    storedDiscoveryItemBuilder.setTriggerId(metadataParcel.discoveryItem.triggerId);
+                }
+                storedDiscoveryItemBuilder.setTxPower(metadataParcel.discoveryItem.txPower);
+                Cache.NearbyType type =
+                        Cache.NearbyType.forNumber(metadataParcel.discoveryItem.type);
+                if (type != null) {
+                    storedDiscoveryItemBuilder.setType(type);
+                }
+            }
+            if (metadataParcel.metadata != null) {
+                FastPairStrings.Builder stringsBuilder = FastPairStrings.newBuilder();
+                if (metadataParcel.metadata.assistantSetupHalfSheet != null) {
+                    stringsBuilder.setAssistantHalfSheetDescription(
+                            metadataParcel.metadata.assistantSetupHalfSheet);
+                }
+                if (metadataParcel.metadata.assistantSetupNotification != null) {
+                    stringsBuilder.setAssistantNotificationDescription(
+                            metadataParcel.metadata.assistantSetupNotification);
+                }
+                if (metadataParcel.metadata.confirmPinDescription != null) {
+                    stringsBuilder.setConfirmPinDescription(
+                            metadataParcel.metadata.confirmPinDescription);
+                }
+                if (metadataParcel.metadata.confirmPinTitle != null) {
+                    stringsBuilder.setConfirmPinTitle(
+                            metadataParcel.metadata.confirmPinTitle);
+                }
+                if (metadataParcel.metadata.connectSuccessCompanionAppInstalled != null) {
+                    stringsBuilder.setPairingFinishedCompanionAppInstalled(
+                            metadataParcel.metadata.connectSuccessCompanionAppInstalled);
+                }
+                if (metadataParcel.metadata.connectSuccessCompanionAppNotInstalled != null) {
+                    stringsBuilder.setPairingFinishedCompanionAppNotInstalled(
+                            metadataParcel.metadata.connectSuccessCompanionAppNotInstalled);
+                }
+                if (metadataParcel.metadata.failConnectGoToSettingsDescription != null) {
+                    stringsBuilder.setPairingFailDescription(
+                            metadataParcel.metadata.failConnectGoToSettingsDescription);
+                }
+                if (metadataParcel.metadata.fastPairTvConnectDeviceNoAccountDescription != null) {
+                    stringsBuilder.setFastPairTvConnectDeviceNoAccountDescription(
+                            metadataParcel.metadata.fastPairTvConnectDeviceNoAccountDescription);
+                }
+                if (metadataParcel.metadata.initialNotificationDescription != null) {
+                    stringsBuilder.setTapToPairWithAccount(
+                            metadataParcel.metadata.initialNotificationDescription);
+                }
+                if (metadataParcel.metadata.initialNotificationDescriptionNoAccount != null) {
+                    stringsBuilder.setTapToPairWithoutAccount(
+                            metadataParcel.metadata.initialNotificationDescriptionNoAccount);
+                }
+                if (metadataParcel.metadata.initialPairingDescription != null) {
+                    stringsBuilder.setInitialPairingDescription(
+                            metadataParcel.metadata.initialPairingDescription);
+                }
+                if (metadataParcel.metadata.retroactivePairingDescription != null) {
+                    stringsBuilder.setRetroactivePairingDescription(
+                            metadataParcel.metadata.retroactivePairingDescription);
+                }
+                if (metadataParcel.metadata.subsequentPairingDescription != null) {
+                    stringsBuilder.setSubsequentPairingDescription(
+                            metadataParcel.metadata.subsequentPairingDescription);
+                }
+                if (metadataParcel.metadata.syncContactsDescription != null) {
+                    stringsBuilder.setSyncContactsDescription(
+                            metadataParcel.metadata.syncContactsDescription);
+                }
+                if (metadataParcel.metadata.syncContactsTitle != null) {
+                    stringsBuilder.setSyncContactsTitle(
+                            metadataParcel.metadata.syncContactsTitle);
+                }
+                if (metadataParcel.metadata.syncSmsDescription != null) {
+                    stringsBuilder.setSyncSmsDescription(
+                            metadataParcel.metadata.syncSmsDescription);
+                }
+                if (metadataParcel.metadata.syncSmsTitle != null) {
+                    stringsBuilder.setSyncSmsTitle(metadataParcel.metadata.syncSmsTitle);
+                }
+                if (metadataParcel.metadata.waitLaunchCompanionAppDescription != null) {
+                    stringsBuilder.setWaitAppLaunchDescription(
+                            metadataParcel.metadata.waitLaunchCompanionAppDescription);
+                }
+                storedDiscoveryItemBuilder.setFastPairStrings(stringsBuilder.build());
+
+                Cache.FastPairInformation.Builder fpInformationBuilder =
+                        Cache.FastPairInformation.newBuilder();
+                Rpcs.TrueWirelessHeadsetImages.Builder imagesBuilder =
+                        Rpcs.TrueWirelessHeadsetImages.newBuilder();
+                if (metadataParcel.metadata.trueWirelessImageUrlCase != null) {
+                    imagesBuilder.setCaseUrl(metadataParcel.metadata.trueWirelessImageUrlCase);
+                }
+                if (metadataParcel.metadata.trueWirelessImageUrlLeftBud != null) {
+                    imagesBuilder.setLeftBudUrl(
+                            metadataParcel.metadata.trueWirelessImageUrlLeftBud);
+                }
+                if (metadataParcel.metadata.trueWirelessImageUrlRightBud != null) {
+                    imagesBuilder.setRightBudUrl(
+                            metadataParcel.metadata.trueWirelessImageUrlRightBud);
+                }
+                fpInformationBuilder.setTrueWirelessImages(imagesBuilder.build());
+                Rpcs.DeviceType deviceType =
+                        Rpcs.DeviceType.forNumber(metadataParcel.metadata.deviceType);
+                if (deviceType != null) {
+                    fpInformationBuilder.setDeviceType(deviceType);
+                }
+
+                storedDiscoveryItemBuilder.setFastPairInformation(fpInformationBuilder.build());
+            }
+            fpDeviceBuilder.setDiscoveryItem(storedDiscoveryItemBuilder.build());
+            fpDeviceList.add(fpDeviceBuilder.build());
+        }
+        return fpDeviceList;
+    }
+
+    static List<Account> convertToAccountList(
+            @Nullable FastPairEligibleAccountParcel[] accountParcels) {
+        if (accountParcels == null) {
+            return new ArrayList<Account>(0);
+        }
+        List<Account> accounts = new ArrayList<Account>(accountParcels.length);
+        for (FastPairEligibleAccountParcel parcel : accountParcels) {
+            if (parcel != null && parcel.account != null) {
+                accounts.add(parcel.account);
+            }
+        }
+        return accounts;
+    }
+
+    private static @Nullable Rpcs.Device convertToDevice(
+            FastPairAntispoofKeyDeviceMetadataParcel metadata) {
+
+        Rpcs.Device.Builder deviceBuilder = Rpcs.Device.newBuilder();
+        if (metadata.antispoofPublicKey != null) {
+            deviceBuilder.setAntiSpoofingKeyPair(Rpcs.AntiSpoofingKeyPair.newBuilder()
+                    .setPublicKey(ByteString.copyFrom(metadata.antispoofPublicKey))
+                    .build());
+        }
+        if (metadata.deviceMetadata != null) {
+            Rpcs.TrueWirelessHeadsetImages.Builder imagesBuilder =
+                    Rpcs.TrueWirelessHeadsetImages.newBuilder();
+            if (metadata.deviceMetadata.trueWirelessImageUrlLeftBud != null) {
+                imagesBuilder.setLeftBudUrl(metadata.deviceMetadata.trueWirelessImageUrlLeftBud);
+            }
+            if (metadata.deviceMetadata.trueWirelessImageUrlRightBud != null) {
+                imagesBuilder.setRightBudUrl(metadata.deviceMetadata.trueWirelessImageUrlRightBud);
+            }
+            if (metadata.deviceMetadata.trueWirelessImageUrlCase != null) {
+                imagesBuilder.setCaseUrl(metadata.deviceMetadata.trueWirelessImageUrlCase);
+            }
+            deviceBuilder.setTrueWirelessImages(imagesBuilder.build());
+            if (metadata.deviceMetadata.imageUrl != null) {
+                deviceBuilder.setImageUrl(metadata.deviceMetadata.imageUrl);
+            }
+            if (metadata.deviceMetadata.intentUri != null) {
+                deviceBuilder.setIntentUri(metadata.deviceMetadata.intentUri);
+            }
+            if (metadata.deviceMetadata.name != null) {
+                deviceBuilder.setName(metadata.deviceMetadata.name);
+            }
+            Rpcs.DeviceType deviceType =
+                    Rpcs.DeviceType.forNumber(metadata.deviceMetadata.deviceType);
+            if (deviceType != null) {
+                deviceBuilder.setDeviceType(deviceType);
+            }
+            deviceBuilder.setBleTxPower(metadata.deviceMetadata.bleTxPower)
+                    .setTriggerDistance(metadata.deviceMetadata.triggerDistance);
+        }
+
+        return deviceBuilder.build();
+    }
+
+    private static @Nullable ByteString convertToImage(
+            FastPairAntispoofKeyDeviceMetadataParcel metadata) {
+        if (metadata.deviceMetadata == null || metadata.deviceMetadata.image == null) {
+            return null;
+        }
+
+        return ByteString.copyFrom(metadata.deviceMetadata.image);
+    }
+
+    private static @Nullable Rpcs.ObservedDeviceStrings
+            convertToObservedDeviceStrings(FastPairAntispoofKeyDeviceMetadataParcel metadata) {
+        if (metadata.deviceMetadata == null) {
+            return null;
+        }
+
+        Rpcs.ObservedDeviceStrings.Builder stringsBuilder = Rpcs.ObservedDeviceStrings.newBuilder();
+        if (metadata.deviceMetadata.assistantSetupHalfSheet != null) {
+            stringsBuilder
+                    .setAssistantSetupHalfSheet(metadata.deviceMetadata.assistantSetupHalfSheet);
+        }
+        if (metadata.deviceMetadata.assistantSetupNotification != null) {
+            stringsBuilder.setAssistantSetupNotification(
+                    metadata.deviceMetadata.assistantSetupNotification);
+        }
+        if (metadata.deviceMetadata.confirmPinDescription != null) {
+            stringsBuilder.setConfirmPinDescription(metadata.deviceMetadata.confirmPinDescription);
+        }
+        if (metadata.deviceMetadata.confirmPinTitle != null) {
+            stringsBuilder.setConfirmPinTitle(metadata.deviceMetadata.confirmPinTitle);
+        }
+        if (metadata.deviceMetadata.connectSuccessCompanionAppInstalled != null) {
+            stringsBuilder.setConnectSuccessCompanionAppInstalled(
+                    metadata.deviceMetadata.connectSuccessCompanionAppInstalled);
+        }
+        if (metadata.deviceMetadata.connectSuccessCompanionAppNotInstalled != null) {
+            stringsBuilder.setConnectSuccessCompanionAppNotInstalled(
+                    metadata.deviceMetadata.connectSuccessCompanionAppNotInstalled);
+        }
+        if (metadata.deviceMetadata.downloadCompanionAppDescription != null) {
+            stringsBuilder.setDownloadCompanionAppDescription(
+                    metadata.deviceMetadata.downloadCompanionAppDescription);
+        }
+        if (metadata.deviceMetadata.failConnectGoToSettingsDescription != null) {
+            stringsBuilder.setFailConnectGoToSettingsDescription(
+                    metadata.deviceMetadata.failConnectGoToSettingsDescription);
+        }
+        if (metadata.deviceMetadata.fastPairTvConnectDeviceNoAccountDescription != null) {
+            stringsBuilder.setFastPairTvConnectDeviceNoAccountDescription(
+                    metadata.deviceMetadata.fastPairTvConnectDeviceNoAccountDescription);
+        }
+        if (metadata.deviceMetadata.initialNotificationDescription != null) {
+            stringsBuilder.setInitialNotificationDescription(
+                    metadata.deviceMetadata.initialNotificationDescription);
+        }
+        if (metadata.deviceMetadata.initialNotificationDescriptionNoAccount != null) {
+            stringsBuilder.setInitialNotificationDescriptionNoAccount(
+                    metadata.deviceMetadata.initialNotificationDescriptionNoAccount);
+        }
+        if (metadata.deviceMetadata.initialPairingDescription != null) {
+            stringsBuilder.setInitialPairingDescription(
+                    metadata.deviceMetadata.initialPairingDescription);
+        }
+        if (metadata.deviceMetadata.locale != null) {
+            stringsBuilder.setLocale(metadata.deviceMetadata.locale);
+        }
+        if (metadata.deviceMetadata.openCompanionAppDescription != null) {
+            stringsBuilder.setOpenCompanionAppDescription(
+                    metadata.deviceMetadata.openCompanionAppDescription);
+        }
+        if (metadata.deviceMetadata.retroactivePairingDescription != null) {
+            stringsBuilder.setRetroactivePairingDescription(
+                    metadata.deviceMetadata.retroactivePairingDescription);
+        }
+        if (metadata.deviceMetadata.subsequentPairingDescription != null) {
+            stringsBuilder.setSubsequentPairingDescription(
+                    metadata.deviceMetadata.subsequentPairingDescription);
+        }
+        if (metadata.deviceMetadata.syncContactsDescription != null) {
+            stringsBuilder.setSyncContactsDescription(
+                    metadata.deviceMetadata.syncContactsDescription);
+        }
+        if (metadata.deviceMetadata.syncContactsTitle != null) {
+            stringsBuilder.setSyncContactsTitle(
+                    metadata.deviceMetadata.syncContactsTitle);
+        }
+        if (metadata.deviceMetadata.syncSmsDescription != null) {
+            stringsBuilder.setSyncSmsDescription(
+                    metadata.deviceMetadata.syncSmsDescription);
+        }
+        if (metadata.deviceMetadata.syncSmsTitle != null) {
+            stringsBuilder.setSyncSmsTitle(
+                    metadata.deviceMetadata.syncSmsTitle);
+        }
+        if (metadata.deviceMetadata.unableToConnectDescription != null) {
+            stringsBuilder.setUnableToConnectDescription(
+                    metadata.deviceMetadata.unableToConnectDescription);
+        }
+        if (metadata.deviceMetadata.unableToConnectTitle != null) {
+            stringsBuilder.setUnableToConnectTitle(
+                    metadata.deviceMetadata.unableToConnectTitle);
+        }
+        if (metadata.deviceMetadata.updateCompanionAppDescription != null) {
+            stringsBuilder.setUpdateCompanionAppDescription(
+                    metadata.deviceMetadata.updateCompanionAppDescription);
+        }
+        if (metadata.deviceMetadata.waitLaunchCompanionAppDescription != null) {
+            stringsBuilder.setWaitLaunchCompanionAppDescription(
+                    metadata.deviceMetadata.waitLaunchCompanionAppDescription);
+        }
+
+        return stringsBuilder.build();
+    }
+
+    static @Nullable Rpcs.GetObservedDeviceResponse
+            convertToGetObservedDeviceResponse(
+                    @Nullable FastPairAntispoofKeyDeviceMetadataParcel metadata) {
+        if (metadata == null) {
+            return null;
+        }
+
+        Rpcs.GetObservedDeviceResponse.Builder responseBuilder =
+                Rpcs.GetObservedDeviceResponse.newBuilder();
+
+        Rpcs.Device device = convertToDevice(metadata);
+        if (device != null) {
+            responseBuilder.setDevice(device);
+        }
+        ByteString image = convertToImage(metadata);
+        if (image != null) {
+            responseBuilder.setImage(image);
+        }
+        Rpcs.ObservedDeviceStrings strings = convertToObservedDeviceStrings(metadata);
+        if (strings != null) {
+            responseBuilder.setStrings(strings);
+        }
+
+        return responseBuilder.build();
+    }
+
+    static @Nullable FastPairAccountKeyDeviceMetadataParcel
+            convertToFastPairAccountKeyDeviceMetadata(
+            @Nullable FastPairUploadInfo uploadInfo) {
+        if (uploadInfo == null) {
+            return null;
+        }
+
+        FastPairAccountKeyDeviceMetadataParcel accountKeyDeviceMetadataParcel =
+                new FastPairAccountKeyDeviceMetadataParcel();
+        if (uploadInfo.getAccountKey() != null) {
+            accountKeyDeviceMetadataParcel.deviceAccountKey =
+                    uploadInfo.getAccountKey().toByteArray();
+        }
+        if (uploadInfo.getSha256AccountKeyPublicAddress() != null) {
+            accountKeyDeviceMetadataParcel.sha256DeviceAccountKeyPublicAddress =
+                    uploadInfo.getSha256AccountKeyPublicAddress().toByteArray();
+        }
+        if (uploadInfo.getStoredDiscoveryItem() != null) {
+            accountKeyDeviceMetadataParcel.metadata =
+                    convertToFastPairDeviceMetadata(uploadInfo.getStoredDiscoveryItem());
+            accountKeyDeviceMetadataParcel.discoveryItem =
+                    convertToFastPairDiscoveryItem(uploadInfo.getStoredDiscoveryItem());
+        }
+
+        return accountKeyDeviceMetadataParcel;
+    }
+
+    private static @Nullable FastPairDiscoveryItemParcel
+            convertToFastPairDiscoveryItem(Cache.StoredDiscoveryItem storedDiscoveryItem) {
+        FastPairDiscoveryItemParcel discoveryItemParcel = new FastPairDiscoveryItemParcel();
+        discoveryItemParcel.actionUrl = storedDiscoveryItem.getActionUrl();
+        discoveryItemParcel.actionUrlType = storedDiscoveryItem.getActionUrlType().getNumber();
+        discoveryItemParcel.appName = storedDiscoveryItem.getAppName();
+        discoveryItemParcel.attachmentType = storedDiscoveryItem.getAttachmentType().getNumber();
+        discoveryItemParcel.authenticationPublicKeySecp256r1 =
+                storedDiscoveryItem.getAuthenticationPublicKeySecp256R1().toByteArray();
+        discoveryItemParcel.bleRecordBytes = storedDiscoveryItem.getBleRecordBytes().toByteArray();
+        discoveryItemParcel.debugCategory = storedDiscoveryItem.getDebugCategory().getNumber();
+        discoveryItemParcel.debugMessage = storedDiscoveryItem.getDebugMessage();
+        discoveryItemParcel.description = storedDiscoveryItem.getDescription();
+        discoveryItemParcel.deviceName = storedDiscoveryItem.getDeviceName();
+        discoveryItemParcel.displayUrl = storedDiscoveryItem.getDisplayUrl();
+        discoveryItemParcel.entityId = storedDiscoveryItem.getEntityId();
+        discoveryItemParcel.featureGraphicUrl = storedDiscoveryItem.getFeatureGraphicUrl();
+        discoveryItemParcel.firstObservationTimestampMillis =
+                storedDiscoveryItem.getFirstObservationTimestampMillis();
+        discoveryItemParcel.groupId = storedDiscoveryItem.getGroupId();
+        discoveryItemParcel.iconFifeUrl = storedDiscoveryItem.getIconFifeUrl();
+        discoveryItemParcel.iconPng = storedDiscoveryItem.getIconPng().toByteArray();
+        discoveryItemParcel.id = storedDiscoveryItem.getId();
+        discoveryItemParcel.lastObservationTimestampMillis =
+                storedDiscoveryItem.getLastObservationTimestampMillis();
+        discoveryItemParcel.lastUserExperience =
+                storedDiscoveryItem.getLastUserExperience().getNumber();
+        discoveryItemParcel.lostMillis = storedDiscoveryItem.getLostMillis();
+        discoveryItemParcel.macAddress = storedDiscoveryItem.getMacAddress();
+        discoveryItemParcel.packageName = storedDiscoveryItem.getPackageName();
+        discoveryItemParcel.pendingAppInstallTimestampMillis =
+                storedDiscoveryItem.getPendingAppInstallTimestampMillis();
+        discoveryItemParcel.rssi = storedDiscoveryItem.getRssi();
+        discoveryItemParcel.state = storedDiscoveryItem.getState().getNumber();
+        discoveryItemParcel.title = storedDiscoveryItem.getTitle();
+        discoveryItemParcel.triggerId = storedDiscoveryItem.getTriggerId();
+        discoveryItemParcel.txPower = storedDiscoveryItem.getTxPower();
+        discoveryItemParcel.type = storedDiscoveryItem.getType().getNumber();
+
+        return discoveryItemParcel;
+    }
+
+    /*  Do we upload these?
+        String downloadCompanionAppDescription =
+             bundle.getString("downloadCompanionAppDescription");
+        String locale = bundle.getString("locale");
+        String openCompanionAppDescription = bundle.getString("openCompanionAppDescription");
+        float triggerDistance = bundle.getFloat("triggerDistance");
+        String unableToConnectDescription = bundle.getString("unableToConnectDescription");
+        String unableToConnectTitle = bundle.getString("unableToConnectTitle");
+        String updateCompanionAppDescription = bundle.getString("updateCompanionAppDescription");
+    */
+    private static @Nullable FastPairDeviceMetadataParcel
+            convertToFastPairDeviceMetadata(Cache.StoredDiscoveryItem storedDiscoveryItem) {
+        FastPairStrings fpStrings = storedDiscoveryItem.getFastPairStrings();
+
+        FastPairDeviceMetadataParcel metadataParcel = new FastPairDeviceMetadataParcel();
+        metadataParcel.assistantSetupHalfSheet = fpStrings.getAssistantHalfSheetDescription();
+        metadataParcel.assistantSetupNotification = fpStrings.getAssistantNotificationDescription();
+        metadataParcel.confirmPinDescription = fpStrings.getConfirmPinDescription();
+        metadataParcel.confirmPinTitle = fpStrings.getConfirmPinTitle();
+        metadataParcel.connectSuccessCompanionAppInstalled =
+                fpStrings.getPairingFinishedCompanionAppInstalled();
+        metadataParcel.connectSuccessCompanionAppNotInstalled =
+                fpStrings.getPairingFinishedCompanionAppNotInstalled();
+        metadataParcel.failConnectGoToSettingsDescription = fpStrings.getPairingFailDescription();
+        metadataParcel.fastPairTvConnectDeviceNoAccountDescription =
+                fpStrings.getFastPairTvConnectDeviceNoAccountDescription();
+        metadataParcel.initialNotificationDescription = fpStrings.getTapToPairWithAccount();
+        metadataParcel.initialNotificationDescriptionNoAccount =
+                fpStrings.getTapToPairWithoutAccount();
+        metadataParcel.initialPairingDescription = fpStrings.getInitialPairingDescription();
+        metadataParcel.retroactivePairingDescription = fpStrings.getRetroactivePairingDescription();
+        metadataParcel.subsequentPairingDescription = fpStrings.getSubsequentPairingDescription();
+        metadataParcel.syncContactsDescription = fpStrings.getSyncContactsDescription();
+        metadataParcel.syncContactsTitle = fpStrings.getSyncContactsTitle();
+        metadataParcel.syncSmsDescription = fpStrings.getSyncSmsDescription();
+        metadataParcel.syncSmsTitle = fpStrings.getSyncSmsTitle();
+        metadataParcel.waitLaunchCompanionAppDescription = fpStrings.getWaitAppLaunchDescription();
+
+        Cache.FastPairInformation fpInformation = storedDiscoveryItem.getFastPairInformation();
+        metadataParcel.trueWirelessImageUrlCase =
+                fpInformation.getTrueWirelessImages().getCaseUrl();
+        metadataParcel.trueWirelessImageUrlLeftBud =
+                fpInformation.getTrueWirelessImages().getLeftBudUrl();
+        metadataParcel.trueWirelessImageUrlRightBud =
+                fpInformation.getTrueWirelessImages().getRightBudUrl();
+        metadataParcel.deviceType = fpInformation.getDeviceType().getNumber();
+
+        return metadataParcel;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/util/ArrayUtils.java b/nearby/service/java/com/android/server/nearby/util/ArrayUtils.java
new file mode 100644
index 0000000..599843c
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/util/ArrayUtils.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.util;
+
+import java.util.Arrays;
+
+/**
+ * ArrayUtils class that help manipulate array.
+ */
+public class ArrayUtils {
+    /** Concatenate N arrays of bytes into a single array. */
+    public static byte[] concatByteArrays(byte[]... arrays) {
+        // Degenerate case - no input provided.
+        if (arrays.length == 0) {
+            return new byte[0];
+        }
+
+        // Compute the total size.
+        int totalSize = 0;
+        for (int i = 0; i < arrays.length; i++) {
+            totalSize += arrays[i].length;
+        }
+
+        // Copy the arrays into the new array.
+        byte[] result = Arrays.copyOf(arrays[0], totalSize);
+        int pos = arrays[0].length;
+        for (int i = 1; i < arrays.length; i++) {
+            byte[] current = arrays[i];
+            System.arraycopy(current, 0, result, pos, current.length);
+            pos += current.length;
+        }
+        return result;
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/util/DataUtils.java b/nearby/service/java/com/android/server/nearby/util/DataUtils.java
new file mode 100644
index 0000000..0b01bc0
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/util/DataUtils.java
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.util;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import service.proto.Cache.ScanFastPairStoreItem;
+import service.proto.Cache.StoredDiscoveryItem;
+import service.proto.FastPairString.FastPairStrings;
+import service.proto.Rpcs.Device;
+import service.proto.Rpcs.GetObservedDeviceResponse;
+import service.proto.Rpcs.ObservedDeviceStrings;
+
+/**
+ * Utils class converts different data types {@link ScanFastPairStoreItem},
+ * {@link StoredDiscoveryItem} and {@link GetObservedDeviceResponse},
+ *
+ */
+public final class DataUtils {
+
+    /**
+     * Converts a {@link GetObservedDeviceResponse} to a {@link ScanFastPairStoreItem}.
+     */
+    public static ScanFastPairStoreItem toScanFastPairStoreItem(
+            GetObservedDeviceResponse observedDeviceResponse,
+            @NonNull String bleAddress, @Nullable String account) {
+        Device device = observedDeviceResponse.getDevice();
+        String deviceName = device.getName();
+        return ScanFastPairStoreItem.newBuilder()
+                .setAddress(bleAddress)
+                .setActionUrl(device.getIntentUri())
+                .setDeviceName(deviceName)
+                .setIconPng(observedDeviceResponse.getImage())
+                .setIconFifeUrl(device.getImageUrl())
+                .setAntiSpoofingPublicKey(device.getAntiSpoofingKeyPair().getPublicKey())
+                .setFastPairStrings(getFastPairStrings(observedDeviceResponse, deviceName, account))
+                .build();
+    }
+
+    /**
+     * Prints readable string for a {@link ScanFastPairStoreItem}.
+     */
+    public static String toString(ScanFastPairStoreItem item) {
+        return "ScanFastPairStoreItem=[address:" + item.getAddress()
+                + ", actionUr:" + item.getActionUrl()
+                + ", deviceName:" + item.getDeviceName()
+                + ", iconPng:" + item.getIconPng()
+                + ", iconFifeUrl:" + item.getIconFifeUrl()
+                + ", antiSpoofingKeyPair:" + item.getAntiSpoofingPublicKey()
+                + ", fastPairStrings:" + toString(item.getFastPairStrings())
+                + "]";
+    }
+
+    /**
+     * Prints readable string for a {@link FastPairStrings}
+     */
+    public static String toString(FastPairStrings fastPairStrings) {
+        return "FastPairStrings["
+                + "tapToPairWithAccount=" + fastPairStrings.getTapToPairWithAccount()
+                + ", tapToPairWithoutAccount=" + fastPairStrings.getTapToPairWithoutAccount()
+                + ", initialPairingDescription=" + fastPairStrings.getInitialPairingDescription()
+                + ", pairingFinishedCompanionAppInstalled="
+                + fastPairStrings.getPairingFinishedCompanionAppInstalled()
+                + ", pairingFinishedCompanionAppNotInstalled="
+                + fastPairStrings.getPairingFinishedCompanionAppNotInstalled()
+                + ", subsequentPairingDescription="
+                + fastPairStrings.getSubsequentPairingDescription()
+                + ", retroactivePairingDescription="
+                + fastPairStrings.getRetroactivePairingDescription()
+                + ", waitAppLaunchDescription=" + fastPairStrings.getWaitAppLaunchDescription()
+                + ", pairingFailDescription=" + fastPairStrings.getPairingFailDescription()
+                + ", assistantHalfSheetDescription="
+                + fastPairStrings.getAssistantHalfSheetDescription()
+                + ", assistantNotificationDescription="
+                + fastPairStrings.getAssistantNotificationDescription()
+                + ", fastPairTvConnectDeviceNoAccountDescription="
+                + fastPairStrings.getFastPairTvConnectDeviceNoAccountDescription()
+                + "]";
+    }
+
+    private static FastPairStrings getFastPairStrings(GetObservedDeviceResponse response,
+            String deviceName, @Nullable String account) {
+        ObservedDeviceStrings strings = response.getStrings();
+        return FastPairStrings.newBuilder()
+                .setTapToPairWithAccount(strings.getInitialNotificationDescription())
+                .setTapToPairWithoutAccount(
+                        strings.getInitialNotificationDescriptionNoAccount())
+                .setInitialPairingDescription(account == null
+                        ? strings.getInitialNotificationDescriptionNoAccount()
+                        : String.format(strings.getInitialPairingDescription(),
+                                deviceName, account))
+                .setPairingFinishedCompanionAppInstalled(
+                        strings.getConnectSuccessCompanionAppInstalled())
+                .setPairingFinishedCompanionAppNotInstalled(
+                        strings.getConnectSuccessCompanionAppNotInstalled())
+                .setSubsequentPairingDescription(strings.getSubsequentPairingDescription())
+                .setRetroactivePairingDescription(strings.getRetroactivePairingDescription())
+                .setWaitAppLaunchDescription(strings.getWaitLaunchCompanionAppDescription())
+                .setPairingFailDescription(strings.getFailConnectGoToSettingsDescription())
+                .setAssistantHalfSheetDescription(strings.getAssistantSetupHalfSheet())
+                .setAssistantNotificationDescription(strings.getAssistantSetupNotification())
+                .setFastPairTvConnectDeviceNoAccountDescription(
+                        strings.getFastPairTvConnectDeviceNoAccountDescription())
+                .build();
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/util/Environment.java b/nearby/service/java/com/android/server/nearby/util/Environment.java
new file mode 100644
index 0000000..d397862
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/util/Environment.java
@@ -0,0 +1,63 @@
+/*
+ * 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.server.nearby.util;
+
+import android.content.ApexEnvironment;
+import android.content.pm.ApplicationInfo;
+import android.os.UserHandle;
+
+import java.io.File;
+
+/**
+ * Provides function to make sure the function caller is from the same apex.
+ */
+public class Environment {
+    /**
+     * NEARBY apex name.
+     */
+    private static final String NEARBY_APEX_NAME = "com.android.tethering";
+
+    /**
+     * The path where the Nearby apex is mounted.
+     * Current value = "/apex/com.android.tethering"
+     */
+    private static final String NEARBY_APEX_PATH =
+            new File("/apex", NEARBY_APEX_NAME).getAbsolutePath();
+
+    /**
+     * Nearby shared folder.
+     */
+    public static File getNearbyDirectory() {
+        return ApexEnvironment.getApexEnvironment(NEARBY_APEX_NAME).getDeviceProtectedDataDir();
+    }
+
+    /**
+     * Nearby user specific folder.
+     */
+    public static File getNearbyDirectory(int userId) {
+        return ApexEnvironment.getApexEnvironment(NEARBY_APEX_NAME)
+                .getCredentialProtectedDataDirForUser(UserHandle.of(userId));
+    }
+
+    /**
+     * Returns true if the app is in the nearby apex, false otherwise.
+     * Checks if the app's path starts with "/apex/com.android.tethering".
+     */
+    public static boolean isAppInNearbyApex(ApplicationInfo appInfo) {
+        return appInfo.sourceDir.startsWith(NEARBY_APEX_PATH);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java b/nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java
new file mode 100644
index 0000000..6021ff6
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java
@@ -0,0 +1,258 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.util;
+
+import android.annotation.Nullable;
+import android.bluetooth.le.ScanRecord;
+import android.os.ParcelUuid;
+import android.util.SparseArray;
+
+import com.android.server.nearby.common.ble.BleFilter;
+import com.android.server.nearby.common.ble.BleRecord;
+
+import java.util.Arrays;
+
+/**
+ * Parses Fast Pair information out of {@link BleRecord}s.
+ *
+ * <p>There are 2 different packet formats that are supported, which is used can be determined by
+ * packet length:
+ *
+ * <p>For 3-byte packets, the full packet is the model ID.
+ *
+ * <p>For all other packets, the first byte is the header, followed by the model ID, followed by
+ * zero or more extra fields. Each field has its own header byte followed by the field value. The
+ * packet header is formatted as 0bVVVLLLLR (V = version, L = model ID length, R = reserved) and
+ * each extra field header is 0bLLLLTTTT (L = field length, T = field type).
+ */
+public class FastPairDecoder {
+
+    private static final int FIELD_TYPE_BLOOM_FILTER = 0;
+    private static final int FIELD_TYPE_BLOOM_FILTER_SALT = 1;
+    private static final int FIELD_TYPE_BLOOM_FILTER_NO_NOTIFICATION = 2;
+    private static final int FIELD_TYPE_BATTERY = 3;
+    private static final int FIELD_TYPE_BATTERY_NO_NOTIFICATION = 4;
+    public static final int FIELD_TYPE_CONNECTION_STATE = 5;
+    private static final int FIELD_TYPE_RANDOM_RESOLVABLE_DATA = 6;
+
+
+    /** FE2C is the 16-bit Service UUID. The rest is the base UUID. See BluetoothUuid (hidden). */
+    private static final ParcelUuid FAST_PAIR_SERVICE_PARCEL_UUID =
+            ParcelUuid.fromString("0000FE2C-0000-1000-8000-00805F9B34FB");
+
+    /** The filter you use to scan for Fast Pair BLE advertisements. */
+    public static final BleFilter FILTER =
+            new BleFilter.Builder().setServiceData(FAST_PAIR_SERVICE_PARCEL_UUID,
+                    new byte[0]).build();
+
+    // NOTE: Ensure that all bitmasks are always ints, not bytes so that bitshifting works correctly
+    // without needing worry about signing errors.
+    private static final int HEADER_VERSION_BITMASK = 0b11100000;
+    private static final int HEADER_LENGTH_BITMASK = 0b00011110;
+    private static final int HEADER_VERSION_OFFSET = 5;
+    private static final int HEADER_LENGTH_OFFSET = 1;
+
+    private static final int EXTRA_FIELD_LENGTH_BITMASK = 0b11110000;
+    private static final int EXTRA_FIELD_TYPE_BITMASK = 0b00001111;
+    private static final int EXTRA_FIELD_LENGTH_OFFSET = 4;
+    private static final int EXTRA_FIELD_TYPE_OFFSET = 0;
+
+    private static final int MIN_ID_LENGTH = 3;
+    private static final int MAX_ID_LENGTH = 14;
+    private static final int HEADER_INDEX = 0;
+    private static final int HEADER_LENGTH = 1;
+    private static final int FIELD_HEADER_LENGTH = 1;
+
+    // Not using java.util.IllegalFormatException because it is unchecked.
+    private static class IllegalFormatException extends Exception {
+        private IllegalFormatException(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * Gets model id data from broadcast
+     */
+    @Nullable
+    public static byte[] getModelId(@Nullable byte[] serviceData) {
+        if (serviceData == null) {
+            return null;
+        }
+
+        if (serviceData.length >= MIN_ID_LENGTH) {
+            if (serviceData.length == MIN_ID_LENGTH) {
+                // If the length == 3, all bytes are the ID. See flag docs for more about
+                // endianness.
+                return serviceData;
+            } else {
+                // Otherwise, the first byte is a header which contains the length of the big-endian
+                // model ID that follows. The model ID will be trimmed if it contains leading zeros.
+                int idIndex = 1;
+                int end = idIndex + getIdLength(serviceData);
+                while (serviceData[idIndex] == 0 && end - idIndex > MIN_ID_LENGTH) {
+                    idIndex++;
+                }
+                return Arrays.copyOfRange(serviceData, idIndex, end);
+            }
+        }
+        return null;
+    }
+
+    /** Gets the FastPair service data array if available, otherwise returns null. */
+    @Nullable
+    public static byte[] getServiceDataArray(BleRecord bleRecord) {
+        return bleRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID);
+    }
+
+    /** Gets the FastPair service data array if available, otherwise returns null. */
+    @Nullable
+    public static byte[] getServiceDataArray(ScanRecord scanRecord) {
+        return scanRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID);
+    }
+
+    /** Gets the bloom filter from the extra fields if available, otherwise returns null. */
+    @Nullable
+    public static byte[] getBloomFilter(@Nullable byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER);
+    }
+
+    /** Gets the bloom filter salt from the extra fields if available, otherwise returns null. */
+    @Nullable
+    public static byte[] getBloomFilterSalt(byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER_SALT);
+    }
+
+    /**
+     * Gets the suppress notification with bloom filter from the extra fields if available,
+     * otherwise returns null.
+     */
+    @Nullable
+    public static byte[] getBloomFilterNoNotification(@Nullable byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER_NO_NOTIFICATION);
+    }
+
+    /**
+     * Get random resolvableData
+     */
+    @Nullable
+    public static byte[] getRandomResolvableData(byte[] serviceData) {
+        return getExtraField(serviceData, FIELD_TYPE_RANDOM_RESOLVABLE_DATA);
+    }
+
+    @Nullable
+    private static byte[] getExtraField(@Nullable byte[] serviceData, int fieldId) {
+        if (serviceData == null || serviceData.length < HEADER_INDEX + HEADER_LENGTH) {
+            return null;
+        }
+        try {
+            return getExtraFields(serviceData).get(fieldId);
+        } catch (IllegalFormatException e) {
+            return null;
+        }
+    }
+
+    /** Gets extra field data at the end of the packet, defined by the extra field header. */
+    private static SparseArray<byte[]> getExtraFields(byte[] serviceData)
+            throws IllegalFormatException {
+        SparseArray<byte[]> extraFields = new SparseArray<>();
+        if (getVersion(serviceData) != 0) {
+            return extraFields;
+        }
+        int headerIndex = getFirstExtraFieldHeaderIndex(serviceData);
+        while (headerIndex < serviceData.length) {
+            int length = getExtraFieldLength(serviceData, headerIndex);
+            int index = headerIndex + FIELD_HEADER_LENGTH;
+            int type = getExtraFieldType(serviceData, headerIndex);
+            int end = index + length;
+            if (extraFields.get(type) == null) {
+                if (end <= serviceData.length) {
+                    extraFields.put(type, Arrays.copyOfRange(serviceData, index, end));
+                } else {
+                    throw new IllegalFormatException(
+                            "Invalid length, " + end + " is longer than service data size "
+                                    + serviceData.length);
+                }
+            }
+            headerIndex = end;
+        }
+        return extraFields;
+    }
+
+    /** Checks whether or not a valid ID is included in the service data packet. */
+    public static boolean hasBeaconIdBytes(BleRecord bleRecord) {
+        byte[] serviceData = bleRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID);
+        return checkModelId(serviceData);
+    }
+
+    /** Check whether byte array is FastPair model id or not. */
+    public static boolean checkModelId(@Nullable byte[] scanResult) {
+        return scanResult != null
+                // The 3-byte format has no header byte (all bytes are the ID).
+                && (scanResult.length == MIN_ID_LENGTH
+                // Header byte exists. We support only format version 0. (A different version
+                // indicates
+                // a breaking change in the format.)
+                || (scanResult.length > MIN_ID_LENGTH
+                && getVersion(scanResult) == 0
+                && isIdLengthValid(scanResult)));
+    }
+
+    /** Checks whether or not bloom filter is included in the service data packet. */
+    public static boolean hasBloomFilter(BleRecord bleRecord) {
+        return (getBloomFilter(getServiceDataArray(bleRecord)) != null
+                || getBloomFilterNoNotification(getServiceDataArray(bleRecord)) != null);
+    }
+
+    /** Checks whether or not bloom filter is included in the service data packet. */
+    public static boolean hasBloomFilter(ScanRecord scanRecord) {
+        return (getBloomFilter(getServiceDataArray(scanRecord)) != null
+                || getBloomFilterNoNotification(getServiceDataArray(scanRecord)) != null);
+    }
+
+    private static int getVersion(byte[] serviceData) {
+        return serviceData.length == MIN_ID_LENGTH
+                ? 0
+                : (serviceData[HEADER_INDEX] & HEADER_VERSION_BITMASK) >> HEADER_VERSION_OFFSET;
+    }
+
+    private static int getIdLength(byte[] serviceData) {
+        return serviceData.length == MIN_ID_LENGTH
+                ? MIN_ID_LENGTH
+                : (serviceData[HEADER_INDEX] & HEADER_LENGTH_BITMASK) >> HEADER_LENGTH_OFFSET;
+    }
+
+    private static int getFirstExtraFieldHeaderIndex(byte[] serviceData) {
+        return HEADER_INDEX + HEADER_LENGTH + getIdLength(serviceData);
+    }
+
+    private static int getExtraFieldLength(byte[] serviceData, int extraFieldIndex) {
+        return (serviceData[extraFieldIndex] & EXTRA_FIELD_LENGTH_BITMASK)
+                >> EXTRA_FIELD_LENGTH_OFFSET;
+    }
+
+    private static int getExtraFieldType(byte[] serviceData, int extraFieldIndex) {
+        return (serviceData[extraFieldIndex] & EXTRA_FIELD_TYPE_BITMASK) >> EXTRA_FIELD_TYPE_OFFSET;
+    }
+
+    private static boolean isIdLengthValid(byte[] serviceData) {
+        int idLength = getIdLength(serviceData);
+        return MIN_ID_LENGTH <= idLength
+                && idLength <= MAX_ID_LENGTH
+                && idLength + HEADER_LENGTH <= serviceData.length;
+    }
+}
+
diff --git a/nearby/service/java/com/android/server/nearby/util/ForegroundThread.java b/nearby/service/java/com/android/server/nearby/util/ForegroundThread.java
new file mode 100644
index 0000000..793ab9a
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/util/ForegroundThread.java
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.util;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+import android.os.HandlerThread;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+
+/**
+ * Shared singleton foreground thread.
+ */
+public class ForegroundThread extends HandlerThread {
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static ForegroundThread sInstance;
+    @GuardedBy("sLock")
+    private static Handler sHandler;
+    @GuardedBy("sLock")
+    private static Executor sExecutor;
+
+    private ForegroundThread() {
+        super(ForegroundThread.class.getName());
+    }
+
+    @GuardedBy("sLock")
+    private static void ensureInstanceLocked() {
+        if (sInstance == null) {
+            sInstance = new ForegroundThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+            sExecutor = new HandlerExecutor(sHandler);
+        }
+    }
+
+    /**
+     * Get the singleton instance of thi class.
+     *
+     * @return the singleton instance of thi class
+     */
+    @NonNull
+    public static ForegroundThread get() {
+        synchronized (sLock) {
+            ensureInstanceLocked();
+            return sInstance;
+        }
+    }
+
+    /**
+     * Get the {@link Handler} for this thread.
+     *
+     * @return the {@link Handler} for this thread.
+     */
+    @NonNull
+    public static Handler getHandler() {
+        synchronized (sLock) {
+            ensureInstanceLocked();
+            return sHandler;
+        }
+    }
+
+    /**
+     * Get the {@link Executor} for this thread.
+     *
+     * @return the {@link Executor} for this thread.
+     */
+    @NonNull
+    public static Executor getExecutor() {
+        synchronized (sLock) {
+            ensureInstanceLocked();
+            return sExecutor;
+        }
+    }
+
+    /**
+     * An adapter {@link Executor} that posts all executed tasks onto the given
+     * {@link Handler}.
+     */
+    private static class HandlerExecutor implements Executor {
+        private final Handler mHandler;
+
+        HandlerExecutor(@NonNull Handler handler) {
+            mHandler = Preconditions.checkNotNull(handler);
+        }
+
+        @Override
+        public void execute(Runnable command) {
+            if (!mHandler.post(command)) {
+                throw new RejectedExecutionException(mHandler + " is shutting down");
+            }
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/util/Hex.java b/nearby/service/java/com/android/server/nearby/util/Hex.java
new file mode 100644
index 0000000..1d1d855
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/util/Hex.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.util;
+
+/**
+ * Hex class that contains hex related functions.
+ */
+public class Hex {
+
+    private static final char[] HEX_UPPERCASE = {
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+
+    private static final char[] HEX_LOWERCASE = {
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+    };
+
+    /**
+     * Bytes array to lower case string.
+     */
+    public static String bytesToStringLowercase(byte[] bytes) {
+        char[] hexChars = new char[bytes.length * 2];
+        int j = 0;
+        for (byte aByte : bytes) {
+            int v = aByte & 0xFF;
+            hexChars[j++] = HEX_LOWERCASE[v >>> 4];
+            hexChars[j++] = HEX_LOWERCASE[v & 0x0F];
+        }
+        return new String(hexChars);
+    }
+
+    /**
+     * Encodes the byte array to string.
+     */
+    public static String bytesToStringUppercase(byte[] bytes) {
+        return bytesToStringUppercase(bytes, false /* zeroTerminated */);
+    }
+
+    /** Encodes a byte array as a hexadecimal representation of bytes. */
+    public static String bytesToStringUppercase(byte[] bytes, boolean zeroTerminated) {
+        int length = bytes.length;
+        StringBuilder out = new StringBuilder(length * 2);
+        for (int i = 0; i < length; i++) {
+            if (zeroTerminated && i == length - 1 && (bytes[i] & 0xff) == 0) {
+                break;
+            }
+            out.append(HEX_UPPERCASE[(bytes[i] & 0xf0) >>> 4]);
+            out.append(HEX_UPPERCASE[bytes[i] & 0x0f]);
+        }
+        return out.toString();
+    }
+    /**
+     * Converts string to byte array.
+     */
+    public static byte[] stringToBytes(String hex) throws IllegalArgumentException {
+        int length = hex.length();
+        if (length % 2 != 0) {
+            throw new IllegalArgumentException("Hex string has odd number of characters");
+        }
+        byte[] out = new byte[length / 2];
+        for (int i = 0; i < length; i += 2) {
+            // Byte.parseByte() doesn't work here because it expects a hex value in -128, 127, and
+            // our hex values are in 0, 255.
+            out[i / 2] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16);
+        }
+        return out;
+    }
+}
diff --git a/nearby/service/proto/Android.bp b/nearby/service/proto/Android.bp
new file mode 100644
index 0000000..1b00cf6
--- /dev/null
+++ b/nearby/service/proto/Android.bp
@@ -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.
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+    name: "fast-pair-lite-protos",
+    proto: {
+        type: "lite",
+        canonical_path_from_root: false,
+    },
+    sdk_version: "system_current",
+    min_sdk_version: "30",
+    srcs: ["src/fastpair/*.proto"],
+    apex_available: [
+        "com.android.tethering",
+    ],
+}
+
+java_library {
+    name: "presence-lite-protos",
+    proto: {
+        type: "lite",
+        canonical_path_from_root: false,
+    },
+    sdk_version: "system_current",
+    min_sdk_version: "30",
+    srcs: ["src/presence/*.proto"],
+    apex_available: [
+        "com.android.tethering",
+    ],
+}
\ No newline at end of file
diff --git a/nearby/service/proto/src/fastpair/cache.proto b/nearby/service/proto/src/fastpair/cache.proto
new file mode 100644
index 0000000..12731fb
--- /dev/null
+++ b/nearby/service/proto/src/fastpair/cache.proto
@@ -0,0 +1,461 @@
+syntax = "proto3";
+package service.proto;
+import "src/fastpair/rpcs.proto";
+import "src/fastpair/fast_pair_string.proto";
+
+// db information for Fast Pair that gets from server.
+message ServerResponseDbItem {
+  // Device's model id.
+  string model_id = 1;
+
+  // Response was received from the server. Contains data needed to display
+  // FastPair notification such as device name, txPower of device, image used
+  // in the notification, etc.
+  GetObservedDeviceResponse get_observed_device_response = 2;
+
+  // The timestamp that make the server fetch.
+  int64 last_fetch_info_timestamp_millis = 3;
+
+  // Whether the item in the cache is expirable or not (when offline mode this
+  // will be false).
+  bool expirable = 4;
+}
+
+
+// Client side scan result.
+message StoredScanResult {
+  // REQUIRED
+  // Unique ID generated based on scan result
+  string id = 1;
+
+  // REQUIRED
+  NearbyType type = 2;
+
+  // REQUIRED
+  // The most recent all upper case mac associated with this item.
+  // (Mac-to-DiscoveryItem is a many-to-many relationship)
+  string mac_address = 4;
+
+  // Beacon's RSSI value
+  int32 rssi = 10;
+
+  // Beacon's tx power
+  int32 tx_power = 11;
+
+  // The mac address encoded in beacon advertisement. Currently only used by
+  // chromecast.
+  string device_setup_mac = 12;
+
+  // Uptime of the device in minutes. Stops incrementing at 255.
+  int32 uptime_minutes = 13;
+
+  // REQUIRED
+  // Client timestamp when the beacon was first observed in BLE scan.
+  int64 first_observation_timestamp_millis = 14;
+
+  // REQUIRED
+  // Client timestamp when the beacon was last observed in BLE scan.
+  int64 last_observation_timestamp_millis = 15;
+
+  // Deprecated fields.
+  reserved 3, 5, 6, 7, 8, 9;
+}
+
+
+// Data for a DiscoveryItem created from server response and client scan result.
+// Only caching original data from scan result, server response, timestamps
+// and user actions. Do not save generated data in this object.
+// Next ID: 50
+message StoredDiscoveryItem {
+  enum State {
+    // Default unknown state.
+    STATE_UNKNOWN = 0;
+
+    // The item is normal.
+    STATE_ENABLED = 1;
+
+    // The item has been muted by user.
+    STATE_MUTED = 2;
+
+    // The item has been disabled by us (likely temporarily).
+    STATE_DISABLED_BY_SYSTEM = 3;
+  }
+
+  // The status of the item.
+  // TODO(b/204409421) remove enum
+  enum DebugMessageCategory {
+    // Default unknown state.
+    STATUS_UNKNOWN = 0;
+
+    // The item is valid and visible in notification.
+    STATUS_VALID_NOTIFICATION = 1;
+
+    // The item made it to list but not to notification.
+    STATUS_VALID_LIST_VIEW = 2;
+
+    // The item is filtered out on client. Never made it to list view.
+    STATUS_DISABLED_BY_CLIENT = 3;
+
+    // The item is filtered out by server. Never made it to client.
+    STATUS_DISABLED_BY_SERVER = 4;
+  }
+
+  enum ExperienceType {
+    EXPERIENCE_UNKNOWN = 0;
+    EXPERIENCE_GOOD = 1;
+    EXPERIENCE_BAD = 2;
+  }
+
+  // REQUIRED
+  // Offline item: unique ID generated on client.
+  // Online item: unique ID generated on server.
+  string id = 1;
+
+  // REQUIRED
+  NearbyType type = 2;
+
+  // REQUIRED
+  // The most recent all upper case mac associated with this item.
+  // (Mac-to-DiscoveryItem is a many-to-many relationship)
+  string mac_address = 4;
+
+  // REQUIRED
+  string action_url = 5;
+
+  // The bluetooth device name from advertisment
+  string device_name = 6;
+
+  // REQUIRED
+  // Item's title
+  string title = 7;
+
+  // Item's description.
+  string description = 8;
+
+  // The URL for display
+  string display_url = 9;
+
+  // REQUIRED
+  // Client timestamp when the beacon was last observed in BLE scan.
+  int64 last_observation_timestamp_millis = 10;
+
+  // REQUIRED
+  // Client timestamp when the beacon was first observed in BLE scan.
+  int64 first_observation_timestamp_millis = 11;
+
+  // REQUIRED
+  // Item's current state. e.g. if the item is blocked.
+  State state = 17;
+
+  // The resolved url type for the action_url.
+  ResolvedUrlType action_url_type = 19;
+
+  // The timestamp when the user is redirected to Play Store after clicking on
+  // the item.
+  int64 pending_app_install_timestamp_millis = 20;
+
+  // Beacon's RSSI value
+  int32 rssi = 22;
+
+  // Beacon's tx power
+  int32 tx_power = 23;
+
+  // Human readable name of the app designated to open the uri
+  // Used in the second line of the notification, "Open in {} app"
+  string app_name = 25;
+
+  // ID used for associating several DiscoveryItems.  These items may be
+  // visually displayed together.
+  string group_id = 26;
+
+  // The timestamp when the attachment was created on PBS server. In case there
+  // are duplicate
+  // items with the same scanId/groupID, only show the one with the latest
+  // timestamp.
+  int64 attachment_creation_sec = 28;
+
+  // Whether the attachment is created in debug namespace
+  DiscoveryAttachmentType attachment_type = 29;
+
+  // Package name of the App that owns this item.
+  string package_name = 30;
+
+  // The average star rating of the app.
+  float star_rating = 31;
+
+  // The "feature" graphic image url used for large sized list view entries.
+  string feature_graphic_url = 32;
+
+  // TriggerId identifies the trigger/beacon that is attached with a message.
+  // It's generated from server for online messages to synchronize formatting
+  // across client versions.
+  // Example:
+  // * BLE_UID: 3||deadbeef
+  // * BLE_URL: http://trigger.id
+  // See go/discovery-store-message-and-trigger-id for more details.
+  string trigger_id = 34;
+
+  // Bytes of item icon in PNG format displayed in Discovery item list.
+  bytes icon_png = 36;
+
+  // A FIFE URL of the item icon displayed in Discovery item list.
+  string icon_fife_url = 49;
+
+  // Message written to bugreport for 3P developers.(No sensitive info)
+  // null if the item is valid
+  string debug_message = 37;
+
+  // Weather the item is filtered out on server.
+  DebugMessageCategory debug_category = 38;
+
+  // Client timestamp when the trigger (e.g. beacon) was last lost (e.g. when
+  // Messages told us the beacon's no longer nearby).
+  int64 lost_millis = 41;
+
+  // The kind of expereince the user last had with this (e.g. if they dismissed
+  // the notification, that's bad; but if they tapped it, that's good).
+  ExperienceType last_user_experience = 42;
+
+  // The most recent BLE advertisement related to this item.
+  bytes ble_record_bytes = 43;
+
+  // An ID generated on the server to uniquely identify content.
+  string entity_id = 44;
+
+  // See equivalent field in NearbyItem.
+  bytes authentication_public_key_secp256r1 = 45;
+
+  // See equivalent field in NearbyItem.
+  FastPairInformation fast_pair_information = 46;
+
+  // Companion app detail.
+  CompanionAppDetails companion_detail = 47;
+
+  // Fast pair strings
+  FastPairStrings fast_pair_strings = 48;
+
+  // Deprecated fields.
+  reserved 3, 12, 13, 14, 15, 16, 18, 21, 24, 27, 33, 35, 39, 40;
+}
+enum ResolvedUrlType {
+  RESOLVED_URL_TYPE_UNKNOWN = 0;
+
+  // The url is resolved to a web page that is not a play store app.
+  // This can be considered as the default resolved type when it's
+  // not the other specific types.
+  WEBPAGE = 1;
+
+  // The url is resolved to the Google Play store app
+  // ie. play.google.com/store
+  APP = 2;
+}
+enum DiscoveryAttachmentType {
+  DISCOVERY_ATTACHMENT_TYPE_UNKNOWN = 0;
+
+  // The attachment is posted in the prod namespace (without "-debug")
+  DISCOVERY_ATTACHMENT_TYPE_NORMAL = 1;
+
+  // The attachment is posted in the debug namespace (with "-debug")
+  DISCOVERY_ATTACHMENT_TYPE_DEBUG = 2;
+}
+// Additional information relevant only for Fast Pair devices.
+message FastPairInformation {
+  // When true, Fast Pair will only create a bond with the device and not
+  // attempt to connect any profiles (for example, A2DP or HFP).
+  bool data_only_connection = 1;
+
+  // Additional images that are attached specifically for true wireless Fast
+  // Pair devices.
+  TrueWirelessHeadsetImages true_wireless_images = 3;
+
+  // When true, this device can support assistant function.
+  bool assistant_supported = 4;
+
+  // Features supported by the Fast Pair device.
+  repeated FastPairFeature features = 5;
+
+  // Optional, the name of the company producing this Fast Pair device.
+  string company_name = 6;
+
+  // Optional, the type of device.
+  DeviceType device_type = 7;
+
+  reserved 2;
+}
+
+
+enum NearbyType {
+  NEARBY_TYPE_UNKNOWN = 0;
+  // Proximity Beacon Service (PBS). This is the only type of nearbyItems which
+  // can be customized by 3p and therefore the intents passed should not be
+  // completely trusted. Deprecated already.
+  NEARBY_PROXIMITY_BEACON = 1;
+  // Physical Web URL beacon. Deprecated already.
+  NEARBY_PHYSICAL_WEB = 2;
+  // Chromecast beacon. Used on client-side only.
+  NEARBY_CHROMECAST = 3;
+  // Wear beacon. Used on client-side only.
+  NEARBY_WEAR = 4;
+  // A device (e.g. a Magic Pair device that needs to be set up). The special-
+  // case devices above (e.g. ChromeCast, Wear) might migrate to this type.
+  NEARBY_DEVICE = 6;
+  // Popular apps/urls based on user's current geo-location.
+  NEARBY_POPULAR_HERE = 7;
+
+  reserved 5;
+}
+
+// A locally cached Fast Pair device associating an account key with the
+// bluetooth address of the device.
+message StoredFastPairItem {
+  // The device's public mac address.
+  string mac_address = 1;
+
+  // The account key written to the device.
+  bytes account_key = 2;
+
+  // When user need to update provider name, enable this value to trigger
+  // writing new name to provider.
+  bool need_to_update_provider_name = 3;
+
+  // The retry times to update name into provider.
+  int32 update_name_retries = 4;
+
+  // Latest firmware version from the server.
+  string latest_firmware_version = 5;
+
+  // The firmware version that is on the device.
+  string device_firmware_version = 6;
+
+  // The timestamp from the last time we fetched the firmware version from the
+  // device.
+  int64 last_check_firmware_timestamp_millis = 7;
+
+  // The timestamp from the last time we fetched the firmware version from
+  // server.
+  int64 last_server_query_timestamp_millis = 8;
+
+  // Only allows one bloom filter check process to create gatt connection and
+  // try to read the firmware version value.
+  bool can_read_firmware = 9;
+
+  // Device's model id.
+  string model_id = 10;
+
+  // Features that this Fast Pair device supports.
+  repeated FastPairFeature features = 11;
+
+  // Keeps the stored discovery item in local cache, we can have most
+  // information of fast pair device locally without through footprints, i.e. we
+  // can have most fast pair features locally.
+  StoredDiscoveryItem discovery_item = 12;
+
+  // When true, the latest uploaded event to FMA is connected. We use
+  // it as the previous ACL state when getting the BluetoothAdapter STATE_OFF to
+  // determine if need to upload the disconnect event to FMA.
+  bool fma_state_is_connected = 13;
+
+  // Device's buffer size range.
+  repeated BufferSizeRange buffer_size_range = 18;
+
+  // The additional account key if this device could be associated with multiple
+  // accounts. Notes that for this device, the account_key field is the basic
+  // one which will not be associated with the accounts.
+  repeated bytes additional_account_key = 19;
+
+  // Deprecated fields.
+  reserved 14, 15, 16, 17;
+}
+
+// Contains information about Fast Pair devices stored through our scanner.
+// Next ID: 29
+message ScanFastPairStoreItem {
+  // Device's model id.
+  string model_id = 1;
+
+  // Device's RSSI value
+  int32 rssi = 2;
+
+  // Device's tx power
+  int32 tx_power = 3;
+
+  // Bytes of item icon in PNG format displayed in Discovery item list.
+  bytes icon_png = 4;
+
+  // A FIFE URL of the item icon displayed in Discovery item list.
+  string icon_fife_url = 28;
+
+  // Device name like "Bose QC 35".
+  string device_name = 5;
+
+  // Client timestamp when user last saw Fast Pair device.
+  int64 last_observation_timestamp_millis = 6;
+
+  // Action url after user click the notification.
+  string action_url = 7;
+
+  // Device's bluetooth address.
+  string address = 8;
+
+  // The computed threshold rssi value that would trigger FastPair notifications
+  int32 threshold_rssi = 9;
+
+  // Populated with the contents of the bloom filter in the event that
+  // the scanned device is advertising a bloom filter instead of a model id
+  bytes bloom_filter = 10;
+
+  // Device name from the BLE scan record
+  string ble_device_name = 11;
+
+  // Strings used for the FastPair UI
+  FastPairStrings fast_pair_strings = 12;
+
+  // A key used to authenticate advertising device.
+  // See NearbyItem.authentication_public_key_secp256r1 for more information.
+  bytes anti_spoofing_public_key = 13;
+
+  // When true, Fast Pair will only create a bond with the device and not
+  // attempt to connect any profiles (for example, A2DP or HFP).
+  bool data_only_connection = 14;
+
+  // The type of the manufacturer (first party, third party, etc).
+  int32 manufacturer_type_num = 15;
+
+  // Additional images that are attached specifically for true wireless Fast
+  // Pair devices.
+  TrueWirelessHeadsetImages true_wireless_images = 16;
+
+  // When true, this device can support assistant function.
+  bool assistant_supported = 17;
+
+  // Optional, the name of the company producing this Fast Pair device.
+  string company_name = 18;
+
+  // Features supported by the Fast Pair device.
+  FastPairFeature features = 19;
+
+  // The interaction type that this scan should trigger
+  InteractionType interaction_type = 20;
+
+  // The copy of the advertisement bytes, used to pass along to other
+  // apps that use Fast Pair as the discovery vehicle.
+  bytes full_ble_record = 21;
+
+  // Companion app related information
+  CompanionAppDetails companion_detail = 22;
+
+  // Client timestamp when user first saw Fast Pair device.
+  int64 first_observation_timestamp_millis = 23;
+
+  // The type of the device (wearable, headphones, etc).
+  int32 device_type_num = 24;
+
+  // The type of notification (app launch smart setup, etc).
+  NotificationType notification_type = 25;
+
+  // The customized title.
+  string customized_title = 26;
+
+  // The customized description.
+  string customized_description = 27;
+}
diff --git a/nearby/service/proto/src/fastpair/data.proto b/nearby/service/proto/src/fastpair/data.proto
new file mode 100644
index 0000000..6f4fadd
--- /dev/null
+++ b/nearby/service/proto/src/fastpair/data.proto
@@ -0,0 +1,26 @@
+syntax = "proto3";
+
+package service.proto;
+import "src/fastpair/cache.proto";
+
+// A device that has been Fast Paired with.
+message FastPairDeviceWithAccountKey {
+  // The account key which was written to the device after pairing completed.
+  bytes account_key = 1;
+
+  // The stored discovery item which represents the notification that should be
+  // associated with the device. Note, this is stored as a raw byte array
+  // instead of StoredDiscoveryItem because icing only supports proto lite and
+  // StoredDiscoveryItem is handed around as a nano proto in implementation,
+  // which are not compatible with each other.
+  StoredDiscoveryItem discovery_item = 3;
+
+  // SHA256 of "account key + headset's public address", this is used to
+  // identify the paired headset. Because of adding account key to generate the
+  // hash value, it makes the information anonymous, even for the same headset,
+  // different accounts have different values.
+  bytes sha256_account_key_public_address = 4;
+
+  // Deprecated fields.
+  reserved 2;
+}
diff --git a/nearby/service/proto/src/fastpair/fast_pair_string.proto b/nearby/service/proto/src/fastpair/fast_pair_string.proto
new file mode 100644
index 0000000..6dfc19a
--- /dev/null
+++ b/nearby/service/proto/src/fastpair/fast_pair_string.proto
@@ -0,0 +1,65 @@
+syntax = "proto2";
+
+package service.proto;
+
+message FastPairStrings {
+  // Required for initial pairing, used when there is a Google account on the
+  // device
+  optional string tap_to_pair_with_account = 1;
+
+  // Required for initial pairing, used when there is no Google account on the
+  // device
+  optional string tap_to_pair_without_account = 2;
+
+  // Description for initial pairing
+  optional string initial_pairing_description = 3;
+
+  // Description after successfully paired the device with companion app
+  // installed
+  optional string pairing_finished_companion_app_installed = 4;
+
+  // Description after successfully paired the device with companion app not
+  // installed
+  optional string pairing_finished_companion_app_not_installed = 5;
+
+  // Description when phone found the device that associates with user's account
+  // before remind user to pair with new device.
+  optional string subsequent_pairing_description = 6;
+
+  // Description when fast pair finds the user paired with device manually
+  // reminds user to opt the device into cloud.
+  optional string retroactive_pairing_description = 7;
+
+  // Description when user click setup device while device is still pairing
+  optional string wait_app_launch_description = 8;
+
+  // Description when user fail to pair with device
+  optional string pairing_fail_description = 9;
+
+  // Title to ask the user to confirm the pin code.
+  optional string confirm_pin_title = 10;
+
+  // Description to ask the user to confirm the pin code.
+  optional string confirm_pin_description = 11;
+
+  // The title of the UI to ask the user to confirm to sync contacts.
+  optional string sync_contacts_title = 12;
+
+  // The description of the UI to ask the user to confirm to sync contacts.
+  optional string sync_contacts_description = 13;
+
+  // The title of the UI to ask the user to confirm to sync SMS.
+  optional string sync_sms_title = 14;
+
+  // The description of the UI to ask the user to confirm to sync SMS.
+  optional string sync_sms_description = 15;
+
+  // The description for half sheet to ask user to setup google assistant.
+  optional string assistant_half_sheet_description = 16;
+
+  // The description for notification to ask user to setup google assistant.
+  optional string assistant_notification_description = 17;
+
+  // Description of the connect device action on TV, when user is not logged in.
+  optional string fast_pair_tv_connect_device_no_account_description = 18;
+}
diff --git a/nearby/service/proto/src/fastpair/rpcs.proto b/nearby/service/proto/src/fastpair/rpcs.proto
new file mode 100644
index 0000000..0399d09
--- /dev/null
+++ b/nearby/service/proto/src/fastpair/rpcs.proto
@@ -0,0 +1,329 @@
+// RPCs for the Nearby Console service.
+syntax = "proto3";
+
+package service.proto;
+// Response containing an observed device.
+message GetObservedDeviceResponse {
+  // The device from the request.
+  Device device = 1;
+
+  // The image icon that shows in the notification
+  bytes image = 3;
+
+  // Strings to be displayed on notifications during the pairing process.
+  ObservedDeviceStrings strings = 4;
+
+  reserved 2;
+}
+
+message Device {
+  // Output only. The server-generated ID of the device.
+  int64 id = 1;
+
+  // The pantheon project number the device is created under. Only Nearby admins
+  // can change this.
+  int64 project_number = 2;
+
+  // How the notification will be displayed to the user
+  NotificationType notification_type = 3;
+
+  // The image to show on the notification.
+  string image_url = 4;
+
+  // The name of the device.
+  string name = 5;
+
+  // The intent that will be launched via the notification.
+  string intent_uri = 6;
+
+  // The transmit power of the device's BLE chip.
+  int32 ble_tx_power = 7;
+
+  // The distance that the device must be within to show a notification.
+  // If no distance is set, we default to 0.6 meters. Only Nearby admins can
+  // change this.
+  float trigger_distance = 8;
+
+  // Output only. Fast Pair only - The anti-spoofing key pair for the device.
+  AntiSpoofingKeyPair anti_spoofing_key_pair = 9;
+
+  // Output only. The current status of the device.
+  Status status = 10;
+
+
+  // DEPRECATED - check for published_version instead.
+  // Output only.
+  // Whether the device has a different, already published version.
+  bool has_published_version = 12;
+
+  // Fast Pair only - The type of device being registered.
+  DeviceType device_type = 13;
+
+
+  // Fast Pair only - Additional images for true wireless headsets.
+  TrueWirelessHeadsetImages true_wireless_images = 15;
+
+  // Fast Pair only - When true, this device can support assistant function.
+  bool assistant_supported = 16;
+
+  // Output only.
+  // The published version of a device that has been approved to be displayed
+  // as a notification - only populated if the device has a different published
+  // version. (A device that only has a published version would not have this
+  // populated).
+  Device published_version = 17;
+
+  // Fast Pair only - When true, Fast Pair will only create a bond with the
+  // device and not attempt to connect any profiles (for example, A2DP or HFP).
+  bool data_only_connection = 18;
+
+  // Name of the company/brand that will be selling the product.
+  string company_name = 19;
+
+  repeated FastPairFeature features = 20;
+
+  // Name of the device that is displayed on the console.
+  string display_name = 21;
+
+  // How the device will be interacted with by the user when the scan record
+  // is detected.
+  InteractionType interaction_type = 22;
+
+  // Companion app information.
+  CompanionAppDetails companion_detail = 23;
+
+  reserved 11, 14;
+}
+
+
+// Represents the format of the final device notification (which is directly
+// correlated to the action taken by the notification).
+enum NotificationType {
+  // Unspecified notification type.
+  NOTIFICATION_TYPE_UNSPECIFIED = 0;
+  // Notification launches the fast pair intent.
+  // Example Notification Title: "Bose SoundLink II"
+  // Notification Description: "Tap to pair with this device"
+  FAST_PAIR = 1;
+  // Notification launches an app.
+  // Notification Title: "[X]" where X is type/name of the device.
+  // Notification Description: "Tap to setup this device"
+  APP_LAUNCH = 2;
+  // Notification launches for Nearby Setup. The notification title and
+  // description is the same as APP_LAUNCH.
+  NEARBY_SETUP = 3;
+  // Notification launches the fast pair intent, but doesn't include an anti-
+  // spoofing key. The notification title and description is the same as
+  // FAST_PAIR.
+  FAST_PAIR_ONE = 4;
+  // Notification launches Smart Setup on devices.
+  // These notifications are identical to APP_LAUNCH except that they always
+  // launch Smart Setup intents within GMSCore.
+  SMART_SETUP = 5;
+}
+
+// How the device will be interacted with when it is seen.
+enum InteractionType {
+  INTERACTION_TYPE_UNKNOWN = 0;
+  AUTO_LAUNCH = 1;
+  NOTIFICATION = 2;
+}
+
+// Features that can be enabled for a Fast Pair device.
+enum FastPairFeature {
+  FAST_PAIR_FEATURE_UNKNOWN = 0;
+  SILENCE_MODE = 1;
+  WIRELESS_CHARGING = 2;
+  DYNAMIC_BUFFER_SIZE = 3;
+  NO_PERSONALIZED_NAME = 4;
+  EDDYSTONE_TRACKING = 5;
+}
+
+message CompanionAppDetails {
+  // Companion app slice provider's authority.
+  string authority = 1;
+
+  // Companion app certificate value.
+  string certificate_hash = 2;
+
+  // Deprecated fields.
+  reserved 3;
+}
+
+// Additional images for True Wireless Fast Pair devices.
+message TrueWirelessHeadsetImages {
+  // Image URL for the left bud.
+  string left_bud_url = 1;
+
+  // Image URL for the right bud.
+  string right_bud_url = 2;
+
+  // Image URL for the case.
+  string case_url = 3;
+}
+
+// Represents the type of device that is being registered.
+enum DeviceType {
+  DEVICE_TYPE_UNSPECIFIED = 0;
+  HEADPHONES = 1;
+  SPEAKER = 2;
+  WEARABLE = 3;
+  INPUT_DEVICE = 4;
+  AUTOMOTIVE = 5;
+  OTHER = 6;
+  TRUE_WIRELESS_HEADPHONES = 7;
+  WEAR_OS = 8;
+  ANDROID_AUTO = 9;
+}
+
+// An anti-spoofing key pair for a device that allows us to verify the device is
+// broadcasting legitimately.
+message AntiSpoofingKeyPair {
+  // The private key (restricted to only be viewable by trusted clients).
+  bytes private_key = 1;
+
+  // The public key.
+  bytes public_key = 2;
+}
+
+// Various states that a customer-configured device notification can be in.
+// PUBLISHED is the only state that shows notifications to the public.
+message Status {
+  // Status types available for each device.
+  enum StatusType {
+    // Unknown status.
+    TYPE_UNSPECIFIED = 0;
+    // Drafted device.
+    DRAFT = 1;
+    // Submitted and waiting for approval.
+    SUBMITTED = 2;
+    // Fully approved and available for end users.
+    PUBLISHED = 3;
+    // Rejected and not available for end users.
+    REJECTED = 4;
+  }
+
+  // Details about a device that has been rejected.
+  message RejectionDetails {
+    // The reason for the rejection.
+    enum RejectionReason {
+      // Unspecified reason.
+      REASON_UNSPECIFIED = 0;
+      // Name is not valid.
+      NAME = 1;
+      // Image is not valid.
+      IMAGE = 2;
+      // Tests have failed.
+      TESTS = 3;
+      // Other reason.
+      OTHER = 4;
+    }
+
+    // A list of reasons the device was rejected.
+    repeated RejectionReason reasons = 1;
+    // Comment about an OTHER rejection reason.
+    string additional_comment = 2;
+  }
+
+  // The status of the device.
+  StatusType status_type = 1;
+
+  // Accompanies Status.REJECTED.
+  RejectionDetails rejection_details = 2;
+}
+
+// Strings to be displayed in notifications surfaced for a device.
+message ObservedDeviceStrings {
+  // The locale of all of the strings.
+  string locale = 1;
+
+  // The notification description for when the device is initially discovered.
+  string initial_notification_description = 2;
+
+  // The notification description for when the device is initially discovered
+  // and no account is logged in.
+  string initial_notification_description_no_account = 3;
+
+  // The notification description for once we have finished pairing and the
+  // companion app has been opened. For google assistant devices, this string will point
+  // users to setting up the assistant.
+  string open_companion_app_description = 4;
+
+  // The notification description for once we have finished pairing and the
+  // companion app needs to be updated before use.
+  string update_companion_app_description = 5;
+
+  // The notification description for once we have finished pairing and the
+  // companion app needs to be installed.
+  string download_companion_app_description = 6;
+
+  // The notification title when a pairing fails.
+  string unable_to_connect_title = 7;
+
+  // The notification summary when a pairing fails.
+  string unable_to_connect_description = 8;
+
+  // The description that helps user initially paired with device.
+  string initial_pairing_description = 9;
+
+  // The description that let user open the companion app.
+  string connect_success_companion_app_installed = 10;
+
+  // The description that let user download the companion app.
+  string connect_success_companion_app_not_installed = 11;
+
+  // The description that reminds user there is a paired device nearby.
+  string subsequent_pairing_description = 12;
+
+  // The description that reminds users opt in their device.
+  string retroactive_pairing_description = 13;
+
+  // The description that indicates companion app is about to launch.
+  string wait_launch_companion_app_description = 14;
+
+  // The description that indicates go to bluetooth settings when connection
+  // fail.
+  string fail_connect_go_to_settings_description = 15;
+
+  // The title of the UI to ask the user to confirm the pin code.
+  string confirm_pin_title = 16;
+
+  // The description of the UI to ask the user to confirm the pin code.
+  string confirm_pin_description = 17;
+
+  // The title of the UI to ask the user to confirm to sync contacts.
+  string sync_contacts_title = 18;
+
+  // The description of the UI to ask the user to confirm to sync contacts.
+  string sync_contacts_description = 19;
+
+  // The title of the UI to ask the user to confirm to sync SMS.
+  string sync_sms_title = 20;
+
+  // The description of the UI to ask the user to confirm to sync SMS.
+  string sync_sms_description = 21;
+
+  // The description in half sheet to ask user setup google assistant
+  string assistant_setup_half_sheet = 22;
+
+  // The description in notification to ask user setup google assistant
+  string assistant_setup_notification = 23;
+
+  // Description of the connect device action on TV, when user is not logged in.
+  string fast_pair_tv_connect_device_no_account_description = 24;
+}
+
+// The buffer size range of a Fast Pair devices support dynamic buffer size.
+message BufferSizeRange {
+  // The max buffer size in ms.
+  int32 max_size = 1;
+
+  // The min buffer size in ms.
+  int32 min_size = 2;
+
+  // The default buffer size in ms.
+  int32 default_size = 3;
+
+  // The codec of this buffer size range.
+  int32 codec = 4;
+}
diff --git a/nearby/service/proto/src/presence/blefilter.proto b/nearby/service/proto/src/presence/blefilter.proto
new file mode 100644
index 0000000..9f75d34
--- /dev/null
+++ b/nearby/service/proto/src/presence/blefilter.proto
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+// Proto Messages define the interface between Nearby nanoapp and its host.
+//
+// Host registers its interest in BLE event by configuring nanoapp with Filters.
+// The nanoapp keeps watching BLE events and notifies host once an event matches
+// a Filter.
+//
+// Each Filter is defined by its id (required) with optional fields of rssi,
+// uuid, MAC etc. The host should guarantee the uniqueness of ids. It is
+// convenient to assign id incrementally when adding a Filter such that its id
+// is the same as the index of the repeated field in Filters.
+//
+// The nanoapp compares each BLE event against the list of Filters, and notifies
+// host when the event matches a Filter. The Field's id will be sent back to
+// host in the FilterResult.
+//
+// It is possible for the nanoapp to return multiple ids when an event matches
+// multiple Filters.
+
+syntax = "proto2";
+
+package service.proto;
+
+// Certificate to verify BLE events from trusted devices.
+// When receiving an advertisement from a remote device, it will
+// be decrypted by authenticity_key and SHA hashed. The device
+// is verified as trusted if the hash result is equal to
+// metadata_encryption_key_tag.
+// See details in go/ns-certificates.
+message PublicateCertificate {
+  optional bytes authenticity_key = 1;
+  optional bytes metadata_encryption_key_tag = 2;
+}
+
+message PublicCredential {
+  optional bytes secret_id = 1;
+  optional bytes authenticity_key = 2;
+  optional bytes public_key = 3;
+  optional bytes encrypted_metadata = 4;
+  optional bytes encrypted_metadata_tag = 5;
+}
+
+message BleFilter {
+  optional uint32 id = 1;  // Required, unique id of this filter.
+  // Maximum delay to notify the client after an event occurs.
+  optional uint32 latency_ms = 2;
+  optional uint32 uuid = 3;
+  // MAC address of the advertising device.
+  optional bytes mac_address = 4;
+  optional bytes mac_mask = 5;
+  // Represents an action that scanners should take when they receive this
+  // packet. See go/nearby-presence-spec for details.
+  optional uint32 intent = 6;
+  // Notify the client if the advertising device is within the distance.
+  // For moving object, the distance is averaged over data sampled within
+  // the period of latency defined above.
+  optional float distance_m = 7;
+  // Used to verify the list of trusted devices.
+  repeated PublicateCertificate certficate = 8;
+}
+
+message BleFilters {
+  repeated BleFilter filter = 1;
+}
+
+// FilterResult is returned to host when a BLE event matches a Filter.
+message BleFilterResult {
+  optional uint32 id = 1;  // id of the matched Filter.
+  optional uint32 tx_power = 2;
+  optional uint32 rssi = 3;
+  optional uint32 intent = 4;
+  optional bytes bluetooth_address = 5;
+  optional PublicCredential public_credential = 6;
+}
+
+message BleFilterResults {
+  repeated BleFilterResult result = 1;
+}
diff --git a/nearby/tests/cts/fastpair/Android.bp b/nearby/tests/cts/fastpair/Android.bp
new file mode 100644
index 0000000..845ed84
--- /dev/null
+++ b/nearby/tests/cts/fastpair/Android.bp
@@ -0,0 +1,47 @@
+// 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "CtsNearbyFastPairTestCases",
+    defaults: ["cts_defaults"],
+    static_libs: [
+        "androidx.test.ext.junit",
+        "androidx.test.ext.truth",
+        "androidx.test.rules",
+        "bluetooth-test-util-lib",
+        "compatibility-device-util-axt",
+        "ctstestrunner-axt",
+        "truth-prebuilt",
+    ],
+    libs: [
+        "android.test.base",
+        "framework-bluetooth.stubs.module_lib",
+        "framework-connectivity-t.impl",
+    ],
+    srcs: ["src/**/*.java"],
+    test_suites: [
+        "cts",
+        "general-tests",
+        "mts-tethering",
+    ],
+    certificate: "platform",
+    platform_apis: true,
+    sdk_version: "module_current",
+    min_sdk_version: "30",
+    target_sdk_version: "32",
+}
diff --git a/nearby/tests/cts/fastpair/AndroidManifest.xml b/nearby/tests/cts/fastpair/AndroidManifest.xml
new file mode 100644
index 0000000..ce841f2
--- /dev/null
+++ b/nearby/tests/cts/fastpair/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.nearby.cts">
+  <uses-sdk android:minSdkVersion="32" android:targetSdkVersion="32" />
+  <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+  <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+
+  <application>
+    <uses-library android:name="android.test.runner"/>
+  </application>
+
+  <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+      android:targetPackage="android.nearby.cts"
+      android:label="CTS tests for android.nearby Fast Pair">
+    <meta-data android:name="listener"
+        android:value="com.android.cts.runner.CtsTestRunListener"/>
+  </instrumentation>
+</manifest>
diff --git a/nearby/tests/cts/fastpair/AndroidTest.xml b/nearby/tests/cts/fastpair/AndroidTest.xml
new file mode 100644
index 0000000..360bbf3
--- /dev/null
+++ b/nearby/tests/cts/fastpair/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Config for CTS Nearby Fast Pair test cases">
+  <option name="test-suite-tag" value="cts" />
+  <option name="config-descriptor:metadata" key="component" value="location" />
+  <!-- Instant cannot access NearbyManager. -->
+  <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+  <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+  <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+  <option name="config-descriptor:metadata" key="parameter" value="all_foldable_states" />
+  <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+    <option name="cleanup-apks" value="true" />
+    <option name="test-file-name" value="CtsNearbyFastPairTestCases.apk" />
+  </target_preparer>
+  <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+    <option name="package" value="android.nearby.cts" />
+  </test>
+  <!-- Only run NearbyUnitTests in MTS if the Nearby Mainline module is installed. -->
+  <object type="module_controller"
+      class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+    <option name="mainline-module-package-name" value="com.google.android.tethering" />
+  </object>
+</configuration>
diff --git a/nearby/tests/cts/fastpair/OWNERS b/nearby/tests/cts/fastpair/OWNERS
new file mode 100644
index 0000000..1756bba
--- /dev/null
+++ b/nearby/tests/cts/fastpair/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 1092133
+
+chunzhang@google.com
+weiwa@google.com
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/CredentialElementTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/CredentialElementTest.java
new file mode 100644
index 0000000..aacb6d8
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/CredentialElementTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+
+package android.nearby.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.CredentialElement;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class CredentialElementTest {
+    private static final String KEY = "SECRETE_ID";
+    private static final byte[] VALUE = new byte[]{1, 2, 3, 4};
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBuilder() {
+        CredentialElement element = new CredentialElement(KEY, VALUE);
+
+        assertThat(element.getKey()).isEqualTo(KEY);
+        assertThat(Arrays.equals(element.getValue(), VALUE)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteParcel() {
+        CredentialElement element = new CredentialElement(KEY, VALUE);
+
+        Parcel parcel = Parcel.obtain();
+        element.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        CredentialElement elementFromParcel = element.CREATOR.createFromParcel(
+                parcel);
+        parcel.recycle();
+
+        assertThat(elementFromParcel.getKey()).isEqualTo(KEY);
+        assertThat(Arrays.equals(elementFromParcel.getValue(), VALUE)).isTrue();
+    }
+
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
new file mode 100644
index 0000000..ec6e89a
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.DataElement;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class DataElementTest {
+
+    private static final int KEY = 1234;
+    private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBuilder() {
+        DataElement dataElement = new DataElement(KEY, VALUE);
+
+        assertThat(dataElement.getKey()).isEqualTo(KEY);
+        assertThat(Arrays.equals(dataElement.getValue(), VALUE)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteParcel() {
+        DataElement dataElement = new DataElement(KEY, VALUE);
+
+        Parcel parcel = Parcel.obtain();
+        dataElement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        DataElement elementFromParcel = DataElement.CREATOR.createFromParcel(
+                parcel);
+        parcel.recycle();
+
+        assertThat(elementFromParcel.getKey()).isEqualTo(KEY);
+        assertThat(Arrays.equals(elementFromParcel.getValue(), VALUE)).isTrue();
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairAntispoofKeyDeviceMetadataTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairAntispoofKeyDeviceMetadataTest.java
new file mode 100644
index 0000000..226efbb
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairAntispoofKeyDeviceMetadataTest.java
@@ -0,0 +1,214 @@
+/*
+ * 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 android.nearby.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.FastPairAntispoofKeyDeviceMetadata;
+import android.nearby.FastPairDeviceMetadata;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class FastPairAntispoofKeyDeviceMetadataTest {
+
+    private static final String ASSISTANT_SETUP_HALFSHEET = "ASSISTANT_SETUP_HALFSHEET";
+    private static final String ASSISTANT_SETUP_NOTIFICATION = "ASSISTANT_SETUP_NOTIFICATION";
+    private static final int BLE_TX_POWER  = 5;
+    private static final String CONFIRM_PIN_DESCRIPTION = "CONFIRM_PIN_DESCRIPTION";
+    private static final String CONFIRM_PIN_TITLE = "CONFIRM_PIN_TITLE";
+    private static final String CONNECT_SUCCESS_COMPANION_APP_INSTALLED =
+            "CONNECT_SUCCESS_COMPANION_APP_INSTALLED";
+    private static final String CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED =
+            "CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED";
+    private static final float DELTA = 0.001f;
+    private static final int DEVICE_TYPE = 7;
+    private static final String DOWNLOAD_COMPANION_APP_DESCRIPTION =
+            "DOWNLOAD_COMPANION_APP_DESCRIPTION";
+    private static final String FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION =
+            "FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION";
+    private static final String FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION =
+            "FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION";
+    private static final byte[] IMAGE = new byte[] {7, 9};
+    private static final String IMAGE_URL = "IMAGE_URL";
+    private static final String INITIAL_NOTIFICATION_DESCRIPTION =
+            "INITIAL_NOTIFICATION_DESCRIPTION";
+    private static final String INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT =
+            "INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT";
+    private static final String INITIAL_PAIRING_DESCRIPTION = "INITIAL_PAIRING_DESCRIPTION";
+    private static final String INTENT_URI = "INTENT_URI";
+    private static final String LOCALE = "LOCALE";
+    private static final String OPEN_COMPANION_APP_DESCRIPTION = "OPEN_COMPANION_APP_DESCRIPTION";
+    private static final String RETRO_ACTIVE_PAIRING_DESCRIPTION =
+            "RETRO_ACTIVE_PAIRING_DESCRIPTION";
+    private static final String SUBSEQUENT_PAIRING_DESCRIPTION = "SUBSEQUENT_PAIRING_DESCRIPTION";
+    private static final String SYNC_CONTACT_DESCRPTION = "SYNC_CONTACT_DESCRPTION";
+    private static final String SYNC_CONTACTS_TITLE = "SYNC_CONTACTS_TITLE";
+    private static final String SYNC_SMS_DESCRIPTION = "SYNC_SMS_DESCRIPTION";
+    private static final String SYNC_SMS_TITLE = "SYNC_SMS_TITLE";
+    private static final float TRIGGER_DISTANCE = 111;
+    private static final String TRUE_WIRELESS_IMAGE_URL_CASE = "TRUE_WIRELESS_IMAGE_URL_CASE";
+    private static final String TRUE_WIRELESS_IMAGE_URL_LEFT_BUD =
+            "TRUE_WIRELESS_IMAGE_URL_LEFT_BUD";
+    private static final String TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD =
+            "TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD";
+    private static final String UNABLE_TO_CONNECT_DESCRIPTION = "UNABLE_TO_CONNECT_DESCRIPTION";
+    private static final String UNABLE_TO_CONNECT_TITLE = "UNABLE_TO_CONNECT_TITLE";
+    private static final String UPDATE_COMPANION_APP_DESCRIPTION =
+            "UPDATE_COMPANION_APP_DESCRIPTION";
+    private static final String WAIT_LAUNCH_COMPANION_APP_DESCRIPTION =
+            "WAIT_LAUNCH_COMPANION_APP_DESCRIPTION";
+    private static final byte[] ANTI_SPOOFING_KEY = new byte[] {4, 5, 6};
+    private static final String NAME = "NAME";
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSetGetFastPairAntispoofKeyDeviceMetadataNotNull() {
+        FastPairDeviceMetadata fastPairDeviceMetadata = genFastPairDeviceMetadata();
+        FastPairAntispoofKeyDeviceMetadata fastPairAntispoofKeyDeviceMetadata =
+                genFastPairAntispoofKeyDeviceMetadata(ANTI_SPOOFING_KEY, fastPairDeviceMetadata);
+
+        assertThat(fastPairAntispoofKeyDeviceMetadata.getAntispoofPublicKey()).isEqualTo(
+                ANTI_SPOOFING_KEY);
+        ensureFastPairDeviceMetadataAsExpected(
+                fastPairAntispoofKeyDeviceMetadata.getFastPairDeviceMetadata());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSetGetFastPairAntispoofKeyDeviceMetadataNull() {
+        FastPairAntispoofKeyDeviceMetadata fastPairAntispoofKeyDeviceMetadata =
+                genFastPairAntispoofKeyDeviceMetadata(null, null);
+        assertThat(fastPairAntispoofKeyDeviceMetadata.getAntispoofPublicKey()).isEqualTo(
+                null);
+        assertThat(fastPairAntispoofKeyDeviceMetadata.getFastPairDeviceMetadata()).isEqualTo(
+                null);
+    }
+
+    /* Verifies DeviceMetadata. */
+    private static void ensureFastPairDeviceMetadataAsExpected(FastPairDeviceMetadata metadata) {
+        assertThat(metadata.getAssistantSetupHalfSheet()).isEqualTo(ASSISTANT_SETUP_HALFSHEET);
+        assertThat(metadata.getAssistantSetupNotification())
+                .isEqualTo(ASSISTANT_SETUP_NOTIFICATION);
+        assertThat(metadata.getBleTxPower()).isEqualTo(BLE_TX_POWER);
+        assertThat(metadata.getConfirmPinDescription()).isEqualTo(CONFIRM_PIN_DESCRIPTION);
+        assertThat(metadata.getConfirmPinTitle()).isEqualTo(CONFIRM_PIN_TITLE);
+        assertThat(metadata.getConnectSuccessCompanionAppInstalled())
+                .isEqualTo(CONNECT_SUCCESS_COMPANION_APP_INSTALLED);
+        assertThat(metadata.getConnectSuccessCompanionAppNotInstalled())
+                .isEqualTo(CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED);
+        assertThat(metadata.getDeviceType()).isEqualTo(DEVICE_TYPE);
+        assertThat(metadata.getDownloadCompanionAppDescription())
+                .isEqualTo(DOWNLOAD_COMPANION_APP_DESCRIPTION);
+        assertThat(metadata.getFailConnectGoToSettingsDescription())
+                .isEqualTo(FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION);
+        assertThat(metadata.getFastPairTvConnectDeviceNoAccountDescription())
+                .isEqualTo(FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION);
+        assertThat(metadata.getImage()).isEqualTo(IMAGE);
+        assertThat(metadata.getImageUrl()).isEqualTo(IMAGE_URL);
+        assertThat(metadata.getInitialNotificationDescription())
+                .isEqualTo(INITIAL_NOTIFICATION_DESCRIPTION);
+        assertThat(metadata.getInitialNotificationDescriptionNoAccount())
+                .isEqualTo(INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT);
+        assertThat(metadata.getInitialPairingDescription()).isEqualTo(INITIAL_PAIRING_DESCRIPTION);
+        assertThat(metadata.getIntentUri()).isEqualTo(INTENT_URI);
+        assertThat(metadata.getLocale()).isEqualTo(LOCALE);
+        assertThat(metadata.getName()).isEqualTo(NAME);
+        assertThat(metadata.getOpenCompanionAppDescription())
+                .isEqualTo(OPEN_COMPANION_APP_DESCRIPTION);
+        assertThat(metadata.getRetroactivePairingDescription())
+                .isEqualTo(RETRO_ACTIVE_PAIRING_DESCRIPTION);
+        assertThat(metadata.getSubsequentPairingDescription())
+                .isEqualTo(SUBSEQUENT_PAIRING_DESCRIPTION);
+        assertThat(metadata.getSyncContactsDescription()).isEqualTo(SYNC_CONTACT_DESCRPTION);
+        assertThat(metadata.getSyncContactsTitle()).isEqualTo(SYNC_CONTACTS_TITLE);
+        assertThat(metadata.getSyncSmsDescription()).isEqualTo(SYNC_SMS_DESCRIPTION);
+        assertThat(metadata.getSyncSmsTitle()).isEqualTo(SYNC_SMS_TITLE);
+        assertThat(metadata.getTriggerDistance()).isWithin(DELTA).of(TRIGGER_DISTANCE);
+        assertThat(metadata.getTrueWirelessImageUrlCase()).isEqualTo(TRUE_WIRELESS_IMAGE_URL_CASE);
+        assertThat(metadata.getTrueWirelessImageUrlLeftBud())
+                .isEqualTo(TRUE_WIRELESS_IMAGE_URL_LEFT_BUD);
+        assertThat(metadata.getTrueWirelessImageUrlRightBud())
+                .isEqualTo(TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD);
+        assertThat(metadata.getUnableToConnectDescription())
+                .isEqualTo(UNABLE_TO_CONNECT_DESCRIPTION);
+        assertThat(metadata.getUnableToConnectTitle()).isEqualTo(UNABLE_TO_CONNECT_TITLE);
+        assertThat(metadata.getUpdateCompanionAppDescription())
+                .isEqualTo(UPDATE_COMPANION_APP_DESCRIPTION);
+        assertThat(metadata.getWaitLaunchCompanionAppDescription())
+                .isEqualTo(WAIT_LAUNCH_COMPANION_APP_DESCRIPTION);
+    }
+
+    /* Generates FastPairAntispoofKeyDeviceMetadata. */
+    private static FastPairAntispoofKeyDeviceMetadata genFastPairAntispoofKeyDeviceMetadata(
+            byte[] antispoofPublicKey, FastPairDeviceMetadata deviceMetadata) {
+        FastPairAntispoofKeyDeviceMetadata.Builder builder =
+                new FastPairAntispoofKeyDeviceMetadata.Builder();
+        builder.setAntispoofPublicKey(antispoofPublicKey);
+        builder.setFastPairDeviceMetadata(deviceMetadata);
+
+        return builder.build();
+    }
+
+    /* Generates FastPairDeviceMetadata. */
+    private static FastPairDeviceMetadata genFastPairDeviceMetadata() {
+        FastPairDeviceMetadata.Builder builder = new FastPairDeviceMetadata.Builder();
+        builder.setAssistantSetupHalfSheet(ASSISTANT_SETUP_HALFSHEET);
+        builder.setAssistantSetupNotification(ASSISTANT_SETUP_NOTIFICATION);
+        builder.setBleTxPower(BLE_TX_POWER);
+        builder.setConfirmPinDescription(CONFIRM_PIN_DESCRIPTION);
+        builder.setConfirmPinTitle(CONFIRM_PIN_TITLE);
+        builder.setConnectSuccessCompanionAppInstalled(CONNECT_SUCCESS_COMPANION_APP_INSTALLED);
+        builder.setConnectSuccessCompanionAppNotInstalled(
+                CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED);
+        builder.setDeviceType(DEVICE_TYPE);
+        builder.setDownloadCompanionAppDescription(DOWNLOAD_COMPANION_APP_DESCRIPTION);
+        builder.setFailConnectGoToSettingsDescription(FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION);
+        builder.setFastPairTvConnectDeviceNoAccountDescription(
+                FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION);
+        builder.setImage(IMAGE);
+        builder.setImageUrl(IMAGE_URL);
+        builder.setInitialNotificationDescription(INITIAL_NOTIFICATION_DESCRIPTION);
+        builder.setInitialNotificationDescriptionNoAccount(
+                INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT);
+        builder.setInitialPairingDescription(INITIAL_PAIRING_DESCRIPTION);
+        builder.setIntentUri(INTENT_URI);
+        builder.setLocale(LOCALE);
+        builder.setName(NAME);
+        builder.setOpenCompanionAppDescription(OPEN_COMPANION_APP_DESCRIPTION);
+        builder.setRetroactivePairingDescription(RETRO_ACTIVE_PAIRING_DESCRIPTION);
+        builder.setSubsequentPairingDescription(SUBSEQUENT_PAIRING_DESCRIPTION);
+        builder.setSyncContactsDescription(SYNC_CONTACT_DESCRPTION);
+        builder.setSyncContactsTitle(SYNC_CONTACTS_TITLE);
+        builder.setSyncSmsDescription(SYNC_SMS_DESCRIPTION);
+        builder.setSyncSmsTitle(SYNC_SMS_TITLE);
+        builder.setTriggerDistance(TRIGGER_DISTANCE);
+        builder.setTrueWirelessImageUrlCase(TRUE_WIRELESS_IMAGE_URL_CASE);
+        builder.setTrueWirelessImageUrlLeftBud(TRUE_WIRELESS_IMAGE_URL_LEFT_BUD);
+        builder.setTrueWirelessImageUrlRightBud(TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD);
+        builder.setUnableToConnectDescription(UNABLE_TO_CONNECT_DESCRIPTION);
+        builder.setUnableToConnectTitle(UNABLE_TO_CONNECT_TITLE);
+        builder.setUpdateCompanionAppDescription(UPDATE_COMPANION_APP_DESCRIPTION);
+        builder.setWaitLaunchCompanionAppDescription(WAIT_LAUNCH_COMPANION_APP_DESCRIPTION);
+
+        return builder.build();
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderServiceTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderServiceTest.java
new file mode 100644
index 0000000..171b6e8
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderServiceTest.java
@@ -0,0 +1,1084 @@
+/*
+ * 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 android.nearby.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.accounts.Account;
+import android.content.Intent;
+import android.nearby.FastPairAccountKeyDeviceMetadata;
+import android.nearby.FastPairAntispoofKeyDeviceMetadata;
+import android.nearby.FastPairDataProviderService;
+import android.nearby.FastPairDeviceMetadata;
+import android.nearby.FastPairDiscoveryItem;
+import android.nearby.FastPairEligibleAccount;
+import android.nearby.aidl.ByteArrayParcel;
+import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel;
+import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataParcel;
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataRequestParcel;
+import android.nearby.aidl.FastPairDeviceMetadataParcel;
+import android.nearby.aidl.FastPairDiscoveryItemParcel;
+import android.nearby.aidl.FastPairEligibleAccountParcel;
+import android.nearby.aidl.FastPairEligibleAccountsRequestParcel;
+import android.nearby.aidl.FastPairManageAccountDeviceRequestParcel;
+import android.nearby.aidl.FastPairManageAccountRequestParcel;
+import android.nearby.aidl.IFastPairAccountDevicesMetadataCallback;
+import android.nearby.aidl.IFastPairAntispoofKeyDeviceMetadataCallback;
+import android.nearby.aidl.IFastPairDataProvider;
+import android.nearby.aidl.IFastPairEligibleAccountsCallback;
+import android.nearby.aidl.IFastPairManageAccountCallback;
+import android.nearby.aidl.IFastPairManageAccountDeviceCallback;
+
+import androidx.annotation.NonNull;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+
+@RunWith(AndroidJUnit4.class)
+public class FastPairDataProviderServiceTest {
+
+    private static final String TAG = "FastPairDataProviderServiceTest";
+
+    private static final String ASSISTANT_SETUP_HALFSHEET = "ASSISTANT_SETUP_HALFSHEET";
+    private static final String ASSISTANT_SETUP_NOTIFICATION = "ASSISTANT_SETUP_NOTIFICATION";
+    private static final int BLE_TX_POWER  = 5;
+    private static final String CONFIRM_PIN_DESCRIPTION = "CONFIRM_PIN_DESCRIPTION";
+    private static final String CONFIRM_PIN_TITLE = "CONFIRM_PIN_TITLE";
+    private static final String CONNECT_SUCCESS_COMPANION_APP_INSTALLED =
+            "CONNECT_SUCCESS_COMPANION_APP_INSTALLED";
+    private static final String CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED =
+            "CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED";
+    private static final float DELTA = 0.001f;
+    private static final int DEVICE_TYPE = 7;
+    private static final String DOWNLOAD_COMPANION_APP_DESCRIPTION =
+            "DOWNLOAD_COMPANION_APP_DESCRIPTION";
+    private static final Account ELIGIBLE_ACCOUNT_1 = new Account("abc@google.com", "type1");
+    private static final boolean ELIGIBLE_ACCOUNT_1_OPT_IN = true;
+    private static final Account ELIGIBLE_ACCOUNT_2 = new Account("def@gmail.com", "type2");
+    private static final boolean ELIGIBLE_ACCOUNT_2_OPT_IN = false;
+    private static final Account MANAGE_ACCOUNT = new Account("ghi@gmail.com", "type3");
+    private static final Account ACCOUNTDEVICES_METADATA_ACCOUNT =
+            new Account("jk@gmail.com", "type4");
+    private static final int NUM_ACCOUNT_DEVICES = 2;
+
+    private static final int ERROR_CODE_BAD_REQUEST =
+            FastPairDataProviderService.ERROR_CODE_BAD_REQUEST;
+    private static final int MANAGE_ACCOUNT_REQUEST_TYPE =
+            FastPairDataProviderService.MANAGE_REQUEST_ADD;
+    private static final String ERROR_STRING = "ERROR_STRING";
+    private static final String FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION =
+            "FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION";
+    private static final String FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION =
+            "FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION";
+    private static final byte[] IMAGE = new byte[] {7, 9};
+    private static final String IMAGE_URL = "IMAGE_URL";
+    private static final String INITIAL_NOTIFICATION_DESCRIPTION =
+            "INITIAL_NOTIFICATION_DESCRIPTION";
+    private static final String INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT =
+            "INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT";
+    private static final String INITIAL_PAIRING_DESCRIPTION = "INITIAL_PAIRING_DESCRIPTION";
+    private static final String INTENT_URI = "INTENT_URI";
+    private static final String LOCALE = "LOCALE";
+    private static final String OPEN_COMPANION_APP_DESCRIPTION = "OPEN_COMPANION_APP_DESCRIPTION";
+    private static final String RETRO_ACTIVE_PAIRING_DESCRIPTION =
+            "RETRO_ACTIVE_PAIRING_DESCRIPTION";
+    private static final String SUBSEQUENT_PAIRING_DESCRIPTION = "SUBSEQUENT_PAIRING_DESCRIPTION";
+    private static final String SYNC_CONTACT_DESCRPTION = "SYNC_CONTACT_DESCRPTION";
+    private static final String SYNC_CONTACTS_TITLE = "SYNC_CONTACTS_TITLE";
+    private static final String SYNC_SMS_DESCRIPTION = "SYNC_SMS_DESCRIPTION";
+    private static final String SYNC_SMS_TITLE = "SYNC_SMS_TITLE";
+    private static final float TRIGGER_DISTANCE = 111;
+    private static final String TRUE_WIRELESS_IMAGE_URL_CASE = "TRUE_WIRELESS_IMAGE_URL_CASE";
+    private static final String TRUE_WIRELESS_IMAGE_URL_LEFT_BUD =
+            "TRUE_WIRELESS_IMAGE_URL_LEFT_BUD";
+    private static final String TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD =
+            "TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD";
+    private static final String UNABLE_TO_CONNECT_DESCRIPTION = "UNABLE_TO_CONNECT_DESCRIPTION";
+    private static final String UNABLE_TO_CONNECT_TITLE = "UNABLE_TO_CONNECT_TITLE";
+    private static final String UPDATE_COMPANION_APP_DESCRIPTION =
+            "UPDATE_COMPANION_APP_DESCRIPTION";
+    private static final String WAIT_LAUNCH_COMPANION_APP_DESCRIPTION =
+            "WAIT_LAUNCH_COMPANION_APP_DESCRIPTION";
+    private static final byte[] ACCOUNT_KEY = new byte[] {3};
+    private static final byte[] ACCOUNT_KEY_2 = new byte[] {9, 3};
+    private static final byte[] SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS = new byte[] {2, 8};
+    private static final byte[] REQUEST_MODEL_ID = new byte[] {1, 2, 3};
+    private static final byte[] ANTI_SPOOFING_KEY = new byte[] {4, 5, 6};
+    private static final String ACTION_URL = "ACTION_URL";
+    private static final int ACTION_URL_TYPE = 5;
+    private static final String APP_NAME = "APP_NAME";
+    private static final int ATTACHMENT_TYPE = 8;
+    private static final byte[] AUTHENTICATION_PUBLIC_KEY_SEC_P256R1 = new byte[] {5, 7};
+    private static final byte[] BLE_RECORD_BYTES = new byte[]{2, 4};
+    private static final int DEBUG_CATEGORY = 9;
+    private static final String DEBUG_MESSAGE = "DEBUG_MESSAGE";
+    private static final String DESCRIPTION = "DESCRIPTION";
+    private static final String DEVICE_NAME = "DEVICE_NAME";
+    private static final String DISPLAY_URL = "DISPLAY_URL";
+    private static final String ENTITY_ID = "ENTITY_ID";
+    private static final String FEATURE_GRAPHIC_URL = "FEATURE_GRAPHIC_URL";
+    private static final long FIRST_OBSERVATION_TIMESTAMP_MILLIS = 8393L;
+    private static final String GROUP_ID = "GROUP_ID";
+    private static final String  ICON_FIFE_URL = "ICON_FIFE_URL";
+    private static final byte[]  ICON_PNG = new byte[]{2, 5};
+    private static final String ID = "ID";
+    private static final long LAST_OBSERVATION_TIMESTAMP_MILLIS = 934234L;
+    private static final int LAST_USER_EXPERIENCE = 93;
+    private static final long LOST_MILLIS = 393284L;
+    private static final String MAC_ADDRESS = "MAC_ADDRESS";
+    private static final String NAME = "NAME";
+    private static final String PACKAGE_NAME = "PACKAGE_NAME";
+    private static final long PENDING_APP_INSTALL_TIMESTAMP_MILLIS = 832393L;
+    private static final int RSSI = 9;
+    private static final int STATE = 63;
+    private static final String TITLE = "TITLE";
+    private static final String TRIGGER_ID = "TRIGGER_ID";
+    private static final int TX_POWER = 62;
+    private static final int TYPE = 73;
+    private static final String BLE_ADDRESS = "BLE_ADDRESS";
+
+    private static final int ELIGIBLE_ACCOUNTS_NUM = 2;
+    private static final ImmutableList<FastPairEligibleAccount> ELIGIBLE_ACCOUNTS =
+            ImmutableList.of(
+                    genHappyPathFastPairEligibleAccount(ELIGIBLE_ACCOUNT_1,
+                            ELIGIBLE_ACCOUNT_1_OPT_IN),
+                    genHappyPathFastPairEligibleAccount(ELIGIBLE_ACCOUNT_2,
+                            ELIGIBLE_ACCOUNT_2_OPT_IN));
+    private static final int ACCOUNTKEY_DEVICE_NUM = 2;
+    private static final ImmutableList<FastPairAccountKeyDeviceMetadata>
+            FAST_PAIR_ACCOUNT_DEVICES_METADATA =
+            ImmutableList.of(
+                    genHappyPathFastPairAccountkeyDeviceMetadata(),
+                    genHappyPathFastPairAccountkeyDeviceMetadata());
+
+    private static final FastPairAntispoofKeyDeviceMetadataRequestParcel
+            FAST_PAIR_ANTI_SPOOF_KEY_DEVICE_METADATA_REQUEST_PARCEL =
+            genFastPairAntispoofKeyDeviceMetadataRequestParcel();
+    private static final FastPairAccountDevicesMetadataRequestParcel
+            FAST_PAIR_ACCOUNT_DEVICES_METADATA_REQUEST_PARCEL =
+            genFastPairAccountDevicesMetadataRequestParcel();
+    private static final FastPairEligibleAccountsRequestParcel
+            FAST_PAIR_ELIGIBLE_ACCOUNTS_REQUEST_PARCEL =
+            genFastPairEligibleAccountsRequestParcel();
+    private static final FastPairManageAccountRequestParcel
+            FAST_PAIR_MANAGE_ACCOUNT_REQUEST_PARCEL =
+            genFastPairManageAccountRequestParcel();
+    private static final FastPairManageAccountDeviceRequestParcel
+            FAST_PAIR_MANAGE_ACCOUNT_DEVICE_REQUEST_PARCEL =
+            genFastPairManageAccountDeviceRequestParcel();
+    private static final FastPairAntispoofKeyDeviceMetadata
+            HAPPY_PATH_FAST_PAIR_ANTI_SPOOF_KEY_DEVICE_METADATA =
+            genHappyPathFastPairAntispoofKeyDeviceMetadata();
+
+    @Captor private ArgumentCaptor<FastPairEligibleAccountParcel[]>
+            mFastPairEligibleAccountParcelsArgumentCaptor;
+    @Captor private ArgumentCaptor<FastPairAccountKeyDeviceMetadataParcel[]>
+            mFastPairAccountKeyDeviceMetadataParcelsArgumentCaptor;
+
+    @Mock private FastPairDataProviderService mMockFastPairDataProviderService;
+    @Mock private IFastPairAntispoofKeyDeviceMetadataCallback.Stub
+            mAntispoofKeyDeviceMetadataCallback;
+    @Mock private IFastPairAccountDevicesMetadataCallback.Stub mAccountDevicesMetadataCallback;
+    @Mock private IFastPairEligibleAccountsCallback.Stub mEligibleAccountsCallback;
+    @Mock private IFastPairManageAccountCallback.Stub mManageAccountCallback;
+    @Mock private IFastPairManageAccountDeviceCallback.Stub mManageAccountDeviceCallback;
+
+    private MyHappyPathProvider mHappyPathFastPairDataProvider;
+    private MyErrorPathProvider mErrorPathFastPairDataProvider;
+
+    @Before
+    public void setUp() throws Exception {
+        initMocks(this);
+
+        mHappyPathFastPairDataProvider =
+                new MyHappyPathProvider(TAG, mMockFastPairDataProviderService);
+        mErrorPathFastPairDataProvider =
+                new MyErrorPathProvider(TAG, mMockFastPairDataProviderService);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHappyPathLoadFastPairAntispoofKeyDeviceMetadata() throws Exception {
+        // AOSP sends calls to OEM via Parcelable.
+        mHappyPathFastPairDataProvider.asProvider().loadFastPairAntispoofKeyDeviceMetadata(
+                FAST_PAIR_ANTI_SPOOF_KEY_DEVICE_METADATA_REQUEST_PARCEL,
+                mAntispoofKeyDeviceMetadataCallback);
+
+        // OEM receives request and verifies that it is as expected.
+        final ArgumentCaptor<FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataRequest>
+                fastPairAntispoofKeyDeviceMetadataRequestCaptor =
+                ArgumentCaptor.forClass(
+                        FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataRequest.class
+                );
+        verify(mMockFastPairDataProviderService).onLoadFastPairAntispoofKeyDeviceMetadata(
+                fastPairAntispoofKeyDeviceMetadataRequestCaptor.capture(),
+                any(FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataCallback.class));
+        ensureHappyPathAsExpected(fastPairAntispoofKeyDeviceMetadataRequestCaptor.getValue());
+
+        // AOSP receives responses and verifies that it is as expected.
+        final ArgumentCaptor<FastPairAntispoofKeyDeviceMetadataParcel>
+                fastPairAntispoofKeyDeviceMetadataParcelCaptor =
+                ArgumentCaptor.forClass(FastPairAntispoofKeyDeviceMetadataParcel.class);
+        verify(mAntispoofKeyDeviceMetadataCallback).onFastPairAntispoofKeyDeviceMetadataReceived(
+                fastPairAntispoofKeyDeviceMetadataParcelCaptor.capture());
+        ensureHappyPathAsExpected(fastPairAntispoofKeyDeviceMetadataParcelCaptor.getValue());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHappyPathLoadFastPairAccountDevicesMetadata() throws Exception {
+        // AOSP sends calls to OEM via Parcelable.
+        mHappyPathFastPairDataProvider.asProvider().loadFastPairAccountDevicesMetadata(
+                FAST_PAIR_ACCOUNT_DEVICES_METADATA_REQUEST_PARCEL,
+                mAccountDevicesMetadataCallback);
+
+        // OEM receives request and verifies that it is as expected.
+        final ArgumentCaptor<FastPairDataProviderService.FastPairAccountDevicesMetadataRequest>
+                fastPairAccountDevicesMetadataRequestCaptor =
+                ArgumentCaptor.forClass(
+                        FastPairDataProviderService.FastPairAccountDevicesMetadataRequest.class);
+        verify(mMockFastPairDataProviderService).onLoadFastPairAccountDevicesMetadata(
+                fastPairAccountDevicesMetadataRequestCaptor.capture(),
+                any(FastPairDataProviderService.FastPairAccountDevicesMetadataCallback.class));
+        ensureHappyPathAsExpected(fastPairAccountDevicesMetadataRequestCaptor.getValue());
+
+        // AOSP receives responses and verifies that it is as expected.
+        verify(mAccountDevicesMetadataCallback).onFastPairAccountDevicesMetadataReceived(
+                mFastPairAccountKeyDeviceMetadataParcelsArgumentCaptor.capture());
+        ensureHappyPathAsExpected(
+                mFastPairAccountKeyDeviceMetadataParcelsArgumentCaptor.getValue());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHappyPathLoadFastPairEligibleAccounts() throws Exception {
+        // AOSP sends calls to OEM via Parcelable.
+        mHappyPathFastPairDataProvider.asProvider().loadFastPairEligibleAccounts(
+                FAST_PAIR_ELIGIBLE_ACCOUNTS_REQUEST_PARCEL,
+                mEligibleAccountsCallback);
+
+        // OEM receives request and verifies that it is as expected.
+        final ArgumentCaptor<FastPairDataProviderService.FastPairEligibleAccountsRequest>
+                fastPairEligibleAccountsRequestCaptor =
+                ArgumentCaptor.forClass(
+                        FastPairDataProviderService.FastPairEligibleAccountsRequest.class);
+        verify(mMockFastPairDataProviderService).onLoadFastPairEligibleAccounts(
+                fastPairEligibleAccountsRequestCaptor.capture(),
+                any(FastPairDataProviderService.FastPairEligibleAccountsCallback.class));
+        ensureHappyPathAsExpected(fastPairEligibleAccountsRequestCaptor.getValue());
+
+        // AOSP receives responses and verifies that it is as expected.
+        verify(mEligibleAccountsCallback).onFastPairEligibleAccountsReceived(
+                mFastPairEligibleAccountParcelsArgumentCaptor.capture());
+        ensureHappyPathAsExpected(mFastPairEligibleAccountParcelsArgumentCaptor.getValue());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHappyPathManageFastPairAccount() throws Exception {
+        // AOSP sends calls to OEM via Parcelable.
+        mHappyPathFastPairDataProvider.asProvider().manageFastPairAccount(
+                FAST_PAIR_MANAGE_ACCOUNT_REQUEST_PARCEL,
+                mManageAccountCallback);
+
+        // OEM receives request and verifies that it is as expected.
+        final ArgumentCaptor<FastPairDataProviderService.FastPairManageAccountRequest>
+                fastPairManageAccountRequestCaptor =
+                ArgumentCaptor.forClass(
+                        FastPairDataProviderService.FastPairManageAccountRequest.class);
+        verify(mMockFastPairDataProviderService).onManageFastPairAccount(
+                fastPairManageAccountRequestCaptor.capture(),
+                any(FastPairDataProviderService.FastPairManageActionCallback.class));
+        ensureHappyPathAsExpected(fastPairManageAccountRequestCaptor.getValue());
+
+        // AOSP receives SUCCESS response.
+        verify(mManageAccountCallback).onSuccess();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHappyPathManageFastPairAccountDevice() throws Exception {
+        // AOSP sends calls to OEM via Parcelable.
+        mHappyPathFastPairDataProvider.asProvider().manageFastPairAccountDevice(
+                FAST_PAIR_MANAGE_ACCOUNT_DEVICE_REQUEST_PARCEL,
+                mManageAccountDeviceCallback);
+
+        // OEM receives request and verifies that it is as expected.
+        final ArgumentCaptor<FastPairDataProviderService.FastPairManageAccountDeviceRequest>
+                fastPairManageAccountDeviceRequestCaptor =
+                ArgumentCaptor.forClass(
+                        FastPairDataProviderService.FastPairManageAccountDeviceRequest.class);
+        verify(mMockFastPairDataProviderService).onManageFastPairAccountDevice(
+                fastPairManageAccountDeviceRequestCaptor.capture(),
+                any(FastPairDataProviderService.FastPairManageActionCallback.class));
+        ensureHappyPathAsExpected(fastPairManageAccountDeviceRequestCaptor.getValue());
+
+        // AOSP receives SUCCESS response.
+        verify(mManageAccountDeviceCallback).onSuccess();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testErrorPathLoadFastPairAntispoofKeyDeviceMetadata() throws Exception {
+        mErrorPathFastPairDataProvider.asProvider().loadFastPairAntispoofKeyDeviceMetadata(
+                FAST_PAIR_ANTI_SPOOF_KEY_DEVICE_METADATA_REQUEST_PARCEL,
+                mAntispoofKeyDeviceMetadataCallback);
+        verify(mMockFastPairDataProviderService).onLoadFastPairAntispoofKeyDeviceMetadata(
+                any(FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataRequest.class),
+                any(FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataCallback.class));
+        verify(mAntispoofKeyDeviceMetadataCallback).onError(
+                eq(ERROR_CODE_BAD_REQUEST), eq(ERROR_STRING));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testErrorPathLoadFastPairAccountDevicesMetadata() throws Exception {
+        mErrorPathFastPairDataProvider.asProvider().loadFastPairAccountDevicesMetadata(
+                FAST_PAIR_ACCOUNT_DEVICES_METADATA_REQUEST_PARCEL,
+                mAccountDevicesMetadataCallback);
+        verify(mMockFastPairDataProviderService).onLoadFastPairAccountDevicesMetadata(
+                any(FastPairDataProviderService.FastPairAccountDevicesMetadataRequest.class),
+                any(FastPairDataProviderService.FastPairAccountDevicesMetadataCallback.class));
+        verify(mAccountDevicesMetadataCallback).onError(
+                eq(ERROR_CODE_BAD_REQUEST), eq(ERROR_STRING));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testErrorPathLoadFastPairEligibleAccounts() throws Exception {
+        mErrorPathFastPairDataProvider.asProvider().loadFastPairEligibleAccounts(
+                FAST_PAIR_ELIGIBLE_ACCOUNTS_REQUEST_PARCEL,
+                mEligibleAccountsCallback);
+        verify(mMockFastPairDataProviderService).onLoadFastPairEligibleAccounts(
+                any(FastPairDataProviderService.FastPairEligibleAccountsRequest.class),
+                any(FastPairDataProviderService.FastPairEligibleAccountsCallback.class));
+        verify(mEligibleAccountsCallback).onError(
+                eq(ERROR_CODE_BAD_REQUEST), eq(ERROR_STRING));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testErrorPathManageFastPairAccount() throws Exception {
+        mErrorPathFastPairDataProvider.asProvider().manageFastPairAccount(
+                FAST_PAIR_MANAGE_ACCOUNT_REQUEST_PARCEL,
+                mManageAccountCallback);
+        verify(mMockFastPairDataProviderService).onManageFastPairAccount(
+                any(FastPairDataProviderService.FastPairManageAccountRequest.class),
+                any(FastPairDataProviderService.FastPairManageActionCallback.class));
+        verify(mManageAccountCallback).onError(eq(ERROR_CODE_BAD_REQUEST), eq(ERROR_STRING));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testErrorPathManageFastPairAccountDevice() throws Exception {
+        mErrorPathFastPairDataProvider.asProvider().manageFastPairAccountDevice(
+                FAST_PAIR_MANAGE_ACCOUNT_DEVICE_REQUEST_PARCEL,
+                mManageAccountDeviceCallback);
+        verify(mMockFastPairDataProviderService).onManageFastPairAccountDevice(
+                any(FastPairDataProviderService.FastPairManageAccountDeviceRequest.class),
+                any(FastPairDataProviderService.FastPairManageActionCallback.class));
+        verify(mManageAccountDeviceCallback).onError(eq(ERROR_CODE_BAD_REQUEST), eq(ERROR_STRING));
+    }
+
+    public static class MyHappyPathProvider extends FastPairDataProviderService {
+
+        private final FastPairDataProviderService mMockFastPairDataProviderService;
+
+        public MyHappyPathProvider(@NonNull String tag, FastPairDataProviderService mock) {
+            super(tag);
+            mMockFastPairDataProviderService = mock;
+        }
+
+        public IFastPairDataProvider asProvider() {
+            Intent intent = new Intent();
+            return IFastPairDataProvider.Stub.asInterface(onBind(intent));
+        }
+
+        @Override
+        public void onLoadFastPairAntispoofKeyDeviceMetadata(
+                @NonNull FastPairAntispoofKeyDeviceMetadataRequest request,
+                @NonNull FastPairAntispoofKeyDeviceMetadataCallback callback) {
+            mMockFastPairDataProviderService.onLoadFastPairAntispoofKeyDeviceMetadata(
+                    request, callback);
+            callback.onFastPairAntispoofKeyDeviceMetadataReceived(
+                    HAPPY_PATH_FAST_PAIR_ANTI_SPOOF_KEY_DEVICE_METADATA);
+        }
+
+        @Override
+        public void onLoadFastPairAccountDevicesMetadata(
+                @NonNull FastPairAccountDevicesMetadataRequest request,
+                @NonNull FastPairAccountDevicesMetadataCallback callback) {
+            mMockFastPairDataProviderService.onLoadFastPairAccountDevicesMetadata(
+                    request, callback);
+            callback.onFastPairAccountDevicesMetadataReceived(FAST_PAIR_ACCOUNT_DEVICES_METADATA);
+        }
+
+        @Override
+        public void onLoadFastPairEligibleAccounts(
+                @NonNull FastPairEligibleAccountsRequest request,
+                @NonNull FastPairEligibleAccountsCallback callback) {
+            mMockFastPairDataProviderService.onLoadFastPairEligibleAccounts(
+                    request, callback);
+            callback.onFastPairEligibleAccountsReceived(ELIGIBLE_ACCOUNTS);
+        }
+
+        @Override
+        public void onManageFastPairAccount(
+                @NonNull FastPairManageAccountRequest request,
+                @NonNull FastPairManageActionCallback callback) {
+            mMockFastPairDataProviderService.onManageFastPairAccount(request, callback);
+            callback.onSuccess();
+        }
+
+        @Override
+        public void onManageFastPairAccountDevice(
+                @NonNull FastPairManageAccountDeviceRequest request,
+                @NonNull FastPairManageActionCallback callback) {
+            mMockFastPairDataProviderService.onManageFastPairAccountDevice(request, callback);
+            callback.onSuccess();
+        }
+    }
+
+    public static class MyErrorPathProvider extends FastPairDataProviderService {
+
+        private final FastPairDataProviderService mMockFastPairDataProviderService;
+
+        public MyErrorPathProvider(@NonNull String tag, FastPairDataProviderService mock) {
+            super(tag);
+            mMockFastPairDataProviderService = mock;
+        }
+
+        public IFastPairDataProvider asProvider() {
+            Intent intent = new Intent();
+            return IFastPairDataProvider.Stub.asInterface(onBind(intent));
+        }
+
+        @Override
+        public void onLoadFastPairAntispoofKeyDeviceMetadata(
+                @NonNull FastPairAntispoofKeyDeviceMetadataRequest request,
+                @NonNull FastPairAntispoofKeyDeviceMetadataCallback callback) {
+            mMockFastPairDataProviderService.onLoadFastPairAntispoofKeyDeviceMetadata(
+                    request, callback);
+            callback.onError(ERROR_CODE_BAD_REQUEST, ERROR_STRING);
+        }
+
+        @Override
+        public void onLoadFastPairAccountDevicesMetadata(
+                @NonNull FastPairAccountDevicesMetadataRequest request,
+                @NonNull FastPairAccountDevicesMetadataCallback callback) {
+            mMockFastPairDataProviderService.onLoadFastPairAccountDevicesMetadata(
+                    request, callback);
+            callback.onError(ERROR_CODE_BAD_REQUEST, ERROR_STRING);
+        }
+
+        @Override
+        public void onLoadFastPairEligibleAccounts(
+                @NonNull FastPairEligibleAccountsRequest request,
+                @NonNull FastPairEligibleAccountsCallback callback) {
+            mMockFastPairDataProviderService.onLoadFastPairEligibleAccounts(request, callback);
+            callback.onError(ERROR_CODE_BAD_REQUEST, ERROR_STRING);
+        }
+
+        @Override
+        public void onManageFastPairAccount(
+                @NonNull FastPairManageAccountRequest request,
+                @NonNull FastPairManageActionCallback callback) {
+            mMockFastPairDataProviderService.onManageFastPairAccount(request, callback);
+            callback.onError(ERROR_CODE_BAD_REQUEST, ERROR_STRING);
+        }
+
+        @Override
+        public void onManageFastPairAccountDevice(
+                @NonNull FastPairManageAccountDeviceRequest request,
+                @NonNull FastPairManageActionCallback callback) {
+            mMockFastPairDataProviderService.onManageFastPairAccountDevice(request, callback);
+            callback.onError(ERROR_CODE_BAD_REQUEST, ERROR_STRING);
+        }
+    }
+
+    /* Generates AntispoofKeyDeviceMetadataRequestParcel. */
+    private static FastPairAntispoofKeyDeviceMetadataRequestParcel
+            genFastPairAntispoofKeyDeviceMetadataRequestParcel() {
+        FastPairAntispoofKeyDeviceMetadataRequestParcel requestParcel =
+                new FastPairAntispoofKeyDeviceMetadataRequestParcel();
+        requestParcel.modelId = REQUEST_MODEL_ID;
+
+        return requestParcel;
+    }
+
+    /* Generates AccountDevicesMetadataRequestParcel. */
+    private static FastPairAccountDevicesMetadataRequestParcel
+            genFastPairAccountDevicesMetadataRequestParcel() {
+        FastPairAccountDevicesMetadataRequestParcel requestParcel =
+                new FastPairAccountDevicesMetadataRequestParcel();
+
+        requestParcel.account = ACCOUNTDEVICES_METADATA_ACCOUNT;
+        requestParcel.deviceAccountKeys = new ByteArrayParcel[NUM_ACCOUNT_DEVICES];
+        requestParcel.deviceAccountKeys[0] = new ByteArrayParcel();
+        requestParcel.deviceAccountKeys[1] = new ByteArrayParcel();
+        requestParcel.deviceAccountKeys[0].byteArray = ACCOUNT_KEY;
+        requestParcel.deviceAccountKeys[1].byteArray = ACCOUNT_KEY_2;
+
+        return requestParcel;
+    }
+
+    /* Generates FastPairEligibleAccountsRequestParcel. */
+    private static FastPairEligibleAccountsRequestParcel
+            genFastPairEligibleAccountsRequestParcel() {
+        FastPairEligibleAccountsRequestParcel requestParcel =
+                new FastPairEligibleAccountsRequestParcel();
+        // No fields since FastPairEligibleAccountsRequestParcel is just a place holder now.
+        return requestParcel;
+    }
+
+    /* Generates FastPairManageAccountRequestParcel. */
+    private static FastPairManageAccountRequestParcel
+            genFastPairManageAccountRequestParcel() {
+        FastPairManageAccountRequestParcel requestParcel =
+                new FastPairManageAccountRequestParcel();
+        requestParcel.account = MANAGE_ACCOUNT;
+        requestParcel.requestType = MANAGE_ACCOUNT_REQUEST_TYPE;
+
+        return requestParcel;
+    }
+
+    /* Generates FastPairManageAccountDeviceRequestParcel. */
+    private static FastPairManageAccountDeviceRequestParcel
+            genFastPairManageAccountDeviceRequestParcel() {
+        FastPairManageAccountDeviceRequestParcel requestParcel =
+                new FastPairManageAccountDeviceRequestParcel();
+        requestParcel.account = MANAGE_ACCOUNT;
+        requestParcel.requestType = MANAGE_ACCOUNT_REQUEST_TYPE;
+        requestParcel.bleAddress = BLE_ADDRESS;
+        requestParcel.accountKeyDeviceMetadata =
+                genHappyPathFastPairAccountkeyDeviceMetadataParcel();
+
+        return requestParcel;
+    }
+
+    /* Generates Happy Path AntispoofKeyDeviceMetadata. */
+    private static FastPairAntispoofKeyDeviceMetadata
+            genHappyPathFastPairAntispoofKeyDeviceMetadata() {
+        FastPairAntispoofKeyDeviceMetadata.Builder builder =
+                new FastPairAntispoofKeyDeviceMetadata.Builder();
+        builder.setAntispoofPublicKey(ANTI_SPOOFING_KEY);
+        builder.setFastPairDeviceMetadata(genHappyPathFastPairDeviceMetadata());
+
+        return builder.build();
+    }
+
+    /* Generates Happy Path FastPairAccountKeyDeviceMetadata. */
+    private static FastPairAccountKeyDeviceMetadata
+            genHappyPathFastPairAccountkeyDeviceMetadata() {
+        FastPairAccountKeyDeviceMetadata.Builder builder =
+                new FastPairAccountKeyDeviceMetadata.Builder();
+        builder.setDeviceAccountKey(ACCOUNT_KEY);
+        builder.setFastPairDeviceMetadata(genHappyPathFastPairDeviceMetadata());
+        builder.setSha256DeviceAccountKeyPublicAddress(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS);
+        builder.setFastPairDiscoveryItem(genHappyPathFastPairDiscoveryItem());
+
+        return builder.build();
+    }
+
+    /* Generates Happy Path FastPairAccountKeyDeviceMetadataParcel. */
+    private static FastPairAccountKeyDeviceMetadataParcel
+            genHappyPathFastPairAccountkeyDeviceMetadataParcel() {
+        FastPairAccountKeyDeviceMetadataParcel parcel =
+                new FastPairAccountKeyDeviceMetadataParcel();
+        parcel.deviceAccountKey = ACCOUNT_KEY;
+        parcel.metadata = genHappyPathFastPairDeviceMetadataParcel();
+        parcel.sha256DeviceAccountKeyPublicAddress = SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS;
+        parcel.discoveryItem = genHappyPathFastPairDiscoveryItemParcel();
+
+        return parcel;
+    }
+
+    /* Generates Happy Path DiscoveryItem. */
+    private static FastPairDiscoveryItem genHappyPathFastPairDiscoveryItem() {
+        FastPairDiscoveryItem.Builder builder = new FastPairDiscoveryItem.Builder();
+
+        builder.setActionUrl(ACTION_URL);
+        builder.setActionUrlType(ACTION_URL_TYPE);
+        builder.setAppName(APP_NAME);
+        builder.setAttachmentType(ATTACHMENT_TYPE);
+        builder.setAuthenticationPublicKeySecp256r1(AUTHENTICATION_PUBLIC_KEY_SEC_P256R1);
+        builder.setBleRecordBytes(BLE_RECORD_BYTES);
+        builder.setDebugCategory(DEBUG_CATEGORY);
+        builder.setDebugMessage(DEBUG_MESSAGE);
+        builder.setDescription(DESCRIPTION);
+        builder.setDeviceName(DEVICE_NAME);
+        builder.setDisplayUrl(DISPLAY_URL);
+        builder.setEntityId(ENTITY_ID);
+        builder.setFeatureGraphicUrl(FEATURE_GRAPHIC_URL);
+        builder.setFirstObservationTimestampMillis(FIRST_OBSERVATION_TIMESTAMP_MILLIS);
+        builder.setGroupId(GROUP_ID);
+        builder.setIconFfeUrl(ICON_FIFE_URL);
+        builder.setIconPng(ICON_PNG);
+        builder.setId(ID);
+        builder.setLastObservationTimestampMillis(LAST_OBSERVATION_TIMESTAMP_MILLIS);
+        builder.setLastUserExperience(LAST_USER_EXPERIENCE);
+        builder.setLostMillis(LOST_MILLIS);
+        builder.setMacAddress(MAC_ADDRESS);
+        builder.setPackageName(PACKAGE_NAME);
+        builder.setPendingAppInstallTimestampMillis(PENDING_APP_INSTALL_TIMESTAMP_MILLIS);
+        builder.setRssi(RSSI);
+        builder.setState(STATE);
+        builder.setTitle(TITLE);
+        builder.setTriggerId(TRIGGER_ID);
+        builder.setTxPower(TX_POWER);
+        builder.setType(TYPE);
+
+        return builder.build();
+    }
+
+    /* Generates Happy Path DiscoveryItemParcel. */
+    private static FastPairDiscoveryItemParcel genHappyPathFastPairDiscoveryItemParcel() {
+        FastPairDiscoveryItemParcel parcel = new FastPairDiscoveryItemParcel();
+
+        parcel.actionUrl = ACTION_URL;
+        parcel.actionUrlType = ACTION_URL_TYPE;
+        parcel.appName = APP_NAME;
+        parcel.attachmentType = ATTACHMENT_TYPE;
+        parcel.authenticationPublicKeySecp256r1 = AUTHENTICATION_PUBLIC_KEY_SEC_P256R1;
+        parcel.bleRecordBytes = BLE_RECORD_BYTES;
+        parcel.debugCategory = DEBUG_CATEGORY;
+        parcel.debugMessage = DEBUG_MESSAGE;
+        parcel.description = DESCRIPTION;
+        parcel.deviceName = DEVICE_NAME;
+        parcel.displayUrl = DISPLAY_URL;
+        parcel.entityId = ENTITY_ID;
+        parcel.featureGraphicUrl = FEATURE_GRAPHIC_URL;
+        parcel.firstObservationTimestampMillis = FIRST_OBSERVATION_TIMESTAMP_MILLIS;
+        parcel.groupId = GROUP_ID;
+        parcel.iconFifeUrl = ICON_FIFE_URL;
+        parcel.iconPng = ICON_PNG;
+        parcel.id = ID;
+        parcel.lastObservationTimestampMillis = LAST_OBSERVATION_TIMESTAMP_MILLIS;
+        parcel.lastUserExperience = LAST_USER_EXPERIENCE;
+        parcel.lostMillis = LOST_MILLIS;
+        parcel.macAddress = MAC_ADDRESS;
+        parcel.packageName = PACKAGE_NAME;
+        parcel.pendingAppInstallTimestampMillis = PENDING_APP_INSTALL_TIMESTAMP_MILLIS;
+        parcel.rssi = RSSI;
+        parcel.state = STATE;
+        parcel.title = TITLE;
+        parcel.triggerId = TRIGGER_ID;
+        parcel.txPower = TX_POWER;
+        parcel.type = TYPE;
+
+        return parcel;
+    }
+
+    /* Generates Happy Path DeviceMetadata. */
+    private static FastPairDeviceMetadata genHappyPathFastPairDeviceMetadata() {
+        FastPairDeviceMetadata.Builder builder = new FastPairDeviceMetadata.Builder();
+        builder.setAssistantSetupHalfSheet(ASSISTANT_SETUP_HALFSHEET);
+        builder.setAssistantSetupNotification(ASSISTANT_SETUP_NOTIFICATION);
+        builder.setBleTxPower(BLE_TX_POWER);
+        builder.setConfirmPinDescription(CONFIRM_PIN_DESCRIPTION);
+        builder.setConfirmPinTitle(CONFIRM_PIN_TITLE);
+        builder.setConnectSuccessCompanionAppInstalled(CONNECT_SUCCESS_COMPANION_APP_INSTALLED);
+        builder.setConnectSuccessCompanionAppNotInstalled(
+                CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED);
+        builder.setDeviceType(DEVICE_TYPE);
+        builder.setDownloadCompanionAppDescription(DOWNLOAD_COMPANION_APP_DESCRIPTION);
+        builder.setFailConnectGoToSettingsDescription(FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION);
+        builder.setFastPairTvConnectDeviceNoAccountDescription(
+                FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION);
+        builder.setImage(IMAGE);
+        builder.setImageUrl(IMAGE_URL);
+        builder.setInitialNotificationDescription(INITIAL_NOTIFICATION_DESCRIPTION);
+        builder.setInitialNotificationDescriptionNoAccount(
+                INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT);
+        builder.setInitialPairingDescription(INITIAL_PAIRING_DESCRIPTION);
+        builder.setIntentUri(INTENT_URI);
+        builder.setLocale(LOCALE);
+        builder.setName(NAME);
+        builder.setOpenCompanionAppDescription(OPEN_COMPANION_APP_DESCRIPTION);
+        builder.setRetroactivePairingDescription(RETRO_ACTIVE_PAIRING_DESCRIPTION);
+        builder.setSubsequentPairingDescription(SUBSEQUENT_PAIRING_DESCRIPTION);
+        builder.setSyncContactsDescription(SYNC_CONTACT_DESCRPTION);
+        builder.setSyncContactsTitle(SYNC_CONTACTS_TITLE);
+        builder.setSyncSmsDescription(SYNC_SMS_DESCRIPTION);
+        builder.setSyncSmsTitle(SYNC_SMS_TITLE);
+        builder.setTriggerDistance(TRIGGER_DISTANCE);
+        builder.setTrueWirelessImageUrlCase(TRUE_WIRELESS_IMAGE_URL_CASE);
+        builder.setTrueWirelessImageUrlLeftBud(TRUE_WIRELESS_IMAGE_URL_LEFT_BUD);
+        builder.setTrueWirelessImageUrlRightBud(TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD);
+        builder.setUnableToConnectDescription(UNABLE_TO_CONNECT_DESCRIPTION);
+        builder.setUnableToConnectTitle(UNABLE_TO_CONNECT_TITLE);
+        builder.setUpdateCompanionAppDescription(UPDATE_COMPANION_APP_DESCRIPTION);
+        builder.setWaitLaunchCompanionAppDescription(WAIT_LAUNCH_COMPANION_APP_DESCRIPTION);
+
+        return builder.build();
+    }
+
+    /* Generates Happy Path DeviceMetadataParcel. */
+    private static FastPairDeviceMetadataParcel genHappyPathFastPairDeviceMetadataParcel() {
+        FastPairDeviceMetadataParcel parcel = new FastPairDeviceMetadataParcel();
+
+        parcel.assistantSetupHalfSheet = ASSISTANT_SETUP_HALFSHEET;
+        parcel.assistantSetupNotification = ASSISTANT_SETUP_NOTIFICATION;
+        parcel.bleTxPower = BLE_TX_POWER;
+        parcel.confirmPinDescription = CONFIRM_PIN_DESCRIPTION;
+        parcel.confirmPinTitle = CONFIRM_PIN_TITLE;
+        parcel.connectSuccessCompanionAppInstalled = CONNECT_SUCCESS_COMPANION_APP_INSTALLED;
+        parcel.connectSuccessCompanionAppNotInstalled =
+                CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED;
+        parcel.deviceType = DEVICE_TYPE;
+        parcel.downloadCompanionAppDescription = DOWNLOAD_COMPANION_APP_DESCRIPTION;
+        parcel.failConnectGoToSettingsDescription = FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION;
+        parcel.fastPairTvConnectDeviceNoAccountDescription =
+                FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION;
+        parcel.image = IMAGE;
+        parcel.imageUrl = IMAGE_URL;
+        parcel.initialNotificationDescription = INITIAL_NOTIFICATION_DESCRIPTION;
+        parcel.initialNotificationDescriptionNoAccount =
+                INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT;
+        parcel.initialPairingDescription = INITIAL_PAIRING_DESCRIPTION;
+        parcel.intentUri = INTENT_URI;
+        parcel.locale = LOCALE;
+        parcel.name = NAME;
+        parcel.openCompanionAppDescription = OPEN_COMPANION_APP_DESCRIPTION;
+        parcel.retroactivePairingDescription = RETRO_ACTIVE_PAIRING_DESCRIPTION;
+        parcel.subsequentPairingDescription = SUBSEQUENT_PAIRING_DESCRIPTION;
+        parcel.syncContactsDescription = SYNC_CONTACT_DESCRPTION;
+        parcel.syncContactsTitle = SYNC_CONTACTS_TITLE;
+        parcel.syncSmsDescription = SYNC_SMS_DESCRIPTION;
+        parcel.syncSmsTitle = SYNC_SMS_TITLE;
+        parcel.triggerDistance = TRIGGER_DISTANCE;
+        parcel.trueWirelessImageUrlCase = TRUE_WIRELESS_IMAGE_URL_CASE;
+        parcel.trueWirelessImageUrlLeftBud = TRUE_WIRELESS_IMAGE_URL_LEFT_BUD;
+        parcel.trueWirelessImageUrlRightBud = TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD;
+        parcel.unableToConnectDescription = UNABLE_TO_CONNECT_DESCRIPTION;
+        parcel.unableToConnectTitle = UNABLE_TO_CONNECT_TITLE;
+        parcel.updateCompanionAppDescription = UPDATE_COMPANION_APP_DESCRIPTION;
+        parcel.waitLaunchCompanionAppDescription = WAIT_LAUNCH_COMPANION_APP_DESCRIPTION;
+
+        return parcel;
+    }
+
+    /* Generates Happy Path FastPairEligibleAccount. */
+    private static FastPairEligibleAccount genHappyPathFastPairEligibleAccount(
+            Account account, boolean optIn) {
+        FastPairEligibleAccount.Builder builder = new FastPairEligibleAccount.Builder();
+        builder.setAccount(account);
+        builder.setOptIn(optIn);
+
+        return builder.build();
+    }
+
+    /* Verifies Happy Path AntispoofKeyDeviceMetadataRequest. */
+    private static void ensureHappyPathAsExpected(
+            FastPairDataProviderService.FastPairAntispoofKeyDeviceMetadataRequest request) {
+        assertThat(request.getModelId()).isEqualTo(REQUEST_MODEL_ID);
+    }
+
+    /* Verifies Happy Path AccountDevicesMetadataRequest. */
+    private static void ensureHappyPathAsExpected(
+            FastPairDataProviderService.FastPairAccountDevicesMetadataRequest request) {
+        assertThat(request.getAccount()).isEqualTo(ACCOUNTDEVICES_METADATA_ACCOUNT);
+        assertThat(request.getDeviceAccountKeys().size()).isEqualTo(ACCOUNTKEY_DEVICE_NUM);
+        assertThat(request.getDeviceAccountKeys()).contains(ACCOUNT_KEY);
+        assertThat(request.getDeviceAccountKeys()).contains(ACCOUNT_KEY_2);
+    }
+
+    /* Verifies Happy Path FastPairEligibleAccountsRequest. */
+    @SuppressWarnings("UnusedVariable")
+    private static void ensureHappyPathAsExpected(
+            FastPairDataProviderService.FastPairEligibleAccountsRequest request) {
+        // No fields since FastPairEligibleAccountsRequest is just a place holder now.
+    }
+
+    /* Verifies Happy Path FastPairManageAccountRequest. */
+    private static void ensureHappyPathAsExpected(
+            FastPairDataProviderService.FastPairManageAccountRequest request) {
+        assertThat(request.getAccount()).isEqualTo(MANAGE_ACCOUNT);
+        assertThat(request.getRequestType()).isEqualTo(MANAGE_ACCOUNT_REQUEST_TYPE);
+    }
+
+    /* Verifies Happy Path FastPairManageAccountDeviceRequest. */
+    private static void ensureHappyPathAsExpected(
+            FastPairDataProviderService.FastPairManageAccountDeviceRequest request) {
+        assertThat(request.getAccount()).isEqualTo(MANAGE_ACCOUNT);
+        assertThat(request.getRequestType()).isEqualTo(MANAGE_ACCOUNT_REQUEST_TYPE);
+        assertThat(request.getBleAddress()).isEqualTo(BLE_ADDRESS);
+        ensureHappyPathAsExpected(request.getAccountKeyDeviceMetadata());
+    }
+
+    /* Verifies Happy Path AntispoofKeyDeviceMetadataParcel. */
+    private static void ensureHappyPathAsExpected(
+            FastPairAntispoofKeyDeviceMetadataParcel metadataParcel) {
+        assertThat(metadataParcel).isNotNull();
+        assertThat(metadataParcel.antispoofPublicKey).isEqualTo(ANTI_SPOOFING_KEY);
+        ensureHappyPathAsExpected(metadataParcel.deviceMetadata);
+    }
+
+    /* Verifies Happy Path FastPairAccountKeyDeviceMetadataParcel[]. */
+    private static void ensureHappyPathAsExpected(
+            FastPairAccountKeyDeviceMetadataParcel[] metadataParcels) {
+        assertThat(metadataParcels).isNotNull();
+        assertThat(metadataParcels).hasLength(ACCOUNTKEY_DEVICE_NUM);
+        for (FastPairAccountKeyDeviceMetadataParcel parcel: metadataParcels) {
+            ensureHappyPathAsExpected(parcel);
+        }
+    }
+
+    /* Verifies Happy Path FastPairAccountKeyDeviceMetadataParcel. */
+    private static void ensureHappyPathAsExpected(
+            FastPairAccountKeyDeviceMetadataParcel metadataParcel) {
+        assertThat(metadataParcel).isNotNull();
+        assertThat(metadataParcel.deviceAccountKey).isEqualTo(ACCOUNT_KEY);
+        assertThat(metadataParcel.sha256DeviceAccountKeyPublicAddress)
+                .isEqualTo(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS);
+        ensureHappyPathAsExpected(metadataParcel.metadata);
+        ensureHappyPathAsExpected(metadataParcel.discoveryItem);
+    }
+
+    /* Verifies Happy Path FastPairAccountKeyDeviceMetadata. */
+    private static void ensureHappyPathAsExpected(
+            FastPairAccountKeyDeviceMetadata metadata) {
+        assertThat(metadata.getDeviceAccountKey()).isEqualTo(ACCOUNT_KEY);
+        assertThat(metadata.getSha256DeviceAccountKeyPublicAddress())
+                .isEqualTo(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS);
+        ensureHappyPathAsExpected(metadata.getFastPairDeviceMetadata());
+        ensureHappyPathAsExpected(metadata.getFastPairDiscoveryItem());
+    }
+
+    /* Verifies Happy Path DeviceMetadataParcel. */
+    private static void ensureHappyPathAsExpected(FastPairDeviceMetadataParcel metadataParcel) {
+        assertThat(metadataParcel).isNotNull();
+
+        assertThat(metadataParcel.assistantSetupHalfSheet).isEqualTo(ASSISTANT_SETUP_HALFSHEET);
+        assertThat(metadataParcel.assistantSetupNotification).isEqualTo(
+                ASSISTANT_SETUP_NOTIFICATION);
+
+        assertThat(metadataParcel.bleTxPower).isEqualTo(BLE_TX_POWER);
+
+        assertThat(metadataParcel.confirmPinDescription).isEqualTo(CONFIRM_PIN_DESCRIPTION);
+        assertThat(metadataParcel.confirmPinTitle).isEqualTo(CONFIRM_PIN_TITLE);
+        assertThat(metadataParcel.connectSuccessCompanionAppInstalled).isEqualTo(
+                CONNECT_SUCCESS_COMPANION_APP_INSTALLED);
+        assertThat(metadataParcel.connectSuccessCompanionAppNotInstalled).isEqualTo(
+                CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED);
+
+        assertThat(metadataParcel.deviceType).isEqualTo(DEVICE_TYPE);
+        assertThat(metadataParcel.downloadCompanionAppDescription).isEqualTo(
+                DOWNLOAD_COMPANION_APP_DESCRIPTION);
+
+        assertThat(metadataParcel.failConnectGoToSettingsDescription).isEqualTo(
+                FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION);
+        assertThat(metadataParcel.fastPairTvConnectDeviceNoAccountDescription).isEqualTo(
+                FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION);
+
+        assertThat(metadataParcel.image).isEqualTo(IMAGE);
+        assertThat(metadataParcel.imageUrl).isEqualTo(IMAGE_URL);
+        assertThat(metadataParcel.initialNotificationDescription).isEqualTo(
+                INITIAL_NOTIFICATION_DESCRIPTION);
+        assertThat(metadataParcel.initialNotificationDescriptionNoAccount).isEqualTo(
+                INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT);
+        assertThat(metadataParcel.initialPairingDescription).isEqualTo(INITIAL_PAIRING_DESCRIPTION);
+        assertThat(metadataParcel.intentUri).isEqualTo(INTENT_URI);
+
+        assertThat(metadataParcel.locale).isEqualTo(LOCALE);
+        assertThat(metadataParcel.name).isEqualTo(NAME);
+
+        assertThat(metadataParcel.openCompanionAppDescription).isEqualTo(
+                OPEN_COMPANION_APP_DESCRIPTION);
+
+        assertThat(metadataParcel.retroactivePairingDescription).isEqualTo(
+                RETRO_ACTIVE_PAIRING_DESCRIPTION);
+
+        assertThat(metadataParcel.subsequentPairingDescription).isEqualTo(
+                SUBSEQUENT_PAIRING_DESCRIPTION);
+        assertThat(metadataParcel.syncContactsDescription).isEqualTo(SYNC_CONTACT_DESCRPTION);
+        assertThat(metadataParcel.syncContactsTitle).isEqualTo(SYNC_CONTACTS_TITLE);
+        assertThat(metadataParcel.syncSmsDescription).isEqualTo(SYNC_SMS_DESCRIPTION);
+        assertThat(metadataParcel.syncSmsTitle).isEqualTo(SYNC_SMS_TITLE);
+
+        assertThat(metadataParcel.triggerDistance).isWithin(DELTA).of(TRIGGER_DISTANCE);
+        assertThat(metadataParcel.trueWirelessImageUrlCase).isEqualTo(TRUE_WIRELESS_IMAGE_URL_CASE);
+        assertThat(metadataParcel.trueWirelessImageUrlLeftBud).isEqualTo(
+                TRUE_WIRELESS_IMAGE_URL_LEFT_BUD);
+        assertThat(metadataParcel.trueWirelessImageUrlRightBud).isEqualTo(
+                TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD);
+
+        assertThat(metadataParcel.unableToConnectDescription).isEqualTo(
+                UNABLE_TO_CONNECT_DESCRIPTION);
+        assertThat(metadataParcel.unableToConnectTitle).isEqualTo(UNABLE_TO_CONNECT_TITLE);
+        assertThat(metadataParcel.updateCompanionAppDescription).isEqualTo(
+                UPDATE_COMPANION_APP_DESCRIPTION);
+
+        assertThat(metadataParcel.waitLaunchCompanionAppDescription).isEqualTo(
+                WAIT_LAUNCH_COMPANION_APP_DESCRIPTION);
+    }
+
+    /* Verifies Happy Path DeviceMetadata. */
+    private static void ensureHappyPathAsExpected(FastPairDeviceMetadata metadata) {
+        assertThat(metadata.getAssistantSetupHalfSheet()).isEqualTo(ASSISTANT_SETUP_HALFSHEET);
+        assertThat(metadata.getAssistantSetupNotification())
+                .isEqualTo(ASSISTANT_SETUP_NOTIFICATION);
+        assertThat(metadata.getBleTxPower()).isEqualTo(BLE_TX_POWER);
+        assertThat(metadata.getConfirmPinDescription()).isEqualTo(CONFIRM_PIN_DESCRIPTION);
+        assertThat(metadata.getConfirmPinTitle()).isEqualTo(CONFIRM_PIN_TITLE);
+        assertThat(metadata.getConnectSuccessCompanionAppInstalled())
+                .isEqualTo(CONNECT_SUCCESS_COMPANION_APP_INSTALLED);
+        assertThat(metadata.getConnectSuccessCompanionAppNotInstalled())
+                .isEqualTo(CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED);
+        assertThat(metadata.getDeviceType()).isEqualTo(DEVICE_TYPE);
+        assertThat(metadata.getDownloadCompanionAppDescription())
+                .isEqualTo(DOWNLOAD_COMPANION_APP_DESCRIPTION);
+        assertThat(metadata.getFailConnectGoToSettingsDescription())
+                .isEqualTo(FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION);
+        assertThat(metadata.getFastPairTvConnectDeviceNoAccountDescription())
+                .isEqualTo(FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION);
+        assertThat(metadata.getImage()).isEqualTo(IMAGE);
+        assertThat(metadata.getImageUrl()).isEqualTo(IMAGE_URL);
+        assertThat(metadata.getInitialNotificationDescription())
+                .isEqualTo(INITIAL_NOTIFICATION_DESCRIPTION);
+        assertThat(metadata.getInitialNotificationDescriptionNoAccount())
+                .isEqualTo(INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT);
+        assertThat(metadata.getInitialPairingDescription()).isEqualTo(INITIAL_PAIRING_DESCRIPTION);
+        assertThat(metadata.getIntentUri()).isEqualTo(INTENT_URI);
+        assertThat(metadata.getLocale()).isEqualTo(LOCALE);
+        assertThat(metadata.getName()).isEqualTo(NAME);
+        assertThat(metadata.getOpenCompanionAppDescription())
+                .isEqualTo(OPEN_COMPANION_APP_DESCRIPTION);
+        assertThat(metadata.getRetroactivePairingDescription())
+                .isEqualTo(RETRO_ACTIVE_PAIRING_DESCRIPTION);
+        assertThat(metadata.getSubsequentPairingDescription())
+                .isEqualTo(SUBSEQUENT_PAIRING_DESCRIPTION);
+        assertThat(metadata.getSyncContactsDescription()).isEqualTo(SYNC_CONTACT_DESCRPTION);
+        assertThat(metadata.getSyncContactsTitle()).isEqualTo(SYNC_CONTACTS_TITLE);
+        assertThat(metadata.getSyncSmsDescription()).isEqualTo(SYNC_SMS_DESCRIPTION);
+        assertThat(metadata.getSyncSmsTitle()).isEqualTo(SYNC_SMS_TITLE);
+        assertThat(metadata.getTriggerDistance()).isWithin(DELTA).of(TRIGGER_DISTANCE);
+        assertThat(metadata.getTrueWirelessImageUrlCase()).isEqualTo(TRUE_WIRELESS_IMAGE_URL_CASE);
+        assertThat(metadata.getTrueWirelessImageUrlLeftBud())
+                .isEqualTo(TRUE_WIRELESS_IMAGE_URL_LEFT_BUD);
+        assertThat(metadata.getTrueWirelessImageUrlRightBud())
+                .isEqualTo(TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD);
+        assertThat(metadata.getUnableToConnectDescription())
+                .isEqualTo(UNABLE_TO_CONNECT_DESCRIPTION);
+        assertThat(metadata.getUnableToConnectTitle()).isEqualTo(UNABLE_TO_CONNECT_TITLE);
+        assertThat(metadata.getUpdateCompanionAppDescription())
+                .isEqualTo(UPDATE_COMPANION_APP_DESCRIPTION);
+        assertThat(metadata.getWaitLaunchCompanionAppDescription())
+                .isEqualTo(WAIT_LAUNCH_COMPANION_APP_DESCRIPTION);
+    }
+
+    /* Verifies Happy Path FastPairDiscoveryItemParcel. */
+    private static void ensureHappyPathAsExpected(FastPairDiscoveryItemParcel itemParcel) {
+        assertThat(itemParcel.actionUrl).isEqualTo(ACTION_URL);
+        assertThat(itemParcel.actionUrlType).isEqualTo(ACTION_URL_TYPE);
+        assertThat(itemParcel.appName).isEqualTo(APP_NAME);
+        assertThat(itemParcel.attachmentType).isEqualTo(ATTACHMENT_TYPE);
+        assertThat(itemParcel.authenticationPublicKeySecp256r1)
+                .isEqualTo(AUTHENTICATION_PUBLIC_KEY_SEC_P256R1);
+        assertThat(itemParcel.bleRecordBytes).isEqualTo(BLE_RECORD_BYTES);
+        assertThat(itemParcel.debugCategory).isEqualTo(DEBUG_CATEGORY);
+        assertThat(itemParcel.debugMessage).isEqualTo(DEBUG_MESSAGE);
+        assertThat(itemParcel.description).isEqualTo(DESCRIPTION);
+        assertThat(itemParcel.deviceName).isEqualTo(DEVICE_NAME);
+        assertThat(itemParcel.displayUrl).isEqualTo(DISPLAY_URL);
+        assertThat(itemParcel.entityId).isEqualTo(ENTITY_ID);
+        assertThat(itemParcel.featureGraphicUrl).isEqualTo(FEATURE_GRAPHIC_URL);
+        assertThat(itemParcel.firstObservationTimestampMillis)
+                .isEqualTo(FIRST_OBSERVATION_TIMESTAMP_MILLIS);
+        assertThat(itemParcel.groupId).isEqualTo(GROUP_ID);
+        assertThat(itemParcel.iconFifeUrl).isEqualTo(ICON_FIFE_URL);
+        assertThat(itemParcel.iconPng).isEqualTo(ICON_PNG);
+        assertThat(itemParcel.id).isEqualTo(ID);
+        assertThat(itemParcel.lastObservationTimestampMillis)
+                .isEqualTo(LAST_OBSERVATION_TIMESTAMP_MILLIS);
+        assertThat(itemParcel.lastUserExperience).isEqualTo(LAST_USER_EXPERIENCE);
+        assertThat(itemParcel.lostMillis).isEqualTo(LOST_MILLIS);
+        assertThat(itemParcel.macAddress).isEqualTo(MAC_ADDRESS);
+        assertThat(itemParcel.packageName).isEqualTo(PACKAGE_NAME);
+        assertThat(itemParcel.pendingAppInstallTimestampMillis)
+                .isEqualTo(PENDING_APP_INSTALL_TIMESTAMP_MILLIS);
+        assertThat(itemParcel.rssi).isEqualTo(RSSI);
+        assertThat(itemParcel.state).isEqualTo(STATE);
+        assertThat(itemParcel.title).isEqualTo(TITLE);
+        assertThat(itemParcel.triggerId).isEqualTo(TRIGGER_ID);
+        assertThat(itemParcel.txPower).isEqualTo(TX_POWER);
+        assertThat(itemParcel.type).isEqualTo(TYPE);
+    }
+
+    /* Verifies Happy Path FastPairDiscoveryItem. */
+    private static void ensureHappyPathAsExpected(FastPairDiscoveryItem item) {
+        assertThat(item.getActionUrl()).isEqualTo(ACTION_URL);
+        assertThat(item.getActionUrlType()).isEqualTo(ACTION_URL_TYPE);
+        assertThat(item.getAppName()).isEqualTo(APP_NAME);
+        assertThat(item.getAttachmentType()).isEqualTo(ATTACHMENT_TYPE);
+        assertThat(item.getAuthenticationPublicKeySecp256r1())
+                .isEqualTo(AUTHENTICATION_PUBLIC_KEY_SEC_P256R1);
+        assertThat(item.getBleRecordBytes()).isEqualTo(BLE_RECORD_BYTES);
+        assertThat(item.getDebugCategory()).isEqualTo(DEBUG_CATEGORY);
+        assertThat(item.getDebugMessage()).isEqualTo(DEBUG_MESSAGE);
+        assertThat(item.getDescription()).isEqualTo(DESCRIPTION);
+        assertThat(item.getDeviceName()).isEqualTo(DEVICE_NAME);
+        assertThat(item.getDisplayUrl()).isEqualTo(DISPLAY_URL);
+        assertThat(item.getEntityId()).isEqualTo(ENTITY_ID);
+        assertThat(item.getFeatureGraphicUrl()).isEqualTo(FEATURE_GRAPHIC_URL);
+        assertThat(item.getFirstObservationTimestampMillis())
+                .isEqualTo(FIRST_OBSERVATION_TIMESTAMP_MILLIS);
+        assertThat(item.getGroupId()).isEqualTo(GROUP_ID);
+        assertThat(item.getIconFfeUrl()).isEqualTo(ICON_FIFE_URL);
+        assertThat(item.getIconPng()).isEqualTo(ICON_PNG);
+        assertThat(item.getId()).isEqualTo(ID);
+        assertThat(item.getLastObservationTimestampMillis())
+                .isEqualTo(LAST_OBSERVATION_TIMESTAMP_MILLIS);
+        assertThat(item.getLastUserExperience()).isEqualTo(LAST_USER_EXPERIENCE);
+        assertThat(item.getLostMillis()).isEqualTo(LOST_MILLIS);
+        assertThat(item.getMacAddress()).isEqualTo(MAC_ADDRESS);
+        assertThat(item.getPackageName()).isEqualTo(PACKAGE_NAME);
+        assertThat(item.getPendingAppInstallTimestampMillis())
+                .isEqualTo(PENDING_APP_INSTALL_TIMESTAMP_MILLIS);
+        assertThat(item.getRssi()).isEqualTo(RSSI);
+        assertThat(item.getState()).isEqualTo(STATE);
+        assertThat(item.getTitle()).isEqualTo(TITLE);
+        assertThat(item.getTriggerId()).isEqualTo(TRIGGER_ID);
+        assertThat(item.getTxPower()).isEqualTo(TX_POWER);
+        assertThat(item.getType()).isEqualTo(TYPE);
+    }
+
+    /* Verifies Happy Path EligibleAccountParcel[]. */
+    private static void ensureHappyPathAsExpected(FastPairEligibleAccountParcel[] accountsParcel) {
+        assertThat(accountsParcel).hasLength(ELIGIBLE_ACCOUNTS_NUM);
+
+        assertThat(accountsParcel[0].account).isEqualTo(ELIGIBLE_ACCOUNT_1);
+        assertThat(accountsParcel[0].optIn).isEqualTo(ELIGIBLE_ACCOUNT_1_OPT_IN);
+
+        assertThat(accountsParcel[1].account).isEqualTo(ELIGIBLE_ACCOUNT_2);
+        assertThat(accountsParcel[1].optIn).isEqualTo(ELIGIBLE_ACCOUNT_2_OPT_IN);
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairEligibleAccountTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairEligibleAccountTest.java
new file mode 100644
index 0000000..0d91d4e
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairEligibleAccountTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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 android.nearby.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.accounts.Account;
+import android.nearby.FastPairEligibleAccount;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class FastPairEligibleAccountTest {
+
+    private static final Account ACCOUNT = new Account("abc@google.com", "type1");
+    private static final Account ACCOUNT_NULL = null;
+
+    private static final boolean OPT_IN_TRUE = true;
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSetGetFastPairEligibleAccountNotNull() {
+        FastPairEligibleAccount eligibleAccount =
+                genFastPairEligibleAccount(ACCOUNT, OPT_IN_TRUE);
+
+        assertThat(eligibleAccount.getAccount()).isEqualTo(ACCOUNT);
+        assertThat(eligibleAccount.isOptIn()).isEqualTo(OPT_IN_TRUE);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSetGetFastPairEligibleAccountNull() {
+        FastPairEligibleAccount eligibleAccount =
+                genFastPairEligibleAccount(ACCOUNT_NULL, OPT_IN_TRUE);
+
+        assertThat(eligibleAccount.getAccount()).isEqualTo(ACCOUNT_NULL);
+        assertThat(eligibleAccount.isOptIn()).isEqualTo(OPT_IN_TRUE);
+    }
+
+    /* Generates FastPairEligibleAccount. */
+    private static FastPairEligibleAccount genFastPairEligibleAccount(
+            Account account, boolean optIn) {
+        FastPairEligibleAccount.Builder builder = new FastPairEligibleAccount.Builder();
+        builder.setAccount(account);
+        builder.setOptIn(optIn);
+
+        return builder.build();
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
new file mode 100644
index 0000000..b9ab95f
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.NearbyDevice;
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.PublicCredential;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class NearbyDeviceParcelableTest {
+
+    private static final String BLUETOOTH_ADDRESS = "00:11:22:33:FF:EE";
+    private static final byte[] SCAN_DATA = new byte[] {1, 2, 3, 4};
+    private static final String FAST_PAIR_MODEL_ID = "1234";
+    private static final int RSSI = -60;
+
+    private NearbyDeviceParcelable.Builder mBuilder;
+
+    @Before
+    public void setUp() {
+        mBuilder =
+                new NearbyDeviceParcelable.Builder()
+                        .setName("testDevice")
+                        .setMedium(NearbyDevice.Medium.BLE)
+                        .setRssi(RSSI)
+                        .setFastPairModelId(FAST_PAIR_MODEL_ID)
+                        .setBluetoothAddress(BLUETOOTH_ADDRESS)
+                        .setData(SCAN_DATA);
+    }
+
+    /** Verify toString returns expected string. */
+    @Test
+    @SdkSuppress(minSdkVersion = 33, codeName = "T")
+    public void testToString() {
+        PublicCredential publicCredential =
+                new PublicCredential.Builder(
+                                new byte[] {1},
+                                new byte[] {2},
+                                new byte[] {3},
+                                new byte[] {4},
+                                new byte[] {5})
+                        .build();
+        NearbyDeviceParcelable nearbyDeviceParcelable =
+                mBuilder.setFastPairModelId(null)
+                        .setData(null)
+                        .setPublicCredential(publicCredential)
+                        .build();
+
+        assertThat(nearbyDeviceParcelable.toString())
+                .isEqualTo(
+                        "NearbyDeviceParcelable[name=testDevice, medium=BLE, txPower=0, rssi=-60,"
+                                + " action=0, bluetoothAddress="
+                                + BLUETOOTH_ADDRESS
+                                + ", fastPairModelId=null, data=null]");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 33, codeName = "T")
+    public void test_defaultNullFields() {
+        NearbyDeviceParcelable nearbyDeviceParcelable =
+                new NearbyDeviceParcelable.Builder()
+                        .setMedium(NearbyDevice.Medium.BLE)
+                        .setRssi(RSSI)
+                        .build();
+
+        assertThat(nearbyDeviceParcelable.getName()).isNull();
+        assertThat(nearbyDeviceParcelable.getFastPairModelId()).isNull();
+        assertThat(nearbyDeviceParcelable.getBluetoothAddress()).isNull();
+        assertThat(nearbyDeviceParcelable.getData()).isNull();
+
+        assertThat(nearbyDeviceParcelable.getMedium()).isEqualTo(NearbyDevice.Medium.BLE);
+        assertThat(nearbyDeviceParcelable.getRssi()).isEqualTo(RSSI);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 33, codeName = "T")
+    public void testWriteParcel() {
+        NearbyDeviceParcelable nearbyDeviceParcelable = mBuilder.build();
+
+        Parcel parcel = Parcel.obtain();
+        nearbyDeviceParcelable.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        NearbyDeviceParcelable actualNearbyDevice =
+                NearbyDeviceParcelable.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertThat(actualNearbyDevice.getRssi()).isEqualTo(RSSI);
+        assertThat(actualNearbyDevice.getFastPairModelId()).isEqualTo(FAST_PAIR_MODEL_ID);
+        assertThat(actualNearbyDevice.getBluetoothAddress()).isEqualTo(BLUETOOTH_ADDRESS);
+        assertThat(Arrays.equals(actualNearbyDevice.getData(), SCAN_DATA)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 33, codeName = "T")
+    public void testWriteParcel_nullModelId() {
+        NearbyDeviceParcelable nearbyDeviceParcelable = mBuilder.setFastPairModelId(null).build();
+
+        Parcel parcel = Parcel.obtain();
+        nearbyDeviceParcelable.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        NearbyDeviceParcelable actualNearbyDevice =
+                NearbyDeviceParcelable.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertThat(actualNearbyDevice.getFastPairModelId()).isNull();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 33, codeName = "T")
+    public void testWriteParcel_nullBluetoothAddress() {
+        NearbyDeviceParcelable nearbyDeviceParcelable = mBuilder.setBluetoothAddress(null).build();
+
+        Parcel parcel = Parcel.obtain();
+        nearbyDeviceParcelable.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        NearbyDeviceParcelable actualNearbyDevice =
+                NearbyDeviceParcelable.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertThat(actualNearbyDevice.getBluetoothAddress()).isNull();
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceTest.java
new file mode 100644
index 0000000..f37800a
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import android.annotation.TargetApi;
+import android.nearby.FastPairDevice;
+import android.nearby.NearbyDevice;
+import android.os.Build;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
+public class NearbyDeviceTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_isValidMedium() {
+        assertThat(NearbyDevice.isValidMedium(1)).isTrue();
+        assertThat(NearbyDevice.isValidMedium(2)).isTrue();
+
+        assertThat(NearbyDevice.isValidMedium(0)).isFalse();
+        assertThat(NearbyDevice.isValidMedium(3)).isFalse();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getMedium_fromChild() {
+        FastPairDevice fastPairDevice = new FastPairDevice.Builder()
+                .addMedium(NearbyDevice.Medium.BLE)
+                .setRssi(-60)
+                .build();
+
+        assertThat(fastPairDevice.getMediums()).contains(1);
+        assertThat(fastPairDevice.getRssi()).isEqualTo(-60);
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyFrameworkInitializerTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyFrameworkInitializerTest.java
new file mode 100644
index 0000000..cf43cb1
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyFrameworkInitializerTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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 android.nearby.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.nearby.NearbyFrameworkInitializer;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+// NearbyFrameworkInitializer was added in T
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class NearbyFrameworkInitializerTest {
+
+    @Test
+    public void testServicesRegistered() {
+        Context ctx = InstrumentationRegistry.getInstrumentation().getContext();
+        assertThat(ctx.getSystemService(Context.NEARBY_SERVICE)).isNotNull();
+    }
+
+    // registerServiceWrappers can only be called during initialization and should throw otherwise
+    @Test(expected = IllegalStateException.class)
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testThrowsException() {
+        NearbyFrameworkInitializer.registerServiceWrappers();
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyManagerTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyManagerTest.java
new file mode 100644
index 0000000..acc7ec0
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyManagerTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import static android.Manifest.permission.READ_DEVICE_CONFIG;
+import static android.Manifest.permission.WRITE_DEVICE_CONFIG;
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.UiAutomation;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.cts.BTAdapterUtils;
+import android.content.Context;
+import android.nearby.BroadcastCallback;
+import android.nearby.BroadcastRequest;
+import android.nearby.NearbyDevice;
+import android.nearby.NearbyManager;
+import android.nearby.PresenceBroadcastRequest;
+import android.nearby.PrivateCredential;
+import android.nearby.ScanCallback;
+import android.nearby.ScanRequest;
+import android.os.Build;
+import android.provider.DeviceConfig;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * TODO(b/215435939) This class doesn't include any logic yet. Because SELinux denies access to
+ * NearbyManager.
+ */
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class NearbyManagerTest {
+    private static final byte[] SALT = new byte[]{1, 2};
+    private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
+    private static final byte[] META_DATA_ENCRYPTION_KEY = new byte[14];
+    private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
+    private static final String DEVICE_NAME = "test_device";
+    private static final int BLE_MEDIUM = 1;
+
+    private Context mContext;
+    private NearbyManager mNearbyManager;
+    private UiAutomation mUiAutomation =
+            InstrumentationRegistry.getInstrumentation().getUiAutomation();
+
+    @Before
+    public void setUp() {
+        mUiAutomation.adoptShellPermissionIdentity(READ_DEVICE_CONFIG, WRITE_DEVICE_CONFIG);
+        DeviceConfig.setProperty(NAMESPACE_TETHERING, "nearby_enable_presence_broadcast_legacy",
+                "true", false);
+
+        mContext = InstrumentationRegistry.getContext();
+        mNearbyManager = mContext.getSystemService(NearbyManager.class);
+
+        enableBluetooth();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_startAndStopScan() {
+        ScanRequest scanRequest = new ScanRequest.Builder()
+                .setScanType(ScanRequest.SCAN_TYPE_FAST_PAIR)
+                .setScanMode(ScanRequest.SCAN_MODE_LOW_LATENCY)
+                .setBleEnabled(true)
+                .build();
+        ScanCallback scanCallback = new ScanCallback() {
+            @Override
+            public void onDiscovered(@NonNull NearbyDevice device) {
+            }
+
+            @Override
+            public void onUpdated(@NonNull NearbyDevice device) {
+
+            }
+
+            @Override
+            public void onLost(@NonNull NearbyDevice device) {
+
+            }
+        };
+        mNearbyManager.startScan(scanRequest, Executors.newSingleThreadExecutor(), scanCallback);
+        mNearbyManager.stopScan(scanCallback);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testStartStopBroadcast() throws InterruptedException {
+        PrivateCredential credential = new PrivateCredential.Builder(SECRETE_ID, AUTHENTICITY_KEY,
+                META_DATA_ENCRYPTION_KEY, DEVICE_NAME)
+                .setIdentityType(IDENTITY_TYPE_PRIVATE)
+                .build();
+        BroadcastRequest broadcastRequest =
+                new PresenceBroadcastRequest.Builder(
+                        Collections.singletonList(BLE_MEDIUM), SALT, credential)
+                        .addAction(123)
+                        .build();
+
+        CountDownLatch latch = new CountDownLatch(1);
+        BroadcastCallback callback = status -> {
+            latch.countDown();
+            assertThat(status).isEqualTo(BroadcastCallback.STATUS_OK);
+        };
+        mNearbyManager.startBroadcast(broadcastRequest, Executors.newSingleThreadExecutor(),
+                callback);
+        latch.await(10, TimeUnit.SECONDS);
+        mNearbyManager.stopBroadcast(callback);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSettingsEnable() {
+        NearbyManager.setFastPairScanEnabled(mContext, false);
+        assertThat(NearbyManager.getFastPairScanEnabled(mContext)).isFalse();
+    }
+
+    private void enableBluetooth() {
+        BluetoothManager manager = mContext.getSystemService(BluetoothManager.class);
+        BluetoothAdapter bluetoothAdapter = manager.getAdapter();
+        if (!bluetoothAdapter.isEnabled()) {
+            assertThat(BTAdapterUtils.enableAdapter(bluetoothAdapter, mContext)).isTrue();
+        }
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
new file mode 100644
index 0000000..1daa410
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import static android.nearby.BroadcastRequest.BROADCAST_TYPE_NEARBY_PRESENCE;
+import static android.nearby.BroadcastRequest.PRESENCE_VERSION_V0;
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.DataElement;
+import android.nearby.PresenceBroadcastRequest;
+import android.nearby.PrivateCredential;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * Tests for {@link PresenceBroadcastRequest}.
+ */
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class PresenceBroadcastRequestTest {
+
+    private static final int VERSION = PRESENCE_VERSION_V0;
+    private static final int TX_POWER = 1;
+    private static final byte[] SALT = new byte[]{1, 2};
+    private static final int ACTION_ID = 123;
+    private static final int BLE_MEDIUM = 1;
+    private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
+    private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
+    private static final byte[] METADATA_ENCRYPTION_KEY = new byte[]{1, 1, 3, 4, 5};
+    private static final int KEY = 1234;
+    private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
+    private static final String DEVICE_NAME = "test_device";
+
+    private PresenceBroadcastRequest.Builder mBuilder;
+
+    @Before
+    public void setUp() {
+        PrivateCredential credential = new PrivateCredential.Builder(SECRETE_ID, AUTHENTICITY_KEY,
+                METADATA_ENCRYPTION_KEY, DEVICE_NAME)
+                .setIdentityType(IDENTITY_TYPE_PRIVATE)
+                .build();
+        DataElement element = new DataElement(KEY, VALUE);
+        mBuilder = new PresenceBroadcastRequest.Builder(Collections.singletonList(BLE_MEDIUM), SALT,
+                credential)
+                .setTxPower(TX_POWER)
+                .setVersion(VERSION)
+                .addAction(ACTION_ID)
+                .addExtendedProperty(element);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBuilder() {
+        PresenceBroadcastRequest broadcastRequest = mBuilder.build();
+
+        assertThat(broadcastRequest.getVersion()).isEqualTo(VERSION);
+        assertThat(Arrays.equals(broadcastRequest.getSalt(), SALT)).isTrue();
+        assertThat(broadcastRequest.getTxPower()).isEqualTo(TX_POWER);
+        assertThat(broadcastRequest.getActions()).containsExactly(ACTION_ID);
+        assertThat(broadcastRequest.getExtendedProperties().get(0).getKey()).isEqualTo(
+                KEY);
+        assertThat(broadcastRequest.getMediums()).containsExactly(BLE_MEDIUM);
+        assertThat(broadcastRequest.getCredential().getIdentityType()).isEqualTo(
+                IDENTITY_TYPE_PRIVATE);
+        assertThat(broadcastRequest.getType()).isEqualTo(BROADCAST_TYPE_NEARBY_PRESENCE);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteParcel() {
+        PresenceBroadcastRequest broadcastRequest = mBuilder.build();
+
+        Parcel parcel = Parcel.obtain();
+        broadcastRequest.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        PresenceBroadcastRequest parcelRequest = PresenceBroadcastRequest.CREATOR.createFromParcel(
+                parcel);
+        parcel.recycle();
+
+        assertThat(parcelRequest.getTxPower()).isEqualTo(TX_POWER);
+        assertThat(parcelRequest.getActions()).containsExactly(ACTION_ID);
+        assertThat(parcelRequest.getExtendedProperties().get(0).getKey()).isEqualTo(
+                KEY);
+        assertThat(parcelRequest.getMediums()).containsExactly(BLE_MEDIUM);
+        assertThat(parcelRequest.getCredential().getIdentityType()).isEqualTo(
+                IDENTITY_TYPE_PRIVATE);
+        assertThat(parcelRequest.getType()).isEqualTo(BROADCAST_TYPE_NEARBY_PRESENCE);
+
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
new file mode 100644
index 0000000..5fefc68
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.DataElement;
+import android.nearby.NearbyDevice;
+import android.nearby.PresenceDevice;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/**
+ * Test for {@link PresenceDevice}.
+ */
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class PresenceDeviceTest {
+    private static final int DEVICE_TYPE = PresenceDevice.DeviceType.PHONE;
+    private static final String DEVICE_ID = "123";
+    private static final String IMAGE_URL = "http://example.com/imageUrl";
+    private static final int RSSI = -40;
+    private static final int MEDIUM = NearbyDevice.Medium.BLE;
+    private static final String DEVICE_NAME = "testDevice";
+    private static final int KEY = 1234;
+    private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
+    private static final byte[] SALT = new byte[]{2, 3};
+    private static final byte[] SECRET_ID = new byte[]{11, 13};
+    private static final byte[] ENCRYPTED_IDENTITY = new byte[]{1, 3, 5, 61};
+    private static final long DISCOVERY_MILLIS = 100L;
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBuilder() {
+        PresenceDevice device =
+                new PresenceDevice.Builder(DEVICE_ID, SALT, SECRET_ID, ENCRYPTED_IDENTITY)
+                        .setDeviceType(DEVICE_TYPE)
+                        .setDeviceImageUrl(IMAGE_URL)
+                        .addExtendedProperty(new DataElement(KEY, VALUE))
+                        .setRssi(RSSI)
+                        .addMedium(MEDIUM)
+                        .setName(DEVICE_NAME)
+                        .setDiscoveryTimestampMillis(DISCOVERY_MILLIS)
+                        .build();
+
+        assertThat(device.getDeviceType()).isEqualTo(DEVICE_TYPE);
+        assertThat(device.getDeviceId()).isEqualTo(DEVICE_ID);
+        assertThat(device.getDeviceImageUrl()).isEqualTo(IMAGE_URL);
+        DataElement dataElement = device.getExtendedProperties().get(0);
+        assertThat(dataElement.getKey()).isEqualTo(KEY);
+        assertThat(Arrays.equals(dataElement.getValue(), VALUE)).isTrue();
+        assertThat(device.getRssi()).isEqualTo(RSSI);
+        assertThat(device.getMediums()).containsExactly(MEDIUM);
+        assertThat(device.getName()).isEqualTo(DEVICE_NAME);
+        assertThat(Arrays.equals(device.getSalt(), SALT)).isTrue();
+        assertThat(Arrays.equals(device.getSecretId(), SECRET_ID)).isTrue();
+        assertThat(Arrays.equals(device.getEncryptedIdentity(), ENCRYPTED_IDENTITY)).isTrue();
+        assertThat(device.getDiscoveryTimestampMillis()).isEqualTo(DISCOVERY_MILLIS);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteParcel() {
+        PresenceDevice device =
+                new PresenceDevice.Builder(DEVICE_ID, SALT, SECRET_ID, ENCRYPTED_IDENTITY)
+                        .addExtendedProperty(new DataElement(KEY, VALUE))
+                        .setRssi(RSSI)
+                        .addMedium(MEDIUM)
+                        .setName(DEVICE_NAME)
+                        .build();
+
+        Parcel parcel = Parcel.obtain();
+        device.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        PresenceDevice parcelDevice = PresenceDevice.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertThat(parcelDevice.getDeviceId()).isEqualTo(DEVICE_ID);
+        assertThat(parcelDevice.getExtendedProperties().get(0).getKey()).isEqualTo(KEY);
+        assertThat(parcelDevice.getRssi()).isEqualTo(RSSI);
+        assertThat(parcelDevice.getMediums()).containsExactly(MEDIUM);
+        assertThat(parcelDevice.getName()).isEqualTo(DEVICE_NAME);
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
new file mode 100644
index 0000000..b7fe40a
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.DataElement;
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
+import android.nearby.ScanRequest;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link android.nearby.PresenceScanFilter}.
+ */
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class PresenceScanFilterTest {
+
+    private static final int RSSI = -40;
+    private static final int ACTION = 123;
+    private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
+    private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
+    private static final byte[] PUBLIC_KEY = new byte[]{1, 1, 2, 2};
+    private static final byte[] ENCRYPTED_METADATA = new byte[]{1, 2, 3, 4, 5};
+    private static final byte[] METADATA_ENCRYPTION_KEY_TAG = new byte[]{1, 1, 3, 4, 5};
+    private static final int KEY = 1234;
+    private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
+
+
+    private PublicCredential mPublicCredential =
+            new PublicCredential.Builder(SECRETE_ID, AUTHENTICITY_KEY, PUBLIC_KEY,
+                    ENCRYPTED_METADATA, METADATA_ENCRYPTION_KEY_TAG)
+                    .setIdentityType(IDENTITY_TYPE_PRIVATE)
+                    .build();
+    private PresenceScanFilter.Builder mBuilder = new PresenceScanFilter.Builder()
+            .setMaxPathLoss(RSSI)
+            .addCredential(mPublicCredential)
+            .addPresenceAction(ACTION)
+            .addExtendedProperty(new DataElement(KEY, VALUE));
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBuilder() {
+        PresenceScanFilter filter = mBuilder.build();
+
+        assertThat(filter.getMaxPathLoss()).isEqualTo(RSSI);
+        assertThat(filter.getCredentials().get(0).getIdentityType()).isEqualTo(
+                IDENTITY_TYPE_PRIVATE);
+        assertThat(filter.getPresenceActions()).containsExactly(ACTION);
+        assertThat(filter.getExtendedProperties().get(0).getKey()).isEqualTo(KEY);
+
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteParcel() {
+        PresenceScanFilter filter = mBuilder.build();
+
+        Parcel parcel = Parcel.obtain();
+        filter.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        PresenceScanFilter parcelFilter = PresenceScanFilter.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertThat(parcelFilter.getType()).isEqualTo(ScanRequest.SCAN_TYPE_NEARBY_PRESENCE);
+        assertThat(parcelFilter.getMaxPathLoss()).isEqualTo(RSSI);
+        assertThat(parcelFilter.getPresenceActions()).containsExactly(ACTION);
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
new file mode 100644
index 0000000..f05f65f
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import static android.nearby.PresenceCredential.CREDENTIAL_TYPE_PRIVATE;
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.CredentialElement;
+import android.nearby.PrivateCredential;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/**
+ * Tests for {@link PrivateCredential}.
+ */
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class PrivateCredentialTest {
+    private static final String DEVICE_NAME = "myDevice";
+    private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
+    private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
+    private static final String KEY = "SecreteId";
+    private static final byte[] VALUE = new byte[]{1, 2, 3, 4, 5};
+    private static final byte[] METADATA_ENCRYPTION_KEY = new byte[]{1, 1, 3, 4, 5};
+
+    private PrivateCredential.Builder mBuilder;
+
+    @Before
+    public void setUp() {
+        mBuilder = new PrivateCredential.Builder(
+                SECRETE_ID, AUTHENTICITY_KEY, METADATA_ENCRYPTION_KEY, DEVICE_NAME)
+                .setIdentityType(IDENTITY_TYPE_PRIVATE)
+                .addCredentialElement(new CredentialElement(KEY, VALUE));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 33, codeName = "T")
+    public void testBuilder() {
+        PrivateCredential credential = mBuilder.build();
+
+        assertThat(credential.getType()).isEqualTo(CREDENTIAL_TYPE_PRIVATE);
+        assertThat(credential.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
+        assertThat(credential.getDeviceName()).isEqualTo(DEVICE_NAME);
+        assertThat(Arrays.equals(credential.getSecretId(), SECRETE_ID)).isTrue();
+        assertThat(Arrays.equals(credential.getAuthenticityKey(), AUTHENTICITY_KEY)).isTrue();
+        assertThat(Arrays.equals(credential.getMetadataEncryptionKey(),
+                METADATA_ENCRYPTION_KEY)).isTrue();
+        CredentialElement credentialElement = credential.getCredentialElements().get(0);
+        assertThat(credentialElement.getKey()).isEqualTo(KEY);
+        assertThat(Arrays.equals(credentialElement.getValue(), VALUE)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 33, codeName = "T")
+    public void testWriteParcel() {
+        PrivateCredential credential = mBuilder.build();
+
+        Parcel parcel = Parcel.obtain();
+        credential.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        PrivateCredential credentialFromParcel = PrivateCredential.CREATOR.createFromParcel(
+                parcel);
+        parcel.recycle();
+
+        assertThat(credentialFromParcel.getType()).isEqualTo(CREDENTIAL_TYPE_PRIVATE);
+        assertThat(credentialFromParcel.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
+        assertThat(Arrays.equals(credentialFromParcel.getSecretId(), SECRETE_ID)).isTrue();
+        assertThat(Arrays.equals(credentialFromParcel.getAuthenticityKey(),
+                AUTHENTICITY_KEY)).isTrue();
+        assertThat(Arrays.equals(credentialFromParcel.getMetadataEncryptionKey(),
+                METADATA_ENCRYPTION_KEY)).isTrue();
+        CredentialElement credentialElement = credentialFromParcel.getCredentialElements().get(0);
+        assertThat(credentialElement.getKey()).isEqualTo(KEY);
+        assertThat(Arrays.equals(credentialElement.getValue(), VALUE)).isTrue();
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
new file mode 100644
index 0000000..11bbacc
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import static android.nearby.PresenceCredential.CREDENTIAL_TYPE_PUBLIC;
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.CredentialElement;
+import android.nearby.PresenceCredential;
+import android.nearby.PublicCredential;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/** Tests for {@link PresenceCredential}. */
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class PublicCredentialTest {
+
+    private static final byte[] SECRETE_ID = new byte[] {1, 2, 3, 4};
+    private static final byte[] AUTHENTICITY_KEY = new byte[] {0, 1, 1, 1};
+    private static final byte[] PUBLIC_KEY = new byte[] {1, 1, 2, 2};
+    private static final byte[] ENCRYPTED_METADATA = new byte[] {1, 2, 3, 4, 5};
+    private static final byte[] METADATA_ENCRYPTION_KEY_TAG = new byte[] {1, 1, 3, 4, 5};
+    private static final String KEY = "KEY";
+    private static final byte[] VALUE = new byte[] {1, 2, 3, 4, 5};
+
+    private PublicCredential.Builder mBuilder;
+
+    @Before
+    public void setUp() {
+        mBuilder =
+                new PublicCredential.Builder(
+                                SECRETE_ID,
+                                AUTHENTICITY_KEY,
+                                PUBLIC_KEY,
+                                ENCRYPTED_METADATA,
+                                METADATA_ENCRYPTION_KEY_TAG)
+                        .addCredentialElement(new CredentialElement(KEY, VALUE))
+                        .setIdentityType(IDENTITY_TYPE_PRIVATE);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBuilder() {
+        PublicCredential credential = mBuilder.build();
+
+        assertThat(credential.getType()).isEqualTo(CREDENTIAL_TYPE_PUBLIC);
+        assertThat(credential.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
+        assertThat(credential.getCredentialElements().get(0).getKey()).isEqualTo(KEY);
+        assertThat(Arrays.equals(credential.getSecretId(), SECRETE_ID)).isTrue();
+        assertThat(Arrays.equals(credential.getAuthenticityKey(), AUTHENTICITY_KEY)).isTrue();
+        assertThat(Arrays.equals(credential.getPublicKey(), PUBLIC_KEY)).isTrue();
+        assertThat(Arrays.equals(credential.getEncryptedMetadata(), ENCRYPTED_METADATA)).isTrue();
+        assertThat(
+                        Arrays.equals(
+                                credential.getEncryptedMetadataKeyTag(),
+                                METADATA_ENCRYPTION_KEY_TAG))
+                .isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteParcel() {
+        PublicCredential credential = mBuilder.build();
+
+        Parcel parcel = Parcel.obtain();
+        credential.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        PublicCredential credentialFromParcel = PublicCredential.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertThat(credentialFromParcel.getType()).isEqualTo(CREDENTIAL_TYPE_PUBLIC);
+        assertThat(credentialFromParcel.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
+        assertThat(Arrays.equals(credentialFromParcel.getSecretId(), SECRETE_ID)).isTrue();
+        assertThat(Arrays.equals(credentialFromParcel.getAuthenticityKey(), AUTHENTICITY_KEY))
+                .isTrue();
+        assertThat(Arrays.equals(credentialFromParcel.getPublicKey(), PUBLIC_KEY)).isTrue();
+        assertThat(Arrays.equals(credentialFromParcel.getEncryptedMetadata(), ENCRYPTED_METADATA))
+                .isTrue();
+        assertThat(
+                        Arrays.equals(
+                                credentialFromParcel.getEncryptedMetadataKeyTag(),
+                                METADATA_ENCRYPTION_KEY_TAG))
+                .isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEquals() {
+        PublicCredential credentialOne =
+                new PublicCredential.Builder(
+                                SECRETE_ID,
+                                AUTHENTICITY_KEY,
+                                PUBLIC_KEY,
+                                ENCRYPTED_METADATA,
+                                METADATA_ENCRYPTION_KEY_TAG)
+                        .addCredentialElement(new CredentialElement(KEY, VALUE))
+                        .setIdentityType(IDENTITY_TYPE_PRIVATE)
+                        .build();
+
+        PublicCredential credentialTwo =
+                new PublicCredential.Builder(
+                                SECRETE_ID,
+                                AUTHENTICITY_KEY,
+                                PUBLIC_KEY,
+                                ENCRYPTED_METADATA,
+                                METADATA_ENCRYPTION_KEY_TAG)
+                        .addCredentialElement(new CredentialElement(KEY, VALUE))
+                        .setIdentityType(IDENTITY_TYPE_PRIVATE)
+                        .build();
+        assertThat(credentialOne.equals((Object) credentialTwo)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testUnEquals() {
+        byte[] idOne = new byte[] {1, 2, 3, 4};
+        byte[] idTwo = new byte[] {4, 5, 6, 7};
+        PublicCredential credentialOne =
+                new PublicCredential.Builder(
+                                idOne,
+                                AUTHENTICITY_KEY,
+                                PUBLIC_KEY,
+                                ENCRYPTED_METADATA,
+                                METADATA_ENCRYPTION_KEY_TAG)
+                        .build();
+
+        PublicCredential credentialTwo =
+                new PublicCredential.Builder(
+                                idTwo,
+                                AUTHENTICITY_KEY,
+                                PUBLIC_KEY,
+                                ENCRYPTED_METADATA,
+                                METADATA_ENCRYPTION_KEY_TAG)
+                        .build();
+        assertThat(credentialOne.equals((Object) credentialTwo)).isFalse();
+    }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java
new file mode 100644
index 0000000..019f8ec
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ */
+
+package android.nearby.cts;
+
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+import static android.nearby.ScanRequest.SCAN_MODE_BALANCED;
+import static android.nearby.ScanRequest.SCAN_MODE_LOW_LATENCY;
+import static android.nearby.ScanRequest.SCAN_MODE_LOW_POWER;
+import static android.nearby.ScanRequest.SCAN_MODE_NO_POWER;
+import static android.nearby.ScanRequest.SCAN_TYPE_EXPOSURE_NOTIFICATION;
+import static android.nearby.ScanRequest.SCAN_TYPE_FAST_PAIR;
+import static android.nearby.ScanRequest.SCAN_TYPE_NEARBY_PRESENCE;
+import static android.nearby.ScanRequest.SCAN_TYPE_NEARBY_SHARE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
+import android.nearby.ScanRequest;
+import android.os.Build;
+import android.os.WorkSource;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class ScanRequestTest {
+
+    private static final int UID = 1001;
+    private static final String APP_NAME = "android.nearby.tests";
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testScanType() {
+        ScanRequest request = new ScanRequest.Builder()
+                .setScanType(SCAN_TYPE_NEARBY_PRESENCE)
+                .build();
+
+        assertThat(request.getScanType()).isEqualTo(SCAN_TYPE_NEARBY_PRESENCE);
+    }
+
+    // Valid scan type must be set to one of ScanRequest#SCAN_TYPE_
+    @Test(expected = IllegalStateException.class)
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testScanType_notSet_throwsException() {
+        new ScanRequest.Builder().setScanMode(SCAN_MODE_BALANCED).build();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testScanMode_defaultLowPower() {
+        ScanRequest request = new ScanRequest.Builder()
+                .setScanType(SCAN_TYPE_FAST_PAIR)
+                .build();
+
+        assertThat(request.getScanMode()).isEqualTo(SCAN_MODE_LOW_POWER);
+    }
+
+    /** Verify setting work source with null value in the scan request is allowed */
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSetWorkSource_nullValue() {
+        ScanRequest request = new ScanRequest.Builder()
+                .setScanType(SCAN_TYPE_EXPOSURE_NOTIFICATION)
+                .setWorkSource(null)
+                .build();
+
+        // Null work source is allowed.
+        assertThat(request.getWorkSource().isEmpty()).isTrue();
+    }
+
+    /** Verify toString returns expected string. */
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testToString() {
+        WorkSource workSource = getWorkSource();
+        ScanRequest request = new ScanRequest.Builder()
+                .setScanType(SCAN_TYPE_NEARBY_SHARE)
+                .setScanMode(SCAN_MODE_BALANCED)
+                .setBleEnabled(true)
+                .setWorkSource(workSource)
+                .build();
+
+        assertThat(request.toString()).isEqualTo(
+                "Request[scanType=2, scanMode=SCAN_MODE_BALANCED, "
+                        + "enableBle=true, workSource=WorkSource{" + UID + " " + APP_NAME
+                        + "}, scanFilters=[]]");
+    }
+
+    /** Verify toString works correctly with null WorkSource. */
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testToString_nullWorkSource() {
+        ScanRequest request = new ScanRequest.Builder().setScanType(
+                SCAN_TYPE_FAST_PAIR).setWorkSource(null).build();
+
+        assertThat(request.toString()).isEqualTo("Request[scanType=1, "
+                + "scanMode=SCAN_MODE_LOW_POWER, enableBle=true, workSource=WorkSource{}, "
+                + "scanFilters=[]]");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testisEnableBle_defaultTrue() {
+        ScanRequest request = new ScanRequest.Builder()
+                .setScanType(SCAN_TYPE_FAST_PAIR)
+                .build();
+
+        assertThat(request.isBleEnabled()).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_isValidScanType() {
+        assertThat(ScanRequest.isValidScanType(SCAN_TYPE_FAST_PAIR)).isTrue();
+        assertThat(ScanRequest.isValidScanType(SCAN_TYPE_NEARBY_SHARE)).isTrue();
+        assertThat(ScanRequest.isValidScanType(SCAN_TYPE_NEARBY_PRESENCE)).isTrue();
+        assertThat(ScanRequest.isValidScanType(SCAN_TYPE_EXPOSURE_NOTIFICATION)).isTrue();
+
+        assertThat(ScanRequest.isValidScanType(0)).isFalse();
+        assertThat(ScanRequest.isValidScanType(5)).isFalse();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_isValidScanMode() {
+        assertThat(ScanRequest.isValidScanMode(SCAN_MODE_LOW_LATENCY)).isTrue();
+        assertThat(ScanRequest.isValidScanMode(SCAN_MODE_BALANCED)).isTrue();
+        assertThat(ScanRequest.isValidScanMode(SCAN_MODE_LOW_POWER)).isTrue();
+        assertThat(ScanRequest.isValidScanMode(SCAN_MODE_NO_POWER)).isTrue();
+
+        assertThat(ScanRequest.isValidScanMode(3)).isFalse();
+        assertThat(ScanRequest.isValidScanMode(-2)).isFalse();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_scanModeToString() {
+        assertThat(ScanRequest.scanModeToString(2)).isEqualTo("SCAN_MODE_LOW_LATENCY");
+        assertThat(ScanRequest.scanModeToString(1)).isEqualTo("SCAN_MODE_BALANCED");
+        assertThat(ScanRequest.scanModeToString(0)).isEqualTo("SCAN_MODE_LOW_POWER");
+        assertThat(ScanRequest.scanModeToString(-1)).isEqualTo("SCAN_MODE_NO_POWER");
+
+        assertThat(ScanRequest.scanModeToString(3)).isEqualTo("SCAN_MODE_INVALID");
+        assertThat(ScanRequest.scanModeToString(-2)).isEqualTo("SCAN_MODE_INVALID");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testScanFilter() {
+        final byte[] secretId = new byte[]{1, 2, 3, 4};
+        final byte[] authenticityKey = new byte[]{0, 1, 1, 1};
+        final byte[] publicKey = new byte[]{1, 1, 2, 2};
+        final byte[] encryptedMetadata = new byte[]{1, 2, 3, 4, 5};
+        final byte[] metadataEncryptionKeyTag = new byte[]{1, 1, 3, 4, 5};
+
+        PublicCredential credential = new PublicCredential.Builder(
+                secretId, authenticityKey, publicKey, encryptedMetadata, metadataEncryptionKeyTag)
+                .setIdentityType(IDENTITY_TYPE_PRIVATE)
+                .build();
+
+        final int rssi = -40;
+        final int action = 123;
+        PresenceScanFilter filter = new PresenceScanFilter.Builder()
+                .addCredential(credential)
+                .setMaxPathLoss(rssi)
+                .addPresenceAction(action)
+                .build();
+
+        ScanRequest request = new ScanRequest.Builder().setScanType(
+                SCAN_TYPE_FAST_PAIR).addScanFilter(filter).build();
+
+        assertThat(request.getScanFilters()).isNotEmpty();
+        assertThat(request.getScanFilters().get(0).getMaxPathLoss()).isEqualTo(rssi);
+    }
+
+    private static WorkSource getWorkSource() {
+        return new WorkSource(UID, APP_NAME);
+    }
+}
diff --git a/nearby/tests/integration/OWNERS b/nearby/tests/integration/OWNERS
new file mode 100644
index 0000000..f4dbde2
--- /dev/null
+++ b/nearby/tests/integration/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 1092133
+
+ericth@google.com
+ryancllin@google.com
\ No newline at end of file
diff --git a/nearby/tests/integration/privileged/Android.bp b/nearby/tests/integration/privileged/Android.bp
new file mode 100644
index 0000000..e3250f6
--- /dev/null
+++ b/nearby/tests/integration/privileged/Android.bp
@@ -0,0 +1,33 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "NearbyIntegrationPrivilegedTests",
+    defaults: ["mts-target-sdk-version-current"],
+    sdk_version: "test_current",
+    certificate: "platform",
+
+    srcs: ["src/**/*.kt"],
+    static_libs: [
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "junit",
+        "truth-prebuilt",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/nearby/tests/integration/privileged/AndroidManifest.xml b/nearby/tests/integration/privileged/AndroidManifest.xml
new file mode 100644
index 0000000..00845f1
--- /dev/null
+++ b/nearby/tests/integration/privileged/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.nearby.integration.privileged">
+
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.nearby.integration.privileged"
+        android:label="Nearby Mainline Module Integration Privileged Tests" />
+
+</manifest>
diff --git a/nearby/tests/integration/privileged/src/android/nearby/integration/privileged/FastPairSettingsProviderTest.kt b/nearby/tests/integration/privileged/src/android/nearby/integration/privileged/FastPairSettingsProviderTest.kt
new file mode 100644
index 0000000..af3f75f
--- /dev/null
+++ b/nearby/tests/integration/privileged/src/android/nearby/integration/privileged/FastPairSettingsProviderTest.kt
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+package android.nearby.integration.privileged
+
+import android.content.Context
+import android.provider.Settings
+import androidx.test.core.app.ApplicationProvider
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameters
+
+data class FastPairSettingsFlag(val name: String, val value: Int) {
+    override fun toString() = name
+}
+
+@RunWith(Parameterized::class)
+class FastPairSettingsProviderTest(private val flag: FastPairSettingsFlag) {
+
+    /** Verify privileged app can enable/disable Fast Pair scan. */
+    @Test
+    fun testSettingsFastPairScan_fromPrivilegedApp() {
+        val appContext = ApplicationProvider.getApplicationContext<Context>()
+        val contentResolver = appContext.contentResolver
+
+        Settings.Secure.putInt(contentResolver, "fast_pair_scan_enabled", flag.value)
+
+        val actualValue = Settings.Secure.getInt(
+                contentResolver, "fast_pair_scan_enabled", /* default value */ -1)
+        assertThat(actualValue).isEqualTo(flag.value)
+    }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}Succeed")
+        fun fastPairScanFlags() = listOf(
+            FastPairSettingsFlag(name = "disable", value = 0),
+            FastPairSettingsFlag(name = "enable", value = 1),
+        )
+    }
+}
diff --git a/nearby/tests/integration/privileged/src/android/nearby/integration/privileged/NearbyManagerTest.kt b/nearby/tests/integration/privileged/src/android/nearby/integration/privileged/NearbyManagerTest.kt
new file mode 100644
index 0000000..3b6337a
--- /dev/null
+++ b/nearby/tests/integration/privileged/src/android/nearby/integration/privileged/NearbyManagerTest.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+package android.nearby.integration.privileged
+
+import android.content.Context
+import android.nearby.NearbyManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class NearbyManagerTest {
+
+    /** Verify privileged app can get Nearby service. */
+    @Test
+    fun testContextGetNearbySystemService_fromPrivilegedApp_returnsNoneNull() {
+        val appContext = ApplicationProvider.getApplicationContext<Context>()
+        val nearbyManager = appContext.getSystemService(Context.NEARBY_SERVICE) as NearbyManager
+
+        assertThat(nearbyManager).isNotNull()
+    }
+}
diff --git a/nearby/tests/integration/untrusted/Android.bp b/nearby/tests/integration/untrusted/Android.bp
new file mode 100644
index 0000000..53dbfb7
--- /dev/null
+++ b/nearby/tests/integration/untrusted/Android.bp
@@ -0,0 +1,33 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "NearbyIntegrationUntrustedTests",
+    defaults: ["mts-target-sdk-version-current"],
+    sdk_version: "test_current",
+
+    srcs: ["src/**/*.kt"],
+    static_libs: [
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "junit",
+        "kotlin-test",
+        "truth-prebuilt",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/nearby/tests/integration/untrusted/AndroidManifest.xml b/nearby/tests/integration/untrusted/AndroidManifest.xml
new file mode 100644
index 0000000..d73f6b2
--- /dev/null
+++ b/nearby/tests/integration/untrusted/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.nearby.integration.untrusted">
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.nearby.integration.untrusted"
+        android:label="Nearby Mainline Module Integration Untrusted Tests" />
+
+</manifest>
diff --git a/nearby/tests/integration/untrusted/src/android/nearby/integration/untrusted/FastPairSettingsProviderTest.kt b/nearby/tests/integration/untrusted/src/android/nearby/integration/untrusted/FastPairSettingsProviderTest.kt
new file mode 100644
index 0000000..c549073
--- /dev/null
+++ b/nearby/tests/integration/untrusted/src/android/nearby/integration/untrusted/FastPairSettingsProviderTest.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+package android.nearby.integration.untrusted
+
+import android.content.Context
+import android.content.ContentResolver
+import android.provider.Settings
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.test.assertFailsWith
+
+
+@RunWith(AndroidJUnit4::class)
+class FastPairSettingsProviderTest {
+    private lateinit var contentResolver: ContentResolver
+
+    @Before
+    fun setUp() {
+        contentResolver = ApplicationProvider.getApplicationContext<Context>().contentResolver
+    }
+
+    /** Verify untrusted app can read Fast Pair scan enabled setting. */
+    @Test
+    fun testSettingsFastPairScan_fromUnTrustedApp_readsSucceed() {
+        Settings.Secure.getInt(contentResolver,
+                "fast_pair_scan_enabled", /* default value */ -1)
+    }
+
+    /** Verify untrusted app can't write Fast Pair scan enabled setting. */
+    @Test
+    fun testSettingsFastPairScan_fromUnTrustedApp_writesFailed() {
+        assertFailsWith<SecurityException> {
+            Settings.Secure.putInt(contentResolver, "fast_pair_scan_enabled", 1)
+        }
+    }
+}
diff --git a/nearby/tests/integration/untrusted/src/android/nearby/integration/untrusted/NearbyManagerTest.kt b/nearby/tests/integration/untrusted/src/android/nearby/integration/untrusted/NearbyManagerTest.kt
new file mode 100644
index 0000000..aa6aa2a
--- /dev/null
+++ b/nearby/tests/integration/untrusted/src/android/nearby/integration/untrusted/NearbyManagerTest.kt
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+package android.nearby.integration.untrusted
+
+import android.content.Context
+import android.nearby.NearbyManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class NearbyManagerTest {
+
+    /** Verify untrusted app can't get Nearby service. */
+    @Test
+    fun testContextGetNearbyService_fromUnTrustedApp_returnsNull() {
+        val appContext = ApplicationProvider.getApplicationContext<Context>()
+        assertThat(appContext.getSystemService(Context.NEARBY_SERVICE)).isNull()
+    }
+}
diff --git a/nearby/tests/multidevices/OWNERS b/nearby/tests/multidevices/OWNERS
new file mode 100644
index 0000000..f4dbde2
--- /dev/null
+++ b/nearby/tests/multidevices/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 1092133
+
+ericth@google.com
+ryancllin@google.com
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/Android.bp b/nearby/tests/multidevices/clients/Android.bp
new file mode 100644
index 0000000..49bc2e9
--- /dev/null
+++ b/nearby/tests/multidevices/clients/Android.bp
@@ -0,0 +1,46 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_library {
+    name: "NearbyMultiDevicesClientsLib",
+    srcs: ["src/**/*.kt"],
+    sdk_version: "test_current",
+    static_libs: [
+        "MoblySnippetHelperLib",
+        "NearbyFastPairProviderLib",
+        "NearbyFastPairSeekerSharedLib",
+        "androidx.test.core",
+        "androidx.test.ext.junit",
+        "androidx.test.uiautomator_uiautomator",
+        "kotlin-stdlib",
+        "mobly-snippet-lib",
+        "truth-prebuilt",
+    ],
+}
+
+android_app {
+    name: "NearbyMultiDevicesClientsSnippets",
+    sdk_version: "test_current",
+    certificate: "platform",
+    static_libs: ["NearbyMultiDevicesClientsLib"],
+    optimize: {
+        enabled: true,
+        shrink: false,
+        proguard_flags_files: ["proguard.flags"],
+    },
+}
diff --git a/nearby/tests/multidevices/clients/AndroidManifest.xml b/nearby/tests/multidevices/clients/AndroidManifest.xml
new file mode 100644
index 0000000..86c10b2
--- /dev/null
+++ b/nearby/tests/multidevices/clients/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.nearby.multidevices">
+
+    <uses-feature android:name="android.hardware.bluetooth" />
+    <uses-feature android:name="android.hardware.bluetooth_le" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+
+    <application>
+        <meta-data
+            android:name="mobly-log-tag"
+            android:value="NearbyMainlineSnippet" />
+        <meta-data
+            android:name="mobly-snippets"
+            android:value="android.nearby.multidevices.fastpair.seeker.FastPairSeekerSnippet,
+                           android.nearby.multidevices.fastpair.provider.FastPairProviderSimulatorSnippet" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:label="Nearby Mainline Module Instrumentation Test"
+        android:targetPackage="android.nearby.multidevices" />
+
+    <instrumentation
+        android:name="com.google.android.mobly.snippet.SnippetRunner"
+        android:label="Nearby Mainline Module Mobly Snippet"
+        android:targetPackage="android.nearby.multidevices" />
+
+</manifest>
diff --git a/nearby/tests/multidevices/clients/proguard.flags b/nearby/tests/multidevices/clients/proguard.flags
new file mode 100644
index 0000000..11938cd
--- /dev/null
+++ b/nearby/tests/multidevices/clients/proguard.flags
@@ -0,0 +1,29 @@
+# Keep all snippet classes.
+-keep class android.nearby.multidevices.** {
+     *;
+}
+
+# Keep AdvertisingSetCallback#onOwnAddressRead callback.
+-keep class * extends android.bluetooth.le.AdvertisingSetCallback {
+     *;
+}
+
+# Do not touch Mobly.
+-keep class com.google.android.mobly.** {
+  *;
+}
+
+# Keep names for easy debugging.
+-dontobfuscate
+
+# Necessary to allow debugging.
+-keepattributes *
+
+# By default, proguard leaves all classes in their original package, which
+# needlessly repeats com.google.android.apps.etc.
+-repackageclasses ""
+
+# Allows proguard to make private and protected methods and fields public as
+# part of optimization. This lets proguard inline trivial getter/setter
+# methods.
+-allowaccessmodification
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorSnippet.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorSnippet.kt
new file mode 100644
index 0000000..922e950
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorSnippet.kt
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.provider
+
+import android.annotation.TargetApi
+import android.content.Context
+import android.nearby.multidevices.fastpair.provider.controller.FastPairProviderSimulatorController
+import android.nearby.multidevices.fastpair.provider.events.ProviderStatusEvents
+import android.os.Build
+import androidx.test.platform.app.InstrumentationRegistry
+import com.google.android.mobly.snippet.Snippet
+import com.google.android.mobly.snippet.rpc.AsyncRpc
+import com.google.android.mobly.snippet.rpc.Rpc
+
+/** Expose Mobly RPC methods for Python side to simulate fast pair provider role. */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+class FastPairProviderSimulatorSnippet : Snippet {
+    private val context: Context = InstrumentationRegistry.getInstrumentation().context
+    private val fastPairProviderSimulatorController = FastPairProviderSimulatorController(context)
+
+    /** Sets up the Fast Pair provider simulator. */
+    @AsyncRpc(description = "Sets up FP provider simulator.")
+    fun setupProviderSimulator(callbackId: String) {
+        fastPairProviderSimulatorController.setupProviderSimulator(ProviderStatusEvents(callbackId))
+    }
+
+    /**
+     * Starts model id advertising for scanning and initial pairing.
+     *
+     * @param callbackId the callback ID corresponding to the
+     * [FastPairProviderSimulatorSnippet#startProviderSimulator] call that started the scanning.
+     * @param modelId a 3-byte hex string for seeker side to recognize the device (ex: 0x00000C).
+     * @param antiSpoofingKeyString a public key for registered headsets.
+     */
+    @AsyncRpc(description = "Starts model id advertising for scanning and initial pairing.")
+    fun startModelIdAdvertising(
+        callbackId: String,
+        modelId: String,
+        antiSpoofingKeyString: String
+    ) {
+        fastPairProviderSimulatorController.startModelIdAdvertising(
+            modelId,
+            antiSpoofingKeyString,
+            ProviderStatusEvents(callbackId)
+        )
+    }
+
+    /** Tears down the Fast Pair provider simulator. */
+    @Rpc(description = "Tears down FP provider simulator.")
+    fun teardownProviderSimulator() {
+        fastPairProviderSimulatorController.teardownProviderSimulator()
+    }
+
+    /** Gets BLE mac address of the Fast Pair provider simulator. */
+    @Rpc(description = "Gets BLE mac address of the Fast Pair provider simulator.")
+    fun getBluetoothLeAddress(): String {
+        return fastPairProviderSimulatorController.getProviderSimulatorBleAddress()
+    }
+
+    /** Gets the latest account key received on the Fast Pair provider simulator */
+    @Rpc(description = "Gets the latest account key received on the Fast Pair provider simulator.")
+    fun getLatestReceivedAccountKey(): String? {
+        return fastPairProviderSimulatorController.getLatestReceivedAccountKey()
+    }
+}
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/controller/FastPairProviderSimulatorController.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/controller/FastPairProviderSimulatorController.kt
new file mode 100644
index 0000000..a2d2659
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/controller/FastPairProviderSimulatorController.kt
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.provider.controller
+
+import android.bluetooth.le.AdvertiseSettings
+import android.content.Context
+import android.nearby.fastpair.provider.FastPairSimulator
+import android.nearby.fastpair.provider.bluetooth.BluetoothController
+import com.google.android.mobly.snippet.util.Log
+import com.google.common.io.BaseEncoding.base64
+
+class FastPairProviderSimulatorController(private val context: Context) :
+    FastPairSimulator.AdvertisingChangedCallback, BluetoothController.EventListener {
+    private lateinit var bluetoothController: BluetoothController
+    private lateinit var eventListener: EventListener
+    private var simulator: FastPairSimulator? = null
+
+    fun setupProviderSimulator(listener: EventListener) {
+        eventListener = listener
+
+        bluetoothController = BluetoothController(context, this)
+        bluetoothController.registerBluetoothStateReceiver()
+        bluetoothController.enableBluetooth()
+        bluetoothController.connectA2DPSinkProfile()
+    }
+
+    fun teardownProviderSimulator() {
+        simulator?.destroy()
+        bluetoothController.unregisterBluetoothStateReceiver()
+    }
+
+    fun startModelIdAdvertising(
+        modelId: String,
+        antiSpoofingKeyString: String,
+        listener: EventListener
+    ) {
+        eventListener = listener
+
+        val antiSpoofingKey = base64().decode(antiSpoofingKeyString)
+        simulator = FastPairSimulator(
+            context, FastPairSimulator.Options.builder(modelId)
+                .setAdvertisingModelId(modelId)
+                .setBluetoothAddress(null)
+                .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
+                .setAdvertisingChangedCallback(this)
+                .setAntiSpoofingPrivateKey(antiSpoofingKey)
+                .setUseRandomSaltForAccountKeyRotation(false)
+                .setDataOnlyConnection(false)
+                .setShowsPasskeyConfirmation(false)
+                .setRemoveAllDevicesDuringPairing(true)
+                .build()
+        )
+    }
+
+    fun getProviderSimulatorBleAddress() = simulator!!.bleAddress!!
+
+    fun getLatestReceivedAccountKey() =
+        simulator!!.accountKey?.let { base64().encode(it.toByteArray()) }
+
+    /**
+     * Called when we change our BLE advertisement.
+     *
+     * @param isAdvertising the advertising status.
+     */
+    override fun onAdvertisingChanged(isAdvertising: Boolean) {
+        Log.i("FastPairSimulator onAdvertisingChanged(isAdvertising: $isAdvertising)")
+        eventListener.onAdvertisingChange(isAdvertising)
+    }
+
+    /** The callback for the first onServiceConnected of A2DP sink profile. */
+    override fun onA2DPSinkProfileConnected() {
+        eventListener.onA2DPSinkProfileConnected()
+    }
+
+    /**
+     * Reports the current bond state of the remote device.
+     *
+     * @param bondState the bond state of the remote device.
+     */
+    override fun onBondStateChanged(bondState: Int) {
+    }
+
+    /**
+     * Reports the current connection state of the remote device.
+     *
+     * @param connectionState the bond state of the remote device.
+     */
+    override fun onConnectionStateChanged(connectionState: Int) {
+    }
+
+    /**
+     * Reports the current scan mode of the local Adapter.
+     *
+     * @param mode the current scan mode of the local Adapter.
+     */
+    override fun onScanModeChange(mode: Int) {
+        eventListener.onScanModeChange(FastPairSimulator.scanModeToString(mode))
+    }
+
+    /** Interface for listening the events from Fast Pair Provider Simulator. */
+    interface EventListener {
+        /** Reports the first onServiceConnected of A2DP sink profile. */
+        fun onA2DPSinkProfileConnected()
+
+        /**
+         * Reports the current scan mode of the local Adapter.
+         *
+         * @param mode the current scan mode in string.
+         */
+        fun onScanModeChange(mode: String)
+
+        /**
+         * Indicates the advertising state of the Fast Pair provider simulator has changed.
+         *
+         * @param isAdvertising the current advertising state, true if advertising otherwise false.
+         */
+        fun onAdvertisingChange(isAdvertising: Boolean)
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/events/ProviderStatusEvents.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/events/ProviderStatusEvents.kt
new file mode 100644
index 0000000..2addd77
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/events/ProviderStatusEvents.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.provider.events
+
+import android.nearby.multidevices.fastpair.provider.controller.FastPairProviderSimulatorController
+import com.google.android.mobly.snippet.util.postSnippetEvent
+
+/** The Mobly snippet events to report to the Python side. */
+class ProviderStatusEvents(private val callbackId: String) :
+    FastPairProviderSimulatorController.EventListener {
+
+    /** Reports the first onServiceConnected of A2DP sink profile. */
+    override fun onA2DPSinkProfileConnected() {
+        postSnippetEvent(callbackId, "onA2DPSinkProfileConnected") {}
+    }
+
+    /**
+     * Indicates the Bluetooth scan mode of the Fast Pair provider simulator has changed.
+     *
+     * @param mode the current scan mode in String mapping by [FastPairSimulator#scanModeToString].
+     */
+    override fun onScanModeChange(mode: String) {
+        postSnippetEvent(callbackId, "onScanModeChange") { putString("mode", mode) }
+    }
+
+    /**
+     * Indicates the advertising state of the Fast Pair provider simulator has changed.
+     *
+     * @param isAdvertising the current advertising state, true if advertising otherwise false.
+     */
+    override fun onAdvertisingChange(isAdvertising: Boolean) {
+        postSnippetEvent(callbackId, "onAdvertisingChange") {
+            putBoolean("isAdvertising", isAdvertising)
+        }
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairSeekerSnippet.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairSeekerSnippet.kt
new file mode 100644
index 0000000..fd4f4b4
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairSeekerSnippet.kt
@@ -0,0 +1,168 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.seeker
+
+import android.content.Context
+import android.nearby.FastPairDeviceMetadata
+import android.nearby.NearbyManager
+import android.nearby.ScanCallback
+import android.nearby.ScanRequest
+import android.nearby.fastpair.seeker.FAKE_TEST_ACCOUNT_NAME
+import android.nearby.multidevices.fastpair.seeker.data.FastPairTestDataManager
+import android.nearby.multidevices.fastpair.seeker.events.PairingCallbackEvents
+import android.nearby.multidevices.fastpair.seeker.events.ScanCallbackEvents
+import android.nearby.multidevices.fastpair.seeker.ui.CheckNearbyHalfSheetUiTest
+import android.nearby.multidevices.fastpair.seeker.ui.DismissNearbyHalfSheetUiTest
+import android.nearby.multidevices.fastpair.seeker.ui.PairByNearbyHalfSheetUiTest
+import androidx.test.core.app.ApplicationProvider
+import com.google.android.mobly.snippet.Snippet
+import com.google.android.mobly.snippet.rpc.AsyncRpc
+import com.google.android.mobly.snippet.rpc.Rpc
+import com.google.android.mobly.snippet.util.Log
+
+/** Expose Mobly RPC methods for Python side to test fast pair seeker role. */
+class FastPairSeekerSnippet : Snippet {
+    private val appContext = ApplicationProvider.getApplicationContext<Context>()
+    private val nearbyManager = appContext.getSystemService(Context.NEARBY_SERVICE) as NearbyManager
+    private val fastPairTestDataManager = FastPairTestDataManager(appContext)
+    private lateinit var scanCallback: ScanCallback
+
+    /**
+     * Starts scanning as a Fast Pair seeker to find provider devices.
+     *
+     * @param callbackId the callback ID corresponding to the {@link FastPairSeekerSnippet#startScan}
+     * call that started the scanning.
+     */
+    @AsyncRpc(description = "Starts scanning as Fast Pair seeker to find provider devices.")
+    fun startScan(callbackId: String) {
+        val scanRequest = ScanRequest.Builder()
+            .setScanMode(ScanRequest.SCAN_MODE_LOW_LATENCY)
+            .setScanType(ScanRequest.SCAN_TYPE_FAST_PAIR)
+            .setBleEnabled(true)
+            .build()
+        scanCallback = ScanCallbackEvents(callbackId)
+
+        Log.i("Start Fast Pair scanning via BLE...")
+        nearbyManager.startScan(scanRequest, /* executor */ { it.run() }, scanCallback)
+    }
+
+    /** Stops the Fast Pair seeker scanning. */
+    @Rpc(description = "Stops the Fast Pair seeker scanning.")
+    fun stopScan() {
+        Log.i("Stop Fast Pair scanning.")
+        nearbyManager.stopScan(scanCallback)
+    }
+
+    /** Waits and asserts the HalfSheet showed for Fast Pair pairing.
+     *
+     * @param modelId the expected model id to be associated with the HalfSheet.
+     * @param timeout the number of seconds to wait before giving up.
+     */
+    @Rpc(description = "Waits the HalfSheet showed for Fast Pair pairing.")
+    fun waitAndAssertHalfSheetShowed(modelId: String, timeout: Int) {
+        Log.i("Waits and asserts the HalfSheet showed for Fast Pair model $modelId.")
+
+        val deviceMetadata: FastPairDeviceMetadata =
+            fastPairTestDataManager.testDataCache.getFastPairDeviceMetadata(modelId)
+                ?: throw IllegalArgumentException(
+                    "Can't find $modelId-FastPairAntispoofKeyDeviceMetadata pair in " +
+                            "FastPairTestDataCache."
+                )
+        val deviceName = deviceMetadata.name!!
+        val initialPairingDescriptionTemplateText = deviceMetadata.initialPairingDescription!!
+
+        CheckNearbyHalfSheetUiTest(
+            waitHalfSheetPopupTimeoutSeconds = timeout,
+            halfSheetTitleText = deviceName,
+            halfSheetSubtitleText = initialPairingDescriptionTemplateText.format(
+                deviceName,
+                FAKE_TEST_ACCOUNT_NAME
+            )
+        ).checkNearbyHalfSheetUi()
+    }
+
+    /** Puts a model id to FastPairAntispoofKeyDeviceMetadata pair into test data cache.
+     *
+     * @param modelId a string of model id to be associated with.
+     * @param json a string of FastPairAntispoofKeyDeviceMetadata JSON object.
+     */
+    @Rpc(
+        description =
+        "Puts a model id to FastPairAntispoofKeyDeviceMetadata pair into test data cache."
+    )
+    fun putAntispoofKeyDeviceMetadata(modelId: String, json: String) {
+        Log.i("Puts a model id to FastPairAntispoofKeyDeviceMetadata pair into test data cache.")
+        fastPairTestDataManager.sendAntispoofKeyDeviceMetadata(modelId, json)
+    }
+
+    /** Puts an array of FastPairAccountKeyDeviceMetadata into test data cache.
+     *
+     * @param json a string of FastPairAccountKeyDeviceMetadata JSON array.
+     */
+    @Rpc(description = "Puts an array of FastPairAccountKeyDeviceMetadata into test data cache.")
+    fun putAccountKeyDeviceMetadata(json: String) {
+        Log.i("Puts an array of FastPairAccountKeyDeviceMetadata into test data cache.")
+        fastPairTestDataManager.sendAccountKeyDeviceMetadataJsonArray(json)
+    }
+
+    /** Dumps all FastPairAccountKeyDeviceMetadata from the test data cache. */
+    @Rpc(description = "Dumps all FastPairAccountKeyDeviceMetadata from the test data cache.")
+    fun dumpAccountKeyDeviceMetadata(): String {
+        Log.i("Dumps all FastPairAccountKeyDeviceMetadata from the test data cache.")
+        return fastPairTestDataManager.testDataCache.dumpAccountKeyDeviceMetadataListAsJson()
+    }
+
+    /** Writes into {@link Settings} whether Fast Pair scan is enabled.
+     *
+     * @param enable whether the Fast Pair scan should be enabled.
+     */
+    @Rpc(description = "Writes into Settings whether Fast Pair scan is enabled.")
+    fun setFastPairScanEnabled(enable: Boolean) {
+        Log.i("Writes into Settings whether Fast Pair scan is enabled.")
+        NearbyManager.setFastPairScanEnabled(appContext, enable)
+    }
+
+    /** Dismisses the half sheet UI if showed. */
+    @Rpc(description = "Dismisses the half sheet UI if showed.")
+    fun dismissHalfSheet() {
+        Log.i("Dismisses the half sheet UI if showed.")
+
+        DismissNearbyHalfSheetUiTest().dismissHalfSheet()
+    }
+
+    /** Starts pairing by interacting with half sheet UI.
+     *
+     * @param callbackId the callback ID corresponding to the
+     * {@link FastPairSeekerSnippet#startPairing} call that started the pairing.
+     */
+    @AsyncRpc(description = "Starts pairing by interacting with half sheet UI.")
+    fun startPairing(callbackId: String) {
+        Log.i("Starts pairing by interacting with half sheet UI.")
+
+        PairByNearbyHalfSheetUiTest().clickConnectButton()
+        fastPairTestDataManager.registerDataReceiveListener(PairingCallbackEvents(callbackId))
+    }
+
+    /** Invokes when the snippet runner shutting down. */
+    override fun shutdown() {
+        super.shutdown()
+
+        Log.i("Resets the Fast Pair test data cache.")
+        fastPairTestDataManager.unregisterDataReceiveListener()
+        fastPairTestDataManager.sendResetCache()
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/data/FastPairTestDataManager.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/data/FastPairTestDataManager.kt
new file mode 100644
index 0000000..239ac61
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/data/FastPairTestDataManager.kt
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.seeker.data
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.nearby.fastpair.seeker.ACTION_RESET_TEST_DATA_CACHE
+import android.nearby.fastpair.seeker.ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA
+import android.nearby.fastpair.seeker.ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA
+import android.nearby.fastpair.seeker.ACTION_WRITE_ACCOUNT_KEY_DEVICE_METADATA
+import android.nearby.fastpair.seeker.DATA_JSON_STRING_KEY
+import android.nearby.fastpair.seeker.DATA_MODEL_ID_STRING_KEY
+import android.nearby.fastpair.seeker.FastPairTestDataCache
+import android.util.Log
+
+/** Manage local FastPairTestDataCache and send to/sync from the remote cache in data provider. */
+class FastPairTestDataManager(private val context: Context) : BroadcastReceiver() {
+    val testDataCache = FastPairTestDataCache()
+    var listener: EventListener? = null
+
+    /** Puts a model id to FastPairAntispoofKeyDeviceMetadata pair into local and remote cache.
+     *
+     * @param modelId a string of model id to be associated with.
+     * @param json a string of FastPairAntispoofKeyDeviceMetadata JSON object.
+     */
+    fun sendAntispoofKeyDeviceMetadata(modelId: String, json: String) {
+        Intent().also { intent ->
+            intent.action = ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA
+            intent.putExtra(DATA_MODEL_ID_STRING_KEY, modelId)
+            intent.putExtra(DATA_JSON_STRING_KEY, json)
+            context.sendBroadcast(intent)
+        }
+        testDataCache.putAntispoofKeyDeviceMetadata(modelId, json)
+    }
+
+    /** Puts account key device metadata array to local and remote cache.
+     *
+     * @param json a string of FastPairAccountKeyDeviceMetadata JSON array.
+     */
+    fun sendAccountKeyDeviceMetadataJsonArray(json: String) {
+        Intent().also { intent ->
+            intent.action = ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA
+            intent.putExtra(DATA_JSON_STRING_KEY, json)
+            context.sendBroadcast(intent)
+        }
+        testDataCache.putAccountKeyDeviceMetadataJsonArray(json)
+    }
+
+    /** Clears local and remote cache. */
+    fun sendResetCache() {
+        context.sendBroadcast(Intent(ACTION_RESET_TEST_DATA_CACHE))
+        testDataCache.reset()
+    }
+
+    /**
+     * Callback method for receiving Intent broadcast from FastPairTestDataProvider.
+     *
+     * See [BroadcastReceiver#onReceive].
+     *
+     * @param context the Context in which the receiver is running.
+     * @param intent the Intent being received.
+     */
+    override fun onReceive(context: Context, intent: Intent) {
+        when (intent.action) {
+            ACTION_WRITE_ACCOUNT_KEY_DEVICE_METADATA -> {
+                Log.d(TAG, "ACTION_WRITE_ACCOUNT_KEY_DEVICE_METADATA received!")
+                val json = intent.getStringExtra(DATA_JSON_STRING_KEY)!!
+                testDataCache.putAccountKeyDeviceMetadataJsonObject(json)
+                listener?.onManageFastPairAccountDevice(json)
+            }
+            else -> Log.d(TAG, "Unknown action received!")
+        }
+    }
+
+    fun registerDataReceiveListener(listener: EventListener) {
+        this.listener = listener
+        val bondStateFilter = IntentFilter(ACTION_WRITE_ACCOUNT_KEY_DEVICE_METADATA)
+        context.registerReceiver(this, bondStateFilter)
+    }
+
+    fun unregisterDataReceiveListener() {
+        this.listener = null
+        context.unregisterReceiver(this)
+    }
+
+    /** Interface for listening the data receive from the remote cache in data provider. */
+    interface EventListener {
+        /** Reports a FastPairAccountKeyDeviceMetadata write into the cache.
+         *
+         * @param json the FastPairAccountKeyDeviceMetadata as JSON object string.
+         */
+        fun onManageFastPairAccountDevice(json: String)
+    }
+
+    companion object {
+        private const val TAG = "FastPairTestDataManager"
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/events/PairingCallbackEvents.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/events/PairingCallbackEvents.kt
new file mode 100644
index 0000000..19de1d9
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/events/PairingCallbackEvents.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.seeker.events
+
+import android.nearby.multidevices.fastpair.seeker.data.FastPairTestDataManager
+import com.google.android.mobly.snippet.util.postSnippetEvent
+
+/** The Mobly snippet events to report to the Python side. */
+class PairingCallbackEvents(private val callbackId: String) :
+    FastPairTestDataManager.EventListener {
+
+    /** Reports a FastPairAccountKeyDeviceMetadata write into the cache.
+     *
+     * @param json the FastPairAccountKeyDeviceMetadata as JSON object string.
+     */
+    override fun onManageFastPairAccountDevice(json: String) {
+        postSnippetEvent(callbackId, "onManageAccountDevice") {
+            putString("accountDeviceJsonString", json)
+        }
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/events/ScanCallbackEvents.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/events/ScanCallbackEvents.kt
new file mode 100644
index 0000000..363355f
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/events/ScanCallbackEvents.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.seeker.events
+
+import android.nearby.NearbyDevice
+import android.nearby.ScanCallback
+import com.google.android.mobly.snippet.util.postSnippetEvent
+
+/** The Mobly snippet events to report to the Python side. */
+class ScanCallbackEvents(private val callbackId: String) : ScanCallback {
+
+    override fun onDiscovered(device: NearbyDevice) {
+        postSnippetEvent(callbackId, "onDiscovered") {
+            putString("device", device.toString())
+        }
+    }
+
+    override fun onUpdated(device: NearbyDevice) {
+        postSnippetEvent(callbackId, "onUpdated") {
+            putString("device", device.toString())
+        }
+    }
+
+    override fun onLost(device: NearbyDevice) {
+        postSnippetEvent(callbackId, "onLost") {
+            putString("device", device.toString())
+        }
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/CheckNearbyHalfSheetUiTest.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/CheckNearbyHalfSheetUiTest.kt
new file mode 100644
index 0000000..84b5e89
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/CheckNearbyHalfSheetUiTest.kt
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.seeker.ui
+
+import android.os.Bundle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** An instrumented test to check Nearby half sheet UI showed correctly.
+ *
+ * To run this test directly:
+ * am instrument -w -r \
+ * -e class android.nearby.multidevices.fastpair.seeker.ui.CheckNearbyHalfSheetUiTest \
+ * android.nearby.multidevices/androidx.test.runner.AndroidJUnitRunner
+ */
+@RunWith(AndroidJUnit4::class)
+class CheckNearbyHalfSheetUiTest {
+    private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+    private val waitHalfSheetPopupTimeoutMs: Long
+    private val halfSheetTitleText: String
+    private val halfSheetSubtitleText: String
+
+    constructor() {
+        val arguments: Bundle = InstrumentationRegistry.getArguments()
+        waitHalfSheetPopupTimeoutMs = arguments.getLong(
+            WAIT_HALF_SHEET_POPUP_TIMEOUT_KEY,
+            DEFAULT_WAIT_HALF_SHEET_POPUP_TIMEOUT_MS
+        )
+        halfSheetTitleText =
+            arguments.getString(HALF_SHEET_TITLE_KEY, DEFAULT_HALF_SHEET_TITLE_TEXT)
+        halfSheetSubtitleText =
+            arguments.getString(HALF_SHEET_SUBTITLE_KEY, DEFAULT_HALF_SHEET_SUBTITLE_TEXT)
+    }
+
+    constructor(
+        waitHalfSheetPopupTimeoutSeconds: Int,
+        halfSheetTitleText: String,
+        halfSheetSubtitleText: String
+    ) {
+        this.waitHalfSheetPopupTimeoutMs = waitHalfSheetPopupTimeoutSeconds * 1000L
+        this.halfSheetTitleText = halfSheetTitleText
+        this.halfSheetSubtitleText = halfSheetSubtitleText
+    }
+
+    @Test
+    fun checkNearbyHalfSheetUi() {
+        // Check Nearby half sheet showed by checking button "Connect" on the DevicePairingFragment.
+        val isConnectButtonShowed = device.wait(
+            Until.hasObject(NearbyHalfSheetUiMap.DevicePairingFragment.connectButton),
+            waitHalfSheetPopupTimeoutMs
+        )
+        assertWithMessage("Nearby half sheet didn't show within $waitHalfSheetPopupTimeoutMs ms.")
+            .that(isConnectButtonShowed).isTrue()
+
+        val halfSheetTitle =
+            device.findObject(NearbyHalfSheetUiMap.DevicePairingFragment.halfSheetTitle)
+        assertThat(halfSheetTitle).isNotNull()
+        assertThat(halfSheetTitle.text).isEqualTo(halfSheetTitleText)
+
+        val halfSheetSubtitle =
+            device.findObject(NearbyHalfSheetUiMap.DevicePairingFragment.halfSheetSubtitle)
+        assertThat(halfSheetSubtitle).isNotNull()
+        assertThat(halfSheetSubtitle.text).isEqualTo(halfSheetSubtitleText)
+
+        val deviceImage = device.findObject(NearbyHalfSheetUiMap.DevicePairingFragment.deviceImage)
+        assertThat(deviceImage).isNotNull()
+
+        val infoButton = device.findObject(NearbyHalfSheetUiMap.DevicePairingFragment.infoButton)
+        assertThat(infoButton).isNotNull()
+    }
+
+    companion object {
+        private const val DEFAULT_WAIT_HALF_SHEET_POPUP_TIMEOUT_MS = 1000L
+        private const val DEFAULT_HALF_SHEET_TITLE_TEXT = "Fast Pair Provider Simulator"
+        private const val DEFAULT_HALF_SHEET_SUBTITLE_TEXT = "Fast Pair Provider Simulator will " +
+                "appear on devices linked with nearby-mainline-fpseeker@google.com"
+        private const val WAIT_HALF_SHEET_POPUP_TIMEOUT_KEY = "WAIT_HALF_SHEET_POPUP_TIMEOUT_MS"
+        private const val HALF_SHEET_TITLE_KEY = "HALF_SHEET_TITLE"
+        private const val HALF_SHEET_SUBTITLE_KEY = "HALF_SHEET_SUBTITLE"
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/DismissNearbyHalfSheetUiTest.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/DismissNearbyHalfSheetUiTest.kt
new file mode 100644
index 0000000..1d99d26
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/DismissNearbyHalfSheetUiTest.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.seeker.ui
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** An instrumented test to dismiss Nearby half sheet UI.
+ *
+ * To run this test directly:
+ * am instrument -w -r \
+ * -e class android.nearby.multidevices.fastpair.seeker.ui.DismissNearbyHalfSheetUiTest \
+ * android.nearby.multidevices/androidx.test.runner.AndroidJUnitRunner
+ */
+@RunWith(AndroidJUnit4::class)
+class DismissNearbyHalfSheetUiTest {
+    private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+
+    @Test
+    fun dismissHalfSheet() {
+        device.pressHome()
+        device.waitForIdle()
+
+        assertWithMessage("Fail to dismiss Nearby half sheet.").that(
+            device.findObject(NearbyHalfSheetUiMap.DevicePairingFragment.connectButton)
+        ).isNull()
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/NearbyHalfSheetUiMap.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/NearbyHalfSheetUiMap.kt
new file mode 100644
index 0000000..c94ff01
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/NearbyHalfSheetUiMap.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.seeker.ui
+
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.BySelector
+
+/** UiMap for Nearby Mainline Half Sheet. */
+object NearbyHalfSheetUiMap {
+    private const val PACKAGE_NAME = "com.google.android.nearby.halfsheet"
+    private const val ANDROID_WIDGET_BUTTON = "android.widget.Button"
+    private const val ANDROID_WIDGET_IMAGE_VIEW = "android.widget.ImageView"
+    private const val ANDROID_WIDGET_TEXT_VIEW = "android.widget.TextView"
+
+    object DevicePairingFragment {
+        val halfSheetTitle: BySelector =
+            By.res(PACKAGE_NAME, "toolbar_title").clazz(ANDROID_WIDGET_TEXT_VIEW)
+        val halfSheetSubtitle: BySelector =
+            By.res(PACKAGE_NAME, "header_subtitle").clazz(ANDROID_WIDGET_TEXT_VIEW)
+        val deviceImage: BySelector =
+            By.res(PACKAGE_NAME, "pairing_pic").clazz(ANDROID_WIDGET_IMAGE_VIEW)
+        val connectButton: BySelector =
+            By.res(PACKAGE_NAME, "connect_btn").clazz(ANDROID_WIDGET_BUTTON).text("Connect")
+        val infoButton: BySelector =
+            By.res(PACKAGE_NAME, "info_icon").clazz(ANDROID_WIDGET_IMAGE_VIEW)
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/PairByNearbyHalfSheetUiTest.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/PairByNearbyHalfSheetUiTest.kt
new file mode 100644
index 0000000..9028668
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ui/PairByNearbyHalfSheetUiTest.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+package android.nearby.multidevices.fastpair.seeker.ui
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** An instrumented test to start pairing by interacting with Nearby half sheet UI.
+ *
+ * To run this test directly:
+ * am instrument -w -r \
+ * -e class android.nearby.multidevices.fastpair.seeker.ui.PairByNearbyHalfSheetUiTest \
+ * android.nearby.multidevices/androidx.test.runner.AndroidJUnitRunner
+ */
+@RunWith(AndroidJUnit4::class)
+class PairByNearbyHalfSheetUiTest {
+    private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+
+    @Test
+    fun clickConnectButton() {
+        val connectButton = NearbyHalfSheetUiMap.DevicePairingFragment.connectButton
+        device.findObject(connectButton).click()
+        device.wait(Until.gone(connectButton), CONNECT_BUTTON_TIMEOUT_MILLS)
+    }
+
+    companion object {
+        const val CONNECT_BUTTON_TIMEOUT_MILLS = 3000L
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/Android.bp b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/Android.bp
new file mode 100644
index 0000000..a6d51ca
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/Android.bp
@@ -0,0 +1,46 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_library {
+    name: "NearbyFastPairSeekerSharedLib",
+    srcs: ["shared/**/*.kt"],
+    sdk_version: "test_current",
+    static_libs: [
+        "guava",
+        "gson-prebuilt-jar",
+    ],
+}
+
+android_library {
+    name: "NearbyFastPairSeekerDataProviderLib",
+    srcs: ["src/**/*.kt"],
+    sdk_version: "test_current",
+    static_libs: ["NearbyFastPairSeekerSharedLib"],
+}
+
+android_app {
+    name: "NearbyFastPairSeekerDataProvider",
+    sdk_version: "test_current",
+    certificate: "platform",
+    static_libs: ["NearbyFastPairSeekerDataProviderLib"],
+    optimize: {
+        enabled: true,
+        shrink: true,
+        proguard_flags_files: ["proguard.flags"],
+    },
+}
diff --git a/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/AndroidManifest.xml b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/AndroidManifest.xml
new file mode 100644
index 0000000..1d62f04
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.nearby.fastpair.seeker.dataprovider">
+
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+
+    <application>
+        <!-- Fast Pair Data Provider Service which acts as an "overlay" to the
+             framework Fast Pair Data Provider. Only supported on Android T and later.
+             All overlays are protected from non-system access via WRITE_SECURE_SETTINGS.
+             Must stay in the same process as Nearby Discovery Service.
+        -->
+        <service
+            android:name=".FastPairTestDataProviderService"
+            android:exported="true"
+            android:permission="android.permission.WRITE_SECURE_SETTINGS"
+            android:visibleToInstantApps="true">
+            <intent-filter>
+                <action android:name="android.nearby.action.FAST_PAIR_DATA_PROVIDER" />
+            </intent-filter>
+
+            <meta-data
+                android:name="instantapps.clients.allowed"
+                android:value="true" />
+            <meta-data
+                android:name="serviceVersion"
+                android:value="1" />
+        </service>
+    </application>
+
+</manifest>
diff --git a/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/proguard.flags b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/proguard.flags
new file mode 100644
index 0000000..15debab
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/proguard.flags
@@ -0,0 +1,19 @@
+# Keep all receivers/service classes.
+-keep class android.nearby.fastpair.seeker.** {
+     *;
+}
+
+# Keep names for easy debugging.
+-dontobfuscate
+
+# Necessary to allow debugging.
+-keepattributes *
+
+# By default, proguard leaves all classes in their original package, which
+# needlessly repeats com.google.android.apps.etc.
+-repackageclasses ""
+
+# Allows proguard to make private and protected methods and fields public as
+# part of optimization. This lets proguard inline trivial getter/setter
+# methods.
+-allowaccessmodification
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/shared/android/nearby/fastpair/seeker/Constants.kt b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/shared/android/nearby/fastpair/seeker/Constants.kt
new file mode 100644
index 0000000..6070140
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/shared/android/nearby/fastpair/seeker/Constants.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.seeker
+
+const val FAKE_TEST_ACCOUNT_NAME = "nearby-mainline-fpseeker@google.com"
+
+const val ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA =
+    "android.nearby.fastpair.seeker.action.ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA"
+const val ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA =
+    "android.nearby.fastpair.seeker.action.ACCOUNT_KEY_DEVICE_METADATA"
+const val ACTION_RESET_TEST_DATA_CACHE = "android.nearby.fastpair.seeker.action.RESET"
+const val ACTION_WRITE_ACCOUNT_KEY_DEVICE_METADATA =
+    "android.nearby.fastpair.seeker.action.WRITE_ACCOUNT_KEY_DEVICE_METADATA"
+
+const val DATA_JSON_STRING_KEY = "json"
+const val DATA_MODEL_ID_STRING_KEY = "modelId"
diff --git a/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/shared/android/nearby/fastpair/seeker/FastPairTestDataCache.kt b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/shared/android/nearby/fastpair/seeker/FastPairTestDataCache.kt
new file mode 100644
index 0000000..e08a122
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/shared/android/nearby/fastpair/seeker/FastPairTestDataCache.kt
@@ -0,0 +1,325 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.seeker
+
+import android.nearby.FastPairAccountKeyDeviceMetadata
+import android.nearby.FastPairAntispoofKeyDeviceMetadata
+import android.nearby.FastPairDeviceMetadata
+import android.nearby.FastPairDiscoveryItem
+import com.google.common.io.BaseEncoding
+import com.google.gson.GsonBuilder
+import com.google.gson.annotations.SerializedName
+
+/** Manage a cache of Fast Pair test data for testing. */
+class FastPairTestDataCache {
+    private val gson = GsonBuilder().disableHtmlEscaping().create()
+    private val accountKeyDeviceMetadataList = mutableListOf<FastPairAccountKeyDeviceMetadata>()
+    private val antispoofKeyDeviceMetadataDataMap =
+        mutableMapOf<String, FastPairAntispoofKeyDeviceMetadataData>()
+
+    fun putAccountKeyDeviceMetadataJsonArray(json: String) {
+        accountKeyDeviceMetadataList +=
+            gson.fromJson(json, Array<FastPairAccountKeyDeviceMetadataData>::class.java)
+                .map { it.toFastPairAccountKeyDeviceMetadata() }
+    }
+
+    fun putAccountKeyDeviceMetadataJsonObject(json: String) {
+        accountKeyDeviceMetadataList +=
+            gson.fromJson(json, FastPairAccountKeyDeviceMetadataData::class.java)
+                .toFastPairAccountKeyDeviceMetadata()
+    }
+
+    fun putAccountKeyDeviceMetadata(accountKeyDeviceMetadata: FastPairAccountKeyDeviceMetadata) {
+        accountKeyDeviceMetadataList += accountKeyDeviceMetadata
+    }
+
+    fun getAccountKeyDeviceMetadataList(): List<FastPairAccountKeyDeviceMetadata> =
+        accountKeyDeviceMetadataList.toList()
+
+    fun dumpAccountKeyDeviceMetadataAsJson(metadata: FastPairAccountKeyDeviceMetadata): String =
+        gson.toJson(FastPairAccountKeyDeviceMetadataData(metadata))
+
+    fun dumpAccountKeyDeviceMetadataListAsJson(): String =
+        gson.toJson(accountKeyDeviceMetadataList.map { FastPairAccountKeyDeviceMetadataData(it) })
+
+    fun putAntispoofKeyDeviceMetadata(modelId: String, json: String) {
+        antispoofKeyDeviceMetadataDataMap[modelId] =
+            gson.fromJson(json, FastPairAntispoofKeyDeviceMetadataData::class.java)
+    }
+
+    fun getAntispoofKeyDeviceMetadata(modelId: String): FastPairAntispoofKeyDeviceMetadata? {
+        return antispoofKeyDeviceMetadataDataMap[modelId]?.toFastPairAntispoofKeyDeviceMetadata()
+    }
+
+    fun getFastPairDeviceMetadata(modelId: String): FastPairDeviceMetadata? =
+        antispoofKeyDeviceMetadataDataMap[modelId]?.deviceMeta?.toFastPairDeviceMetadata()
+
+    fun reset() {
+        accountKeyDeviceMetadataList.clear()
+        antispoofKeyDeviceMetadataDataMap.clear()
+    }
+
+    data class FastPairAccountKeyDeviceMetadataData(
+        @SerializedName("account_key") val accountKey: String?,
+        @SerializedName("sha256_account_key_public_address") val accountKeyPublicAddress: String?,
+        @SerializedName("fast_pair_device_metadata") val deviceMeta: FastPairDeviceMetadataData?,
+        @SerializedName("fast_pair_discovery_item") val discoveryItem: FastPairDiscoveryItemData?
+    ) {
+        constructor(meta: FastPairAccountKeyDeviceMetadata) : this(
+            accountKey = meta.deviceAccountKey?.base64Encode(),
+            accountKeyPublicAddress = meta.sha256DeviceAccountKeyPublicAddress?.base64Encode(),
+            deviceMeta = meta.fastPairDeviceMetadata?.let { FastPairDeviceMetadataData(it) },
+            discoveryItem = meta.fastPairDiscoveryItem?.let { FastPairDiscoveryItemData(it) }
+        )
+
+        fun toFastPairAccountKeyDeviceMetadata(): FastPairAccountKeyDeviceMetadata {
+            return FastPairAccountKeyDeviceMetadata.Builder()
+                .setDeviceAccountKey(accountKey?.base64Decode())
+                .setSha256DeviceAccountKeyPublicAddress(accountKeyPublicAddress?.base64Decode())
+                .setFastPairDeviceMetadata(deviceMeta?.toFastPairDeviceMetadata())
+                .setFastPairDiscoveryItem(discoveryItem?.toFastPairDiscoveryItem())
+                .build()
+        }
+    }
+
+    data class FastPairAntispoofKeyDeviceMetadataData(
+        @SerializedName("anti_spoofing_public_key_str") val antispoofPublicKey: String?,
+        @SerializedName("fast_pair_device_metadata") val deviceMeta: FastPairDeviceMetadataData?
+    ) {
+        fun toFastPairAntispoofKeyDeviceMetadata(): FastPairAntispoofKeyDeviceMetadata {
+            return FastPairAntispoofKeyDeviceMetadata.Builder()
+                .setAntispoofPublicKey(antispoofPublicKey?.base64Decode())
+                .setFastPairDeviceMetadata(deviceMeta?.toFastPairDeviceMetadata())
+                .build()
+        }
+    }
+
+    data class FastPairDeviceMetadataData(
+        @SerializedName("assistant_setup_half_sheet") val assistantSetupHalfSheet: String?,
+        @SerializedName("assistant_setup_notification") val assistantSetupNotification: String?,
+        @SerializedName("ble_tx_power") val bleTxPower: Int,
+        @SerializedName("confirm_pin_description") val confirmPinDescription: String?,
+        @SerializedName("confirm_pin_title") val confirmPinTitle: String?,
+        @SerializedName("connect_success_companion_app_installed") val compAppInstalled: String?,
+        @SerializedName("connect_success_companion_app_not_installed") val comAppNotIns: String?,
+        @SerializedName("device_type") val deviceType: Int,
+        @SerializedName("download_companion_app_description") val downloadComApp: String?,
+        @SerializedName("fail_connect_go_to_settings_description") val failConnectDes: String?,
+        @SerializedName("fast_pair_tv_connect_device_no_account_description") val accDes: String?,
+        @SerializedName("image_url") val imageUrl: String?,
+        @SerializedName("initial_notification_description") val initNotification: String?,
+        @SerializedName("initial_notification_description_no_account") val initNoAccount: String?,
+        @SerializedName("initial_pairing_description") val initialPairingDescription: String?,
+        @SerializedName("intent_uri") val intentUri: String?,
+        @SerializedName("locale") val locale: String?,
+        @SerializedName("name") val name: String?,
+        @SerializedName("open_companion_app_description") val openCompanionAppDescription: String?,
+        @SerializedName("retroactive_pairing_description") val retroactivePairingDes: String?,
+        @SerializedName("subsequent_pairing_description") val subsequentPairingDescription: String?,
+        @SerializedName("sync_contacts_description") val syncContactsDescription: String?,
+        @SerializedName("sync_contacts_title") val syncContactsTitle: String?,
+        @SerializedName("sync_sms_description") val syncSmsDescription: String?,
+        @SerializedName("sync_sms_title") val syncSmsTitle: String?,
+        @SerializedName("trigger_distance") val triggerDistance: Double,
+        @SerializedName("case_url") val trueWirelessImageUrlCase: String?,
+        @SerializedName("left_bud_url") val trueWirelessImageUrlLeftBud: String?,
+        @SerializedName("right_bud_url") val trueWirelessImageUrlRightBud: String?,
+        @SerializedName("unable_to_connect_description") val unableToConnectDescription: String?,
+        @SerializedName("unable_to_connect_title") val unableToConnectTitle: String?,
+        @SerializedName("update_companion_app_description") val updateCompAppDes: String?,
+        @SerializedName("wait_launch_companion_app_description") val waitLaunchCompApp: String?
+    ) {
+        constructor(meta: FastPairDeviceMetadata) : this(
+            assistantSetupHalfSheet = meta.assistantSetupHalfSheet,
+            assistantSetupNotification = meta.assistantSetupNotification,
+            bleTxPower = meta.bleTxPower,
+            confirmPinDescription = meta.confirmPinDescription,
+            confirmPinTitle = meta.confirmPinTitle,
+            compAppInstalled = meta.connectSuccessCompanionAppInstalled,
+            comAppNotIns = meta.connectSuccessCompanionAppNotInstalled,
+            deviceType = meta.deviceType,
+            downloadComApp = meta.downloadCompanionAppDescription,
+            failConnectDes = meta.failConnectGoToSettingsDescription,
+            accDes = meta.fastPairTvConnectDeviceNoAccountDescription,
+            imageUrl = meta.imageUrl,
+            initNotification = meta.initialNotificationDescription,
+            initNoAccount = meta.initialNotificationDescriptionNoAccount,
+            initialPairingDescription = meta.initialPairingDescription,
+            intentUri = meta.intentUri,
+            locale = meta.locale,
+            name = meta.name,
+            openCompanionAppDescription = meta.openCompanionAppDescription,
+            retroactivePairingDes = meta.retroactivePairingDescription,
+            subsequentPairingDescription = meta.subsequentPairingDescription,
+            syncContactsDescription = meta.syncContactsDescription,
+            syncContactsTitle = meta.syncContactsTitle,
+            syncSmsDescription = meta.syncSmsDescription,
+            syncSmsTitle = meta.syncSmsTitle,
+            triggerDistance = meta.triggerDistance.toDouble(),
+            trueWirelessImageUrlCase = meta.trueWirelessImageUrlCase,
+            trueWirelessImageUrlLeftBud = meta.trueWirelessImageUrlLeftBud,
+            trueWirelessImageUrlRightBud = meta.trueWirelessImageUrlRightBud,
+            unableToConnectDescription = meta.unableToConnectDescription,
+            unableToConnectTitle = meta.unableToConnectTitle,
+            updateCompAppDes = meta.updateCompanionAppDescription,
+            waitLaunchCompApp = meta.waitLaunchCompanionAppDescription
+        )
+
+        fun toFastPairDeviceMetadata(): FastPairDeviceMetadata {
+            return FastPairDeviceMetadata.Builder()
+                .setAssistantSetupHalfSheet(assistantSetupHalfSheet)
+                .setAssistantSetupNotification(assistantSetupNotification)
+                .setBleTxPower(bleTxPower)
+                .setConfirmPinDescription(confirmPinDescription)
+                .setConfirmPinTitle(confirmPinTitle)
+                .setConnectSuccessCompanionAppInstalled(compAppInstalled)
+                .setConnectSuccessCompanionAppNotInstalled(comAppNotIns)
+                .setDeviceType(deviceType)
+                .setDownloadCompanionAppDescription(downloadComApp)
+                .setFailConnectGoToSettingsDescription(failConnectDes)
+                .setFastPairTvConnectDeviceNoAccountDescription(accDes)
+                .setImageUrl(imageUrl)
+                .setInitialNotificationDescription(initNotification)
+                .setInitialNotificationDescriptionNoAccount(initNoAccount)
+                .setInitialPairingDescription(initialPairingDescription)
+                .setIntentUri(intentUri)
+                .setLocale(locale)
+                .setName(name)
+                .setOpenCompanionAppDescription(openCompanionAppDescription)
+                .setRetroactivePairingDescription(retroactivePairingDes)
+                .setSubsequentPairingDescription(subsequentPairingDescription)
+                .setSyncContactsDescription(syncContactsDescription)
+                .setSyncContactsTitle(syncContactsTitle)
+                .setSyncSmsDescription(syncSmsDescription)
+                .setSyncSmsTitle(syncSmsTitle)
+                .setTriggerDistance(triggerDistance.toFloat())
+                .setTrueWirelessImageUrlCase(trueWirelessImageUrlCase)
+                .setTrueWirelessImageUrlLeftBud(trueWirelessImageUrlLeftBud)
+                .setTrueWirelessImageUrlRightBud(trueWirelessImageUrlRightBud)
+                .setUnableToConnectDescription(unableToConnectDescription)
+                .setUnableToConnectTitle(unableToConnectTitle)
+                .setUpdateCompanionAppDescription(updateCompAppDes)
+                .setWaitLaunchCompanionAppDescription(waitLaunchCompApp)
+                .build()
+        }
+    }
+
+    data class FastPairDiscoveryItemData(
+        @SerializedName("action_url") val actionUrl: String?,
+        @SerializedName("action_url_type") val actionUrlType: Int,
+        @SerializedName("app_name") val appName: String?,
+        @SerializedName("attachment_type") val attachmentType: Int,
+        @SerializedName("authentication_public_key_secp256r1") val authenticationPublicKey: String?,
+        @SerializedName("ble_record_bytes") val bleRecordBytes: String?,
+        @SerializedName("debug_category") val debugCategory: Int,
+        @SerializedName("debug_message") val debugMessage: String?,
+        @SerializedName("description") val description: String?,
+        @SerializedName("device_name") val deviceName: String?,
+        @SerializedName("display_url") val displayUrl: String?,
+        @SerializedName("entity_id") val entityId: String?,
+        @SerializedName("feature_graphic_url") val featureGraphicUrl: String?,
+        @SerializedName("first_observation_timestamp_millis") val firstObservationMs: Long,
+        @SerializedName("group_id") val groupId: String?,
+        @SerializedName("icon_fife_url") val iconFfeUrl: String?,
+        @SerializedName("icon_png") val iconPng: String?,
+        @SerializedName("id") val id: String?,
+        @SerializedName("last_observation_timestamp_millis") val lastObservationMs: Long,
+        @SerializedName("last_user_experience") val lastUserExperience: Int,
+        @SerializedName("lost_millis") val lostMillis: Long,
+        @SerializedName("mac_address") val macAddress: String?,
+        @SerializedName("package_name") val packageName: String?,
+        @SerializedName("pending_app_install_timestamp_millis") val pendingAppInstallMs: Long,
+        @SerializedName("rssi") val rssi: Int,
+        @SerializedName("state") val state: Int,
+        @SerializedName("title") val title: String?,
+        @SerializedName("trigger_id") val triggerId: String?,
+        @SerializedName("tx_power") val txPower: Int,
+        @SerializedName("type") val type: Int
+    ) {
+        constructor(item: FastPairDiscoveryItem) : this(
+            actionUrl = item.actionUrl,
+            actionUrlType = item.actionUrlType,
+            appName = item.appName,
+            attachmentType = item.attachmentType,
+            authenticationPublicKey = item.authenticationPublicKeySecp256r1?.base64Encode(),
+            bleRecordBytes = item.bleRecordBytes?.base64Encode(),
+            debugCategory = item.debugCategory,
+            debugMessage = item.debugMessage,
+            description = item.description,
+            deviceName = item.deviceName,
+            displayUrl = item.displayUrl,
+            entityId = item.entityId,
+            featureGraphicUrl = item.featureGraphicUrl,
+            firstObservationMs = item.firstObservationTimestampMillis,
+            groupId = item.groupId,
+            iconFfeUrl = item.iconFfeUrl,
+            iconPng = item.iconPng?.base64Encode(),
+            id = item.id,
+            lastObservationMs = item.lastObservationTimestampMillis,
+            lastUserExperience = item.lastUserExperience,
+            lostMillis = item.lostMillis,
+            macAddress = item.macAddress,
+            packageName = item.packageName,
+            pendingAppInstallMs = item.pendingAppInstallTimestampMillis,
+            rssi = item.rssi,
+            state = item.state,
+            title = item.title,
+            triggerId = item.triggerId,
+            txPower = item.txPower,
+            type = item.type
+        )
+
+        fun toFastPairDiscoveryItem(): FastPairDiscoveryItem {
+            return FastPairDiscoveryItem.Builder()
+                .setActionUrl(actionUrl)
+                .setActionUrlType(actionUrlType)
+                .setAppName(appName)
+                .setAttachmentType(attachmentType)
+                .setAuthenticationPublicKeySecp256r1(authenticationPublicKey?.base64Decode())
+                .setBleRecordBytes(bleRecordBytes?.base64Decode())
+                .setDebugCategory(debugCategory)
+                .setDebugMessage(debugMessage)
+                .setDescription(description)
+                .setDeviceName(deviceName)
+                .setDisplayUrl(displayUrl)
+                .setEntityId(entityId)
+                .setFeatureGraphicUrl(featureGraphicUrl)
+                .setFirstObservationTimestampMillis(firstObservationMs)
+                .setGroupId(groupId)
+                .setIconFfeUrl(iconFfeUrl)
+                .setIconPng(iconPng?.base64Decode())
+                .setId(id)
+                .setLastObservationTimestampMillis(lastObservationMs)
+                .setLastUserExperience(lastUserExperience)
+                .setLostMillis(lostMillis)
+                .setMacAddress(macAddress)
+                .setPackageName(packageName)
+                .setPendingAppInstallTimestampMillis(pendingAppInstallMs)
+                .setRssi(rssi)
+                .setState(state)
+                .setTitle(title)
+                .setTriggerId(triggerId)
+                .setTxPower(txPower)
+                .setType(type)
+                .build()
+        }
+    }
+}
+
+private fun String.base64Decode(): ByteArray = BaseEncoding.base64().decode(this)
+
+private fun ByteArray.base64Encode(): String = BaseEncoding.base64().encode(this)
diff --git a/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/data/FastPairTestDataManager.kt b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/data/FastPairTestDataManager.kt
new file mode 100644
index 0000000..e924da1
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/data/FastPairTestDataManager.kt
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.seeker.data
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.nearby.FastPairAccountKeyDeviceMetadata
+import android.nearby.fastpair.seeker.ACTION_RESET_TEST_DATA_CACHE
+import android.nearby.fastpair.seeker.ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA
+import android.nearby.fastpair.seeker.ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA
+import android.nearby.fastpair.seeker.ACTION_WRITE_ACCOUNT_KEY_DEVICE_METADATA
+import android.nearby.fastpair.seeker.DATA_JSON_STRING_KEY
+import android.nearby.fastpair.seeker.DATA_MODEL_ID_STRING_KEY
+import android.nearby.fastpair.seeker.FastPairTestDataCache
+import android.util.Log
+
+/** Manage local FastPairTestDataCache and receive/update the remote cache in test snippet. */
+class FastPairTestDataManager(private val context: Context) : BroadcastReceiver() {
+    val testDataCache = FastPairTestDataCache()
+
+    /** Writes a FastPairAccountKeyDeviceMetadata into local and remote cache.
+     *
+     * @param accountKeyDeviceMetadata the FastPairAccountKeyDeviceMetadata to write.
+     * @return a json object string of the accountKeyDeviceMetadata.
+     */
+    fun writeAccountKeyDeviceMetadata(
+        accountKeyDeviceMetadata: FastPairAccountKeyDeviceMetadata
+    ): String {
+        testDataCache.putAccountKeyDeviceMetadata(accountKeyDeviceMetadata)
+
+        val json =
+            testDataCache.dumpAccountKeyDeviceMetadataAsJson(accountKeyDeviceMetadata)
+        Intent().also { intent ->
+            intent.action = ACTION_WRITE_ACCOUNT_KEY_DEVICE_METADATA
+            intent.putExtra(DATA_JSON_STRING_KEY, json)
+            context.sendBroadcast(intent)
+        }
+        return json
+    }
+
+    /**
+     * Callback method for receiving Intent broadcast from test snippet.
+     *
+     * See [BroadcastReceiver#onReceive].
+     *
+     * @param context the Context in which the receiver is running.
+     * @param intent the Intent being received.
+     */
+    override fun onReceive(context: Context, intent: Intent) {
+        when (intent.action) {
+            ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA -> {
+                Log.d(TAG, "ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA received!")
+                val modelId = intent.getStringExtra(DATA_MODEL_ID_STRING_KEY)!!
+                val json = intent.getStringExtra(DATA_JSON_STRING_KEY)!!
+                testDataCache.putAntispoofKeyDeviceMetadata(modelId, json)
+            }
+            ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA -> {
+                Log.d(TAG, "ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA received!")
+                val json = intent.getStringExtra(DATA_JSON_STRING_KEY)!!
+                testDataCache.putAccountKeyDeviceMetadataJsonArray(json)
+            }
+            ACTION_RESET_TEST_DATA_CACHE -> {
+                Log.d(TAG, "ACTION_RESET_TEST_DATA_CACHE received!")
+                testDataCache.reset()
+            }
+            else -> Log.d(TAG, "Unknown action received!")
+        }
+    }
+
+    companion object {
+        private const val TAG = "FastPairTestDataManager"
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/dataprovider/FastPairTestDataProviderService.kt b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/dataprovider/FastPairTestDataProviderService.kt
new file mode 100644
index 0000000..3f5a803
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/dataprovider/FastPairTestDataProviderService.kt
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.seeker.dataprovider
+
+import android.accounts.Account
+import android.content.IntentFilter
+import android.nearby.FastPairDataProviderService
+import android.nearby.FastPairEligibleAccount
+import android.nearby.fastpair.seeker.*
+import android.nearby.fastpair.seeker.data.FastPairTestDataManager
+import android.util.Log
+
+/**
+ * Fast Pair Test Data Provider Service entry point for platform overlay.
+ */
+class FastPairTestDataProviderService : FastPairDataProviderService(TAG) {
+    private lateinit var testDataManager: FastPairTestDataManager
+
+    override fun onCreate() {
+        Log.d(TAG, "onCreate()")
+        testDataManager = FastPairTestDataManager(this)
+
+        val bondStateFilter = IntentFilter(ACTION_RESET_TEST_DATA_CACHE).apply {
+            addAction(ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA)
+            addAction(ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA)
+        }
+        registerReceiver(testDataManager, bondStateFilter)
+    }
+
+    override fun onDestroy() {
+        Log.d(TAG, "onDestroy()")
+        unregisterReceiver(testDataManager)
+
+        super.onDestroy()
+    }
+
+    override fun onLoadFastPairAntispoofKeyDeviceMetadata(
+        request: FastPairAntispoofKeyDeviceMetadataRequest,
+        callback: FastPairAntispoofKeyDeviceMetadataCallback
+    ) {
+        val requestedModelId = request.modelId.bytesToStringLowerCase()
+        Log.d(TAG, "onLoadFastPairAntispoofKeyDeviceMetadata(modelId: $requestedModelId)")
+
+        val fastPairAntispoofKeyDeviceMetadata =
+            testDataManager.testDataCache.getAntispoofKeyDeviceMetadata(requestedModelId)
+        if (fastPairAntispoofKeyDeviceMetadata != null) {
+            callback.onFastPairAntispoofKeyDeviceMetadataReceived(fastPairAntispoofKeyDeviceMetadata)
+        } else {
+            Log.d(TAG, "No metadata available for $requestedModelId!")
+            callback.onError(ERROR_CODE_BAD_REQUEST, "No metadata available for $requestedModelId")
+        }
+    }
+
+    override fun onLoadFastPairAccountDevicesMetadata(
+        request: FastPairAccountDevicesMetadataRequest,
+        callback: FastPairAccountDevicesMetadataCallback
+    ) {
+        val requestedAccount = request.account
+        val requestedAccountKeys = request.deviceAccountKeys
+        Log.d(
+            TAG, "onLoadFastPairAccountDevicesMetadata(" +
+                    "account: $requestedAccount, accountKeys:$requestedAccountKeys)"
+        )
+        Log.d(TAG, testDataManager.testDataCache.dumpAccountKeyDeviceMetadataListAsJson())
+
+        callback.onFastPairAccountDevicesMetadataReceived(
+            testDataManager.testDataCache.getAccountKeyDeviceMetadataList()
+        )
+    }
+
+    override fun onLoadFastPairEligibleAccounts(
+        request: FastPairEligibleAccountsRequest,
+        callback: FastPairEligibleAccountsCallback
+    ) {
+        Log.d(TAG, "onLoadFastPairEligibleAccounts()")
+        callback.onFastPairEligibleAccountsReceived(ELIGIBLE_ACCOUNTS_TEST_CONSTANT)
+    }
+
+    override fun onManageFastPairAccount(
+        request: FastPairManageAccountRequest, callback: FastPairManageActionCallback
+    ) {
+        val requestedAccount = request.account
+        val requestType = request.requestType
+        Log.d(TAG, "onManageFastPairAccount(account: $requestedAccount, requestType: $requestType)")
+
+        callback.onSuccess()
+    }
+
+    override fun onManageFastPairAccountDevice(
+        request: FastPairManageAccountDeviceRequest, callback: FastPairManageActionCallback
+    ) {
+        val requestedAccount = request.account
+        val requestType = request.requestType
+        val requestTypeString = if (requestType == MANAGE_REQUEST_ADD) "Add" else "Remove"
+        val requestedBleAddress = request.bleAddress
+        val requestedAccountKeyDeviceMetadata = request.accountKeyDeviceMetadata
+        Log.d(
+            TAG,
+            "onManageFastPairAccountDevice(requestedAccount: $requestedAccount, " +
+                    "requestType: $requestTypeString,"
+        )
+        Log.d(TAG, "requestedBleAddress: $requestedBleAddress,")
+
+        val requestedAccountKeyDeviceMetadataInJson =
+            testDataManager.writeAccountKeyDeviceMetadata(requestedAccountKeyDeviceMetadata)
+        Log.d(TAG, "requestedAccountKeyDeviceMetadata: $requestedAccountKeyDeviceMetadataInJson)")
+
+        callback.onSuccess()
+    }
+
+    companion object {
+        private const val TAG = "FastPairTestDataProviderService"
+        private val ELIGIBLE_ACCOUNTS_TEST_CONSTANT = listOf(
+            FastPairEligibleAccount.Builder()
+                .setAccount(Account(FAKE_TEST_ACCOUNT_NAME, "FakeTestAccount"))
+                .setOptIn(true)
+                .build(),
+        )
+
+        private fun ByteArray.bytesToStringLowerCase(): String =
+            joinToString(separator = "") { eachByte -> "%02x".format(eachByte) }
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/Android.bp b/nearby/tests/multidevices/clients/test_support/fastpair_provider/Android.bp
new file mode 100644
index 0000000..e01c436
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/Android.bp
@@ -0,0 +1,44 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_library {
+    name: "NearbyFastPairProviderLib",
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
+    sdk_version: "core_platform",
+    libs: [
+        // order matters: classes in framework-bluetooth are resolved before framework, meaning
+        // @hide APIs in framework-bluetooth are resolved before @SystemApi stubs in framework
+        "framework-bluetooth.impl",
+        "framework",
+
+        // if sdk_version="" this gets automatically included, but here we need to add manually.
+        "framework-res",
+    ],
+    static_libs: [
+        "NearbyFastPairProviderLiteProtos",
+        "androidx.test.core",
+        "error_prone_annotations",
+        "fast-pair-lite-protos",
+        "framework-annotations-lib",
+        "kotlin-stdlib",
+        "service-nearby-pre-jarjar",
+    ],
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/AndroidManifest.xml b/nearby/tests/multidevices/clients/test_support/fastpair_provider/AndroidManifest.xml
new file mode 100644
index 0000000..400a434
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.nearby.fastpair.provider">
+
+    <uses-feature android:name="android.hardware.bluetooth" />
+    <uses-feature android:name="android.hardware.bluetooth_le" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
+
+</manifest>
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/proto/Android.bp b/nearby/tests/multidevices/clients/test_support/fastpair_provider/proto/Android.bp
new file mode 100644
index 0000000..7ae43e5
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/proto/Android.bp
@@ -0,0 +1,30 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+    name: "NearbyFastPairProviderLiteProtos",
+    proto: {
+        type: "lite",
+        canonical_path_from_root: false,
+    },
+    sdk_version: "system_current",
+    min_sdk_version: "30",
+    srcs: ["*.proto"],
+}
+
+
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/proto/event_stream_protocol.proto b/nearby/tests/multidevices/clients/test_support/fastpair_provider/proto/event_stream_protocol.proto
new file mode 100644
index 0000000..54db34a
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/proto/event_stream_protocol.proto
@@ -0,0 +1,85 @@
+syntax = "proto2";
+
+package android.nearby.fastpair.provider;
+
+option java_package = "android.nearby.fastpair.provider";
+option java_outer_classname = "EventStreamProtocol";
+
+enum EventGroup {
+  UNSPECIFIED = 0;
+  BLUETOOTH = 1;
+  LOGGING = 2;
+  DEVICE = 3;
+  DEVICE_ACTION = 4;
+  DEVICE_CONFIGURATION = 5;
+  DEVICE_CAPABILITY_SYNC = 6;
+  SMART_AUDIO_SOURCE_SWITCHING = 7;
+  ACKNOWLEDGEMENT = 255;
+}
+
+enum BluetoothEventCode {
+  BLUETOOTH_UNSPECIFIED = 0;
+  BLUETOOTH_ENABLE_SILENCE_MODE = 1;
+  BLUETOOTH_DISABLE_SILENCE_MODE = 2;
+}
+
+enum LoggingEventCode {
+  LOG_UNSPECIFIED = 0;
+  LOG_FULL = 1;
+  LOG_SAVE_TO_BUFFER = 2;
+}
+
+enum DeviceEventCode {
+  DEVICE_UNSPECIFIED = 0;
+  DEVICE_MODEL_ID = 1;
+  DEVICE_BLE_ADDRESS = 2;
+  DEVICE_BATTERY_INFO = 3;
+  ACTIVE_COMPONENTS_REQUEST = 5;
+  ACTIVE_COMPONENTS_RESPONSE = 6;
+  DEVICE_CAPABILITY = 7;
+  PLATFORM_TYPE = 8;
+  FIRMWARE_VERSION = 9;
+  SECTION_NONCE = 10;
+}
+
+enum DeviceActionEventCode {
+  DEVICE_ACTION_UNSPECIFIED = 0;
+  DEVICE_ACTION_RING = 1;
+}
+
+enum DeviceConfigurationEventCode {
+  CONFIGURATION_UNSPECIFIED = 0;
+  CONFIGURATION_BUFFER_SIZE = 1;
+}
+
+enum DeviceCapabilitySyncEventCode {
+  REQUEST_UNSPECIFIED = 0;
+  REQUEST_CAPABILITY_UPDATE = 1;
+  CONFIGURABLE_BUFFER_SIZE_RANGE = 2;
+}
+
+enum AcknowledgementEventCode {
+  ACKNOWLEDGEMENT_UNSPECIFIED = 0;
+  ACKNOWLEDGEMENT_ACK = 1;
+  ACKNOWLEDGEMENT_NAK = 2;
+}
+
+enum PlatformType {
+  PLATFORM_TYPE_UNKNOWN = 0;
+  ANDROID = 1;
+}
+
+enum SassEventCode {
+  EVENT_UNSPECIFIED = 0;
+  EVENT_GET_CAPABILITY_OF_SASS = 0x10;
+  EVENT_NOTIFY_CAPABILITY_OF_SASS = 0x11;
+  EVENT_SET_MULTI_POINT_STATE = 0x12;
+  EVENT_SWITCH_AUDIO_SOURCE_BETWEEN_CONNECTED_DEVICES = 0x30;
+  EVENT_SWITCH_BACK = 0x31;
+  EVENT_NOTIFY_MULTIPOINT_SWITCH_EVENT = 0x32;
+  EVENT_GET_CONNECTION_STATUS = 0x33;
+  EVENT_NOTIFY_CONNECTION_STATUS = 0x34;
+  EVENT_SASS_INITIATED_CONNECTION = 0x40;
+  EVENT_INDICATE_IN_USE_ACCOUNT_KEY = 0x41;
+  EVENT_SET_CUSTOM_DATA = 0x42;
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/Android.bp b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/Android.bp
new file mode 100644
index 0000000..87d352f
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/Android.bp
@@ -0,0 +1,56 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// Build and install NearbyFastPairProviderSimulatorApp to your phone:
+// m NearbyFastPairProviderSimulatorApp
+// adb root
+// adb remount && adb reboot (make first time remount work)
+//
+// adb root
+// adb remount
+// adb push ${ANDROID_PRODUCT_OUT}/system/app/NearbyFastPairProviderSimulatorApp /system/app/
+// adb reboot
+android_app {
+    name: "NearbyFastPairProviderSimulatorApp",
+    sdk_version: "test_current",
+    // Sign with "platform" certificate for accessing Bluetooth @SystemAPI
+    certificate: "platform",
+    static_libs: ["NearbyFastPairProviderSimulatorLib"],
+    optimize: {
+        enabled: true,
+        shrink: true,
+        proguard_flags_files: ["proguard.flags"],
+    },
+}
+
+android_library {
+    name: "NearbyFastPairProviderSimulatorLib",
+    sdk_version: "test_current",
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
+    static_libs: [
+        "NearbyFastPairProviderLib",
+        "NearbyFastPairProviderLiteProtos",
+        "NearbyFastPairProviderSimulatorLiteProtos",
+        "androidx.annotation_annotation",
+        "error_prone_annotations",
+        "fast-pair-lite-protos",
+    ],
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/AndroidManifest.xml b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/AndroidManifest.xml
new file mode 100644
index 0000000..8880b11
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.nearby.fastpair.provider.simulator.app" >
+
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
+
+    <application
+        android:allowBackup="true"
+        android:label="@string/app_name" >
+        <activity
+            android:name=".MainActivity"
+            android:windowSoftInputMode="stateHidden"
+            android:screenOrientation="portrait"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/proguard.flags b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/proguard.flags
new file mode 100644
index 0000000..0827c60
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/proguard.flags
@@ -0,0 +1,19 @@
+# Keep AdvertisingSetCallback#onOwnAddressRead callback.
+-keep class * extends android.bluetooth.le.AdvertisingSetCallback {
+     *;
+}
+
+# Keep names for easy debugging.
+-dontobfuscate
+
+# Necessary to allow debugging.
+-keepattributes *
+
+# By default, proguard leaves all classes in their original package, which
+# needlessly repeats com.google.android.apps.etc.
+-repackageclasses ""
+
+# Allows proguard to make private and protected methods and fields public as
+# part of optimization. This lets proguard inline trivial getter/setter
+# methods.
+-allowaccessmodification
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/proto/Android.bp b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/proto/Android.bp
new file mode 100644
index 0000000..e964800
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/proto/Android.bp
@@ -0,0 +1,30 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+    name: "NearbyFastPairProviderSimulatorLiteProtos",
+    proto: {
+        type: "lite",
+        canonical_path_from_root: false,
+    },
+    sdk_version: "system_current",
+    min_sdk_version: "30",
+    srcs: ["*.proto"],
+}
+
+
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/proto/simulator_stream_protocol.proto b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/proto/simulator_stream_protocol.proto
new file mode 100644
index 0000000..9b17fda
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/proto/simulator_stream_protocol.proto
@@ -0,0 +1,110 @@
+syntax = "proto2";
+
+package android.nearby.fastpair.provider.simulator;
+
+option java_package = "android.nearby.fastpair.provider.simulator";
+option java_outer_classname = "SimulatorStreamProtocol";
+
+// Used by remote devices to control simulator behaviors.
+message Command {
+  // Type of this command.
+  required Code code = 1;
+
+  // Required for SHOW_BATTERY.
+  optional BatteryInfo battery_info = 2;
+
+  enum Code {
+    // Request for simulator's acknowledge message.
+    POLLING = 0;
+
+    // Reset and clear bluetooth state.
+    RESET = 1;
+
+    // Present battery information in the advertisement.
+    SHOW_BATTERY = 2;
+
+    // Remove battery information in the advertisement.
+    HIDE_BATTERY = 3;
+
+    // Request for BR/EDR address.
+    REQUEST_BLUETOOTH_ADDRESS_PUBLIC = 4;
+
+    // Request for BLE address.
+    REQUEST_BLUETOOTH_ADDRESS_BLE = 5;
+
+    // Request for account key.
+    REQUEST_ACCOUNT_KEY = 6;
+  }
+
+  // Battery information for true wireless headsets.
+  // https://devsite.googleplex.com/nearby/fast-pair/early-access/spec#BatteryNotification
+  message BatteryInfo {
+    // Show or hide the battery UI notification.
+    optional bool suppress_notification = 1;
+    repeated BatteryValue battery_values = 2;
+
+    // Advertised battery level data.
+    message BatteryValue {
+      // The charging flag.
+      required bool charging = 1;
+
+      // Battery level from 0 to 100.
+      required uint32 level = 2;
+    }
+  }
+}
+
+// Notify the remote devices when states are changed or response the command on
+// the simulator.
+message Event {
+  // Type of this event.
+  required Code code = 1;
+
+  // Required for BLUETOOTH_STATE_BOND.
+  optional int32 bond_state = 2;
+
+  // Required for BLUETOOTH_STATE_CONNECTION.
+  optional int32 connection_state = 3;
+
+  // Required for BLUETOOTH_STATE_SCAN_MODE.
+  optional int32 scan_mode = 4;
+
+  // Required for BLUETOOTH_ADDRESS_PUBLIC.
+  optional string public_address = 5;
+
+  // Required for BLUETOOTH_ADDRESS_BLE.
+  optional string ble_address = 6;
+
+  // Required for BLUETOOTH_ALIAS_NAME.
+  optional string alias_name = 7;
+
+  // Required for REQUEST_ACCOUNT_KEY.
+  optional bytes account_key = 8;
+
+  enum Code {
+    // Response the polling.
+    ACKNOWLEDGE = 0;
+
+    // Notify the event android.bluetooth.device.action.BOND_STATE_CHANGED
+    BLUETOOTH_STATE_BOND = 1;
+
+    // Notify the event
+    // android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
+    BLUETOOTH_STATE_CONNECTION = 2;
+
+    // Notify the event android.bluetooth.adapter.action.SCAN_MODE_CHANGED
+    BLUETOOTH_STATE_SCAN_MODE = 3;
+
+    // Notify the current BR/EDR address
+    BLUETOOTH_ADDRESS_PUBLIC = 4;
+
+    // Notify the current BLE address
+    BLUETOOTH_ADDRESS_BLE = 5;
+
+    // Notify the event android.bluetooth.device.action.ALIAS_CHANGED
+    BLUETOOTH_ALIAS_NAME = 6;
+
+    // Response the REQUEST_ACCOUNT_KEY.
+    ACCOUNT_KEY = 7;
+  }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/layout/activity_main.xml b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/layout/activity_main.xml
new file mode 100644
index 0000000..b7e85eb
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/layout/activity_main.xml
@@ -0,0 +1,190 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:layout_margin="16dp"
+    android:keepScreenOn="true"
+    tools:context=".MainActivity">
+
+    <TextView
+        android:id="@+id/bluetooth_address_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textSize="14dp"
+        android:textStyle="bold"
+        android:padding="8dp"/>
+
+    <TextView
+        android:id="@+id/device_name_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textSize="14dp"
+        android:textStyle="bold"
+        android:padding="8dp"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="8dp"
+        android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="14dp"
+                android:textStyle="bold"
+                android:text="Model ID:"/>
+            <Spinner
+                android:id="@+id/model_id_spinner"
+                android:textSize="14dp"
+                android:textStyle="bold"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+        <TextView
+            android:id="@+id/tx_power_text_view"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="wrap_content"
+            android:textSize="14dp"
+            android:textStyle="bold" />
+    </LinearLayout>
+
+    <TextView
+        android:id="@+id/anti_spoofing_private_key_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textSize="14dp"
+        android:textStyle="bold"
+        android:padding="8dp"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <TextView
+            android:id="@+id/is_advertising_text_view"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="wrap_content"
+            android:textSize="14dp"
+            android:textStyle="bold"
+            android:padding="8dp"/>
+        <TextView
+            android:id="@+id/scan_mode_text_view"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="wrap_content"
+            android:textSize="14dp"
+            android:textStyle="bold"
+            android:padding="8dp"/>
+    </LinearLayout>
+
+    <TextView
+        android:id="@+id/remote_device_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textSize="14dp"
+        android:textStyle="bold"
+        android:padding="8dp"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <TextView
+            android:id="@+id/is_paired_text_view"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="wrap_content"
+            android:textSize="14dp"
+            android:textStyle="bold"
+            android:padding="8dp"/>
+        <TextView
+            android:id="@+id/is_connected_text_view"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="wrap_content"
+            android:textSize="14dp"
+            android:textStyle="bold"
+            android:padding="8dp"/>
+    </LinearLayout>
+
+    <Button
+        android:id="@+id/reset_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="Reset"
+        android:onClick="onResetButtonClicked"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp"
+        android:orientation="horizontal"
+        android:layout_gravity="center_vertical">
+
+      <Spinner
+          android:id="@+id/event_stream_spinner"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"/>
+
+      <Button
+          android:id="@+id/send_event_message_button"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="Send Event Message"
+          android:onClick="onSendEventStreamMessageButtonClicked"/>
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="8dp"
+        android:orientation="horizontal"
+        android:layout_gravity="center_vertical">
+        <Switch
+            android:id="@+id/fail_switch"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Force Fail" />
+        <Switch
+            android:id="@+id/app_launch_switch"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Trigger app launch"
+            android:paddingLeft="8dp"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/adv_options"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp"
+        android:orientation="horizontal"
+        android:layout_gravity="center_vertical">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="8dp"
+            android:textColor="@android:color/black"
+            android:text="adv options"/>
+
+        <Spinner
+            android:id="@+id/adv_option_spinner"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+    </LinearLayout>
+
+    <TextView
+        android:id="@+id/text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="bottom"
+        android:scrollbars="vertical"/>
+</LinearLayout>
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/layout/user_input_dialog.xml b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/layout/user_input_dialog.xml
new file mode 100644
index 0000000..980b057
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/layout/user_input_dialog.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="16dp">
+
+  <EditText
+      android:id="@+id/userInputDialog"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:hint="@string/firmware_input_hint"
+      android:inputType="text" />
+
+</LinearLayout>
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/menu/menu.xml b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/menu/menu.xml
new file mode 100644
index 0000000..f225522
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/menu/menu.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".MainActivity">
+
+  <item
+      android:id="@+id/sign_out_menu_item"
+      android:title="Sign out"/>
+  <item
+      android:id="@+id/reset_account_keys_menu_item"
+      android:title="Reset Account Keys"/>
+  <item
+      android:id="@+id/reset_device_name_menu_item"
+      android:title="Reset Device Name"/>
+  <item
+    android:id="@+id/set_firmware_version"
+    android:title="Set Firmware Version"/>
+  <item
+      android:id="@+id/set_simulator_capability"
+      android:title="Set Simulator Capability"/>
+  <item
+    android:id="@+id/use_new_gatt_characteristics_id"
+    android:checkable="true"
+    android:checked="false"
+    android:title="Use new GATT characteristics id"/>
+</menu>
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/values/dimens.xml b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/values/dimens.xml
new file mode 100644
index 0000000..47c8224
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/values/dimens.xml
@@ -0,0 +1,5 @@
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/values/strings.xml b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/values/strings.xml
new file mode 100644
index 0000000..5123038
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/res/values/strings.xml
@@ -0,0 +1,31 @@
+<resources>
+    <string name="app_name">Fast Pair Provider Simulator</string>
+    <string-array name="adv_options">
+        <item>0: No battery info</item>
+        <item>1: Show L(⬆) + R(⬆) + C(⬆)</item>
+        <item>2: Show L + R + C(unknown)</item>
+        <item>3: Show L(low 10) + R(low 9) + C(low 25)</item>
+        <item>4: Suppress battery w/o level changes</item>
+        <item>5: Suppress L(low 10) + R(11) + C</item>
+        <item>6: Suppress L(low ⬆) + R(low ⬆) + C(low 10)</item>
+        <item>7: Suppress L(low ⬆) + R(low ⬆) + C(low ⬆)</item>
+        <item>8: Show subsequent pairing notification</item>
+        <item>9: Suppress subsequent pairing notification</item>
+    </string-array>
+    <string-array name="event_stream_options">
+        <item>OHD event</item>
+        <item>Log event</item>
+        <item>Battery event</item>
+    </string-array>
+    <string name="firmware_dialog_title">Firmware version number</string>
+    <string name="firmware_input_hint">Type in version number</string>
+    <string name="passkey_dialog_title">Passkey needed</string>
+    <string name="passkey_input_hint">Type in passkey</string>
+    <!-- Passkey confirmation dialog title. [CHAR_LIMIT=NONE]-->
+    <string name="confirm_passkey">Confirm passkey</string>
+    <string name="model_id_progress_title">Get models from server</string>
+
+    <!-- Fast Pair Simulator: pair one device only. -->
+    <string name="fast_pair_simulator" translatable="false">Fast Pair Simulator</string>
+
+</resources>
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/app/FutureCallbackWrapper.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/app/FutureCallbackWrapper.java
new file mode 100644
index 0000000..4db8560
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/app/FutureCallbackWrapper.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.simulator.app;
+
+import android.util.Log;
+
+import com.google.common.util.concurrent.FutureCallback;
+
+/** Wrapper for {@link FutureCallback} to prevent the memory linkage. */
+public abstract class FutureCallbackWrapper<T> implements FutureCallback<T> {
+    private static final String TAG = FutureCallback.class.getSimpleName();
+
+    public static FutureCallbackWrapper<Void> createRegisterCallback(MainActivity activity) {
+        String id = activity.mRemoteDeviceId;
+        return new FutureCallbackWrapper<Void>() {
+            @Override
+            public void onSuccess(Void result) {
+                Log.d(TAG, String.format("%s was registered", id));
+            }
+
+            @Override
+            public void onFailure(Throwable t) {
+                Log.w(TAG, String.format("Failed to register %s", id), t);
+            }
+        };
+    }
+
+    public static FutureCallbackWrapper<Void> createDefaultIOCallback(MainActivity activity) {
+        String id = activity.mRemoteDeviceId;
+        return new FutureCallbackWrapper<Void>() {
+            @Override
+            public void onSuccess(Void result) {
+            }
+
+            @Override
+            public void onFailure(Throwable t) {
+                Log.w(TAG, String.format("IO stream error on %s", id), t);
+            }
+        };
+    }
+
+    public static FutureCallbackWrapper<Void> createDestroyCallback() {
+        return new FutureCallbackWrapper<Void>() {
+            @Override
+            public void onSuccess(Void result) {
+                Log.d(TAG, "remote devices manager is destroyed");
+            }
+
+            @Override
+            public void onFailure(Throwable t) {
+                Log.w(TAG, "Failed to destroy remote devices manager", t);
+            }
+        };
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/app/MainActivity.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/app/MainActivity.java
new file mode 100644
index 0000000..e916c53
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/app/MainActivity.java
@@ -0,0 +1,1044 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.simulator.app;
+
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.BLUETOOTH_STATE_BOND;
+import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.BLUETOOTH_STATE_CONNECTION;
+import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.BLUETOOTH_STATE_SCAN_MODE;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.io.BaseEncoding.base64;
+
+import android.Manifest.permission;
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.le.AdvertiseSettings;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.nearby.fastpair.provider.EventStreamProtocol.EventGroup;
+import android.nearby.fastpair.provider.FastPairSimulator;
+import android.nearby.fastpair.provider.FastPairSimulator.BatteryValue;
+import android.nearby.fastpair.provider.FastPairSimulator.KeyInputCallback;
+import android.nearby.fastpair.provider.FastPairSimulator.PasskeyEventCallback;
+import android.nearby.fastpair.provider.bluetooth.BluetoothController;
+import android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event;
+import android.nearby.fastpair.provider.simulator.testing.RemoteDevice;
+import android.nearby.fastpair.provider.simulator.testing.RemoteDevicesManager;
+import android.nearby.fastpair.provider.simulator.testing.StreamIOHandlerFactory;
+import android.nearby.fastpair.provider.utils.Logger;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.text.method.ScrollingMovementMethod;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.Switch;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+import androidx.core.util.Consumer;
+
+import com.google.common.base.Ascii;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.protobuf.ByteString;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Executors;
+
+import service.proto.Rpcs.AntiSpoofingKeyPair;
+import service.proto.Rpcs.Device;
+import service.proto.Rpcs.DeviceType;
+
+/**
+ * Simulates a Fast Pair device (e.g. a headset).
+ *
+ * <p>See README in this directory, and {http://go/fast-pair-spec}.
+ */
+@SuppressLint("SetTextI18n")
+public class MainActivity extends Activity {
+    public static final String TAG = "FastPairProviderSimulatorApp";
+    private final Logger mLogger = new Logger(TAG);
+
+    /** Device has a display and the ability to input Yes/No. */
+    private static final int IO_CAPABILITY_IO = 1;
+
+    /** Device only has a keyboard for entry but no display. */
+    private static final int IO_CAPABILITY_IN = 2;
+
+    /** Device has no Input or Output capability. */
+    private static final int IO_CAPABILITY_NONE = 3;
+
+    /** Device has a display and a full keyboard. */
+    private static final int IO_CAPABILITY_KBDISP = 4;
+
+    private static final String SHARED_PREFS_NAME =
+            "android.nearby.fastpair.provider.simulator.app";
+    private static final String EXTRA_MODEL_ID = "MODEL_ID";
+    private static final String EXTRA_BLUETOOTH_ADDRESS = "BLUETOOTH_ADDRESS";
+    private static final String EXTRA_TX_POWER_LEVEL = "TX_POWER_LEVEL";
+    private static final String EXTRA_FIRMWARE_VERSION = "FIRMWARE_VERSION";
+    private static final String EXTRA_SUPPORT_DYNAMIC_SIZE = "SUPPORT_DYNAMIC_SIZE";
+    private static final String EXTRA_USE_RANDOM_SALT_FOR_ACCOUNT_KEY_ROTATION =
+            "USE_RANDOM_SALT_FOR_ACCOUNT_KEY_ROTATION";
+    private static final String EXTRA_REMOTE_DEVICE_ID = "REMOTE_DEVICE_ID";
+    private static final String EXTRA_USE_NEW_GATT_CHARACTERISTICS_ID =
+            "USE_NEW_GATT_CHARACTERISTICS_ID";
+    public static final String EXTRA_REMOVE_ALL_DEVICES_DURING_PAIRING =
+            "REMOVE_ALL_DEVICES_DURING_PAIRING";
+    private static final String KEY_ACCOUNT_NAME = "ACCOUNT_NAME";
+    private static final String[] PERMISSIONS =
+            new String[]{permission.BLUETOOTH, permission.BLUETOOTH_ADMIN, permission.GET_ACCOUNTS};
+    private static final int LIGHT_GREEN = 0xFFC8FFC8;
+    private static final String ANTI_SPOOFING_KEY_LABEL = "Anti-spoofing key";
+
+    private static final ImmutableMap<String, String> ANTI_SPOOFING_PRIVATE_KEY_MAP =
+            new ImmutableMap.Builder<String, String>()
+                    .put("361A2E", "/1rMqyJRGeOK6vkTNgM70xrytxdKg14mNQkITeusK20=")
+                    .put("00000D", "03/MAmUPTGNsN+2iA/1xASXoPplDh3Ha5/lk2JgEBx4=")
+                    .put("00000C", "Cbj9eCJrTdDgSYxLkqtfADQi86vIaMvxJsQ298sZYWE=")
+                    // BLE only devices
+                    .put("49426D", "I5QFOJW0WWFgKKZiwGchuseXsq/p9RN/aYtNsGEVGT0=")
+                    .put("01E5CE", "FbHt8STpHJDd4zFQFjimh4Zt7IU94U28MOEIXgUEeCw=")
+                    .put("8D13B9", "mv++LcJB1n0mbLNGWlXCv/8Gb6aldctrJC4/Ma/Q3Rg=")
+                    .put("9AB0F6", "9eKQNwJUr5vCg0c8rtOXkJcWTAsBmmvEKSgXIqAd50Q=")
+                    // Android Auto
+                    .put("8E083D", "hGQeREDKM/H1834zWMmTIe0Ap4Zl5igThgE62OtdcKA=")
+                    .buildOrThrow();
+
+    private static final Uri REMOTE_DEVICE_INPUT_STREAM_URI =
+            Uri.fromFile(new File("/data/local/nearby/tmp/read.pipe"));
+
+    private static final Uri REMOTE_DEVICE_OUTPUT_STREAM_URI =
+            Uri.fromFile(new File("/data/local/nearby/tmp/write.pipe"));
+
+    private static final String MODEL_ID_DEFAULT = "00000C";
+
+    private static final String MODEL_ID_APP_LAUNCH = "60EB56";
+
+    private static final int MODEL_ID_LENGTH = 6;
+
+    private BluetoothController mBluetoothController;
+    private final BluetoothController.EventListener mEventListener =
+            new BluetoothController.EventListener() {
+
+                @Override
+                public void onBondStateChanged(int bondState) {
+                    sendEventToRemoteDevice(
+                            Event.newBuilder().setCode(BLUETOOTH_STATE_BOND).setBondState(
+                                    bondState));
+                    updateStatusView();
+                }
+
+                @Override
+                public void onConnectionStateChanged(int connectionState) {
+                    sendEventToRemoteDevice(
+                            Event.newBuilder()
+                                    .setCode(BLUETOOTH_STATE_CONNECTION)
+                                    .setConnectionState(connectionState));
+                    updateStatusView();
+                }
+
+                @Override
+                public void onScanModeChange(int mode) {
+                    sendEventToRemoteDevice(
+                            Event.newBuilder().setCode(BLUETOOTH_STATE_SCAN_MODE).setScanMode(
+                                    mode));
+                    updateStatusView();
+                }
+
+                @Override
+                public void onA2DPSinkProfileConnected() {
+                    reset();
+                }
+            };
+
+    @Nullable
+    private FastPairSimulator mFastPairSimulator;
+    @Nullable
+    private AlertDialog mInputPasskeyDialog;
+    private Switch mFailSwitch;
+    private Switch mAppLaunchSwitch;
+    private Spinner mAdvOptionSpinner;
+    private Spinner mEventStreamSpinner;
+    private EventGroup mEventGroup;
+    private SharedPreferences mSharedPreferences;
+    private Spinner mModelIdSpinner;
+    private final RemoteDevicesManager mRemoteDevicesManager = new RemoteDevicesManager();
+    @Nullable
+    private RemoteDeviceListener mInputStreamListener;
+    @Nullable
+    String mRemoteDeviceId;
+    private final Map<String, Device> mModelsMap = new LinkedHashMap<>();
+    private boolean mRemoveAllDevicesDuringPairing = true;
+
+    void sendEventToRemoteDevice(Event.Builder eventBuilder) {
+        if (mRemoteDeviceId == null) {
+            return;
+        }
+
+        mLogger.log("Send data to output stream: %s", eventBuilder.getCode().getNumber());
+        mRemoteDevicesManager.writeDataToRemoteDevice(
+                mRemoteDeviceId,
+                eventBuilder.build().toByteString(),
+                FutureCallbackWrapper.createDefaultIOCallback(this));
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.activity_main);
+
+        mSharedPreferences = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE);
+
+        mRemoveAllDevicesDuringPairing =
+                getIntent().getBooleanExtra(EXTRA_REMOVE_ALL_DEVICES_DURING_PAIRING, true);
+
+        mFailSwitch = findViewById(R.id.fail_switch);
+        mFailSwitch.setOnCheckedChangeListener((CompoundButton buttonView, boolean isChecked) -> {
+            if (mFastPairSimulator != null) {
+                mFastPairSimulator.setShouldFailPairing(isChecked);
+            }
+        });
+
+        mAppLaunchSwitch = findViewById(R.id.app_launch_switch);
+        mAppLaunchSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> reset());
+
+        mAdvOptionSpinner = findViewById(R.id.adv_option_spinner);
+        mEventStreamSpinner = findViewById(R.id.event_stream_spinner);
+        ArrayAdapter<CharSequence> advOptionAdapter =
+                ArrayAdapter.createFromResource(
+                        this, R.array.adv_options, android.R.layout.simple_spinner_item);
+        ArrayAdapter<CharSequence> eventStreamAdapter =
+                ArrayAdapter.createFromResource(
+                        this, R.array.event_stream_options, android.R.layout.simple_spinner_item);
+        advOptionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mAdvOptionSpinner.setAdapter(advOptionAdapter);
+        mEventStreamSpinner.setAdapter(eventStreamAdapter);
+        mAdvOptionSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> adapterView, View view, int position,
+                    long id) {
+                startAdvertisingBatteryInformationBasedOnOption(position);
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> adapterView) {
+            }
+        });
+        mEventStreamSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position,
+                    long id) {
+                switch (EventGroup.forNumber(position + 1)) {
+                    case BLUETOOTH:
+                        mEventGroup = EventGroup.BLUETOOTH;
+                        break;
+                    case LOGGING:
+                        mEventGroup = EventGroup.LOGGING;
+                        break;
+                    case DEVICE:
+                        mEventGroup = EventGroup.DEVICE;
+                        break;
+                    default:
+                        // fall through
+                }
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+            }
+        });
+        setupModelIdSpinner();
+        setupRemoteDevices();
+        if (checkPermissions(PERMISSIONS)) {
+            mBluetoothController = new BluetoothController(this, mEventListener);
+            mBluetoothController.registerBluetoothStateReceiver();
+            mBluetoothController.enableBluetooth();
+            mBluetoothController.connectA2DPSinkProfile();
+
+            if (mSharedPreferences.getString(KEY_ACCOUNT_NAME, "").isEmpty()) {
+                putFixedModelLocal();
+                resetModelIdSpinner();
+                reset();
+            }
+        } else {
+            requestPermissions(PERMISSIONS, 0 /* requestCode */);
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.menu, menu);
+        menu.findItem(R.id.use_new_gatt_characteristics_id).setChecked(
+                getFromIntentOrPrefs(
+                        EXTRA_USE_NEW_GATT_CHARACTERISTICS_ID, /* defaultValue= */ false));
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (item.getItemId() == R.id.sign_out_menu_item) {
+            recreate();
+            return true;
+        } else if (item.getItemId() == R.id.reset_account_keys_menu_item) {
+            resetAccountKeys();
+            return true;
+        } else if (item.getItemId() == R.id.reset_device_name_menu_item) {
+            resetDeviceName();
+            return true;
+        } else if (item.getItemId() == R.id.set_firmware_version) {
+            setFirmware();
+            return true;
+        } else if (item.getItemId() == R.id.set_simulator_capability) {
+            setSimulatorCapability();
+            return true;
+        } else if (item.getItemId() == R.id.use_new_gatt_characteristics_id) {
+            if (!item.isChecked()) {
+                item.setChecked(true);
+                mSharedPreferences.edit()
+                        .putBoolean(EXTRA_USE_NEW_GATT_CHARACTERISTICS_ID, true).apply();
+            } else {
+                item.setChecked(false);
+                mSharedPreferences.edit()
+                        .putBoolean(EXTRA_USE_NEW_GATT_CHARACTERISTICS_ID, false).apply();
+            }
+            reset();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void setFirmware() {
+        View firmwareInputView =
+                LayoutInflater.from(getApplicationContext()).inflate(R.layout.user_input_dialog,
+                        null);
+        EditText userInputDialogEditText = firmwareInputView.findViewById(R.id.userInputDialog);
+        new AlertDialog.Builder(MainActivity.this)
+                .setView(firmwareInputView)
+                .setCancelable(false)
+                .setPositiveButton(android.R.string.ok, (dialogBox, id) -> {
+                    String input = userInputDialogEditText.getText().toString();
+                    mSharedPreferences.edit().putString(EXTRA_FIRMWARE_VERSION,
+                            input).apply();
+                    reset();
+                })
+                .setNegativeButton(android.R.string.cancel, null)
+                .setTitle(R.string.firmware_dialog_title)
+                .show();
+    }
+
+    private void setSimulatorCapability() {
+        String[] capabilityKeys = new String[]{EXTRA_SUPPORT_DYNAMIC_SIZE};
+        String[] capabilityNames = new String[]{"Dynamic Buffer Size"};
+        // Default values.
+        boolean[] capabilitySelected = new boolean[]{false};
+        // Get from preferences if exist.
+        for (int i = 0; i < capabilityKeys.length; i++) {
+            capabilitySelected[i] =
+                    mSharedPreferences.getBoolean(capabilityKeys[i], capabilitySelected[i]);
+        }
+
+        new AlertDialog.Builder(MainActivity.this)
+                .setMultiChoiceItems(
+                        capabilityNames,
+                        capabilitySelected,
+                        (dialog, which, isChecked) -> capabilitySelected[which] = isChecked)
+                .setCancelable(false)
+                .setPositiveButton(
+                        android.R.string.ok,
+                        (dialogBox, id) -> {
+                            for (int i = 0; i < capabilityKeys.length; i++) {
+                                mSharedPreferences
+                                        .edit()
+                                        .putBoolean(capabilityKeys[i], capabilitySelected[i])
+                                        .apply();
+                            }
+                            setCapabilityToSimulator();
+                        })
+                .setNegativeButton(android.R.string.cancel, null)
+                .setTitle("Simulator Capability")
+                .show();
+    }
+
+    private void setCapabilityToSimulator() {
+        if (mFastPairSimulator != null) {
+            mFastPairSimulator.setDynamicBufferSize(
+                    getFromIntentOrPrefs(EXTRA_SUPPORT_DYNAMIC_SIZE, false));
+        }
+    }
+
+    private static String getModelIdString(long id) {
+        String result = Ascii.toUpperCase(Long.toHexString(id));
+        while (result.length() < MODEL_ID_LENGTH) {
+            result = "0" + result;
+        }
+        return result;
+    }
+
+    private void putFixedModelLocal() {
+        mModelsMap.put(
+                "00000C",
+                Device.newBuilder()
+                        .setId(12)
+                        .setAntiSpoofingKeyPair(AntiSpoofingKeyPair.newBuilder().build())
+                        .setDeviceType(DeviceType.HEADPHONES)
+                        .build());
+    }
+
+    private void setupModelIdSpinner() {
+        mModelIdSpinner = findViewById(R.id.model_id_spinner);
+
+        ArrayAdapter<String> modelIdAdapter =
+                new ArrayAdapter<>(this, android.R.layout.simple_spinner_item);
+        modelIdAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mModelIdSpinner.setAdapter(modelIdAdapter);
+        resetModelIdSpinner();
+        mModelIdSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position,
+                    long id) {
+                setModelId(mModelsMap.keySet().toArray(new String[0])[position]);
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> adapterView) {
+            }
+        });
+    }
+
+    private void setupRemoteDevices() {
+        if (Strings.isNullOrEmpty(getIntent().getStringExtra(EXTRA_REMOTE_DEVICE_ID))) {
+            mLogger.log("Can't get remote device id");
+            return;
+        }
+        mRemoteDeviceId = getIntent().getStringExtra(EXTRA_REMOTE_DEVICE_ID);
+        mInputStreamListener = new RemoteDeviceListener(this);
+
+        try {
+            mRemoteDevicesManager.registerRemoteDevice(
+                    mRemoteDeviceId,
+                    new RemoteDevice(
+                            mRemoteDeviceId,
+                            StreamIOHandlerFactory.createStreamIOHandler(
+                                    StreamIOHandlerFactory.Type.LOCAL_FILE,
+                                    REMOTE_DEVICE_INPUT_STREAM_URI,
+                                    REMOTE_DEVICE_OUTPUT_STREAM_URI),
+                            mInputStreamListener));
+        } catch (IOException e) {
+            mLogger.log(e, "Failed to create stream IO handler");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    @UiThread
+    private void resetModelIdSpinner() {
+        ArrayAdapter adapter = (ArrayAdapter) mModelIdSpinner.getAdapter();
+        if (adapter == null) {
+            return;
+        }
+
+        adapter.clear();
+        if (!mModelsMap.isEmpty()) {
+            for (String modelId : mModelsMap.keySet()) {
+                adapter.add(modelId + "-" + mModelsMap.get(modelId).getName());
+            }
+            mModelIdSpinner.setEnabled(true);
+            int newPos = getPositionFromModelId(getModelId());
+            if (newPos < 0) {
+                String newModelId = mModelsMap.keySet().iterator().next();
+                Toast.makeText(this,
+                        "Can't find Model ID " + getModelId() + " from console, reset it to "
+                                + newModelId, Toast.LENGTH_SHORT).show();
+                setModelId(newModelId);
+                newPos = 0;
+            }
+            mModelIdSpinner.setSelection(newPos, /* animate= */ false);
+        } else {
+            mModelIdSpinner.setEnabled(false);
+        }
+    }
+
+    private String getModelId() {
+        return getFromIntentOrPrefs(EXTRA_MODEL_ID, MODEL_ID_DEFAULT).toUpperCase(Locale.US);
+    }
+
+    private boolean setModelId(String modelId) {
+        String validModelId = getValidModelId(modelId);
+        if (TextUtils.isEmpty(validModelId)) {
+            mLogger.log("Can't do setModelId because inputted modelId is invalid!");
+            return false;
+        }
+
+        if (getModelId().equals(validModelId)) {
+            return false;
+        }
+        mSharedPreferences.edit().putString(EXTRA_MODEL_ID, validModelId).apply();
+        reset();
+        return true;
+    }
+
+    @Nullable
+    private static String getValidModelId(String modelId) {
+        if (TextUtils.isEmpty(modelId) || modelId.length() < MODEL_ID_LENGTH) {
+            return null;
+        }
+
+        return modelId.substring(0, MODEL_ID_LENGTH).toUpperCase(Locale.US);
+    }
+
+    private int getPositionFromModelId(String modelId) {
+        int i = 0;
+        for (String id : mModelsMap.keySet()) {
+            if (id.equals(modelId)) {
+                return i;
+            }
+            i++;
+        }
+        return -1;
+    }
+
+    private void resetAccountKeys() {
+        if (mFastPairSimulator != null) {
+            mFastPairSimulator.resetAccountKeys();
+            mFastPairSimulator.startAdvertising();
+        }
+    }
+
+    private void resetDeviceName() {
+        if (mFastPairSimulator != null) {
+            mFastPairSimulator.resetDeviceName();
+        }
+    }
+
+    /** Called via activity_main.xml */
+    public void onResetButtonClicked(View view) {
+        reset();
+    }
+
+    /** Called via activity_main.xml */
+    public void onSendEventStreamMessageButtonClicked(View view) {
+        if (mFastPairSimulator != null) {
+            mFastPairSimulator.sendEventStreamMessageToRfcommDevices(mEventGroup);
+        }
+    }
+
+    void reset() {
+        Button resetButton = findViewById(R.id.reset_button);
+        if (mModelsMap.isEmpty() || !resetButton.isEnabled()) {
+            return;
+        }
+        resetButton.setText("Resetting...");
+        resetButton.setEnabled(false);
+        mModelIdSpinner.setEnabled(false);
+        mAppLaunchSwitch.setEnabled(false);
+
+        if (mFastPairSimulator != null) {
+            mFastPairSimulator.stopAdvertising();
+
+            if (mBluetoothController.getRemoteDevice() != null) {
+                if (mRemoveAllDevicesDuringPairing) {
+                    mFastPairSimulator.removeBond(mBluetoothController.getRemoteDevice());
+                }
+                mBluetoothController.clearRemoteDevice();
+            }
+            // To be safe, also unpair from all phones (this covers the case where you kill +
+            // relaunch the
+            // simulator while paired).
+            if (mRemoveAllDevicesDuringPairing) {
+                mFastPairSimulator.disconnectAllBondedDevices();
+            }
+            // Sometimes a device will still be connected even though it's not bonded. :( Clear
+            // that too.
+            BluetoothProfile profileProxy = mBluetoothController.getA2DPSinkProfileProxy();
+            for (BluetoothDevice device : profileProxy.getConnectedDevices()) {
+                mFastPairSimulator.disconnect(profileProxy, device);
+            }
+        }
+        updateStatusView();
+
+        if (mFastPairSimulator != null) {
+            mFastPairSimulator.destroy();
+        }
+        TextView textView = (TextView) findViewById(R.id.text_view);
+        textView.setText("");
+        textView.setMovementMethod(new ScrollingMovementMethod());
+
+        String modelId = getModelId();
+
+        String txPower = getFromIntentOrPrefs(EXTRA_TX_POWER_LEVEL, "HIGH");
+        updateStringStatusView(R.id.tx_power_text_view, "TxPower", txPower);
+
+        String bluetoothAddress = getFromIntentOrPrefs(EXTRA_BLUETOOTH_ADDRESS, "");
+
+        String firmwareVersion = getFromIntentOrPrefs(EXTRA_FIRMWARE_VERSION, "1.1");
+        try {
+            Preconditions.checkArgument(base16().decode(bluetoothAddress).length == 6);
+        } catch (IllegalArgumentException e) {
+            mLogger.log("Invalid BLUETOOTH_ADDRESS extra (%s), using default.", bluetoothAddress);
+            bluetoothAddress = null;
+        }
+        final String finalBluetoothAddress = bluetoothAddress;
+
+        updateStringStatusView(
+                R.id.anti_spoofing_private_key_text_view, ANTI_SPOOFING_KEY_LABEL, "Loading...");
+
+        boolean useRandomSaltForAccountKeyRotation =
+                getFromIntentOrPrefs(EXTRA_USE_RANDOM_SALT_FOR_ACCOUNT_KEY_ROTATION, false);
+
+        Executors.newSingleThreadExecutor().execute(() -> {
+            // Fetch the anti-spoofing key corresponding to this model ID (if it
+            // exists).
+            // The account must have Project Viewer permission for the project
+            // that owns
+            // the model ID (normally discoverer-test or discoverer-devices).
+            byte[] antiSpoofingKey = getAntiSpoofingKey(modelId);
+            String antiSpoofingKeyString;
+            Device device = mModelsMap.get(modelId);
+            if (antiSpoofingKey != null) {
+                antiSpoofingKeyString = base64().encode(antiSpoofingKey);
+            } else {
+                if (mSharedPreferences.getString(KEY_ACCOUNT_NAME, "").isEmpty()) {
+                    antiSpoofingKeyString = "Can't fetch, no account";
+                } else {
+                    if (device == null) {
+                        antiSpoofingKeyString = String.format(Locale.US,
+                                "Can't find model %s from console", modelId);
+                    } else if (!device.hasAntiSpoofingKeyPair()) {
+                        antiSpoofingKeyString = String.format(Locale.US,
+                                "Can't find AntiSpoofingKeyPair for model %s", modelId);
+                    } else if (device.getAntiSpoofingKeyPair().getPrivateKey().isEmpty()) {
+                        antiSpoofingKeyString = String.format(Locale.US,
+                                "Can't find privateKey for model %s", modelId);
+                    } else {
+                        antiSpoofingKeyString = "Unknown error";
+                    }
+                }
+            }
+
+            int desiredIoCapability = getIoCapabilityFromModelId(modelId);
+
+            mBluetoothController.setIoCapability(
+                    /*ioCapabilityClassic=*/ desiredIoCapability,
+                    /*ioCapabilityBLE=*/ desiredIoCapability);
+
+            runOnUiThread(() -> {
+                updateStringStatusView(
+                        R.id.anti_spoofing_private_key_text_view,
+                        ANTI_SPOOFING_KEY_LABEL,
+                        antiSpoofingKeyString);
+                FastPairSimulator.Options option = FastPairSimulator.Options.builder(modelId)
+                        .setAdvertisingModelId(
+                                mAppLaunchSwitch.isChecked() ? MODEL_ID_APP_LAUNCH : modelId)
+                        .setBluetoothAddress(finalBluetoothAddress)
+                        .setTxPowerLevel(toTxPowerLevel(txPower))
+                        .setAdvertisingChangedCallback(isAdvertising -> updateStatusView())
+                        .setAntiSpoofingPrivateKey(antiSpoofingKey)
+                        .setUseRandomSaltForAccountKeyRotation(useRandomSaltForAccountKeyRotation)
+                        .setDataOnlyConnection(device != null && device.getDataOnlyConnection())
+                        .setShowsPasskeyConfirmation(
+                                device.getDeviceType().equals(DeviceType.ANDROID_AUTO))
+                        .setRemoveAllDevicesDuringPairing(mRemoveAllDevicesDuringPairing)
+                        .build();
+                Logger textViewLogger = new Logger(FastPairSimulator.TAG) {
+
+                    @FormatMethod
+                    public void log(@Nullable Throwable exception, String message,
+                            Object... objects) {
+                        super.log(exception, message, objects);
+
+                        String exceptionMessage = (exception == null) ? ""
+                                : " - " + exception.getMessage();
+                        final String finalMessage =
+                                String.format(message, objects) + exceptionMessage;
+
+                        textView.post(() -> {
+                            String newText =
+                                    textView.getText() + "\n\n" + finalMessage;
+                            textView.setText(newText);
+                        });
+                    }
+                };
+                mFastPairSimulator =
+                        new FastPairSimulator(this, option, textViewLogger);
+                mFastPairSimulator.setFirmwareVersion(firmwareVersion);
+                mFailSwitch.setChecked(
+                        mFastPairSimulator.getShouldFailPairing());
+                mAdvOptionSpinner.setSelection(0);
+                setCapabilityToSimulator();
+
+                updateStringStatusView(R.id.bluetooth_address_text_view,
+                        "Bluetooth address",
+                        mFastPairSimulator.getBluetoothAddress());
+
+                updateStringStatusView(R.id.device_name_text_view,
+                        "Device name",
+                        mFastPairSimulator.getDeviceName());
+
+                resetButton.setText("Reset");
+                resetButton.setEnabled(true);
+                mModelIdSpinner.setEnabled(true);
+                mAppLaunchSwitch.setEnabled(true);
+                mFastPairSimulator.setDeviceNameCallback(deviceName ->
+                        updateStringStatusView(
+                                R.id.device_name_text_view,
+                                "Device name", deviceName));
+
+                if (desiredIoCapability == IO_CAPABILITY_IN
+                        || device.getDeviceType().equals(DeviceType.ANDROID_AUTO)) {
+                    mFastPairSimulator.setPasskeyEventCallback(mPasskeyEventCallback);
+                }
+                if (mInputStreamListener != null) {
+                    mInputStreamListener.setFastPairSimulator(mFastPairSimulator);
+                }
+            });
+        });
+    }
+
+    private int getIoCapabilityFromModelId(String modelId) {
+        Device device = mModelsMap.get(modelId);
+        if (device == null) {
+            return IO_CAPABILITY_NONE;
+        } else {
+            if (getAntiSpoofingKey(modelId) == null) {
+                return IO_CAPABILITY_NONE;
+            } else {
+                switch (device.getDeviceType()) {
+                    case INPUT_DEVICE:
+                        return IO_CAPABILITY_IN;
+
+                    case DEVICE_TYPE_UNSPECIFIED:
+                        return IO_CAPABILITY_NONE;
+
+                    // Treats wearable to IO_CAPABILITY_KBDISP for simulator because there seems
+                    // no suitable
+                    // type.
+                    case WEARABLE:
+                        return IO_CAPABILITY_KBDISP;
+
+                    default:
+                        return IO_CAPABILITY_IO;
+                }
+            }
+        }
+    }
+
+    @Nullable
+    ByteString getAccontKey() {
+        if (mFastPairSimulator == null) {
+            return null;
+        }
+        return mFastPairSimulator.getAccountKey();
+    }
+
+    @Nullable
+    private byte[] getAntiSpoofingKey(String modelId) {
+        Device device = mModelsMap.get(modelId);
+        if (device != null
+                && device.hasAntiSpoofingKeyPair()
+                && !device.getAntiSpoofingKeyPair().getPrivateKey().isEmpty()) {
+            return base64().decode(device.getAntiSpoofingKeyPair().getPrivateKey().toStringUtf8());
+        } else if (ANTI_SPOOFING_PRIVATE_KEY_MAP.containsKey(modelId)) {
+            return base64().decode(ANTI_SPOOFING_PRIVATE_KEY_MAP.get(modelId));
+        } else {
+            return null;
+        }
+    }
+
+    private final PasskeyEventCallback mPasskeyEventCallback = new PasskeyEventCallback() {
+        @Override
+        public void onPasskeyRequested(KeyInputCallback keyInputCallback) {
+            showInputPasskeyDialog(keyInputCallback);
+        }
+
+        @Override
+        public void onPasskeyConfirmation(int passkey, Consumer<Boolean> isConfirmed) {
+            showConfirmPasskeyDialog(passkey, isConfirmed);
+        }
+
+        @Override
+        public void onRemotePasskeyReceived(int passkey) {
+            if (mInputPasskeyDialog == null) {
+                return;
+            }
+
+            EditText userInputDialogEditText = mInputPasskeyDialog.findViewById(
+                    R.id.userInputDialog);
+            if (userInputDialogEditText == null) {
+                return;
+            }
+
+            userInputDialogEditText.setText(String.format("%d", passkey));
+        }
+    };
+
+    private void showInputPasskeyDialog(KeyInputCallback keyInputCallback) {
+        if (mInputPasskeyDialog == null) {
+            View userInputView =
+                    LayoutInflater.from(getApplicationContext()).inflate(R.layout.user_input_dialog,
+                            null);
+            EditText userInputDialogEditText = userInputView.findViewById(R.id.userInputDialog);
+            userInputDialogEditText.setHint(R.string.passkey_input_hint);
+            userInputDialogEditText.setInputType(InputType.TYPE_CLASS_NUMBER);
+            mInputPasskeyDialog = new AlertDialog.Builder(MainActivity.this)
+                    .setView(userInputView)
+                    .setCancelable(false)
+                    .setPositiveButton(
+                            android.R.string.ok,
+                            (DialogInterface dialogBox, int id) -> {
+                                String input = userInputDialogEditText.getText().toString();
+                                keyInputCallback.onKeyInput(Integer.parseInt(input));
+                            })
+                    .setNegativeButton(android.R.string.cancel, /* listener= */ null)
+                    .setTitle(R.string.passkey_dialog_title)
+                    .create();
+        }
+        if (!mInputPasskeyDialog.isShowing()) {
+            mInputPasskeyDialog.show();
+        }
+    }
+
+    private void showConfirmPasskeyDialog(int passkey, Consumer<Boolean> isConfirmed) {
+        runOnUiThread(() -> new AlertDialog.Builder(MainActivity.this)
+                .setCancelable(false)
+                .setTitle(R.string.confirm_passkey)
+                .setMessage(String.valueOf(passkey))
+                .setPositiveButton(android.R.string.ok,
+                        (d, w) -> isConfirmed.accept(true))
+                .setNegativeButton(android.R.string.cancel,
+                        (d, w) -> isConfirmed.accept(false))
+                .create()
+                .show());
+    }
+
+    @UiThread
+    private void updateStringStatusView(int id, String name, String value) {
+        ((TextView) findViewById(id)).setText(name + ": " + value);
+    }
+
+    @UiThread
+    private void updateStatusView() {
+        TextView remoteDeviceTextView = (TextView) findViewById(R.id.remote_device_text_view);
+        remoteDeviceTextView.setBackgroundColor(
+                mBluetoothController.getRemoteDevice() != null ? LIGHT_GREEN : Color.LTGRAY);
+        String remoteDeviceString = mBluetoothController.getRemoteDeviceAsString();
+        remoteDeviceTextView.setText("Remote device: " + remoteDeviceString);
+
+        updateBooleanStatusView(
+                R.id.is_advertising_text_view,
+                "BLE advertising",
+                mFastPairSimulator != null && mFastPairSimulator.isAdvertising());
+
+        updateStringStatusView(
+                R.id.scan_mode_text_view,
+                "Mode",
+                FastPairSimulator.scanModeToString(mBluetoothController.getScanMode()));
+
+        boolean isPaired = mBluetoothController.isPaired();
+        updateBooleanStatusView(R.id.is_paired_text_view, "Paired", isPaired);
+
+        updateBooleanStatusView(
+                R.id.is_connected_text_view, "Connected", mBluetoothController.isConnected());
+    }
+
+    @UiThread
+    private void updateBooleanStatusView(int id, String name, boolean value) {
+        TextView view = (TextView) findViewById(id);
+        view.setBackgroundColor(value ? LIGHT_GREEN : Color.LTGRAY);
+        view.setText(name + ": " + (value ? "Yes" : "No"));
+    }
+
+    private String getFromIntentOrPrefs(String key, String defaultValue) {
+        Bundle extras = getIntent().getExtras();
+        extras = extras != null ? extras : new Bundle();
+        SharedPreferences prefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE);
+        String value = extras.getString(key, prefs.getString(key, defaultValue));
+        if (value == null) {
+            prefs.edit().remove(key).apply();
+        } else {
+            prefs.edit().putString(key, value).apply();
+        }
+        return value;
+    }
+
+    private boolean getFromIntentOrPrefs(String key, boolean defaultValue) {
+        Bundle extras = getIntent().getExtras();
+        extras = extras != null ? extras : new Bundle();
+        SharedPreferences prefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE);
+        boolean value = extras.getBoolean(key, prefs.getBoolean(key, defaultValue));
+        prefs.edit().putBoolean(key, value).apply();
+        return value;
+    }
+
+    private static int toTxPowerLevel(String txPowerLevelString) {
+        switch (txPowerLevelString.toUpperCase()) {
+            case "3":
+            case "HIGH":
+                return AdvertiseSettings.ADVERTISE_TX_POWER_HIGH;
+            case "2":
+            case "MEDIUM":
+                return AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM;
+            case "1":
+            case "LOW":
+                return AdvertiseSettings.ADVERTISE_TX_POWER_LOW;
+            case "0":
+            case "ULTRA_LOW":
+                return AdvertiseSettings.ADVERTISE_TX_POWER_ULTRA_LOW;
+            default:
+                throw new IllegalArgumentException(
+                        "Unexpected TxPower="
+                                + txPowerLevelString
+                                + ", please provide HIGH, MEDIUM, LOW, or ULTRA_LOW.");
+        }
+    }
+
+    private boolean checkPermissions(String[] permissions) {
+        for (String permission : permissions) {
+            if (checkSelfPermission(permission) != PERMISSION_GRANTED) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    protected void onDestroy() {
+        mRemoteDevicesManager.destroy();
+
+        if (mFastPairSimulator != null) {
+            mFastPairSimulator.destroy();
+            mBluetoothController.unregisterBluetoothStateReceiver();
+        }
+
+        // Recover the IO capability.
+        mBluetoothController.setIoCapability(
+                /*ioCapabilityClassic=*/ IO_CAPABILITY_IO, /*ioCapabilityBLE=*/
+                IO_CAPABILITY_KBDISP);
+
+        super.onDestroy();
+    }
+
+    @Override
+    public void onRequestPermissionsResult(
+            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+        // Relaunch this activity.
+        recreate();
+    }
+
+    void startAdvertisingBatteryInformationBasedOnOption(int option) {
+        if (mFastPairSimulator == null) {
+            return;
+        }
+
+        // Option 0 is "No battery info", it means simulator will not pack battery information when
+        // advertising. For the others with battery info, since we are simulating the Presto's
+        // behavior,
+        // there will always be three battery values.
+        switch (option) {
+            case 0:
+                // Option "0: No battery info"
+                mFastPairSimulator.clearBatteryValues();
+                break;
+            case 1:
+                // Option "1: Show L(⬆) + R(⬆) + C(⬆)"
+                mFastPairSimulator.setSuppressBatteryNotification(false);
+                mFastPairSimulator.setBatteryValues(new BatteryValue(true, 60),
+                        new BatteryValue(true, 61),
+                        new BatteryValue(true, 62));
+                break;
+            case 2:
+                // Option "2: Show L + R + C(unknown)"
+                mFastPairSimulator.setSuppressBatteryNotification(false);
+                mFastPairSimulator.setBatteryValues(new BatteryValue(false, 70),
+                        new BatteryValue(false, 71),
+                        new BatteryValue(false, -1));
+                break;
+            case 3:
+                // Option "3: Show L(low 10) + R(low 9) + C(low 25)"
+                mFastPairSimulator.setSuppressBatteryNotification(false);
+                mFastPairSimulator.setBatteryValues(new BatteryValue(false, 10),
+                        new BatteryValue(false, 9),
+                        new BatteryValue(false, 25));
+                break;
+            case 4:
+                // Option "4: Suppress battery w/o level changes"
+                // Just change the suppress bit and keep the battery values the same as before.
+                mFastPairSimulator.setSuppressBatteryNotification(true);
+                break;
+            case 5:
+                // Option "5: Suppress L(low 10) + R(11) + C"
+                mFastPairSimulator.setSuppressBatteryNotification(true);
+                mFastPairSimulator.setBatteryValues(new BatteryValue(false, 10),
+                        new BatteryValue(false, 11),
+                        new BatteryValue(false, 82));
+                break;
+            case 6:
+                // Option "6: Suppress L(low ⬆) + R(low ⬆) + C(low 10)"
+                mFastPairSimulator.setSuppressBatteryNotification(true);
+                mFastPairSimulator.setBatteryValues(new BatteryValue(true, 10),
+                        new BatteryValue(true, 9),
+                        new BatteryValue(false, 10));
+                break;
+            case 7:
+                // Option "7: Suppress L(low ⬆) + R(low ⬆) + C(low ⬆)"
+                mFastPairSimulator.setSuppressBatteryNotification(true);
+                mFastPairSimulator.setBatteryValues(new BatteryValue(true, 10),
+                        new BatteryValue(true, 9),
+                        new BatteryValue(true, 25));
+                break;
+            case 8:
+                // Option "8: Show subsequent pairing notification"
+                mFastPairSimulator.setSuppressSubsequentPairingNotification(false);
+                break;
+            case 9:
+                // Option "9: Suppress subsequent pairing notification"
+                mFastPairSimulator.setSuppressSubsequentPairingNotification(true);
+                break;
+            default:
+                // Unknown option, do nothing.
+                return;
+        }
+
+        mFastPairSimulator.startAdvertising();
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/app/RemoteDeviceListener.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/app/RemoteDeviceListener.java
new file mode 100644
index 0000000..fac8cb5
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/app/RemoteDeviceListener.java
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.simulator.app;
+
+import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.ACCOUNT_KEY;
+import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.ACKNOWLEDGE;
+import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.BLUETOOTH_ADDRESS_BLE;
+import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.BLUETOOTH_ADDRESS_PUBLIC;
+
+import android.nearby.fastpair.provider.FastPairSimulator;
+import android.nearby.fastpair.provider.FastPairSimulator.BatteryValue;
+import android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Command;
+import android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Command.BatteryInfo;
+import android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event;
+import android.nearby.fastpair.provider.simulator.testing.InputStreamListener;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+
+/** Listener for input stream of the remote device. */
+public class RemoteDeviceListener implements InputStreamListener {
+    private static final String TAG = RemoteDeviceListener.class.getSimpleName();
+
+    private final MainActivity mMainActivity;
+    @Nullable
+    private FastPairSimulator mFastPairSimulator;
+
+    public RemoteDeviceListener(MainActivity mainActivity) {
+        this.mMainActivity = mainActivity;
+    }
+
+    @Override
+    public void onInputData(ByteString byteString) {
+        Command command;
+        try {
+            command = Command.parseFrom(byteString);
+        } catch (InvalidProtocolBufferException e) {
+            Log.w(TAG, String.format("%s input data is not a Command",
+                    mMainActivity.mRemoteDeviceId), e);
+            return;
+        }
+
+        mMainActivity.runOnUiThread(() -> {
+            Log.d(TAG, String.format("%s new command %s",
+                    mMainActivity.mRemoteDeviceId, command.getCode()));
+            switch (command.getCode()) {
+                case POLLING:
+                    mMainActivity.sendEventToRemoteDevice(
+                            Event.newBuilder().setCode(ACKNOWLEDGE));
+                    break;
+                case RESET:
+                    mMainActivity.reset();
+                    break;
+                case SHOW_BATTERY:
+                    onShowBattery(command.getBatteryInfo());
+                    break;
+                case HIDE_BATTERY:
+                    onHideBattery();
+                    break;
+                case REQUEST_BLUETOOTH_ADDRESS_BLE:
+                    onRequestBleAddress();
+                    break;
+                case REQUEST_BLUETOOTH_ADDRESS_PUBLIC:
+                    onRequestPublicAddress();
+                    break;
+                case REQUEST_ACCOUNT_KEY:
+                    ByteString accountKey = mMainActivity.getAccontKey();
+                    if (accountKey == null) {
+                        break;
+                    }
+                    mMainActivity.sendEventToRemoteDevice(
+                            Event.newBuilder().setCode(ACCOUNT_KEY)
+                                    .setAccountKey(accountKey));
+                    break;
+            }
+        });
+    }
+
+    @Override
+    public void onClose() {
+        Log.d(TAG, String.format("%s input stream is closed", mMainActivity.mRemoteDeviceId));
+    }
+
+    void setFastPairSimulator(FastPairSimulator fastPairSimulator) {
+        this.mFastPairSimulator = fastPairSimulator;
+    }
+
+    private void onShowBattery(@Nullable BatteryInfo batteryInfo) {
+        if (mFastPairSimulator == null || batteryInfo == null) {
+            Log.w(TAG, "skip showing battery");
+            return;
+        }
+
+        if (batteryInfo.getBatteryValuesCount() != 3) {
+            Log.w(TAG, String.format("skip showing battery: count is not valid %d",
+                    batteryInfo.getBatteryValuesCount()));
+            return;
+        }
+
+        Log.d(TAG, String.format("Show battery %s", batteryInfo));
+
+        if (batteryInfo.hasSuppressNotification()) {
+            mFastPairSimulator.setSuppressBatteryNotification(
+                    batteryInfo.getSuppressNotification());
+        }
+        mFastPairSimulator.setBatteryValues(
+                convertFrom(batteryInfo.getBatteryValues(0)),
+                convertFrom(batteryInfo.getBatteryValues(1)),
+                convertFrom(batteryInfo.getBatteryValues(2)));
+        mFastPairSimulator.startAdvertising();
+    }
+
+    private void onHideBattery() {
+        if (mFastPairSimulator == null) {
+            return;
+        }
+
+        mFastPairSimulator.clearBatteryValues();
+        mFastPairSimulator.startAdvertising();
+    }
+
+    private void onRequestBleAddress() {
+        if (mFastPairSimulator == null) {
+            return;
+        }
+
+        mMainActivity.sendEventToRemoteDevice(
+                Event.newBuilder()
+                        .setCode(BLUETOOTH_ADDRESS_BLE)
+                        .setBleAddress(mFastPairSimulator.getBleAddress()));
+    }
+
+    private void onRequestPublicAddress() {
+        if (mFastPairSimulator == null) {
+            return;
+        }
+
+        mMainActivity.sendEventToRemoteDevice(
+                Event.newBuilder()
+                        .setCode(BLUETOOTH_ADDRESS_PUBLIC)
+                        .setPublicAddress(mFastPairSimulator.getBluetoothAddress()));
+    }
+
+    private static BatteryValue convertFrom(BatteryInfo.BatteryValue batteryValue) {
+        return new BatteryValue(batteryValue.getCharging(), batteryValue.getLevel());
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/InputStreamListener.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/InputStreamListener.java
new file mode 100644
index 0000000..b29225a
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/InputStreamListener.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.simulator.testing;
+
+import com.google.protobuf.ByteString;
+
+/** Listener for input stream. */
+public interface InputStreamListener {
+
+    /** Called when new data {@code byteString} is read from the input stream. */
+    void onInputData(ByteString byteString);
+
+    /** Called when the input stream is closed. */
+    void onClose();
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/LocalFileStreamIOHandler.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/LocalFileStreamIOHandler.java
new file mode 100644
index 0000000..cf8b022
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/LocalFileStreamIOHandler.java
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+
+package android.nearby.fastpair.provider.simulator.testing;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.io.BaseEncoding.base16;
+
+import android.net.Uri;
+
+import androidx.annotation.Nullable;
+
+import com.google.protobuf.ByteString;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+
+/**
+ * Opens the {@code inputUri} and {@code outputUri} as local files and provides reading/writing
+ * data operations.
+ *
+ * To support bluetooth testing on real devices, the named pipes are created as local files and the
+ * pipe data are transferred via usb cable, then (1) the peripheral device writes {@code Event} to
+ * the output stream and reads {@code Command} from the input stream (2) the central devices write
+ * {@code Command} to the output stream and read {@code Event} from the input stream.
+ *
+ * The {@code Event} and {@code Command} are special protocols which are defined at
+ * simulator_stream_protocol.proto.
+ */
+public class LocalFileStreamIOHandler implements StreamIOHandler {
+
+    private static final int MAX_IO_DATA_LENGTH_BYTE = 65535;
+
+    private final String mInputPath;
+    private final String mOutputPath;
+
+    LocalFileStreamIOHandler(Uri inputUri, Uri outputUri) throws IOException {
+        if (!isFileExists(inputUri.getPath())) {
+            throw new FileNotFoundException("Input path is not exists.");
+        }
+        if (!isFileExists(outputUri.getPath())) {
+            throw new FileNotFoundException("Output path is not exists.");
+        }
+
+        this.mInputPath = inputUri.getPath();
+        this.mOutputPath = outputUri.getPath();
+    }
+
+    /**
+     * Reads a {@code ByteString} from the input stream. The input stream must be opened before
+     * calling this method.
+     */
+    @Override
+    public ByteString read() throws IOException {
+        try (InputStreamReader inputStream = new InputStreamReader(
+                new FileInputStream(mInputPath))) {
+            int size = inputStream.read();
+            if (size == 0) {
+                throw new IOException(String.format("Missing data size %d", size));
+            }
+
+            if (size > MAX_IO_DATA_LENGTH_BYTE) {
+                throw new IOException("Exceed the maximum data length when reading.");
+            }
+
+            char[] data = new char[size];
+            int count = inputStream.read(data);
+            if (count != size) {
+                throw new IOException(
+                        String.format("Expected size was %s but got %s", size, count));
+            }
+
+            return ByteString.copyFrom(base16().decode(new String(data)));
+        }
+    }
+
+    /**
+     * Writes a {@code output} into the output stream. The output stream must be opened before
+     * calling this method.
+     */
+    @Override
+    public void write(ByteString output) throws IOException {
+        checkArgument(output.size() > 0, "Output data is empty.");
+
+        if (output.size() > MAX_IO_DATA_LENGTH_BYTE) {
+            throw new IOException("Exceed the maximum data length when writing.");
+        }
+
+        try (OutputStreamWriter outputStream =
+                     new OutputStreamWriter(new FileOutputStream(mOutputPath))) {
+            String base16Output = base16().encode(output.toByteArray());
+            outputStream.write(base16Output.length());
+            outputStream.write(base16Output);
+        }
+    }
+
+    private static boolean isFileExists(@Nullable String path) {
+        return path != null && new File(path).exists();
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/RemoteDevice.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/RemoteDevice.java
new file mode 100644
index 0000000..11ec9cb
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/RemoteDevice.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.simulator.testing;
+
+/** Represents a remote device and provides a {@link StreamIOHandler} to communicate with it. */
+public class RemoteDevice {
+    private final String mId;
+    private final StreamIOHandler mStreamIOHandler;
+    private final InputStreamListener mInputStreamListener;
+
+    public RemoteDevice(
+            String id, StreamIOHandler streamIOHandler, InputStreamListener inputStreamListener) {
+        this.mId = id;
+        this.mStreamIOHandler = streamIOHandler;
+        this.mInputStreamListener = inputStreamListener;
+    }
+
+    /** The id used by this device. */
+    public String getId() {
+        return mId;
+    }
+
+    /** The handler processes input and output data channels. */
+    public StreamIOHandler getStreamIOHandler() {
+        return mStreamIOHandler;
+    }
+
+    /** Listener for the input stream. */
+    public InputStreamListener getInputStreamListener() {
+        return mInputStreamListener;
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/RemoteDevicesManager.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/RemoteDevicesManager.java
new file mode 100644
index 0000000..02260c2
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/RemoteDevicesManager.java
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.simulator.testing;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import android.util.Log;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.protobuf.ByteString;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+
+/**
+ * Manages the IO streams with remote devices.
+ *
+ * <p>The caller must invoke {@link #registerRemoteDevice} before starting to communicate with the
+ * remote device, and invoke {@link #unregisterRemoteDevice} after finishing tasks. If this instance
+ * is not used anymore, the caller need to invoke {@link #destroy} to release all resources.
+ *
+ * <p>All of the methods are thread-safe.
+ */
+public class RemoteDevicesManager {
+    private static final String TAG = "RemoteDevicesManager";
+
+    private final Map<String, RemoteDevice> mRemoteDeviceMap = new HashMap<>();
+    private final ListeningExecutorService mBackgroundExecutor =
+            MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
+    private final ListeningExecutorService mListenInputStreamExecutors =
+            MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
+    private final Map<String, ListenableFuture<Void>> mListeningTaskMap = new HashMap<>();
+
+    /**
+     * Opens input and output data streams for {@code remoteDevice} in the background and notifies
+     * the
+     * open result via {@code callback}, and assigns a dedicated executor to listen the input data
+     * stream if data streams are opened successfully. The dedicated executor will invoke the
+     * {@code
+     * remoteDevice.inputStreamListener().onInputData()} directly if the new data exists in the
+     * input
+     * stream and invoke the {@code remoteDevice.inputStreamListener().onClose()} if the input
+     * stream
+     * is closed.
+     */
+    public synchronized void registerRemoteDevice(String id, RemoteDevice remoteDevice) {
+        checkState(mRemoteDeviceMap.put(id, remoteDevice) == null,
+                "The %s is already registered", id);
+        startListeningInputStreamTask(remoteDevice);
+    }
+
+    /**
+     * Closes the data streams for specific remote device {@code id} in the background and notifies
+     * the result via {@code callback}.
+     */
+    public synchronized void unregisterRemoteDevice(String id) {
+        RemoteDevice remoteDevice = mRemoteDeviceMap.remove(id);
+        checkState(remoteDevice != null, "The %s is not registered", id);
+        if (mListeningTaskMap.containsKey(id)) {
+            mListeningTaskMap.remove(id).cancel(/* mayInterruptIfRunning= */ true);
+        }
+    }
+
+    /** Closes all data streams of registered remote devices and stop all background tasks. */
+    public synchronized void destroy() {
+        mRemoteDeviceMap.clear();
+        mListeningTaskMap.clear();
+        mListenInputStreamExecutors.shutdownNow();
+    }
+
+    /**
+     * Writes {@code data} into the output data stream of specific remote device {@code id} in the
+     * background and notifies the result via {@code callback}.
+     */
+    public synchronized void writeDataToRemoteDevice(
+            String id, ByteString data, FutureCallback<Void> callback) {
+        RemoteDevice remoteDevice = mRemoteDeviceMap.get(id);
+        checkState(remoteDevice != null, "The %s is not registered", id);
+
+        runInBackground(() -> {
+            remoteDevice.getStreamIOHandler().write(data);
+            return null;
+        }, callback);
+    }
+
+    private void runInBackground(Callable<Void> callable, FutureCallback<Void> callback) {
+        Futures.addCallback(
+                mBackgroundExecutor.submit(callable), callback, MoreExecutors.directExecutor());
+    }
+
+    private void startListeningInputStreamTask(RemoteDevice remoteDevice) {
+        ListenableFuture<Void> listenFuture = mListenInputStreamExecutors.submit(() -> {
+            Log.i(TAG, "Start listening " + remoteDevice.getId());
+            while (true) {
+                ByteString data;
+                try {
+                    data = remoteDevice.getStreamIOHandler().read();
+                } catch (IOException | IllegalStateException e) {
+                    break;
+                }
+                remoteDevice.getInputStreamListener().onInputData(data);
+            }
+        }, /* result= */ null);
+        Futures.addCallback(listenFuture, new FutureCallback<Void>() {
+            @Override
+            public void onSuccess(Void result) {
+                Log.i(TAG, "Stop listening " + remoteDevice.getId());
+                remoteDevice.getInputStreamListener().onClose();
+            }
+
+            @Override
+            public void onFailure(Throwable t) {
+                Log.w(TAG, "Stop listening " + remoteDevice.getId() + ", cause: " + t);
+                remoteDevice.getInputStreamListener().onClose();
+            }
+        }, MoreExecutors.directExecutor());
+        mListeningTaskMap.put(remoteDevice.getId(), listenFuture);
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/StreamIOHandler.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/StreamIOHandler.java
new file mode 100644
index 0000000..d5fdb9e
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/StreamIOHandler.java
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.simulator.testing;
+
+import com.google.protobuf.ByteString;
+
+import java.io.IOException;
+
+/**
+ * Opens input and output data channels, then provides read and write operations to the data
+ * channels.
+ */
+public interface StreamIOHandler {
+    /**
+     * Reads stream data from the input channel.
+     *
+     * @return a protocol buffer contains the input message
+     * @throws IOException errors occur when reading the input stream
+     */
+    ByteString read() throws IOException;
+
+    /**
+     * Writes stream data to the output channel.
+     *
+     * @param output a protocol buffer contains the output message
+     * @throws IOException errors occur when writing the output message to output stream
+     */
+    void write(ByteString output) throws IOException;
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/StreamIOHandlerFactory.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/StreamIOHandlerFactory.java
new file mode 100644
index 0000000..24cfe56
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/simulator_app/src/android/nearby/fastpair/provider/simulator/testing/StreamIOHandlerFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.simulator.testing;
+
+import android.net.Uri;
+
+import java.io.IOException;
+
+/** A simple factory creating {@link StreamIOHandler} according to {@link Type}. */
+public class StreamIOHandlerFactory {
+
+    /** Types for creating {@link StreamIOHandler}. */
+    public enum Type {
+
+        /**
+         * A {@link StreamIOHandler} accepts local file uris and provides reading/writing file
+         * operations.
+         */
+        LOCAL_FILE
+    }
+
+    /** Creates an instance of {@link StreamIOHandler}. */
+    public static StreamIOHandler createStreamIOHandler(Type type, Uri input, Uri output)
+            throws IOException {
+        if (type.equals(Type.LOCAL_FILE)) {
+            return new LocalFileStreamIOHandler(input, output);
+        }
+        throw new IllegalArgumentException(String.format("Can't support %s", type));
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/FastPairAdvertiser.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/FastPairAdvertiser.java
new file mode 100644
index 0000000..95c077b
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/FastPairAdvertiser.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider;
+
+import androidx.annotation.Nullable;
+
+/** Helper for advertising Fast Pair data. */
+public interface FastPairAdvertiser {
+
+    void startAdvertising(@Nullable byte[] serviceData);
+
+    void stopAdvertising();
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/FastPairSimulator.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/FastPairSimulator.java
new file mode 100644
index 0000000..0d5563e
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/FastPairSimulator.java
@@ -0,0 +1,2391 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider;
+
+import static android.bluetooth.BluetoothAdapter.EXTRA_STATE;
+import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE;
+import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
+import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
+import static android.bluetooth.BluetoothAdapter.STATE_OFF;
+import static android.bluetooth.BluetoothAdapter.STATE_ON;
+import static android.bluetooth.BluetoothDevice.ERROR;
+import static android.bluetooth.BluetoothGattCharacteristic.PERMISSION_READ;
+import static android.bluetooth.BluetoothGattCharacteristic.PERMISSION_WRITE;
+import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_INDICATE;
+import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_NOTIFY;
+import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_READ;
+import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_WRITE;
+import static android.nearby.fastpair.provider.bluetooth.BluetoothManager.wrap;
+import static android.nearby.fastpair.provider.bluetooth.RfcommServer.State.CONNECTED;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption.AES_BLOCK_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption.encrypt;
+import static com.android.server.nearby.common.bluetooth.fastpair.Bytes.toBytes;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.A2DP_SINK_SERVICE_UUID;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.TransportDiscoveryService.BLUETOOTH_SIG_ORGANIZATION_ID;
+import static com.android.server.nearby.common.bluetooth.fastpair.EllipticCurveDiffieHellmanExchange.PUBLIC_KEY_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.MessageStreamHmacEncoder.SECTION_NONCE_LENGTH;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.primitives.Bytes.concat;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass.Device.Major;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.le.AdvertiseSettings;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nearby.fastpair.provider.EventStreamProtocol.AcknowledgementEventCode;
+import android.nearby.fastpair.provider.EventStreamProtocol.DeviceActionEventCode;
+import android.nearby.fastpair.provider.EventStreamProtocol.DeviceCapabilitySyncEventCode;
+import android.nearby.fastpair.provider.EventStreamProtocol.DeviceConfigurationEventCode;
+import android.nearby.fastpair.provider.EventStreamProtocol.DeviceEventCode;
+import android.nearby.fastpair.provider.EventStreamProtocol.EventGroup;
+import android.nearby.fastpair.provider.bluetooth.BluetoothGattServerConfig;
+import android.nearby.fastpair.provider.bluetooth.BluetoothGattServerConfig.ServiceConfig;
+import android.nearby.fastpair.provider.bluetooth.BluetoothGattServerConnection;
+import android.nearby.fastpair.provider.bluetooth.BluetoothGattServerConnection.Notifier;
+import android.nearby.fastpair.provider.bluetooth.BluetoothGattServerHelper;
+import android.nearby.fastpair.provider.bluetooth.BluetoothGattServlet;
+import android.nearby.fastpair.provider.bluetooth.RfcommServer;
+import android.nearby.fastpair.provider.crypto.Crypto;
+import android.nearby.fastpair.provider.crypto.E2eeCalculator;
+import android.nearby.fastpair.provider.utils.Logger;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.core.util.Consumer;
+
+import com.android.server.nearby.common.bloomfilter.BloomFilter;
+import com.android.server.nearby.common.bloomfilter.FastPairBloomFilterHasher;
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption;
+import com.android.server.nearby.common.bluetooth.fastpair.BluetoothAddress;
+import com.android.server.nearby.common.bluetooth.fastpair.Bytes.Value;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.AccountKeyCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.BeaconActionsCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.BeaconActionsCharacteristic.BeaconActionType;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.FirmwareVersionCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.NameCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.PasskeyCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.TransportDiscoveryService;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.TransportDiscoveryService.BrHandoverDataCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.TransportDiscoveryService.ControlPointCharacteristic;
+import com.android.server.nearby.common.bluetooth.fastpair.EllipticCurveDiffieHellmanExchange;
+import com.android.server.nearby.common.bluetooth.fastpair.Ltv;
+import com.android.server.nearby.common.bluetooth.fastpair.MessageStreamHmacEncoder;
+import com.android.server.nearby.common.bluetooth.fastpair.NamingEncoder;
+
+import com.google.common.base.Ascii;
+import com.google.common.primitives.Bytes;
+import com.google.protobuf.ByteString;
+
+import java.lang.reflect.Method;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Simulates a Fast Pair device (e.g. a headset).
+ *
+ * <p>Note: There are two deviations from the spec:
+ *
+ * <ul>
+ *   <li>Instead of using the public address when in pairing mode (discoverable), it always uses the
+ *       random private address (RPA), because that's how stock Android works. To work around this,
+ *       it implements the BR/EDR Handover profile (which is no longer part of the Fast Pair spec)
+ *       when simulating a keyless device (i.e. Fast Pair 1.0), which allows the phone to ask for
+ *       the public address. When there is an anti-spoofing key, i.e. Fast Pair 2.0, the public
+ *       address is delivered via the Key-based Pairing handshake. b/79374759 tracks fixing this.
+ *   <li>The simulator always identifies its device capabilities as Keyboard/Display, even when
+ *       simulating a keyless (Fast Pair 1.0) device that should identify as NoInput/NoOutput.
+ *       b/79377125 tracks fixing this.
+ * </ul>
+ *
+ * @see {http://go/fast-pair-2-spec}
+ */
+public class FastPairSimulator {
+    public static final String TAG = "FastPairSimulator";
+    private final Logger mLogger;
+
+    private static final int BECOME_DISCOVERABLE_TIMEOUT_SEC = 3;
+
+    private static final int SCAN_MODE_REFRESH_SEC = 30;
+
+    /**
+     * Headphones. Generated by
+     * http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html
+     */
+    private static final Value CLASS_OF_DEVICE =
+            new Value(base16().decode("200418"), ByteOrder.BIG_ENDIAN);
+
+    private static final byte[] SUPPORTED_SERVICES_LTV = new Ltv(
+            TransportDiscoveryService.SERVICE_UUIDS_16_BIT_LIST_TYPE,
+            toBytes(ByteOrder.LITTLE_ENDIAN, A2DP_SINK_SERVICE_UUID)
+    ).getBytes();
+    private static final byte[] TDS_CONTROL_POINT_RESPONSE_PARAMETER =
+            Bytes.concat(new byte[]{BLUETOOTH_SIG_ORGANIZATION_ID}, SUPPORTED_SERVICES_LTV);
+
+    private static final String SIMULATOR_FAKE_BLE_ADDRESS = "11:22:33:44:55:66";
+
+    private static final long ADVERTISING_REFRESH_DELAY_1_MIN = TimeUnit.MINUTES.toMillis(1);
+
+    /**
+     * The size of account key filter in bytes is (1.2*n + 3), n represents the size of account key,
+     * see https://developers.google.com/nearby/fast-pair/spec#advertising_when_not_discoverable.
+     * However we'd like to advertise something else, so we could only afford 8 account keys.
+     *
+     * <ul>
+     *   <li>BLE flags: 3 bytes
+     *   <li>TxPower: 3 bytes
+     *   <li>FastPair: max 25 bytes
+     *       <ul>
+     *         <li>FastPair service data: 4 bytes
+     *         <li>Flags: 1 byte
+     *         <li>Account key filter: max 14 bytes (1 byte: length + type, 13 bytes: max 8 account
+     *             keys)
+     *         <li>Salt: 2 bytes
+     *         <li>Battery: 4 bytes
+     *       </ul>
+     * </ul>
+     */
+    private String mDeviceFirmwareVersion = "1.1.0";
+
+    private byte[] mSessionNonce;
+
+    private boolean mUseLogFullEvent = true;
+
+    private enum ResultCode {
+        SUCCESS((byte) 0x00),
+        OP_CODE_NOT_SUPPORTED((byte) 0x01),
+        INVALID_PARAMETER((byte) 0x02),
+        UNSUPPORTED_ORGANIZATION_ID((byte) 0x03),
+        OPERATION_FAILED((byte) 0x04);
+
+        private final byte mByteValue;
+
+        ResultCode(byte byteValue) {
+            this.mByteValue = byteValue;
+        }
+    }
+
+    private enum TransportState {
+        OFF((byte) 0x00),
+        ON((byte) 0x01),
+        TEMPORARILY_UNAVAILABLE((byte) 0x10);
+
+        private final byte mByteValue;
+
+        TransportState(byte byteValue) {
+            this.mByteValue = byteValue;
+        }
+    }
+
+    private final Context mContext;
+    private final Options mOptions;
+    private final Handler mUiThreadHandler = new Handler(Looper.getMainLooper());
+    // No thread pool: Only used in test app (outside gmscore) and in javatests/.../gmscore/.
+    private final ScheduledExecutorService mExecutor =
+            Executors.newSingleThreadScheduledExecutor(); // exempt
+    private final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (mShouldFailPairing) {
+                mLogger.log("Pairing disabled by test app switch");
+                return;
+            }
+            if (mIsDestroyed) {
+                // Sometimes this receiver does not successfully unregister in destroy()
+                // which causes events to occur after the simulator is stopped, so ignore
+                // those events.
+                mLogger.log("Intent received after simulator destroyed, ignoring");
+                return;
+            }
+            BluetoothDevice device = intent.getParcelableExtra(
+                    BluetoothDevice.EXTRA_DEVICE);
+            switch (intent.getAction()) {
+                case BluetoothAdapter.ACTION_SCAN_MODE_CHANGED:
+                    if (isDiscoverable()) {
+                        mIsDiscoverableLatch.countDown();
+                    }
+                    break;
+                case BluetoothDevice.ACTION_PAIRING_REQUEST:
+                    int variant = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
+                            ERROR);
+                    int key = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, ERROR);
+                    mLogger.log(
+                            "Pairing request, variant=%d, key=%s", variant,
+                            key == ERROR ? "(none)" : key);
+
+                    // Prevent Bluetooth Settings from getting the pairing request.
+                    abortBroadcast();
+
+                    mPairingDevice = device;
+                    if (mSecret == null) {
+                        // We haven't done the handshake over GATT to agree on the shared
+                        // secret. For now, just accept anyway (so we can still simulate
+                        // old 1.0 model IDs).
+                        mLogger.log("No handshake, auto-accepting anyway.");
+                        setPasskeyConfirmation(true);
+                    } else if (variant
+                            == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION) {
+                        // Store the passkey. And check it, since there's a race (see
+                        // method for why). Usually this check is a no-op and we'll get
+                        // the passkey later over GATT.
+                        mLocalPasskey = key;
+                        checkPasskey();
+                    } else if (variant == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) {
+                        if (mPasskeyEventCallback != null) {
+                            mPasskeyEventCallback.onPasskeyRequested(
+                                    FastPairSimulator.this::enterPassKey);
+                        } else {
+                            mLogger.log("passkeyEventCallback is not set!");
+                            enterPassKey(key);
+                        }
+                    } else if (variant == BluetoothDevice.PAIRING_VARIANT_CONSENT) {
+                        setPasskeyConfirmation(true);
+
+                    } else if (variant == BluetoothDevice.PAIRING_VARIANT_PIN) {
+                        if (mPasskeyEventCallback != null) {
+                            mPasskeyEventCallback.onPasskeyRequested(
+                                    (int pin) -> {
+                                        byte[] newPin = convertPinToBytes(
+                                                String.format(Locale.ENGLISH, "%d", pin));
+                                        mPairingDevice.setPin(newPin);
+                                    });
+                        }
+                    } else {
+                        // Reject the pairing request if it's not using the Numeric
+                        // Comparison (aka Passkey Confirmation) method.
+                        setPasskeyConfirmation(false);
+                    }
+                    break;
+                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
+                    int bondState =
+                            intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+                                    BluetoothDevice.BOND_NONE);
+                    mLogger.log("Bond state to %s changed to %d", device, bondState);
+                    switch (bondState) {
+                        case BluetoothDevice.BOND_BONDING:
+                            // If we've started bonding, we shouldn't be advertising.
+                            mAdvertiser.stopAdvertising();
+                            // Not discoverable anymore, but still connectable.
+                            setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
+                            break;
+                        case BluetoothDevice.BOND_BONDED:
+                            // Once bonded, advertise the account keys.
+                            mAdvertiser.startAdvertising(accountKeysServiceData());
+                            setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
+
+                            // If it is subsequent pair, we need to add paired device here.
+                            if (mIsSubsequentPair
+                                    && mSecret != null
+                                    && mSecret.length == AES_BLOCK_LENGTH) {
+                                addAccountKey(mSecret, mPairingDevice);
+                            }
+                            break;
+                        case BluetoothDevice.BOND_NONE:
+                            // If the bonding process fails, we should be advertising again.
+                            mAdvertiser.startAdvertising(getServiceData());
+                            break;
+                        default:
+                            break;
+                    }
+                    break;
+                case BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED:
+                    mLogger.log(
+                            "Connection state to %s changed to %d",
+                            device,
+                            intent.getIntExtra(
+                                    BluetoothAdapter.EXTRA_CONNECTION_STATE,
+                                    BluetoothAdapter.STATE_DISCONNECTED));
+                    break;
+                case BluetoothAdapter.ACTION_STATE_CHANGED:
+                    int state = intent.getIntExtra(EXTRA_STATE, -1);
+                    mLogger.log("Bluetooth adapter state=%s", state);
+                    switch (state) {
+                        case STATE_ON:
+                            startRfcommServer();
+                            break;
+                        case STATE_OFF:
+                            stopRfcommServer();
+                            break;
+                        default: // fall out
+                    }
+                    break;
+                default:
+                    mLogger.log(new IllegalArgumentException(intent.toString()),
+                            "Received unexpected intent");
+                    break;
+            }
+        }
+    };
+
+    @Nullable
+    private byte[] convertPinToBytes(@Nullable String pin) {
+        if (TextUtils.isEmpty(pin)) {
+            return null;
+        }
+        byte[] pinBytes;
+        pinBytes = pin.getBytes(StandardCharsets.UTF_8);
+        if (pinBytes.length <= 0 || pinBytes.length > 16) {
+            return null;
+        }
+        return pinBytes;
+    }
+
+    private final NotifiableGattServlet mPasskeyServlet =
+            new NotifiableGattServlet() {
+                @Override
+                // Simulating deprecated API {@code PasskeyCharacteristic.ID} for testing.
+                @SuppressWarnings("deprecation")
+                public BluetoothGattCharacteristic getBaseCharacteristic() {
+                    return new BluetoothGattCharacteristic(
+                            PasskeyCharacteristic.CUSTOM_128_BIT_UUID,
+                            PROPERTY_WRITE | PROPERTY_INDICATE,
+                            PERMISSION_WRITE);
+                }
+
+                @Override
+                public void write(
+                        BluetoothGattServerConnection connection, int offset, byte[] value) {
+                    mLogger.log("Got value from passkey servlet: %s", base16().encode(value));
+                    if (mSecret == null) {
+                        mLogger.log("Ignoring write to passkey characteristic, no pairing secret.");
+                        return;
+                    }
+
+                    try {
+                        mRemotePasskey = PasskeyCharacteristic.decrypt(
+                                PasskeyCharacteristic.Type.SEEKER, mSecret, value);
+                        if (mPasskeyEventCallback != null) {
+                            mPasskeyEventCallback.onRemotePasskeyReceived(mRemotePasskey);
+                        }
+                        checkPasskey();
+                    } catch (GeneralSecurityException e) {
+                        mLogger.log(
+                                "Decrypting passkey value %s failed using key %s",
+                                base16().encode(value), base16().encode(mSecret));
+                    }
+                }
+            };
+
+    private final NotifiableGattServlet mDeviceNameServlet =
+            new NotifiableGattServlet() {
+                @Override
+                // Simulating deprecated API {@code NameCharacteristic.ID} for testing.
+                @SuppressWarnings("deprecation")
+                BluetoothGattCharacteristic getBaseCharacteristic() {
+                    return new BluetoothGattCharacteristic(
+                            NameCharacteristic.CUSTOM_128_BIT_UUID,
+                            PROPERTY_WRITE | PROPERTY_INDICATE,
+                            PERMISSION_WRITE);
+                }
+
+                @Override
+                public void write(
+                        BluetoothGattServerConnection connection, int offset, byte[] value) {
+                    mLogger.log("Got value from device naming servlet: %s", base16().encode(value));
+                    if (mSecret == null) {
+                        mLogger.log("Ignoring write to name characteristic, no pairing secret.");
+                        return;
+                    }
+                    // Parse the device name from seeker to write name into provider.
+                    mLogger.log("Got name byte array size = %d", value.length);
+                    try {
+                        String decryptedDeviceName =
+                                NamingEncoder.decodeNamingPacket(mSecret, value);
+                        if (decryptedDeviceName != null) {
+                            setDeviceName(decryptedDeviceName.getBytes(StandardCharsets.UTF_8));
+                            mLogger.log("write device name = %s", decryptedDeviceName);
+                        }
+                    } catch (GeneralSecurityException e) {
+                        mLogger.log(e, "Failed to decrypt device name.");
+                    }
+                    // For testing to make sure we get the new provider name from simulator.
+                    if (mWriteNameCountDown != null) {
+                        mLogger.log("finish count down latch to write device name.");
+                        mWriteNameCountDown.countDown();
+                    }
+                }
+            };
+
+    private Value mBluetoothAddress;
+    private final FastPairAdvertiser mAdvertiser;
+    private final Map<String, BluetoothGattServerHelper> mBluetoothGattServerHelpers =
+            new HashMap<>();
+    private CountDownLatch mIsDiscoverableLatch = new CountDownLatch(1);
+    private ScheduledFuture<?> mRevertDiscoverableFuture;
+    private boolean mShouldFailPairing = false;
+    private boolean mIsDestroyed = false;
+    private boolean mIsAdvertising;
+    @Nullable
+    private String mBleAddress;
+    private BluetoothDevice mPairingDevice;
+    private int mLocalPasskey;
+    private int mRemotePasskey;
+    @Nullable
+    private byte[] mSecret;
+    @Nullable
+    private byte[] mAccountKey; // The latest account key added.
+    // The first account key added. Eddystone treats that account as the owner of the device.
+    @Nullable
+    private byte[] mOwnerAccountKey;
+    @Nullable
+    private PasskeyConfirmationCallback mPasskeyConfirmationCallback;
+    @Nullable
+    private DeviceNameCallback mDeviceNameCallback;
+    @Nullable
+    private PasskeyEventCallback mPasskeyEventCallback;
+    private final List<BatteryValue> mBatteryValues;
+    private boolean mSuppressBatteryNotification = false;
+    private boolean mSuppressSubsequentPairingNotification = false;
+    HandshakeRequest mHandshakeRequest;
+    @Nullable
+    private CountDownLatch mWriteNameCountDown;
+    private final RfcommServer mRfcommServer = new RfcommServer();
+    private boolean mSupportDynamicBufferSize = false;
+    private NotifiableGattServlet mBeaconActionsServlet;
+    private final FastPairSimulatorDatabase mFastPairSimulatorDatabase;
+    private boolean mIsSubsequentPair = false;
+
+    /** Sets the flag for failing paring for debug purpose. */
+    public void setShouldFailPairing(boolean shouldFailPairing) {
+        this.mShouldFailPairing = shouldFailPairing;
+    }
+
+    /** Gets the flag for failing paring for debug purpose. */
+    public boolean getShouldFailPairing() {
+        return mShouldFailPairing;
+    }
+
+    /** Clear the battery values, then no battery information is packed when advertising. */
+    public void clearBatteryValues() {
+        mBatteryValues.clear();
+    }
+
+    /** Sets the battery items which will be included in the advertisement packet. */
+    public void setBatteryValues(BatteryValue... batteryValues) {
+        this.mBatteryValues.clear();
+        Collections.addAll(this.mBatteryValues, batteryValues);
+    }
+
+    /** Sets whether the battery advertisement packet is within suppress type or not. */
+    public void setSuppressBatteryNotification(boolean suppressBatteryNotification) {
+        this.mSuppressBatteryNotification = suppressBatteryNotification;
+    }
+
+    /** Sets whether the account key data is within suppress type or not. */
+    public void setSuppressSubsequentPairingNotification(boolean isSuppress) {
+        mSuppressSubsequentPairingNotification = isSuppress;
+    }
+
+    /** Calls this to start advertising after some values are changed. */
+    public void startAdvertising() {
+        mAdvertiser.startAdvertising(getServiceData());
+    }
+
+    /** Send Event Message on to rfcomm connected devices. */
+    public void sendEventStreamMessageToRfcommDevices(EventGroup eventGroup) {
+        // Send fake log when event code is logging and type is not using Log_Full event.
+        if (eventGroup == EventGroup.LOGGING && !mUseLogFullEvent) {
+            mRfcommServer.sendFakeEventStreamLoggingMessage(
+                    getDeviceName()
+                            + " "
+                            + getBleAddress()
+                            + " send log at "
+                            + new SimpleDateFormat("HH:mm:ss:SSS", Locale.US)
+                            .format(Calendar.getInstance().getTime()));
+        } else {
+            mRfcommServer.sendFakeEventStreamMessage(eventGroup);
+        }
+    }
+
+    public void setUseLogFullEvent(boolean useLogFullEvent) {
+        this.mUseLogFullEvent = useLogFullEvent;
+    }
+
+    /** An optional way to get advertising status updates. */
+    public interface AdvertisingChangedCallback {
+        /**
+         * Called when we change our BLE advertisement.
+         *
+         * @param isAdvertising the advertising status.
+         */
+        void onAdvertisingChanged(boolean isAdvertising);
+    }
+
+    /** A way for tests to get callbacks when passkey confirmation is invoked. */
+    public interface PasskeyConfirmationCallback {
+        void onPasskeyConfirmation(boolean confirm);
+    }
+
+    /** A way for simulator UI update to get callback when device name is changed. */
+    public interface DeviceNameCallback {
+        void onNameChanged(String deviceName);
+    }
+
+    /**
+     * Callback when there comes a passkey input request from BT service, or receiving remote
+     * device's passkey.
+     */
+    public interface PasskeyEventCallback {
+        void onPasskeyRequested(KeyInputCallback keyInputCallback);
+
+        void onRemotePasskeyReceived(int passkey);
+
+        default void onPasskeyConfirmation(int passkey, Consumer<Boolean> isConfirmed) {
+        }
+    }
+
+    /** Options for the simulator. */
+    public static class Options {
+        private final String mModelId;
+
+        // TODO(b/143117318):Remove this when app-launch type has its own anti-spoofing key.
+        private final String mAdvertisingModelId;
+
+        @Nullable
+        private final String mBluetoothAddress;
+
+        @Nullable
+        private final String mBleAddress;
+
+        private final boolean mDataOnlyConnection;
+
+        private final int mTxPowerLevel;
+
+        private final boolean mEnableNameCharacteristic;
+
+        private final AdvertisingChangedCallback mAdvertisingChangedCallback;
+
+        private final boolean mIncludeTransportDataDescriptor;
+
+        @Nullable
+        private final byte[] mAntiSpoofingPrivateKey;
+
+        private final boolean mUseRandomSaltForAccountKeyRotation;
+
+        private final boolean mBecomeDiscoverable;
+
+        private final boolean mShowsPasskeyConfirmation;
+
+        private final boolean mEnableBeaconActionsCharacteristic;
+
+        private final boolean mRemoveAllDevicesDuringPairing;
+
+        @Nullable
+        private final ByteString mEddystoneIdentityKey;
+
+        private Options(
+                String modelId,
+                String advertisingModelId,
+                @Nullable String bluetoothAddress,
+                @Nullable String bleAddress,
+                boolean dataOnlyConnection,
+                int txPowerLevel,
+                boolean enableNameCharacteristic,
+                AdvertisingChangedCallback advertisingChangedCallback,
+                boolean includeTransportDataDescriptor,
+                @Nullable byte[] antiSpoofingPrivateKey,
+                boolean useRandomSaltForAccountKeyRotation,
+                boolean becomeDiscoverable,
+                boolean showsPasskeyConfirmation,
+                boolean enableBeaconActionsCharacteristic,
+                boolean removeAllDevicesDuringPairing,
+                @Nullable ByteString eddystoneIdentityKey) {
+            this.mModelId = modelId;
+            this.mAdvertisingModelId = advertisingModelId;
+            this.mBluetoothAddress = bluetoothAddress;
+            this.mBleAddress = bleAddress;
+            this.mDataOnlyConnection = dataOnlyConnection;
+            this.mTxPowerLevel = txPowerLevel;
+            this.mEnableNameCharacteristic = enableNameCharacteristic;
+            this.mAdvertisingChangedCallback = advertisingChangedCallback;
+            this.mIncludeTransportDataDescriptor = includeTransportDataDescriptor;
+            this.mAntiSpoofingPrivateKey = antiSpoofingPrivateKey;
+            this.mUseRandomSaltForAccountKeyRotation = useRandomSaltForAccountKeyRotation;
+            this.mBecomeDiscoverable = becomeDiscoverable;
+            this.mShowsPasskeyConfirmation = showsPasskeyConfirmation;
+            this.mEnableBeaconActionsCharacteristic = enableBeaconActionsCharacteristic;
+            this.mRemoveAllDevicesDuringPairing = removeAllDevicesDuringPairing;
+            this.mEddystoneIdentityKey = eddystoneIdentityKey;
+        }
+
+        public String getModelId() {
+            return mModelId;
+        }
+
+        // TODO(b/143117318):Remove this when app-launch type has its own anti-spoofing key.
+        public String getAdvertisingModelId() {
+            return mAdvertisingModelId;
+        }
+
+        @Nullable
+        public String getBluetoothAddress() {
+            return mBluetoothAddress;
+        }
+
+        @Nullable
+        public String getBleAddress() {
+            return mBleAddress;
+        }
+
+        public boolean getDataOnlyConnection() {
+            return mDataOnlyConnection;
+        }
+
+        public int getTxPowerLevel() {
+            return mTxPowerLevel;
+        }
+
+        public boolean getEnableNameCharacteristic() {
+            return mEnableNameCharacteristic;
+        }
+
+        public AdvertisingChangedCallback getAdvertisingChangedCallback() {
+            return mAdvertisingChangedCallback;
+        }
+
+        public boolean getIncludeTransportDataDescriptor() {
+            return mIncludeTransportDataDescriptor;
+        }
+
+        @Nullable
+        public byte[] getAntiSpoofingPrivateKey() {
+            return mAntiSpoofingPrivateKey;
+        }
+
+        public boolean getUseRandomSaltForAccountKeyRotation() {
+            return mUseRandomSaltForAccountKeyRotation;
+        }
+
+        public boolean getBecomeDiscoverable() {
+            return mBecomeDiscoverable;
+        }
+
+        public boolean getShowsPasskeyConfirmation() {
+            return mShowsPasskeyConfirmation;
+        }
+
+        public boolean getEnableBeaconActionsCharacteristic() {
+            return mEnableBeaconActionsCharacteristic;
+        }
+
+        public boolean getRemoveAllDevicesDuringPairing() {
+            return mRemoveAllDevicesDuringPairing;
+        }
+
+        @Nullable
+        public ByteString getEddystoneIdentityKey() {
+            return mEddystoneIdentityKey;
+        }
+
+        /** Converts an instance to a builder. */
+        public Builder toBuilder() {
+            return new Options.Builder(this);
+        }
+
+        /** Constructs a builder. */
+        public static Builder builder() {
+            return new Options.Builder();
+        }
+
+        /** @param modelId Must be a 3-byte hex string. */
+        public static Builder builder(String modelId) {
+            return new Options.Builder()
+                    .setModelId(Ascii.toUpperCase(modelId))
+                    .setAdvertisingModelId(Ascii.toUpperCase(modelId))
+                    .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
+                    .setAdvertisingChangedCallback(isAdvertising -> {
+                    })
+                    .setIncludeTransportDataDescriptor(true)
+                    .setUseRandomSaltForAccountKeyRotation(false)
+                    .setEnableNameCharacteristic(true)
+                    .setDataOnlyConnection(false)
+                    .setBecomeDiscoverable(true)
+                    .setShowsPasskeyConfirmation(false)
+                    .setEnableBeaconActionsCharacteristic(true)
+                    .setRemoveAllDevicesDuringPairing(true);
+        }
+
+        /** A builder for {@link Options}. */
+        public static class Builder {
+
+            private String mModelId;
+
+            // TODO(b/143117318):Remove this when app-launch type has its own anti-spoofing key.
+            private String mAdvertisingModelId;
+
+            @Nullable
+            private String mBluetoothAddress;
+
+            @Nullable
+            private String mBleAddress;
+
+            private boolean mDataOnlyConnection;
+
+            private int mTxPowerLevel;
+
+            private boolean mEnableNameCharacteristic;
+
+            private AdvertisingChangedCallback mAdvertisingChangedCallback;
+
+            private boolean mIncludeTransportDataDescriptor;
+
+            @Nullable
+            private byte[] mAntiSpoofingPrivateKey;
+
+            private boolean mUseRandomSaltForAccountKeyRotation;
+
+            private boolean mBecomeDiscoverable;
+
+            private boolean mShowsPasskeyConfirmation;
+
+            private boolean mEnableBeaconActionsCharacteristic;
+
+            private boolean mRemoveAllDevicesDuringPairing;
+
+            @Nullable
+            private ByteString mEddystoneIdentityKey;
+
+            private Builder() {
+            }
+
+            private Builder(Options option) {
+                this.mModelId = option.mModelId;
+                this.mAdvertisingModelId = option.mAdvertisingModelId;
+                this.mBluetoothAddress = option.mBluetoothAddress;
+                this.mBleAddress = option.mBleAddress;
+                this.mDataOnlyConnection = option.mDataOnlyConnection;
+                this.mTxPowerLevel = option.mTxPowerLevel;
+                this.mEnableNameCharacteristic = option.mEnableNameCharacteristic;
+                this.mAdvertisingChangedCallback = option.mAdvertisingChangedCallback;
+                this.mIncludeTransportDataDescriptor = option.mIncludeTransportDataDescriptor;
+                this.mAntiSpoofingPrivateKey = option.mAntiSpoofingPrivateKey;
+                this.mUseRandomSaltForAccountKeyRotation =
+                        option.mUseRandomSaltForAccountKeyRotation;
+                this.mBecomeDiscoverable = option.mBecomeDiscoverable;
+                this.mShowsPasskeyConfirmation = option.mShowsPasskeyConfirmation;
+                this.mEnableBeaconActionsCharacteristic = option.mEnableBeaconActionsCharacteristic;
+                this.mRemoveAllDevicesDuringPairing = option.mRemoveAllDevicesDuringPairing;
+                this.mEddystoneIdentityKey = option.mEddystoneIdentityKey;
+            }
+
+            /**
+             * Must be one of the {@code ADVERTISE_TX_POWER_*} levels in {@link AdvertiseSettings}.
+             * Default is HIGH.
+             */
+            public Builder setTxPowerLevel(int txPowerLevel) {
+                this.mTxPowerLevel = txPowerLevel;
+                return this;
+            }
+
+            /**
+             * Must be a 6-byte hex string (optionally with colons).
+             * Default is this device's BT MAC.
+             */
+            public Builder setBluetoothAddress(@Nullable String bluetoothAddress) {
+                this.mBluetoothAddress = bluetoothAddress;
+                return this;
+            }
+
+            public Builder setBleAddress(@Nullable String bleAddress) {
+                this.mBleAddress = bleAddress;
+                return this;
+            }
+
+            /** A boolean to decide if enable name characteristic as simulator characteristic. */
+            public Builder setEnableNameCharacteristic(boolean enable) {
+                this.mEnableNameCharacteristic = enable;
+                return this;
+            }
+
+            /** @see AdvertisingChangedCallback */
+            public Builder setAdvertisingChangedCallback(
+                    AdvertisingChangedCallback advertisingChangedCallback) {
+                this.mAdvertisingChangedCallback = advertisingChangedCallback;
+                return this;
+            }
+
+            public Builder setDataOnlyConnection(boolean dataOnlyConnection) {
+                this.mDataOnlyConnection = dataOnlyConnection;
+                return this;
+            }
+
+            /**
+             * Set whether to include the Transport Data descriptor, which has the list of supported
+             * profiles. This is required by the spec, but if we can't get it, we recover gracefully
+             * by assuming support for one of {A2DP, Headset}. Default is true.
+             */
+            public Builder setIncludeTransportDataDescriptor(
+                    boolean includeTransportDataDescriptor) {
+                this.mIncludeTransportDataDescriptor = includeTransportDataDescriptor;
+                return this;
+            }
+
+            public Builder setAntiSpoofingPrivateKey(@Nullable byte[] antiSpoofingPrivateKey) {
+                this.mAntiSpoofingPrivateKey = antiSpoofingPrivateKey;
+                return this;
+            }
+
+            public Builder setUseRandomSaltForAccountKeyRotation(
+                    boolean useRandomSaltForAccountKeyRotation) {
+                this.mUseRandomSaltForAccountKeyRotation = useRandomSaltForAccountKeyRotation;
+                return this;
+            }
+
+            // TODO(b/143117318):Remove this when app-launch type has its own anti-spoofing key.
+            public Builder setAdvertisingModelId(String modelId) {
+                this.mAdvertisingModelId = modelId;
+                return this;
+            }
+
+            public Builder setBecomeDiscoverable(boolean becomeDiscoverable) {
+                this.mBecomeDiscoverable = becomeDiscoverable;
+                return this;
+            }
+
+            public Builder setShowsPasskeyConfirmation(boolean showsPasskeyConfirmation) {
+                this.mShowsPasskeyConfirmation = showsPasskeyConfirmation;
+                return this;
+            }
+
+            public Builder setEnableBeaconActionsCharacteristic(
+                    boolean enableBeaconActionsCharacteristic) {
+                this.mEnableBeaconActionsCharacteristic = enableBeaconActionsCharacteristic;
+                return this;
+            }
+
+            public Builder setRemoveAllDevicesDuringPairing(boolean removeAllDevicesDuringPairing) {
+                this.mRemoveAllDevicesDuringPairing = removeAllDevicesDuringPairing;
+                return this;
+            }
+
+            /**
+             * Non-public because this is required to create a builder. See
+             * {@link Options#builder}.
+             */
+            public Builder setModelId(String modelId) {
+                this.mModelId = modelId;
+                return this;
+            }
+
+            public Builder setEddystoneIdentityKey(@Nullable ByteString eddystoneIdentityKey) {
+                this.mEddystoneIdentityKey = eddystoneIdentityKey;
+                return this;
+            }
+
+            // Custom builder in order to normalize properties. go/autovalue/builders-howto
+            public Options build() {
+                return new Options(
+                        Ascii.toUpperCase(mModelId),
+                        Ascii.toUpperCase(mAdvertisingModelId),
+                        mBluetoothAddress,
+                        mBleAddress,
+                        mDataOnlyConnection,
+                        mTxPowerLevel,
+                        mEnableNameCharacteristic,
+                        mAdvertisingChangedCallback,
+                        mIncludeTransportDataDescriptor,
+                        mAntiSpoofingPrivateKey,
+                        mUseRandomSaltForAccountKeyRotation,
+                        mBecomeDiscoverable,
+                        mShowsPasskeyConfirmation,
+                        mEnableBeaconActionsCharacteristic,
+                        mRemoveAllDevicesDuringPairing,
+                        mEddystoneIdentityKey);
+            }
+        }
+    }
+
+    public FastPairSimulator(Context context, Options options) {
+        this(context, options, new Logger(TAG));
+    }
+
+    public FastPairSimulator(Context context, Options options, Logger logger) {
+        this.mContext = context;
+        this.mOptions = options;
+        this.mLogger = logger;
+
+        this.mBatteryValues = new ArrayList<>();
+
+        String bluetoothAddress =
+                !TextUtils.isEmpty(options.getBluetoothAddress())
+                        ? options.getBluetoothAddress()
+                        : Settings.Secure.getString(context.getContentResolver(),
+                                "bluetooth_address");
+        if (bluetoothAddress == null && VERSION.SDK_INT >= VERSION_CODES.O) {
+            // Requires a modified Android O build for access to bluetoothAdapter.getAddress().
+            // See http://google3/java/com/google/location/nearby/apps/fastpair/simulator/README.md.
+            bluetoothAddress = mBluetoothAdapter.getAddress();
+        }
+        this.mBluetoothAddress =
+                new Value(BluetoothAddress.decode(bluetoothAddress), ByteOrder.BIG_ENDIAN);
+        this.mBleAddress = options.getBleAddress();
+        this.mAdvertiser = new OreoFastPairAdvertiser(this);
+
+        mFastPairSimulatorDatabase = new FastPairSimulatorDatabase(context);
+
+        byte[] deviceName = getDeviceNameInBytes();
+        mLogger.log(
+                "Provider default device name is %s",
+                deviceName != null ? new String(deviceName, StandardCharsets.UTF_8) : null);
+
+        if (mOptions.getDataOnlyConnection()) {
+            // To get BLE address, we need to start advertising first, and then
+            // {@code#setBleAddress} will be called with BLE address.
+            mAdvertiser.startAdvertising(modelIdServiceData(/* forAdvertising= */ true));
+        } else {
+            // Make this so that the simulator doesn't start automatically.
+            // This is tricky since the simulator is used in our integ tests as well.
+            start(mBleAddress != null ? mBleAddress : bluetoothAddress);
+        }
+    }
+
+    public void start(String address) {
+        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
+        filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
+        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        mContext.registerReceiver(mBroadcastReceiver, filter);
+
+        BluetoothManager bluetoothManager = mContext.getSystemService(BluetoothManager.class);
+        BluetoothGattServerHelper bluetoothGattServerHelper =
+                new BluetoothGattServerHelper(mContext, wrap(bluetoothManager));
+        mBluetoothGattServerHelpers.put(address, bluetoothGattServerHelper);
+
+        if (mOptions.getBecomeDiscoverable()) {
+            try {
+                becomeDiscoverable();
+            } catch (InterruptedException | TimeoutException e) {
+                mLogger.log(e, "Error becoming discoverable");
+            }
+        }
+
+        mAdvertiser.startAdvertising(modelIdServiceData(/* forAdvertising= */ true));
+        startGattServer(bluetoothGattServerHelper);
+        startRfcommServer();
+        scheduleAdvertisingRefresh();
+    }
+
+    /**
+     * Regenerate service data on a fixed interval.
+     * This causes the bloom filter to be refreshed and a different salt to be used for rotation.
+     */
+    @SuppressWarnings("FutureReturnValueIgnored")
+    private void scheduleAdvertisingRefresh() {
+        mExecutor.scheduleAtFixedRate(() -> {
+            if (mIsAdvertising) {
+                mAdvertiser.startAdvertising(getServiceData());
+            }
+        }, ADVERTISING_REFRESH_DELAY_1_MIN, ADVERTISING_REFRESH_DELAY_1_MIN, TimeUnit.MILLISECONDS);
+    }
+
+    public void destroy() {
+        try {
+            mLogger.log("Destroying simulator");
+            mIsDestroyed = true;
+            mContext.unregisterReceiver(mBroadcastReceiver);
+            mAdvertiser.stopAdvertising();
+            for (BluetoothGattServerHelper helper : mBluetoothGattServerHelpers.values()) {
+                helper.close();
+            }
+            stopRfcommServer();
+            mDeviceNameCallback = null;
+            mExecutor.shutdownNow();
+        } catch (IllegalArgumentException ignored) {
+            // Happens if you haven't given us permissions yet, so we didn't register the receiver.
+        }
+    }
+
+    public boolean isDestroyed() {
+        return mIsDestroyed;
+    }
+
+    @Nullable
+    public String getBluetoothAddress() {
+        return BluetoothAddress.encode(mBluetoothAddress.getBytes(ByteOrder.BIG_ENDIAN));
+    }
+
+    public boolean isAdvertising() {
+        return mIsAdvertising;
+    }
+
+    public void setIsAdvertising(boolean isAdvertising) {
+        if (this.mIsAdvertising != isAdvertising) {
+            this.mIsAdvertising = isAdvertising;
+            mOptions.getAdvertisingChangedCallback().onAdvertisingChanged(isAdvertising);
+        }
+    }
+
+    public void stopAdvertising() {
+        mAdvertiser.stopAdvertising();
+    }
+
+    public void setBleAddress(String bleAddress) {
+        this.mBleAddress = bleAddress;
+        if (mOptions.getDataOnlyConnection()) {
+            mBluetoothAddress = new Value(BluetoothAddress.decode(bleAddress),
+                    ByteOrder.BIG_ENDIAN);
+            start(bleAddress);
+        }
+        // When BLE address changes, needs to send BLE address to the client again.
+        sendDeviceBleAddress(bleAddress);
+
+        // If we are advertising something other than the model id (e.g. the bloom filter), restart
+        // the advertisement so that it is updated with the new address.
+        if (isAdvertising() && !isDiscoverable()) {
+            mAdvertiser.startAdvertising(getServiceData());
+        }
+    }
+
+    @Nullable
+    public String getBleAddress() {
+        return mBleAddress;
+    }
+
+    // This method is only for testing to make test block until write name success or time out.
+    @VisibleForTesting
+    public void setCountDownLatchToWriteName(CountDownLatch countDownLatch) {
+        mLogger.log("Set up count down latch to write device name.");
+        mWriteNameCountDown = countDownLatch;
+    }
+
+    public boolean areBeaconActionsNotificationsEnabled() {
+        return mBeaconActionsServlet.areNotificationsEnabled();
+    }
+
+    private abstract class NotifiableGattServlet extends BluetoothGattServlet {
+        private final Map<BluetoothGattServerConnection, Notifier> mConnections = new HashMap<>();
+
+        abstract BluetoothGattCharacteristic getBaseCharacteristic();
+
+        @Override
+        public BluetoothGattCharacteristic getCharacteristic() {
+            // Enabling indication requires the Client Characteristic Configuration descriptor.
+            BluetoothGattCharacteristic characteristic = getBaseCharacteristic();
+            characteristic.addDescriptor(
+                    new BluetoothGattDescriptor(
+                            Constants.CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR_UUID,
+                            BluetoothGattDescriptor.PERMISSION_READ
+                                    | BluetoothGattDescriptor.PERMISSION_WRITE));
+            return characteristic;
+        }
+
+        @Override
+        public void enableNotification(BluetoothGattServerConnection connection, Notifier notifier)
+                throws BluetoothGattException {
+            mLogger.log("Registering notifier for %s", getCharacteristic());
+            mConnections.put(connection, notifier);
+        }
+
+        @Override
+        public void disableNotification(BluetoothGattServerConnection connection, Notifier notifier)
+                throws BluetoothGattException {
+            mLogger.log("Removing notifier for %s", getCharacteristic());
+            mConnections.remove(connection);
+        }
+
+        boolean areNotificationsEnabled() {
+            return !mConnections.isEmpty();
+        }
+
+        void sendNotification(byte[] data) {
+            if (mConnections.isEmpty()) {
+                mLogger.log("Not sending notify as no notifier registered");
+                return;
+            }
+            // Needs to be on a separate thread to avoid deadlocking and timing out (waits for a
+            // callback from OS, which happens on the main thread).
+            mExecutor.execute(
+                    () -> {
+                        for (Map.Entry<BluetoothGattServerConnection, Notifier> entry :
+                                mConnections.entrySet()) {
+                            try {
+                                mLogger.log("Sending notify %s to %s",
+                                        getCharacteristic(),
+                                        entry.getKey().getDevice().getAddress());
+                                entry.getValue().notify(data);
+                            } catch (BluetoothException e) {
+                                mLogger.log(
+                                        e,
+                                        "Failed to notify (indicate) result of %s to %s",
+                                        getCharacteristic(),
+                                        entry.getKey().getDevice().getAddress());
+                            }
+                        }
+                    });
+        }
+    }
+
+    private void startRfcommServer() {
+        mRfcommServer.setRequestHandler(this::handleRfcommServerRequest);
+        mRfcommServer.setStateMonitor(state -> {
+            mLogger.log("RfcommServer is in %s state", state);
+            if (CONNECTED.equals(state)) {
+                sendModelId();
+                sendDeviceBleAddress(mBleAddress);
+                sendFirmwareVersion();
+                sendSessionNonce();
+            }
+        });
+        mRfcommServer.start();
+    }
+
+    private void handleRfcommServerRequest(int eventGroup, int eventCode, byte[] data) {
+        switch (eventGroup) {
+            case EventGroup.DEVICE_VALUE:
+                if (data == null) {
+                    break;
+                }
+
+                String deviceValue = base16().encode(data);
+                if (eventCode == DeviceEventCode.DEVICE_CAPABILITY_VALUE) {
+                    mLogger.log("Received phone capability: %s", deviceValue);
+                } else if (eventCode == DeviceEventCode.PLATFORM_TYPE_VALUE) {
+                    mLogger.log("Received platform type: %s", deviceValue);
+                }
+                break;
+            case EventGroup.DEVICE_ACTION_VALUE:
+                if (eventCode == DeviceActionEventCode.DEVICE_ACTION_RING_VALUE) {
+                    mLogger.log("receive device action with ring value, data = %d",
+                            data[0]);
+                    sendDeviceRingActionResponse();
+                    // Simulate notifying the seeker that the ringing has stopped due
+                    // to user interaction (such as tapping the bud).
+                    mUiThreadHandler.postDelayed(this::sendDeviceRingStoppedAction,
+                            5000);
+                }
+                break;
+            case EventGroup.DEVICE_CONFIGURATION_VALUE:
+                if (eventCode == DeviceConfigurationEventCode.CONFIGURATION_BUFFER_SIZE_VALUE) {
+                    mLogger.log(
+                            "receive device action with buffer size value, data = %s",
+                            base16().encode(data));
+                    sendSetBufferActionResponse(data);
+                }
+                break;
+            case EventGroup.DEVICE_CAPABILITY_SYNC_VALUE:
+                if (eventCode == DeviceCapabilitySyncEventCode.REQUEST_CAPABILITY_UPDATE_VALUE) {
+                    mLogger.log("receive device capability update request.");
+                    sendCapabilitySync();
+                }
+                break;
+            default: // fall out
+                break;
+        }
+    }
+
+    private void stopRfcommServer() {
+        mRfcommServer.stop();
+        mRfcommServer.setRequestHandler(null);
+        mRfcommServer.setStateMonitor(null);
+    }
+
+    private void sendModelId() {
+        mLogger.log("Send model ID to the client");
+        mRfcommServer.send(
+                EventGroup.DEVICE_VALUE,
+                DeviceEventCode.DEVICE_MODEL_ID_VALUE,
+                modelIdServiceData(/* forAdvertising= */ false));
+    }
+
+    private void sendDeviceBleAddress(String bleAddress) {
+        mLogger.log("Send BLE address (%s) to the client", bleAddress);
+        if (bleAddress != null) {
+            mRfcommServer.send(
+                    EventGroup.DEVICE_VALUE,
+                    DeviceEventCode.DEVICE_BLE_ADDRESS_VALUE,
+                    BluetoothAddress.decode(bleAddress));
+        }
+    }
+
+    private void sendFirmwareVersion() {
+        mLogger.log("Send Firmware Version (%s) to the client", mDeviceFirmwareVersion);
+        mRfcommServer.send(
+                EventGroup.DEVICE_VALUE,
+                DeviceEventCode.FIRMWARE_VERSION_VALUE,
+                mDeviceFirmwareVersion.getBytes());
+    }
+
+    private void sendSessionNonce() {
+        mLogger.log("Send SessionNonce (%s) to the client", mDeviceFirmwareVersion);
+        SecureRandom secureRandom = new SecureRandom();
+        mSessionNonce = new byte[SECTION_NONCE_LENGTH];
+        secureRandom.nextBytes(mSessionNonce);
+        mRfcommServer.send(
+                EventGroup.DEVICE_VALUE, DeviceEventCode.SECTION_NONCE_VALUE, mSessionNonce);
+    }
+
+    private void sendDeviceRingActionResponse() {
+        mLogger.log("Send device ring action response to the client");
+        mRfcommServer.send(
+                EventGroup.ACKNOWLEDGEMENT_VALUE,
+                AcknowledgementEventCode.ACKNOWLEDGEMENT_ACK_VALUE,
+                new byte[]{
+                        EventGroup.DEVICE_ACTION_VALUE,
+                        DeviceActionEventCode.DEVICE_ACTION_RING_VALUE
+                });
+    }
+
+    private void sendSetBufferActionResponse(byte[] data) {
+        boolean hmacPassed = false;
+        for (ByteString accountKey : getAccountKeys()) {
+            try {
+                if (MessageStreamHmacEncoder.verifyHmac(
+                        accountKey.toByteArray(), mSessionNonce, data)) {
+                    hmacPassed = true;
+                    mLogger.log("Buffer size data matches account key %s",
+                            base16().encode(accountKey.toByteArray()));
+                    break;
+                }
+            } catch (GeneralSecurityException e) {
+                // Ignore.
+            }
+        }
+        if (hmacPassed) {
+            mLogger.log("Send buffer size action response %s to the client", base16().encode(data));
+            mRfcommServer.send(
+                    EventGroup.ACKNOWLEDGEMENT_VALUE,
+                    AcknowledgementEventCode.ACKNOWLEDGEMENT_ACK_VALUE,
+                    new byte[]{
+                            EventGroup.DEVICE_CONFIGURATION_VALUE,
+                            DeviceConfigurationEventCode.CONFIGURATION_BUFFER_SIZE_VALUE,
+                            data[0],
+                            data[1],
+                            data[2]
+                    });
+        } else {
+            mLogger.log("No matched account key for sendSetBufferActionResponse");
+        }
+    }
+
+    private void sendCapabilitySync() {
+        mLogger.log("Send capability sync to the client");
+        if (mSupportDynamicBufferSize) {
+            mLogger.log("Send dynamic buffer size range to the client");
+            mRfcommServer.send(
+                    EventGroup.DEVICE_CAPABILITY_SYNC_VALUE,
+                    DeviceCapabilitySyncEventCode.CONFIGURABLE_BUFFER_SIZE_RANGE_VALUE,
+                    new byte[]{
+                            0x00, 0x01, (byte) 0xf4, 0x00, 0x64, 0x00, (byte) 0xc8,
+                            0x01, 0x00, (byte) 0xff, 0x00, 0x01, 0x00, (byte) 0x88,
+                            0x02, 0x01, (byte) 0xff, 0x01, 0x01, 0x01, (byte) 0x88,
+                            0x03, 0x02, (byte) 0xff, 0x02, 0x01, 0x02, (byte) 0x88,
+                            0x04, 0x03, (byte) 0xff, 0x03, 0x01, 0x03, (byte) 0x88
+                    });
+        }
+    }
+
+    private void sendDeviceRingStoppedAction() {
+        mLogger.log("Sending device ring stopped action to the client");
+        mRfcommServer.send(
+                EventGroup.DEVICE_ACTION_VALUE,
+                DeviceActionEventCode.DEVICE_ACTION_RING_VALUE,
+                // Additional data for stopping ringing on all components.
+                new byte[]{0x00});
+    }
+
+    private void startGattServer(BluetoothGattServerHelper helper) {
+        BluetoothGattServlet tdsControlPointServlet =
+                new NotifiableGattServlet() {
+                    @Override
+                    public BluetoothGattCharacteristic getBaseCharacteristic() {
+                        return new BluetoothGattCharacteristic(ControlPointCharacteristic.ID,
+                                PROPERTY_WRITE | PROPERTY_INDICATE, PERMISSION_WRITE);
+                    }
+
+                    @Override
+                    public void write(
+                            BluetoothGattServerConnection connection, int offset, byte[] value)
+                            throws BluetoothGattException {
+                        mLogger.log("Requested TDS Control Point write, value=%s",
+                                base16().encode(value));
+
+                        ResultCode resultCode = checkTdsControlPointRequest(value);
+                        if (resultCode == ResultCode.SUCCESS) {
+                            try {
+                                becomeDiscoverable();
+                            } catch (TimeoutException | InterruptedException e) {
+                                mLogger.log(e, "Failed to become discoverable");
+                                resultCode = ResultCode.OPERATION_FAILED;
+                            }
+                        }
+
+                        mLogger.log("Request complete, resultCode=%s", resultCode);
+
+                        mLogger.log("Sending TDS Control Point response indication");
+                        sendNotification(
+                                Bytes.concat(
+                                        new byte[]{
+                                                getTdsControlPointOpCode(value),
+                                                resultCode.mByteValue,
+                                        },
+                                        resultCode == ResultCode.SUCCESS
+                                                ? TDS_CONTROL_POINT_RESPONSE_PARAMETER
+                                                : new byte[0]));
+                    }
+                };
+
+        BluetoothGattServlet brHandoverDataServlet =
+                new BluetoothGattServlet() {
+
+                    @Override
+                    public BluetoothGattCharacteristic getCharacteristic() {
+                        return new BluetoothGattCharacteristic(BrHandoverDataCharacteristic.ID,
+                                PROPERTY_READ, PERMISSION_READ);
+                    }
+
+                    @Override
+                    public byte[] read(BluetoothGattServerConnection connection, int offset) {
+                        return Bytes.concat(
+                                new byte[]{BrHandoverDataCharacteristic.BR_EDR_FEATURES},
+                                mBluetoothAddress.getBytes(ByteOrder.LITTLE_ENDIAN),
+                                CLASS_OF_DEVICE.getBytes(ByteOrder.LITTLE_ENDIAN));
+                    }
+                };
+
+        BluetoothGattServlet bluetoothSigServlet =
+                new BluetoothGattServlet() {
+
+                    @Override
+                    public BluetoothGattCharacteristic getCharacteristic() {
+                        BluetoothGattCharacteristic characteristic =
+                                new BluetoothGattCharacteristic(
+                                        TransportDiscoveryService.BluetoothSigDataCharacteristic.ID,
+                                        0 /* no properties */,
+                                        0 /* no permissions */);
+
+                        if (mOptions.getIncludeTransportDataDescriptor()) {
+                            characteristic.addDescriptor(
+                                    new BluetoothGattDescriptor(
+                                            TransportDiscoveryService.BluetoothSigDataCharacteristic
+                                                    .BrTransportBlockDataDescriptor.ID,
+                                            BluetoothGattDescriptor.PERMISSION_READ));
+                        }
+                        return characteristic;
+                    }
+
+                    @Override
+                    public byte[] readDescriptor(
+                            BluetoothGattServerConnection connection,
+                            BluetoothGattDescriptor descriptor,
+                            int offset)
+                            throws BluetoothGattException {
+                        return transportDiscoveryData();
+                    }
+                };
+
+        BluetoothGattServlet accountKeyServlet =
+                new BluetoothGattServlet() {
+                    @Override
+                    // Simulating deprecated API {@code AccountKeyCharacteristic.ID} for testing.
+                    @SuppressWarnings("deprecation")
+                    public BluetoothGattCharacteristic getCharacteristic() {
+                        return new BluetoothGattCharacteristic(
+                                AccountKeyCharacteristic.CUSTOM_128_BIT_UUID,
+                                PROPERTY_WRITE,
+                                PERMISSION_WRITE);
+                    }
+
+                    @Override
+                    public void write(
+                            BluetoothGattServerConnection connection, int offset, byte[] value) {
+                        mLogger.log("Got value from account key servlet: %s",
+                                base16().encode(value));
+                        try {
+                            addAccountKey(AesEcbSingleBlockEncryption.decrypt(mSecret, value),
+                                    mPairingDevice);
+                        } catch (GeneralSecurityException e) {
+                            mLogger.log(e, "Failed to decrypt account key.");
+                        }
+                        mUiThreadHandler.post(
+                                () -> mAdvertiser.startAdvertising(accountKeysServiceData()));
+                    }
+                };
+
+        BluetoothGattServlet firmwareVersionServlet =
+                new BluetoothGattServlet() {
+                    @Override
+                    public BluetoothGattCharacteristic getCharacteristic() {
+                        return new BluetoothGattCharacteristic(
+                                FirmwareVersionCharacteristic.ID, PROPERTY_READ, PERMISSION_READ);
+                    }
+
+                    @Override
+                    public byte[] read(BluetoothGattServerConnection connection, int offset) {
+                        return mDeviceFirmwareVersion.getBytes();
+                    }
+                };
+
+        BluetoothGattServlet keyBasedPairingServlet =
+                new NotifiableGattServlet() {
+                    @Override
+                    // Simulating deprecated API {@code KeyBasedPairingCharacteristic.ID} for
+                    // testing.
+                    @SuppressWarnings("deprecation")
+                    public BluetoothGattCharacteristic getBaseCharacteristic() {
+                        return new BluetoothGattCharacteristic(
+                                KeyBasedPairingCharacteristic.CUSTOM_128_BIT_UUID,
+                                PROPERTY_WRITE | PROPERTY_INDICATE,
+                                PERMISSION_WRITE);
+                    }
+
+                    @Override
+                    public void write(
+                            BluetoothGattServerConnection connection, int offset, byte[] value) {
+                        mLogger.log("Requesting key based pairing handshake, value=%s",
+                                base16().encode(value));
+
+                        mSecret = null;
+                        byte[] seekerPublicAddress = null;
+                        if (value.length == AES_BLOCK_LENGTH) {
+
+                            for (ByteString key : getAccountKeys()) {
+                                byte[] candidateSecret = key.toByteArray();
+                                try {
+                                    seekerPublicAddress = handshake(candidateSecret, value);
+                                    mSecret = candidateSecret;
+                                    mIsSubsequentPair = true;
+                                    break;
+                                } catch (GeneralSecurityException e) {
+                                    mLogger.log(e, "Failed to decrypt with %s",
+                                            base16().encode(candidateSecret));
+                                }
+                            }
+                        } else if (value.length == AES_BLOCK_LENGTH + PUBLIC_KEY_LENGTH
+                                && mOptions.getAntiSpoofingPrivateKey() != null) {
+                            try {
+                                byte[] encryptedRequest = Arrays.copyOf(value, AES_BLOCK_LENGTH);
+                                byte[] receivedPublicKey =
+                                        Arrays.copyOfRange(value, AES_BLOCK_LENGTH, value.length);
+                                byte[] candidateSecret =
+                                        EllipticCurveDiffieHellmanExchange.create(
+                                                        mOptions.getAntiSpoofingPrivateKey())
+                                                .generateSecret(receivedPublicKey);
+                                seekerPublicAddress = handshake(candidateSecret, encryptedRequest);
+                                mSecret = candidateSecret;
+                            } catch (Exception e) {
+                                mLogger.log(
+                                        e,
+                                        "Failed to decrypt with anti-spoofing private key %s",
+                                        base16().encode(mOptions.getAntiSpoofingPrivateKey()));
+                            }
+                        } else {
+                            mLogger.log("Packet length invalid, %d", value.length);
+                            return;
+                        }
+
+                        if (mSecret == null) {
+                            mLogger.log("Couldn't find a usable key to decrypt with.");
+                            return;
+                        }
+
+                        mLogger.log("Found valid decryption key, %s", base16().encode(mSecret));
+                        byte[] salt = new byte[9];
+                        new Random().nextBytes(salt);
+                        try {
+                            byte[] data = concat(
+                                    new byte[]{KeyBasedPairingCharacteristic.Response.TYPE},
+                                    mBluetoothAddress.getBytes(ByteOrder.BIG_ENDIAN), salt);
+                            byte[] encryptedAddress = encrypt(mSecret, data);
+                            mLogger.log(
+                                    "Sending handshake response %s with size %d",
+                                    base16().encode(encryptedAddress), encryptedAddress.length);
+                            sendNotification(encryptedAddress);
+
+                            // Notify seeker for NameCharacteristic to get provider device name
+                            // when seeker request device name flag is true.
+                            if (mOptions.getEnableNameCharacteristic()
+                                    && mHandshakeRequest.requestDeviceName()) {
+                                byte[] encryptedResponse =
+                                        getDeviceNameInBytes() != null ? createEncryptedDeviceName()
+                                                : new byte[0];
+                                mLogger.log(
+                                        "Sending device name response %s with size %d",
+                                        base16().encode(encryptedResponse),
+                                        encryptedResponse.length);
+                                mDeviceNameServlet.sendNotification(encryptedResponse);
+                            }
+
+                            // Disconnects the current connection to allow the following pairing
+                            // request. Needs to be on a separate thread to avoid deadlocking and
+                            // timing out (waits for a callback from OS, which happens on this
+                            // thread).
+                            //
+                            // Note: The spec does not require you to disconnect from other
+                            // devices at this point.
+                            // If headphones support multiple simultaneous connections, they
+                            // should stay connected. But Android fails to pair with the new
+                            // device if we don't first disconnect from any other device.
+                            mLogger.log("Skip remove bond, value=%s",
+                                    mOptions.getRemoveAllDevicesDuringPairing());
+                            if (mOptions.getRemoveAllDevicesDuringPairing()
+                                    && mHandshakeRequest.getType()
+                                    == HandshakeRequest.Type.KEY_BASED_PAIRING_REQUEST
+                                    && !mHandshakeRequest.requestRetroactivePair()) {
+                                mExecutor.execute(() -> disconnectAllBondedDevices());
+                            }
+
+                            if (mHandshakeRequest.getType()
+                                    == HandshakeRequest.Type.KEY_BASED_PAIRING_REQUEST
+                                    && mHandshakeRequest.requestProviderInitialBonding()) {
+                                // Run on executor to ensure it doesn't happen until after the
+                                // notify (which tells the remote device what address to expect).
+                                String seekerPublicAddressString =
+                                        BluetoothAddress.encode(seekerPublicAddress);
+                                mExecutor.execute(() -> {
+                                    mLogger.log("Sending pairing request to %s",
+                                            seekerPublicAddressString);
+                                    mBluetoothAdapter.getRemoteDevice(
+                                            seekerPublicAddressString).createBond();
+                                });
+                            }
+                        } catch (GeneralSecurityException e) {
+                            mLogger.log(e, "Failed to notify of static mac address");
+                        }
+                    }
+
+                    @Nullable
+                    private byte[] handshake(byte[] key, byte[] encryptedPairingRequest)
+                            throws GeneralSecurityException {
+                        mHandshakeRequest = new HandshakeRequest(key, encryptedPairingRequest);
+
+                        byte[] decryptedAddress = mHandshakeRequest.getVerificationData();
+                        if (mBleAddress != null
+                                && Arrays.equals(decryptedAddress,
+                                BluetoothAddress.decode(mBleAddress))
+                                || Arrays.equals(decryptedAddress,
+                                mBluetoothAddress.getBytes(ByteOrder.BIG_ENDIAN))) {
+                            mLogger.log("Address matches: %s", base16().encode(decryptedAddress));
+                        } else {
+                            throw new GeneralSecurityException(
+                                    "Address (BLE or BR/EDR) is not correct: "
+                                            + base16().encode(decryptedAddress)
+                                            + ", "
+                                            + mBleAddress
+                                            + ", "
+                                            + getBluetoothAddress());
+                        }
+
+                        switch (mHandshakeRequest.getType()) {
+                            case KEY_BASED_PAIRING_REQUEST:
+                                return handleKeyBasedPairingRequest(mHandshakeRequest);
+                            case ACTION_OVER_BLE:
+                                return handleActionOverBleRequest(mHandshakeRequest);
+                            case UNKNOWN:
+                                // continue to throw the exception;
+                        }
+                        throw new GeneralSecurityException(
+                                "Type is not correct: " + mHandshakeRequest.getType());
+                    }
+
+                    @Nullable
+                    private byte[] handleKeyBasedPairingRequest(HandshakeRequest handshakeRequest)
+                            throws GeneralSecurityException {
+                        if (handshakeRequest.requestDiscoverable()) {
+                            mLogger.log("Requested discoverability");
+                            setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+                        }
+
+                        mLogger.log(
+                                "KeyBasedPairing: initialBonding=%s, requestDeviceName=%s, "
+                                        + "retroactivePair=%s",
+                                handshakeRequest.requestProviderInitialBonding(),
+                                handshakeRequest.requestDeviceName(),
+                                handshakeRequest.requestRetroactivePair());
+
+                        byte[] seekerPublicAddress = null;
+                        if (handshakeRequest.requestProviderInitialBonding()
+                                || handshakeRequest.requestRetroactivePair()) {
+                            seekerPublicAddress = handshakeRequest.getSeekerPublicAddress();
+                            mLogger.log(
+                                    "Seeker sends BR/EDR address %s to provider",
+                                    BluetoothAddress.encode(seekerPublicAddress));
+                        }
+
+                        if (handshakeRequest.requestRetroactivePair()) {
+                            if (mBluetoothAdapter.getRemoteDevice(
+                                    seekerPublicAddress).getBondState()
+                                    != BluetoothDevice.BOND_BONDED) {
+                                throw new GeneralSecurityException(
+                                        "Address (BR/EDR) is not bonded: "
+                                                + BluetoothAddress.encode(seekerPublicAddress));
+                            }
+                        }
+
+                        return seekerPublicAddress;
+                    }
+
+                    @Nullable
+                    private byte[] handleActionOverBleRequest(HandshakeRequest handshakeRequest) {
+                        // TODO(wollohchou): implement action over ble request.
+                        if (handshakeRequest.requestDeviceAction()) {
+                            mLogger.log("Requesting action over BLE, device action");
+                        } else if (handshakeRequest.requestFollowedByAdditionalData()) {
+                            mLogger.log(
+                                    "Requesting action over BLE, followed by additional data, "
+                                            + "type:%s",
+                                    handshakeRequest.getAdditionalDataType());
+                        } else {
+                            mLogger.log("Requesting action over BLE");
+                        }
+                        return null;
+                    }
+
+                    /**
+                     * @return The encrypted device name from provider for seeker to use.
+                     */
+                    private byte[] createEncryptedDeviceName() throws GeneralSecurityException {
+                        byte[] deviceName = getDeviceNameInBytes();
+                        String providerName = new String(deviceName, StandardCharsets.UTF_8);
+                        mLogger.log(
+                                "Sending handshake response for device name %s with size %d",
+                                providerName, deviceName.length);
+                        return NamingEncoder.encodeNamingPacket(mSecret, providerName);
+                    }
+                };
+
+        mBeaconActionsServlet =
+                new NotifiableGattServlet() {
+                    private static final int GATT_ERROR_UNAUTHENTICATED = 0x80;
+                    private static final int GATT_ERROR_INVALID_VALUE = 0x81;
+                    private static final int NONCE_LENGTH = 8;
+                    private static final int ONE_TIME_AUTH_KEY_OFFSET = 2;
+                    private static final int ONE_TIME_AUTH_KEY_LENGTH = 8;
+                    private static final int IDENTITY_KEY_LENGTH = 32;
+                    private static final byte TRANSMISSION_POWER = 0;
+
+                    private final SecureRandom mRandom = new SecureRandom();
+                    private final MessageDigest mSha256;
+                    @Nullable
+                    private byte[] mLastNonce;
+                    @Nullable
+                    private ByteString mIdentityKey = mOptions.getEddystoneIdentityKey();
+
+                    {
+                        try {
+                            mSha256 = MessageDigest.getInstance("SHA-256");
+                            mSha256.reset();
+                        } catch (NoSuchAlgorithmException e) {
+                            throw new IllegalStateException(
+                                    "System missing SHA-256 implementation.", e);
+                        }
+                    }
+
+                    @Override
+                    // Simulating deprecated API {@code BeaconActionsCharacteristic.ID} for testing.
+                    @SuppressWarnings("deprecation")
+                    public BluetoothGattCharacteristic getBaseCharacteristic() {
+                        return new BluetoothGattCharacteristic(
+                                BeaconActionsCharacteristic.CUSTOM_128_BIT_UUID,
+                                PROPERTY_READ | PROPERTY_WRITE | PROPERTY_NOTIFY,
+                                PERMISSION_READ | PERMISSION_WRITE);
+                    }
+
+                    @Override
+                    public byte[] read(BluetoothGattServerConnection connection, int offset) {
+                        mLastNonce = new byte[NONCE_LENGTH];
+                        mRandom.nextBytes(mLastNonce);
+                        return mLastNonce;
+                    }
+
+                    @Override
+                    public void write(
+                            BluetoothGattServerConnection connection, int offset, byte[] value)
+                            throws BluetoothGattException {
+                        mLogger.log("Got value from beacon actions servlet: %s",
+                                base16().encode(value));
+                        if (value.length == 0) {
+                            mLogger.log("Packet length invalid, %d", value.length);
+                            throw new BluetoothGattException("Packet length invalid",
+                                    GATT_ERROR_INVALID_VALUE);
+                        }
+                        switch (value[0]) {
+                            case BeaconActionType.READ_BEACON_PARAMETERS:
+                                handleReadBeaconParameters(value);
+                                break;
+                            case BeaconActionType.READ_PROVISIONING_STATE:
+                                handleReadProvisioningState(value);
+                                break;
+                            case BeaconActionType.SET_EPHEMERAL_IDENTITY_KEY:
+                                handleSetEphemeralIdentityKey(value);
+                                break;
+                            case BeaconActionType.CLEAR_EPHEMERAL_IDENTITY_KEY:
+                            case BeaconActionType.READ_EPHEMERAL_IDENTITY_KEY:
+                            case BeaconActionType.RING:
+                            case BeaconActionType.READ_RINGING_STATE:
+                                throw new BluetoothGattException(
+                                        "Unimplemented beacon action",
+                                        BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+                            default:
+                                throw new BluetoothGattException(
+                                        "Unknown beacon action",
+                                        BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+                        }
+                    }
+
+                    private boolean verifyAccountKeyToken(byte[] value, boolean ownerOnly)
+                            throws BluetoothGattException {
+                        if (value.length < ONE_TIME_AUTH_KEY_LENGTH + ONE_TIME_AUTH_KEY_OFFSET) {
+                            mLogger.log("Packet length invalid, %d", value.length);
+                            throw new BluetoothGattException(
+                                    "Packet length invalid", GATT_ERROR_INVALID_VALUE);
+                        }
+                        byte[] hashedAccountKey =
+                                Arrays.copyOfRange(
+                                        value,
+                                        ONE_TIME_AUTH_KEY_OFFSET,
+                                        ONE_TIME_AUTH_KEY_LENGTH + ONE_TIME_AUTH_KEY_OFFSET);
+                        if (mLastNonce == null) {
+                            throw new BluetoothGattException(
+                                    "Nonce wasn't set", GATT_ERROR_UNAUTHENTICATED);
+                        }
+                        if (ownerOnly) {
+                            ByteString accountKey = getOwnerAccountKey();
+                            if (accountKey != null) {
+                                mSha256.update(accountKey.toByteArray());
+                                mSha256.update(mLastNonce);
+                                return Arrays.equals(
+                                        hashedAccountKey,
+                                        Arrays.copyOf(mSha256.digest(), ONE_TIME_AUTH_KEY_LENGTH));
+                            }
+                        } else {
+                            Set<ByteString> accountKeys = getAccountKeys();
+                            for (ByteString accountKey : accountKeys) {
+                                mSha256.update(accountKey.toByteArray());
+                                mSha256.update(mLastNonce);
+                                if (Arrays.equals(
+                                        hashedAccountKey,
+                                        Arrays.copyOf(mSha256.digest(),
+                                                ONE_TIME_AUTH_KEY_LENGTH))) {
+                                    return true;
+                                }
+                            }
+                        }
+                        return false;
+                    }
+
+                    private int getBeaconClock() {
+                        return (int) TimeUnit.MILLISECONDS.toSeconds(SystemClock.elapsedRealtime());
+                    }
+
+                    private ByteString fromBytes(byte... bytes) {
+                        return ByteString.copyFrom(bytes);
+                    }
+
+                    private byte[] intToByteArray(int value) {
+                        byte[] data = new byte[4];
+                        data[3] = (byte) value;
+                        data[2] = (byte) (value >>> 8);
+                        data[1] = (byte) (value >>> 16);
+                        data[0] = (byte) (value >>> 24);
+                        return data;
+                    }
+
+                    private void handleReadBeaconParameters(byte[] value)
+                            throws BluetoothGattException {
+                        if (!verifyAccountKeyToken(value, /* ownerOnly= */ false)) {
+                            throw new BluetoothGattException(
+                                    "failed to authenticate account key",
+                                    GATT_ERROR_UNAUTHENTICATED);
+                        }
+                        sendNotification(
+                                fromBytes(
+                                        (byte) BeaconActionType.READ_BEACON_PARAMETERS,
+                                        (byte) 5 /* data length */,
+                                        TRANSMISSION_POWER)
+                                        .concat(ByteString.copyFrom(
+                                                intToByteArray(getBeaconClock())))
+                                        .toByteArray());
+                    }
+
+                    private void handleReadProvisioningState(byte[] value)
+                            throws BluetoothGattException {
+                        if (!verifyAccountKeyToken(value, /* ownerOnly= */ false)) {
+                            throw new BluetoothGattException(
+                                    "failed to authenticate account key",
+                                    GATT_ERROR_UNAUTHENTICATED);
+                        }
+                        byte flags = 0;
+                        if (verifyAccountKeyToken(value, /* ownerOnly= */ true)) {
+                            flags |= (byte) (1 << 1);
+                        }
+                        if (mIdentityKey == null) {
+                            sendNotification(
+                                    fromBytes(
+                                            (byte) BeaconActionType.READ_PROVISIONING_STATE,
+                                            (byte) 1 /* data length */,
+                                            flags)
+                                            .toByteArray());
+                        } else {
+                            flags |= (byte) 1;
+                            sendNotification(
+                                    fromBytes(
+                                            (byte) BeaconActionType.READ_PROVISIONING_STATE,
+                                            (byte) 21 /* data length */,
+                                            flags)
+                                            .concat(
+                                                    E2eeCalculator.computeE2eeEid(
+                                                            mIdentityKey, /* exponent= */ 10,
+                                                            getBeaconClock()))
+                                            .toByteArray());
+                        }
+                    }
+
+                    private void handleSetEphemeralIdentityKey(byte[] value)
+                            throws BluetoothGattException {
+                        if (!verifyAccountKeyToken(value, /* ownerOnly= */ true)) {
+                            throw new BluetoothGattException(
+                                    "failed to authenticate owner account key",
+                                    GATT_ERROR_UNAUTHENTICATED);
+                        }
+                        if (value.length
+                                != ONE_TIME_AUTH_KEY_LENGTH + ONE_TIME_AUTH_KEY_OFFSET
+                                + IDENTITY_KEY_LENGTH) {
+                            mLogger.log("Packet length invalid, %d", value.length);
+                            throw new BluetoothGattException("Packet length invalid",
+                                    GATT_ERROR_INVALID_VALUE);
+                        }
+                        if (mIdentityKey != null) {
+                            throw new BluetoothGattException(
+                                    "Device is already provisioned as Eddystone",
+                                    GATT_ERROR_UNAUTHENTICATED);
+                        }
+                        mIdentityKey = Crypto.aesEcbNoPaddingDecrypt(
+                                ByteString.copyFrom(mOwnerAccountKey),
+                                ByteString.copyFrom(value)
+                                        .substring(ONE_TIME_AUTH_KEY_LENGTH
+                                                + ONE_TIME_AUTH_KEY_OFFSET));
+                    }
+                };
+
+        ServiceConfig fastPairServiceConfig =
+                new ServiceConfig()
+                        .addCharacteristic(accountKeyServlet)
+                        .addCharacteristic(keyBasedPairingServlet)
+                        .addCharacteristic(mPasskeyServlet)
+                        .addCharacteristic(firmwareVersionServlet);
+        if (mOptions.getEnableBeaconActionsCharacteristic()) {
+            fastPairServiceConfig.addCharacteristic(mBeaconActionsServlet);
+        }
+
+        BluetoothGattServerConfig config =
+                new BluetoothGattServerConfig()
+                        .addService(
+                                TransportDiscoveryService.ID,
+                                new ServiceConfig()
+                                        .addCharacteristic(tdsControlPointServlet)
+                                        .addCharacteristic(brHandoverDataServlet)
+                                        .addCharacteristic(bluetoothSigServlet))
+                        .addService(
+                                FastPairService.ID,
+                                mOptions.getEnableNameCharacteristic()
+                                        ? fastPairServiceConfig.addCharacteristic(
+                                        mDeviceNameServlet)
+                                        : fastPairServiceConfig);
+
+        mLogger.log(
+                "Starting GATT server, support name characteristic %b",
+                mOptions.getEnableNameCharacteristic());
+        try {
+            helper.open(config);
+        } catch (BluetoothException e) {
+            mLogger.log(e, "Error starting GATT server");
+        }
+    }
+
+    /** Callback for passkey/pin input. */
+    public interface KeyInputCallback {
+        void onKeyInput(int key);
+    }
+
+    public void enterPassKey(int passkey) {
+        mLogger.log("enterPassKey called with passkey %d.", passkey);
+        mPairingDevice.setPairingConfirmation(true);
+    }
+
+    private void checkPasskey() {
+        // There's a race between the PAIRING_REQUEST broadcast from the OS giving us the local
+        // passkey, and the remote passkey received over GATT. Skip the check until we have both.
+        if (mLocalPasskey == 0 || mRemotePasskey == 0) {
+            mLogger.log(
+                    "Skipping passkey check, missing local (%s) or remote (%s).",
+                    mLocalPasskey, mRemotePasskey);
+            return;
+        }
+
+        // Regardless of whether it matches, send our (encrypted) passkey to the seeker.
+        sendPasskeyToRemoteDevice(mLocalPasskey);
+
+        mLogger.log("Checking localPasskey %s == remotePasskey %s", mLocalPasskey, mRemotePasskey);
+        boolean passkeysMatched = mLocalPasskey == mRemotePasskey;
+        if (mOptions.getShowsPasskeyConfirmation() && passkeysMatched
+                && mPasskeyEventCallback != null) {
+            mLogger.log("callbacks the UI for passkey confirmation.");
+            mPasskeyEventCallback.onPasskeyConfirmation(mLocalPasskey,
+                    this::setPasskeyConfirmation);
+        } else {
+            setPasskeyConfirmation(passkeysMatched);
+        }
+    }
+
+    private void sendPasskeyToRemoteDevice(int passkey) {
+        try {
+            mPasskeyServlet.sendNotification(
+                    PasskeyCharacteristic.encrypt(
+                            PasskeyCharacteristic.Type.PROVIDER, mSecret, passkey));
+        } catch (GeneralSecurityException e) {
+            mLogger.log(e, "Failed to encrypt passkey response.");
+        }
+    }
+
+    public void setFirmwareVersion(String versionNumber) {
+        mDeviceFirmwareVersion = versionNumber;
+    }
+
+    public void setDynamicBufferSize(boolean support) {
+        if (mSupportDynamicBufferSize != support) {
+            mSupportDynamicBufferSize = support;
+            sendCapabilitySync();
+        }
+    }
+
+    @VisibleForTesting
+    void setPasskeyConfirmationCallback(PasskeyConfirmationCallback callback) {
+        this.mPasskeyConfirmationCallback = callback;
+    }
+
+    public void setDeviceNameCallback(DeviceNameCallback callback) {
+        this.mDeviceNameCallback = callback;
+    }
+
+    public void setPasskeyEventCallback(PasskeyEventCallback passkeyEventCallback) {
+        this.mPasskeyEventCallback = passkeyEventCallback;
+    }
+
+    private void setPasskeyConfirmation(boolean confirm) {
+        mPairingDevice.setPairingConfirmation(confirm);
+        if (mPasskeyConfirmationCallback != null) {
+            mPasskeyConfirmationCallback.onPasskeyConfirmation(confirm);
+        }
+        mLocalPasskey = 0;
+        mRemotePasskey = 0;
+    }
+
+    private void becomeDiscoverable() throws InterruptedException, TimeoutException {
+        setDiscoverable(true);
+    }
+
+    public void cancelDiscovery() throws InterruptedException, TimeoutException {
+        setDiscoverable(false);
+    }
+
+    private void setDiscoverable(boolean discoverable)
+            throws InterruptedException, TimeoutException {
+        mIsDiscoverableLatch = new CountDownLatch(1);
+        setScanMode(discoverable ? SCAN_MODE_CONNECTABLE_DISCOVERABLE : SCAN_MODE_CONNECTABLE);
+        // If we're already discoverable, count down the latch right away. Otherwise,
+        // we'll get a broadcast when we successfully become discoverable.
+        if (isDiscoverable()) {
+            mIsDiscoverableLatch.countDown();
+        }
+        if (mIsDiscoverableLatch.await(BECOME_DISCOVERABLE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            mLogger.log("Successfully became switched discoverable mode %s", discoverable);
+        } else {
+            throw new TimeoutException();
+        }
+    }
+
+    private void setScanMode(int scanMode) {
+        if (mRevertDiscoverableFuture != null) {
+            mRevertDiscoverableFuture.cancel(false /* may interrupt if running */);
+        }
+
+        mLogger.log("Setting scan mode to %s", scanModeToString(scanMode));
+        try {
+            Method method = mBluetoothAdapter.getClass().getMethod("setScanMode", Integer.TYPE);
+            method.invoke(mBluetoothAdapter, scanMode);
+
+            if (scanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+                mRevertDiscoverableFuture =
+                        mExecutor.schedule(() -> setScanMode(SCAN_MODE_CONNECTABLE),
+                                SCAN_MODE_REFRESH_SEC, TimeUnit.SECONDS);
+            }
+        } catch (Exception e) {
+            mLogger.log(e, "Error setting scan mode to %d", scanMode);
+        }
+    }
+
+    public static String scanModeToString(int scanMode) {
+        switch (scanMode) {
+            case SCAN_MODE_CONNECTABLE_DISCOVERABLE:
+                return "DISCOVERABLE";
+            case SCAN_MODE_CONNECTABLE:
+                return "CONNECTABLE";
+            case SCAN_MODE_NONE:
+                return "NOT CONNECTABLE";
+            default:
+                return "UNKNOWN(" + scanMode + ")";
+        }
+    }
+
+    private ResultCode checkTdsControlPointRequest(byte[] request) {
+        if (request.length < 2) {
+            mLogger.log(
+                    new IllegalArgumentException(), "Expected length >= 2 for %s",
+                    base16().encode(request));
+            return ResultCode.INVALID_PARAMETER;
+        }
+        byte opCode = getTdsControlPointOpCode(request);
+        if (opCode != ControlPointCharacteristic.ACTIVATE_TRANSPORT_OP_CODE) {
+            mLogger.log(
+                    new IllegalArgumentException(),
+                    "Expected Activate Transport op code (0x01), got %d",
+                    opCode);
+            return ResultCode.OP_CODE_NOT_SUPPORTED;
+        }
+        if (request[1] != BLUETOOTH_SIG_ORGANIZATION_ID) {
+            mLogger.log(
+                    new IllegalArgumentException(),
+                    "Expected Bluetooth SIG organization ID (0x01), got %d",
+                    request[1]);
+            return ResultCode.UNSUPPORTED_ORGANIZATION_ID;
+        }
+        return ResultCode.SUCCESS;
+    }
+
+    private static byte getTdsControlPointOpCode(byte[] request) {
+        return request.length < 1 ? 0x00 : request[0];
+    }
+
+    private boolean isDiscoverable() {
+        return mBluetoothAdapter.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE;
+    }
+
+    private byte[] modelIdServiceData(boolean forAdvertising) {
+        // Note: This used to be little-endian but is now big-endian. See b/78229467 for details.
+        byte[] modelIdPacket =
+                base16().decode(
+                        forAdvertising ? mOptions.getAdvertisingModelId() : mOptions.getModelId());
+        if (!mBatteryValues.isEmpty()) {
+            // If we are going to advertise battery values with the packet, then switch to the
+            // non-3-byte model ID format.
+            modelIdPacket = concat(new byte[]{0b00000110}, modelIdPacket);
+        }
+        return modelIdPacket;
+    }
+
+    private byte[] accountKeysServiceData() {
+        try {
+            return concat(new byte[]{0x00}, generateBloomFilterFields());
+        } catch (NoSuchAlgorithmException e) {
+            throw new IllegalStateException("Unable to build bloom filter.", e);
+        }
+    }
+
+    private byte[] transportDiscoveryData() {
+        byte[] transportData = SUPPORTED_SERVICES_LTV;
+        return Bytes.concat(
+                new byte[]{BLUETOOTH_SIG_ORGANIZATION_ID},
+                new byte[]{tdsFlags(isDiscoverable() ? TransportState.ON : TransportState.OFF)},
+                new byte[]{(byte) transportData.length},
+                transportData);
+    }
+
+    private byte[] generateBloomFilterFields() throws NoSuchAlgorithmException {
+        Set<ByteString> accountKeys = getAccountKeys();
+        if (accountKeys.isEmpty()) {
+            return new byte[0];
+        }
+        BloomFilter bloomFilter =
+                new BloomFilter(
+                        new byte[(int) (1.2 * accountKeys.size()) + 3],
+                        new FastPairBloomFilterHasher());
+        String address = mBleAddress == null ? SIMULATOR_FAKE_BLE_ADDRESS : mBleAddress;
+
+        // Simulator supports Central Address Resolution characteristic, so when paired, the BLE
+        // address in Seeker will be resolved to BR/EDR address. This caused Seeker fails on
+        // checking the bloom filter due to different address is used for salting. In order to
+        // let battery values notification be shown on paired device, we use random salt to
+        // workaround it.
+        boolean advertisingBatteryValues = !mBatteryValues.isEmpty();
+        byte[] salt;
+        if (mOptions.getUseRandomSaltForAccountKeyRotation() || advertisingBatteryValues) {
+            salt = new byte[1];
+            new SecureRandom().nextBytes(salt);
+            mLogger.log("Using random salt %s for bloom filter", base16().encode(salt));
+        } else {
+            salt = BluetoothAddress.decode(address);
+            mLogger.log("Using address %s for bloom filter", address);
+        }
+
+        // To prevent tampering, account filter shall be slightly modified to include battery data
+        // when the battery values are included in the advertisement. Normally, when building the
+        // account filter, a value V is produce by combining the account key with a salt. Instead,
+        // when battery values are also being advertised, it be constructed as follows:
+        // - the first 16 bytes are account key.
+        // - the next bytes are the salt.
+        // - the remaining bytes are the battery data.
+        byte[] saltAndBatteryData =
+                advertisingBatteryValues ? concat(salt, generateBatteryData()) : salt;
+
+        for (ByteString accountKey : accountKeys) {
+            bloomFilter.add(concat(accountKey.toByteArray(), saltAndBatteryData));
+        }
+        byte[] packet = generateAccountKeyData(bloomFilter);
+        return mOptions.getUseRandomSaltForAccountKeyRotation() || advertisingBatteryValues
+                // Create a header with length 1 and type 1 for a random salt.
+                ? concat(packet, createField((byte) 0x11, salt))
+                // Exclude the salt from the packet, BLE address will be assumed by the client.
+                : packet;
+    }
+
+    /**
+     * Creates a new field for the packet.
+     *
+     * The header is formatted 0xLLLLTTTT where LLLL is the
+     * length of the field and TTTT is the type (0 for bloom filter, 1 for salt).
+     */
+    private byte[] createField(byte header, byte[] value) {
+        return concat(new byte[]{header}, value);
+    }
+
+    public int getTxPower() {
+        return mOptions.getTxPowerLevel();
+    }
+
+    @Nullable
+    byte[] getServiceData() {
+        byte[] packet =
+                isDiscoverable()
+                        ? modelIdServiceData(/* forAdvertising= */ true)
+                        : !getAccountKeys().isEmpty() ? accountKeysServiceData() : null;
+        return addBatteryValues(packet);
+    }
+
+    @Nullable
+    private byte[] addBatteryValues(byte[] packet) {
+        if (mBatteryValues.isEmpty() || packet == null) {
+            return packet;
+        }
+
+        return concat(packet, generateBatteryData());
+    }
+
+    private byte[] generateBatteryData() {
+        // Byte 0: Battery length and type, first 4 bits are the number of battery values, second
+        // 4 are the type.
+        // Byte 1 - length: Battery values, the first bit is charging status, the remaining bits are
+        // the actual value between 0 and 100, or -1 for unknown.
+        byte[] batteryData = new byte[mBatteryValues.size() + 1];
+        batteryData[0] = (byte) (mBatteryValues.size() << 4
+                | (mSuppressBatteryNotification ? 0b0100 : 0b0011));
+
+        int batteryValueIndex = 1;
+        for (BatteryValue batteryValue : mBatteryValues) {
+            batteryData[batteryValueIndex++] =
+                    (byte)
+                            ((batteryValue.mCharging ? 0b10000000 : 0b00000000)
+                                    | (0b01111111 & batteryValue.mLevel));
+        }
+
+        return batteryData;
+    }
+
+    private byte[] generateAccountKeyData(BloomFilter bloomFilter) {
+        // Byte 0: length and type, first 4 bits are the length of bloom filter, second 4 are the
+        // type which indicating the subsequent pairing notification is suppressed or not.
+        // The following bytes are the data of bloom filter.
+        byte[] filterBytes = bloomFilter.asBytes();
+        byte lengthAndType = (byte) (filterBytes.length << 4
+                | (mSuppressSubsequentPairingNotification ? 0b0010 : 0b0000));
+        mLogger.log(
+                "Generate bloom filter with suppress subsequent pairing notification:%b",
+                mSuppressSubsequentPairingNotification);
+        return createField(lengthAndType, filterBytes);
+    }
+
+    /** Disconnects all bonded devices. */
+    public void disconnectAllBondedDevices() {
+        for (BluetoothDevice device : mBluetoothAdapter.getBondedDevices()) {
+            if (device.getBluetoothClass().getMajorDeviceClass() == Major.PHONE) {
+                removeBond(device);
+            }
+        }
+    }
+
+    public void disconnect(BluetoothProfile profile, BluetoothDevice device) {
+        device.disconnect();
+    }
+
+    public void removeBond(BluetoothDevice device) {
+        device.removeBond();
+    }
+
+    public void resetAccountKeys() {
+        mFastPairSimulatorDatabase.setAccountKeys(new HashSet<>());
+        mFastPairSimulatorDatabase.setFastPairSeekerDevices(new HashSet<>());
+        mAccountKey = null;
+        mOwnerAccountKey = null;
+        mLogger.log("Remove all account keys");
+    }
+
+    public void addAccountKey(byte[] key) {
+        addAccountKey(key, /* device= */ null);
+    }
+
+    private void addAccountKey(byte[] key, @Nullable BluetoothDevice device) {
+        mAccountKey = key;
+        if (mOwnerAccountKey == null) {
+            mOwnerAccountKey = key;
+        }
+
+        mFastPairSimulatorDatabase.addAccountKey(key);
+        mFastPairSimulatorDatabase.addFastPairSeekerDevice(device, key);
+        mLogger.log("Add account key: key=%s, device=%s", base16().encode(key), device);
+    }
+
+    private Set<ByteString> getAccountKeys() {
+        return mFastPairSimulatorDatabase.getAccountKeys();
+    }
+
+    /** Get the latest account key. */
+    @Nullable
+    public ByteString getAccountKey() {
+        if (mAccountKey == null) {
+            return null;
+        }
+        return ByteString.copyFrom(mAccountKey);
+    }
+
+    /** Get the owner account key (the first account key registered). */
+    @Nullable
+    public ByteString getOwnerAccountKey() {
+        if (mOwnerAccountKey == null) {
+            return null;
+        }
+        return ByteString.copyFrom(mOwnerAccountKey);
+    }
+
+    public void resetDeviceName() {
+        mFastPairSimulatorDatabase.setLocalDeviceName(null);
+        // Trigger simulator to update device name text view.
+        if (mDeviceNameCallback != null) {
+            mDeviceNameCallback.onNameChanged(getDeviceName());
+        }
+    }
+
+    // This method is used in test case with default name in provider.
+    public void setDeviceName(String deviceName) {
+        setDeviceName(deviceName.getBytes(StandardCharsets.UTF_8));
+    }
+
+    private void setDeviceName(@Nullable byte[] deviceName) {
+        mFastPairSimulatorDatabase.setLocalDeviceName(deviceName);
+
+        mLogger.log("Save device name : %s", getDeviceName());
+        // Trigger simulator to update device name text view.
+        if (mDeviceNameCallback != null) {
+            mDeviceNameCallback.onNameChanged(getDeviceName());
+        }
+    }
+
+    @Nullable
+    private byte[] getDeviceNameInBytes() {
+        return mFastPairSimulatorDatabase.getLocalDeviceName();
+    }
+
+    @Nullable
+    public String getDeviceName() {
+        String providerDeviceName =
+                getDeviceNameInBytes() != null
+                        ? new String(getDeviceNameInBytes(), StandardCharsets.UTF_8)
+                        : null;
+        mLogger.log("get device name = %s", providerDeviceName);
+        return providerDeviceName;
+    }
+
+    /**
+     * Bit index: Description - Value
+     *
+     * <ul>
+     *   <li>0-1: Role - 0b10 (Provider only)
+     *   <li>2: Transport Data Incomplete: 0 (false)
+     *   <li>3-4: Transport State (0b00: Off, 0b01: On, 0b10: Temporarily Unavailable)
+     *   <li>5-7: Reserved for future use
+     * </ul>
+     */
+    private static byte tdsFlags(TransportState transportState) {
+        return (byte) (0b00000010 & (transportState.mByteValue << 3));
+    }
+
+    /** Detailed information about battery value. */
+    public static class BatteryValue {
+        boolean mCharging;
+
+        // The range is 0 ~ 100, and -1 represents the battery level is unknown.
+        int mLevel;
+
+        public BatteryValue(boolean charging, int level) {
+            this.mCharging = charging;
+            this.mLevel = level;
+        }
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/FastPairSimulatorDatabase.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/FastPairSimulatorDatabase.java
new file mode 100644
index 0000000..cbe39ff
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/FastPairSimulatorDatabase.java
@@ -0,0 +1,264 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider;
+
+import static com.google.common.io.BaseEncoding.base16;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import androidx.annotation.Nullable;
+
+import com.google.protobuf.ByteString;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/** Stores fast pair related information for each paired device */
+public class FastPairSimulatorDatabase {
+
+    private static final String SHARED_PREF_NAME =
+            "android.nearby.fastpair.provider.fastpairsimulator";
+    private static final String KEY_DEVICE_NAME = "DEVICE_NAME";
+    private static final String KEY_ACCOUNT_KEYS = "ACCOUNT_KEYS";
+    private static final int MAX_NUMBER_OF_ACCOUNT_KEYS = 8;
+
+    // [for SASS]
+    private static final String KEY_FAST_PAIR_SEEKER_DEVICE = "FAST_PAIR_SEEKER_DEVICE";
+
+    private final SharedPreferences mSharedPreferences;
+
+    public FastPairSimulatorDatabase(Context context) {
+        mSharedPreferences = context.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
+    }
+
+    /** Adds single account key. */
+    public void addAccountKey(byte[] accountKey) {
+        if (mSharedPreferences == null) {
+            return;
+        }
+
+        Set<ByteString> accountKeys = new HashSet<>(getAccountKeys());
+        if (accountKeys.size() >= MAX_NUMBER_OF_ACCOUNT_KEYS) {
+            Set<ByteString> removedKeys = new HashSet<>();
+            int removedCount = accountKeys.size() - MAX_NUMBER_OF_ACCOUNT_KEYS + 1;
+            for (ByteString key : accountKeys) {
+                if (removedKeys.size() == removedCount) {
+                    break;
+                }
+                removedKeys.add(key);
+            }
+
+            accountKeys.removeAll(removedKeys);
+        }
+
+        // Just make sure the newest key will not be removed.
+        accountKeys.add(ByteString.copyFrom(accountKey));
+        setAccountKeys(accountKeys);
+    }
+
+    /** Sets account keys, overrides all. */
+    public void setAccountKeys(Set<ByteString> accountKeys) {
+        if (mSharedPreferences == null) {
+            return;
+        }
+
+        Set<String> keys = new HashSet<>();
+        for (ByteString item : accountKeys) {
+            keys.add(base16().encode(item.toByteArray()));
+        }
+
+        mSharedPreferences.edit().putStringSet(KEY_ACCOUNT_KEYS, keys).apply();
+    }
+
+    /** Gets all account keys. */
+    public Set<ByteString> getAccountKeys() {
+        if (mSharedPreferences == null) {
+            return new HashSet<>();
+        }
+
+        Set<String> keys = mSharedPreferences.getStringSet(KEY_ACCOUNT_KEYS, new HashSet<>());
+        Set<ByteString> accountKeys = new HashSet<>();
+        // Add new account keys one by one.
+        for (String key : keys) {
+            accountKeys.add(ByteString.copyFrom(base16().decode(key)));
+        }
+
+        return accountKeys;
+    }
+
+    /** Sets local device name. */
+    public void setLocalDeviceName(byte[] deviceName) {
+        if (mSharedPreferences == null) {
+            return;
+        }
+
+        String humanReadableName = deviceName != null ? new String(deviceName, UTF_8) : null;
+        if (humanReadableName == null) {
+            mSharedPreferences.edit().remove(KEY_DEVICE_NAME).apply();
+        } else {
+            mSharedPreferences.edit().putString(KEY_DEVICE_NAME, humanReadableName).apply();
+        }
+    }
+
+    /** Gets local device name. */
+    @Nullable
+    public byte[] getLocalDeviceName() {
+        if (mSharedPreferences == null) {
+            return null;
+        }
+
+        String deviceName = mSharedPreferences.getString(KEY_DEVICE_NAME, null);
+        return deviceName != null ? deviceName.getBytes(UTF_8) : null;
+    }
+
+    /**
+     * [for SASS] Adds seeker device info. <a
+     * href="http://go/smart-audio-source-switching-design">Sass design doc</a>
+     */
+    public void addFastPairSeekerDevice(@Nullable BluetoothDevice device, byte[] accountKey) {
+        if (mSharedPreferences == null) {
+            return;
+        }
+
+        if (device == null) {
+            return;
+        }
+
+        // When hitting size limitation, choose the existing items to delete.
+        Set<FastPairSeekerDevice> fastPairSeekerDevices = getFastPairSeekerDevices();
+        if (fastPairSeekerDevices.size() > MAX_NUMBER_OF_ACCOUNT_KEYS) {
+            int removedCount = fastPairSeekerDevices.size() - MAX_NUMBER_OF_ACCOUNT_KEYS + 1;
+            Set<FastPairSeekerDevice> removedFastPairDevices = new HashSet<>();
+            for (FastPairSeekerDevice fastPairDevice : fastPairSeekerDevices) {
+                if (removedFastPairDevices.size() == removedCount) {
+                    break;
+                }
+                removedFastPairDevices.add(fastPairDevice);
+            }
+            fastPairSeekerDevices.removeAll(removedFastPairDevices);
+        }
+
+        fastPairSeekerDevices.add(new FastPairSeekerDevice(device, accountKey));
+        setFastPairSeekerDevices(fastPairSeekerDevices);
+    }
+
+    /** [for SASS] Sets all seeker device info, overrides all. */
+    public void setFastPairSeekerDevices(Set<FastPairSeekerDevice> fastPairSeekerDeviceSet) {
+        if (mSharedPreferences == null) {
+            return;
+        }
+
+        Set<String> rawStringSet = new HashSet<>();
+        for (FastPairSeekerDevice item : fastPairSeekerDeviceSet) {
+            rawStringSet.add(item.toRawString());
+        }
+
+        mSharedPreferences.edit().putStringSet(KEY_FAST_PAIR_SEEKER_DEVICE, rawStringSet).apply();
+    }
+
+    /** [for SASS] Gets all seeker device info. */
+    public Set<FastPairSeekerDevice> getFastPairSeekerDevices() {
+        if (mSharedPreferences == null) {
+            return new HashSet<>();
+        }
+
+        Set<FastPairSeekerDevice> fastPairSeekerDevices = new HashSet<>();
+        Set<String> rawStringSet =
+                mSharedPreferences.getStringSet(KEY_FAST_PAIR_SEEKER_DEVICE, new HashSet<>());
+        for (String rawString : rawStringSet) {
+            FastPairSeekerDevice fastPairDevice = FastPairSeekerDevice.fromRawString(rawString);
+            if (fastPairDevice == null) {
+                continue;
+            }
+            fastPairSeekerDevices.add(fastPairDevice);
+        }
+
+        return fastPairSeekerDevices;
+    }
+
+    /** Defines data structure for the paired Fast Pair device. */
+    public static class FastPairSeekerDevice {
+        private static final int INDEX_DEVICE = 0;
+        private static final int INDEX_ACCOUNT_KEY = 1;
+
+        private final BluetoothDevice mDevice;
+        private final byte[] mAccountKey;
+
+        private FastPairSeekerDevice(BluetoothDevice device, byte[] accountKey) {
+            this.mDevice = device;
+            this.mAccountKey = accountKey;
+        }
+
+        public BluetoothDevice getBluetoothDevice() {
+            return mDevice;
+        }
+
+        public byte[] getAccountKey() {
+            return mAccountKey;
+        }
+
+        public String toRawString() {
+            return String.format("%s,%s", mDevice, base16().encode(mAccountKey));
+        }
+
+        /** Decodes the raw string if possible. */
+        @Nullable
+        public static FastPairSeekerDevice fromRawString(String rawString) {
+            BluetoothDevice device = null;
+            byte[] accountKey = null;
+            int step = INDEX_DEVICE;
+
+            StringTokenizer tokenizer = new StringTokenizer(rawString, ",");
+            while (tokenizer.hasMoreElements()) {
+                boolean shouldStop = false;
+                String token = tokenizer.nextToken();
+                switch (step) {
+                    case INDEX_DEVICE:
+                        try {
+                            device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(token);
+                        } catch (IllegalArgumentException e) {
+                            device = null;
+                        }
+                        break;
+                    case INDEX_ACCOUNT_KEY:
+                        accountKey = base16().decode(token);
+                        if (accountKey.length != 16) {
+                            accountKey = null;
+                        }
+                        break;
+                    default:
+                        shouldStop = true;
+                }
+
+                if (shouldStop) {
+                    break;
+                }
+                step++;
+            }
+            if (device != null && accountKey != null) {
+                return new FastPairSeekerDevice(device, accountKey);
+            }
+            return null;
+        }
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/HandshakeRequest.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/HandshakeRequest.java
new file mode 100644
index 0000000..9cfffd8
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/HandshakeRequest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption.decrypt;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.BLUETOOTH_ADDRESS_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.ActionOverBleFlag.ADDITIONAL_DATA_CHARACTERISTIC;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.ActionOverBleFlag.DEVICE_ACTION;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.KeyBasedPairingRequestFlag.PROVIDER_INITIATES_BONDING;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.KeyBasedPairingRequestFlag.REQUEST_DEVICE_NAME;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.KeyBasedPairingRequestFlag.REQUEST_DISCOVERABLE;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.KeyBasedPairingRequestFlag.REQUEST_RETROACTIVE_PAIR;
+import static com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request.ADDITIONAL_DATA_TYPE_INDEX;
+
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.AdditionalDataCharacteristic.AdditionalDataType;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic.Request;
+
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+
+/**
+ * A wrapper for Fast Pair Provider to access decoded handshake request from the Seeker.
+ *
+ * @see {go/fast-pair-early-spec-handshake}
+ */
+public class HandshakeRequest {
+
+    /**
+     * 16 bytes data: 1-byte for type, 1-byte for flags, 6-bytes for provider's BLE address, 8 bytes
+     * optional data.
+     *
+     * @see {go/fast-pair-spec-handshake-message1}
+     */
+    private final byte[] mDecryptedMessage;
+
+    /** Enumerates the handshake message types. */
+    public enum Type {
+        KEY_BASED_PAIRING_REQUEST(Request.TYPE_KEY_BASED_PAIRING_REQUEST),
+        ACTION_OVER_BLE(Request.TYPE_ACTION_OVER_BLE),
+        UNKNOWN((byte) 0xFF);
+
+        private final byte mValue;
+
+        Type(byte type) {
+            mValue = type;
+        }
+
+        public byte getValue() {
+            return mValue;
+        }
+
+        public static Type valueOf(byte value) {
+            for (Type type : Type.values()) {
+                if (type.getValue() == value) {
+                    return type;
+                }
+            }
+            return UNKNOWN;
+        }
+    }
+
+    public HandshakeRequest(byte[] key, byte[] encryptedPairingRequest)
+            throws GeneralSecurityException {
+        mDecryptedMessage = decrypt(key, encryptedPairingRequest);
+    }
+
+    /**
+     * Gets the type of this handshake request. Currently, we have 2 types: 0x00 for Key-based
+     * Pairing Request and 0x10 for Action Request.
+     */
+    public Type getType() {
+        return Type.valueOf(mDecryptedMessage[Request.TYPE_INDEX]);
+    }
+
+    /**
+     * Gets verification data of this handshake request.
+     * Currently, we use Provider's BLE address.
+     */
+    public byte[] getVerificationData() {
+        return Arrays.copyOfRange(
+                mDecryptedMessage,
+                Request.VERIFICATION_DATA_INDEX,
+                Request.VERIFICATION_DATA_INDEX + Request.VERIFICATION_DATA_LENGTH);
+    }
+
+    /** Gets Seeker's public address of the handshake request. */
+    public byte[] getSeekerPublicAddress() {
+        return Arrays.copyOfRange(
+                mDecryptedMessage,
+                Request.SEEKER_PUBLIC_ADDRESS_INDEX,
+                Request.SEEKER_PUBLIC_ADDRESS_INDEX + BLUETOOTH_ADDRESS_LENGTH);
+    }
+
+    /** Checks whether the Seeker request discoverability from flags byte. */
+    public boolean requestDiscoverable() {
+        return (getFlags() & REQUEST_DISCOVERABLE) != 0;
+    }
+
+    /**
+     * Checks whether the Seeker requests that the Provider shall initiate bonding from flags byte.
+     */
+    public boolean requestProviderInitialBonding() {
+        return (getFlags() & PROVIDER_INITIATES_BONDING) != 0;
+    }
+
+    /** Checks whether the Seeker requests that the Provider shall notify the existing name. */
+    public boolean requestDeviceName() {
+        return (getFlags() & REQUEST_DEVICE_NAME) != 0;
+    }
+
+    /** Checks whether this is for retroactively writing account key. */
+    public boolean requestRetroactivePair() {
+        return (getFlags() & REQUEST_RETROACTIVE_PAIR) != 0;
+    }
+
+    /** Gets the flags of this handshake request. */
+    private byte getFlags() {
+        return mDecryptedMessage[Request.FLAGS_INDEX];
+    }
+
+    /** Checks whether the Seeker requests a device action. */
+    public boolean requestDeviceAction() {
+        return (getFlags() & DEVICE_ACTION) != 0;
+    }
+
+    /**
+     * Checks whether the Seeker requests an action which will be followed by an additional data
+     * .
+     */
+    public boolean requestFollowedByAdditionalData() {
+        return (getFlags() & ADDITIONAL_DATA_CHARACTERISTIC) != 0;
+    }
+
+    /** Gets the {@link AdditionalDataType} of this handshake request. */
+    @AdditionalDataType
+    public int getAdditionalDataType() {
+        if (!requestFollowedByAdditionalData()
+                || mDecryptedMessage.length <= ADDITIONAL_DATA_TYPE_INDEX) {
+            return AdditionalDataType.UNKNOWN;
+        }
+        return mDecryptedMessage[ADDITIONAL_DATA_TYPE_INDEX];
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/OreoFastPairAdvertiser.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/OreoFastPairAdvertiser.java
new file mode 100644
index 0000000..bc0cdfe
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/OreoFastPairAdvertiser.java
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider;
+
+import static com.google.common.io.BaseEncoding.base16;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.AdvertisingSet;
+import android.bluetooth.le.AdvertisingSetCallback;
+import android.bluetooth.le.AdvertisingSetParameters;
+import android.bluetooth.le.BluetoothLeAdvertiser;
+import android.nearby.fastpair.provider.utils.Logger;
+import android.os.ParcelUuid;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
+/** Fast Pair advertiser taking advantage of new Android Oreo advertising features. */
+public final class OreoFastPairAdvertiser implements FastPairAdvertiser {
+    private static final String TAG = "OreoFastPairAdvertiser";
+    private final Logger mLogger = new Logger(TAG);
+
+    private final FastPairSimulator mSimulator;
+    private final BluetoothLeAdvertiser mAdvertiser;
+    private final AdvertisingSetCallback mAdvertisingSetCallback;
+    private AdvertisingSet mAdvertisingSet;
+
+    public OreoFastPairAdvertiser(FastPairSimulator simulator) {
+        this.mSimulator = simulator;
+        this.mAdvertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
+        this.mAdvertisingSetCallback = new AdvertisingSetCallback() {
+
+            @Override
+            public void onAdvertisingSetStarted(
+                    AdvertisingSet set, int txPower, int status) {
+                if (status == AdvertisingSetCallback.ADVERTISE_SUCCESS) {
+                    mLogger.log("Advertising succeeded, advertising at %s dBm", txPower);
+                    simulator.setIsAdvertising(true);
+                    mAdvertisingSet = set;
+                    mAdvertisingSet.getOwnAddress();
+                } else {
+                    mLogger.log(
+                            new IllegalStateException(),
+                            "Advertising failed, error code=%d", status);
+                }
+            }
+
+            @Override
+            public void onAdvertisingDataSet(AdvertisingSet set, int status) {
+                if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
+                    mLogger.log(
+                            new IllegalStateException(),
+                            "Updating advertisement failed, error code=%d",
+                            status);
+                    stopAdvertising();
+                }
+            }
+
+            // Callback for AdvertisingSet.getOwnAddress().
+            @Override
+            public void onOwnAddressRead(
+                    AdvertisingSet set, int addressType, String address) {
+                if (!address.equals(simulator.getBleAddress())) {
+                    mLogger.log(
+                            "Read own BLE address=%s at %s",
+                            address,
+                            new SimpleDateFormat("HH:mm:ss:SSS", Locale.US)
+                                    .format(Calendar.getInstance().getTime()));
+                    // Implicitly start the advertising once BLE address callback arrived.
+                    simulator.setBleAddress(address);
+                }
+            }
+        };
+    }
+
+    @Override
+    public void startAdvertising(@Nullable byte[] serviceData) {
+        // To be informed that BLE address is rotated, we need to polling query it asynchronously.
+        if (mAdvertisingSet != null) {
+            mAdvertisingSet.getOwnAddress();
+        }
+
+        if (mSimulator.isDestroyed()) {
+            return;
+        }
+
+        if (serviceData == null) {
+            mLogger.log("Service data is null, stop advertising");
+            stopAdvertising();
+            return;
+        }
+
+        AdvertiseData data =
+                new AdvertiseData.Builder()
+                        .addServiceData(new ParcelUuid(FastPairService.ID), serviceData)
+                        .setIncludeTxPowerLevel(true)
+                        .build();
+
+        mLogger.log("Advertising FE2C service data=%s", base16().encode(serviceData));
+
+        if (mAdvertisingSet != null) {
+            mAdvertisingSet.setAdvertisingData(data);
+            return;
+        }
+
+        stopAdvertising();
+        AdvertisingSetParameters parameters =
+                new AdvertisingSetParameters.Builder()
+                        .setLegacyMode(true)
+                        .setConnectable(true)
+                        .setScannable(true)
+                        .setInterval(AdvertisingSetParameters.INTERVAL_LOW)
+                        .setTxPowerLevel(convertAdvertiseSettingsTxPower(mSimulator.getTxPower()))
+                        .build();
+        mAdvertiser.startAdvertisingSet(parameters, data, null, null, null,
+                mAdvertisingSetCallback);
+    }
+
+    private static int convertAdvertiseSettingsTxPower(int txPower) {
+        switch (txPower) {
+            case AdvertiseSettings.ADVERTISE_TX_POWER_ULTRA_LOW:
+                return AdvertisingSetParameters.TX_POWER_ULTRA_LOW;
+            case AdvertiseSettings.ADVERTISE_TX_POWER_LOW:
+                return AdvertisingSetParameters.TX_POWER_LOW;
+            case AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM:
+                return AdvertisingSetParameters.TX_POWER_MEDIUM;
+            default:
+                return AdvertisingSetParameters.TX_POWER_HIGH;
+        }
+    }
+
+    @Override
+    public void stopAdvertising() {
+        if (mSimulator.isDestroyed()) {
+            return;
+        }
+
+        mAdvertiser.stopAdvertisingSet(mAdvertisingSetCallback);
+        mAdvertisingSet = null;
+        mSimulator.setIsAdvertising(false);
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothController.kt b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothController.kt
new file mode 100644
index 0000000..0cc0c92
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothController.kt
@@ -0,0 +1,276 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.bluetooth
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothManager
+import android.bluetooth.BluetoothProfile
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.nearby.fastpair.provider.FastPairSimulator
+import android.nearby.fastpair.provider.utils.Logger
+import android.os.SystemClock
+import android.provider.Settings
+
+/** Controls the local Bluetooth adapter for Fast Pair testing. */
+class BluetoothController(
+    private val context: Context,
+    private val listener: EventListener
+) : BroadcastReceiver() {
+    private val mLogger = Logger(TAG)
+    private val bluetoothAdapter: BluetoothAdapter =
+        (context.getSystemService(Context.BLUETOOTH_SERVICE) as? BluetoothManager)?.adapter!!
+    private var remoteDevice: BluetoothDevice? = null
+    private var remoteDeviceConnectionState: Int = BluetoothAdapter.STATE_DISCONNECTED
+    private var a2dpSinkProxy: BluetoothProfile? = null
+
+    /** Turns on the local Bluetooth adapter */
+    fun enableBluetooth() {
+        if (!bluetoothAdapter.isEnabled) {
+            bluetoothAdapter.enable()
+            waitForBluetoothState(BluetoothAdapter.STATE_ON)
+        }
+    }
+
+    /**
+     * Sets the Input/Output capability of the device for both classic Bluetooth and BLE operations.
+     * Note: In order to let changes take effect, this method will make sure the Bluetooth stack is
+     * restarted by blocking calling thread.
+     *
+     * @param ioCapabilityClassic One of {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_NONE},
+     * ```
+     *     {@link #IO_CAPABILITY_KBDISP} or more in {@link BluetoothAdapter}.
+     * @param ioCapabilityBLE
+     * ```
+     * One of {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_NONE}, {@link
+     * ```
+     *     #IO_CAPABILITY_KBDISP} or more in {@link BluetoothAdapter}.
+     * ```
+     */
+    fun setIoCapability(ioCapabilityClassic: Int, ioCapabilityBLE: Int) {
+        bluetoothAdapter.ioCapability = ioCapabilityClassic
+        bluetoothAdapter.leIoCapability = ioCapabilityBLE
+
+        // Toggling airplane mode on/off to restart Bluetooth stack and reset the BLE.
+        try {
+            Settings.Global.putInt(
+                context.contentResolver,
+                Settings.Global.AIRPLANE_MODE_ON,
+                TURN_AIRPLANE_MODE_ON
+            )
+        } catch (expectedOnNonCustomAndroid: SecurityException) {
+            mLogger.log(
+                expectedOnNonCustomAndroid,
+                "Requires custom Android to toggle airplane mode"
+            )
+            // Fall back to turn off Bluetooth.
+            bluetoothAdapter.disable()
+        }
+        waitForBluetoothState(BluetoothAdapter.STATE_OFF)
+        try {
+            Settings.Global.putInt(
+                context.contentResolver,
+                Settings.Global.AIRPLANE_MODE_ON,
+                TURN_AIRPLANE_MODE_OFF
+            )
+        } catch (expectedOnNonCustomAndroid: SecurityException) {
+            mLogger.log(
+                expectedOnNonCustomAndroid,
+                "SecurityException while toggled airplane mode."
+            )
+        } finally {
+            // Double confirm that Bluetooth is turned on.
+            bluetoothAdapter.enable()
+        }
+        waitForBluetoothState(BluetoothAdapter.STATE_ON)
+    }
+
+    /** Registers this Bluetooth state change receiver. */
+    fun registerBluetoothStateReceiver() {
+        val bondStateFilter =
+            IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED).apply {
+                addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)
+                addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)
+            }
+        context.registerReceiver(
+            this,
+            bondStateFilter,
+            /* broadcastPermission= */ null,
+            /* scheduler= */ null
+        )
+    }
+
+    /** Unregisters this Bluetooth state change receiver. */
+    fun unregisterBluetoothStateReceiver() {
+        context.unregisterReceiver(this)
+    }
+
+    /** Clears current remote device. */
+    fun clearRemoteDevice() {
+        remoteDevice = null
+    }
+
+    /** Gets current remote device. */
+    fun getRemoteDevice(): BluetoothDevice? = remoteDevice
+
+    /** Gets current remote device as string. */
+    fun getRemoteDeviceAsString(): String = remoteDevice?.remoteDeviceToString() ?: "none"
+
+    /** Connects the Bluetooth A2DP sink profile service. */
+    fun connectA2DPSinkProfile() {
+        // Get the A2DP proxy before continuing with initialization.
+        bluetoothAdapter.getProfileProxy(
+            context,
+            object : BluetoothProfile.ServiceListener {
+                override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
+                    // When Bluetooth turns off and then on again, this is called again. But we only care
+                    // the first time. There doesn't seem to be a way to unregister our listener.
+                    if (a2dpSinkProxy == null) {
+                        a2dpSinkProxy = proxy
+                        listener.onA2DPSinkProfileConnected()
+                    }
+                }
+
+                override fun onServiceDisconnected(profile: Int) {}
+            },
+            BluetoothProfile.A2DP_SINK
+        )
+    }
+
+    /** Get the current Bluetooth scan mode of the local Bluetooth adapter. */
+    fun getScanMode(): Int = bluetoothAdapter.scanMode
+
+    /** Return true if the remote device is connected to the local adapter. */
+    fun isConnected(): Boolean = remoteDeviceConnectionState == BluetoothAdapter.STATE_CONNECTED
+
+    /** Return true if the remote device is bonded (paired) to the local adapter. */
+    fun isPaired(): Boolean = bluetoothAdapter.bondedDevices.contains(remoteDevice)
+
+    /** Gets the A2DP sink profile proxy. */
+    fun getA2DPSinkProfileProxy(): BluetoothProfile? = a2dpSinkProxy
+
+    /**
+     * Callback method for receiving Intent broadcast of Bluetooth state.
+     *
+     * See [BroadcastReceiver#onReceive].
+     *
+     * @param context the Context in which the receiver is running.
+     * @param intent the Intent being received.
+     */
+    override fun onReceive(context: Context, intent: Intent) {
+        when (intent.action) {
+            BluetoothDevice.ACTION_BOND_STATE_CHANGED -> {
+                // After a device starts bonding, we only pay attention to intents about that device.
+                val device =
+                    intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
+                val bondState =
+                    intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR)
+                remoteDevice =
+                    when (bondState) {
+                        BluetoothDevice.BOND_BONDING, BluetoothDevice.BOND_BONDED -> device
+                        BluetoothDevice.BOND_NONE -> null
+                        else -> remoteDevice
+                    }
+                mLogger.log(
+                    "ACTION_BOND_STATE_CHANGED, the bound state of " +
+                            "the remote device (%s) change to %s.",
+                    remoteDevice?.remoteDeviceToString(),
+                    bondState.bondStateToString()
+                )
+                listener.onBondStateChanged(bondState)
+            }
+            BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED -> {
+                remoteDeviceConnectionState =
+                    intent.getIntExtra(
+                        BluetoothAdapter.EXTRA_CONNECTION_STATE,
+                        BluetoothAdapter.STATE_DISCONNECTED
+                    )
+                mLogger.log(
+                    "ACTION_CONNECTION_STATE_CHANGED, the new connectionState: %s",
+                    remoteDeviceConnectionState
+                )
+                listener.onConnectionStateChanged(remoteDeviceConnectionState)
+            }
+            BluetoothAdapter.ACTION_SCAN_MODE_CHANGED -> {
+                val scanMode =
+                    intent.getIntExtra(
+                        BluetoothAdapter.EXTRA_SCAN_MODE,
+                        BluetoothAdapter.SCAN_MODE_NONE
+                    )
+                mLogger.log(
+                    "ACTION_SCAN_MODE_CHANGED, the new scanMode: %s",
+                    FastPairSimulator.scanModeToString(scanMode)
+                )
+                listener.onScanModeChange(scanMode)
+            }
+            else -> {}
+        }
+    }
+
+    private fun waitForBluetoothState(state: Int) {
+        while (bluetoothAdapter.state != state) {
+            SystemClock.sleep(1000)
+        }
+    }
+
+    private fun BluetoothDevice.remoteDeviceToString(): String = "${this.name}-${this.address}"
+
+    private fun Int.bondStateToString(): String =
+        when (this) {
+            BluetoothDevice.BOND_NONE -> "BOND_NONE"
+            BluetoothDevice.BOND_BONDING -> "BOND_BONDING"
+            BluetoothDevice.BOND_BONDED -> "BOND_BONDED"
+            else -> "BOND_ERROR"
+        }
+
+    /** Interface for listening the events from Bluetooth controller. */
+    interface EventListener {
+        /** The callback for the first onServiceConnected of A2DP sink profile. */
+        fun onA2DPSinkProfileConnected()
+
+        /**
+         * Reports the current bond state of the remote device.
+         *
+         * @param bondState the bond state of the remote device.
+         */
+        fun onBondStateChanged(bondState: Int)
+
+        /**
+         * Reports the current connection state of the remote device.
+         *
+         * @param connectionState the bond state of the remote device.
+         */
+        fun onConnectionStateChanged(connectionState: Int)
+
+        /**
+         * Reports the current scan mode of the local Adapter.
+         *
+         * @param mode the current scan mode of the local Adapter.
+         */
+        fun onScanModeChange(mode: Int)
+    }
+
+    companion object {
+        private const val TAG = "BluetoothController"
+
+        private const val TURN_AIRPLANE_MODE_OFF = 0
+        private const val TURN_AIRPLANE_MODE_ON = 1
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServerConfig.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServerConfig.java
new file mode 100644
index 0000000..3cacd55
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServerConfig.java
@@ -0,0 +1,151 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.bluetooth;
+
+import android.annotation.TargetApi;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattService;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.bluetooth.BluetoothConsts;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+/** Configuration of a GATT server. */
+@TargetApi(18)
+public class BluetoothGattServerConfig {
+    private final Map<UUID, ServiceConfig> mServiceConfigs = new HashMap<UUID, ServiceConfig>();
+
+    @Nullable
+    private BluetoothGattServerHelper.Listener mServerlistener = null;
+
+    public BluetoothGattServerConfig addService(UUID uuid, ServiceConfig serviceConfig) {
+        mServiceConfigs.put(uuid, serviceConfig);
+        return this;
+    }
+
+    public BluetoothGattServerConfig setServerConnectionListener(
+            BluetoothGattServerHelper.Listener listener) {
+        mServerlistener = listener;
+        return this;
+    }
+
+    @Nullable
+    public BluetoothGattServerHelper.Listener getServerListener() {
+        return mServerlistener;
+    }
+
+    /**
+     * Adds a service and a characteristic to indicate that the server has dynamic services.
+     * This is a workaround for b/21587710.
+     * TODO(lingjunl): remove them when b/21587710 is fixed.
+     */
+    public BluetoothGattServerConfig addSelfDefinedDynamicService() {
+        ServiceConfig serviceConfig = new ServiceConfig().addCharacteristic(
+                new BluetoothGattServlet() {
+                    @Override
+                    public BluetoothGattCharacteristic getCharacteristic() {
+                        return new BluetoothGattCharacteristic(
+                                BluetoothConsts.SERVICE_DYNAMIC_CHARACTERISTIC,
+                                BluetoothGattCharacteristic.PROPERTY_READ,
+                                BluetoothGattCharacteristic.PERMISSION_READ);
+                    }
+                });
+        return addService(BluetoothConsts.SERVICE_DYNAMIC_SERVICE, serviceConfig);
+    }
+
+    public List<BluetoothGattService> getBluetoothGattServices() {
+        List<BluetoothGattService> result = new ArrayList<BluetoothGattService>();
+        for (Entry<UUID, ServiceConfig> serviceEntry : mServiceConfigs.entrySet()) {
+            UUID serviceUuid = serviceEntry.getKey();
+            ServiceConfig serviceConfig = serviceEntry.getValue();
+            if (serviceUuid == null || serviceConfig == null) {
+                // This is not supposed to happen
+                throw new IllegalStateException();
+            }
+            BluetoothGattService gattService = new BluetoothGattService(serviceUuid,
+                    BluetoothGattService.SERVICE_TYPE_PRIMARY);
+            for (Entry<BluetoothGattCharacteristic, BluetoothGattServlet> servletEntry :
+                    serviceConfig.getServlets().entrySet()) {
+                BluetoothGattCharacteristic characteristic = servletEntry.getKey();
+                if (characteristic == null) {
+                    // This is not supposed to happen
+                    throw new IllegalStateException();
+                }
+                gattService.addCharacteristic(characteristic);
+            }
+            result.add(gattService);
+        }
+        return result;
+    }
+
+    public List<UUID> getAdvertisedUuids() {
+        List<UUID> result = new ArrayList<UUID>();
+        for (Entry<UUID, ServiceConfig> serviceEntry : mServiceConfigs.entrySet()) {
+            UUID serviceUuid = serviceEntry.getKey();
+            ServiceConfig serviceConfig = serviceEntry.getValue();
+            if (serviceUuid == null || serviceConfig == null) {
+                // This is not supposed to happen
+                throw new IllegalStateException();
+            }
+            if (serviceConfig.isAdvertised()) {
+                result.add(serviceUuid);
+            }
+        }
+        return result;
+    }
+
+    public Map<BluetoothGattCharacteristic, BluetoothGattServlet> getServlets() {
+        Map<BluetoothGattCharacteristic, BluetoothGattServlet> result =
+                new HashMap<BluetoothGattCharacteristic, BluetoothGattServlet>();
+        for (ServiceConfig serviceConfig : mServiceConfigs.values()) {
+            result.putAll(serviceConfig.getServlets());
+        }
+        return result;
+    }
+
+    /** Configuration of a GATT service. */
+    public static class ServiceConfig {
+        private final Map<BluetoothGattCharacteristic, BluetoothGattServlet> mServlets =
+                new HashMap<BluetoothGattCharacteristic, BluetoothGattServlet>();
+        private boolean mAdvertise = false;
+
+        public ServiceConfig addCharacteristic(BluetoothGattServlet servlet) {
+            mServlets.put(servlet.getCharacteristic(), servlet);
+            return this;
+        }
+
+        public ServiceConfig setAdvertise(boolean advertise) {
+            mAdvertise = advertise;
+            return this;
+        }
+
+        public Map<BluetoothGattCharacteristic, BluetoothGattServlet> getServlets() {
+            return mServlets;
+        }
+
+        public boolean isAdvertised() {
+            return mAdvertise;
+        }
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServerConnection.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServerConnection.java
new file mode 100644
index 0000000..fae6951
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServerConnection.java
@@ -0,0 +1,468 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.bluetooth;
+
+import android.annotation.TargetApi;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.ReservedUuids;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.Operation;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.io.BaseEncoding;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Connection to a bluetooth LE device over Gatt.
+ */
+@TargetApi(18)
+public class BluetoothGattServerConnection implements Closeable {
+    @SuppressWarnings("unused")
+    private static final String TAG = BluetoothGattServerConnection.class.getSimpleName();
+
+    /** See {@link BluetoothGattDescriptor#DISABLE_NOTIFICATION_VALUE}. */
+    private static final short DISABLE_NOTIFICATION_VALUE = 0x0000;
+
+    /** See {@link BluetoothGattDescriptor#ENABLE_NOTIFICATION_VALUE}. */
+    private static final short ENABLE_NOTIFICATION_VALUE = 0x0001;
+
+    /** See {@link BluetoothGattDescriptor#ENABLE_INDICATION_VALUE}. */
+    private static final short ENABLE_INDICATION_VALUE = 0x0002;
+
+    /** Default MTU when value is unknown. */
+    public static final int DEFAULT_MTU = 23;
+
+    @VisibleForTesting
+    static final long OPERATION_TIMEOUT = TimeUnit.SECONDS.toMillis(1);
+
+    /** Notification types as defined by the BLE spec vol 4, sec G, part 3.3.3.3 */
+    public enum NotificationType {
+        NOTIFICATION,
+        INDICATION
+    }
+
+    /** BT operation types that can be in flight. */
+    public enum OperationType {
+        SEND_NOTIFICATION
+    }
+
+    private final Map<ScopedKey, Object> mContextValues = new HashMap<ScopedKey, Object>();
+    private final List<Listener> mCloseListeners = new ArrayList<Listener>();
+
+    private final BluetoothGattServerHelper mBluetoothGattServerHelper;
+    private final BluetoothDevice mBluetoothDevice;
+
+    @VisibleForTesting
+    BluetoothOperationExecutor mBluetoothOperationScheduler =
+            new BluetoothOperationExecutor(1);
+
+    /** Stores pending writes. For each UUID, we store an offset and a byte[] of data. */
+    @VisibleForTesting
+    final Map<BluetoothGattServlet, SortedMap<Integer, byte[]>> mQueuedCharacteristicWrites =
+            new HashMap<BluetoothGattServlet, SortedMap<Integer, byte[]>>();
+
+    @VisibleForTesting
+    final Map<BluetoothGattCharacteristic, Notifier> mRegisteredNotifications =
+            new HashMap<BluetoothGattCharacteristic, Notifier>();
+
+    private final Map<BluetoothGattCharacteristic, BluetoothGattServlet> mServlets;
+
+    public BluetoothGattServerConnection(
+            BluetoothGattServerHelper bluetoothGattServerHelper,
+            BluetoothDevice device,
+            BluetoothGattServerConfig serverConfig) {
+        mBluetoothGattServerHelper = bluetoothGattServerHelper;
+        mBluetoothDevice = device;
+        mServlets = serverConfig.getServlets();
+    }
+
+    public void setContextValue(Object scope, String key, @Nullable Object value) {
+        mContextValues.put(new ScopedKey(scope, key), value);
+    }
+
+    @Nullable
+    public Object getContextValue(Object scope, String key) {
+        return mContextValues.get(new ScopedKey(scope, key));
+    }
+
+    public BluetoothDevice getDevice() {
+        return mBluetoothDevice;
+    }
+
+    public int getMtu() {
+        return DEFAULT_MTU;
+    }
+
+    public int getMaxDataPacketSize() {
+        // Per BT specs (3.2.9), only MTU - 3 bytes can be used to transmit data
+        return getMtu() - 3;
+    }
+
+    public void addCloseListener(Listener listener) {
+        synchronized (mCloseListeners) {
+            mCloseListeners.add(listener);
+        }
+    }
+
+    public void removeCloseListener(Listener listener) {
+        synchronized (mCloseListeners) {
+            mCloseListeners.remove(listener);
+        }
+    }
+
+    private BluetoothGattServlet getServlet(BluetoothGattCharacteristic characteristic)
+            throws BluetoothGattException {
+        BluetoothGattServlet servlet = mServlets.get(characteristic);
+        if (servlet == null) {
+            throw new BluetoothGattException(
+                    String.format("No handler registered for characteristic %s.",
+                            characteristic.getUuid()),
+                    BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+        }
+        return servlet;
+    }
+
+    public byte[] readCharacteristic(int offset, BluetoothGattCharacteristic characteristic)
+            throws BluetoothGattException {
+        return getServlet(characteristic).read(this, offset);
+    }
+
+    public void writeCharacteristic(BluetoothGattCharacteristic characteristic,
+            boolean preparedWrite,
+            int offset, byte[] value) throws BluetoothGattException {
+        Log.d(TAG, String.format(
+                "Received %d bytes at offset %d on %s from device %s, prepareWrite=%s.",
+                value.length,
+                offset,
+                BluetoothGattUtils.toString(characteristic),
+                mBluetoothDevice,
+                preparedWrite));
+        BluetoothGattServlet servlet = getServlet(characteristic);
+        if (preparedWrite) {
+            SortedMap<Integer, byte[]> bytePackets = mQueuedCharacteristicWrites.get(servlet);
+            if (bytePackets == null) {
+                bytePackets = new TreeMap<Integer, byte[]>();
+                mQueuedCharacteristicWrites.put(servlet, bytePackets);
+            }
+            bytePackets.put(offset, value);
+            return;
+        }
+
+        Log.d(TAG, servlet.toString());
+        servlet.write(this, offset, value);
+    }
+
+    public byte[] readDescriptor(int offset, BluetoothGattDescriptor descriptor)
+            throws BluetoothGattException {
+        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
+        if (characteristic == null) {
+            throw new BluetoothGattException(String.format(
+                    "Descriptor %s not associated with a characteristics!",
+                    BluetoothGattUtils.toString(descriptor)), BluetoothGatt.GATT_FAILURE);
+        }
+        return getServlet(characteristic).readDescriptor(this, descriptor, offset);
+    }
+
+    public void writeDescriptor(
+            BluetoothGattDescriptor descriptor,
+            boolean preparedWrite,
+            int offset,
+            byte[] value) throws BluetoothGattException {
+        Log.d(TAG, String.format(
+                "Received %d bytes at offset %d on %s from device %s, prepareWrite=%s.",
+                value.length,
+                offset,
+                BluetoothGattUtils.toString(descriptor),
+                mBluetoothDevice,
+                preparedWrite));
+        if (preparedWrite) {
+            throw new BluetoothGattException(
+                    String.format("Prepare write not supported for descriptor %s.", descriptor),
+                    BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+        }
+
+        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
+        if (characteristic == null) {
+            throw new BluetoothGattException(String.format(
+                    "Descriptor %s not associated with a characteristics!",
+                    BluetoothGattUtils.toString(descriptor)), BluetoothGatt.GATT_FAILURE);
+        }
+        BluetoothGattServlet servlet = getServlet(characteristic);
+        if (descriptor.getUuid().equals(
+                ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION)) {
+            handleCharacteristicConfigurationChange(characteristic, servlet, offset, value);
+            return;
+        }
+        servlet.writeDescriptor(this, descriptor, offset, value);
+    }
+
+    private void handleCharacteristicConfigurationChange(
+            final BluetoothGattCharacteristic characteristic, BluetoothGattServlet servlet,
+            int offset,
+            byte[] value)
+            throws BluetoothGattException {
+        if (offset != 0) {
+            throw new BluetoothGattException(String.format(
+                    "Offset should be 0 when changing the client characteristic config: %d.",
+                    offset),
+                    BluetoothGatt.GATT_INVALID_OFFSET);
+        }
+        if (value.length != 2) {
+            throw new BluetoothGattException(String.format(
+                    "Value 0x%s is undefined for the client characteristic config",
+                    BaseEncoding.base16().encode(value)),
+                    BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH);
+        }
+
+        boolean notificationRegistered = mRegisteredNotifications.containsKey(characteristic);
+        Notifier notifier;
+        switch (toShort(value)) {
+            case ENABLE_NOTIFICATION_VALUE:
+                if (!notificationRegistered) {
+                    notifier = new Notifier() {
+                        @Override
+                        public void notify(byte[] data) throws BluetoothException {
+                            sendNotification(characteristic, NotificationType.NOTIFICATION, data);
+                        }
+                    };
+                    mRegisteredNotifications.put(characteristic, notifier);
+                    servlet.enableNotification(this, notifier);
+                }
+                break;
+            case ENABLE_INDICATION_VALUE:
+                if (!notificationRegistered) {
+                    notifier = new Notifier() {
+                        @Override
+                        public void notify(byte[] data) throws BluetoothException {
+                            sendNotification(characteristic, NotificationType.INDICATION, data);
+                        }
+                    };
+                    mRegisteredNotifications.put(characteristic, notifier);
+                    servlet.enableNotification(this, notifier);
+                }
+                break;
+            case DISABLE_NOTIFICATION_VALUE:
+                // Note: this disables notifications or indications.
+                if (notificationRegistered) {
+                    notifier = mRegisteredNotifications.remove(characteristic);
+                    if (notifier == null) {
+                        return; // this is not supposed to happen
+                    }
+                    servlet.disableNotification(this, notifier);
+                }
+                break;
+            default:
+                throw new BluetoothGattException(String.format(
+                        "Value 0x%s is undefined for the client characteristic config",
+                        BaseEncoding.base16().encode(value)),
+                        BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+        }
+    }
+
+    private static short toShort(byte[] value) {
+        Preconditions.checkNotNull(value);
+        Preconditions.checkArgument(value.length == 2, "Length should be 2 bytes.");
+
+        return (short) ((value[0] & 0x00FF) | (value[1] << 8));
+    }
+
+    public void executeWrite(boolean execute) throws BluetoothGattException {
+        if (!execute) {
+            mQueuedCharacteristicWrites.clear();
+            return;
+        }
+
+        try {
+            for (Entry<BluetoothGattServlet, SortedMap<Integer, byte[]>> queuedWrite :
+                    mQueuedCharacteristicWrites.entrySet()) {
+                BluetoothGattServlet servlet = queuedWrite.getKey();
+                SortedMap<Integer, byte[]> chunks = queuedWrite.getValue();
+                if (servlet == null || chunks == null) {
+                    // This is not supposed to happen
+                    throw new IllegalStateException();
+                }
+                assembleByteChunksAndHandle(servlet, chunks);
+            }
+        } finally {
+            mQueuedCharacteristicWrites.clear();
+        }
+    }
+
+    /**
+     * Assembles the specified queued writes and calls the provided write handler on the assembled
+     * chunks. Tries to assemble all the chunks into one write request. For example, if the content
+     * of byteChunks is:
+     * <code>
+     * offset data_size
+     * 0       10
+     * 10        1
+     * 11        5
+     * </code>
+     *
+     * then this method would call <code>writeHandler.onWrite(0, byte[16])</code>
+     *
+     * However, if all the chunks cannot be assembled into a continuous byte[], then onWrite() will
+     * be called multiple times with the largest continuous chunks. For example, if the content of
+     * byteChunks is:
+     * <code>
+     * offset data_size
+     * 10       12
+     * 30        5
+     * 35        9
+     * </code>
+     *
+     * then this method would call <code>writeHandler.onWrite(10, byte[12)</code> and
+     * <code>writeHandler.onWrite(30, byte[14]).
+     */
+    private void assembleByteChunksAndHandle(BluetoothGattServlet servlet,
+            SortedMap<Integer, byte[]> byteChunks) throws BluetoothGattException {
+        ByteArrayOutputStream assembledRequest = new ByteArrayOutputStream();
+        Integer startWritingAtOffset = 0;
+
+        while (!byteChunks.isEmpty()) {
+            Integer offset = byteChunks.firstKey();
+
+            if (offset.intValue() < startWritingAtOffset + assembledRequest.size()) {
+                throw new BluetoothGattException(
+                        "Expected offset of at least " + assembledRequest.size()
+                                + ", but got offset " + offset, BluetoothGatt.GATT_INVALID_OFFSET);
+            }
+
+            // If we have a hole, then write what we've already assembled and start assembling a new
+            // long write
+            if (offset.intValue() > startWritingAtOffset + assembledRequest.size()) {
+                servlet.write(this, startWritingAtOffset.intValue(),
+                        assembledRequest.toByteArray());
+                startWritingAtOffset = offset;
+                assembledRequest.reset();
+            }
+
+            try {
+                byte[] dataChunk = byteChunks.remove(offset);
+                if (dataChunk == null) {
+                    // This is not supposed to happen
+                    throw new IllegalStateException();
+                }
+                assembledRequest.write(dataChunk);
+            } catch (IOException e) {
+                throw new BluetoothGattException("Error assembling request",
+                        BluetoothGatt.GATT_FAILURE);
+            }
+        }
+
+        // If there is anything to write, write it
+        if (assembledRequest.size() > 0) {
+            Preconditions.checkNotNull(startWritingAtOffset); // should never be null at this point
+            servlet.write(this, startWritingAtOffset.intValue(), assembledRequest.toByteArray());
+        }
+    }
+
+    private void sendNotification(final BluetoothGattCharacteristic characteristic,
+            final NotificationType notificationType, final byte[] data)
+            throws BluetoothException {
+        mBluetoothOperationScheduler.execute(
+                new Operation<Void>(OperationType.SEND_NOTIFICATION) {
+                    @Override
+                    public void run() throws BluetoothException {
+                        mBluetoothGattServerHelper.sendNotification(mBluetoothDevice,
+                                characteristic,
+                                data,
+                                notificationType == NotificationType.INDICATION ? true : false);
+                    }
+                },
+                OPERATION_TIMEOUT);
+    }
+
+    @Override
+    public void close() throws IOException {
+        try {
+            mBluetoothGattServerHelper.closeConnection(mBluetoothDevice);
+        } catch (BluetoothException e) {
+            throw new IOException("Failed to close connection", e);
+        }
+    }
+
+    public void notifyNotificationSent(int status) {
+        mBluetoothOperationScheduler.notifyCompletion(
+                new Operation<Void>(OperationType.SEND_NOTIFICATION), status);
+    }
+
+    public void onClose() {
+        synchronized (mCloseListeners) {
+            for (Listener listener : mCloseListeners) {
+                listener.onClose();
+            }
+        }
+    }
+
+    /** Scope/key pair to use to reference contextual values. */
+    private static class ScopedKey {
+        private final Object mScope;
+        private final String mKey;
+
+        ScopedKey(Object scope, String key) {
+            mScope = scope;
+            mKey = key;
+        }
+
+        @Override
+        public boolean equals(@Nullable Object o) {
+            if (!(o instanceof ScopedKey)) {
+                return false;
+            }
+            ScopedKey other = (ScopedKey) o;
+            return other.mScope.equals(mScope) && other.mKey.equals(mKey);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(mScope, mKey);
+        }
+    }
+
+    /** Listener to be notified when the connection closes. */
+    public interface Listener {
+        void onClose();
+    }
+
+    /** Notifier to notify data over notification or indication. */
+    public interface Notifier {
+        void notify(byte[] data) throws BluetoothException;
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServerHelper.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServerHelper.java
new file mode 100644
index 0000000..9339e14
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServerHelper.java
@@ -0,0 +1,449 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.bluetooth;
+
+import android.annotation.TargetApi;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.os.Build.VERSION_CODES;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.testability.VersionProvider;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattServer;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattServerCallback;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.Operation;
+
+import com.google.common.base.Preconditions;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Helper for simplifying operations on {@link BluetoothGattServer}.
+ */
+@TargetApi(18)
+public class BluetoothGattServerHelper {
+    private static final String TAG = BluetoothGattServerHelper.class.getSimpleName();
+
+    @VisibleForTesting
+    static final long OPERATION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(1);
+    private static final int MAX_PARALLEL_OPERATIONS = 5;
+
+    /** BT operation types that can be in flight. */
+    public enum OperationType {
+        ADD_SERVICE,
+        CLOSE_CONNECTION,
+        START_ADVERTISING
+    }
+
+    private final Object mOperationLock = new Object();
+    @VisibleForTesting
+    final BluetoothGattServerCallback mGattServerCallback =
+            new GattServerCallback();
+    @VisibleForTesting
+    BluetoothOperationExecutor mBluetoothOperationScheduler =
+            new BluetoothOperationExecutor(MAX_PARALLEL_OPERATIONS);
+
+    private final Context mContext;
+    private final BluetoothManager mBluetoothManager;
+    private final VersionProvider mVersionProvider;
+
+    @Nullable
+    @VisibleForTesting
+    volatile BluetoothGattServerConfig mServerConfig = null;
+
+    @Nullable
+    @VisibleForTesting
+    volatile BluetoothGattServer mBluetoothGattServer = null;
+
+    @VisibleForTesting
+    final ConcurrentMap<BluetoothDevice, BluetoothGattServerConnection>
+            mConnections = new ConcurrentHashMap<BluetoothDevice, BluetoothGattServerConnection>();
+
+    public BluetoothGattServerHelper(Context context, BluetoothManager bluetoothManager) {
+        this(
+                Preconditions.checkNotNull(context),
+                Preconditions.checkNotNull(bluetoothManager),
+                new VersionProvider()
+        );
+    }
+
+    @VisibleForTesting
+    BluetoothGattServerHelper(
+            Context context, BluetoothManager bluetoothManager, VersionProvider versionProvider) {
+        mContext = context;
+        mBluetoothManager = bluetoothManager;
+        mVersionProvider = versionProvider;
+    }
+
+    @Nullable
+    public BluetoothGattServerConfig getConfig() {
+        return mServerConfig;
+    }
+
+    public void open(final BluetoothGattServerConfig gattServerConfig) throws BluetoothException {
+        synchronized (mOperationLock) {
+            Preconditions.checkState(mBluetoothGattServer == null, "Gatt server is already open.");
+            final BluetoothGattServer server =
+                    mBluetoothManager.openGattServer(mContext, mGattServerCallback);
+            if (server == null) {
+                throw new BluetoothException(
+                        "Failed to open the GATT server, openGattServer returned null.");
+            }
+
+            try {
+                for (final BluetoothGattService service :
+                        gattServerConfig.getBluetoothGattServices()) {
+                    if (service == null) {
+                        continue;
+                    }
+                    mBluetoothOperationScheduler.execute(
+                            new Operation<Void>(OperationType.ADD_SERVICE, service) {
+                                @Override
+                                public void run() throws BluetoothException {
+                                    boolean success = server.addService(service);
+                                    if (!success) {
+                                        throw new BluetoothException("Fails on adding service");
+                                    }
+                                }
+                            }, OPERATION_TIMEOUT_MILLIS);
+                }
+                mBluetoothGattServer = server;
+                mServerConfig = gattServerConfig;
+            } catch (BluetoothException e) {
+                server.close();
+                throw e;
+            }
+        }
+    }
+
+    public boolean isOpen() {
+        synchronized (mOperationLock) {
+            return mBluetoothGattServer != null;
+        }
+    }
+
+    public void close() {
+        synchronized (mOperationLock) {
+            BluetoothGattServer bluetoothGattServer = mBluetoothGattServer;
+            if (bluetoothGattServer == null) {
+                return;
+            }
+            bluetoothGattServer.close();
+            mBluetoothGattServer = null;
+        }
+    }
+
+    private BluetoothGattServerConnection getConnectionByDevice(BluetoothDevice device)
+            throws BluetoothGattException {
+        BluetoothGattServerConnection bluetoothLeConnection = mConnections.get(device);
+        if (bluetoothLeConnection == null) {
+            throw new BluetoothGattException(
+                    String.format("Received operation on an unknown device: %s", device),
+                    BluetoothGatt.GATT_FAILURE);
+        }
+        return bluetoothLeConnection;
+    }
+
+    public void sendNotification(
+            BluetoothDevice device,
+            BluetoothGattCharacteristic characteristic,
+            byte[] data,
+            boolean confirm)
+            throws BluetoothException {
+        Log.d(TAG, String.format("Sending a %s of %d bytes on characteristics %s on device %s.",
+                confirm ? "indication" : "notification",
+                data.length,
+                characteristic.getUuid(),
+                device));
+        synchronized (mOperationLock) {
+            BluetoothGattServer bluetoothGattServer = mBluetoothGattServer;
+            if (bluetoothGattServer == null) {
+                throw new BluetoothException("Server is not open.");
+            }
+            BluetoothGattCharacteristic clonedCharacteristic =
+                    BluetoothGattUtils.clone(characteristic);
+            clonedCharacteristic.setValue(data);
+            bluetoothGattServer.notifyCharacteristicChanged(device, clonedCharacteristic, confirm);
+        }
+    }
+
+    public void closeConnection(final BluetoothDevice bluetoothDevice) throws BluetoothException {
+        final BluetoothGattServer bluetoothGattServer = mBluetoothGattServer;
+        if (bluetoothGattServer == null) {
+            throw new BluetoothException("Server is not open.");
+        }
+        int connectionSate =
+                mBluetoothManager.getConnectionState(bluetoothDevice, BluetoothProfile.GATT);
+        if (connectionSate != BluetoothGatt.STATE_CONNECTED) {
+            return;
+        }
+        mBluetoothOperationScheduler.execute(
+                new Operation<Void>(OperationType.CLOSE_CONNECTION) {
+                    @Override
+                    public void run() throws BluetoothException {
+                        bluetoothGattServer.cancelConnection(bluetoothDevice);
+                    }
+                },
+                OPERATION_TIMEOUT_MILLIS);
+    }
+
+    private class GattServerCallback extends BluetoothGattServerCallback {
+        @Override
+        public void onServiceAdded(int status, BluetoothGattService service) {
+            mBluetoothOperationScheduler.notifyCompletion(
+                    new Operation<Void>(OperationType.ADD_SERVICE, service), status);
+        }
+
+        @Override
+        public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
+            BluetoothGattServerConfig serverConfig = mServerConfig;
+            BluetoothGattServer bluetoothGattServer = mBluetoothGattServer;
+            BluetoothGattServerConnection bluetoothLeConnection;
+            if (serverConfig == null || bluetoothGattServer == null) {
+                return;
+            }
+            switch (newState) {
+                case BluetoothGattServer.STATE_CONNECTED:
+                    if (status != BluetoothGatt.GATT_SUCCESS) {
+                        Log.e(TAG, String.format("Connection to %s failed: %s", device,
+                                BluetoothGattUtils.getMessageForStatusCode(status)));
+                        return;
+                    }
+                    Log.i(TAG, String.format("Connected to device %s.", device));
+                    if (mConnections.containsKey(device)) {
+                        Log.w(TAG, String.format("A connection is already open with device %s. "
+                                + "Keeping existing one.", device));
+                        return;
+                    }
+
+                    BluetoothGattServerConnection connection = new BluetoothGattServerConnection(
+                            BluetoothGattServerHelper.this,
+                            device,
+                            serverConfig);
+                    if (serverConfig.getServerListener() != null) {
+                        serverConfig.getServerListener().onConnection(connection);
+                    }
+                    mConnections.put(device, connection);
+
+                    // By default, Android disconnects active GATT server connection if the
+                    // advertisement is
+                    // stop (or sometime stopScanning also disconnect, see b/62667394). Asking
+                    // the server to
+                    // reverse connect will tell Android to keep the connection open.
+                    // Code handling connect() on Android OS is: btif_gatt_server.c
+                    // Note: for Android < P, unknown type devices don't connect. See b/62827460.
+                    //       for Android P+, unknown type devices always use LE to connect (see
+                    //       code)
+                    // Note: for Android < N, dual mode devices always connect using BT classic,
+                    // so connect()
+                    //       should *NOT* be called for those devices. See b/29819614.
+                    if (mVersionProvider.getSdkInt() >= VERSION_CODES.N
+                            || device.getType() != BluetoothDevice.DEVICE_TYPE_DUAL) {
+                        boolean success = bluetoothGattServer.connect(device, /* autoConnect */
+                                false);
+                        if (!success) {
+                            Log.w(TAG, String.format(
+                                    "Keeping connection open on stop advertising failed for "
+                                            + "device %s.",
+                                    device));
+                        }
+                    }
+                    break;
+                case BluetoothGattServer.STATE_DISCONNECTED:
+                    if (status != BluetoothGatt.GATT_SUCCESS) {
+                        Log.w(TAG, String.format(
+                                "Disconnection from %s error: %s. Proceeding anyway.",
+                                device, BluetoothGattUtils.getMessageForStatusCode(status)));
+                    }
+                    bluetoothLeConnection = mConnections.remove(device);
+                    if (bluetoothLeConnection != null) {
+                        // Disconnect the server, required after connecting to it.
+                        bluetoothGattServer.cancelConnection(device);
+                        bluetoothLeConnection.onClose();
+                    }
+                    mBluetoothOperationScheduler.notifyCompletion(
+                            new Operation<Void>(OperationType.CLOSE_CONNECTION), status);
+                    break;
+                default:
+                    Log.e(TAG, String.format("Unexpected connection state: %d", newState));
+            }
+        }
+
+        @Override
+        public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset,
+                BluetoothGattCharacteristic characteristic) {
+            BluetoothGattServer bluetoothGattServer = mBluetoothGattServer;
+            if (bluetoothGattServer == null) {
+                return;
+            }
+            try {
+                byte[] value =
+                        getConnectionByDevice(device).readCharacteristic(offset, characteristic);
+                bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS,
+                        offset,
+                        value);
+            } catch (BluetoothGattException e) {
+                Log.e(TAG,
+                        String.format(
+                                "Could not read  %s on device %s at offset %d",
+                                BluetoothGattUtils.toString(characteristic),
+                                device,
+                                offset),
+                        e);
+                bluetoothGattServer.sendResponse(
+                        device, requestId, e.getGattErrorCode(), offset, null);
+            }
+        }
+
+        @Override
+        public void onCharacteristicWriteRequest(BluetoothDevice device,
+                int requestId,
+                BluetoothGattCharacteristic characteristic,
+                boolean preparedWrite,
+                boolean responseNeeded,
+                int offset,
+                byte[] value) {
+            BluetoothGattServer bluetoothGattServer = mBluetoothGattServer;
+            if (bluetoothGattServer == null) {
+                return;
+            }
+            try {
+                getConnectionByDevice(device).writeCharacteristic(characteristic,
+                        preparedWrite,
+                        offset,
+                        value);
+                if (responseNeeded) {
+                    bluetoothGattServer.sendResponse(
+                            device, requestId, BluetoothGatt.GATT_SUCCESS, offset, null);
+                }
+            } catch (BluetoothGattException e) {
+                Log.e(TAG,
+                        String.format(
+                                "Could not write %s on device %s at offset %d",
+                                BluetoothGattUtils.toString(characteristic),
+                                device,
+                                offset),
+                        e);
+                bluetoothGattServer.sendResponse(
+                        device, requestId, e.getGattErrorCode(), offset, null);
+            }
+        }
+
+        @Override
+        public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset,
+                BluetoothGattDescriptor descriptor) {
+            BluetoothGattServer bluetoothGattServer = mBluetoothGattServer;
+            if (bluetoothGattServer == null) {
+                return;
+            }
+            try {
+                byte[] value = getConnectionByDevice(device).readDescriptor(offset, descriptor);
+                bluetoothGattServer.sendResponse(
+                        device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
+            } catch (BluetoothGattException e) {
+                Log.e(TAG, String.format(
+                                "Could not read %s on device %s at %d",
+                                BluetoothGattUtils.toString(descriptor),
+                                device,
+                                offset),
+                        e);
+                bluetoothGattServer.sendResponse(
+                        device, requestId, e.getGattErrorCode(), offset, null);
+            }
+        }
+
+        @Override
+        public void onDescriptorWriteRequest(BluetoothDevice device,
+                int requestId,
+                BluetoothGattDescriptor descriptor,
+                boolean preparedWrite,
+                boolean responseNeeded,
+                int offset,
+                byte[] value) {
+            BluetoothGattServer bluetoothGattServer = mBluetoothGattServer;
+            if (bluetoothGattServer == null) {
+                return;
+            }
+            try {
+                getConnectionByDevice(device)
+                        .writeDescriptor(descriptor, preparedWrite, offset, value);
+                if (responseNeeded) {
+                    bluetoothGattServer.sendResponse(
+                            device, requestId, BluetoothGatt.GATT_SUCCESS, offset, null);
+                }
+                Log.d(TAG, "Operation onDescriptorWriteRequest successful.");
+            } catch (BluetoothGattException e) {
+                Log.e(TAG,
+                        String.format(
+                                "Could not write %s on device %s at %d",
+                                BluetoothGattUtils.toString(descriptor),
+                                device,
+                                offset),
+                        e);
+                bluetoothGattServer.sendResponse(
+                        device, requestId, e.getGattErrorCode(), offset, null);
+            }
+        }
+
+        @Override
+        public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
+            BluetoothGattServer bluetoothGattServer = mBluetoothGattServer;
+            if (bluetoothGattServer == null) {
+                return;
+            }
+            try {
+                getConnectionByDevice(device).executeWrite(execute);
+                bluetoothGattServer.sendResponse(
+                        device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null);
+            } catch (BluetoothGattException e) {
+                Log.e(TAG, "Could not execute write.", e);
+                bluetoothGattServer.sendResponse(device, requestId, e.getGattErrorCode(), 0, null);
+            }
+        }
+
+        @Override
+        public void onNotificationSent(BluetoothDevice device, int status) {
+            Log.d(TAG,
+                    String.format("Received onNotificationSent for device %s with status %s",
+                            device, status));
+            try {
+                getConnectionByDevice(device).notifyNotificationSent(status);
+            } catch (BluetoothGattException e) {
+                Log.e(TAG, "An error occurred when receiving onNotificationSent: " + e);
+            }
+        }
+    }
+
+    /** Listener for {@link BluetoothGattServerHelper}'s events. */
+    public interface Listener {
+        /** Called when a new connection to the server is established. */
+        void onConnection(BluetoothGattServerConnection connection);
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServlet.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServlet.java
new file mode 100644
index 0000000..e25e223
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattServlet.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.bluetooth;
+
+import android.annotation.TargetApi;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.nearby.fastpair.provider.bluetooth.BluetoothGattServerConnection.Notifier;
+
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+
+/** Servlet to handle GATT operations on a characteristic. */
+@TargetApi(18)
+public abstract class BluetoothGattServlet {
+    public byte[] read(BluetoothGattServerConnection connection,
+            @SuppressWarnings("unused") int offset) throws BluetoothGattException {
+        throw new BluetoothGattException("Read not supported.",
+                BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+    }
+
+    public void write(BluetoothGattServerConnection connection,
+            @SuppressWarnings("unused") int offset, @SuppressWarnings("unused") byte[] value)
+            throws BluetoothGattException {
+        throw new BluetoothGattException("Write not supported.",
+                BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+    }
+
+    public byte[] readDescriptor(BluetoothGattServerConnection connection,
+            BluetoothGattDescriptor descriptor, @SuppressWarnings("unused") int offset)
+            throws BluetoothGattException {
+        throw new BluetoothGattException("Read not supported.",
+                BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+    }
+
+    public void writeDescriptor(BluetoothGattServerConnection connection,
+            BluetoothGattDescriptor descriptor,
+            @SuppressWarnings("unused") int offset, @SuppressWarnings("unused") byte[] value)
+            throws BluetoothGattException {
+        throw new BluetoothGattException("Write not supported.",
+                BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+    }
+
+    public void enableNotification(BluetoothGattServerConnection connection, Notifier notifier)
+            throws BluetoothGattException {
+        throw new BluetoothGattException("Notification not supported.",
+                BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+    }
+
+    public void disableNotification(BluetoothGattServerConnection connection, Notifier notifier)
+            throws BluetoothGattException {
+        throw new BluetoothGattException("Notification not supported.",
+                BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED);
+    }
+
+    public abstract BluetoothGattCharacteristic getCharacteristic();
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattUtils.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattUtils.java
new file mode 100644
index 0000000..7ac26ee
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothGattUtils.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 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 android.nearby.fastpair.provider.bluetooth;
+
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+
+/**
+ * Utils for Gatt profile.
+ */
+public class BluetoothGattUtils {
+
+    /**
+     * Returns a string message for a BluetoothGatt status codes.
+     */
+    public static String getMessageForStatusCode(int statusCode) {
+        switch (statusCode) {
+            case BluetoothGatt.GATT_SUCCESS:
+                return "GATT_SUCCESS";
+            case BluetoothGatt.GATT_FAILURE:
+                return "GATT_FAILURE";
+            case BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION:
+                return "GATT_INSUFFICIENT_AUTHENTICATION";
+            case BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION:
+                return "GATT_INSUFFICIENT_AUTHORIZATION";
+            case BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION:
+                return "GATT_INSUFFICIENT_ENCRYPTION";
+            case BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH:
+                return "GATT_INVALID_ATTRIBUTE_LENGTH";
+            case BluetoothGatt.GATT_INVALID_OFFSET:
+                return "GATT_INVALID_OFFSET";
+            case BluetoothGatt.GATT_READ_NOT_PERMITTED:
+                return "GATT_READ_NOT_PERMITTED";
+            case BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED:
+                return "GATT_REQUEST_NOT_SUPPORTED";
+            case BluetoothGatt.GATT_WRITE_NOT_PERMITTED:
+                return "GATT_WRITE_NOT_PERMITTED";
+            case BluetoothGatt.GATT_CONNECTION_CONGESTED:
+                return "GATT_CONNECTION_CONGESTED";
+            default:
+                return "Unknown error code";
+        }
+    }
+
+    /** Clones a {@link BluetoothGattCharacteristic} so the value can be changed thread-safely. */
+    public static BluetoothGattCharacteristic clone(BluetoothGattCharacteristic characteristic)
+            throws BluetoothException {
+        BluetoothGattCharacteristic result = new BluetoothGattCharacteristic(
+                characteristic.getUuid(),
+                characteristic.getProperties(), characteristic.getPermissions());
+        try {
+            Field instanceIdField = BluetoothGattCharacteristic.class.getDeclaredField("mInstance");
+            Field serviceField = BluetoothGattCharacteristic.class.getDeclaredField("mService");
+            Field descriptorField = BluetoothGattCharacteristic.class.getDeclaredField(
+                    "mDescriptors");
+            instanceIdField.setAccessible(true);
+            serviceField.setAccessible(true);
+            descriptorField.setAccessible(true);
+            instanceIdField.set(result, instanceIdField.get(characteristic));
+            serviceField.set(result, serviceField.get(characteristic));
+            descriptorField.set(result, descriptorField.get(characteristic));
+            byte[] value = characteristic.getValue();
+            if (value != null) {
+                result.setValue(Arrays.copyOf(value, value.length));
+            }
+            result.setWriteType(characteristic.getWriteType());
+        } catch (NoSuchFieldException e) {
+            throw new BluetoothException("Cannot clone characteristic.", e);
+        } catch (IllegalAccessException e) {
+            throw new BluetoothException("Cannot clone characteristic.", e);
+        } catch (IllegalArgumentException e) {
+            throw new BluetoothException("Cannot clone characteristic.", e);
+        }
+        return result;
+    }
+
+    /** Creates a user-readable string from a {@link BluetoothGattDescriptor}. */
+    public static String toString(@Nullable BluetoothGattDescriptor descriptor) {
+        if (descriptor == null) {
+            return "null descriptor";
+        }
+        return String.format("descriptor %s on %s",
+                descriptor.getUuid(),
+                toString(descriptor.getCharacteristic()));
+    }
+
+    /** Creates a user-readable string from a {@link BluetoothGattCharacteristic}. */
+    public static String toString(@Nullable BluetoothGattCharacteristic characteristic) {
+        if (characteristic == null) {
+            return "null characteristic";
+        }
+        return String.format("characteristic %s on %s",
+                characteristic.getUuid(),
+                toString(characteristic.getService()));
+    }
+
+    /** Creates a user-readable string from a {@link BluetoothGattService}. */
+    public static String toString(@Nullable BluetoothGattService service) {
+        if (service == null) {
+            return "null service";
+        }
+        return String.format("service %s", service.getUuid());
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothManager.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothManager.java
new file mode 100644
index 0000000..bf241f1
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/BluetoothManager.java
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.bluetooth;
+
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothAdapter;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattServer;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattServerCallback;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Mockable wrapper of {@link android.bluetooth.BluetoothManager}.
+ */
+public class BluetoothManager {
+
+    private android.bluetooth.BluetoothManager mWrappedInstance;
+
+    private BluetoothManager(android.bluetooth.BluetoothManager instance) {
+        mWrappedInstance = instance;
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothManager#openGattServer(Context,
+     * android.bluetooth.BluetoothGattServerCallback)}.
+     */
+    @Nullable
+    public BluetoothGattServer openGattServer(Context context,
+            BluetoothGattServerCallback callback) {
+        return BluetoothGattServer.wrap(
+                mWrappedInstance.openGattServer(context, callback.unwrap()));
+    }
+
+    /**
+     * See {@link android.bluetooth.BluetoothManager#getConnectionState(
+     *android.bluetooth.BluetoothDevice, int)}.
+     */
+    public int getConnectionState(BluetoothDevice device, int profile) {
+        return mWrappedInstance.getConnectionState(device.unwrap(), profile);
+    }
+
+    /** See {@link android.bluetooth.BluetoothManager#getConnectedDevices(int)}. */
+    public List<BluetoothDevice> getConnectedDevices(int profile) {
+        List<android.bluetooth.BluetoothDevice> devices = mWrappedInstance.getConnectedDevices(
+                profile);
+        List<BluetoothDevice> wrappedDevices = new ArrayList<>(devices.size());
+        for (android.bluetooth.BluetoothDevice device : devices) {
+            wrappedDevices.add(BluetoothDevice.wrap(device));
+        }
+        return wrappedDevices;
+    }
+
+    /** See {@link android.bluetooth.BluetoothManager#getAdapter()}. */
+    public BluetoothAdapter getAdapter() {
+        return BluetoothAdapter.wrap(mWrappedInstance.getAdapter());
+    }
+
+    public static BluetoothManager wrap(android.bluetooth.BluetoothManager bluetoothManager) {
+        return new BluetoothManager(bluetoothManager);
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/RfcommServer.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/RfcommServer.java
new file mode 100644
index 0000000..9ed95ac
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/bluetooth/RfcommServer.java
@@ -0,0 +1,419 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.bluetooth;
+
+import static android.nearby.fastpair.provider.bluetooth.RfcommServer.State.ACCEPTING;
+import static android.nearby.fastpair.provider.bluetooth.RfcommServer.State.CONNECTED;
+import static android.nearby.fastpair.provider.bluetooth.RfcommServer.State.RESTARTING;
+import static android.nearby.fastpair.provider.bluetooth.RfcommServer.State.STARTING;
+import static android.nearby.fastpair.provider.bluetooth.RfcommServer.State.STOPPED;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.nearby.fastpair.provider.EventStreamProtocol;
+import android.nearby.fastpair.provider.utils.Logger;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Listens for a rfcomm client to connect and supports both sending messages to the client and
+ * receiving messages from the client.
+ */
+public class RfcommServer {
+    private static final String TAG = "RfcommServer";
+    private final Logger mLogger = new Logger(TAG);
+
+    private static final String FAST_PAIR_RFCOMM_SERVICE_NAME = "FastPairServer";
+    public static final UUID FAST_PAIR_RFCOMM_UUID =
+            UUID.fromString("df21fe2c-2515-4fdb-8886-f12c4d67927c");
+
+    /** A single thread executor where all state checks are performed. */
+    private final ExecutorService mControllerExecutor = Executors.newSingleThreadExecutor();
+
+    private final ExecutorService mSendMessageExecutor = Executors.newSingleThreadExecutor();
+    private final ExecutorService mReceiveMessageExecutor = Executors.newSingleThreadExecutor();
+
+    @Nullable
+    private BluetoothServerSocket mServerSocket;
+    @Nullable
+    private BluetoothSocket mSocket;
+
+    private State mState = STOPPED;
+    private boolean mIsStopRequested = false;
+
+    @Nullable
+    private RequestHandler mRequestHandler;
+
+    @Nullable
+    private CountDownLatch mCountDownLatch;
+    @Nullable
+    private StateMonitor mStateMonitor;
+
+    /**
+     * Manages RfcommServer status.
+     *
+     * <pre>{@code
+     *      +------------------------------------------------+
+     *      +-------------------------------+                |
+     *      v                               |                |
+     * +---------+    +----------+    +-----+-----+    +-----+-----+
+     * | STOPPED +--> | STARTING +--> | ACCEPTING +--> | CONNECTED |
+     * +---------+    +-----+----+    +-------+---+    +-----+-----+
+     *      ^               |             ^   v              |
+     *      +---------------+         +---+--------+         |
+     *                                | RESTARTING | <-------+
+     *                                +------------+
+     * }</pre>
+     *
+     * If Stop action is not requested, the server will restart forever. Otherwise, go stopped.
+     */
+    public enum State {
+        STOPPED,
+        STARTING,
+        RESTARTING,
+        ACCEPTING,
+        CONNECTED,
+    }
+
+    /** Starts the rfcomm server. */
+    public void start() {
+        runInControllerExecutor(this::startServer);
+    }
+
+    private void startServer() {
+        log("Start RfcommServer");
+
+        if (!mState.equals(STOPPED)) {
+            log("Server is not stopped, skip start request.");
+            return;
+        }
+        updateState(STARTING);
+        mIsStopRequested = false;
+
+        startAccept();
+    }
+
+    private void restartServer() {
+        log("Restart RfcommServer");
+        updateState(RESTARTING);
+        startAccept();
+    }
+
+    private void startAccept() {
+        try {
+            // Gets server socket in controller thread for stop() API.
+            mServerSocket =
+                    BluetoothAdapter.getDefaultAdapter()
+                            .listenUsingRfcommWithServiceRecord(
+                                    FAST_PAIR_RFCOMM_SERVICE_NAME, FAST_PAIR_RFCOMM_UUID);
+        } catch (IOException e) {
+            log("Create service record failed, stop server");
+            stopServer();
+            return;
+        }
+
+        updateState(ACCEPTING);
+        new Thread(() -> accept(mServerSocket)).start();
+    }
+
+    private void accept(BluetoothServerSocket serverSocket) {
+        triggerCountdownLatch();
+
+        try {
+            BluetoothSocket socket = serverSocket.accept();
+            serverSocket.close();
+
+            runInControllerExecutor(() -> startListen(socket));
+        } catch (IOException e) {
+            log("IOException when accepting new connection");
+            runInControllerExecutor(() -> handleAcceptException(serverSocket));
+        }
+    }
+
+    private void handleAcceptException(BluetoothServerSocket serverSocket) {
+        if (mIsStopRequested) {
+            stopServer();
+        } else {
+            closeServerSocket(serverSocket);
+            restartServer();
+        }
+    }
+
+    private void startListen(BluetoothSocket bluetoothSocket) {
+        if (mIsStopRequested) {
+            closeSocket(bluetoothSocket);
+            stopServer();
+            return;
+        }
+
+        updateState(CONNECTED);
+        // Sets method parameter to global socket for stop() API.
+        this.mSocket = bluetoothSocket;
+        new Thread(() -> listen(bluetoothSocket)).start();
+    }
+
+    private void listen(BluetoothSocket bluetoothSocket) {
+        triggerCountdownLatch();
+
+        try {
+            DataInputStream dataInputStream = new DataInputStream(bluetoothSocket.getInputStream());
+            while (true) {
+                int eventGroup = dataInputStream.readUnsignedByte();
+                int eventCode = dataInputStream.readUnsignedByte();
+                int additionalLength = dataInputStream.readUnsignedShort();
+
+                byte[] data = new byte[additionalLength];
+                if (additionalLength > 0) {
+                    int count = 0;
+                    do {
+                        count += dataInputStream.read(data, count, additionalLength - count);
+                    } while (count < additionalLength);
+                }
+
+                if (mRequestHandler != null) {
+                    // In order not to block listening thread, use different thread to dispatch
+                    // message.
+                    mReceiveMessageExecutor.execute(
+                            () -> {
+                                mRequestHandler.handleRequest(eventGroup, eventCode, data);
+                                triggerCountdownLatch();
+                            });
+                }
+            }
+        } catch (IOException e) {
+            log(
+                    String.format(
+                            "IOException when listening to %s",
+                            bluetoothSocket.getRemoteDevice().getAddress()));
+            runInControllerExecutor(() -> handleListenException(bluetoothSocket));
+        }
+    }
+
+    private void handleListenException(BluetoothSocket bluetoothSocket) {
+        if (mIsStopRequested) {
+            stopServer();
+        } else {
+            closeSocket(bluetoothSocket);
+            restartServer();
+        }
+    }
+
+    public void sendFakeEventStreamMessage(EventStreamProtocol.EventGroup eventGroup) {
+        switch (eventGroup) {
+            case BLUETOOTH:
+                send(EventStreamProtocol.EventGroup.BLUETOOTH_VALUE,
+                        EventStreamProtocol.BluetoothEventCode.BLUETOOTH_ENABLE_SILENCE_MODE_VALUE,
+                        new byte[0]);
+                break;
+            case LOGGING:
+                send(EventStreamProtocol.EventGroup.LOGGING_VALUE,
+                        EventStreamProtocol.LoggingEventCode.LOG_FULL_VALUE,
+                        new byte[0]);
+                break;
+            case DEVICE:
+                send(EventStreamProtocol.EventGroup.DEVICE_VALUE,
+                        EventStreamProtocol.DeviceEventCode.DEVICE_BATTERY_INFO_VALUE,
+                        new byte[]{0x11, 0x12, 0x13});
+                break;
+            default: // fall out
+        }
+    }
+
+    public void sendFakeEventStreamLoggingMessage(@Nullable String logContent) {
+        send(EventStreamProtocol.EventGroup.LOGGING_VALUE,
+                EventStreamProtocol.LoggingEventCode.LOG_SAVE_TO_BUFFER_VALUE,
+                logContent != null ? logContent.getBytes(UTF_8) : new byte[0]);
+    }
+
+    public void send(int eventGroup, int eventCode, byte[] data) {
+        runInControllerExecutor(
+                () -> {
+                    if (!CONNECTED.equals(mState)) {
+                        log("Server is not in CONNECTED state, skip send request");
+                        return;
+                    }
+                    BluetoothSocket bluetoothSocket = this.mSocket;
+                    mSendMessageExecutor.execute(() -> {
+                        String address = bluetoothSocket.getRemoteDevice().getAddress();
+                        try {
+                            DataOutputStream dataOutputStream =
+                                    new DataOutputStream(bluetoothSocket.getOutputStream());
+                            dataOutputStream.writeByte(eventGroup);
+                            dataOutputStream.writeByte(eventCode);
+                            dataOutputStream.writeShort(data.length);
+                            if (data.length > 0) {
+                                dataOutputStream.write(data);
+                            }
+                            dataOutputStream.flush();
+                            log(
+                                    String.format(
+                                            "Send message to %s: %s, %s, %s.",
+                                            address, eventGroup, eventCode, data.length));
+                        } catch (IOException e) {
+                            log(
+                                    String.format(
+                                            "Failed to send message to %s: %s, %s, %s.",
+                                            address, eventGroup, eventCode, data.length),
+                                    e);
+                        }
+                    });
+                });
+    }
+
+    /** Stops the rfcomm server. */
+    public void stop() {
+        runInControllerExecutor(() -> {
+            log("Stop RfcommServer");
+
+            if (STOPPED.equals(mState)) {
+                log("Server is stopped, skip stop request.");
+                return;
+            }
+
+            if (mIsStopRequested) {
+                log("Stop is already requested, skip stop request.");
+                return;
+            }
+            mIsStopRequested = true;
+
+            if (ACCEPTING.equals(mState)) {
+                closeServerSocket(mServerSocket);
+            }
+
+            if (CONNECTED.equals(mState)) {
+                closeSocket(mSocket);
+            }
+        });
+    }
+
+    private void stopServer() {
+        updateState(STOPPED);
+        triggerCountdownLatch();
+    }
+
+    private void updateState(State newState) {
+        log(String.format("Change state from %s to %s", mState, newState));
+        if (mStateMonitor != null) {
+            mStateMonitor.onStateChanged(newState);
+        }
+        mState = newState;
+    }
+
+    private void closeServerSocket(BluetoothServerSocket serverSocket) {
+        try {
+            if (serverSocket != null) {
+                log(String.format("Close server socket: %s", serverSocket));
+                serverSocket.close();
+            }
+        } catch (IOException | NullPointerException e) {
+            // NullPointerException is used to skip robolectric test failure.
+            // In unit test, different virtual devices are set up in different threads, calling
+            // ServerSocket.close() in wrong thread will result in NullPointerException since there
+            // is no corresponding service record.
+            // TODO(hylo): Remove NullPointerException when the solution is submitted to test cases.
+            log("Failed to stop server", e);
+        }
+    }
+
+    private void closeSocket(BluetoothSocket socket) {
+        try {
+            if (socket != null && socket.isConnected()) {
+                log(String.format("Close socket: %s", socket.getRemoteDevice().getAddress()));
+                socket.close();
+            }
+        } catch (IOException e) {
+            log(String.format("IOException when close socket %s",
+                    socket.getRemoteDevice().getAddress()));
+        }
+    }
+
+    private void runInControllerExecutor(Runnable runnable) {
+        mControllerExecutor.execute(runnable);
+    }
+
+    private void log(String message) {
+        mLogger.log("Server=%s, %s", FAST_PAIR_RFCOMM_SERVICE_NAME, message);
+    }
+
+    private void log(String message, Throwable e) {
+        mLogger.log(e, "Server=%s, %s", FAST_PAIR_RFCOMM_SERVICE_NAME, message);
+    }
+
+    private void triggerCountdownLatch() {
+        if (mCountDownLatch != null) {
+            mCountDownLatch.countDown();
+        }
+    }
+
+    /** Interface to handle incoming request from clients. */
+    public interface RequestHandler {
+        void handleRequest(int eventGroup, int eventCode, byte[] data);
+    }
+
+    public void setRequestHandler(@Nullable RequestHandler requestHandler) {
+        this.mRequestHandler = requestHandler;
+    }
+
+    /** A state monitor to send signal when state is changed. */
+    public interface StateMonitor {
+        void onStateChanged(State state);
+    }
+
+    public void setStateMonitor(@Nullable StateMonitor stateMonitor) {
+        this.mStateMonitor = stateMonitor;
+    }
+
+    @VisibleForTesting
+    void setCountDownLatch(@Nullable CountDownLatch countDownLatch) {
+        this.mCountDownLatch = countDownLatch;
+    }
+
+    @VisibleForTesting
+    void setIsStopRequested(boolean isStopRequested) {
+        this.mIsStopRequested = isStopRequested;
+    }
+
+    @VisibleForTesting
+    void simulateAcceptIOException() {
+        runInControllerExecutor(() -> {
+            if (ACCEPTING.equals(mState)) {
+                closeServerSocket(mServerSocket);
+            }
+        });
+    }
+
+    @VisibleForTesting
+    void simulateListenIOException() {
+        runInControllerExecutor(() -> {
+            if (CONNECTED.equals(mState)) {
+                closeSocket(mSocket);
+            }
+        });
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/crypto/Crypto.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/crypto/Crypto.java
new file mode 100644
index 0000000..0aa4f6e
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/crypto/Crypto.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.crypto;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import android.annotation.SuppressLint;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.protobuf.ByteString;
+
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+
+/** Cryptography utilities for ephemeral IDs. */
+public final class Crypto {
+    private static final int AES_BLOCK_SIZE = 16;
+    private static final ImmutableSet<Integer> VALID_AES_KEY_SIZES = ImmutableSet.of(16, 24, 32);
+    private static final String AES_ECB_NOPADDING_ENCRYPTION_ALGO = "AES/ECB/NoPadding";
+    private static final String AES_ENCRYPTION_ALGO = "AES";
+
+    /** Encrypts the provided data with the provided key using the AES/ECB/NoPadding algorithm. */
+    public static ByteString aesEcbNoPaddingEncrypt(ByteString key, ByteString data) {
+        return aesEcbOperation(key, data, Cipher.ENCRYPT_MODE);
+    }
+
+    /** Decrypts the provided data with the provided key using the AES/ECB/NoPadding algorithm. */
+    public static ByteString aesEcbNoPaddingDecrypt(ByteString key, ByteString data) {
+        return aesEcbOperation(key, data, Cipher.DECRYPT_MODE);
+    }
+
+    @SuppressLint("GetInstance")
+    private static ByteString aesEcbOperation(ByteString key, ByteString data, int operation) {
+        checkArgument(VALID_AES_KEY_SIZES.contains(key.size()));
+        checkArgument(data.size() % AES_BLOCK_SIZE == 0);
+        try {
+            Cipher aesCipher = Cipher.getInstance(AES_ECB_NOPADDING_ENCRYPTION_ALGO);
+            SecretKeySpec secretKeySpec = new SecretKeySpec(key.toByteArray(), AES_ENCRYPTION_ALGO);
+            aesCipher.init(operation, secretKeySpec);
+            ByteBuffer output = ByteBuffer.allocate(data.size());
+            checkState(aesCipher.doFinal(data.asReadOnlyByteBuffer(), output) == data.size());
+            output.rewind();
+            return ByteString.copyFrom(output);
+        } catch (GeneralSecurityException e) {
+            // Should never happen.
+            throw new AssertionError(e);
+        }
+    }
+
+    private Crypto() {
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/crypto/E2eeCalculator.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/crypto/E2eeCalculator.java
new file mode 100644
index 0000000..794c19d
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/crypto/E2eeCalculator.java
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.crypto;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
+import com.google.common.primitives.Bytes;
+import com.google.common.primitives.Ints;
+import com.google.protobuf.ByteString;
+
+import java.math.BigInteger;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.EllipticCurve;
+import java.util.Collections;
+
+/** Provides methods for calculating E2EE EIDs and E2E encryption/decryption based on E2EE EIDs. */
+public final class E2eeCalculator {
+
+    private static final byte[] TEMP_KEY_PADDING_1 =
+            Bytes.toArray(Collections.nCopies(11, (byte) 0xFF));
+    private static final byte[] TEMP_KEY_PADDING_2 = new byte[11];
+    private static final ECParameterSpec CURVE_SPEC = getCurveSpec();
+    private static final BigInteger P = ((ECFieldFp) CURVE_SPEC.getCurve().getField()).getP();
+    private static final BigInteger TWO = new BigInteger("2");
+    private static final BigInteger THREE = new BigInteger("3");
+    private static final int E2EE_EID_IDENTITY_KEY_SIZE = 32;
+    private static final int E2EE_EID_SIZE = 20;
+
+    /**
+     * Computes the E2EE EID value for the given device clock based time. Note that Eddystone
+     * beacons start advertising the new EID at a random time within the window, therefore the
+     * currently advertised EID for beacon time <em>t</em> may be either
+     * {@code computeE2eeEid(eik, k, t)} or {@code computeE2eeEid(eik, k, t - (1 << k))}.
+     *
+     * <p>The E2EE EID computation is based on https://goto.google.com/e2ee-eid-computation.
+     *
+     * @param identityKey        the beacon's 32-byte Eddystone E2EE identity key
+     * @param exponent           rotation period exponent as configured on the beacon, must be in
+     *                           range the [0,15]
+     * @param deviceClockSeconds the value of the beacon's 32-bit seconds time counter (treated as
+     *                           an unsigned value)
+     * @return E2EE EID value.
+     */
+    public static ByteString computeE2eeEid(
+            ByteString identityKey, int exponent, int deviceClockSeconds) {
+        return computePublicKey(computePrivateKey(identityKey, exponent, deviceClockSeconds));
+    }
+
+    private static ByteString computePublicKey(BigInteger privateKey) {
+        return getXCoordinateBytes(toPoint(privateKey));
+    }
+
+    private static BigInteger computePrivateKey(
+            ByteString identityKey, int exponent, int deviceClockSeconds) {
+        Preconditions.checkArgument(
+                Preconditions.checkNotNull(identityKey).size() == E2EE_EID_IDENTITY_KEY_SIZE);
+        Preconditions.checkArgument(exponent >= 0 && exponent < 16);
+
+        byte[] exponentByte = new byte[]{(byte) exponent};
+        byte[] paddedCounter = Ints.toByteArray((deviceClockSeconds >>> exponent) << exponent);
+        byte[] data =
+                Bytes.concat(
+                        TEMP_KEY_PADDING_1,
+                        exponentByte,
+                        paddedCounter,
+                        TEMP_KEY_PADDING_2,
+                        exponentByte,
+                        paddedCounter);
+
+        byte[] rTag =
+                Crypto.aesEcbNoPaddingEncrypt(identityKey, ByteString.copyFrom(data)).toByteArray();
+        return new BigInteger(1, rTag).mod(CURVE_SPEC.getOrder());
+    }
+
+    private static ECPoint toPoint(BigInteger privateKey) {
+        return multiplyPoint(CURVE_SPEC.getGenerator(), privateKey);
+    }
+
+    private static ByteString getXCoordinateBytes(ECPoint point) {
+        byte[] unalignedBytes = point.getAffineX().toByteArray();
+
+        // The unalignedBytes may have length < 32 if the leading E2EE EID bytes are zero, or
+        // it may be E2EE_EID_SIZE + 1 if the leading bit is 1, in which case the first byte is
+        // always zero.
+        Verify.verify(
+                unalignedBytes.length <= E2EE_EID_SIZE
+                        || (unalignedBytes.length == E2EE_EID_SIZE + 1 && unalignedBytes[0] == 0));
+
+        byte[] bytes;
+        if (unalignedBytes.length < E2EE_EID_SIZE) {
+            bytes = new byte[E2EE_EID_SIZE];
+            System.arraycopy(
+                    unalignedBytes, 0, bytes, bytes.length - unalignedBytes.length,
+                    unalignedBytes.length);
+        } else if (unalignedBytes.length == E2EE_EID_SIZE + 1) {
+            bytes = new byte[E2EE_EID_SIZE];
+            System.arraycopy(unalignedBytes, 1, bytes, 0, E2EE_EID_SIZE);
+        } else { // unalignedBytes.length ==  GattE2EE_EID_SIZE
+            bytes = unalignedBytes;
+        }
+        return ByteString.copyFrom(bytes);
+    }
+
+    /** Returns a secp160r1 curve spec. */
+    private static ECParameterSpec getCurveSpec() {
+        final BigInteger p = new BigInteger("ffffffffffffffffffffffffffffffff7fffffff", 16);
+        final BigInteger n = new BigInteger("0100000000000000000001f4c8f927aed3ca752257", 16);
+        final BigInteger a = new BigInteger("ffffffffffffffffffffffffffffffff7ffffffc", 16);
+        final BigInteger b = new BigInteger("1c97befc54bd7a8b65acf89f81d4d4adc565fa45", 16);
+        final BigInteger gx = new BigInteger("4a96b5688ef573284664698968c38bb913cbfc82", 16);
+        final BigInteger gy = new BigInteger("23a628553168947d59dcc912042351377ac5fb32", 16);
+        final int h = 1;
+        ECFieldFp fp = new ECFieldFp(p);
+        EllipticCurve spec = new EllipticCurve(fp, a, b);
+        ECPoint g = new ECPoint(gx, gy);
+        return new ECParameterSpec(spec, g, n, h);
+    }
+
+    /** Returns the scalar multiplication result of k*p in Fp. */
+    private static ECPoint multiplyPoint(ECPoint p, BigInteger k) {
+        ECPoint r = ECPoint.POINT_INFINITY;
+        ECPoint s = p;
+        BigInteger kModP = k.mod(P);
+        int length = kModP.bitLength();
+        for (int i = 0; i <= length - 1; i++) {
+            if (kModP.mod(TWO).byteValue() == 1) {
+                r = addPoint(r, s);
+            }
+            s = doublePoint(s);
+            kModP = kModP.divide(TWO);
+        }
+        return r;
+    }
+
+    /** Returns the point addition r+s in Fp. */
+    private static ECPoint addPoint(ECPoint r, ECPoint s) {
+        if (r.equals(s)) {
+            return doublePoint(r);
+        } else if (r.equals(ECPoint.POINT_INFINITY)) {
+            return s;
+        } else if (s.equals(ECPoint.POINT_INFINITY)) {
+            return r;
+        }
+        BigInteger slope =
+                r.getAffineY()
+                        .subtract(s.getAffineY())
+                        .multiply(r.getAffineX().subtract(s.getAffineX()).modInverse(P))
+                        .mod(P);
+        BigInteger x =
+                slope.modPow(TWO, P).subtract(r.getAffineX()).subtract(s.getAffineX()).mod(P);
+        BigInteger y = s.getAffineY().negate().mod(P);
+        y = y.add(slope.multiply(s.getAffineX().subtract(x))).mod(P);
+        return new ECPoint(x, y);
+    }
+
+    /** Returns the point doubling 2*r in Fp. */
+    private static ECPoint doublePoint(ECPoint r) {
+        if (r.equals(ECPoint.POINT_INFINITY)) {
+            return r;
+        }
+        BigInteger slope = r.getAffineX().pow(2).multiply(THREE);
+        slope = slope.add(CURVE_SPEC.getCurve().getA());
+        slope = slope.multiply(r.getAffineY().multiply(TWO).modInverse(P));
+        BigInteger x = slope.pow(2).subtract(r.getAffineX().multiply(TWO)).mod(P);
+        BigInteger y =
+                r.getAffineY().negate().add(slope.multiply(r.getAffineX().subtract(x))).mod(P);
+        return new ECPoint(x, y);
+    }
+
+    private E2eeCalculator() {
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/utils/Logger.java b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/utils/Logger.java
new file mode 100644
index 0000000..794f100
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/fastpair_provider/src/android/nearby/fastpair/provider/utils/Logger.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+package android.nearby.fastpair.provider.utils;
+
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.google.errorprone.annotations.FormatMethod;
+
+/**
+ * The base context for a logging statement.
+ */
+public class Logger {
+    private final String mString;
+
+    public Logger(String tag) {
+        this.mString = tag;
+    }
+
+    @FormatMethod
+    public void log(String message, Object... objects) {
+        log(null, message, objects);
+    }
+
+    /** Logs to the console. */
+    @FormatMethod
+    public void log(@Nullable Throwable exception, String message, Object... objects) {
+        if (exception == null) {
+            Log.i(mString, String.format(message, objects));
+        } else {
+            Log.w(mString, String.format(message, objects));
+            Log.w(mString, String.format("Cause: %s", exception));
+        }
+    }
+}
diff --git a/nearby/tests/multidevices/clients/test_support/snippet_helper/Android.bp b/nearby/tests/multidevices/clients/test_support/snippet_helper/Android.bp
new file mode 100644
index 0000000..697c88d
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/snippet_helper/Android.bp
@@ -0,0 +1,24 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_library {
+    name: "MoblySnippetHelperLib",
+    srcs: ["src/**/*.kt"],
+    sdk_version: "test_current",
+    static_libs: ["mobly-snippet-lib",],
+}
diff --git a/nearby/tests/multidevices/clients/test_support/snippet_helper/AndroidManifest.xml b/nearby/tests/multidevices/clients/test_support/snippet_helper/AndroidManifest.xml
new file mode 100644
index 0000000..4858f46
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/snippet_helper/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.mobly.snippet.util">
+
+</manifest>
diff --git a/nearby/tests/multidevices/clients/test_support/snippet_helper/src/com/google/android/mobly/snippet/util/SnippetEventHelper.kt b/nearby/tests/multidevices/clients/test_support/snippet_helper/src/com/google/android/mobly/snippet/util/SnippetEventHelper.kt
new file mode 100644
index 0000000..0dbcb57
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/snippet_helper/src/com/google/android/mobly/snippet/util/SnippetEventHelper.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+package com.google.android.mobly.snippet.util
+
+import android.os.Bundle
+import com.google.android.mobly.snippet.event.EventCache
+import com.google.android.mobly.snippet.event.SnippetEvent
+
+/**
+ * Posts an {@link SnippetEvent} to the event cache with data bundle [fill] by the given function.
+ *
+ * This is a helper function to make your client side codes more concise. Sample usage:
+ * ```
+ *   postSnippetEvent(callbackId, "onReceiverFound") {
+ *     putLong("discoveryTimeMs", discoveryTimeMs)
+ *     putBoolean("isKnown", isKnown)
+ *   }
+ * ```
+ *
+ * @param callbackId the callbackId passed to the {@link
+ * com.google.android.mobly.snippet.rpc.AsyncRpc} method.
+ * @param eventName the name of the event.
+ * @param fill the function to fill the data bundle.
+ */
+fun postSnippetEvent(callbackId: String, eventName: String, fill: Bundle.() -> Unit) {
+  val eventData = Bundle().apply(fill)
+  val snippetEvent = SnippetEvent(callbackId, eventName).apply { data.putAll(eventData) }
+  EventCache.getInstance().postEvent(snippetEvent)
+}
diff --git a/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/Android.bp b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/Android.bp
new file mode 100644
index 0000000..284d5c2
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/Android.bp
@@ -0,0 +1,38 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// Run the tests: atest --host MoblySnippetHelperRoboTest
+android_robolectric_test {
+    name: "MoblySnippetHelperRoboTest",
+    srcs: ["src/**/*.kt"],
+    instrumentation_for: "NearbyMultiDevicesClientsSnippets",
+    java_resources: ["robolectric.properties"],
+
+    static_libs: [
+        "MoblySnippetHelperLib",
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "junit",
+        "mobly-snippet-lib",
+        "truth-prebuilt",
+    ],
+    test_options: {
+        // timeout in seconds.
+        timeout: 36000,
+    },
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/AndroidManifest.xml b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/AndroidManifest.xml
new file mode 100644
index 0000000..f1fef23
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.google.android.mobly.snippet.util"/>
diff --git a/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/robolectric.properties b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/robolectric.properties
new file mode 100644
index 0000000..2ea03bb
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/robolectric.properties
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2022 Google Inc.
+#
+# 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.
+#
+sdk=NEWEST_SDK
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/src/com/google/android/mobly/snippet/util/SnippetEventHelperTest.kt b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/src/com/google/android/mobly/snippet/util/SnippetEventHelperTest.kt
new file mode 100644
index 0000000..641ab82
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/src/com/google/android/mobly/snippet/util/SnippetEventHelperTest.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+package com.google.android.mobly.snippet.util
+
+import androidx.test.platform.app.InstrumentationRegistry
+import com.google.android.mobly.snippet.event.EventSnippet
+import com.google.android.mobly.snippet.util.Log
+import com.google.common.truth.Truth.assertThat
+import org.json.JSONObject
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+/** Robolectric tests for SnippetEventHelper.kt. */
+@RunWith(RobolectricTestRunner::class)
+class SnippetEventHelperTest {
+
+  @Test
+  fun testPostSnippetEvent_withDataBundle_writesEventCache() {
+    val testCallbackId = "test_1234"
+    val testEventName = "onTestEvent"
+    val testBundleDataStrKey = "testStrKey"
+    val testBundleDataStrValue = "testStrValue"
+    val testBundleDataIntKey = "testIntKey"
+    val testBundleDataIntValue = 777
+    val eventSnippet = EventSnippet()
+    Log.initLogTag(InstrumentationRegistry.getInstrumentation().context)
+
+    postSnippetEvent(testCallbackId, testEventName) {
+      putString(testBundleDataStrKey, testBundleDataStrValue)
+      putInt(testBundleDataIntKey, testBundleDataIntValue)
+    }
+
+    val event = eventSnippet.eventWaitAndGet(testCallbackId, testEventName, null)
+    assertThat(event.getJSONObject("data").toString())
+      .isEqualTo(
+        JSONObject()
+          .put(testBundleDataIntKey, testBundleDataIntValue)
+          .put(testBundleDataStrKey, testBundleDataStrValue)
+          .toString()
+      )
+  }
+}
diff --git a/nearby/tests/multidevices/host/Android.bp b/nearby/tests/multidevices/host/Android.bp
new file mode 100644
index 0000000..933cae9
--- /dev/null
+++ b/nearby/tests/multidevices/host/Android.bp
@@ -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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// Run the tests: atest -v CtsNearbyMultiDevicesTestSuite
+python_test_host {
+    name: "CtsNearbyMultiDevicesTestSuite",
+    main: "suite_main.py",
+    srcs: ["*.py"],
+    libs: ["NearbyMultiDevicesHostHelper"],
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+    test_options: {
+        unit_test: false,
+    },
+    data: [
+        // Package the snippet with the Mobly test.
+        ":NearbyMultiDevicesClientsSnippets",
+        // Package the data provider with the Mobly test.
+        ":NearbyFastPairSeekerDataProvider",
+        // Package the JSON metadata with the Mobly test.
+        "test_data/**/*",
+    ],
+}
+
+python_library_host {
+    name: "NearbyMultiDevicesHostHelper",
+    srcs: ["test_helper/*.py"],
+}
diff --git a/nearby/tests/multidevices/host/AndroidTest.xml b/nearby/tests/multidevices/host/AndroidTest.xml
new file mode 100644
index 0000000..a5f6839
--- /dev/null
+++ b/nearby/tests/multidevices/host/AndroidTest.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Config for CTS Nearby Mainline multi devices end-to-end test suite">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="wifi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
+
+    <device name="device1">
+        <!-- For coverage to work, the APK should not be uninstalled until after coverage is pulled.
+             So it's a lot easier to install APKs outside the python code.
+        -->
+        <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+            <option name="test-file-name" value="NearbyMultiDevicesClientsSnippets.apk" />
+            <option name="test-file-name" value="NearbyFastPairSeekerDataProvider.apk" />
+            <option name="check-min-sdk" value="true" />
+        </target_preparer>
+        <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+            <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
+            <option name="run-command" value="wm dismiss-keyguard" />
+        </target_preparer>
+        <target_preparer class="com.android.tradefed.targetprep.PythonVirtualenvPreparer">
+          <!-- Any python dependencies can be specified and will be installed with pip -->
+          <!-- TODO(b/225958696): Import python dependencies -->
+          <option name="dep-module" value="mobly" />
+          <option name="dep-module" value="retry" />
+        </target_preparer>
+        <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+            <option name="force-skip-system-props" value="true" /> <!-- avoid restarting device -->
+            <option name="screen-always-on" value="on" />
+        </target_preparer>
+    </device>
+    <device name="device2">
+        <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+            <option name="test-file-name" value="NearbyMultiDevicesClientsSnippets.apk" />
+            <option name="test-file-name" value="NearbyFastPairSeekerDataProvider.apk" />
+            <option name="check-min-sdk" value="true" />
+        </target_preparer>
+        <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+            <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
+            <option name="run-command" value="wm dismiss-keyguard" />
+        </target_preparer>
+        <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+            <option name="force-skip-system-props" value="true" /> <!-- avoid restarting device -->
+            <option name="screen-always-on" value="on" />
+        </target_preparer>
+    </device>
+
+    <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="CtsNearbyMultiDevicesTestSuite" />
+      <!-- Timeout limit in milliseconds for all test cases of the python binary -->
+      <option name="mobly-test-timeout" value="60000" />
+    </test>
+</configuration>
+
diff --git a/nearby/tests/multidevices/host/initial_pairing_test.py b/nearby/tests/multidevices/host/initial_pairing_test.py
new file mode 100644
index 0000000..1a49045
--- /dev/null
+++ b/nearby/tests/multidevices/host/initial_pairing_test.py
@@ -0,0 +1,62 @@
+#  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.
+
+"""CTS-V Nearby Mainline Fast Pair end-to-end test case: initial pairing test."""
+
+from test_helper import constants
+from test_helper import fast_pair_base_test
+
+# The model ID to simulate on provider side.
+PROVIDER_SIMULATOR_MODEL_ID = constants.DEFAULT_MODEL_ID
+# The public key to simulate as registered headsets.
+PROVIDER_SIMULATOR_ANTI_SPOOFING_KEY = constants.DEFAULT_ANTI_SPOOFING_KEY
+# The anti-spoof key device metadata JSON file for data provider at seeker side.
+PROVIDER_SIMULATOR_KDM_JSON_FILE = constants.DEFAULT_KDM_JSON_FILE
+
+# Time in seconds for events waiting.
+SETUP_TIMEOUT_SEC = constants.SETUP_TIMEOUT_SEC
+BECOME_DISCOVERABLE_TIMEOUT_SEC = constants.BECOME_DISCOVERABLE_TIMEOUT_SEC
+START_ADVERTISING_TIMEOUT_SEC = constants.START_ADVERTISING_TIMEOUT_SEC
+HALF_SHEET_POPUP_TIMEOUT_SEC = constants.HALF_SHEET_POPUP_TIMEOUT_SEC
+MANAGE_ACCOUNT_DEVICE_TIMEOUT_SEC = constants.AVERAGE_PAIRING_TIMEOUT_SEC * 2
+
+
+class InitialPairingTest(fast_pair_base_test.FastPairBaseTest):
+    """Fast Pair initial pairing test."""
+
+    def setup_test(self) -> None:
+        super().setup_test()
+        self._provider.start_model_id_advertising(PROVIDER_SIMULATOR_MODEL_ID,
+                                                  PROVIDER_SIMULATOR_ANTI_SPOOFING_KEY)
+        self._provider.wait_for_discoverable_mode(BECOME_DISCOVERABLE_TIMEOUT_SEC)
+        self._provider.wait_for_advertising_start(START_ADVERTISING_TIMEOUT_SEC)
+        self._seeker.put_anti_spoof_key_device_metadata(PROVIDER_SIMULATOR_MODEL_ID,
+                                                        PROVIDER_SIMULATOR_KDM_JSON_FILE)
+        self._seeker.set_fast_pair_scan_enabled(True)
+
+    # TODO(b/214015364): Remove Bluetooth bound on both sides ("Forget device").
+    def teardown_test(self) -> None:
+        self._seeker.set_fast_pair_scan_enabled(False)
+        self._provider.teardown_provider_simulator()
+        self._seeker.dismiss_halfsheet()
+        super().teardown_test()
+
+    def test_seeker_initial_pair_provider(self) -> None:
+        self._seeker.wait_and_assert_halfsheet_showed(
+            timeout_seconds=HALF_SHEET_POPUP_TIMEOUT_SEC,
+            expected_model_id=PROVIDER_SIMULATOR_MODEL_ID)
+        self._seeker.start_pairing()
+        self._seeker.wait_and_assert_account_device(
+            get_account_key_from_provider=self._provider.get_latest_received_account_key,
+            timeout_seconds=MANAGE_ACCOUNT_DEVICE_TIMEOUT_SEC)
diff --git a/nearby/tests/multidevices/host/seeker_discover_provider_test.py b/nearby/tests/multidevices/host/seeker_discover_provider_test.py
new file mode 100644
index 0000000..6356595
--- /dev/null
+++ b/nearby/tests/multidevices/host/seeker_discover_provider_test.py
@@ -0,0 +1,52 @@
+#  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.
+
+"""CTS-V Nearby Mainline Fast Pair end-to-end test case: seeker can discover the provider."""
+
+from test_helper import constants
+from test_helper import fast_pair_base_test
+
+# The model ID to simulate on provider side.
+PROVIDER_SIMULATOR_MODEL_ID = constants.DEFAULT_MODEL_ID
+# The public key to simulate as registered headsets.
+PROVIDER_SIMULATOR_ANTI_SPOOFING_KEY = constants.DEFAULT_ANTI_SPOOFING_KEY
+
+# Time in seconds for events waiting.
+BECOME_DISCOVERABLE_TIMEOUT_SEC = constants.BECOME_DISCOVERABLE_TIMEOUT_SEC
+START_ADVERTISING_TIMEOUT_SEC = constants.START_ADVERTISING_TIMEOUT_SEC
+SCAN_TIMEOUT_SEC = constants.SCAN_TIMEOUT_SEC
+
+
+class SeekerDiscoverProviderTest(fast_pair_base_test.FastPairBaseTest):
+    """Fast Pair seeker discover provider test."""
+
+    def setup_test(self) -> None:
+        super().setup_test()
+        self._provider.start_model_id_advertising(
+            PROVIDER_SIMULATOR_MODEL_ID, PROVIDER_SIMULATOR_ANTI_SPOOFING_KEY)
+        self._provider.wait_for_discoverable_mode(BECOME_DISCOVERABLE_TIMEOUT_SEC)
+        self._provider.wait_for_advertising_start(START_ADVERTISING_TIMEOUT_SEC)
+        self._seeker.start_scan()
+
+    def teardown_test(self) -> None:
+        self._seeker.stop_scan()
+        self._provider.teardown_provider_simulator()
+        super().teardown_test()
+
+    def test_seeker_start_scanning_find_provider(self) -> None:
+        provider_ble_mac_address = self._provider.get_ble_mac_address()
+        self._seeker.wait_and_assert_provider_found(
+            timeout_seconds=SCAN_TIMEOUT_SEC,
+            expected_model_id=PROVIDER_SIMULATOR_MODEL_ID,
+            expected_ble_mac_address=provider_ble_mac_address)
diff --git a/nearby/tests/multidevices/host/seeker_show_halfsheet_test.py b/nearby/tests/multidevices/host/seeker_show_halfsheet_test.py
new file mode 100644
index 0000000..f6561e5
--- /dev/null
+++ b/nearby/tests/multidevices/host/seeker_show_halfsheet_test.py
@@ -0,0 +1,56 @@
+#  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.
+
+"""CTS-V Nearby Mainline Fast Pair end-to-end test case: seeker show half sheet UI."""
+
+from test_helper import constants
+from test_helper import fast_pair_base_test
+
+# The model ID to simulate on provider side.
+PROVIDER_SIMULATOR_MODEL_ID = constants.DEFAULT_MODEL_ID
+# The public key to simulate as registered headsets.
+PROVIDER_SIMULATOR_ANTI_SPOOFING_KEY = constants.DEFAULT_ANTI_SPOOFING_KEY
+# The anti-spoof key device metadata JSON file for data provider at seeker side.
+PROVIDER_SIMULATOR_KDM_JSON_FILE = constants.DEFAULT_KDM_JSON_FILE
+
+# Time in seconds for events waiting.
+SETUP_TIMEOUT_SEC = constants.SETUP_TIMEOUT_SEC
+BECOME_DISCOVERABLE_TIMEOUT_SEC = constants.BECOME_DISCOVERABLE_TIMEOUT_SEC
+START_ADVERTISING_TIMEOUT_SEC = constants.START_ADVERTISING_TIMEOUT_SEC
+HALF_SHEET_POPUP_TIMEOUT_SEC = constants.HALF_SHEET_POPUP_TIMEOUT_SEC
+
+
+class SeekerShowHalfSheetTest(fast_pair_base_test.FastPairBaseTest):
+    """Fast Pair seeker show half sheet UI test."""
+
+    def setup_test(self) -> None:
+        super().setup_test()
+        self._provider.start_model_id_advertising(PROVIDER_SIMULATOR_MODEL_ID,
+                                                  PROVIDER_SIMULATOR_ANTI_SPOOFING_KEY)
+        self._provider.wait_for_discoverable_mode(BECOME_DISCOVERABLE_TIMEOUT_SEC)
+        self._provider.wait_for_advertising_start(START_ADVERTISING_TIMEOUT_SEC)
+        self._seeker.put_anti_spoof_key_device_metadata(PROVIDER_SIMULATOR_MODEL_ID,
+                                                        PROVIDER_SIMULATOR_KDM_JSON_FILE)
+        self._seeker.set_fast_pair_scan_enabled(True)
+
+    def teardown_test(self) -> None:
+        self._seeker.set_fast_pair_scan_enabled(False)
+        self._provider.teardown_provider_simulator()
+        self._seeker.dismiss_halfsheet()
+        super().teardown_test()
+
+    def test_seeker_show_half_sheet(self) -> None:
+        self._seeker.wait_and_assert_halfsheet_showed(
+            timeout_seconds=HALF_SHEET_POPUP_TIMEOUT_SEC,
+            expected_model_id=PROVIDER_SIMULATOR_MODEL_ID)
diff --git a/nearby/tests/multidevices/host/suite_main.py b/nearby/tests/multidevices/host/suite_main.py
new file mode 100644
index 0000000..4f5d48c
--- /dev/null
+++ b/nearby/tests/multidevices/host/suite_main.py
@@ -0,0 +1,41 @@
+#  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.
+
+"""The entry point for Nearby Mainline multi devices end-to-end test suite."""
+
+import logging
+import sys
+
+from mobly import suite_runner
+
+import initial_pairing_test
+import seeker_discover_provider_test
+import seeker_show_halfsheet_test
+
+_BOOTSTRAP_LOGGING_FILENAME = '/tmp/nearby_multi_devices_test_suite_log.txt'
+_TEST_CLASSES_LIST = [
+    seeker_discover_provider_test.SeekerDiscoverProviderTest,
+    seeker_show_halfsheet_test.SeekerShowHalfSheetTest,
+    initial_pairing_test.InitialPairingTest,
+]
+
+
+def _valid_argument(arg: str) -> bool:
+    return arg.startswith(('--config', '-c', '--tests', '--test_case'))
+
+
+if __name__ == '__main__':
+    logging.basicConfig(filename=_BOOTSTRAP_LOGGING_FILENAME, level=logging.INFO)
+    suite_runner.run_suite(argv=[arg for arg in sys.argv if _valid_argument(arg)],
+                           test_classes=_TEST_CLASSES_LIST)
diff --git a/nearby/tests/multidevices/host/test_data/fastpair/pixelbuds-a_account_devicemeta_json.txt b/nearby/tests/multidevices/host/test_data/fastpair/pixelbuds-a_account_devicemeta_json.txt
new file mode 100644
index 0000000..6be58df
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_data/fastpair/pixelbuds-a_account_devicemeta_json.txt
@@ -0,0 +1,66 @@
+[
+  {
+    "account_key": "BPy5AaSyMfrFvMNgr6f7GA==",
+    "sha256_account_key_public_address": "jNGRz+Ni6ZuLd8hVF3lmGoJnF5byXBUyVi9CmnrF1so=",
+    "fast_pair_device_metadata": {
+      "image_url": "https:\/\/lh3.googleusercontent.com\/2PffmZiopo2AjT8sshX0Se3jV-91cp4yOCIay2bBvZqKoKGVy5B4uyzdHsde6UrUSGaoCqV-h4edd5ZljA4oSGc",
+      "intent_uri": "intent:#Intent;action=com.google.android.gms.nearby.discovery%3AACTION_MAGIC_PAIR;package=com.google.android.gms;component=com.google.android.gms\/.nearby.discovery.service.DiscoveryService;S.com.google.android.gms.nearby.discovery%3AEXTRA_COMPANION_APP=com.google.android.apps.wearables.maestro.companion;end",
+      "ble_tx_power": 0,
+      "trigger_distance": 0,
+      "device_type": 0,
+      "left_bud_url": "",
+      "right_bud_url": "",
+      "case_url": "",
+      "initial_notification_description": "Tap to pair. Earbuds will be tied to %s",
+      "initial_notification_description_no_account": "Tap to pair with this device",
+      "initial_pairing_description": "Pixel Buds A-Series will appear on devices linked with ericth.nearby.dogfood@gmail.com",
+      "connect_success_companion_app_installed": "Your device is ready to be set up",
+      "connect_success_companion_app_not_installed": "Download the device app on Google Play to see all available features",
+      "subsequent_pairing_description": "Connect %s to this phone",
+      "retroactive_pairing_description": "Save device to %s for faster pairing to your other devices",
+      "wait_launch_companion_app_description": "This will take a few moments",
+      "fail_connect_go_to_settings_description": "Try manually pairing to the device by going to Settings",
+      "confirm_pin_title": "",
+      "confirm_pin_description": "",
+      "sync_contacts_title": "",
+      "sync_contacts_description": "",
+      "sync_sms_title": "",
+      "sync_sms_description": "",
+      "assistant_setup_half_sheet": "Get hands-free help on the go from Google Assistant",
+      "assistant_setup_notification": "Tap to set up your Google Assistant",
+      "fast_pair_tv_connect_device_no_account_description": "Select connect to pair your %s with this device"
+    },
+    "fast_pair_discovery_item": {
+      "id": "",
+      "type": 6,
+      "mac_address": "",
+      "action_url": "intent:#Intent;action=com.google.android.gms.nearby.discovery%3AACTION_MAGIC_PAIR;package=com.google.android.gms;component=com.google.android.gms\/.nearby.discovery.service.DiscoveryService;S.com.google.android.gms.nearby.discovery%3AEXTRA_COMPANION_APP=com.google.android.apps.wearables.maestro.companion;end",
+      "device_name": "",
+      "title": "Pixel Buds A-Series",
+      "description": "Tap to pair with this device",
+      "display_url": "",
+      "last_observation_timestamp_millis": 0,
+      "first_observation_timestamp_millis": 0,
+      "state": 1,
+      "action_url_type": 2,
+      "rssi": 0,
+      "pending_app_install_timestamp_millis": 0,
+      "tx_power": 0,
+      "app_name": "",
+      "group_id": "",
+      "attachment_type": 0,
+      "package_name": "",
+      "feature_graphic_url": "",
+      "trigger_id": "",
+      "icon_png": "",
+      "icon_fife_url": "https:\/\/lh3.googleusercontent.com\/2PffmZiopo2AjT8sshX0Se3jV-91cp4yOCIay2bBvZqKoKGVy5B4uyzdHsde6UrUSGaoCqV-h4edd5ZljA4oSGc",
+      "debug_message": "",
+      "debug_category": 0,
+      "lost_millis": 0,
+      "last_user_experience": 0,
+      "ble_record_bytes": "",
+      "entity_id": "",
+      "authentication_public_key_secp256r1": "z+grhW8lWVA34JUQhXOxMrk1WqVy+VpEDd2K+01ZJvS6KdV0OUg7FRMzq+ITuOqKO\/2TIRKEAEfMKdyk2Ob1Vw=="
+    }
+  }
+]
\ No newline at end of file
diff --git a/nearby/tests/multidevices/host/test_data/fastpair/pixelbuds-a_antispoofkey_devicemeta_json.txt b/nearby/tests/multidevices/host/test_data/fastpair/pixelbuds-a_antispoofkey_devicemeta_json.txt
new file mode 100644
index 0000000..c03d000
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_data/fastpair/pixelbuds-a_antispoofkey_devicemeta_json.txt
@@ -0,0 +1,38 @@
+{
+  "anti_spoofing_public_key_str": "z+grhW8lWVA34JUQhXOxMrk1WqVy+VpEDd2K+01ZJvS6KdV0OUg7FRMzq+ITuOqKO\/2TIRKEAEfMKdyk2Ob1Vw==",
+  "fast_pair_device_metadata": {
+    "image_url": "https:\/\/lh3.googleusercontent.com\/2PffmZiopo2AjT8sshX0Se3jV-91cp4yOCIay2bBvZqKoKGVy5B4uyzdHsde6UrUSGaoCqV-h4edd5ZljA4oSGc",
+    "intent_uri": "intent:#Intent;action=com.google.android.gms.nearby.discovery%3AACTION_MAGIC_PAIR;package=com.google.android.gms;component=com.google.android.gms\/.nearby.discovery.service.DiscoveryService;S.com.google.android.gms.nearby.discovery%3AEXTRA_COMPANION_APP=com.google.android.apps.wearables.maestro.companion;end",
+    "ble_tx_power": -11,
+    "trigger_distance": 0.6000000238418579,
+    "device_type": 7,
+    "name": "Pixel Buds A-Series",
+    "left_bud_url": "https:\/\/lh3.googleusercontent.com\/O8SVJ5E7CXUkpkym7ibZbp6wypuO7HaTFcslT_FjmEzJX4KHoIY_kzLTdK2kwJXiDBgg8cC__sG-JJ5aVnQtFjQ",
+    "right_bud_url": "https:\/\/lh3.googleusercontent.com\/X_FsRmEKH_fgKzvopyrlyWJAdczRel42Tih7p9-e-U48gBTaggGVQx70K27TzlqIaqYVuaNpTnGoUsKIgiy4WA",
+    "case_url": "https:\/\/lh3.googleusercontent.com\/mNZ7CGplQSpZhoY79jXDQU4B65eY2f0SndnYZLk1PSm8zKTYeRU7REmrLL_pptD6HpVI2F_oQ6xhhtZKOvB8EQ",
+    "locale": "en-US",
+    "initial_notification_description": "Tap to pair. Earbuds will be tied to %s",
+    "initial_notification_description_no_account": "Tap to pair with this device",
+    "open_companion_app_description": "Tap to finish setup",
+    "update_companion_app_description": "Tap to update device settings and finish setup",
+    "download_companion_app_description": "Tap to download device app on Google Play and see all features",
+    "unable_to_connect_title": "Unable to connect",
+    "unable_to_connect_description": "Try manually pairing to the device",
+    "initial_pairing_description": "%s will appear on devices linked with %s",
+    "connect_success_companion_app_installed": "Your device is ready to be set up",
+    "connect_success_companion_app_not_installed": "Download the device app on Google Play to see all available features",
+    "subsequent_pairing_description": "Connect %s to this phone",
+    "retroactive_pairing_description": "Save device to %s for faster pairing to your other devices",
+    "wait_launch_companion_app_description": "This will take a few moments",
+    "fail_connect_go_to_settings_description": "Try manually pairing to the device by going to Settings",
+    "confirm_pin_title": "",
+    "confirm_pin_description": "",
+    "sync_contacts_title": "",
+    "sync_contacts_description": "",
+    "sync_sms_title": "",
+    "sync_sms_description": "",
+    "assistant_setup_half_sheet": "Get hands-free help on the go from Google Assistant",
+    "assistant_setup_notification": "Tap to set up your Google Assistant",
+    "fast_pair_tv_connect_device_no_account_description": "Select connect to pair your %s with this device"
+  }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/host/test_data/fastpair/simulator_account_devicemeta_json.txt b/nearby/tests/multidevices/host/test_data/fastpair/simulator_account_devicemeta_json.txt
new file mode 100644
index 0000000..392c443
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_data/fastpair/simulator_account_devicemeta_json.txt
@@ -0,0 +1,66 @@
+[
+  {
+    "account_key": "BPy5AaSyMfrFvMNgr6f7GA==",
+    "sha256_account_key_public_address": "jNGRz+Ni6ZuLd8hVF3lmGoJnF5byXBUyVi9CmnrF1so=",
+    "fast_pair_device_metadata": {
+      "assistant_setup_half_sheet": "Get hands-free help on the go from Google Assistant",
+      "assistant_setup_notification": "Tap to set up your Google Assistant",
+      "ble_tx_power": 0,
+      "case_url": "",
+      "confirm_pin_description": "",
+      "confirm_pin_title": "",
+      "connect_success_companion_app_installed": "Your device is ready to be set up",
+      "connect_success_companion_app_not_installed": "Download the device app on Google Play to see all available features",
+      "device_type": 0,
+      "fail_connect_go_to_settings_description": "Try manually pairing to the device by going to Settings",
+      "fast_pair_tv_connect_device_no_account_description": "Select connect to pair your %s with this device",
+      "image_url": "https://lh3.googleusercontent.com/2PffmZiopo2AjT8sshX0Se3jV-91cp4yOCIay2bBvZqKoKGVy5B4uyzdHsde6UrUSGaoCqV-h4edd5ZljA4oSGc",
+      "initial_notification_description": "Tap to pair. Earbuds will be tied to %s",
+      "initial_notification_description_no_account": "Tap to pair with this device",
+      "initial_pairing_description": "Pixel Buds A-Series will appear on devices linked with ericth.nearby.dogfood@gmail.com",
+      "intent_uri": "intent:#Intent;action=com.google.android.gms.nearby.discovery%3AACTION_MAGIC_PAIR;package=com.google.android.gms;component=com.google.android.gms/.nearby.discovery.service.DiscoveryService;S.com.google.android.gms.nearby.discovery%3AEXTRA_COMPANION_APP=com.google.android.apps.wearables.maestro.companion;end",
+      "left_bud_url": "",
+      "retroactive_pairing_description": "Save device to %s for faster pairing to your other devices",
+      "right_bud_url": "",
+      "subsequent_pairing_description": "Connect %s to this phone",
+      "sync_contacts_description": "",
+      "sync_contacts_title": "",
+      "sync_sms_description": "",
+      "sync_sms_title": "",
+      "trigger_distance": 0,
+      "wait_launch_companion_app_description": "This will take a few moments"
+    },
+    "fast_pair_discovery_item": {
+      "action_url": "intent:#Intent;action=com.google.android.gms.nearby.discovery%3AACTION_MAGIC_PAIR;package=com.google.android.gms;component=com.google.android.gms/.nearby.discovery.service.DiscoveryService;S.com.google.android.gms.nearby.discovery%3AEXTRA_COMPANION_APP=com.google.android.apps.wearables.maestro.companion;end",
+      "action_url_type": 2,
+      "app_name": "",
+      "attachment_type": 0,
+      "authentication_public_key_secp256r1": "z+grhW8lWVA34JUQhXOxMrk1WqVy+VpEDd2K+01ZJvS6KdV0OUg7FRMzq+ITuOqKO/2TIRKEAEfMKdyk2Ob1Vw==",
+      "ble_record_bytes": "",
+      "debug_category": 0,
+      "debug_message": "",
+      "description": "Tap to pair with this device",
+      "device_name": "",
+      "display_url": "",
+      "entity_id": "",
+      "feature_graphic_url": "",
+      "first_observation_timestamp_millis": 0,
+      "group_id": "",
+      "icon_fife_url": "https://lh3.googleusercontent.com/2PffmZiopo2AjT8sshX0Se3jV-91cp4yOCIay2bBvZqKoKGVy5B4uyzdHsde6UrUSGaoCqV-h4edd5ZljA4oSGc",
+      "icon_png": "",
+      "id": "",
+      "last_observation_timestamp_millis": 0,
+      "last_user_experience": 0,
+      "lost_millis": 0,
+      "mac_address": "",
+      "package_name": "",
+      "pending_app_install_timestamp_millis": 0,
+      "rssi": 0,
+      "state": 1,
+      "title": "Pixel Buds A-Series",
+      "trigger_id": "",
+      "tx_power": 0,
+      "type": 6
+    }
+  }
+]
\ No newline at end of file
diff --git a/nearby/tests/multidevices/host/test_data/fastpair/simulator_antispoofkey_devicemeta_json.txt b/nearby/tests/multidevices/host/test_data/fastpair/simulator_antispoofkey_devicemeta_json.txt
new file mode 100644
index 0000000..7cb29f4
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_data/fastpair/simulator_antispoofkey_devicemeta_json.txt
@@ -0,0 +1,38 @@
+{
+  "anti_spoofing_public_key_str": "sjp\/AOS7+VnTCaueeWorjdeJ8Nc32EOmpe\/QRhzY9+cMNELU1QA3jzgvUXdWW73nl6+EN01eXtLBu2Fw9CGmfA==",
+  "fast_pair_device_metadata": {
+    "assistant_setup_half_sheet": "Get hands-free help on the go from Google Assistant",
+    "assistant_setup_notification": "Tap to set up your Google Assistant",
+    "ble_tx_power": -10,
+    "case_url": "https://lh3.googleusercontent.com/mNZ7CGplQSpZhoY79jXDQU4B65eY2f0SndnYZLk1PSm8zKTYeRU7REmrLL_pptD6HpVI2F_oQ6xhhtZKOvB8EQ",
+    "confirm_pin_description": "",
+    "confirm_pin_title": "",
+    "connect_success_companion_app_installed": "Your device is ready to be set up",
+    "connect_success_companion_app_not_installed": "Download the device app on Google Play to see all available features",
+    "device_type": 7,
+    "download_companion_app_description": "Tap to download device app on Google Play and see all features",
+    "fail_connect_go_to_settings_description": "Try manually pairing to the device by going to Settings",
+    "fast_pair_tv_connect_device_no_account_description": "Select connect to pair your %s with this device",
+    "image_url": "https://lh3.googleusercontent.com/THpAzISZGa5F86cMsBcTPhRWefBPc5dorBxWdOPCGvbFg6ZMHUjFuE-4kbLuoLoIMHf3Fd8jUvvcxnjp_Q",
+    "initial_notification_description": "Tap to pair. Earbuds will be tied to %s",
+    "initial_notification_description_no_account": "Tap to pair with this device",
+    "initial_pairing_description": "%s will appear on devices linked with %s",
+    "intent_uri": "intent:#Intent;action=com.google.android.gms.nearby.discovery%3AACTION_MAGIC_PAIR;package=com.google.android.gms;component=com.google.android.gms/.nearby.discovery.service.DiscoveryService;S.com.google.android.gms.nearby.discovery%3AEXTRA_COMPANION_APP=com.google.android.testapp;end",
+    "left_bud_url": "https://lh3.googleusercontent.com/O8SVJ5E7CXUkpkym7ibZbp6wypuO7HaTFcslT_FjmEzJX4KHoIY_kzLTdK2kwJXiDBgg8cC__sG-JJ5aVnQtFjQ",
+    "locale": "en-US",
+    "name": "Fast Pair Provider Simulator",
+    "open_companion_app_description": "Tap to finish setup",
+    "retroactive_pairing_description": "Save device to %s for faster pairing to your other devices",
+    "right_bud_url": "https://lh3.googleusercontent.com/X_FsRmEKH_fgKzvopyrlyWJAdczRel42Tih7p9-e-U48gBTaggGVQx70K27TzlqIaqYVuaNpTnGoUsKIgiy4WA",
+    "subsequent_pairing_description": "Connect %s to this phone",
+    "sync_contacts_description": "",
+    "sync_contacts_title": "",
+    "sync_sms_description": "",
+    "sync_sms_title": "",
+    "trigger_distance": 0.6000000238418579,
+    "unable_to_connect_description": "Try manually pairing to the device",
+    "unable_to_connect_title": "Unable to connect",
+    "update_companion_app_description": "Tap to update device settings and finish setup",
+    "wait_launch_companion_app_description": "This will take a few moments"
+  }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/host/test_helper/__init__.py b/nearby/tests/multidevices/host/test_helper/__init__.py
new file mode 100644
index 0000000..b0cae91
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_helper/__init__.py
@@ -0,0 +1,13 @@
+#  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.
diff --git a/nearby/tests/multidevices/host/test_helper/constants.py b/nearby/tests/multidevices/host/test_helper/constants.py
new file mode 100644
index 0000000..342be8f
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_helper/constants.py
@@ -0,0 +1,38 @@
+#  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.
+
+# Default model ID to simulate on provider side.
+DEFAULT_MODEL_ID = '00000c'
+
+# Default public key to simulate as registered headsets.
+DEFAULT_ANTI_SPOOFING_KEY = 'Cbj9eCJrTdDgSYxLkqtfADQi86vIaMvxJsQ298sZYWE='
+
+# Default anti-spoof Key Device Metadata JSON file for data provider at seeker side.
+DEFAULT_KDM_JSON_FILE = 'simulator_antispoofkey_devicemeta_json.txt'
+
+# Time in seconds for events waiting according to Fast Pair certification guidelines:
+# https://developers.google.com/nearby/fast-pair/certification-guideline
+SETUP_TIMEOUT_SEC = 5
+BECOME_DISCOVERABLE_TIMEOUT_SEC = 10
+START_ADVERTISING_TIMEOUT_SEC = 5
+SCAN_TIMEOUT_SEC = 5
+HALF_SHEET_POPUP_TIMEOUT_SEC = 5
+AVERAGE_PAIRING_TIMEOUT_SEC = 12
+
+# The phone to simulate Fast Pair provider (like headphone) needs changes in Android system:
+# 1. System permission check removal
+# 2. Adjusts Bluetooth profile configurations
+# The build fingerprint of the custom ROM for Fast Pair provider simulator.
+FAST_PAIR_PROVIDER_SIMULATOR_BUILD_FINGERPRINT = (
+    'google/bramble/bramble:Tiramisu/MASTER/eng.hylo.20211019.091550:userdebug/dev-keys')
diff --git a/nearby/tests/multidevices/host/test_helper/event_helper.py b/nearby/tests/multidevices/host/test_helper/event_helper.py
new file mode 100644
index 0000000..8abf05c
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_helper/event_helper.py
@@ -0,0 +1,69 @@
+#  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 is a shared library to help handling Mobly event waiting logic."""
+
+import time
+from typing import Callable
+
+from mobly.controllers.android_device_lib import callback_handler
+from mobly.controllers.android_device_lib import snippet_event
+
+# Abbreviations for common use type
+CallbackHandler = callback_handler.CallbackHandler
+SnippetEvent = snippet_event.SnippetEvent
+
+# Type definition for the callback functions to make code formatted nicely
+OnReceivedCallback = Callable[[SnippetEvent, int], bool]
+OnWaitingCallback = Callable[[int], None]
+OnMissedCallback = Callable[[], None]
+
+
+def wait_callback_event(callback_event_handler: CallbackHandler,
+                        event_name: str, timeout_seconds: int,
+                        on_received: OnReceivedCallback,
+                        on_waiting: OnWaitingCallback,
+                        on_missed: OnMissedCallback) -> None:
+    """Waits until the matched event has been received or timeout.
+
+    Here we keep waitAndGet for event callback from EventSnippet.
+    We loop until over timeout_seconds instead of directly
+    waitAndGet(timeout=teardown_timeout_seconds). Because there is
+    MAX_TIMEOUT limitation in callback_handler of Mobly.
+
+    Args:
+      callback_event_handler: Mobly callback events handler.
+      event_name: the specific name of the event to wait.
+      timeout_seconds: the number of seconds to wait before giving up.
+      on_received: calls when event received, return false to keep waiting.
+      on_waiting: calls when waitAndGet timeout.
+      on_missed: calls when giving up.
+    """
+    start_time = time.perf_counter()
+    deadline = start_time + timeout_seconds
+    while time.perf_counter() < deadline:
+        remaining_time_sec = min(callback_handler.DEFAULT_TIMEOUT,
+                                 deadline - time.perf_counter())
+        try:
+            event = callback_event_handler.waitAndGet(
+                event_name, timeout=remaining_time_sec)
+        except callback_handler.TimeoutError:
+            elapsed_time = int(time.perf_counter() - start_time)
+            on_waiting(elapsed_time)
+        else:
+            elapsed_time = int(time.perf_counter() - start_time)
+            if on_received(event, elapsed_time):
+                break
+    else:
+        on_missed()
diff --git a/nearby/tests/multidevices/host/test_helper/fast_pair_base_test.py b/nearby/tests/multidevices/host/test_helper/fast_pair_base_test.py
new file mode 100644
index 0000000..8b84839
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_helper/fast_pair_base_test.py
@@ -0,0 +1,75 @@
+#  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.
+
+"""Base for all Nearby Mainline Fast Pair end-to-end test cases."""
+
+from typing import List, Tuple
+
+from mobly import base_test
+from mobly import signals
+from mobly.controllers import android_device
+
+from test_helper import constants
+from test_helper import fast_pair_provider_simulator
+from test_helper import fast_pair_seeker
+
+# Abbreviations for common use type.
+AndroidDevice = android_device.AndroidDevice
+FastPairProviderSimulator = fast_pair_provider_simulator.FastPairProviderSimulator
+FastPairSeeker = fast_pair_seeker.FastPairSeeker
+REQUIRED_BUILD_FINGERPRINT = constants.FAST_PAIR_PROVIDER_SIMULATOR_BUILD_FINGERPRINT
+
+
+class FastPairBaseTest(base_test.BaseTestClass):
+    """Base class for all Nearby Mainline Fast Pair end-to-end classes to inherit."""
+
+    _duts: List[AndroidDevice]
+    _provider: FastPairProviderSimulator
+    _seeker: FastPairSeeker
+
+    def setup_class(self) -> None:
+        super().setup_class()
+        self._duts = self.register_controller(android_device, min_number=2)
+
+        provider_ad, seeker_ad = self._check_devices_supported()
+        self._provider = FastPairProviderSimulator(provider_ad)
+        self._seeker = FastPairSeeker(seeker_ad)
+        self._provider.load_snippet()
+        self._seeker.load_snippet()
+
+    def setup_test(self) -> None:
+        super().setup_test()
+        self._provider.setup_provider_simulator(constants.SETUP_TIMEOUT_SEC)
+
+    def teardown_test(self) -> None:
+        super().teardown_test()
+        # Create per-test excepts of logcat.
+        for dut in self._duts:
+            dut.services.create_output_excerpts_all(self.current_test_info)
+
+    def _check_devices_supported(self) -> Tuple[AndroidDevice, AndroidDevice]:
+        # Assume the 1st phone is provider, the 2nd one is seeker.
+        provider_ad, seeker_ad = self._duts[:2]
+
+        for ad in self._duts:
+            if ad.build_info['build_fingerprint'] == REQUIRED_BUILD_FINGERPRINT:
+                if ad != provider_ad:
+                    provider_ad, seeker_ad = seeker_ad, provider_ad
+                break
+        else:
+            raise signals.TestAbortClass(
+                f'None of phones has custom ROM ({REQUIRED_BUILD_FINGERPRINT}) for Fast Pair '
+                f'provider simulator. Skip all the test cases!')
+
+        return provider_ad, seeker_ad
diff --git a/nearby/tests/multidevices/host/test_helper/fast_pair_provider_simulator.py b/nearby/tests/multidevices/host/test_helper/fast_pair_provider_simulator.py
new file mode 100644
index 0000000..d6484fb
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_helper/fast_pair_provider_simulator.py
@@ -0,0 +1,190 @@
+#  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.
+
+"""Fast Pair provider simulator role."""
+
+from mobly import asserts
+from mobly.controllers import android_device
+from mobly.controllers.android_device_lib import snippet_event
+import retry
+from typing import Optional
+
+from test_helper import event_helper
+
+# The package name of the provider simulator snippet.
+FP_PROVIDER_SIMULATOR_SNIPPETS_PACKAGE = 'android.nearby.multidevices'
+
+# Events reported from the provider simulator snippet.
+ON_A2DP_SINK_PROFILE_CONNECT_EVENT = 'onA2DPSinkProfileConnected'
+ON_SCAN_MODE_CHANGE_EVENT = 'onScanModeChange'
+ON_ADVERTISING_CHANGE_EVENT = 'onAdvertisingChange'
+
+# Target scan mode.
+DISCOVERABLE_MODE = 'DISCOVERABLE'
+
+# Abbreviations for common use type.
+AndroidDevice = android_device.AndroidDevice
+SnippetEvent = snippet_event.SnippetEvent
+wait_for_event = event_helper.wait_callback_event
+
+
+class FastPairProviderSimulator:
+    """A proxy for provider simulator snippet on the device."""
+
+    def __init__(self, ad: AndroidDevice) -> None:
+        self._ad = ad
+        self._ad.debug_tag = 'FastPairProviderSimulator'
+        self._provider_status_callback = None
+
+    def load_snippet(self) -> None:
+        """Starts the provider simulator snippet and connects.
+
+        Raises:
+          SnippetError: Illegal load operations are attempted.
+        """
+        self._ad.load_snippet(
+            name='fp', package=FP_PROVIDER_SIMULATOR_SNIPPETS_PACKAGE)
+
+    def setup_provider_simulator(self, timeout_seconds: int) -> None:
+        """Sets up the Fast Pair provider simulator.
+
+        Args:
+          timeout_seconds: The number of seconds to wait before giving up.
+        """
+        setup_status_callback = self._ad.fp.setupProviderSimulator()
+
+        def _on_a2dp_sink_profile_connect_event_received(_, elapsed_time: int) -> bool:
+            self._ad.log.info('Provider simulator connected to A2DP sink in %d seconds.',
+                              elapsed_time)
+            return True
+
+        def _on_a2dp_sink_profile_connect_event_waiting(elapsed_time: int) -> None:
+            self._ad.log.info(
+                'Still waiting "%s" event callback from provider side '
+                'after %d seconds...', ON_A2DP_SINK_PROFILE_CONNECT_EVENT, elapsed_time)
+
+        def _on_a2dp_sink_profile_connect_event_missed() -> None:
+            asserts.fail(f'Timed out after {timeout_seconds} seconds waiting for '
+                         f'the specific "{ON_A2DP_SINK_PROFILE_CONNECT_EVENT}" event.')
+
+        wait_for_event(
+            callback_event_handler=setup_status_callback,
+            event_name=ON_A2DP_SINK_PROFILE_CONNECT_EVENT,
+            timeout_seconds=timeout_seconds,
+            on_received=_on_a2dp_sink_profile_connect_event_received,
+            on_waiting=_on_a2dp_sink_profile_connect_event_waiting,
+            on_missed=_on_a2dp_sink_profile_connect_event_missed)
+
+    def start_model_id_advertising(self, model_id: str, anti_spoofing_key: str) -> None:
+        """Starts model id advertising for scanning and initial pairing.
+
+        Args:
+          model_id: A 3-byte hex string for seeker side to recognize the device (ex:
+            0x00000C).
+          anti_spoofing_key: A public key for registered headsets.
+        """
+        self._ad.log.info(
+            'Provider simulator starts advertising as model id "%s" with anti-spoofing key "%s".',
+            model_id, anti_spoofing_key)
+        self._provider_status_callback = (
+            self._ad.fp.startModelIdAdvertising(model_id, anti_spoofing_key))
+
+    def teardown_provider_simulator(self) -> None:
+        """Tears down the Fast Pair provider simulator."""
+        self._ad.fp.teardownProviderSimulator()
+
+    @retry.retry(tries=3)
+    def get_ble_mac_address(self) -> str:
+        """Gets Bluetooth low energy mac address of the provider simulator.
+
+        The BLE mac address will be set by the AdvertisingSet.getOwnAddress()
+        callback. This is the callback flow in the custom Android build. It takes
+        a while after advertising started so we use retry here to wait it.
+
+        Returns:
+          The BLE mac address of the Fast Pair provider simulator.
+        """
+        return self._ad.fp.getBluetoothLeAddress()
+
+    def wait_for_discoverable_mode(self, timeout_seconds: int) -> None:
+        """Waits onScanModeChange event to ensure provider is discoverable.
+
+        Args:
+          timeout_seconds: The number of seconds to wait before giving up.
+        """
+
+        def _on_scan_mode_change_event_received(
+                scan_mode_change_event: SnippetEvent, elapsed_time: int) -> bool:
+            scan_mode = scan_mode_change_event.data['mode']
+            self._ad.log.info(
+                'Provider simulator changed the scan mode to %s in %d seconds.',
+                scan_mode, elapsed_time)
+            return scan_mode == DISCOVERABLE_MODE
+
+        def _on_scan_mode_change_event_waiting(elapsed_time: int) -> None:
+            self._ad.log.info(
+                'Still waiting "%s" event callback from provider side '
+                'after %d seconds...', ON_SCAN_MODE_CHANGE_EVENT, elapsed_time)
+
+        def _on_scan_mode_change_event_missed() -> None:
+            asserts.fail(f'Timed out after {timeout_seconds} seconds waiting for '
+                         f'the specific "{ON_SCAN_MODE_CHANGE_EVENT}" event.')
+
+        wait_for_event(
+            callback_event_handler=self._provider_status_callback,
+            event_name=ON_SCAN_MODE_CHANGE_EVENT,
+            timeout_seconds=timeout_seconds,
+            on_received=_on_scan_mode_change_event_received,
+            on_waiting=_on_scan_mode_change_event_waiting,
+            on_missed=_on_scan_mode_change_event_missed)
+
+    def wait_for_advertising_start(self, timeout_seconds: int) -> None:
+        """Waits onAdvertisingChange event to ensure provider is advertising.
+
+        Args:
+          timeout_seconds: The number of seconds to wait before giving up.
+        """
+
+        def _on_advertising_mode_change_event_received(
+                scan_mode_change_event: SnippetEvent, elapsed_time: int) -> bool:
+            advertising_mode = scan_mode_change_event.data['isAdvertising']
+            self._ad.log.info(
+                'Provider simulator changed the advertising mode to %s in %d seconds.',
+                advertising_mode, elapsed_time)
+            return advertising_mode
+
+        def _on_advertising_mode_change_event_waiting(elapsed_time: int) -> None:
+            self._ad.log.info(
+                'Still waiting "%s" event callback from provider side '
+                'after %d seconds...', ON_ADVERTISING_CHANGE_EVENT, elapsed_time)
+
+        def _on_advertising_mode_change_event_missed() -> None:
+            asserts.fail(f'Timed out after {timeout_seconds} seconds waiting for '
+                         f'the specific "{ON_ADVERTISING_CHANGE_EVENT}" event.')
+
+        wait_for_event(
+            callback_event_handler=self._provider_status_callback,
+            event_name=ON_ADVERTISING_CHANGE_EVENT,
+            timeout_seconds=timeout_seconds,
+            on_received=_on_advertising_mode_change_event_received,
+            on_waiting=_on_advertising_mode_change_event_waiting,
+            on_missed=_on_advertising_mode_change_event_missed)
+
+    def get_latest_received_account_key(self) -> Optional[str]:
+        """Gets the latest account key received on the provider side.
+
+        Returns:
+          The account key received at provider side.
+        """
+        return self._ad.fp.getLatestReceivedAccountKey()
diff --git a/nearby/tests/multidevices/host/test_helper/fast_pair_seeker.py b/nearby/tests/multidevices/host/test_helper/fast_pair_seeker.py
new file mode 100644
index 0000000..64fc2f2
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_helper/fast_pair_seeker.py
@@ -0,0 +1,186 @@
+#  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.
+
+"""Fast Pair seeker role."""
+
+import json
+from typing import Callable, Optional
+
+from mobly import asserts
+from mobly.controllers import android_device
+from mobly.controllers.android_device_lib import snippet_event
+
+from test_helper import event_helper
+from test_helper import utils
+
+# The package name of the Nearby Mainline Fast Pair seeker Mobly snippet.
+FP_SEEKER_SNIPPETS_PACKAGE = 'android.nearby.multidevices'
+
+# Events reported from the seeker snippet.
+ON_PROVIDER_FOUND_EVENT = 'onDiscovered'
+ON_MANAGE_ACCOUNT_DEVICE_EVENT = 'onManageAccountDevice'
+
+# Abbreviations for common use type.
+AndroidDevice = android_device.AndroidDevice
+JsonObject = utils.JsonObject
+ProviderAccountKeyCallable = Callable[[], Optional[str]]
+SnippetEvent = snippet_event.SnippetEvent
+wait_for_event = event_helper.wait_callback_event
+
+
+class FastPairSeeker:
+    """A proxy for seeker snippet on the device."""
+
+    def __init__(self, ad: AndroidDevice) -> None:
+        self._ad = ad
+        self._ad.debug_tag = 'MainlineFastPairSeeker'
+        self._scan_result_callback = None
+        self._pairing_result_callback = None
+
+    def load_snippet(self) -> None:
+        """Starts the seeker snippet and connects.
+
+        Raises:
+          SnippetError: Illegal load operations are attempted.
+        """
+        self._ad.load_snippet(name='fp', package=FP_SEEKER_SNIPPETS_PACKAGE)
+
+    def start_scan(self) -> None:
+        """Starts scanning to find Fast Pair provider devices."""
+        self._scan_result_callback = self._ad.fp.startScan()
+
+    def stop_scan(self) -> None:
+        """Stops the Fast Pair seeker scanning."""
+        self._ad.fp.stopScan()
+
+    def wait_and_assert_provider_found(self, timeout_seconds: int,
+                                       expected_model_id: str,
+                                       expected_ble_mac_address: str) -> None:
+        """Waits and asserts any onDiscovered event from the seeker.
+
+        Args:
+          timeout_seconds: The number of seconds to wait before giving up.
+          expected_model_id: The expected model ID of the remote Fast Pair provider
+            device.
+          expected_ble_mac_address: The expected BLE MAC address of the remote Fast
+            Pair provider device.
+        """
+
+        def _on_provider_found_event_received(provider_found_event: SnippetEvent,
+                                              elapsed_time: int) -> bool:
+            nearby_device_str = provider_found_event.data['device']
+            self._ad.log.info('Seeker discovered first provider(%s) in %d seconds.',
+                              nearby_device_str, elapsed_time)
+            return expected_ble_mac_address in nearby_device_str
+
+        def _on_provider_found_event_waiting(elapsed_time: int) -> None:
+            self._ad.log.info(
+                'Still waiting "%s" event callback from seeker side '
+                'after %d seconds...', ON_PROVIDER_FOUND_EVENT, elapsed_time)
+
+        def _on_provider_found_event_missed() -> None:
+            asserts.fail(f'Timed out after {timeout_seconds} seconds waiting for '
+                         f'the specific "{ON_PROVIDER_FOUND_EVENT}" event.')
+
+        wait_for_event(
+            callback_event_handler=self._scan_result_callback,
+            event_name=ON_PROVIDER_FOUND_EVENT,
+            timeout_seconds=timeout_seconds,
+            on_received=_on_provider_found_event_received,
+            on_waiting=_on_provider_found_event_waiting,
+            on_missed=_on_provider_found_event_missed)
+
+    def put_anti_spoof_key_device_metadata(self, model_id: str, kdm_json_file_name: str) -> None:
+        """Puts a model id to FastPairAntispoofKeyDeviceMetadata pair into test data cache.
+
+        Args:
+          model_id: A string of model id to be associated with.
+          kdm_json_file_name: The FastPairAntispoofKeyDeviceMetadata JSON object.
+        """
+        self._ad.log.info('Puts FastPairAntispoofKeyDeviceMetadata into test data cache for '
+                          'model id "%s".', model_id)
+        kdm_json_object = utils.load_json_fast_pair_test_data(kdm_json_file_name)
+        self._ad.fp.putAntispoofKeyDeviceMetadata(
+            model_id,
+            utils.serialize_as_simplified_json_str(kdm_json_object))
+
+    def set_fast_pair_scan_enabled(self, enable: bool) -> None:
+        """Writes into Settings whether Fast Pair scan is enabled.
+
+        Args:
+          enable: whether the Fast Pair scan should be enabled.
+        """
+        self._ad.log.info('%s Fast Pair scan in Android settings.',
+                          'Enables' if enable else 'Disables')
+        self._ad.fp.setFastPairScanEnabled(enable)
+
+    def wait_and_assert_halfsheet_showed(self, timeout_seconds: int,
+                                         expected_model_id: str) -> None:
+        """Waits and asserts the onHalfSheetShowed event from the seeker.
+
+        Args:
+          timeout_seconds: The number of seconds to wait before giving up.
+          expected_model_id: A 3-byte hex string for seeker side to recognize
+            the remote provider device (ex: 0x00000c).
+        """
+        self._ad.log.info('Waits and asserts the half sheet showed for model id "%s".',
+                          expected_model_id)
+        self._ad.fp.waitAndAssertHalfSheetShowed(expected_model_id, timeout_seconds)
+
+    def dismiss_halfsheet(self) -> None:
+        """Dismisses the half sheet UI if showed."""
+        self._ad.fp.dismissHalfSheet()
+
+    def start_pairing(self) -> None:
+        """Starts pairing the provider via "Connect" button on half sheet UI."""
+        self._pairing_result_callback = self._ad.fp.startPairing()
+
+    def wait_and_assert_account_device(
+            self, timeout_seconds: int,
+            get_account_key_from_provider: ProviderAccountKeyCallable) -> None:
+        """Waits and asserts the onHalfSheetShowed event from the seeker.
+
+        Args:
+          timeout_seconds: The number of seconds to wait before giving up.
+          get_account_key_from_provider: The callable to get expected account key from the provider
+            side.
+        """
+
+        def _on_manage_account_device_event_received(manage_account_device_event: SnippetEvent,
+                                                     elapsed_time: int) -> bool:
+            account_key_json_str = manage_account_device_event.data['accountDeviceJsonString']
+            account_key_from_seeker = json.loads(account_key_json_str)['account_key']
+            account_key_from_provider = get_account_key_from_provider()
+            self._ad.log.info('Seeker add an account device with account key "%s" in %d seconds.',
+                              account_key_from_seeker, elapsed_time)
+            self._ad.log.info('The latest provider side account key is "%s".',
+                              account_key_from_provider)
+            return account_key_from_seeker == account_key_from_provider
+
+        def _on_manage_account_device_event_waiting(elapsed_time: int) -> None:
+            self._ad.log.info(
+                'Still waiting "%s" event callback from seeker side '
+                'after %d seconds...', ON_MANAGE_ACCOUNT_DEVICE_EVENT, elapsed_time)
+
+        def _on_manage_account_device_event_missed() -> None:
+            asserts.fail(f'Timed out after {timeout_seconds} seconds waiting for '
+                         f'the specific "{ON_MANAGE_ACCOUNT_DEVICE_EVENT}" event.')
+
+        wait_for_event(
+            callback_event_handler=self._pairing_result_callback,
+            event_name=ON_MANAGE_ACCOUNT_DEVICE_EVENT,
+            timeout_seconds=timeout_seconds,
+            on_received=_on_manage_account_device_event_received,
+            on_waiting=_on_manage_account_device_event_waiting,
+            on_missed=_on_manage_account_device_event_missed)
diff --git a/nearby/tests/multidevices/host/test_helper/utils.py b/nearby/tests/multidevices/host/test_helper/utils.py
new file mode 100644
index 0000000..a0acb57
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_helper/utils.py
@@ -0,0 +1,42 @@
+#  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.
+
+import json
+import pathlib
+import sys
+from typing import Any, Dict
+
+# Type definition
+JsonObject = Dict[str, Any]
+
+
+def load_json_fast_pair_test_data(json_file_name: str) -> JsonObject:
+    """Loads a JSON text file from test data directory into a Json object.
+
+    Args:
+      json_file_name: The name of the JSON file.
+    """
+    return json.loads(
+        pathlib.Path(sys.argv[0]).parent.joinpath(
+            'test_data', 'fastpair', json_file_name).read_text()
+    )
+
+
+def serialize_as_simplified_json_str(json_data: JsonObject) -> str:
+    """Serializes a JSON object into a string without empty space.
+
+    Args:
+      json_data: The JSON object to be serialized.
+    """
+    return json.dumps(json_data, separators=(',', ':'))
diff --git a/nearby/tests/multidevices/host/tool/fast_pair_data_provider_shell.sh b/nearby/tests/multidevices/host/tool/fast_pair_data_provider_shell.sh
new file mode 100755
index 0000000..a74c1a9
--- /dev/null
+++ b/nearby/tests/multidevices/host/tool/fast_pair_data_provider_shell.sh
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+#
+# 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.
+
+# A script to interactively manage FastPairTestDataCache of FastPairTestDataProviderService.
+#
+# FastPairTestDataProviderService (../../clients/test_service/fastpair_seeker_data_provider/) is a
+# run-Time configurable FastPairDataProviderService. It has a FastPairTestDataManager to receive
+# Intent broadcast to add/clear the FastPairTestDataCache. This cache provides the data to return to
+# the Nearby Mainline module for onXXX calls (ex: onLoadFastPairAntispoofKeyDeviceMetadata).
+#
+# To use this tool, make sure you:
+# 1. Flash the ROM your built to the device
+# 2. Build and install NearbyFastPairSeekerDataProvider to the device
+# m NearbyFastPairSeekerDataProvider
+# adb install -r -g ${ANDROID_PRODUCT_OUT}/system/app/NearbyFastPairSeekerDataProvider/NearbyFastPairSeekerDataProvider.apk
+# 3. Check FastPairService can connect to the FastPairTestDataProviderService.
+# adb logcat ServiceMonitor:* *:S
+# (ex: ServiceMonitor: [FAST_PAIR_DATA_PROVIDER] connected to {
+# android.nearby.fastpair.seeker.dataprovider/android.nearby.fastpair.seeker.dataprovider.FastPairTestDataProviderService})
+#
+# Sample Usages:
+# 1. Send FastPairAntispoofKeyDeviceMetadata for PixelBuds-A to FastPairTestDataCache
+# ./fast_pair_data_provider_shell.sh -m=718c17  -a=../test_data/fastpair/pixelbuds-a_antispoofkey_devicemeta_json.txt
+# 2. Send FastPairAccountDevicesMetadata for PixelBuds-A to FastPairTestDataCache
+# ./fast_pair_data_provider_shell.sh -d=../test_data/fastpair/pixelbuds-a_account_devicemeta_json.txt
+# 3. Send FastPairAntispoofKeyDeviceMetadata for Provider Simulator to FastPairTestDataCache
+# ./fast_pair_data_provider_shell.sh -m=00000c -a=../test_data/fastpair/simulator_antispoofkey_devicemeta_json.txt
+# 4. Send FastPairAccountDevicesMetadata for Provider Simulator to FastPairTestDataCache
+# ./fast_pair_data_provider_shell.sh -d=../test_data/fastpair/simulator_account_devicemeta_json.txt
+# 5. Clear FastPairTestDataCache
+# ./fast_pair_data_provider_shell.sh -c
+#
+# Check logcat:
+# adb logcat FastPairTestDataManager:* FastPairTestDataProviderService:* *:S
+
+for i in "$@"; do
+  case $i in
+    -a=*|--ask=*)
+      ASK_FILE="${i#*=}"
+      shift # past argument=value
+      ;;
+    -m=*|--model=*)
+      MODEL_ID="${i#*=}"
+      shift # past argument=value
+      ;;
+    -d=*|--adm=*)
+      ADM_FILE="${i#*=}"
+      shift # past argument=value
+      ;;
+    -c)
+      CLEAR="true"
+      shift # past argument
+      ;;
+    -*|--*)
+      echo "Unknown option $i"
+      exit 1
+      ;;
+    *)
+      ;;
+  esac
+done
+
+readonly ACTION_BASE="android.nearby.fastpair.seeker.action"
+readonly ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA="$ACTION_BASE.ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA"
+readonly ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA="$ACTION_BASE.ACCOUNT_KEY_DEVICE_METADATA"
+readonly ACTION_RESET_TEST_DATA_CACHE="$ACTION_BASE.RESET"
+readonly DATA_JSON_STRING_KEY="json"
+readonly DATA_MODEL_ID_STRING_KEY="modelId"
+
+if [[ -n "${ASK_FILE}" ]] && [[ -n "${MODEL_ID}" ]]; then
+  echo "Sending AntispoofKeyDeviceMetadata for model ${MODEL_ID} to the FastPairTestDataCache..."
+  ASK_JSON_TEXT=$(tr -d '\n' < "$ASK_FILE")
+  CMD="am broadcast -a $ACTION_SEND_ANTISPOOF_KEY_DEVICE_METADATA "
+  CMD+="-e $DATA_MODEL_ID_STRING_KEY '$MODEL_ID' "
+  CMD+="-e $DATA_JSON_STRING_KEY '\"'$ASK_JSON_TEXT'\"'"
+  CMD="adb shell \"$CMD\""
+  echo "$CMD" && eval "$CMD"
+fi
+
+if [ -n "${ADM_FILE}" ]; then
+  echo "Sending AccountKeyDeviceMetadata to the FastPairTestDataCache..."
+  ADM_JSON_TEXT=$(tr -d '\n' < "$ADM_FILE")
+  CMD="am broadcast -a $ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA "
+  CMD+="-e $DATA_JSON_STRING_KEY '\"'$ADM_JSON_TEXT'\"'"
+  CMD="adb shell \"$CMD\""
+  echo "$CMD" && eval "$CMD"
+fi
+
+if [ -n "${CLEAR}" ]; then
+  echo "Cleaning FastPairTestDataCache..."
+  CMD="adb shell am broadcast -a $ACTION_RESET_TEST_DATA_CACHE"
+  echo "$CMD" && eval "$CMD"
+fi
diff --git a/nearby/tests/robotests/Android.bp b/nearby/tests/robotests/Android.bp
new file mode 100644
index 0000000..56c0107
--- /dev/null
+++ b/nearby/tests/robotests/Android.bp
@@ -0,0 +1,56 @@
+// 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.
+
+//############################################
+// Nearby Robolectric test target. #
+//############################################
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_robolectric_test {
+    name: "NearbyRoboTests",
+    srcs: ["src/**/*.java"],
+    instrumentation_for: "NearbyFakeTestApp",
+    java_resource_dirs: ["config"],
+
+    libs: [
+        "android-support-annotations",
+        "services.core",
+    ],
+
+    static_libs: [
+        "androidx.test.core",
+        "androidx.core_core",
+        "androidx.annotation_annotation",
+        "androidx.legacy_legacy-support-v4",
+        "androidx.recyclerview_recyclerview",
+        "androidx.preference_preference",
+        "androidx.appcompat_appcompat",
+        "androidx.lifecycle_lifecycle-runtime",
+        "androidx.mediarouter_mediarouter-nodeps",
+        "error_prone_annotations",
+        "mockito-robolectric-prebuilt",
+        "service-nearby-pre-jarjar",
+        "truth-prebuilt",
+        "robolectric_android-all-stub",
+        "Robolectric_all-target",
+    ],
+
+    test_options: {
+        // timeout in seconds.
+        timeout: 36000,
+    },
+}
diff --git a/nearby/tests/robotests/AndroidManifest.xml b/nearby/tests/robotests/AndroidManifest.xml
new file mode 100644
index 0000000..25376cf
--- /dev/null
+++ b/nearby/tests/robotests/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.server.nearby.common.bluetooth.fastpair.test">
+</manifest>
diff --git a/nearby/tests/robotests/config/robolectric.properties b/nearby/tests/robotests/config/robolectric.properties
new file mode 100644
index 0000000..932de7d
--- /dev/null
+++ b/nearby/tests/robotests/config/robolectric.properties
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2021 Google Inc.
+#
+# 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.
+#
+sdk=NEWEST_SDK
\ No newline at end of file
diff --git a/nearby/tests/robotests/fake_app/Android.bp b/nearby/tests/robotests/fake_app/Android.bp
new file mode 100644
index 0000000..707b38f
--- /dev/null
+++ b/nearby/tests/robotests/fake_app/Android.bp
@@ -0,0 +1,26 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_app {
+    name: "NearbyFakeTestApp",
+    srcs: ["*.java"],
+    platform_apis: true,
+    optimize: {
+        enabled: false,
+    },
+}
diff --git a/nearby/tests/robotests/fake_app/AndroidManifest.xml b/nearby/tests/robotests/fake_app/AndroidManifest.xml
new file mode 100644
index 0000000..fdb5390
--- /dev/null
+++ b/nearby/tests/robotests/fake_app/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.server.nearby" />
diff --git a/nearby/tests/robotests/fake_app/Empty.java b/nearby/tests/robotests/fake_app/Empty.java
new file mode 100644
index 0000000..96619d5
--- /dev/null
+++ b/nearby/tests/robotests/fake_app/Empty.java
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
+
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Bluelet.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Bluelet.java
new file mode 100644
index 0000000..182fde7
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Bluelet.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower;
+
+import android.os.ParcelUuid;
+
+/**
+ * User interface for mocking and simulation of a Bluetooth device.
+ */
+public interface Bluelet {
+
+    /**
+     * See {@link #setCreateBondOutcome}.
+     */
+    enum CreateBondOutcome {
+        SUCCESS,
+        FAILURE,
+        TIMEOUT
+    }
+
+    /**
+     * See {@link #setIoCapabilities}. Note that Bluetooth specifies a few more choices, but this is
+     * all DeviceShadower currently supports.
+     */
+    enum IoCapabilities {
+        NO_INPUT_NO_OUTPUT,
+        DISPLAY_YES_NO,
+        KEYBOARD_ONLY
+    }
+
+    /**
+     * See {@link #setFetchUuidsTiming}.
+     */
+    enum FetchUuidsTiming {
+        BEFORE_BONDING,
+        AFTER_BONDING,
+        NEVER
+    }
+
+    /**
+     * Set the initial state of the local Bluetooth adapter at the beginning of the test.
+     * <p>This method is not associated with broadcast event and is intended to be called at the
+     * beginning of the test. Allowed states:
+     *
+     * @see android.bluetooth.BluetoothAdapter#STATE_OFF
+     * @see android.bluetooth.BluetoothAdapter#STATE_ON
+     * </p>
+     */
+    Bluelet setAdapterInitialState(int state) throws IllegalArgumentException;
+
+    /**
+     * Set the bluetooth class of the local Bluetooth device at the beginning of the test.
+     * <p>
+     *
+     * @see android.bluetooth.BluetoothClass.Device
+     * @see android.bluetooth.BluetoothClass.Service
+     */
+    Bluelet setBluetoothClass(int bluetoothClass);
+
+    /**
+     * Set the scan mode of the local Bluetooth device at the beginning of the test.
+     */
+    Bluelet setScanMode(int scanMode);
+
+    /**
+     * Set the Bluetooth profiles supported by this device (e.g. A2DP Sink).
+     */
+    Bluelet setProfileUuids(ParcelUuid... profileUuids);
+
+    /**
+     * Makes bond attempts with this device succeed or fail.
+     *
+     * @param failureReason Ignored unless outcome is {@link CreateBondOutcome#FAILURE}. This is
+     * delivered in the intent that indicates bond state has changed to BOND_NONE. Values:
+     * https://cs.corp.google.com/android/frameworks/base/core/java/android/bluetooth/BluetoothDevice.java?rcl=38d9ee4cd661c10e012f71051d23644c65607eed&l=472
+     */
+    Bluelet setCreateBondOutcome(CreateBondOutcome outcome, int failureReason);
+
+    /**
+     * Sets the IO capabilities of this device. When bonding, a device states its IO capabilities in
+     * the pairing request. The pairing variant used depends on the IO capabilities of both devices
+     * (e.g. Just Works is the only available option for a NoInputNoOutput device, while Numeric
+     * Comparison aka Passkey Confirmation is used if both devices have a display and the ability to
+     * confirm/deny).
+     *
+     * @see <a href="https://blog.bluetooth.com/bluetooth-pairing-part-4">Bluetooth blog</a>
+     */
+    Bluelet setIoCapabilities(IoCapabilities ioCapabilities);
+
+    /**
+     * Make the device refuse connections. By default, connections are accepted.
+     *
+     * @param refuse Connections are refused if True.
+     */
+    Bluelet setRefuseConnections(boolean refuse);
+
+    /**
+     * Make the device refuse GATT connections. By default. connections are accepted.
+     *
+     * @param refuse GATT connections are refused if true.
+     */
+    Bluelet setRefuseGattConnections(boolean refuse);
+
+    /**
+     * When to send the ACTION_UUID broadcast. This can be {@link FetchUuidsTiming#BEFORE_BONDING},
+     * {@link FetchUuidsTiming#AFTER_BONDING}, or {@link FetchUuidsTiming#NEVER}. The default is
+     * {@link FetchUuidsTiming#AFTER_BONDING}.
+     */
+    Bluelet setFetchUuidsTiming(FetchUuidsTiming fetchUuidsTiming);
+
+    /**
+     * Adds a bonded device to the BluetoothAdapter.
+     */
+    Bluelet addBondedDevice(String address);
+
+    /**
+     * Enables the CVE-2019-2225 represents that the pairing variant will switch from Just Works to
+     * Consent when local device's io capability is Display Yes/No and remote is NoInputNoOutput.
+     *
+     * @see <a href="https://source.android.com/security/bulletin/2019-12-01#system">the security
+     * bulletin at 2019-12-01</a>
+     */
+    Bluelet enableCVE20192225(boolean value);
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/DeviceShadowEnvironment.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/DeviceShadowEnvironment.java
new file mode 100644
index 0000000..513d649
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/DeviceShadowEnvironment.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower;
+
+import com.android.libraries.testing.deviceshadower.Enums.Distance;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+/**
+ * Environment to setup and config Bluetooth unit test.
+ */
+public class DeviceShadowEnvironment {
+
+    private static final String TAG = "DeviceShadowEnvironment";
+    private static final long RESET_TIMEOUT_MILLIS = 3000;
+
+    private static boolean sIsInitialized = false;
+
+    private DeviceShadowEnvironment() {
+    }
+
+    public static void init() {
+        sIsInitialized = true;
+        DeviceShadowEnvironmentImpl.reset();
+    }
+
+    public static void reset() {
+        sIsInitialized = false;
+
+        // Order matters because each steps check and manipulate internal objects in order.
+        // Wait Scheduler and executors complete, and shut down executors.
+        DeviceShadowEnvironmentImpl.await(RESET_TIMEOUT_MILLIS);
+
+        // Throw RuntimeException if there is any internal exceptions.
+        DeviceShadowEnvironmentImpl.checkInternalExceptions();
+
+        // Clear internal exceptions, and devicelets.
+        DeviceShadowEnvironmentImpl.reset();
+    }
+
+    public static boolean await(long timeoutMillis) {
+        return DeviceShadowEnvironmentImpl.await(timeoutMillis);
+    }
+
+    public static Devicelet addDevice(final String address) {
+        return DeviceShadowEnvironmentImpl.addDevice(address);
+    }
+
+    public static void removeDevice(String address) {
+        DeviceShadowEnvironmentImpl.removeDevice(address);
+    }
+
+    public static void setLocalDevice(final String address) {
+        DeviceShadowEnvironmentImpl.setLocalDevice(address);
+    }
+
+    public static void putNear(String address1, String address2) {
+        DeviceShadowEnvironmentImpl.setDistance(address1, address2, Distance.NEAR);
+    }
+
+    public static void setDistance(String address1, String address2, Distance distance) {
+        DeviceShadowEnvironmentImpl.setDistance(address1, address2, distance);
+    }
+
+    public static Future<Void> run(final String address, final Runnable snippet) {
+        return run(
+                address,
+                () -> {
+                    snippet.run();
+                    return null;
+                });
+    }
+
+    public static <T> Future<T> run(final String address, final Callable<T> snippet) {
+        return DeviceShadowEnvironmentImpl.run(address, snippet);
+    }
+
+    /* package */
+    static boolean isInitialized() {
+        return sIsInitialized;
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/DeviceShadowEnvironmentInternal.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/DeviceShadowEnvironmentInternal.java
new file mode 100644
index 0000000..a5f8e6d
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/DeviceShadowEnvironmentInternal.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower;
+
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.sms.SmsContentProvider;
+
+/**
+ * Internal interface for device shadower.
+ */
+public class DeviceShadowEnvironmentInternal {
+
+    /**
+     * Set an interruptible point to tested code.
+     * <p>
+     * This should only make changes when DeviceShadowEnvironment initialized, which means only in
+     * test cases.
+     */
+    public static void setInterruptibleBluetooth(int identifier) {
+        if (DeviceShadowEnvironment.isInitialized()) {
+            assert identifier > 0;
+            DeviceShadowEnvironmentImpl.setInterruptibleBluetooth(identifier);
+        }
+    }
+
+    /**
+     * Mark all bluetooth operation broken after identifier in tested code.
+     */
+    public static void interruptBluetooth(String address, int identifier) {
+        DeviceShadowEnvironmentImpl.interruptBluetooth(address, identifier);
+    }
+
+    /**
+     * Return SMS content provider to be registered by robolectric context.
+     */
+    public static Class<SmsContentProvider> getSmsContentProviderClass() {
+        return SmsContentProvider.class;
+    }
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Devicelet.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Devicelet.java
new file mode 100644
index 0000000..bf31ead
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Devicelet.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower;
+
+/**
+ * Devicelet is the handler to operate shadowed device objects in DeviceShadower.
+ */
+public interface Devicelet {
+
+    Bluelet bluetooth();
+
+    Nfclet nfc();
+
+    Smslet sms();
+
+    String getAddress();
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Enums.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Enums.java
new file mode 100644
index 0000000..9eb3514
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Enums.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower;
+
+/**
+ * Contains Enums used by DeviceShadower in interface and internally.
+ */
+public interface Enums {
+
+    /**
+     * Represents vague distance between two devicelets.
+     */
+    enum Distance {
+        NEAR,
+        MID,
+        FAR,
+        AWAY,
+    }
+
+    /**
+     * Abstract base interface for operations.
+     */
+    interface Operation {
+
+    }
+
+    /**
+     * NFC operations.
+     */
+    enum NfcOperation implements Operation {
+        GET_ADAPTER,
+        ENABLE,
+        DISABLE,
+    }
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Nfclet.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Nfclet.java
new file mode 100644
index 0000000..4b00f24
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Nfclet.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower;
+
+/**
+ * Interface of Nfclet
+ */
+public interface Nfclet {
+
+    Nfclet setInitialState(int state);
+
+    Nfclet setInterruptOperation(Enums.NfcOperation operation);
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Smslet.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Smslet.java
new file mode 100644
index 0000000..483fab6
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/Smslet.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower;
+
+import android.net.Uri;
+
+/**
+ * Interface of Smslet
+ */
+public interface Smslet {
+
+    Smslet addSms(Uri uri, String body);
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetooth.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetooth.java
new file mode 100644
index 0000000..be8390e
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetooth.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 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 android.bluetooth;
+
+import android.content.AttributionSource;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelUuid;
+
+/**
+ * Fake interface replacement for hidden IBluetooth class
+ */
+public interface IBluetooth {
+
+    // Bluetooth settings.
+    String getAddress();
+
+    String getName();
+
+    boolean setName(String name);
+
+    // Remote device properties.
+    int getRemoteClass(BluetoothDevice device);
+
+    String getRemoteName(BluetoothDevice device);
+
+    int getRemoteType(BluetoothDevice device, AttributionSource attributionSource);
+
+    ParcelUuid[] getRemoteUuids(BluetoothDevice device);
+
+    boolean fetchRemoteUuids(BluetoothDevice device);
+
+    // Bluetooth discovery.
+    int getScanMode();
+
+    boolean setScanMode(int mode, int duration);
+
+    int getDiscoverableTimeout();
+
+    boolean setDiscoverableTimeout(int timeout);
+
+    boolean startDiscovery();
+
+    boolean cancelDiscovery();
+
+    boolean isDiscovering();
+
+    // Adapter state.
+    boolean isEnabled();
+
+    int getState();
+
+    boolean enable();
+
+    boolean disable();
+
+    // Rfcomm sockets.
+    ParcelFileDescriptor connectSocket(BluetoothDevice device, int type, ParcelUuid uuid,
+            int port, int flag);
+
+    ParcelFileDescriptor createSocketChannel(int type, String serviceName, ParcelUuid uuid,
+            int port, int flag);
+
+    // BLE settings.
+    /* SINCE SDK 21 */ boolean isMultiAdvertisementSupported();
+
+    /* SINCE SDK 22 */ boolean isPeripheralModeSupported();
+
+    /* SINCE SDK 21 */  boolean isOffloadedFilteringSupported();
+
+    // Bonding (pairing).
+    int getBondState(BluetoothDevice device, AttributionSource attributionSource);
+
+    boolean createBond(BluetoothDevice device, int transport, OobData remoteP192Data,
+            OobData remoteP256Data, AttributionSource attributionSource);
+
+    boolean setPairingConfirmation(BluetoothDevice device, boolean accept,
+            AttributionSource attributionSource);
+
+    boolean setPasskey(BluetoothDevice device, int passkey);
+
+    boolean cancelBondProcess(BluetoothDevice device);
+
+    boolean removeBond(BluetoothDevice device);
+
+    BluetoothDevice[] getBondedDevices();
+
+    // Connecting to profiles.
+    int getAdapterConnectionState();
+
+    int getProfileConnectionState(int profile);
+
+    // Access permissions
+    int getPhonebookAccessPermission(BluetoothDevice device);
+
+    boolean setPhonebookAccessPermission(BluetoothDevice device, int value);
+
+    int getMessageAccessPermission(BluetoothDevice device);
+
+    boolean setMessageAccessPermission(BluetoothDevice device, int value);
+
+    int getSimAccessPermission(BluetoothDevice device);
+
+    boolean setSimAccessPermission(BluetoothDevice device, int value);
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothGatt.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothGatt.java
new file mode 100644
index 0000000..16e4f01
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothGatt.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 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 android.bluetooth;
+
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanSettings;
+import android.os.ParcelUuid;
+
+import java.util.List;
+
+/**
+ * Fake interface replacement for IBluetoothGatt
+ * TODO(b/200231384): include >=N interface.
+ */
+public interface IBluetoothGatt {
+
+    /* ONLY SDK 23 */
+    void startScan(int appIf, boolean isServer, ScanSettings settings,
+            List<ScanFilter> filters, List<?> scanStorages, String callPackage);
+
+    /* ONLY SDK 21 */
+    void startScan(int appIf, boolean isServer, ScanSettings settings,
+            List<ScanFilter> filters, List<?> scanStorages);
+
+    /* SINCE SDK 21 */
+    void stopScan(int appIf, boolean isServer);
+
+    /* SINCE SDK 21 */
+    void startMultiAdvertising(
+            int appIf, AdvertiseData advertiseData, AdvertiseData scanResponse,
+            AdvertiseSettings settings);
+
+    /* SINCE SDK 21 */
+    void stopMultiAdvertising(int appIf);
+
+    /* SINCE SDK 21 */
+    void registerClient(ParcelUuid appId, IBluetoothGattCallback callback);
+
+    /* SINCE SDK 21 */
+    void unregisterClient(int clientIf);
+
+    /* SINCE SDK 21 */
+    void clientConnect(int clientIf, String address, boolean isDirect, int transport);
+
+    /* SINCE SDK 21 */
+    void clientDisconnect(int clientIf, String address);
+
+    /* SINCE SDK 21 */
+    void discoverServices(int clientIf, String address);
+
+    /* SINCE SDK 21 */
+    void readCharacteristic(int clientIf, String address, int srvcType,
+            int srvcInstanceId, ParcelUuid srvcId, int charInstanceId, ParcelUuid charId,
+            int authReq);
+
+    /* SINCE SDK 21 */
+    void writeCharacteristic(int clientIf, String address, int srvcType,
+            int srvcInstanceId, ParcelUuid srvcId, int charInstanceId, ParcelUuid charId,
+            int writeType, int authReq, byte[] value);
+
+    /* SINCE SDK 21 */
+    void readDescriptor(int clientIf, String address, int srvcType,
+            int srvcInstanceId, ParcelUuid srvcId, int charInstanceId, ParcelUuid charId,
+            int descrInstanceId, ParcelUuid descrUuid, int authReq);
+
+    /* SINCE SDK 21 */
+    void writeDescriptor(int clientIf, String address, int srvcType,
+            int srvcInstanceId, ParcelUuid srvcId, int charInstanceId, ParcelUuid charId,
+            int descrInstanceId, ParcelUuid descrId, int writeType, int authReq, byte[] value);
+
+    /* SINCE SDK 21 */
+    void registerForNotification(int clientIf, String address, int srvcType,
+            int srvcInstanceId, ParcelUuid srvcId, int charInstanceId, ParcelUuid charId,
+            boolean enable);
+
+    /* SINCE SDK 21 */
+    void registerServer(ParcelUuid appId, IBluetoothGattServerCallback callback);
+
+    /* SINCE SDK 21 */
+    void unregisterServer(int serverIf);
+
+    /* SINCE SDK 21 */
+    void serverConnect(int servertIf, String address, boolean isDirect, int transport);
+
+    /* SINCE SDK 21 */
+    void serverDisconnect(int serverIf, String address);
+
+    /* SINCE SDK 21 */
+    void beginServiceDeclaration(int serverIf, int srvcType, int srvcInstanceId, int minHandles,
+            ParcelUuid srvcId, boolean advertisePreferred);
+
+    /* SINCE SDK 21 */
+    void addIncludedService(int serverIf, int srvcType, int srvcInstanceId, ParcelUuid srvcId);
+
+    /* SINCE SDK 21 */
+    void addCharacteristic(int serverIf, ParcelUuid charId, int properties, int permissions);
+
+    /* SINCE SDK 21 */
+    void addDescriptor(int serverIf, ParcelUuid descId, int permissions);
+
+    /* SINCE SDK 21 */
+    void endServiceDeclaration(int serverIf);
+
+    /* SINCE SDK 21 */
+    void removeService(int serverIf, int srvcType, int srvcInstanceId, ParcelUuid srvcId);
+
+    /* SINCE SDK 21 */
+    void clearServices(int serverIf);
+
+    /* SINCE SDK 21 */
+    void sendResponse(int serverIf, String address, int requestId,
+            int status, int offset, byte[] value);
+
+    /* SINCE SDK 21 */
+    void sendNotification(int serverIf, String address, int srvcType,
+            int srvcInstanceId, ParcelUuid srvcId, int charInstanceId, ParcelUuid charId,
+            boolean confirm, byte[] value);
+
+    /* SINCE SDK 21 */
+    void configureMTU(int clientIf, String address, int mtu);
+
+    /* SINCE SDK 21 */
+    void connectionParameterUpdate(int clientIf, String address, int connectionPriority);
+
+    void disconnectAll();
+
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states);
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothGattCallback.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothGattCallback.java
new file mode 100644
index 0000000..b29369b
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothGattCallback.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 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 android.bluetooth;
+
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.ScanResult;
+import android.os.ParcelUuid;
+
+/**
+ * Fake interface replacement for IBluetoothGattCallback
+ * TODO(b/200231384): include >=N interface.
+ */
+public interface IBluetoothGattCallback {
+
+    /* SINCE SDK 21 */
+    void onClientRegistered(int status, int clientIf);
+
+    /* SINCE SDK 21 */
+    void onClientConnectionState(int status, int clientIf, boolean connected, String address);
+
+    /* ONLY SDK 19 */
+    void onScanResult(String address, int rssi, byte[] advData);
+
+    /* SINCE SDK 21 */
+    void onScanResult(ScanResult scanResult);
+
+    /* SINCE SDK 21 */
+    void onGetService(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid);
+
+    /* SINCE SDK 21 */
+    void onGetIncludedService(String address, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int inclSrvcType,
+            int inclSrvcInstId, ParcelUuid inclSrvcUuid);
+
+    /* SINCE SDK 21 */
+    void onGetCharacteristic(String address, int srvcType,
+            int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid,
+            int charProps);
+
+    /* SINCE SDK 21 */
+    void onGetDescriptor(String address, int srvcType,
+            int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid,
+            int descrInstId, ParcelUuid descrUuid);
+
+    /* SINCE SDK 21 */
+    void onSearchComplete(String address, int status);
+
+    /* SINCE SDK 21 */
+    void onCharacteristicRead(String address, int status, int srvcType,
+            int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid,
+            byte[] value);
+
+    /* SINCE SDK 21 */
+    void onCharacteristicWrite(String address, int status, int srvcType,
+            int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid);
+
+    /* SINCE SDK 21 */
+    void onExecuteWrite(String address, int status);
+
+    /* SINCE SDK 21 */
+    void onDescriptorRead(String address, int status, int srvcType,
+            int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid,
+            int descrInstId, ParcelUuid descrUuid,
+            byte[] value);
+
+    /* SINCE SDK 21 */
+    void onDescriptorWrite(String address, int status, int srvcType,
+            int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid,
+            int descrInstId, ParcelUuid descrUuid);
+
+    /* SINCE SDK 21 */
+    void onNotify(String address, int srvcType,
+            int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid,
+            byte[] value);
+
+    /* SINCE SDK 21 */
+    void onReadRemoteRssi(String address, int rssi, int status);
+
+    /* SDK 21 */
+    void onMultiAdvertiseCallback(int status, boolean isStart,
+            AdvertiseSettings advertiseSettings);
+
+    /* SDK 21 */
+    void onConfigureMTU(String address, int mtu, int status);
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothGattServerCallback.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothGattServerCallback.java
new file mode 100644
index 0000000..10b91bb
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothGattServerCallback.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 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 android.bluetooth;
+
+import android.os.ParcelUuid;
+
+/**
+ * Fake interface of internal IBluetoothGattServerCallback.
+ */
+public interface IBluetoothGattServerCallback {
+
+    /* SINCE SDK 21 */
+    void onServerRegistered(int status, int serverIf);
+
+    /* SINCE SDK 21 */
+    void onScanResult(String address, int rssi, byte[] advData);
+
+    /* SINCE SDK 21 */
+    void onServerConnectionState(int status, int serverIf, boolean connected, String address);
+
+    /* SINCE SDK 21 */
+    void onServiceAdded(int status, int srvcType, int srvcInstId, ParcelUuid srvcId);
+
+    /* SINCE SDK 21 */
+    void onCharacteristicReadRequest(String address, int transId, int offset, boolean isLong,
+            int srvcType, int srvcInstId, ParcelUuid srvcId, int charInstId, ParcelUuid charId);
+
+    /* SINCE SDK 21 */
+    void onDescriptorReadRequest(String address, int transId, int offset, boolean isLong,
+            int srvcType, int srvcInstId, ParcelUuid srvcId,
+            int charInstId, ParcelUuid charId, ParcelUuid descrId);
+
+    /* SINCE SDK 21 */
+    void onCharacteristicWriteRequest(String address, int transId, int offset, int length,
+            boolean isPrep, boolean needRsp, int srvcType, int srvcInstId, ParcelUuid srvcId,
+            int charInstId, ParcelUuid charId, byte[] value);
+
+    /* SINCE SDK 21 */
+    void onDescriptorWriteRequest(String address, int transId, int offset, int length,
+            boolean isPrep, boolean needRsp, int srvcType, int srvcInstId, ParcelUuid srvcId,
+            int charInstId, ParcelUuid charId, ParcelUuid descrId, byte[] value);
+
+    /* SINCE SDK 21 */
+    void onExecuteWrite(String address, int transId, boolean execWrite);
+
+    /* SINCE SDK 21 */
+    void onNotificationSent(String address, int status);
+
+    /* SINCE SDK 22 */
+    void onMtuChanged(String address, int mtu);
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothManager.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothManager.java
new file mode 100644
index 0000000..6bb2209
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothManager.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.
+ */
+
+/**
+ * Intentionally in package android.bluetooth to fake existing interface in Android.
+ */
+package android.bluetooth;
+
+/**
+ * Fake interface for IBluetoothManager.
+ */
+public interface IBluetoothManager {
+
+    boolean enable();
+
+    boolean disable(boolean persist);
+
+    String getAddress();
+
+    String getName();
+
+    IBluetooth registerAdapter(IBluetoothManagerCallback callback);
+
+    IBluetoothGatt getBluetoothGatt();
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothManagerCallback.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothManagerCallback.java
new file mode 100644
index 0000000..f39b82f
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/bluetooth/IBluetoothManagerCallback.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 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 android.bluetooth;
+
+/**
+ * Fake interface replacement for hidden IBluetoothManagerCallback class
+ */
+public interface IBluetoothManagerCallback {
+
+}
+
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/nfc/BeamShareData.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/nfc/BeamShareData.java
new file mode 100644
index 0000000..5357a9b
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/nfc/BeamShareData.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 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 android.nfc;
+
+import android.net.Uri;
+import android.os.UserHandle;
+
+/**
+ * Fake BeamShareData.
+ */
+public class BeamShareData {
+
+    public NdefMessage ndefMessage;
+    public Uri[] uris;
+    public UserHandle userHandle;
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/nfc/IAppCallback.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/nfc/IAppCallback.java
new file mode 100644
index 0000000..7b62f19
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/nfc/IAppCallback.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 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 android.nfc;
+
+/**
+ * Fake interface for nfc service.
+ */
+public interface IAppCallback {
+
+    /* M */ void onNdefPushComplete(byte peerLlcpVersion);
+
+    /* M */ BeamShareData createBeamShareData(byte peerLlcpVersion);
+
+    /* L */ void onNdefPushComplete();
+
+    /* L */ BeamShareData createBeamShareData();
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/nfc/INfcAdapter.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/nfc/INfcAdapter.java
new file mode 100644
index 0000000..08acdbc
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/fakes/android/nfc/INfcAdapter.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 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 android.nfc;
+
+/**
+ * Fake interface of INfcAdapter
+ */
+public interface INfcAdapter {
+
+    void setAppCallback(IAppCallback callback);
+
+    boolean enable();
+
+    boolean disable(boolean saveState);
+
+    int getState();
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BleAdvertiser.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BleAdvertiser.java
new file mode 100644
index 0000000..f3328c8
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BleAdvertiser.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.BluetoothLeAdvertiser;
+import android.util.Log;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+
+import com.google.common.base.Preconditions;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+
+/**
+ * Helper class to operate a device as BLE advertiser.
+ */
+public class BleAdvertiser {
+
+    private static final String TAG = "BleAdvertiser";
+
+    private static final int DEFAULT_MODE = AdvertiseSettings.ADVERTISE_MODE_BALANCED;
+    private static final int DEFAULT_TX_POWER_LEVEL = AdvertiseSettings.ADVERTISE_TX_POWER_HIGH;
+    private static final boolean DEFAULT_CONNECTABLE = true;
+    private static final int DEFAULT_TIMEOUT = 0;
+
+
+    /**
+     * Callback of {@link BleAdvertiser}.
+     */
+    public interface Callback {
+
+        void onStartFailure(String address, int errorCode);
+
+        void onStartSuccess(String address, AdvertiseSettings settingsInEffect);
+    }
+
+    /**
+     * Builder class of {@link BleAdvertiser}.
+     */
+    public static final class Builder {
+
+        private final String mAddress;
+        private final Callback mCallback;
+        private AdvertiseSettings mSettings = defaultSettings();
+        private AdvertiseData mData;
+        private AdvertiseData mResponse;
+
+        public Builder(String address, Callback callback) {
+            this.mAddress = Preconditions.checkNotNull(address);
+            this.mCallback = Preconditions.checkNotNull(callback);
+        }
+
+        public Builder setAdvertiseSettings(AdvertiseSettings settings) {
+            this.mSettings = settings;
+            return this;
+        }
+
+        public Builder setAdvertiseData(AdvertiseData data) {
+            this.mData = data;
+            return this;
+        }
+
+        public Builder setResponseData(AdvertiseData response) {
+            this.mResponse = response;
+            return this;
+        }
+
+        public BleAdvertiser build() {
+            return new BleAdvertiser(mAddress, mCallback, mSettings, mData, mResponse);
+        }
+    }
+
+    private static AdvertiseSettings defaultSettings() {
+        return new AdvertiseSettings.Builder()
+                .setAdvertiseMode(DEFAULT_MODE)
+                .setConnectable(DEFAULT_CONNECTABLE)
+                .setTimeout(DEFAULT_TIMEOUT)
+                .setTxPowerLevel(DEFAULT_TX_POWER_LEVEL).build();
+    }
+
+    private final String mAddress;
+    private final Callback mCallback;
+    private final AdvertiseSettings mSettings;
+    private final AdvertiseData mData;
+    private final AdvertiseData mResponse;
+    private final CountDownLatch mStartAdvertiseLatch;
+    private BluetoothLeAdvertiser mAdvertiser;
+
+    private BleAdvertiser(String address, Callback callback, AdvertiseSettings settings,
+            AdvertiseData data, AdvertiseData response) {
+        this.mAddress = address;
+        this.mCallback = callback;
+        this.mSettings = settings;
+        this.mData = data;
+        this.mResponse = response;
+        mStartAdvertiseLatch = new CountDownLatch(1);
+        DeviceShadowEnvironment.addDevice(address).bluetooth()
+                .setAdapterInitialState(BluetoothAdapter.STATE_ON);
+    }
+
+    /**
+     * Starts advertising.
+     */
+    public Future<Void> start() {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mAdvertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
+                mAdvertiser.startAdvertising(mSettings, mData, mResponse, mAdvertiseCallback);
+            }
+        });
+    }
+
+    /**
+     * Stops advertising.
+     */
+    public Future<Void> stop() {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mAdvertiser.stopAdvertising(mAdvertiseCallback);
+            }
+        });
+    }
+
+    public void waitTillAdvertiseCompleted() {
+        try {
+            mStartAdvertiseLatch.await();
+        } catch (InterruptedException e) {
+            Log.w(TAG, mAddress + " fails to wait till advertise completed: ", e);
+        }
+    }
+
+    private final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
+        @Override
+        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
+            Log.v(TAG,
+                    String.format("onStartSuccess(settingsInEffect: %s) on %s ", settingsInEffect,
+                            mAddress));
+            mCallback.onStartSuccess(mAddress, settingsInEffect);
+            mStartAdvertiseLatch.countDown();
+        }
+
+        @Override
+        public void onStartFailure(int errorCode) {
+            Log.v(TAG, String.format("onStartFailure(errorCode: %d) on %s", errorCode, mAddress));
+            mCallback.onStartFailure(mAddress, errorCode);
+            mStartAdvertiseLatch.countDown();
+        }
+    };
+}
+
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BleScanner.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BleScanner.java
new file mode 100644
index 0000000..6a44c2b
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BleScanner.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.util.Log;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+
+import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Helper class to operate a device as BLE scanner.
+ */
+public class BleScanner {
+
+    private static final String TAG = "BleScanner";
+
+    private static final int DEFAULT_MODE = ScanSettings.SCAN_MODE_LOW_LATENCY;
+    private static final int DEFAULT_CALLBACK_TYPE = ScanSettings.CALLBACK_TYPE_ALL_MATCHES;
+    private static final long DEFAULT_DELAY = 0L;
+
+    /**
+     * Callback of {@link BleScanner}.
+     */
+    public interface Callback {
+
+        void onScanResult(String address, int callbackType, ScanResult result);
+
+        void onBatchScanResults(String address, List<ScanResult> results);
+
+        void onScanFailed(String address, int errorCode);
+    }
+
+    /**
+     * Builder class of {@link BleScanner}.
+     */
+    public static final class Builder {
+
+        private final String mAddress;
+        private final Callback mCallback;
+        private ScanSettings mSettings = defaultSettings();
+        private List<ScanFilter> mFilters;
+        private int mNumOfExpectedScanCallbacks = 1;
+
+        public Builder(String address, Callback callback) {
+            this.mAddress = Preconditions.checkNotNull(address);
+            this.mCallback = Preconditions.checkNotNull(callback);
+        }
+
+        public Builder setScanSettings(ScanSettings settings) {
+            this.mSettings = settings;
+            return this;
+        }
+
+        public Builder addScanFilter(ScanFilter... filterArgs) {
+            if (this.mFilters == null) {
+                this.mFilters = new ArrayList<>();
+            }
+            for (ScanFilter filter : filterArgs) {
+                this.mFilters.add(filter);
+            }
+            return this;
+        }
+
+        /**
+         * Sets number of expected scan result callback.
+         *
+         * @param num Number of expected scan result callback, default to 1.
+         */
+        public Builder setNumOfExpectedScanCallbacks(int num) {
+            mNumOfExpectedScanCallbacks = num;
+            return this;
+        }
+
+        public BleScanner build() {
+            return new BleScanner(
+                    mAddress, mCallback, mSettings, mFilters, mNumOfExpectedScanCallbacks);
+        }
+    }
+
+    private static ScanSettings defaultSettings() {
+        return new ScanSettings.Builder()
+                .setScanMode(DEFAULT_MODE)
+                .setCallbackType(DEFAULT_CALLBACK_TYPE)
+                .setReportDelay(DEFAULT_DELAY).build();
+    }
+
+    private final String mAddress;
+    private final Callback mCallback;
+    private final ScanSettings mSettings;
+    private final List<ScanFilter> mFilters;
+    private final BlockingQueue<Integer> mScanResultCounts;
+    private int mNumOfExpectedScanCallbacks;
+    private int mNumOfReceivedScanCallbacks;
+    private BluetoothLeScanner mScanner;
+
+    private BleScanner(String address, Callback callback, ScanSettings settings,
+            List<ScanFilter> filters, int numOfExpectedScanResult) {
+        this.mAddress = address;
+        this.mCallback = callback;
+        this.mSettings = settings;
+        this.mFilters = filters;
+        this.mNumOfExpectedScanCallbacks = numOfExpectedScanResult;
+        this.mNumOfReceivedScanCallbacks = 0;
+        this.mScanResultCounts = new LinkedBlockingQueue<>(numOfExpectedScanResult);
+        DeviceShadowEnvironment.addDevice(address).bluetooth()
+                .setAdapterInitialState(BluetoothAdapter.STATE_ON);
+    }
+
+    public Future<Void> start() {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
+                mScanner.startScan(mFilters, mSettings, mScanCallback);
+            }
+        });
+    }
+
+    public void waitTillNextScanResult(long timeoutMillis) {
+        Integer result = null;
+        if (mNumOfReceivedScanCallbacks >= mNumOfExpectedScanCallbacks) {
+            return;
+        }
+        try {
+            if (timeoutMillis < 0) {
+                result = mScanResultCounts.take();
+            } else {
+                result = mScanResultCounts.poll(timeoutMillis, TimeUnit.MILLISECONDS);
+            }
+            if (result != null && result >= 0) {
+                mNumOfReceivedScanCallbacks++;
+            }
+            Log.v(TAG, "Scan results: " + result);
+        } catch (InterruptedException e) {
+            Log.w(TAG, mAddress + " fails to wait till next scan result: ", e);
+        }
+    }
+
+    public void waitTillNextScanResult() {
+        waitTillNextScanResult(-1);
+    }
+
+    public void waitTillAllScanResults() {
+        while (mNumOfReceivedScanCallbacks < mNumOfExpectedScanCallbacks) {
+            try {
+                if (mScanResultCounts.take() >= 0) {
+                    mNumOfReceivedScanCallbacks++;
+                }
+            } catch (InterruptedException e) {
+                Log.w(TAG, String.format("%s fails to wait scan result", mAddress), e);
+                return;
+            }
+        }
+    }
+
+    public Future<Void> stop() {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
+                mScanner.stopScan(mScanCallback);
+            }
+        });
+    }
+
+    private final ScanCallback mScanCallback = new ScanCallback() {
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            Log.v(TAG, String.format("onScanResult(callbackType: %d, result: %s) on %s",
+                    callbackType, result, mAddress));
+            mCallback.onScanResult(mAddress, callbackType, result);
+            try {
+                mScanResultCounts.put(1);
+            } catch (InterruptedException e) {
+                // no-op.
+            }
+        }
+
+        @Override
+        public void onBatchScanResults(List<ScanResult> results) {
+            /**** Not supported yet.
+             Log.v(TAG, String.format("onBatchScanResults(results: %s) on %s",
+             Arrays.toString(results.toArray()), address));
+             callback.onBatchScanResults(address, results);
+             try {
+             scanResultCounts.put(results.size());
+             } catch (InterruptedException e) {
+             // no-op.
+             }
+             */
+        }
+
+        @Override
+        public void onScanFailed(int errorCode) {
+            /**** Not supported yet.
+             Log.v(TAG, String.format("onScanFailed(errorCode: %d) on %s", errorCode, address));
+             callback.onScanFailed(address, errorCode);
+             try {
+             scanResultCounts.put(-1);
+             } catch (InterruptedException e) {
+             // no-op.
+             }
+             */
+        }
+    };
+}
+
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothGattClient.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothGattClient.java
new file mode 100644
index 0000000..69e77af
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothGattClient.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Helper class to operate a device as gatt client.
+ */
+public class BluetoothGattClient {
+
+    private static final String TAG = "BluetoothGattClient";
+    private static final int LATCH_TIMEOUT_MILLIS = 1000;
+
+    /**
+     * Callback of BluetoothGattClient.
+     */
+    public interface Callback {
+
+        void onConnectionStateChange(String address, int status, int newState);
+
+        void onCharacteristicChanged(String address, UUID uuid, byte[] value);
+
+        void onCharacteristicRead(String address, UUID uuid, byte[] value, int status);
+
+        void onCharacteristicWrite(String address, UUID uuid, byte[] value, int status);
+
+        void onDescriptorRead(String address, UUID uuid, byte[] value, int status);
+
+        void onDescriptorWrite(String address, UUID uuid, byte[] value, int status);
+
+        void onServicesDiscovered(
+                UUID[] serviceUuid, UUID[] characteristicUuid, UUID[] descriptorUuid, int status);
+
+        void onConfigureMTU(String address, int mtu, int status);
+    }
+
+    private final String mAddress;
+    private final Callback mCallback;
+    private final Context mContext;
+    private final Map<UUID, BluetoothGattCharacteristic> mCharacteristics = new HashMap<>();
+    private final Map<UUID, BluetoothGattDescriptor> mDescriptors = new HashMap<>();
+    private BluetoothGatt mGatt;
+    private CountDownLatch mConnectionLatch;
+    private CountDownLatch mServiceDiscoverLatch;
+
+    public BluetoothGattClient(String address, Callback callback, Context context) {
+        this.mAddress = address;
+        this.mCallback = callback;
+        this.mContext = context;
+        DeviceShadowEnvironment.addDevice(address).bluetooth()
+                .setAdapterInitialState(BluetoothAdapter.STATE_ON);
+    }
+
+    public Future<Void> connect(final String remoteAddress) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mConnectionLatch = new CountDownLatch(1);
+                mGatt = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(remoteAddress)
+                        .connectGatt(mContext, false /* auto connect */, mGattCallback);
+                try {
+                    mConnectionLatch.await(LATCH_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+                } catch (InterruptedException e) {
+                    // no-op.
+                }
+
+                mServiceDiscoverLatch = new CountDownLatch(1);
+                mGatt.discoverServices();
+                try {
+                    mServiceDiscoverLatch.await(LATCH_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+                } catch (InterruptedException e) {
+                    // no-op.
+                }
+            }
+        });
+    }
+
+    public Future<Void> close() {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mGatt.disconnect();
+                mGatt.close();
+            }
+        });
+    }
+
+    public Future<Void> readCharacteristic(final UUID uuid) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mGatt.readCharacteristic(mCharacteristics.get(uuid));
+            }
+        });
+    }
+
+    public Future<Void> setNotification(final UUID uuid) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mGatt.setCharacteristicNotification(mCharacteristics.get(uuid), true);
+            }
+        });
+    }
+
+    public Future<Void> writeCharacteristic(final UUID uuid, final byte[] value) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                BluetoothGattCharacteristic characteristic = mCharacteristics.get(uuid);
+                characteristic.setValue(value);
+                mGatt.writeCharacteristic(characteristic);
+            }
+        });
+    }
+
+    /**
+     * Reads the value of a descriptor with given UUID.
+     *
+     * <p>If different characteristics on the service have the same descriptor, use {@link
+     * BluetoothGattClient#readDescriptor(UUID, UUID)} instead.
+     */
+    public Future<Void> readDescriptor(final UUID uuid) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mGatt.readDescriptor(mDescriptors.get(uuid));
+            }
+        });
+    }
+
+    /**
+     * Reads the descriptor value of the specified characteristic.
+     */
+    public Future<Void> readDescriptor(final UUID descriptorUuid, final UUID characteristicUuid) {
+        return DeviceShadowEnvironment.run(
+                mAddress,
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        mGatt.readDescriptor(
+                                mCharacteristics.get(characteristicUuid)
+                                        .getDescriptor(descriptorUuid));
+                    }
+                });
+    }
+
+    /**
+     * Writes to the descriptor with given UUID.
+     *
+     * <p>If different characteristics on the service have the same descriptor, use {@link
+     * BluetoothGattClient#writeDescriptor(UUID, UUID, byte[])} instead.
+     */
+    public Future<Void> writeDescriptor(final UUID uuid, final byte[] value) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                BluetoothGattDescriptor descriptor = mDescriptors.get(uuid);
+                descriptor.setValue(value);
+                mGatt.writeDescriptor(descriptor);
+            }
+        });
+    }
+
+    /**
+     * Writes to the descriptor of the specified characteristic.
+     */
+    public Future<Void> writeDescriptor(
+            final UUID descriptorUuid, final UUID characteristicUuid, final byte[] value) {
+        return DeviceShadowEnvironment.run(
+                mAddress,
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        BluetoothGattDescriptor descriptor =
+                                mCharacteristics.get(characteristicUuid)
+                                        .getDescriptor(descriptorUuid);
+                        descriptor.setValue(value);
+                        mGatt.writeDescriptor(descriptor);
+                    }
+                });
+    }
+
+    public Future<Void> requestMtu(int mtu) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mGatt.requestMtu(mtu);
+            }
+        });
+    }
+
+    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
+        @Override
+        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+            Log.v(TAG, String.format("onConnectionStateChange(status: %s, newState: %s)",
+                    status, newState));
+            if (mConnectionLatch != null) {
+                mConnectionLatch.countDown();
+            }
+            mCallback.onConnectionStateChange(gatt.getDevice().getAddress(), status, newState);
+        }
+
+        @Override
+        public void onCharacteristicChanged(
+                BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
+            Log.v(TAG, String.format("onCharacteristicChanged(characteristic: %s, value: %s)",
+                    characteristic.getUuid(), Arrays.toString(characteristic.getValue())));
+            mCallback.onCharacteristicChanged(
+                    gatt.getDevice().getAddress(), characteristic.getUuid(),
+                    characteristic.getValue());
+        }
+
+        @Override
+        public void onCharacteristicRead(
+                BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
+            Log.v(TAG, String.format("onCharacteristicRead(descriptor: %s, status: %s)",
+                    characteristic.getUuid(), status));
+            mCallback.onCharacteristicRead(
+                    gatt.getDevice().getAddress(), characteristic.getUuid(),
+                    characteristic.getValue(),
+                    status);
+        }
+
+        @Override
+        public void onCharacteristicWrite(
+                BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
+            Log.v(TAG, String.format("onCharacteristicWrite(descriptor: %s, status: %s)",
+                    characteristic.getUuid(), status));
+            mCallback.onCharacteristicWrite(gatt.getDevice().getAddress(),
+                    characteristic.getUuid(), characteristic.getValue(), status);
+        }
+
+        @Override
+        public void onDescriptorRead(
+                BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
+            Log.v(TAG, String.format("onDescriptorRead(descriptor: %s, status: %s)",
+                    descriptor.getUuid(), status));
+            mCallback.onDescriptorRead(
+                    gatt.getDevice().getAddress(), descriptor.getUuid(), descriptor.getValue(),
+                    status);
+        }
+
+        @Override
+        public void onDescriptorWrite(
+                BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
+            Log.v(TAG, String.format("onDescriptorWrite(descriptor: %s, status: %s)",
+                    descriptor.getUuid(), status));
+            mCallback.onDescriptorWrite(
+                    gatt.getDevice().getAddress(), descriptor.getUuid(), descriptor.getValue(),
+                    status);
+        }
+
+        @Override
+        public synchronized void onServicesDiscovered(BluetoothGatt gatt, int status) {
+            Log.v(TAG, "Discovered service: " + gatt.getServices());
+            List<UUID> serviceUuid = new ArrayList<>();
+            List<UUID> characteristicUuid = new ArrayList<>();
+            List<UUID> descriptorUuid = new ArrayList<>();
+            for (BluetoothGattService service : gatt.getServices()) {
+                serviceUuid.add(service.getUuid());
+                for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
+                    mCharacteristics.put(characteristic.getUuid(), characteristic);
+                    characteristicUuid.add(characteristic.getUuid());
+                    for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) {
+                        mDescriptors.put(descriptor.getUuid(), descriptor);
+                        descriptorUuid.add(descriptor.getUuid());
+                    }
+                }
+            }
+
+            Collections.sort(serviceUuid);
+            Collections.sort(characteristicUuid);
+            Collections.sort(descriptorUuid);
+
+            mCallback.onServicesDiscovered(serviceUuid.toArray(new UUID[serviceUuid.size()]),
+                    characteristicUuid.toArray(new UUID[characteristicUuid.size()]),
+                    descriptorUuid.toArray(new UUID[descriptorUuid.size()]),
+                    status);
+            mServiceDiscoverLatch.countDown();
+        }
+
+        @Override
+        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
+            Log.v(TAG, String.format("onMtuChanged(mtu: %s, status: %s)", mtu, status));
+            mCallback.onConfigureMTU(gatt.getDevice().getAddress(), mtu, status);
+        }
+    };
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothGattMaster.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothGattMaster.java
new file mode 100644
index 0000000..e9f364a
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothGattMaster.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattServer;
+import android.bluetooth.BluetoothGattServerCallback;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.Future;
+
+/**
+ * Helper class to operate a device as gatt server.
+ */
+public class BluetoothGattMaster {
+
+    private static final String TAG = "BluetoothGattMaster";
+
+    /**
+     * Callback of BluetoothGattMaster.
+     */
+    public interface Callback {
+
+        void onConnectionStateChange(String address, int status, int newState);
+
+        void onCharacteristicReadRequest(String address, UUID uuid);
+
+        void onCharacteristicWriteRequest(String address, UUID uuid, byte[] value,
+                boolean preparedWrite, boolean responseNeeded);
+
+        void onDescriptorReadRequest(String address, UUID uuid);
+
+        void onDescriptorWriteRequest(String address, UUID uuid, byte[] value,
+                boolean preparedWrite, boolean responseNeeded);
+
+        void onNotificationSent(String address, int status);
+
+        void onExecuteWrite(String address, boolean execute);
+
+        void onServiceAdded(UUID uuid, int status);
+
+        void onMtuChanged(String address, int mtu);
+    }
+
+    private final String mAddress;
+    private final Callback mCallback;
+    private final Context mContext;
+    private BluetoothGattServer mGattServer;
+    private final Map<UUID, BluetoothGattCharacteristic> mCharacteristics = new HashMap<>();
+
+    public BluetoothGattMaster(String address, Callback callback, Context context) {
+        this.mAddress = address;
+        this.mCallback = callback;
+        this.mContext = context;
+        DeviceShadowEnvironment.addDevice(address).bluetooth()
+                .setAdapterInitialState(BluetoothAdapter.STATE_ON);
+    }
+
+    public Future<Void> start(final BluetoothGattService service) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                BluetoothManager manager = mContext.getSystemService(BluetoothManager.class);
+                mGattServer = manager.openGattServer(mContext, mGattServerCallback);
+                mGattServer.addService(service);
+            }
+        });
+    }
+
+    public Future<Void> stop() {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mGattServer.close();
+            }
+        });
+    }
+
+    public Future<Void> notifyCharacteristic(
+            final String remoteAddress, final UUID uuid, final byte[] value,
+            final boolean confirm) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                BluetoothGattCharacteristic characteristic = mCharacteristics.get(uuid);
+                characteristic.setValue(value);
+                mGattServer.notifyCharacteristicChanged(
+                        BluetoothAdapter.getDefaultAdapter().getRemoteDevice(remoteAddress),
+                        characteristic, confirm);
+            }
+        });
+    }
+
+    private BluetoothGattServerCallback mGattServerCallback = new BluetoothGattServerCallback() {
+        @Override
+        public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
+            String address = device.getAddress();
+            Log.v(TAG, String.format(
+                    "BluetoothGattServerManager.onConnectionStateChange on %s: status %d,"
+                            + " newState %d", address, status, newState));
+            mCallback.onConnectionStateChange(address, status, newState);
+        }
+
+        @Override
+        public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset,
+                BluetoothGattCharacteristic characteristic) {
+            String address = device.getAddress();
+            UUID uuid = characteristic.getUuid();
+            Log.v(TAG,
+                    String.format("BluetoothGattServerManager.onCharacteristicReadRequest on %s: "
+                                    + "characteristic %s, request %d, offset %d",
+                            address, uuid, requestId, offset));
+            mCallback.onCharacteristicReadRequest(address, uuid);
+            mGattServer.sendResponse(
+                    device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                    characteristic.getValue());
+        }
+
+        @Override
+        public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
+                BluetoothGattCharacteristic characteristic, boolean preparedWrite,
+                boolean responseNeeded,
+                int offset, byte[] value) {
+            String address = device.getAddress();
+            UUID uuid = characteristic.getUuid();
+            Log.v(TAG,
+                    String.format("BluetoothGattServerManager.onCharacteristicWriteRequest on %s: "
+                                    + "characteristic %s, request %d, offset %d, preparedWrite %b, "
+                                    + "responseNeeded %b",
+                            address, uuid, requestId, offset, preparedWrite, responseNeeded));
+            mCallback.onCharacteristicWriteRequest(address, uuid, value, preparedWrite,
+                    responseNeeded);
+
+            if (responseNeeded) {
+                mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                        null);
+            }
+        }
+
+        @Override
+        public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset,
+                BluetoothGattDescriptor descriptor) {
+            String address = device.getAddress();
+            UUID uuid = descriptor.getUuid();
+            Log.v(TAG, String.format("BluetoothGattServerManager.onDescriptorReadRequest on %s: "
+                            + " descriptor %s, requestId %d, offset %d",
+                    address, uuid, requestId, offset));
+            mCallback.onDescriptorReadRequest(address, uuid);
+            mGattServer.sendResponse(
+                    device, requestId, BluetoothGatt.GATT_SUCCESS, offset, descriptor.getValue());
+        }
+
+        @Override
+        public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
+                BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded,
+                int offset, byte[] value) {
+            String address = device.getAddress();
+            UUID uuid = descriptor.getUuid();
+            Log.v(TAG, String.format("BluetoothGattServerManager.onDescriptorWriteRequest on %s: "
+                            + "descriptor %s, requestId %d, offset %d, preparedWrite %b, "
+                            + "responseNeeded %b",
+                    address, uuid, requestId, offset, preparedWrite, responseNeeded));
+            mCallback.onDescriptorWriteRequest(address, uuid, value, preparedWrite, responseNeeded);
+
+            if (responseNeeded) {
+                mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                        null);
+            }
+        }
+
+        @Override
+        public void onNotificationSent(BluetoothDevice device, int status) {
+            String address = device.getAddress();
+            Log.v(TAG,
+                    String.format("BluetoothGattServerManager.onNotificationSent on %s: status %d",
+                            address, status));
+            mCallback.onNotificationSent(address, status);
+        }
+
+        @Override
+        public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
+            /*** Not implemented yet
+             String address = device.getAddress();
+             Log.v(TAG, String.format(
+             "BluetoothGattServerManager.onExecuteWrite on %s: requestId %d, execute %b",
+             address, requestId, execute));
+             callback.onExecuteWrite(address, execute);
+             */
+        }
+
+        @Override
+        public void onServiceAdded(int status, BluetoothGattService service) {
+            UUID uuid = service.getUuid();
+            Log.v(TAG, String.format(
+                    "BluetoothGattServerManager.onServiceAdded: service %s, status %d",
+                    uuid, status));
+            mCallback.onServiceAdded(uuid, status);
+
+            for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
+                mCharacteristics.put(characteristic.getUuid(), characteristic);
+            }
+        }
+
+        @Override
+        public void onMtuChanged(BluetoothDevice device, int mtu) {
+            Log.v(TAG, String.format("onMtuChanged(mtu: %s)", mtu));
+            mCallback.onMtuChanged(device.getAddress(), mtu);
+        }
+    };
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothRfcommAcceptor.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothRfcommAcceptor.java
new file mode 100644
index 0000000..5204c2a
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothRfcommAcceptor.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.util.Log;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironmentInternal;
+import com.android.libraries.testing.deviceshadower.helpers.utils.IOUtils;
+
+import java.io.IOException;
+import java.util.Queue;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Helper class to operate a device with basic functionality to accept BluetoothRfcommConnection.
+ *
+ * <p>
+ * Usage: // Create a virtual device to accept incoming connection. BluetoothRfcommAcceptor acceptor
+ * = new BluetoothRfcommAcceptor(address, uuid, callback); // Start accepting incoming connection,
+ * with given uuid. acceptor.start(); // Connector needs to wait till acceptor started to make sure
+ * there is a server socket created. acceptor.waitTillServerSocketStarted();
+ *
+ * // Connector can initiate connection.
+ *
+ * // A blocking call to wait for connection. acceptor.waitTillConnected();
+ *
+ * // Acceptor sends a message acceptor.send("Hello".getBytes());
+ *
+ * // Cancel acceptor to release all blocking calls. acceptor.cancel();
+ */
+public class BluetoothRfcommAcceptor {
+
+    private static final String TAG = "BluetoothRfcommAcceptor";
+
+    /**
+     * Identifiers to control Bluetooth operation.
+     */
+    public static final int PRE_START = 4;
+    public static final int PRE_ACCEPT = 1;
+    public static final int PRE_WRITE = 3;
+    public static final int PRE_READ = 2;
+
+    private final String mAddress;
+    private final UUID mUuid;
+    private BluetoothSocket mSocket;
+    private BluetoothServerSocket mServerSocket;
+
+    private final AtomicBoolean mCancelled;
+    private final Callback mCallback;
+    private final CountDownLatch mStartLatch = new CountDownLatch(1);
+    private final CountDownLatch mConnectLatch = new CountDownLatch(1);
+    private final Queue<CountDownLatch> mReadLatches = new ConcurrentLinkedQueue<>();
+
+    /**
+     * Callback of BluetoothRfcommAcceptor.
+     */
+    public interface Callback {
+
+        void onSocketAccepted(BluetoothSocket socket);
+
+        void onDataReceived(byte[] data);
+
+        void onDataWritten(byte[] data);
+
+        void onError(Exception exception);
+    }
+
+    public BluetoothRfcommAcceptor(String address, UUID uuid, Callback callback) {
+        this.mAddress = address;
+        this.mUuid = uuid;
+        this.mCallback = callback;
+        this.mCancelled = new AtomicBoolean(false);
+        DeviceShadowEnvironment.addDevice(address).bluetooth()
+                .setAdapterInitialState(BluetoothAdapter.STATE_ON);
+    }
+
+    /**
+     * Start bluetooth server socket, accept incoming connection, and receive incoming data once
+     * connected.
+     */
+    public Future<Void> start() {
+        return DeviceShadowEnvironment.run(mAddress, mCode);
+    }
+
+    /**
+     * Blocking call to wait bluetooth server socket started.
+     */
+    public void waitTillServerSocketStarted() {
+        try {
+            mStartLatch.await();
+        } catch (InterruptedException e) {
+            Log.w(TAG, mAddress + " fail to wait till started: ", e);
+        }
+    }
+
+    public void waitTillConnected() {
+        try {
+            mConnectLatch.await();
+        } catch (InterruptedException e) {
+            Log.w(TAG, mAddress + " fail to wait till started: ", e);
+        }
+    }
+
+    public void waitTillDataReceived() {
+        try {
+            if (mReadLatches.size() > 0) {
+                mReadLatches.poll().await();
+            }
+        } catch (InterruptedException e) {
+            // no-op
+        }
+    }
+
+    /**
+     * Stop receiving data by closing socket.
+     */
+    public Future<Void> cancel() {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mCancelled.set(true);
+                try {
+                    mSocket.close();
+                } catch (IOException e) {
+                    Log.w(TAG, mAddress + " fail to close server socket", e);
+                }
+            }
+        });
+    }
+
+    /**
+     * Send data to connected device.
+     */
+    public Future<Void> send(final byte[] data) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                if (mSocket != null) {
+                    try {
+                        DeviceShadowEnvironmentInternal.setInterruptibleBluetooth(PRE_WRITE);
+                        IOUtils.write(mSocket.getOutputStream(), data);
+                        Log.d(TAG, mAddress + " write: " + new String(data));
+                        mCallback.onDataWritten(data);
+                    } catch (IOException e) {
+                        Log.w(TAG, mAddress + " fail to write: ", e);
+                        mCallback.onError(new IOException("Fail to write", e));
+                    }
+                }
+            }
+        });
+    }
+
+    private Runnable mCode = new Runnable() {
+        @Override
+        public void run() {
+            try {
+                DeviceShadowEnvironmentInternal.setInterruptibleBluetooth(PRE_START);
+                mServerSocket = BluetoothAdapter.getDefaultAdapter()
+                        .listenUsingInsecureRfcommWithServiceRecord("AA", mUuid);
+            } catch (IOException e) {
+                Log.w(TAG, mAddress + " fail to start server socket: ", e);
+                mCallback.onError(new IOException("Fail to start server socket", e));
+                return;
+            } finally {
+                mStartLatch.countDown();
+            }
+
+            try {
+                DeviceShadowEnvironmentInternal.setInterruptibleBluetooth(PRE_ACCEPT);
+                mSocket = mServerSocket.accept();
+                Log.d(TAG, mAddress + " accept: " + mSocket.getRemoteDevice().getAddress());
+                mCallback.onSocketAccepted(mSocket);
+                mServerSocket.close();
+            } catch (IOException e) {
+                Log.w(TAG, mAddress + " fail to connect: ", e);
+                mCallback.onError(new IOException("Fail to connect", e));
+                return;
+            } finally {
+                mConnectLatch.countDown();
+            }
+
+            do {
+                try {
+                    CountDownLatch latch = new CountDownLatch(1);
+                    mReadLatches.add(latch);
+                    DeviceShadowEnvironmentInternal.setInterruptibleBluetooth(PRE_READ);
+                    byte[] data = IOUtils.read(mSocket.getInputStream());
+                    Log.d(TAG, mAddress + " read: " + new String(data));
+                    mCallback.onDataReceived(data);
+                    latch.countDown();
+                } catch (IOException e) {
+                    Log.w(TAG, mAddress + " fail to read: ", e);
+                    mCallback.onError(new IOException("Fail to read", e));
+                    return;
+                }
+            } while (!mCancelled.get());
+
+            Log.d(TAG, mAddress + " stop receiving");
+        }
+    };
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothRfcommConnector.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothRfcommConnector.java
new file mode 100644
index 0000000..e386d59
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/bluetooth/BluetoothRfcommConnector.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothSocket;
+import android.util.Log;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironmentInternal;
+import com.android.libraries.testing.deviceshadower.helpers.utils.IOUtils;
+
+import java.io.IOException;
+import java.util.Queue;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Helper class to operate a device with basic functionality to accept BluetoothRfcommConnection.
+ *
+ * <p>
+ * Usage: // Create a virtual device to initiate connection. BluetoothRfcommConnector connector =
+ * new BluetoothRfcommConnector(address, callback); // Start connection to a remote address with
+ * given uuid. connector.start(remoteAddress, remoteUuid);
+ *
+ * // A blocking call to wait for connection. connector.waitTillConnected();
+ *
+ * // Connector sends a message connector.send("Hello".getBytes());
+ *
+ * // Cancel connector to release all blocking calls. connector.cancel();
+ */
+public class BluetoothRfcommConnector {
+
+    private static final String TAG = "BluetoothRfcommConnector";
+
+    /**
+     * Identifiers to control Bluetooth operation.
+     */
+    public static final int PRE_CONNECT = 1;
+    public static final int PRE_READ = 2;
+    public static final int PRE_WRITE = 3;
+
+    private final String mAddress;
+    private String mRemoteAddress = null;
+    private final UUID mRemoteUuid;
+    private BluetoothSocket mSocket;
+
+    private final Callback mCallback;
+    private final AtomicBoolean mCancelled;
+    private final CountDownLatch mConnectLatch = new CountDownLatch(1);
+    private final Queue<CountDownLatch> mReadLatches = new ConcurrentLinkedQueue<>();
+
+    /**
+     * Callback of BluetoothRfcommConnector.
+     */
+    public interface Callback {
+
+        void onConnected(BluetoothSocket socket);
+
+        void onDataReceived(byte[] data);
+
+        void onDataWritten(byte[] data);
+
+        void onError(Exception exception);
+    }
+
+    public BluetoothRfcommConnector(String address, UUID uuid, Callback callback) {
+        this.mAddress = address;
+        this.mRemoteUuid = uuid;
+        this.mCallback = callback;
+        this.mCancelled = new AtomicBoolean(false);
+        DeviceShadowEnvironment.addDevice(address).bluetooth()
+                .setAdapterInitialState(BluetoothAdapter.STATE_ON);
+    }
+
+    /**
+     * Start connection to a remote address, and receive data once connected.
+     */
+    public Future<Void> start(String remoteAddress) {
+        this.mRemoteAddress = remoteAddress;
+        return DeviceShadowEnvironment.run(mAddress, mCode);
+    }
+
+    /**
+     * Stop receiving data.
+     */
+    public Future<Void> cancel() {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mCancelled.set(true);
+                try {
+                    mSocket.close();
+                } catch (IOException e) {
+                    Log.w(TAG, mAddress + " fail to close socket", e);
+                }
+            }
+        });
+    }
+
+    public void waitTillConnected() {
+        try {
+            mConnectLatch.await();
+        } catch (InterruptedException e) {
+            Log.w(TAG, mAddress + " fail to wait till started: ", e);
+        }
+    }
+
+    public void waitTillDataReceived() {
+        try {
+            if (mReadLatches.size() > 0) {
+                mReadLatches.poll().await();
+            }
+        } catch (InterruptedException e) {
+            // no-op.
+        }
+    }
+
+    /**
+     * Send data to conneceted device.
+     */
+    public Future<Void> send(final byte[] data) {
+        return DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                if (mSocket != null) {
+                    try {
+                        DeviceShadowEnvironmentInternal.setInterruptibleBluetooth(PRE_WRITE);
+                        IOUtils.write(mSocket.getOutputStream(), data);
+                        Log.d(TAG, mAddress + " write: " + new String(data));
+                        mCallback.onDataWritten(data);
+                    } catch (IOException e) {
+                        Log.w(TAG, mAddress + " fail to write: ", e);
+                        mCallback.onError(new IOException("Fail to write", e));
+                    }
+                }
+            }
+        });
+    }
+
+    private Runnable mCode = new Runnable() {
+        @Override
+        public void run() {
+            try {
+                DeviceShadowEnvironmentInternal.setInterruptibleBluetooth(PRE_CONNECT);
+                mSocket = BluetoothAdapter.getDefaultAdapter()
+                        .getRemoteDevice(mRemoteAddress)
+                        .createInsecureRfcommSocketToServiceRecord(mRemoteUuid);
+                mSocket.connect();
+                Log.d(TAG, mAddress + " accept: " + mSocket.getRemoteDevice().getAddress());
+                mCallback.onConnected(mSocket);
+            } catch (IOException e) {
+                Log.w(TAG, mAddress + " fail to connect: ", e);
+                mCallback.onError(new IOException("Fail to connect", e));
+            } finally {
+                mConnectLatch.countDown();
+            }
+
+            try {
+                do {
+                    CountDownLatch latch = new CountDownLatch(1);
+                    mReadLatches.add(latch);
+                    DeviceShadowEnvironmentInternal.setInterruptibleBluetooth(PRE_READ);
+                    byte[] data = IOUtils.read(mSocket.getInputStream());
+                    Log.d(TAG, mAddress + " read: " + new String(data));
+                    mCallback.onDataReceived(data);
+                    latch.countDown();
+                } while (!mCancelled.get());
+            } catch (IOException e) {
+                Log.w(TAG, mAddress + " fail to read: ", e);
+                mCallback.onError(new IOException("Fail to read", e));
+            }
+            Log.d(TAG, mAddress + " stop receiving");
+        }
+    };
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/nfc/NfcActivity.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/nfc/NfcActivity.java
new file mode 100644
index 0000000..8ae4435
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/nfc/NfcActivity.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.nfc;
+
+import android.app.Activity;
+
+/**
+ * Activity that triggers or receives NFC events.
+ */
+public class NfcActivity extends Activity {
+
+    private NfcReceiver.Callback mCallback;
+
+    public void setCallback(NfcReceiver.Callback callback) {
+        this.mCallback = callback;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        NfcReceiver.processIntent(mCallback, getIntent());
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/nfc/NfcReceiver.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/nfc/NfcReceiver.java
new file mode 100644
index 0000000..b85a124
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/nfc/NfcReceiver.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.nfc;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nfc.NdefMessage;
+import android.nfc.NfcAdapter;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Helper class to receive NFC events.
+ */
+public class NfcReceiver {
+
+    private static final String TAG = "NfcReceiver";
+
+    /**
+     * Callback to receive message.
+     */
+    public interface Callback {
+
+        void onReceive(String message);
+    }
+
+    private final String mAddress;
+    private final Activity mActivity;
+    private CountDownLatch mReceiveLatch;
+
+    private final BroadcastReceiver mReceiver;
+    private final IntentFilter mFilter;
+
+    public NfcReceiver(String address, Activity activity, final Callback callback) {
+        this(address, activity, new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
+                    processIntent(callback, intent);
+                }
+            }
+        });
+        DeviceShadowEnvironment.addDevice(address);
+    }
+
+    public NfcReceiver(
+            final String address, Activity activity, final BroadcastReceiver clientReceiver) {
+        this.mAddress = address;
+        this.mActivity = activity;
+
+        this.mFilter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
+        this.mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                Log.v(TAG, "Receive broadcast on device " + address);
+                clientReceiver.onReceive(context, intent);
+                mReceiveLatch.countDown();
+            }
+        };
+        DeviceShadowEnvironment.addDevice(address);
+    }
+
+    public void startReceive() throws InterruptedException, ExecutionException {
+        mReceiveLatch = new CountDownLatch(1);
+
+        DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getApplication().registerReceiver(mReceiver, mFilter);
+            }
+        }).get();
+    }
+
+    public void waitUntilReceive(long timeoutMillis) throws InterruptedException {
+        mReceiveLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
+    }
+
+    public void stopReceive() throws InterruptedException, ExecutionException {
+        DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getApplication().unregisterReceiver(mReceiver);
+            }
+        }).get();
+    }
+
+    static void processIntent(Callback callback, Intent intent) {
+        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
+        if (rawMsgs != null && rawMsgs.length > 0) {
+            // only one message sent during the beam
+            NdefMessage msg = (NdefMessage) rawMsgs[0];
+            if (callback != null) {
+                callback.onReceive(new String(msg.getRecords()[0].getPayload()));
+            }
+        }
+    }
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/nfc/NfcSender.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/nfc/NfcSender.java
new file mode 100644
index 0000000..dbbb5fa
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/nfc/NfcSender.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.nfc;
+
+import android.app.Activity;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcAdapter.CreateNdefMessageCallback;
+import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
+import android.nfc.NfcEvent;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Helper class to send NFC events.
+ */
+public class NfcSender {
+
+    private static final String NFC_PACKAGE = "DS_PKG";
+    private static final String NFC_TAG = "DS_TAG";
+
+    /**
+     * Callback to update sender status.
+     */
+    public interface Callback {
+
+        void onSend(String message);
+    }
+
+    private final String mAddress;
+    private final Activity mActivity;
+    private final Callback mCallback;
+    private final SenderCallback mSenderCallback;
+    private String mSessage;
+
+    public NfcSender(String address, Activity activity, Callback callback) {
+        this.mCallback = callback;
+        this.mAddress = address;
+        this.mActivity = activity;
+        DeviceShadowEnvironment.addDevice(address);
+        this.mSenderCallback = new SenderCallback();
+    }
+
+    public void startSend(String message) throws InterruptedException, ExecutionException {
+        this.mSessage = message;
+        DeviceShadowEnvironment.run(mAddress, new Runnable() {
+            @Override
+            public void run() {
+                NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(mActivity);
+                nfcAdapter.setNdefPushMessageCallback(mSenderCallback, mActivity);
+                nfcAdapter.setOnNdefPushCompleteCallback(mSenderCallback, mActivity);
+            }
+        }).get();
+    }
+
+    class SenderCallback implements CreateNdefMessageCallback, OnNdefPushCompleteCallback {
+
+        @Override
+        public NdefMessage createNdefMessage(NfcEvent event) {
+            NdefMessage msg = new NdefMessage(new NdefRecord[]{
+                    NdefRecord.createExternal(NFC_PACKAGE, NFC_TAG, mSessage.getBytes())
+            });
+            return msg;
+        }
+
+        @Override
+        public void onNdefPushComplete(NfcEvent event) {
+            mCallback.onSend(mSessage);
+        }
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/utils/IOUtils.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/utils/IOUtils.java
new file mode 100644
index 0000000..d89754b
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/helpers/utils/IOUtils.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.helpers.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * Utils for IO methods.
+ */
+public class IOUtils {
+
+    /**
+     * Write num of bytes to be sent and payload through OutputStream.
+     */
+    public static void write(OutputStream os, byte[] data) throws IOException {
+        ByteBuffer buffer = ByteBuffer.allocate(4 + data.length).putInt(data.length).put(data);
+        os.write(buffer.array());
+    }
+
+    /**
+     * Read num of bytes to be read, and payload through InputStream.
+     *
+     * @return payload received.
+     */
+    public static byte[] read(InputStream is) throws IOException {
+        byte[] size = new byte[4];
+        is.read(size, 0, 4 /* bytes of int type */);
+
+        byte[] data = new byte[ByteBuffer.wrap(size).getInt()];
+        is.read(data);
+        return data;
+    }
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/DeviceShadowEnvironmentImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/DeviceShadowEnvironmentImpl.java
new file mode 100644
index 0000000..6a06ce4
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/DeviceShadowEnvironmentImpl.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal;
+
+import android.content.ContentProvider;
+import android.os.Looper;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.Enums.Distance;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.BlueletImpl;
+import com.android.libraries.testing.deviceshadower.internal.common.NamedRunnable;
+import com.android.libraries.testing.deviceshadower.internal.common.Scheduler;
+import com.android.libraries.testing.deviceshadower.internal.nfc.NfcletImpl;
+import com.android.libraries.testing.deviceshadower.internal.sms.SmsContentProvider;
+import com.android.libraries.testing.deviceshadower.internal.sms.SmsletImpl;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import com.google.common.collect.ImmutableList;
+
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowLooper;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Proxy to manage internal data models, and help shadows to exchange data.
+ */
+public class DeviceShadowEnvironmentImpl {
+
+    private static final Logger LOGGER = Logger.create("DeviceShadowEnvironmentImpl");
+    private static final long SCHEDULER_WAIT_TIMEOUT_MILLIS = 5000L;
+
+    // ThreadLocal to store local address for each device.
+    private static InheritableThreadLocal<DeviceletImpl> sLocalDeviceletImpl =
+            new InheritableThreadLocal<>();
+
+    // Devicelets contains all registered devicelet to simulate a device.
+    private static final Map<String, DeviceletImpl> DEVICELETS = new ConcurrentHashMap<>();
+
+    @VisibleForTesting
+    static final Map<String, ExecutorService> EXECUTORS = new ConcurrentHashMap<>();
+
+    private static final List<DeviceShadowException> INTERNAL_EXCEPTIONS =
+            Collections.synchronizedList(new ArrayList<DeviceShadowException>());
+
+    private static final ContentProvider smsContentProvider = new SmsContentProvider();
+
+    public static DeviceletImpl getDeviceletImpl(String address) {
+        return DEVICELETS.get(address);
+    }
+
+    public static void checkInternalExceptions() {
+        if (INTERNAL_EXCEPTIONS.size() > 0) {
+            for (DeviceShadowException exception : INTERNAL_EXCEPTIONS) {
+                LOGGER.e("Internal exception", exception);
+            }
+            INTERNAL_EXCEPTIONS.clear();
+            throw new RuntimeException("DeviceShadower has internal exceptions");
+        }
+    }
+
+    public static void reset() {
+        // reset local devicelet for single device testing
+        sLocalDeviceletImpl.remove();
+        DEVICELETS.clear();
+        BlueletImpl.reset();
+        INTERNAL_EXCEPTIONS.clear();
+    }
+
+    public static boolean await(long timeoutMillis) {
+        boolean schedulerDone = false;
+        try {
+            schedulerDone = Scheduler.await(timeoutMillis);
+        } catch (InterruptedException e) {
+            // no-op.
+        } finally {
+            if (!schedulerDone) {
+                catchInternalException(new DeviceShadowException("Scheduler not complete"));
+                for (DeviceletImpl devicelet : DEVICELETS.values()) {
+                    LOGGER.e(
+                            String.format(
+                                    "Device %s\n\tUI: %s\n\tService: %s",
+                                    devicelet.getAddress(),
+                                    devicelet.getUiScheduler(),
+                                    devicelet.getServiceScheduler()));
+                }
+                Scheduler.clear();
+            }
+        }
+        for (ExecutorService executor : EXECUTORS.values()) {
+            executor.shutdownNow();
+        }
+        boolean terminateSuccess = true;
+        for (ExecutorService executor : EXECUTORS.values()) {
+            try {
+                executor.awaitTermination(timeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                terminateSuccess = false;
+            }
+            if (!executor.isTerminated()) {
+                LOGGER.e("Failed to terminate executor.");
+                terminateSuccess = false;
+            }
+        }
+        EXECUTORS.clear();
+        return schedulerDone && terminateSuccess;
+    }
+
+    public static boolean hasLocalDeviceletImpl() {
+        return sLocalDeviceletImpl.get() != null;
+    }
+
+    public static DeviceletImpl getLocalDeviceletImpl() {
+        return sLocalDeviceletImpl.get();
+    }
+
+    public static List<DeviceletImpl> getDeviceletImpls() {
+        return ImmutableList.copyOf(DEVICELETS.values());
+    }
+
+    public static BlueletImpl getLocalBlueletImpl() {
+        return sLocalDeviceletImpl.get().blueletImpl();
+    }
+
+    public static BlueletImpl getBlueletImpl(String address) {
+        DeviceletImpl devicelet = getDeviceletImpl(address);
+        return devicelet == null ? null : devicelet.blueletImpl();
+    }
+
+    public static NfcletImpl getLocalNfcletImpl() {
+        return sLocalDeviceletImpl.get().nfcletImpl();
+    }
+
+    public static NfcletImpl getNfcletImpl(String address) {
+        DeviceletImpl devicelet = getDeviceletImpl(address);
+        return devicelet == null ? null : devicelet.nfcletImpl();
+    }
+
+    public static SmsletImpl getLocalSmsletImpl() {
+        return sLocalDeviceletImpl.get().smsletImpl();
+    }
+
+    public static ContentProvider getSmsContentProvider() {
+        return smsContentProvider;
+    }
+
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public static DeviceletImpl addDevice(String address) {
+        EXECUTORS.put(address, Executors.newCachedThreadPool());
+
+        // DeviceShadower keeps track of the "local" device based on the current thread. It uses an
+        // InheritableThreadLocal, so threads created by the current thread also get the same
+        // thread-local value. Add the device on its own thread, to set the thread local for that
+        // thread and its children.
+        try {
+            EXECUTORS
+                    .get(address)
+                    .submit(
+                            () -> {
+                                DeviceletImpl devicelet = new DeviceletImpl(address);
+                                DEVICELETS.put(address, devicelet);
+                                setLocalDevice(address);
+                                // Ensure these threads are actually created, by posting one empty
+                                // runnable.
+                                devicelet.getServiceScheduler()
+                                        .post(NamedRunnable.create("Init", () -> {
+                                        }));
+                                devicelet.getUiScheduler().post(NamedRunnable.create("Init", () -> {
+                                }));
+                            })
+                    .get();
+        } catch (InterruptedException | ExecutionException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return DEVICELETS.get(address);
+    }
+
+    public static void removeDevice(String address) {
+        DEVICELETS.remove(address);
+        EXECUTORS.remove(address);
+    }
+
+    public static void setInterruptibleBluetooth(int identifier) {
+        getLocalBlueletImpl().setInterruptible(identifier);
+    }
+
+    public static void interruptBluetooth(String address, int identifier) {
+        getBlueletImpl(address).interrupt(identifier);
+    }
+
+    public static void setDistance(String address1, String address2, final Distance distance) {
+        final DeviceletImpl device1 = getDeviceletImpl(address1);
+        final DeviceletImpl device2 = getDeviceletImpl(address2);
+
+        Future<Void> result1 = null;
+        Future<Void> result2 = null;
+        if (device1.updateDistance(address2, distance)) {
+            result1 =
+                    run(
+                            address1,
+                            () -> {
+                                device1.onDistanceChange(device2, distance);
+                                return null;
+                            });
+        }
+
+        if (device2.updateDistance(address1, distance)) {
+            result2 =
+                    run(
+                            address2,
+                            () -> {
+                                device2.onDistanceChange(device1, distance);
+                                return null;
+                            });
+        }
+
+        try {
+            if (result1 != null) {
+                result1.get();
+            }
+            if (result2 != null) {
+                result2.get();
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            catchInternalException(new DeviceShadowException(e));
+        }
+    }
+
+    /**
+     * Set local Bluelet for current thread.
+     *
+     * <p>This can be used to convert current running thread to hold a bluelet object, so that unit
+     * test does not have to call BluetoothEnvironment.run() to run code.
+     */
+    @VisibleForTesting
+    public static void setLocalDevice(String address) {
+        DeviceletImpl local = DEVICELETS.get(address);
+        if (local == null) {
+            throw new RuntimeException(address + " is not initialized by BluetoothEnvironment");
+        }
+        sLocalDeviceletImpl.set(local);
+    }
+
+    public static <T> Future<T> run(final String address, final Callable<T> snippet) {
+        return EXECUTORS
+                .get(address)
+                .submit(
+                        () -> {
+                            DeviceShadowEnvironmentImpl.setLocalDevice(address);
+                            ShadowLooper mainLooper = Shadows.shadowOf(Looper.getMainLooper());
+                            try {
+                                T result = snippet.call();
+
+                                // Avoid idling the main looper in paused mode since doing so is
+                                // only allowed from the main thread.
+                                if (!mainLooper.isPaused()) {
+                                    // In Robolectric, runnable doesn't run when posting thread
+                                    // differs from looper thread, idle main looper explicitly to
+                                    // execute posted Runnables.
+                                    ShadowLooper.idleMainLooper();
+                                }
+
+                                // Wait all scheduled runnables complete.
+                                Scheduler.await(SCHEDULER_WAIT_TIMEOUT_MILLIS);
+                                return result;
+                            } catch (Exception e) {
+                                LOGGER.e("Fail to call code on device: " + address, e);
+                                if (!mainLooper.isPaused()) {
+                                    // reset() is not supported in paused mode.
+                                    mainLooper.reset();
+                                }
+                                throw new RuntimeException(e);
+                            }
+                        });
+    }
+
+    // @CanIgnoreReturnValue
+    // Return value can be ignored because {@link Scheduler} will call
+    // {@link catchInternalException} to catch exceptions, and throw when test completes.
+    public static Future<?> runOnUi(String address, NamedRunnable snippet) {
+        Scheduler scheduler = DeviceShadowEnvironmentImpl.getDeviceletImpl(address)
+                .getUiScheduler();
+        return run(scheduler, address, snippet);
+    }
+
+    // @CanIgnoreReturnValue
+    // Return value can be ignored because {@link Scheduler} will call
+    // {@link catchInternalException} to catch exceptions, and throw when test completes.
+    public static Future<?> runOnService(String address, NamedRunnable snippet) {
+        Scheduler scheduler =
+                DeviceShadowEnvironmentImpl.getDeviceletImpl(address).getServiceScheduler();
+        return run(scheduler, address, snippet);
+    }
+
+    // @CanIgnoreReturnValue
+    // Return value can be ignored because {@link Scheduler} will call
+    // {@link catchInternalException} to catch exceptions, and throw when test completes.
+    private static Future<?> run(
+            Scheduler scheduler, final String address, final NamedRunnable snippet) {
+        return scheduler.post(
+                NamedRunnable.create(
+                        snippet.toString(),
+                        () -> {
+                            DeviceShadowEnvironmentImpl.setLocalDevice(address);
+                            snippet.run();
+                        }));
+    }
+
+    public static void catchInternalException(Exception exception) {
+        INTERNAL_EXCEPTIONS.add(new DeviceShadowException(exception));
+    }
+
+    // This is used to test Device Shadower internal.
+    @VisibleForTesting
+    public static void setDeviceletForTest(String address, DeviceletImpl devicelet) {
+        DEVICELETS.put(address, devicelet);
+    }
+
+    @VisibleForTesting
+    public static void setExecutorForTest(String address) {
+        setExecutorForTest(address, Executors.newCachedThreadPool());
+    }
+
+    @VisibleForTesting
+    public static void setExecutorForTest(String address, ExecutorService executor) {
+        EXECUTORS.put(address, executor);
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/DeviceShadowException.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/DeviceShadowException.java
new file mode 100644
index 0000000..77d358f
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/DeviceShadowException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal;
+
+/**
+ * Internal exception to indicate error from DeviceShadower framework.
+ */
+public class DeviceShadowException extends Exception {
+
+    public DeviceShadowException(Throwable e) {
+        super(e);
+    }
+
+    public DeviceShadowException(String msg) {
+        super(msg);
+    }
+
+    public DeviceShadowException(String msg, Throwable e) {
+        super(msg, e);
+    }
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/DeviceletImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/DeviceletImpl.java
new file mode 100644
index 0000000..9aea065
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/DeviceletImpl.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal;
+
+import com.android.libraries.testing.deviceshadower.Bluelet;
+import com.android.libraries.testing.deviceshadower.Devicelet;
+import com.android.libraries.testing.deviceshadower.Enums.Distance;
+import com.android.libraries.testing.deviceshadower.Nfclet;
+import com.android.libraries.testing.deviceshadower.Smslet;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.BlueletImpl;
+import com.android.libraries.testing.deviceshadower.internal.common.BroadcastManager;
+import com.android.libraries.testing.deviceshadower.internal.common.Scheduler;
+import com.android.libraries.testing.deviceshadower.internal.nfc.NfcletImpl;
+import com.android.libraries.testing.deviceshadower.internal.sms.SmsletImpl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * DeviceletImpl is the implementation to hold different medium-let in DeviceShadowEnvironment.
+ */
+public class DeviceletImpl implements Devicelet {
+
+    private final BlueletImpl mBluelet;
+    private final NfcletImpl mNfclet;
+    private final SmsletImpl mSmslet;
+    private final BroadcastManager mBroadcastManager;
+    private final String mAddress;
+    private final Map<String, Distance> mDistanceMap = new HashMap<>();
+    private final Scheduler mServiceScheduler;
+    private final Scheduler mUiScheduler;
+
+    public DeviceletImpl(String address) {
+        this.mAddress = address;
+        this.mServiceScheduler = new Scheduler(address + "-service");
+        this.mUiScheduler = new Scheduler(address + "-main");
+        this.mBroadcastManager = new BroadcastManager(mUiScheduler);
+        this.mBluelet = new BlueletImpl(address, mBroadcastManager);
+        this.mNfclet = new NfcletImpl();
+        this.mSmslet = new SmsletImpl();
+    }
+
+    @Override
+    public Bluelet bluetooth() {
+        return mBluelet;
+    }
+
+    public BlueletImpl blueletImpl() {
+        return mBluelet;
+    }
+
+    @Override
+    public Nfclet nfc() {
+        return mNfclet;
+    }
+
+    public NfcletImpl nfcletImpl() {
+        return mNfclet;
+    }
+
+    @Override
+    public Smslet sms() {
+        return mSmslet;
+    }
+
+    public SmsletImpl smsletImpl() {
+        return mSmslet;
+    }
+
+    public BroadcastManager getBroadcastManager() {
+        return mBroadcastManager;
+    }
+
+    @Override
+    public String getAddress() {
+        return mAddress;
+    }
+
+    Scheduler getServiceScheduler() {
+        return mServiceScheduler;
+    }
+
+    Scheduler getUiScheduler() {
+        return mUiScheduler;
+    }
+
+    /**
+     * Update distance to remote device.
+     *
+     * @return true if distance updated.
+     */
+    /*package*/ boolean updateDistance(String remoteAddress, Distance distance) {
+        Distance currentDistance = mDistanceMap.get(remoteAddress);
+        if (currentDistance == null || !distance.equals(currentDistance)) {
+            mDistanceMap.put(remoteAddress, distance);
+            return true;
+        }
+        return false;
+    }
+
+    /*package*/ void onDistanceChange(DeviceletImpl remote, Distance distance) {
+        if (distance == Distance.NEAR) {
+            mNfclet.onNear(remote.mNfclet);
+        }
+    }
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/AdapterDelegate.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/AdapterDelegate.java
new file mode 100644
index 0000000..b5227b7
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/AdapterDelegate.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass.Device;
+import android.os.Build.VERSION;
+
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.DeviceletImpl;
+import com.android.libraries.testing.deviceshadower.internal.common.NamedRunnable;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * Class handling Bluetooth Adapter State change. Currently async event processing is not supported,
+ * and there is no deferred operation when adapter is in a pending state.
+ */
+class AdapterDelegate {
+
+    /**
+     * Callback for adapter
+     */
+    public interface Callback {
+
+        void onAdapterStateChange(State prevState, State newState);
+
+        void onBleStateChange(State prevState, State newState);
+
+        void onDiscoveryStarted();
+
+        void onDiscoveryFinished();
+
+        void onDeviceFound(String address, int bluetoothClass, String name);
+    }
+
+    @GuardedBy("this")
+    private State mCurrentState;
+
+    private final String mAddress;
+    private final Callback mCallback;
+    private AtomicBoolean mIsDiscovering = new AtomicBoolean(false);
+    private final AtomicInteger mScanMode = new AtomicInteger(BluetoothAdapter.SCAN_MODE_NONE);
+    private int mBluetoothClass = Device.PHONE_SMART;
+
+    AdapterDelegate(String address, Callback callback) {
+        this.mAddress = address;
+        this.mCurrentState = State.OFF;
+        this.mCallback = callback;
+    }
+
+    synchronized void processEvent(Event event) {
+        State newState = TRANSITION[mCurrentState.ordinal()][event.ordinal()];
+        if (newState == null) {
+            return;
+        }
+        State prevState = mCurrentState;
+        mCurrentState = newState;
+        handleStateChange(prevState, newState);
+    }
+
+    private void handleStateChange(State prevState, State newState) {
+        // TODO(b/200231384): fake service bind/unbind on state change
+        if (prevState.equals(newState)) {
+            return;
+        }
+        if (VERSION.SDK_INT < 23) {
+            mCallback.onAdapterStateChange(prevState, newState);
+        } else {
+            mCallback.onBleStateChange(prevState, newState);
+            if (newState.equals(State.BLE_TURNING_ON)
+                    || newState.equals(State.BLE_TURNING_OFF)
+                    || newState.equals(State.OFF)
+                    || (newState.equals(State.BLE_ON) && prevState.equals(State.BLE_TURNING_ON))) {
+                return;
+            }
+            if (newState.equals(State.BLE_ON)) {
+                newState = State.OFF;
+            } else if (prevState.equals(State.BLE_ON)) {
+                prevState = State.OFF;
+            }
+            mCallback.onAdapterStateChange(prevState, newState);
+        }
+    }
+
+    synchronized State getState() {
+        return mCurrentState;
+    }
+
+    synchronized void setState(State state) {
+        mCurrentState = state;
+    }
+
+    void setBluetoothClass(int bluetoothClass) {
+        this.mBluetoothClass = bluetoothClass;
+    }
+
+    int getBluetoothClass() {
+        return mBluetoothClass;
+    }
+
+    @SuppressWarnings("FutureReturnValueIgnored")
+    void startDiscovery() {
+        synchronized (this) {
+            if (mIsDiscovering.get()) {
+                return;
+            }
+            mIsDiscovering.set(true);
+        }
+
+        mCallback.onDiscoveryStarted();
+
+        NamedRunnable onDeviceFound =
+                NamedRunnable.create(
+                        "BluetoothAdapter.onDeviceFound",
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                List<DeviceletImpl> devices =
+                                        DeviceShadowEnvironmentImpl.getDeviceletImpls();
+                                for (DeviceletImpl devicelet : devices) {
+                                    BlueletImpl bluelet = devicelet.blueletImpl();
+                                    if (mAddress.equals(devicelet.getAddress())
+                                            || bluelet.getAdapterDelegate().mScanMode.get()
+                                                    != BluetoothAdapter
+                                            .SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+                                        continue;
+                                    }
+                                    mCallback.onDeviceFound(
+                                            bluelet.address,
+                                            bluelet.getAdapterDelegate().mBluetoothClass,
+                                            bluelet.mName);
+                                }
+                                finishDiscovery();
+                            }
+                        });
+
+        DeviceShadowEnvironmentImpl.runOnUi(mAddress, onDeviceFound);
+    }
+
+    void cancelDiscovery() {
+        finishDiscovery();
+    }
+
+    boolean isDiscovering() {
+        return mIsDiscovering.get();
+    }
+
+    void setScanMode(int scanMode) {
+        // TODO(b/200231384): broadcast scan mode change.
+        this.mScanMode.set(scanMode);
+    }
+
+    int getScanMode() {
+        return mScanMode.get();
+    }
+
+    private void finishDiscovery() {
+        synchronized (this) {
+            if (!mIsDiscovering.get()) {
+                return;
+            }
+            mIsDiscovering.set(false);
+        }
+        mCallback.onDiscoveryFinished();
+    }
+
+    enum State {
+        OFF(BluetoothAdapter.STATE_OFF),
+        TURNING_ON(BluetoothAdapter.STATE_TURNING_ON),
+        ON(BluetoothAdapter.STATE_ON),
+        TURNING_OFF(BluetoothAdapter.STATE_TURNING_OFF),
+        // States for API23+
+        BLE_TURNING_ON(BluetoothConstants.STATE_BLE_TURNING_ON),
+        BLE_ON(BluetoothConstants.STATE_BLE_ON),
+        BLE_TURNING_OFF(BluetoothConstants.STATE_BLE_TURNING_OFF);
+
+        private static final Map<Integer, State> LOOKUP = new HashMap<>();
+
+        static {
+            for (State state : State.values()) {
+                LOOKUP.put(state.getValue(), state);
+            }
+        }
+
+        static State lookup(int value) {
+            return LOOKUP.get(value);
+        }
+
+        private final int mValue;
+
+        State(int value) {
+            this.mValue = value;
+        }
+
+        int getValue() {
+            return mValue;
+        }
+    }
+
+    /*
+     * Represents Bluetooth events which can trigger adapter state change.
+     */
+    enum Event {
+        USER_TURN_ON,
+        USER_TURN_OFF,
+        BREDR_STARTED,
+        BREDR_STOPPED,
+        // Events for API23+
+        BLE_TURN_ON,
+        BLE_TURN_OFF,
+        BLE_STARTED,
+        BLE_STOPPED
+    }
+
+    private static final State[][] TRANSITION =
+            new State[State.values().length][Event.values().length];
+
+    static {
+        if (VERSION.SDK_INT < 23) {
+            // transition table before API23
+            TRANSITION[State.OFF.ordinal()][Event.USER_TURN_ON.ordinal()] = State.TURNING_ON;
+            TRANSITION[State.TURNING_ON.ordinal()][Event.BREDR_STARTED.ordinal()] = State.ON;
+            TRANSITION[State.ON.ordinal()][Event.USER_TURN_OFF.ordinal()] = State.TURNING_OFF;
+            TRANSITION[State.TURNING_OFF.ordinal()][Event.BREDR_STOPPED.ordinal()] = State.OFF;
+        } else {
+            // transition table starting from API23
+            TRANSITION[State.OFF.ordinal()][Event.BLE_TURN_ON.ordinal()] = State.BLE_TURNING_ON;
+            TRANSITION[State.BLE_TURNING_ON.ordinal()][Event.BLE_STARTED.ordinal()] = State.BLE_ON;
+            TRANSITION[State.BLE_ON.ordinal()][Event.USER_TURN_ON.ordinal()] = State.TURNING_ON;
+            TRANSITION[State.TURNING_ON.ordinal()][Event.BREDR_STARTED.ordinal()] = State.ON;
+            TRANSITION[State.ON.ordinal()][Event.BLE_TURN_OFF.ordinal()] = State.TURNING_OFF;
+            TRANSITION[State.TURNING_OFF.ordinal()][Event.BREDR_STOPPED.ordinal()] = State.BLE_ON;
+            TRANSITION[State.BLE_ON.ordinal()][Event.USER_TURN_OFF.ordinal()] =
+                    State.BLE_TURNING_OFF;
+            TRANSITION[State.BLE_TURNING_OFF.ordinal()][Event.BLE_STOPPED.ordinal()] = State.OFF;
+        }
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/BlueletImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/BlueletImpl.java
new file mode 100644
index 0000000..4e534e3
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/BlueletImpl.java
@@ -0,0 +1,495 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth;
+
+import static org.robolectric.util.ReflectionHelpers.callConstructor;
+
+import android.Manifest.permission;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.IBluetoothManager;
+import android.content.AttributionSource;
+import android.content.Intent;
+import android.os.Build.VERSION;
+import android.os.ParcelUuid;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.Bluelet;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.AdapterDelegate.Event;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.AdapterDelegate.State;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.connection.RfcommDelegate;
+import com.android.libraries.testing.deviceshadower.internal.common.BroadcastManager;
+import com.android.libraries.testing.deviceshadower.internal.common.Interrupter;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A container class of a real-world Bluetooth device.
+ */
+public class BlueletImpl implements Bluelet {
+
+    enum PairingConfirmation {
+        UNKNOWN,
+        CONFIRMED,
+        DENIED
+    }
+
+    /**
+     * See hidden {@link #EXTRA_REASON} and reason values in {@link BluetoothDevice}.
+     */
+    static final int REASON_SUCCESS = 0;
+    /**
+     * See hidden {@link #EXTRA_REASON} and reason values in {@link BluetoothDevice}.
+     */
+    static final int UNBOND_REASON_AUTH_FAILED = 1;
+    /**
+     * See hidden {@link #EXTRA_REASON} and reason values in {@link BluetoothDevice}.
+     */
+    static final int UNBOND_REASON_AUTH_CANCELED = 3;
+
+    /**
+     * Hidden in {@link BluetoothDevice}.
+     */
+    private static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
+
+    private static final Logger LOGGER = Logger.create("BlueletImpl");
+
+    private static final ImmutableMap<Integer, Integer> PROFILE_STATE_TO_ADAPTER_STATE =
+            ImmutableMap.<Integer, Integer>builder()
+                    .put(BluetoothProfile.STATE_CONNECTED, BluetoothAdapter.STATE_CONNECTED)
+                    .put(BluetoothProfile.STATE_CONNECTING, BluetoothAdapter.STATE_CONNECTING)
+                    .put(BluetoothProfile.STATE_DISCONNECTING, BluetoothAdapter.STATE_DISCONNECTING)
+                    .put(BluetoothProfile.STATE_DISCONNECTED, BluetoothAdapter.STATE_DISCONNECTED)
+                    .build();
+
+    public static void reset() {
+        RfcommDelegate.reset();
+    }
+
+    public final String address;
+    String mName;
+    ParcelUuid[] mProfileUuids = new ParcelUuid[0];
+    int mPhonebookAccessPermission;
+    int mMessageAccessPermission;
+    int mSimAccessPermission;
+    final BluetoothAdapter mAdapter;
+    int mPassKey;
+
+    private CreateBondOutcome mCreateBondOutcome = CreateBondOutcome.SUCCESS;
+    private int mCreateBondFailureReason;
+    private IoCapabilities mIoCapabilities = IoCapabilities.NO_INPUT_NO_OUTPUT;
+    private boolean mRefuseConnections;
+    private FetchUuidsTiming mFetchUuidsTiming = FetchUuidsTiming.AFTER_BONDING;
+    private boolean mEnableCVE20192225;
+
+    private final Interrupter mInterrupter;
+    private final AdapterDelegate mAdapterDelegate;
+    private final RfcommDelegate mRfcommDelegate;
+    private final GattDelegate mGattDelegate;
+    private final BluetoothBroadcastHandler mBluetoothBroadcastHandler;
+    private final Map<String, Integer> mRemoteAddressToBondState = new HashMap<>();
+    private final Map<String, PairingConfirmation> mRemoteAddressToPairingConfirmation =
+            new HashMap<>();
+    private final Map<Integer, Integer> mProfileTypeToConnectionState = new HashMap<>();
+    private final Set<BluetoothDevice> mBondedDevices = new HashSet<>();
+
+    public BlueletImpl(String address, BroadcastManager broadcastManager) {
+        this.address = address;
+        this.mName = address;
+        this.mAdapter = callConstructor(BluetoothAdapter.class,
+                ClassParameter.from(IBluetoothManager.class, new IBluetoothManagerImpl()),
+                ClassParameter.from(AttributionSource.class,
+                        AttributionSource.myAttributionSource()));
+        mBluetoothBroadcastHandler = new BluetoothBroadcastHandler(broadcastManager);
+        mInterrupter = new Interrupter();
+        mAdapterDelegate = new AdapterDelegate(address, mBluetoothBroadcastHandler);
+        mRfcommDelegate = new RfcommDelegate(address, mBluetoothBroadcastHandler, mInterrupter);
+        mGattDelegate = new GattDelegate(address);
+    }
+
+    @Override
+    public Bluelet setAdapterInitialState(int state) throws IllegalArgumentException {
+        LOGGER.d(String.format("Address: %s, setAdapterInitialState(%d)", address, state));
+        Preconditions.checkArgument(
+                state == BluetoothAdapter.STATE_OFF || state == BluetoothAdapter.STATE_ON,
+                "State must be BluetoothAdapter.STATE_ON or BluetoothAdapter.STATE_OFF.");
+        mAdapterDelegate.setState(State.lookup(state));
+        return this;
+    }
+
+    @Override
+    public Bluelet setBluetoothClass(int bluetoothClass) {
+        mAdapterDelegate.setBluetoothClass(bluetoothClass);
+        return this;
+    }
+
+    @Override
+    public Bluelet setScanMode(int scanMode) {
+        mAdapterDelegate.setScanMode(scanMode);
+        return this;
+    }
+
+    @Override
+    public Bluelet setProfileUuids(ParcelUuid... profileUuids) {
+        this.mProfileUuids = profileUuids;
+        return this;
+    }
+
+    @Override
+    public Bluelet setIoCapabilities(IoCapabilities ioCapabilities) {
+        this.mIoCapabilities = ioCapabilities;
+        return this;
+    }
+
+    @Override
+    public Bluelet setCreateBondOutcome(CreateBondOutcome outcome, int failureReason) {
+        mCreateBondOutcome = outcome;
+        mCreateBondFailureReason = failureReason;
+        return this;
+    }
+
+    @Override
+    public Bluelet setRefuseConnections(boolean refuse) {
+        mRefuseConnections = refuse;
+        return this;
+    }
+
+    @Override
+    public Bluelet setRefuseGattConnections(boolean refuse) {
+        getGattDelegate().setRefuseConnections(refuse);
+        return this;
+    }
+
+    @Override
+    public Bluelet setFetchUuidsTiming(FetchUuidsTiming fetchUuidsTiming) {
+        this.mFetchUuidsTiming = fetchUuidsTiming;
+        return this;
+    }
+
+    @Override
+    public Bluelet addBondedDevice(String address) {
+        this.mBondedDevices.add(mAdapter.getRemoteDevice(address));
+        return this;
+    }
+
+    @Override
+    public Bluelet enableCVE20192225(boolean value) {
+        this.mEnableCVE20192225 = value;
+        return this;
+    }
+
+    IoCapabilities getIoCapabilities() {
+        return mIoCapabilities;
+    }
+
+    CreateBondOutcome getCreateBondOutcome() {
+        return mCreateBondOutcome;
+    }
+
+    int getCreateBondFailureReason() {
+        return mCreateBondFailureReason;
+    }
+
+    public boolean getRefuseConnections() {
+        return mRefuseConnections;
+    }
+
+    public FetchUuidsTiming getFetchUuidsTiming() {
+        return mFetchUuidsTiming;
+    }
+
+    BluetoothDevice[] getBondedDevices() {
+        return mBondedDevices.toArray(new BluetoothDevice[0]);
+    }
+
+    public boolean getEnableCVE20192225() {
+        return mEnableCVE20192225;
+    }
+
+    public void enableAdapter() {
+        LOGGER.d(String.format("Address: %s, enableAdapter()", address));
+        // TODO(b/200231384): async enabling, configurable delay, failure path
+        if (VERSION.SDK_INT < 23) {
+            mAdapterDelegate.processEvent(Event.USER_TURN_ON);
+            mAdapterDelegate.processEvent(Event.BREDR_STARTED);
+        } else {
+            mAdapterDelegate.processEvent(Event.BLE_TURN_ON);
+            mAdapterDelegate.processEvent(Event.BLE_STARTED);
+            mAdapterDelegate.processEvent(Event.USER_TURN_ON);
+            mAdapterDelegate.processEvent(Event.BREDR_STARTED);
+        }
+    }
+
+    public void disableAdapter() {
+        LOGGER.d(String.format("Address: %s, disableAdapter()", address));
+        // TODO(b/200231384): async disabling, configurable delay, failure path
+        if (VERSION.SDK_INT < 23) {
+            mAdapterDelegate.processEvent(Event.USER_TURN_OFF);
+            mAdapterDelegate.processEvent(Event.BREDR_STOPPED);
+        } else {
+            mAdapterDelegate.processEvent(Event.BLE_TURN_OFF);
+            mAdapterDelegate.processEvent(Event.BREDR_STOPPED);
+            mAdapterDelegate.processEvent(Event.USER_TURN_OFF);
+            mAdapterDelegate.processEvent(Event.BLE_STOPPED);
+        }
+    }
+
+    public AdapterDelegate getAdapterDelegate() {
+        return mAdapterDelegate;
+    }
+
+    public RfcommDelegate getRfcommDelegate() {
+        return mRfcommDelegate;
+    }
+
+    public GattDelegate getGattDelegate() {
+        return mGattDelegate;
+    }
+
+    public BluetoothAdapter getAdapter() {
+        return mAdapter;
+    }
+
+    public void setInterruptible(int identifier) {
+        LOGGER.d(String.format("Address: %s, setInterruptible(%d)", address, identifier));
+        mInterrupter.setInterruptible(identifier);
+    }
+
+    public void interrupt(int identifier) {
+        LOGGER.d(String.format("Address: %s, interrupt(%d)", address, identifier));
+        mInterrupter.interrupt(identifier);
+    }
+
+    @VisibleForTesting
+    public void setAdapterState(int state) throws IllegalArgumentException {
+        State s = State.lookup(state);
+        if (s == null) {
+            throw new IllegalArgumentException();
+        }
+        mAdapterDelegate.setState(s);
+    }
+
+    public int getBondState(String remoteAddress) {
+        return mRemoteAddressToBondState.containsKey(remoteAddress)
+                ? mRemoteAddressToBondState.get(remoteAddress)
+                : BluetoothDevice.BOND_NONE;
+    }
+
+    public void setBondState(String remoteAddress, int bondState, int failureReason) {
+        Intent intent =
+                newDeviceIntent(BluetoothDevice.ACTION_BOND_STATE_CHANGED, remoteAddress)
+                        .putExtra(BluetoothDevice.EXTRA_BOND_STATE, bondState)
+                        .putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
+                                getBondState(remoteAddress));
+
+        if (failureReason != REASON_SUCCESS) {
+            intent.putExtra(EXTRA_REASON, failureReason);
+        }
+
+        LOGGER.d(
+                String.format(
+                        "Address: %s, Bluetooth Bond State Change Intent: remote=%s, %s -> %s "
+                                + "(reason=%s)",
+                        address, remoteAddress, getBondState(remoteAddress), bondState,
+                        failureReason));
+        mRemoteAddressToBondState.put(remoteAddress, bondState);
+        mBluetoothBroadcastHandler.mBroadcastManager.sendBroadcast(
+                intent, android.Manifest.permission.BLUETOOTH);
+    }
+
+    public void onPairingRequest(String remoteAddress, int variant, int key) {
+        Intent intent =
+                newDeviceIntent(BluetoothDevice.ACTION_PAIRING_REQUEST, remoteAddress)
+                        .putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, variant)
+                        .putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, key);
+
+        LOGGER.d(
+                String.format(
+                        "Address: %s, Bluetooth Pairing Request Intent: remote=%s, variant=%s, "
+                                + "key=%s", address, remoteAddress, variant, key));
+        mBluetoothBroadcastHandler.mBroadcastManager.sendBroadcast(intent, permission.BLUETOOTH);
+    }
+
+    public PairingConfirmation getPairingConfirmation(String remoteAddress) {
+        PairingConfirmation confirmation = mRemoteAddressToPairingConfirmation.get(remoteAddress);
+        return confirmation == null ? PairingConfirmation.UNKNOWN : confirmation;
+    }
+
+    public void setPairingConfirmation(String remoteAddress, PairingConfirmation confirmation) {
+        mRemoteAddressToPairingConfirmation.put(remoteAddress, confirmation);
+    }
+
+    public void onFetchedUuids(String remoteAddress, ParcelUuid[] profileUuids) {
+        Intent intent =
+                newDeviceIntent(BluetoothDevice.ACTION_UUID, remoteAddress)
+                        .putExtra(BluetoothDevice.EXTRA_UUID, profileUuids);
+
+        LOGGER.d(
+                String.format(
+                        "Address: %s, Bluetooth Found UUIDs Intent: remoteAddress=%s, uuids=%s",
+                        address, remoteAddress, Arrays.toString(profileUuids)));
+        mBluetoothBroadcastHandler.mBroadcastManager.sendBroadcast(
+                intent, android.Manifest.permission.BLUETOOTH);
+    }
+
+    private static int maxProfileState(int a, int b) {
+        // Prefer connected > connecting > disconnecting > disconnected.
+        switch (a) {
+            case BluetoothProfile.STATE_CONNECTED:
+                return a;
+            case BluetoothProfile.STATE_CONNECTING:
+                return b == BluetoothProfile.STATE_CONNECTED ? b : a;
+            case BluetoothProfile.STATE_DISCONNECTING:
+                return b == BluetoothProfile.STATE_CONNECTED
+                        || b == BluetoothProfile.STATE_CONNECTING
+                        ? b
+                        : a;
+            case BluetoothProfile.STATE_DISCONNECTED:
+            default:
+                return b;
+        }
+    }
+
+    public int getAdapterConnectionState() {
+        int maxState = BluetoothProfile.STATE_DISCONNECTED;
+        for (int state : mProfileTypeToConnectionState.values()) {
+            maxState = maxProfileState(maxState, state);
+        }
+        return PROFILE_STATE_TO_ADAPTER_STATE.get(maxState);
+    }
+
+    public int getProfileConnectionState(int profileType) {
+        return mProfileTypeToConnectionState.containsKey(profileType)
+                ? mProfileTypeToConnectionState.get(profileType)
+                : BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    public void setProfileConnectionState(int profileType, int state, String remoteAddress) {
+        int previousAdapterState = getAdapterConnectionState();
+        mProfileTypeToConnectionState.put(profileType, state);
+        int adapterState = getAdapterConnectionState();
+        if (previousAdapterState != adapterState) {
+            Intent intent =
+                    newDeviceIntent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED, remoteAddress)
+                            .putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE,
+                                    previousAdapterState)
+                            .putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, adapterState);
+
+            LOGGER.d(
+                    "Adapter Connection State Changed Intent: "
+                            + previousAdapterState
+                            + " -> "
+                            + adapterState);
+            mBluetoothBroadcastHandler.mBroadcastManager.sendBroadcast(
+                    intent, android.Manifest.permission.BLUETOOTH);
+        }
+    }
+
+    static class BluetoothBroadcastHandler implements AdapterDelegate.Callback,
+            RfcommDelegate.Callback {
+
+        private final BroadcastManager mBroadcastManager;
+
+        BluetoothBroadcastHandler(BroadcastManager broadcastManager) {
+            this.mBroadcastManager = broadcastManager;
+        }
+
+        @Override
+        public void onAdapterStateChange(State prevState, State newState) {
+            int prev = prevState.getValue();
+            int cur = newState.getValue();
+            LOGGER.d("Bluetooth State Change Intent: " + State.lookup(prev) + " -> " + State.lookup(
+                    cur));
+            Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
+            intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prev);
+            intent.putExtra(BluetoothAdapter.EXTRA_STATE, cur);
+            mBroadcastManager.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH);
+        }
+
+        @Override
+        public void onBleStateChange(State prevState, State newState) {
+            int prev = prevState.getValue();
+            int cur = newState.getValue();
+            LOGGER.d("BLE State Change Intent: " + State.lookup(prev) + " -> " + State.lookup(cur));
+            Intent intent = new Intent(BluetoothConstants.ACTION_BLE_STATE_CHANGED);
+            intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prev);
+            intent.putExtra(BluetoothAdapter.EXTRA_STATE, cur);
+            mBroadcastManager.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH);
+        }
+
+        @Override
+        public void onConnectionStateChange(String remoteAddress, boolean isConnected) {
+            LOGGER.d("Bluetooth Connection State Change Intent, isConnected: " + isConnected);
+            Intent intent =
+                    isConnected
+                            ? newDeviceIntent(BluetoothDevice.ACTION_ACL_CONNECTED, remoteAddress)
+                            : newDeviceIntent(BluetoothDevice.ACTION_ACL_DISCONNECTED,
+                                    remoteAddress);
+            mBroadcastManager.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH);
+        }
+
+        @Override
+        public void onDiscoveryStarted() {
+            LOGGER.d("Bluetooth discovery started.");
+            Intent intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
+            mBroadcastManager.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH);
+        }
+
+        @Override
+        public void onDiscoveryFinished() {
+            LOGGER.d("Bluetooth discovery finished.");
+            Intent intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
+            mBroadcastManager.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH);
+        }
+
+        @Override
+        public void onDeviceFound(String address, int bluetoothClass, String name) {
+            LOGGER.d("Bluetooth device found, address: " + address);
+            Intent intent =
+                    newDeviceIntent(BluetoothDevice.ACTION_FOUND, address)
+                            .putExtra(
+                                    BluetoothDevice.EXTRA_CLASS,
+                                    callConstructor(
+                                            BluetoothClass.class,
+                                            ClassParameter.from(int.class, bluetoothClass)))
+                            .putExtra(BluetoothDevice.EXTRA_NAME, name);
+            // TODO(b/200231384): support rssi
+            // TODO(b/200231384): send broadcast with additional ACCESS_COARSE_LOCATION permission
+            // once broadcast permission is implemented.
+            mBroadcastManager.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH);
+        }
+    }
+
+    private static Intent newDeviceIntent(String action, String address) {
+        return new Intent(action)
+                .putExtra(
+                        BluetoothDevice.EXTRA_DEVICE,
+                        BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address));
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/BluetoothConstants.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/BluetoothConstants.java
new file mode 100644
index 0000000..fa519da
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/BluetoothConstants.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth;
+
+/**
+ * A class to hold Bluetooth constants.
+ */
+public class BluetoothConstants {
+
+    /*** Bluetooth Adapter State ***/
+    // Must be identical to BluetoothAdapter hidden field STATE_BLE_TURNING_ON
+    public static final int STATE_BLE_TURNING_ON = 14;
+
+    // Must be identical to BluetoothAdapter hidden field STATE_BLE_ON
+    public static final int STATE_BLE_ON = 15;
+
+    // Must be identical to BluetoothAdapter hidden field STATE_BLE_TURNING_OFF
+    public static final int STATE_BLE_TURNING_OFF = 16;
+
+    // Must be identical to BluetoothAdapter hidden field ACTION_BLE_STATE_CHANGED
+    public static final String ACTION_BLE_STATE_CHANGED =
+            "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
+
+    /*** Rfcomm Socket ***/
+    // Must be identical to BluetoothSocket field TYPE_RFCOMM.
+    // The field was package-private before M.
+    public static final int TYPE_RFCOMM = 1;
+
+    public static final int SOCKET_CLOSE = -10000;
+
+    // Android Bluetooth use -1 as port when creating server socket with uuid
+    public static final int SERVER_SOCKET_CHANNEL_AUTO_ASSIGN = -1;
+
+    // Android Bluetooth use -1 as port when creating socket with a uuid
+    public static final int SOCKET_CHANNEL_CONNECT_WITH_UUID = -1;
+
+    /*** BLE Advertise/Scan ***/
+    // Must be identical to AdvertiseCallback hidden field ADVERTISE_SUCCESS.
+    public static final int ADVERTISE_SUCCESS = 0;
+
+    // Must be identical to ScanRecord field DATA_TYPE_FLAGS.
+    public static final int DATA_TYPE_FLAGS = 0x01;
+
+    // Must be identical to ScanRecord field DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE.
+    public static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE = 0x07;
+
+    // Must be identical to ScanRecord field DATA_TYPE_LOCAL_NAME_COMPLETE.
+    public static final int DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09;
+
+    // Must be identical to ScanRecord field DATA_TYPE_TX_POWER_LEVEL.
+    public static final int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
+
+    // Must be identical to ScanRecord field DATA_TYPE_SERVICE_DATA.
+    public static final int DATA_TYPE_SERVICE_DATA = 0x16;
+
+    // Must be identical to ScanRecord field DATA_TYPE_MANUFACTURER_SPECIFIC_DATA.
+    public static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
+
+    /**
+     * @see #DATA_TYPE_FLAGS
+     */
+    public interface Flags {
+
+        byte LE_LIMITED_DISCOVERABLE_MODE = 1;
+        byte LE_GENERAL_DISCOVERABLE_MODE = 1 << 1;
+        byte BR_EDR_NOT_SUPPORTED = 1 << 2;
+        byte SIMULTANEOUS_LE_AND_BR_EDR_CONTROLLER = 1 << 3;
+        byte SIMULTANEOUS_LE_AND_BR_EDR_HOST = 1 << 4;
+    }
+
+    /**
+     * Observed that Android sets this for {@link #DATA_TYPE_FLAGS} when a packet is connectable (on
+     * a Nexus 6P running 7.1.2).
+     */
+    public static final byte FLAGS_IN_CONNECTABLE_PACKETS =
+            Flags.BR_EDR_NOT_SUPPORTED
+                    | Flags.LE_GENERAL_DISCOVERABLE_MODE
+                    | Flags.SIMULTANEOUS_LE_AND_BR_EDR_CONTROLLER
+                    | Flags.SIMULTANEOUS_LE_AND_BR_EDR_HOST;
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/GattDelegate.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/GattDelegate.java
new file mode 100644
index 0000000..4618561
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/GattDelegate.java
@@ -0,0 +1,609 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth;
+
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.IBluetoothGattCallback;
+import android.bluetooth.IBluetoothGattServerCallback;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.ParcelUuid;
+import android.os.SystemClock;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.DeviceletImpl;
+import com.android.libraries.testing.deviceshadower.internal.utils.GattHelper;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Bytes;
+
+import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Delegate to operate gatt operations.
+ */
+public class GattDelegate {
+
+    private static final int DEFAULT_RSSI = -50;
+    private static final Logger LOGGER = Logger.create("GattDelegate");
+
+    // chipset properties
+    // use 2 as API 21 requires multi-advertisement support to use Le Advertising.
+    private final int mMaxAdvertiseInstances = 2;
+    private final AtomicBoolean mIsOffloadedFilteringSupported = new AtomicBoolean(false);
+    private final String mAddress;
+    private final AtomicInteger mCurrentClientIf = new AtomicInteger(0);
+    private final AtomicInteger mCurrentServerIf = new AtomicInteger(0);
+    private final AtomicBoolean mCurrentConnectionState = new AtomicBoolean(false);
+    private final Map<ParcelUuid, Service> mServices = new HashMap<>();
+    private final Map<Integer, IBluetoothGattCallback> mClientCallbacks;
+    private final Map<Integer, IBluetoothGattServerCallback> mServerCallbacks;
+    private final Map<Integer, Advertiser> mAdvertisers;
+    private final Map<Integer, Scanner> mScanners;
+    @Nullable
+    private Request mLastRequest;
+    private boolean mConnectable = true;
+
+    /**
+     * The parameters of a request, e.g. readCharacteristic(). Subclass for each request.
+     *
+     * @see #getLastRequest()
+     */
+    abstract static class Request {
+
+        final int mSrvcType;
+        final int mSrvcInstId;
+        final ParcelUuid mSrvcId;
+        final int mCharInstId;
+        final ParcelUuid mCharId;
+
+        Request(int srvcType, int srvcInstId, ParcelUuid srvcId, int charInstId,
+                ParcelUuid charId) {
+            this.mSrvcType = srvcType;
+            this.mSrvcInstId = srvcInstId;
+            this.mSrvcId = srvcId;
+            this.mCharInstId = charInstId;
+            this.mCharId = charId;
+        }
+    }
+
+    /**
+     * Corresponds to {@link android.bluetooth.IBluetoothGatt#readCharacteristic}.
+     */
+    static class ReadCharacteristicRequest extends Request {
+
+        ReadCharacteristicRequest(
+                int srvcType, int srvcInstId, ParcelUuid srvcId, int charInstId,
+                ParcelUuid charId) {
+            super(srvcType, srvcInstId, srvcId, charInstId, charId);
+        }
+    }
+
+    /**
+     * Corresponds to {@link android.bluetooth.IBluetoothGatt#readDescriptor}.
+     */
+    static class ReadDescriptorRequest extends Request {
+
+        final int mDescrInstId;
+        final ParcelUuid mDescrId;
+
+        ReadDescriptorRequest(
+                int srvcType,
+                int srvcInstId,
+                ParcelUuid srvcId,
+                int charInstId,
+                ParcelUuid charId,
+                int descrInstId,
+                ParcelUuid descrId) {
+            super(srvcType, srvcInstId, srvcId, charInstId, charId);
+            this.mDescrInstId = descrInstId;
+            this.mDescrId = descrId;
+        }
+    }
+
+    GattDelegate(String address) {
+        this(
+                address,
+                new HashMap<>(),
+                new HashMap<>(),
+                new ConcurrentHashMap<>(),
+                new ConcurrentHashMap<>());
+    }
+
+    @VisibleForTesting
+    GattDelegate(
+            String address,
+            Map<Integer, IBluetoothGattCallback> clientCallbacks,
+            Map<Integer, IBluetoothGattServerCallback> serverCallbacks,
+            Map<Integer, Advertiser> advertisers,
+            Map<Integer, Scanner> scanners) {
+        this.mAddress = address;
+        this.mClientCallbacks = clientCallbacks;
+        this.mServerCallbacks = serverCallbacks;
+        this.mAdvertisers = advertisers;
+        this.mScanners = scanners;
+    }
+
+    public void setRefuseConnections(boolean refuse) {
+        this.mConnectable = !refuse;
+    }
+
+    /**
+     * Used to maintain state between the request (e.g. readCharacteristic()) and sendResponse().
+     */
+    @Nullable
+    Request getLastRequest() {
+        return mLastRequest;
+    }
+
+    /**
+     * @see #getLastRequest()
+     */
+    void setLastRequest(@Nullable Request params) {
+        mLastRequest = params;
+    }
+
+    public int getClientIf() {
+        // TODO(b/200231384): support multiple client if.
+        return mCurrentClientIf.get();
+    }
+
+    public int getServerIf() {
+        // TODO(b/200231384): support multiple server if.
+        return mCurrentServerIf.get();
+    }
+
+    public IBluetoothGattServerCallback getServerCallback(int serverIf) {
+        return mServerCallbacks.get(serverIf);
+    }
+
+    public IBluetoothGattCallback getClientCallback(int clientIf) {
+        return mClientCallbacks.get(clientIf);
+    }
+
+    public int registerServer(IBluetoothGattServerCallback callback) {
+        mServerCallbacks.put(mCurrentServerIf.incrementAndGet(), callback);
+        return getServerIf();
+    }
+
+    public int registerClient(IBluetoothGattCallback callback) {
+        mClientCallbacks.put(mCurrentClientIf.incrementAndGet(), callback);
+        LOGGER.d(String.format("Client registered on %s, clientIf: %d", mAddress, getClientIf()));
+        return getClientIf();
+    }
+
+    public void unregisterClient(int clientIf) {
+        mClientCallbacks.remove(clientIf);
+        LOGGER.d(String.format("Client unregistered on %s, clientIf: %d", mAddress, clientIf));
+    }
+
+    public void unregisterServer(int serverIf) {
+        mServerCallbacks.remove(serverIf);
+    }
+
+    public int getMaxAdvertiseInstances() {
+        return mMaxAdvertiseInstances;
+    }
+
+    public boolean isOffloadedFilteringSupported() {
+        return mIsOffloadedFilteringSupported.get();
+    }
+
+    public boolean connect(String address) {
+        return mConnectable;
+    }
+
+    public boolean disconnect(String address) {
+        return true;
+    }
+
+    public void clientConnectionStateChange(
+            int state, int clientIf, boolean connected, String address) {
+        if (connected != mCurrentConnectionState.get()) {
+            mCurrentConnectionState.set(connected);
+            IBluetoothGattCallback callback = getClientCallback(clientIf);
+            if (callback != null) {
+                callback.onClientConnectionState(state, clientIf, connected, address);
+            }
+        }
+    }
+
+    public void serverConnectionStateChange(
+            int state, int serverIf, boolean connected, String address) {
+        if (connected != mCurrentConnectionState.get()) {
+            mCurrentConnectionState.set(connected);
+            IBluetoothGattServerCallback callback = getServerCallback(serverIf);
+            if (callback != null) {
+                callback.onServerConnectionState(state, serverIf, connected, address);
+            }
+        }
+    }
+
+    public Service addService(ParcelUuid uuid) {
+        Service srvc = new Service(uuid);
+        mServices.put(uuid, srvc);
+        return srvc;
+    }
+
+    public Collection<Service> getServices() {
+        return mServices.values();
+    }
+
+    public Service getService(ParcelUuid uuid) {
+        return mServices.get(uuid);
+    }
+
+    public void clientSetMtu(int clientIf, int mtu, String serverAddress) {
+        IBluetoothGattCallback callback = getClientCallback(clientIf);
+        if (callback != null && Build.VERSION.SDK_INT >= 21) {
+            callback.onConfigureMTU(serverAddress, mtu, BluetoothGatt.GATT_SUCCESS);
+        }
+    }
+
+    public void serverSetMtu(int serverIf, int mtu, String clientAddress) {
+        IBluetoothGattServerCallback callback = getServerCallback(serverIf);
+        if (callback != null && Build.VERSION.SDK_INT >= 22) {
+            callback.onMtuChanged(clientAddress, mtu);
+        }
+    }
+
+    public void startMultiAdvertising(
+            int appIf,
+            AdvertiseData advertiseData,
+            AdvertiseData scanResponse,
+            final AdvertiseSettings settings) {
+        LOGGER.d(String.format("startMultiAdvertising(%d) on %s", appIf, mAddress));
+        final Advertiser advertiser =
+                new Advertiser(
+                        appIf,
+                        mAddress,
+                        DeviceShadowEnvironmentImpl.getLocalBlueletImpl().mName,
+                        txPowerFromFlag(settings.getTxPowerLevel()),
+                        advertiseData,
+                        scanResponse,
+                        settings);
+        mAdvertisers.put(appIf, advertiser);
+        final IBluetoothGattCallback callback = mClientCallbacks.get(appIf);
+        @SuppressWarnings("unused") // go/futurereturn-lsc
+        Future<?> possiblyIgnoredError =
+                DeviceShadowEnvironmentImpl.run(
+                        mAddress,
+                        () -> {
+                            callback.onMultiAdvertiseCallback(
+                                    BluetoothConstants.ADVERTISE_SUCCESS, true /* isStart */,
+                                    settings);
+                            return null;
+                        });
+    }
+
+    /**
+     * Returns TxPower in dBm as measured at the source.
+     *
+     * <p>Note that this will vary by device and the values are only roughly accurate. The
+     * measurements were taken with a Nexus 6. Copied from the TxEddystone-UID app:
+     * {https://github.com/google/eddystone/blob/master/eddystone-uid/tools/txeddystone-uid/TxEddystone-UID/app/src/main/java/com/google/sample/txeddystone_uid/MainActivity.java}
+     */
+    private static byte txPowerFromFlag(int txPowerFlag) {
+        switch (txPowerFlag) {
+            case AdvertiseSettings.ADVERTISE_TX_POWER_HIGH:
+                return (byte) -16;
+            case AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM:
+                return (byte) -26;
+            case AdvertiseSettings.ADVERTISE_TX_POWER_LOW:
+                return (byte) -35;
+            case AdvertiseSettings.ADVERTISE_TX_POWER_ULTRA_LOW:
+                return (byte) -59;
+            default:
+                throw new IllegalStateException("Unknown TxPower level=" + txPowerFlag);
+        }
+    }
+
+    public void stopMultiAdvertising(int appIf) {
+        LOGGER.d(String.format("stopAdvertising(%d) on %s", appIf, mAddress));
+        Advertiser advertiser = mAdvertisers.get(appIf);
+        if (advertiser == null) {
+            LOGGER.d(String.format("Advertising already stopped on %s, clientIf: %d", mAddress,
+                    appIf));
+            return;
+        }
+        mAdvertisers.remove(appIf);
+        final IBluetoothGattCallback callback = mClientCallbacks.get(appIf);
+        @SuppressWarnings("unused") // go/futurereturn-lsc
+        Future<?> possiblyIgnoredError =
+                DeviceShadowEnvironmentImpl.run(
+                        mAddress,
+                        () -> {
+                            callback.onMultiAdvertiseCallback(
+                                    BluetoothConstants.ADVERTISE_SUCCESS, false /* isStart */,
+                                    null /* setting */);
+                            return null;
+                        });
+    }
+
+    public void startScan(final int appIf, ScanSettings settings, List<ScanFilter> filters) {
+        LOGGER.d(String.format("startScan(%d) on %s", appIf, mAddress));
+        if (filters == null) {
+            filters = new ArrayList<>();
+        }
+        final Scanner scanner = new Scanner(appIf, settings, filters);
+        mScanners.put(appIf, scanner);
+        @SuppressWarnings("unused") // go/futurereturn-lsc
+        Future<?> possiblyIgnoredError =
+                DeviceShadowEnvironmentImpl.run(
+                        mAddress,
+                        () -> {
+                            try {
+                                scan(scanner);
+                            } catch (InterruptedException e) {
+                                LOGGER.e(
+                                        String.format("Failed to scan on %s, clientIf: %d.",
+                                                mAddress, scanner.mClientIf),
+                                        e);
+                            }
+                            return null;
+                        });
+    }
+
+    // TODO(b/200231384): support periodic scan with interval and scan window.
+    private void scan(Scanner scanner) throws InterruptedException {
+        // fetch existing advertisements
+        List<DeviceletImpl> devicelets = DeviceShadowEnvironmentImpl.getDeviceletImpls();
+        for (DeviceletImpl devicelet : devicelets) {
+            BlueletImpl bluelet = devicelet.blueletImpl();
+            if (bluelet.address.equals(mAddress)) {
+                continue;
+            }
+            for (Advertiser advertiser : bluelet.getGattDelegate().mAdvertisers.values()) {
+                if (VERSION.SDK_INT < 21) {
+                    throw new UnsupportedOperationException(
+                            String.format("API %d is not supported.", VERSION.SDK_INT));
+                }
+
+                byte[] advertiseData =
+                        GattHelper.convertAdvertiseData(
+                                advertiser.mAdvertiseData,
+                                advertiser.mTxPowerLevel,
+                                advertiser.mName,
+                                advertiser.mSettings.isConnectable());
+                byte[] scanResponse =
+                        GattHelper.convertAdvertiseData(
+                                advertiser.mScanResponse,
+                                advertiser.mTxPowerLevel,
+                                advertiser.mName,
+                                advertiser.mSettings.isConnectable());
+
+                ScanRecord scanRecord =
+                        ReflectionHelpers.callStaticMethod(
+                                ScanRecord.class,
+                                "parseFromBytes",
+                                ClassParameter.from(byte[].class,
+                                        Bytes.concat(advertiseData, scanResponse)));
+                ScanResult scanResult =
+                        new ScanResult(
+                                BluetoothAdapter.getDefaultAdapter()
+                                        .getRemoteDevice(advertiser.mAddress),
+                                scanRecord,
+                                DEFAULT_RSSI,
+                                SystemClock.elapsedRealtimeNanos());
+
+                if (!matchFilters(scanResult, scanner.mFilters)) {
+                    continue;
+                }
+
+                IBluetoothGattCallback callback = mClientCallbacks.get(scanner.mClientIf);
+                if (callback == null) {
+                    LOGGER.e(
+                            String.format("Callback is null on %s, clientIf: %d", mAddress,
+                                    scanner.mClientIf));
+                    return;
+                }
+                callback.onScanResult(scanResult);
+            }
+        }
+    }
+
+    private boolean matchFilters(ScanResult scanResult, List<ScanFilter> filters) {
+        for (ScanFilter filter : filters) {
+            if (!filter.matches(scanResult)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public void stopScan(int appIf) {
+        LOGGER.d(String.format("stopScan(%d) on %s", appIf, mAddress));
+        Scanner scanner = mScanners.get(appIf);
+        if (scanner == null) {
+            LOGGER.d(
+                    String.format("Scanning already stopped on %s, clientIf: %d", mAddress, appIf));
+            return;
+        }
+        mScanners.remove(appIf);
+    }
+
+    static class Service {
+
+        private Map<ParcelUuid, Characteristic> mCharacteristics = new HashMap<>();
+        private ParcelUuid mUuid;
+
+        Service(ParcelUuid uuid) {
+            this.mUuid = uuid;
+        }
+
+        Characteristic getCharacteristic(ParcelUuid uuid) {
+            return mCharacteristics.get(uuid);
+        }
+
+        Characteristic addCharacteristic(ParcelUuid uuid, int properties, int permissions) {
+            Characteristic ch = new Characteristic(uuid, properties, permissions);
+            mCharacteristics.put(uuid, ch);
+            return ch;
+        }
+
+        Collection<Characteristic> getCharacteristics() {
+            return mCharacteristics.values();
+        }
+
+        ParcelUuid getUuid() {
+            return this.mUuid;
+        }
+    }
+
+    static class Characteristic {
+
+        private int mProperties;
+        private ParcelUuid mUuid;
+        private Map<ParcelUuid, Descriptor> mDescriptors = new HashMap<>();
+        private Set<String> mNotifyClients = new HashSet<>();
+        private byte[] mValue;
+
+        Characteristic(ParcelUuid uuid, int properties, int permissions) {
+            this.mProperties = properties;
+            this.mUuid = uuid;
+        }
+
+        Descriptor getDescriptor(ParcelUuid uuid) {
+            return mDescriptors.get(uuid);
+        }
+
+        Descriptor addDescriptor(ParcelUuid uuid, int permissions) {
+            Descriptor desc = new Descriptor(uuid, permissions);
+            mDescriptors.put(uuid, desc);
+            return desc;
+        }
+
+        Collection<Descriptor> getDescriptors() {
+            return mDescriptors.values();
+        }
+
+        void setValue(byte[] value) {
+            this.mValue = value;
+        }
+
+        byte[] getValue() {
+            return mValue;
+        }
+
+        ParcelUuid getUuid() {
+            return mUuid;
+        }
+
+        int getProperties() {
+            return mProperties;
+        }
+
+        void registerNotification(String client, int clientIf) {
+            mNotifyClients.add(client);
+        }
+
+        Set<String> getNotifyClients() {
+            return mNotifyClients;
+        }
+    }
+
+    static class Descriptor {
+
+        int mPermissions;
+        ParcelUuid mUuid;
+        byte[] mValue;
+
+        Descriptor(ParcelUuid uuid, int permissions) {
+            this.mUuid = uuid;
+            this.mPermissions = permissions;
+        }
+
+        void setValue(byte[] value) {
+            this.mValue = value;
+        }
+
+        byte[] getValue() {
+            return mValue;
+        }
+
+        ParcelUuid getUuid() {
+            return mUuid;
+        }
+    }
+
+    @VisibleForTesting
+    static class Advertiser {
+
+        final int mClientIf;
+        final String mAddress;
+        final String mName;
+        final int mTxPowerLevel;
+        final AdvertiseData mAdvertiseData;
+        @Nullable
+        final AdvertiseData mScanResponse;
+        final AdvertiseSettings mSettings;
+
+        Advertiser(
+                int clientIf,
+                String address,
+                String name,
+                int txPowerLevel,
+                AdvertiseData advertiseData,
+                AdvertiseData scanResponse,
+                AdvertiseSettings settings) {
+            this.mClientIf = clientIf;
+            this.mAddress = Preconditions.checkNotNull(address);
+            this.mName = name;
+            this.mTxPowerLevel = txPowerLevel;
+            this.mAdvertiseData = Preconditions.checkNotNull(advertiseData);
+            this.mScanResponse = scanResponse;
+            this.mSettings = Preconditions.checkNotNull(settings);
+        }
+    }
+
+    @VisibleForTesting
+    static class Scanner {
+
+        final int mClientIf;
+        final ScanSettings mSettings;
+        final List<ScanFilter> mFilters;
+
+        Scanner(int clientIf, ScanSettings settings, List<ScanFilter> filters) {
+            this.mClientIf = clientIf;
+            this.mSettings = Preconditions.checkNotNull(settings);
+            this.mFilters = Preconditions.checkNotNull(filters);
+        }
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/IBluetoothGattImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/IBluetoothGattImpl.java
new file mode 100644
index 0000000..0ac287d
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/IBluetoothGattImpl.java
@@ -0,0 +1,707 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.IBluetoothGatt;
+import android.bluetooth.IBluetoothGattCallback;
+import android.bluetooth.IBluetoothGattServerCallback;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanSettings;
+import android.os.ParcelUuid;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.GattDelegate.ReadCharacteristicRequest;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.GattDelegate.ReadDescriptorRequest;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.GattDelegate.Request;
+import com.android.libraries.testing.deviceshadower.internal.common.NamedRunnable;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of IBluetoothGatt.
+ */
+public class IBluetoothGattImpl implements IBluetoothGatt {
+
+    private static final Logger LOGGER = Logger.create("IBluetoothGattImpl");
+    private GattDelegate.Service mCurrentService;
+    private GattDelegate.Characteristic mCurrentCharacteristic;
+
+    @Override
+    public void startScan(
+            int appIf,
+            boolean isServer,
+            ScanSettings settings,
+            List<ScanFilter> filters,
+            List<?> scanStorages,
+            String callingPackage) {
+        localGattDelegate().startScan(appIf, settings, filters);
+    }
+
+    @Override
+    public void startScan(
+            int appIf,
+            boolean isServer,
+            ScanSettings settings,
+            List<ScanFilter> filters,
+            List<?> scanStorages) {
+        startScan(appIf, isServer, settings, filters, scanStorages, "" /* callingPackage */);
+    }
+
+    @Override
+    public void stopScan(int appIf, boolean isServer) {
+        localGattDelegate().stopScan(appIf);
+    }
+
+    @Override
+    public void startMultiAdvertising(
+            int appIf,
+            AdvertiseData advertiseData,
+            AdvertiseData scanResponse,
+            AdvertiseSettings settings) {
+        localGattDelegate().startMultiAdvertising(appIf, advertiseData, scanResponse, settings);
+    }
+
+    @Override
+    public void stopMultiAdvertising(int appIf) {
+        localGattDelegate().stopMultiAdvertising(appIf);
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void registerClient(ParcelUuid appId, final IBluetoothGattCallback callback) {
+        final int clientIf = localGattDelegate().registerClient(callback);
+        NamedRunnable onClientRegistered =
+                NamedRunnable.create(
+                        "ClientGatt.onClientRegistered=" + clientIf,
+                        () -> {
+                            callback.onClientRegistered(BluetoothGatt.GATT_SUCCESS, clientIf);
+                        });
+
+        DeviceShadowEnvironmentImpl.runOnService(localAddress(), onClientRegistered);
+    }
+
+    @Override
+    public void unregisterClient(int clientIf) {
+        localGattDelegate().unregisterClient(clientIf);
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void clientConnect(
+            final int clientIf, final String serverAddress, boolean isDirect, int transport) {
+        // TODO(b/200231384): implement auto connect.
+        String clientAddress = localAddress();
+        int serverIf = remoteGattDelegate(serverAddress).getServerIf();
+        boolean success = remoteGattDelegate(serverAddress).connect(clientAddress);
+        if (!success) {
+            LOGGER.i(String.format("clientConnect failed: %s connect %s", serverAddress,
+                    clientAddress));
+            return;
+        }
+
+        DeviceShadowEnvironmentImpl.runOnService(
+                clientAddress,
+                newClientConnectionStateChangeRunnable(clientIf, true, serverAddress));
+
+        DeviceShadowEnvironmentImpl.runOnService(
+                serverAddress,
+                newServerConnectionStateChangeRunnable(serverIf, true, clientAddress));
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void clientDisconnect(final int clientIf, final String serverAddress) {
+        final String clientAddress = localAddress();
+        remoteGattDelegate(serverAddress).disconnect(clientAddress);
+        int serverIf = remoteGattDelegate(serverAddress).getServerIf();
+
+
+        DeviceShadowEnvironmentImpl.runOnService(
+                clientAddress,
+                newClientConnectionStateChangeRunnable(clientIf, false, serverAddress));
+
+        DeviceShadowEnvironmentImpl.runOnService(
+                serverAddress,
+                newServerConnectionStateChangeRunnable(serverIf, false, clientAddress));
+    }
+
+    @Override
+    public void discoverServices(int clientIf, String serverAddress) {
+        final IBluetoothGattCallback callback = localGattDelegate().getClientCallback(clientIf);
+        if (callback == null) {
+            return;
+        }
+        for (GattDelegate.Service service : remoteGattDelegate(serverAddress).getServices()) {
+            callback.onGetService(serverAddress, 0 /*srvcType*/, 0 /*srvcInstId*/,
+                    service.getUuid());
+
+            for (GattDelegate.Characteristic characteristic : service.getCharacteristics()) {
+                callback.onGetCharacteristic(
+                        serverAddress,
+                        0 /*srvcType*/,
+                        0 /*srvcInstId*/,
+                        service.getUuid(),
+                        0 /*charInstId*/,
+                        characteristic.getUuid(),
+                        characteristic.getProperties());
+                for (GattDelegate.Descriptor descriptor : characteristic.getDescriptors()) {
+                    callback.onGetDescriptor(
+                            serverAddress,
+                            0 /*srvcType*/,
+                            0 /*srvcInstId*/,
+                            service.getUuid(),
+                            0 /*charInstId*/,
+                            characteristic.getUuid(),
+                            0 /*descrInstId*/,
+                            descriptor.getUuid());
+                }
+            }
+        }
+
+        callback.onSearchComplete(serverAddress, BluetoothGatt.GATT_SUCCESS);
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void readCharacteristic(
+            final int clientIf,
+            final String serverAddress,
+            final int srvcType,
+            final int srvcInstId,
+            final ParcelUuid srvcId,
+            final int charInstId,
+            final ParcelUuid charId,
+            final int authReq) {
+        // TODO(b/200231384): implement authReq.
+        final String clientAddress = localAddress();
+        localGattDelegate()
+                .setLastRequest(
+                        new ReadCharacteristicRequest(srvcType, srvcInstId, srvcId, charInstId,
+                                charId));
+
+        NamedRunnable serverOnCharacteristicReadRequest =
+                NamedRunnable.create(
+                        "ServerGatt.onCharacteristicReadRequest",
+                        () -> {
+                            int serverIf = localGattDelegate().getServerIf();
+                            IBluetoothGattServerCallback callback =
+                                    localGattDelegate().getServerCallback(serverIf);
+                            if (callback != null) {
+                                callback.onCharacteristicReadRequest(
+                                        clientAddress,
+                                        0 /*transId*/,
+                                        0 /*offset*/,
+                                        false /*isLong*/,
+                                        0 /*srvcType*/,
+                                        srvcInstId,
+                                        srvcId,
+                                        charInstId,
+                                        charId);
+                            }
+                        });
+
+        DeviceShadowEnvironmentImpl.runOnService(serverAddress, serverOnCharacteristicReadRequest);
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void writeCharacteristic(
+            final int clientIf,
+            final String serverAddress,
+            final int srvcType,
+            final int srvcInstId,
+            final ParcelUuid srvcId,
+            final int charInstId,
+            final ParcelUuid charId,
+            final int writeType,
+            final int authReq,
+            final byte[] value) {
+        // TODO(b/200231384): implement write with response needed.
+        remoteGattDelegate(serverAddress).getService(srvcId).getCharacteristic(charId)
+                .setValue(value);
+        final String clientAddress = localAddress();
+
+        NamedRunnable clientOnCharacteristicWrite =
+                NamedRunnable.create(
+                        "ClientGatt.onCharacteristicWrite",
+                        () -> {
+                            IBluetoothGattCallback callback = localGattDelegate().getClientCallback(
+                                    clientIf);
+                            if (callback != null) {
+                                callback.onCharacteristicWrite(
+                                        serverAddress,
+                                        BluetoothGatt.GATT_SUCCESS,
+                                        0 /*srvcType*/,
+                                        srvcInstId,
+                                        srvcId,
+                                        charInstId,
+                                        charId);
+                            }
+                        });
+
+        NamedRunnable onCharacteristicWriteRequest =
+                NamedRunnable.create(
+                        "ServerGatt.onCharacteristicWriteRequest",
+                        () -> {
+                            int serverIf = localGattDelegate().getServerIf();
+                            IBluetoothGattServerCallback callback =
+                                    localGattDelegate().getServerCallback(serverIf);
+                            if (callback != null) {
+                                callback.onCharacteristicWriteRequest(
+                                        clientAddress,
+                                        0 /*transId*/,
+                                        0 /*offset*/,
+                                        value.length,
+                                        false /*isPrep*/,
+                                        false /*needRsp*/,
+                                        0 /*srvcType*/,
+                                        srvcInstId,
+                                        srvcId,
+                                        charInstId,
+                                        charId,
+                                        value);
+                            }
+                        });
+
+        DeviceShadowEnvironmentImpl.runOnService(clientAddress, clientOnCharacteristicWrite);
+
+        DeviceShadowEnvironmentImpl.runOnService(serverAddress, onCharacteristicWriteRequest);
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void readDescriptor(
+            final int clientIf,
+            final String serverAddress,
+            final int srvcType,
+            final int srvcInstId,
+            final ParcelUuid srvcId,
+            final int charInstId,
+            final ParcelUuid charId,
+            final int descrInstId,
+            final ParcelUuid descrId,
+            final int authReq) {
+        final String clientAddress = localAddress();
+        localGattDelegate()
+                .setLastRequest(
+                        new ReadDescriptorRequest(
+                                srvcType, srvcInstId, srvcId, charInstId, charId, descrInstId,
+                                descrId));
+
+        NamedRunnable serverOnDescriptorReadRequest =
+                NamedRunnable.create(
+                        "ServerGatt.onDescriptorReadRequest",
+                        () -> {
+                            int serverIf = localGattDelegate().getServerIf();
+                            IBluetoothGattServerCallback callback =
+                                    localGattDelegate().getServerCallback(serverIf);
+                            if (callback != null) {
+                                callback.onDescriptorReadRequest(
+                                        clientAddress,
+                                        0 /*transId*/,
+                                        0 /*offset*/,
+                                        false /*isLong*/,
+                                        0 /*srvcType*/,
+                                        srvcInstId,
+                                        srvcId,
+                                        charInstId,
+                                        charId,
+                                        descrId);
+                            }
+                        });
+
+        DeviceShadowEnvironmentImpl.runOnService(serverAddress, serverOnDescriptorReadRequest);
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void writeDescriptor(
+            final int clientIf,
+            final String serverAddress,
+            final int srvcType,
+            final int srvcInstId,
+            final ParcelUuid srvcId,
+            final int charInstId,
+            final ParcelUuid charId,
+            final int descrInstId,
+            final ParcelUuid descrId,
+            final int writeType,
+            final int authReq,
+            final byte[] value) {
+        // TODO(b/200231384): implement write with response needed.
+        remoteGattDelegate(serverAddress)
+                .getService(srvcId)
+                .getCharacteristic(charId)
+                .getDescriptor(descrId)
+                .setValue(value);
+        final String clientAddress = localAddress();
+
+        NamedRunnable serverOnDescriptorWriteRequest =
+                NamedRunnable.create(
+                        "ServerGatt.onDescriptorWriteRequest",
+                        () -> {
+                            int serverIf = localGattDelegate().getServerIf();
+                            IBluetoothGattServerCallback callback =
+                                    localGattDelegate().getServerCallback(serverIf);
+                            if (callback != null) {
+                                callback.onDescriptorWriteRequest(
+                                        clientAddress,
+                                        0 /*transId*/,
+                                        0 /*offset*/,
+                                        value.length,
+                                        false /*isPrep*/,
+                                        false /*needRsp*/,
+                                        0 /*srvcType*/,
+                                        srvcInstId,
+                                        srvcId,
+                                        charInstId,
+                                        charId,
+                                        descrId,
+                                        value);
+                            }
+                        });
+
+        NamedRunnable clientOnDescriptorWrite =
+                NamedRunnable.create(
+                        "ClientGatt.onDescriptorWrite",
+                        () -> {
+                            IBluetoothGattCallback callback = localGattDelegate().getClientCallback(
+                                    clientIf);
+                            if (callback != null) {
+                                callback.onDescriptorWrite(
+                                        serverAddress,
+                                        BluetoothGatt.GATT_SUCCESS,
+                                        0 /*srvcType*/,
+                                        srvcInstId,
+                                        srvcId,
+                                        charInstId,
+                                        charId,
+                                        descrInstId,
+                                        descrId);
+                            }
+                        });
+
+        DeviceShadowEnvironmentImpl.runOnService(serverAddress, serverOnDescriptorWriteRequest);
+
+        DeviceShadowEnvironmentImpl.runOnService(clientAddress, clientOnDescriptorWrite);
+    }
+
+    @Override
+    public void registerForNotification(
+            int clientIf,
+            String remoteAddress,
+            int srvcType,
+            int srvcInstId,
+            ParcelUuid srvcId,
+            int charInstId,
+            ParcelUuid charId,
+            boolean enable) {
+        remoteGattDelegate(remoteAddress)
+                .getService(srvcId)
+                .getCharacteristic(charId)
+                .registerNotification(localAddress(), clientIf);
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void registerServer(ParcelUuid appId, final IBluetoothGattServerCallback callback) {
+        // TODO(b/200231384): support multiple serverIf.
+        final int serverIf = localGattDelegate().registerServer(callback);
+        NamedRunnable serverOnRegistered =
+                NamedRunnable.create(
+                        "ServerGatt.onServerRegistered",
+                        () -> {
+                            callback.onServerRegistered(BluetoothGatt.GATT_SUCCESS, serverIf);
+                        });
+
+        DeviceShadowEnvironmentImpl.runOnService(localAddress(), serverOnRegistered);
+    }
+
+    @Override
+    public void unregisterServer(int serverIf) {
+        localGattDelegate().unregisterServer(serverIf);
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void serverConnect(
+            final int serverIf, final String clientAddress, boolean isDirect, int transport) {
+        // TODO(b/200231384): implement isDirect and transport.
+        boolean success = localGattDelegate().connect(clientAddress);
+        final String serverAddress = localAddress();
+        if (!success) {
+            return;
+        }
+        int clientIf = remoteGattDelegate(clientAddress).getClientIf();
+
+        DeviceShadowEnvironmentImpl.runOnService(
+                serverAddress,
+                newServerConnectionStateChangeRunnable(serverIf, true, clientAddress));
+
+        DeviceShadowEnvironmentImpl.runOnService(
+                clientAddress,
+                newClientConnectionStateChangeRunnable(clientIf, true, serverAddress));
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void serverDisconnect(final int serverIf, final String clientAddress) {
+        localGattDelegate().disconnect(clientAddress);
+        String serverAddress = localAddress();
+        int clientIf = remoteGattDelegate(clientAddress).getClientIf();
+
+        DeviceShadowEnvironmentImpl.runOnService(
+                serverAddress,
+                newServerConnectionStateChangeRunnable(serverIf, false, clientAddress));
+
+        DeviceShadowEnvironmentImpl.runOnService(
+                clientAddress,
+                newClientConnectionStateChangeRunnable(clientIf, false, serverAddress));
+    }
+
+    @Override
+    public void beginServiceDeclaration(
+            int serverIf,
+            int srvcType,
+            int srvcInstId,
+            int minHandles,
+            ParcelUuid srvcId,
+            boolean advertisePreferred) {
+        // TODO(b/200231384): support different service type, instanceId, advertisePreferred.
+        mCurrentService = localGattDelegate().addService(srvcId);
+    }
+
+    @Override
+    public void addIncludedService(int serverIf, int srvcType, int srvcInstId, ParcelUuid srvcId) {
+        // TODO(b/200231384): implement this.
+    }
+
+    @Override
+    public void addCharacteristic(int serverIf, ParcelUuid charId, int properties,
+            int permissions) {
+        mCurrentCharacteristic = mCurrentService.addCharacteristic(charId, properties, permissions);
+    }
+
+    @Override
+    public void addDescriptor(int serverIf, ParcelUuid descId, int permissions) {
+        mCurrentCharacteristic.addDescriptor(descId, permissions);
+    }
+
+    @Override
+    public void endServiceDeclaration(int serverIf) {
+        // TODO(b/200231384): choose correct srvc type and inst id.
+        IBluetoothGattServerCallback callback = localGattDelegate().getServerCallback(serverIf);
+        if (callback != null) {
+            callback.onServiceAdded(
+                    BluetoothGatt.GATT_SUCCESS, 0 /*srvcType*/, 0 /*srvcInstId*/,
+                    mCurrentService.getUuid());
+        }
+        mCurrentService = null;
+    }
+
+    @Override
+    public void removeService(int serverIf, int srvcType, int srvcInstId, ParcelUuid srvcId) {
+        // TODO(b/200231384): implement remove service.
+        // localGattDelegate().removeService(srvcId);
+    }
+
+    @Override
+    public void clearServices(int serverIf) {
+        // TODO(b/200231384): support multiple serverIf.
+        // localGattDelegate().clearService();
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void sendResponse(
+            int serverIf, String clientAddress, int requestId, int status, int offset,
+            byte[] value) {
+        // TODO(b/200231384): implement more operations.
+        String serverAddress = localAddress();
+
+        DeviceShadowEnvironmentImpl.runOnService(
+                clientAddress,
+                NamedRunnable.create(
+                        "ClientGatt.receiveResponse",
+                        () -> {
+                            IBluetoothGattCallback callback =
+                                    localGattDelegate().getClientCallback(
+                                            localGattDelegate().getClientIf());
+                            if (callback != null) {
+                                Request request = localGattDelegate().getLastRequest();
+                                localGattDelegate().setLastRequest(null);
+                                if (request != null) {
+                                    if (request instanceof ReadCharacteristicRequest) {
+                                        callback.onCharacteristicRead(
+                                                serverAddress,
+                                                status,
+                                                request.mSrvcType,
+                                                request.mSrvcInstId,
+                                                request.mSrvcId,
+                                                request.mCharInstId,
+                                                request.mCharId,
+                                                value);
+                                    } else if (request instanceof ReadDescriptorRequest) {
+                                        ReadDescriptorRequest readDescriptorRequest =
+                                                (ReadDescriptorRequest) request;
+                                        callback.onDescriptorRead(
+                                                serverAddress,
+                                                status,
+                                                readDescriptorRequest.mSrvcType,
+                                                readDescriptorRequest.mSrvcInstId,
+                                                readDescriptorRequest.mSrvcId,
+                                                readDescriptorRequest.mCharInstId,
+                                                readDescriptorRequest.mCharId,
+                                                readDescriptorRequest.mDescrInstId,
+                                                readDescriptorRequest.mDescrId,
+                                                value);
+                                    }
+                                }
+                            }
+                        }));
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void sendNotification(
+            final int serverIf,
+            final String address,
+            final int srvcType,
+            final int srvcInstId,
+            final ParcelUuid srvcId,
+            final int charInstId,
+            final ParcelUuid charId,
+            boolean confirm,
+            final byte[] value) {
+        GattDelegate.Characteristic characteristic =
+                localGattDelegate().getService(srvcId).getCharacteristic(charId);
+        characteristic.setValue(value);
+        final String serverAddress = localAddress();
+        for (final String clientAddress : characteristic.getNotifyClients()) {
+            NamedRunnable clientOnNotify =
+                    NamedRunnable.create(
+                            "ClientGatt.onNotify",
+                            () -> {
+                                int clientIf = localGattDelegate().getClientIf();
+                                IBluetoothGattCallback callback =
+                                        localGattDelegate().getClientCallback(clientIf);
+                                if (callback != null) {
+                                    callback.onNotify(
+                                            serverAddress, srvcType, srvcInstId, srvcId, charInstId,
+                                            charId, value);
+                                }
+                            });
+
+            DeviceShadowEnvironmentImpl.runOnService(clientAddress, clientOnNotify);
+        }
+
+        NamedRunnable serverOnNotificationSent =
+                NamedRunnable.create(
+                        "ServerGatt.onNotificationSent",
+                        () -> {
+                            IBluetoothGattServerCallback callback =
+                                    localGattDelegate().getServerCallback(serverIf);
+                            if (callback != null) {
+                                callback.onNotificationSent(address, BluetoothGatt.GATT_SUCCESS);
+                            }
+                        });
+
+        DeviceShadowEnvironmentImpl.runOnService(serverAddress, serverOnNotificationSent);
+    }
+
+    @Override
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void configureMTU(int clientIf, String address, int mtu) {
+        final String clientAddress = localAddress();
+
+        NamedRunnable clientSetMtu =
+                NamedRunnable.create(
+                        "ClientGatt.setMtu",
+                        () -> {
+                            localGattDelegate().clientSetMtu(clientIf, mtu, address);
+                        });
+        NamedRunnable serverSetMtu =
+                NamedRunnable.create(
+                        "ServerGatt.setMtu",
+                        () -> {
+                            int serverIf = localGattDelegate().getServerIf();
+                            localGattDelegate().serverSetMtu(serverIf, mtu, clientAddress);
+                        });
+
+        DeviceShadowEnvironmentImpl.runOnService(clientAddress, clientSetMtu);
+
+        DeviceShadowEnvironmentImpl.runOnService(address, serverSetMtu);
+    }
+
+    @Override
+    public void connectionParameterUpdate(int clientIf, String address, int connectionPriority) {
+        // TODO(b/200231384): Implement.
+    }
+
+    @Override
+    public void disconnectAll() {
+    }
+
+    @Override
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        return new ArrayList<>();
+    }
+
+    @VisibleForTesting
+    static GattDelegate remoteGattDelegate(String address) {
+        return DeviceShadowEnvironmentImpl.getBlueletImpl(address).getGattDelegate();
+    }
+
+    private static GattDelegate localGattDelegate() {
+        return DeviceShadowEnvironmentImpl.getLocalBlueletImpl().getGattDelegate();
+    }
+
+    private static String localAddress() {
+        return DeviceShadowEnvironmentImpl.getLocalBlueletImpl().address;
+    }
+
+    private static NamedRunnable newClientConnectionStateChangeRunnable(
+            final int clientIf, final boolean isConnected, final String serverAddress) {
+        return NamedRunnable.create(
+                "ClientGatt.clientConnectionStateChange",
+                () -> {
+                    localGattDelegate()
+                            .clientConnectionStateChange(
+                                    BluetoothGatt.GATT_SUCCESS, clientIf, isConnected,
+                                    serverAddress);
+                });
+    }
+
+    private static NamedRunnable newServerConnectionStateChangeRunnable(
+            final int serverIf, final boolean isConnected, final String clientAddress) {
+        return NamedRunnable.create(
+                "ServerGatt.serverConnectionStateChange",
+                () -> {
+                    localGattDelegate()
+                            .serverConnectionStateChange(
+                                    BluetoothGatt.GATT_SUCCESS, serverIf, isConnected,
+                                    clientAddress);
+                });
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/IBluetoothImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/IBluetoothImpl.java
new file mode 100644
index 0000000..ccf0ac3
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/IBluetoothImpl.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetooth;
+import android.bluetooth.OobData;
+import android.content.AttributionSource;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelUuid;
+
+import com.android.libraries.testing.deviceshadower.Bluelet.CreateBondOutcome;
+import com.android.libraries.testing.deviceshadower.Bluelet.FetchUuidsTiming;
+import com.android.libraries.testing.deviceshadower.Bluelet.IoCapabilities;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.AdapterDelegate.State;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.BlueletImpl.PairingConfirmation;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import com.google.common.base.Preconditions;
+
+import java.util.Random;
+
+/**
+ * Implementation of IBluetooth interface.
+ */
+public class IBluetoothImpl implements IBluetooth {
+
+    private static final Logger LOGGER = Logger.create("BlueletImpl");
+
+    private enum PairingVariant {
+        JUST_WORKS,
+        /**
+         * AKA Passkey Confirmation.
+         */
+        NUMERIC_COMPARISON,
+        PASSKEY_INPUT,
+        CONSENT
+    }
+
+    /**
+     * User will be prompted to accept or deny the incoming pairing request.
+     */
+    private static final int PAIRING_VARIANT_CONSENT = 3;
+
+    /**
+     * User will be prompted to enter the passkey displayed on remote device. This is used for
+     * Bluetooth 2.1 pairing.
+     */
+    private static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
+
+    public IBluetoothImpl() {
+    }
+
+    @Override
+    public String getAddress() {
+        return localBlueletImpl().address;
+    }
+
+    @Override
+    public String getName() {
+        return localBlueletImpl().mName;
+    }
+
+    @Override
+    public boolean setName(String name) {
+        localBlueletImpl().mName = name;
+        return true;
+    }
+
+    @Override
+    public int getRemoteClass(BluetoothDevice device) {
+        return remoteBlueletImpl(device.getAddress()).getAdapterDelegate().getBluetoothClass();
+    }
+
+    @Override
+    public String getRemoteName(BluetoothDevice device) {
+        return remoteBlueletImpl(device.getAddress()).mName;
+    }
+
+    @Override
+    public int getRemoteType(BluetoothDevice device, AttributionSource attributionSource) {
+        return BluetoothDevice.DEVICE_TYPE_LE;
+    }
+
+    @Override
+    public ParcelUuid[] getRemoteUuids(BluetoothDevice device) {
+        return remoteBlueletImpl(device.getAddress()).mProfileUuids;
+    }
+
+    @Override
+    public boolean fetchRemoteUuids(BluetoothDevice device) {
+        localBlueletImpl().onFetchedUuids(device.getAddress(), getRemoteUuids(device));
+        return true;
+    }
+
+    @Override
+    public int getBondState(BluetoothDevice device, AttributionSource attributionSource) {
+        return localBlueletImpl().getBondState(device.getAddress());
+    }
+
+    @Override
+    public boolean createBond(BluetoothDevice device, int transport, OobData remoteP192Data,
+            OobData remoteP256Data, AttributionSource attributionSource) {
+        setBondState(device.getAddress(), BluetoothDevice.BOND_BONDING, BlueletImpl.REASON_SUCCESS);
+
+        BlueletImpl remoteBluelet = remoteBlueletImpl(device.getAddress());
+        BlueletImpl localBluelet = localBlueletImpl();
+
+        // Like the real Bluetooth stack, choose a pairing variant based on IO Capabilities.
+        // https://blog.bluetooth.com/bluetooth-pairing-part-2-key-generation-methods
+        PairingVariant variant = PairingVariant.JUST_WORKS;
+        if (localBluelet.getIoCapabilities() == IoCapabilities.DISPLAY_YES_NO) {
+            if (remoteBluelet.getIoCapabilities() == IoCapabilities.DISPLAY_YES_NO) {
+                variant = PairingVariant.NUMERIC_COMPARISON;
+            } else if (remoteBluelet.getIoCapabilities() == IoCapabilities.KEYBOARD_ONLY) {
+                variant = PairingVariant.PASSKEY_INPUT;
+            } else if (remoteBluelet.getIoCapabilities() == IoCapabilities.NO_INPUT_NO_OUTPUT
+                    && localBluelet.getEnableCVE20192225()) {
+                // After CVE-2019-2225, Bluetooth decides to ask consent instead of JustWorks.
+                variant = PairingVariant.CONSENT;
+            }
+        }
+
+        // Bonding doesn't complete until the passkey is confirmed on both devices. The passkey is a
+        // positive 6-digit integer, generated by the Bluetooth stack.
+        int passkey = new Random().nextInt(999999) + 1;
+        switch (variant) {
+            case NUMERIC_COMPARISON:
+                localBluelet.onPairingRequest(
+                        remoteBluelet.address, BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION,
+                        passkey);
+                remoteBluelet.onPairingRequest(
+                        localBluelet.address, BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION,
+                        passkey);
+                break;
+            case JUST_WORKS:
+                // Bonding completes immediately, with no PAIRING_REQUEST broadcast.
+                finishBonding(device);
+                break;
+            case PASSKEY_INPUT:
+                localBluelet.onPairingRequest(
+                        remoteBluelet.address, PAIRING_VARIANT_DISPLAY_PASSKEY, passkey);
+                localBluelet.mPassKey = passkey;
+                remoteBluelet.onPairingRequest(
+                        localBluelet.address, PAIRING_VARIANT_DISPLAY_PASSKEY, passkey);
+                break;
+            case CONSENT:
+                localBluelet.onPairingRequest(remoteBluelet.address,
+                        PAIRING_VARIANT_CONSENT, /* key= */ 0);
+                if (remoteBluelet.getIoCapabilities() == IoCapabilities.NO_INPUT_NO_OUTPUT) {
+                    remoteBluelet.setPairingConfirmation(localBluelet.address,
+                            PairingConfirmation.CONFIRMED);
+                } else {
+                    remoteBluelet.onPairingRequest(
+                            localBluelet.address, PAIRING_VARIANT_CONSENT, /* key= */ 0);
+                }
+                break;
+        }
+        return true;
+    }
+
+    private void finishBonding(BluetoothDevice device) {
+        BlueletImpl remoteBluelet = remoteBlueletImpl(device.getAddress());
+        finishBonding(
+                device, remoteBluelet.getCreateBondOutcome(),
+                remoteBluelet.getCreateBondFailureReason());
+    }
+
+    private void finishBonding(BluetoothDevice device, CreateBondOutcome outcome,
+            int failureReason) {
+        switch (outcome) {
+            case SUCCESS:
+                setBondState(device.getAddress(), BluetoothDevice.BOND_BONDED,
+                        BlueletImpl.REASON_SUCCESS);
+                break;
+            case FAILURE:
+                setBondState(device.getAddress(), BluetoothDevice.BOND_NONE, failureReason);
+                break;
+            case TIMEOUT:
+                // Send nothing.
+                break;
+        }
+    }
+
+    @Override
+    public boolean setPairingConfirmation(BluetoothDevice device, boolean confirmed,
+            AttributionSource attributionSource) {
+        localBlueletImpl()
+                .setPairingConfirmation(
+                        device.getAddress(),
+                        confirmed ? PairingConfirmation.CONFIRMED : PairingConfirmation.DENIED);
+
+        PairingConfirmation remoteConfirmation =
+                remoteBlueletImpl(device.getAddress()).getPairingConfirmation(
+                        localBlueletImpl().address);
+        if (confirmed && remoteConfirmation == PairingConfirmation.CONFIRMED) {
+            LOGGER.d(String.format("CONFIRMED"));
+            finishBonding(device);
+        } else if (!confirmed || remoteConfirmation == PairingConfirmation.DENIED) {
+            LOGGER.d(String.format("NOT CONFIRMED"));
+            finishBonding(device, CreateBondOutcome.FAILURE, BlueletImpl.UNBOND_REASON_AUTH_FAILED);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean setPasskey(BluetoothDevice device, int passkey) {
+        BlueletImpl remoteBluelet = remoteBlueletImpl(device.getAddress());
+        if (passkey == remoteBluelet.mPassKey) {
+            finishBonding(device);
+        } else {
+            finishBonding(device, CreateBondOutcome.FAILURE, BlueletImpl.UNBOND_REASON_AUTH_FAILED);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean cancelBondProcess(BluetoothDevice device) {
+        finishBonding(device, CreateBondOutcome.FAILURE, BlueletImpl.UNBOND_REASON_AUTH_CANCELED);
+        return true;
+    }
+
+    @Override
+    public boolean removeBond(BluetoothDevice device) {
+        setBondState(device.getAddress(), BluetoothDevice.BOND_NONE, BlueletImpl.REASON_SUCCESS);
+        return true;
+    }
+
+    @Override
+    public BluetoothDevice[] getBondedDevices() {
+        return localBlueletImpl().getBondedDevices();
+    }
+
+    @Override
+    public int getAdapterConnectionState() {
+        return localBlueletImpl().getAdapterConnectionState();
+    }
+
+    @Override
+    public int getProfileConnectionState(int profile) {
+        return localBlueletImpl().getProfileConnectionState(profile);
+    }
+
+    @Override
+    public int getPhonebookAccessPermission(BluetoothDevice device) {
+        return remoteBlueletImpl(device.getAddress()).mPhonebookAccessPermission;
+    }
+
+    @Override
+    public boolean setPhonebookAccessPermission(BluetoothDevice device, int value) {
+        remoteBlueletImpl(device.getAddress()).mPhonebookAccessPermission = value;
+        return true;
+    }
+
+    @Override
+    public int getMessageAccessPermission(BluetoothDevice device) {
+        return remoteBlueletImpl(device.getAddress()).mMessageAccessPermission;
+    }
+
+    @Override
+    public boolean setMessageAccessPermission(BluetoothDevice device, int value) {
+        remoteBlueletImpl(device.getAddress()).mMessageAccessPermission = value;
+        return true;
+    }
+
+    @Override
+    public int getSimAccessPermission(BluetoothDevice device) {
+        return remoteBlueletImpl(device.getAddress()).mSimAccessPermission;
+    }
+
+    @Override
+    public boolean setSimAccessPermission(BluetoothDevice device, int value) {
+        remoteBlueletImpl(device.getAddress()).mSimAccessPermission = value;
+        return true;
+    }
+
+    private static void setBondState(String remoteAddress, int state, int failureReason) {
+        BlueletImpl remoteBluelet = remoteBlueletImpl(remoteAddress);
+
+        if (remoteBluelet.getFetchUuidsTiming() == FetchUuidsTiming.BEFORE_BONDING) {
+            fetchUuidsOnBondedState(remoteAddress, state);
+        }
+
+        remoteBluelet.setBondState(localBlueletImpl().address, state, failureReason);
+        localBlueletImpl().setBondState(remoteAddress, state, failureReason);
+
+        if (remoteBluelet.getFetchUuidsTiming() == FetchUuidsTiming.AFTER_BONDING) {
+            fetchUuidsOnBondedState(remoteAddress, state);
+        }
+    }
+
+    private static void fetchUuidsOnBondedState(String remoteAddress, int state) {
+        if (state == BluetoothDevice.BOND_BONDED) {
+            remoteBlueletImpl(remoteAddress)
+                    .onFetchedUuids(localBlueletImpl().address, localBlueletImpl().mProfileUuids);
+            localBlueletImpl()
+                    .onFetchedUuids(remoteAddress, remoteBlueletImpl(remoteAddress).mProfileUuids);
+        }
+    }
+
+    @Override
+    public int getScanMode() {
+        return localBlueletImpl().getAdapterDelegate().getScanMode();
+    }
+
+    @Override
+    public boolean setScanMode(int mode, int duration) {
+        localBlueletImpl().getAdapterDelegate().setScanMode(mode);
+        return true;
+    }
+
+    @Override
+    public int getDiscoverableTimeout() {
+        return -1;
+    }
+
+    @Override
+    public boolean setDiscoverableTimeout(int timeout) {
+        return true;
+    }
+
+    @Override
+    public boolean startDiscovery() {
+        localBlueletImpl().getAdapterDelegate().startDiscovery();
+        return true;
+    }
+
+    @Override
+    public boolean cancelDiscovery() {
+        localBlueletImpl().getAdapterDelegate().cancelDiscovery();
+        return true;
+    }
+
+    @Override
+    public boolean isDiscovering() {
+        return localBlueletImpl().getAdapterDelegate().isDiscovering();
+
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return localBlueletImpl().getAdapterDelegate().getState().equals(State.ON);
+    }
+
+    @Override
+    public int getState() {
+        return localBlueletImpl().getAdapterDelegate().getState().getValue();
+    }
+
+    @Override
+    public boolean enable() {
+        localBlueletImpl().enableAdapter();
+        return true;
+    }
+
+    @Override
+    public boolean disable() {
+        localBlueletImpl().disableAdapter();
+        return true;
+    }
+
+    @Override
+    public ParcelFileDescriptor connectSocket(BluetoothDevice device, int type, ParcelUuid uuid,
+            int port, int flag) {
+        Preconditions.checkArgument(
+                port == BluetoothConstants.SOCKET_CHANNEL_CONNECT_WITH_UUID,
+                "Connect to port is not supported.");
+        Preconditions.checkArgument(
+                type == BluetoothConstants.TYPE_RFCOMM,
+                "Only Rfcomm socket is supported.");
+        return localBlueletImpl().getRfcommDelegate()
+                .connectSocket(device.getAddress(), uuid.getUuid());
+    }
+
+    @Override
+    public ParcelFileDescriptor createSocketChannel(int type, String serviceName, ParcelUuid uuid,
+            int port, int flag) {
+        Preconditions.checkArgument(
+                port == BluetoothConstants.SERVER_SOCKET_CHANNEL_AUTO_ASSIGN,
+                "Listen on port is not supported.");
+        Preconditions.checkArgument(
+                type == BluetoothConstants.TYPE_RFCOMM,
+                "Only Rfcomm socket is supported.");
+        return localBlueletImpl().getRfcommDelegate().createSocketChannel(serviceName, uuid);
+    }
+
+    @Override
+    public boolean isMultiAdvertisementSupported() {
+        return maxAdvertiseInstances() > 1;
+    }
+
+    @Override
+    public boolean isPeripheralModeSupported() {
+        return maxAdvertiseInstances() > 0;
+    }
+
+    private int maxAdvertiseInstances() {
+        return localBlueletImpl().getGattDelegate().getMaxAdvertiseInstances();
+    }
+
+    @Override
+    public boolean isOffloadedFilteringSupported() {
+        return localBlueletImpl().getGattDelegate().isOffloadedFilteringSupported();
+    }
+
+    private static BlueletImpl localBlueletImpl() {
+        return DeviceShadowEnvironmentImpl.getLocalBlueletImpl();
+    }
+
+    private static BlueletImpl remoteBlueletImpl(String address) {
+        return DeviceShadowEnvironmentImpl.getBlueletImpl(address);
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/IBluetoothManagerImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/IBluetoothManagerImpl.java
new file mode 100644
index 0000000..cb38a41
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/IBluetoothManagerImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth;
+
+import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothGatt;
+import android.bluetooth.IBluetoothManager;
+import android.bluetooth.IBluetoothManagerCallback;
+
+/**
+ * Implementation of IBluetoothManager interface
+ */
+public class IBluetoothManagerImpl implements IBluetoothManager {
+
+    private final IBluetooth mFakeBluetoothService = new IBluetoothImpl();
+    private final IBluetoothGatt mFakeGattService = new IBluetoothGattImpl();
+
+    @Override
+    public String getAddress() {
+        return mFakeBluetoothService.getAddress();
+    }
+
+    @Override
+    public String getName() {
+        return mFakeBluetoothService.getName();
+    }
+
+    @Override
+    public IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
+        return mFakeBluetoothService;
+    }
+
+    @Override
+    public IBluetoothGatt getBluetoothGatt() {
+        return mFakeGattService;
+    }
+
+    @Override
+    public boolean enable() {
+        mFakeBluetoothService.enable();
+        return true;
+    }
+
+    @Override
+    public boolean disable(boolean persist) {
+        mFakeBluetoothService.disable();
+        return true;
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/FileDescriptorFactory.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/FileDescriptorFactory.java
new file mode 100644
index 0000000..12fa587
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/FileDescriptorFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth.connection;
+
+import java.io.FileDescriptor;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Factory which creates {@link FileDescriptor} given an MAC address. Each MAC address can have many
+ * FileDescriptor but each FileDescriptor only maps to one MAC address.
+ */
+public class FileDescriptorFactory {
+
+    private static FileDescriptorFactory sInstance = null;
+
+    public static synchronized FileDescriptorFactory getInstance() {
+        if (sInstance == null) {
+            sInstance = new FileDescriptorFactory();
+        }
+        return sInstance;
+    }
+
+    public static synchronized void reset() {
+        sInstance = null;
+    }
+
+    private final Map<FileDescriptor, String> mAddressMap;
+
+    private FileDescriptorFactory() {
+        mAddressMap = new ConcurrentHashMap<>();
+    }
+
+    public FileDescriptor createFileDescriptor(String address) {
+        FileDescriptor fd = new FileDescriptor();
+        mAddressMap.put(fd, address);
+        return fd;
+    }
+
+    public String getAddress(FileDescriptor fd) {
+        return mAddressMap.get(fd);
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/PageScanHandler.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/PageScanHandler.java
new file mode 100644
index 0000000..82b97ff
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/PageScanHandler.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth.connection;
+
+import android.os.Build.VERSION;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.internal.utils.MacAddressGenerator;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Encapsulate page scan operations -- handle connection establishment between Bluetooth devices.
+ */
+public class PageScanHandler {
+
+    private static final ConnectionRequest REQUEST_SERVER_SOCKET_CLOSE = new ConnectionRequest();
+
+    private static PageScanHandler sInstance = null;
+
+    public static synchronized PageScanHandler getInstance() {
+        if (sInstance == null) {
+            sInstance = new PageScanHandler();
+        }
+        return sInstance;
+    }
+
+    public static synchronized void reset() {
+        sInstance = null;
+    }
+
+    // use FileDescriptor to identify incoming data before socket is connected.
+    private final Map<FileDescriptor, BlockingQueue<Integer>> mIncomingDataMap;
+    // map a server socket fd to a connection request queue
+    private final Map<FileDescriptor, BlockingQueue<ConnectionRequest>> mConnectionRequests;
+    // map a fd on client side to a fd of BluetoothSocket(not BluetoothServerSocket) on server side
+    private final Map<FileDescriptor, FileDescriptor> mClientServerFdMap;
+    // map a client fd to a connection request so the client socket can finish the pending
+    // connection
+    private final Map<FileDescriptor, ConnectionRequest> mPendingConnections;
+
+    private PageScanHandler() {
+        mIncomingDataMap = new ConcurrentHashMap<>();
+        mConnectionRequests = new ConcurrentHashMap<>();
+        mClientServerFdMap = new ConcurrentHashMap<>();
+        mPendingConnections = new ConcurrentHashMap<>();
+    }
+
+    public void postConnectionRequest(FileDescriptor serverSocketFd, ConnectionRequest request)
+            throws InterruptedException {
+        // used by the returning socket on server-side
+        FileDescriptor fd = FileDescriptorFactory.getInstance()
+                .createFileDescriptor(request.mServerAddress);
+        mClientServerFdMap.put(request.mClientFd, fd);
+        BlockingQueue<ConnectionRequest> requests = mConnectionRequests.get(serverSocketFd);
+        requests.put(request);
+        mPendingConnections.put(request.mClientFd, request);
+    }
+
+    public void addServerSocket(FileDescriptor serverSocketFd) {
+        mConnectionRequests.put(serverSocketFd, new LinkedBlockingQueue<ConnectionRequest>());
+    }
+
+    public FileDescriptor getServerFd(FileDescriptor clientFd) {
+        return mClientServerFdMap.get(clientFd);
+    }
+
+    // TODO(b/79994182): see go/objecttostring-lsc
+    @SuppressWarnings("ObjectToString")
+    public FileDescriptor processNextConnectionRequest(FileDescriptor serverSocketFd)
+            throws IOException, InterruptedException {
+        ConnectionRequest request = mConnectionRequests.get(serverSocketFd).take();
+        if (request == REQUEST_SERVER_SOCKET_CLOSE) {
+            // TODO(b/79994182): FileDescriptor does not implement toString() in serverSocketFd
+            throw new IOException("Server socket is closed. fd: " + serverSocketFd);
+        }
+        writeInitialConnectionInfo(serverSocketFd, request.mClientAddress, request.mPort);
+        return request.mClientFd;
+    }
+
+    public void waitForConnectionEstablished(FileDescriptor clientFd) throws InterruptedException {
+        ConnectionRequest request = mPendingConnections.get(clientFd);
+        if (request != null) {
+            request.mCountDownLatch.await();
+        }
+    }
+
+    public void finishPendingConnection(FileDescriptor clientFd) {
+        ConnectionRequest request = mPendingConnections.get(clientFd);
+        if (request != null) {
+            request.mCountDownLatch.countDown();
+        }
+    }
+
+    public void cancelServerSocket(FileDescriptor serverSocketFd) throws InterruptedException {
+        mConnectionRequests.get(serverSocketFd).put(REQUEST_SERVER_SOCKET_CLOSE);
+    }
+
+    public void writeInitialConnectionInfo(FileDescriptor fd, String address, int port)
+            throws InterruptedException {
+        for (byte b : initialConnectionInfo(address, port)) {
+            write(fd, Integer.valueOf(b));
+        }
+    }
+
+    public void writePort(FileDescriptor fd, int port) throws InterruptedException {
+        byte[] bytes = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(port).array();
+        for (byte b : bytes) {
+            write(fd, Integer.valueOf(b));
+        }
+    }
+
+    public void write(FileDescriptor fd, int data) throws InterruptedException {
+        BlockingQueue<Integer> incomingData = mIncomingDataMap.get(fd);
+        if (incomingData == null) {
+            synchronized (mIncomingDataMap) {
+                incomingData = mIncomingDataMap.get(fd);
+                if (incomingData == null) {
+                    incomingData = new LinkedBlockingQueue<Integer>();
+                    mIncomingDataMap.put(fd, incomingData);
+                }
+            }
+        }
+        incomingData.put(data);
+    }
+
+    public int read(FileDescriptor fd) throws InterruptedException {
+        return mIncomingDataMap.get(fd).take();
+    }
+
+    /**
+     * A connection request from a {@link android.bluetooth.BluetoothSocket}.
+     */
+    @VisibleForTesting
+    public static class ConnectionRequest {
+
+        final FileDescriptor mClientFd;
+        final String mClientAddress;
+        final String mServerAddress;
+        final int mPort;
+        final CountDownLatch mCountDownLatch; // block server socket until connection established
+
+        public ConnectionRequest(FileDescriptor fd, String clientAddress, String serverAddress,
+                int port) {
+            mClientFd = fd;
+            this.mClientAddress = clientAddress;
+            this.mServerAddress = serverAddress;
+            this.mPort = port;
+            mCountDownLatch = new CountDownLatch(1);
+        }
+
+        private ConnectionRequest() {
+            mClientFd = null;
+            mClientAddress = null;
+            mServerAddress = null;
+            mPort = -1;
+            mCountDownLatch = new CountDownLatch(0);
+        }
+    }
+
+    private static byte[] initialConnectionInfo(String addr, int port) {
+        byte[] mac = MacAddressGenerator.convertStringMacAddress(addr);
+        int channel = port;
+        int status = 0;
+
+        if (VERSION.SDK_INT < 23) {
+            byte[] signal = new byte[16];
+            short signalSize = 16;
+            ByteBuffer buffer = ByteBuffer.wrap(signal);
+            buffer.order(ByteOrder.LITTLE_ENDIAN)
+                    .putShort(signalSize)
+                    .put(mac)
+                    .putInt(channel)
+                    .putInt(status);
+            return buffer.array();
+        } else {
+            byte[] signal = new byte[20];
+            short signalSize = 20;
+            short maxTxPacketSize = 10000;
+            short maxRxPacketSize = 10000;
+            ByteBuffer buffer = ByteBuffer.wrap(signal);
+            buffer.order(ByteOrder.LITTLE_ENDIAN)
+                    .putShort(signalSize)
+                    .put(mac)
+                    .putInt(channel)
+                    .putInt(status)
+                    .putShort(maxTxPacketSize)
+                    .putShort(maxRxPacketSize);
+            return buffer.array();
+        }
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/PhysicalLink.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/PhysicalLink.java
new file mode 100644
index 0000000..e474c69
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/PhysicalLink.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth.connection;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import com.google.common.collect.Sets;
+
+import java.io.FileDescriptor;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A class represents a physical link for communications between two Bluetooth devices.
+ */
+public class PhysicalLink {
+
+    // Intended to use RfcommDelegate
+    private static final Logger LOGGER = Logger.create("RfcommDelegate");
+
+    private final Object mLock;
+    // Every socket has unique FileDescriptor, so use it as socket identifier during communication
+    private final Map<FileDescriptor, RfcommSocketConnection> mConnectionLookup;
+    // Map fd of a socket to the fd of the other socket it connects to
+    private final Map<FileDescriptor, FileDescriptor> mFdMap;
+    private final Set<RfcommSocketConnection> mConnections;
+    private final AtomicBoolean mIsEncrypted;
+    private final Map<String, RfcommDelegate.Callback> mCallbacks = new HashMap<>();
+
+    public PhysicalLink(String address1, String address2) {
+        this(address1,
+                DeviceShadowEnvironmentImpl.getBlueletImpl(address1).getRfcommDelegate().mCallback,
+                address2,
+                DeviceShadowEnvironmentImpl.getBlueletImpl(address2).getRfcommDelegate().mCallback,
+                new ConcurrentHashMap<FileDescriptor, RfcommSocketConnection>(),
+                new ConcurrentHashMap<FileDescriptor, FileDescriptor>(),
+                Sets.<RfcommSocketConnection>newConcurrentHashSet());
+    }
+
+    @VisibleForTesting
+    PhysicalLink(String address1, RfcommDelegate.Callback callback1,
+            String address2, RfcommDelegate.Callback callback2,
+            Map<FileDescriptor, RfcommSocketConnection> connectionLookup,
+            Map<FileDescriptor, FileDescriptor> fdMap,
+            Set<RfcommSocketConnection> connections) {
+        mLock = new Object();
+        mCallbacks.put(address1, callback1);
+        mCallbacks.put(address2, callback2);
+        this.mConnectionLookup = connectionLookup;
+        this.mFdMap = fdMap;
+        this.mConnections = connections;
+        mIsEncrypted = new AtomicBoolean(false);
+    }
+
+    public void addConnection(FileDescriptor fd1, FileDescriptor fd2) {
+        synchronized (mLock) {
+            int oldSize = mConnections.size();
+            RfcommSocketConnection connection = new RfcommSocketConnection(
+                    FileDescriptorFactory.getInstance().getAddress(fd1),
+                    FileDescriptorFactory.getInstance().getAddress(fd2)
+            );
+            mConnections.add(connection);
+            mConnectionLookup.put(fd1, connection);
+            mConnectionLookup.put(fd2, connection);
+            mFdMap.put(fd1, fd2);
+            mFdMap.put(fd2, fd1);
+            if (oldSize == 0) {
+                onConnectionStateChange(true);
+            }
+        }
+    }
+
+    // TODO(b/79994182): see go/objecttostring-lsc
+    @SuppressWarnings("ObjectToString")
+    public void closeConnection(FileDescriptor fd) {
+        // check for early return without locking
+        if (!mConnectionLookup.containsKey(fd)) {
+            // TODO(b/79994182): FileDescriptor does not implement toString() in fd
+            LOGGER.d("Connection doesn't exist, FileDescriptor: " + fd);
+            return;
+        }
+        synchronized (mLock) {
+            RfcommSocketConnection connection = mConnectionLookup.get(fd);
+            if (connection == null) {
+                // TODO(b/79994182): FileDescriptor does not implement toString() in fd
+                LOGGER.d("Connection doesn't exist, FileDescriptor: " + fd);
+                return;
+            }
+            int oldSize = mConnections.size();
+            FileDescriptor connectingFd = mFdMap.get(fd);
+            mConnectionLookup.remove(fd);
+            mConnectionLookup.remove(connectingFd);
+            mFdMap.remove(fd);
+            mFdMap.remove(connectingFd);
+            mConnections.remove(connection);
+            if (oldSize == 1) {
+                onConnectionStateChange(false);
+            }
+        }
+    }
+
+    public RfcommSocketConnection getConnection(FileDescriptor fd) {
+        return mConnectionLookup.get(fd);
+    }
+
+    public void encrypt() {
+        mIsEncrypted.set(true);
+    }
+
+    public boolean isEncrypted() {
+        return mIsEncrypted.get();
+    }
+
+    public boolean isConnected() {
+        return !mConnections.isEmpty();
+    }
+
+    private void onConnectionStateChange(boolean isConnected) {
+        for (Entry<String, RfcommDelegate.Callback> entry : mCallbacks.entrySet()) {
+            RfcommDelegate.Callback callback = entry.getValue();
+            String localAddress = entry.getKey();
+            callback.onConnectionStateChange(getRemoteAddress(localAddress), isConnected);
+        }
+    }
+
+    private String getRemoteAddress(String address) {
+        String remoteAddress = null;
+        for (String addr : mCallbacks.keySet()) {
+            if (!addr.equals(address)) {
+                remoteAddress = addr;
+                break;
+            }
+        }
+        return remoteAddress;
+    }
+
+    /**
+     * Represents a Rfcomm socket connection between two {@link android.bluetooth.BluetoothSocket}.
+     */
+    public static class RfcommSocketConnection {
+
+        final Map<String, BlockingQueue<Integer>> mIncomingDataMap; // address : incomingData
+
+        public RfcommSocketConnection(String address1, String address2) {
+            mIncomingDataMap = new ConcurrentHashMap<>();
+            mIncomingDataMap.put(address1, new LinkedBlockingQueue<Integer>());
+            mIncomingDataMap.put(address2, new LinkedBlockingQueue<Integer>());
+        }
+
+        public void write(String address, int b) throws InterruptedException {
+            mIncomingDataMap.get(address).put(b);
+        }
+
+        public int read(String address) throws InterruptedException {
+            return mIncomingDataMap.get(address).take();
+        }
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/RfcommDelegate.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/RfcommDelegate.java
new file mode 100644
index 0000000..3a4fdf6
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/RfcommDelegate.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth.connection;
+
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelUuid;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.BlueletImpl;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.BluetoothConstants;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.connection.PageScanHandler.ConnectionRequest;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.connection.PhysicalLink.RfcommSocketConnection;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.connection.SdpHandler.ServiceRecord;
+import com.android.libraries.testing.deviceshadower.internal.common.Interrupter;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import com.google.errorprone.annotations.FormatMethod;
+
+import org.robolectric.util.ReflectionHelpers;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Delegate for Bluetooth Rfcommon operations, including creating service record, establishing
+ * connection, and data communications.
+ * <p>Socket connection with uuid is supported. Listen on port and connect to port are not
+ * supported.</p>
+ */
+public class RfcommDelegate {
+
+    private static final Logger LOGGER = Logger.create("RfcommDelegate");
+    private static final Object LOCK = new Object();
+
+    /**
+     * Callback for Rfcomm operations
+     */
+    public interface Callback {
+
+        void onConnectionStateChange(String remoteAddress, boolean isConnected);
+    }
+
+    public static void reset() {
+        PageScanHandler.reset();
+        FileDescriptorFactory.reset();
+    }
+
+    final Callback mCallback;
+    private final String mAddress;
+    private final Interrupter mInterrupter;
+    private final SdpHandler mSdpHandler;
+    private final PageScanHandler mPageScanHandler;
+    private final Map<String, PhysicalLink> mConnectionMap; // remoteAddress : physicalLink
+
+    public RfcommDelegate(String address, Callback callback, Interrupter interrupter) {
+        this.mAddress = address;
+        this.mCallback = callback;
+        this.mInterrupter = interrupter;
+        mSdpHandler = new SdpHandler(address);
+        mPageScanHandler = PageScanHandler.getInstance();
+        mConnectionMap = new ConcurrentHashMap<>();
+    }
+
+    @SuppressWarnings("ObjectToString")
+    public ParcelFileDescriptor createSocketChannel(String serviceName, ParcelUuid uuid) {
+        ServiceRecord record = mSdpHandler.createServiceRecord(uuid.getUuid(), serviceName);
+        if (record == null) {
+            LOGGER.e(
+                    String.format("Address %s: failed to create socket channel, uuid: %s", mAddress,
+                            uuid));
+            return null;
+        }
+        try {
+            mPageScanHandler.writePort(record.mServerSocketFd, record.mPort);
+        } catch (InterruptedException e) {
+            LOGGER.e(String.format("Address %s: failed to write port to incoming data, fd: %s",
+                    mAddress,
+                    record.mServerSocketFd), e);
+            return null;
+        }
+        return parcelFileDescriptor(record.mServerSocketFd);
+    }
+
+    @SuppressWarnings("ObjectToString")
+    public ParcelFileDescriptor connectSocket(String remoteAddress, UUID uuid) {
+        BlueletImpl remote = DeviceShadowEnvironmentImpl.getBlueletImpl(remoteAddress);
+        if (remote == null) {
+            LOGGER.e(String.format("Device %s is not defined.", remoteAddress));
+            return null;
+        }
+        ServiceRecord record = remote.getRfcommDelegate().mSdpHandler.lookupChannel(uuid);
+        if (record == null) {
+            LOGGER.e(String.format("Address %s: failed to connect socket, uuid: %s", mAddress,
+                    uuid));
+            return null;
+        }
+        FileDescriptor fd = FileDescriptorFactory.getInstance().createFileDescriptor(mAddress);
+        try {
+            mPageScanHandler.writePort(fd, record.mPort);
+        } catch (InterruptedException e) {
+            LOGGER.e(String.format("Address %s: failed to write port to incoming data, fd: %s",
+                    mAddress,
+                    fd), e);
+            return null;
+        }
+
+        // establish connection
+        try {
+            initiateConnectToServer(fd, record, remoteAddress);
+        } catch (IOException e) {
+            LOGGER.e(
+                    String.format("Address %s: fail to initiate connection to server, clientFd: %s",
+                            mAddress, fd), e);
+            return null;
+        }
+        return parcelFileDescriptor(fd);
+    }
+
+    /**
+     * Creates connection and unblocks server socket.
+     * <p>ShadowBluetoothSocket calls the method at the end of connect().</p>
+     */
+    public void finishPendingConnection(
+            String serverAddress, FileDescriptor clientFd, boolean isEncrypted) {
+        // update states
+        PhysicalLink physicalChannel = mConnectionMap.get(serverAddress);
+        if (physicalChannel == null) {
+            // use class level lock to ensure two RfcommDelegate hold reference to the same Physical
+            // Link
+            synchronized (LOCK) {
+                physicalChannel = mConnectionMap.get(serverAddress);
+                if (physicalChannel == null) {
+                    physicalChannel = new PhysicalLink(
+                            serverAddress,
+                            FileDescriptorFactory.getInstance().getAddress(clientFd));
+                    addPhysicalChannel(serverAddress, physicalChannel);
+                    BlueletImpl remote = DeviceShadowEnvironmentImpl.getBlueletImpl(serverAddress);
+                    remote.getRfcommDelegate().addPhysicalChannel(mAddress, physicalChannel);
+                }
+            }
+        }
+        physicalChannel.addConnection(clientFd, mPageScanHandler.getServerFd(clientFd));
+
+        if (isEncrypted) {
+            physicalChannel.encrypt();
+        }
+        mPageScanHandler.finishPendingConnection(clientFd);
+    }
+
+    /**
+     * Process the next {@link ConnectionRequest} to {@link android.bluetooth.BluetoothServerSocket}
+     * identified by serverSocketFd. This call will block until next connection request is
+     * available.
+     */
+    @SuppressWarnings("ObjectToString")
+    public FileDescriptor processNextConnectionRequest(FileDescriptor serverSocketFd)
+            throws IOException {
+        try {
+            return mPageScanHandler.processNextConnectionRequest(serverSocketFd);
+        } catch (InterruptedException e) {
+            throw new IOException(
+                    logError(e, "failed to process next connection request, serverSocketFd: %s",
+                            serverSocketFd),
+                    e);
+        }
+    }
+
+    /**
+     * Waits for a connection established.
+     * <p>ShadowBluetoothServerSocket calls the method at the end of accept(). Ensure that a
+     * connection is established when accept() returns.</p>
+     */
+    @SuppressWarnings("ObjectToString")
+    public void waitForConnectionEstablished(FileDescriptor clientFd) throws IOException {
+        try {
+            mPageScanHandler.waitForConnectionEstablished(clientFd);
+        } catch (InterruptedException e) {
+            throw new IOException(
+                    logError(e, "failed to wait for connection established. clientFd: %s",
+                            clientFd), e);
+        }
+    }
+
+    @SuppressWarnings("ObjectToString")
+    public void write(String remoteAddress, FileDescriptor localFd, int b)
+            throws IOException {
+        checkInterrupt();
+        RfcommSocketConnection connection =
+                mConnectionMap.get(remoteAddress).getConnection(localFd);
+        if (connection == null) {
+            throw new IOException("closed");
+        }
+        try {
+            connection.write(remoteAddress, b);
+        } catch (InterruptedException e) {
+            throw new IOException(
+                    logError(e, "failed to write to target %s, fd: %s", remoteAddress,
+                            localFd), e);
+        }
+    }
+
+    @SuppressWarnings("ObjectToString")
+    public int read(String remoteAddress, FileDescriptor localFd) throws IOException {
+        checkInterrupt();
+        // remoteAddress is null: 1. server socket, 2. client socket before connected
+        try {
+            if (remoteAddress == null) {
+                return mPageScanHandler.read(localFd);
+            }
+        } catch (InterruptedException e) {
+            throw new IOException(logError(e, "failed to read, fd: %s", localFd), e);
+        }
+
+        RfcommSocketConnection connection =
+                mConnectionMap.get(remoteAddress).getConnection(localFd);
+        if (connection == null) {
+            throw new IOException("closed");
+        }
+        try {
+            return connection.read(mAddress);
+        } catch (InterruptedException e) {
+            throw new IOException(logError(e, "failed to read, fd: %s", localFd), e);
+        }
+    }
+
+    @SuppressWarnings("ObjectToString")
+    public void shutdownInput(String remoteAddress, FileDescriptor localFd)
+            throws IOException {
+        // remoteAddress is null: 1. server socket, 2. client socket before connected
+        try {
+            if (remoteAddress == null) {
+                mPageScanHandler.write(localFd, BluetoothConstants.SOCKET_CLOSE);
+                return;
+            }
+        } catch (InterruptedException e) {
+            throw new IOException(logError(e, "failed to shutdown input. fd: %s", localFd), e);
+        }
+
+        RfcommSocketConnection connection =
+                mConnectionMap.get(remoteAddress).getConnection(localFd);
+        if (connection == null) {
+            LOGGER.d(String.format("Address %s: Connection already closed. fd: %s.", mAddress,
+                    localFd));
+            return;
+        }
+        try {
+            connection.write(mAddress, BluetoothConstants.SOCKET_CLOSE);
+        } catch (InterruptedException e) {
+            throw new IOException(logError(e, "failed to shutdown input. fd: %s", localFd), e);
+        }
+    }
+
+    @SuppressWarnings("ObjectToString")
+    public void shutdownOutput(String remoteAddress, FileDescriptor localFd)
+            throws IOException {
+        RfcommSocketConnection connection =
+                mConnectionMap.get(remoteAddress).getConnection(localFd);
+        if (connection == null) {
+            LOGGER.d(String.format("Address %s: Connection already closed. fd: %s.", mAddress,
+                    localFd));
+            return;
+        }
+        try {
+            connection.write(remoteAddress, BluetoothConstants.SOCKET_CLOSE);
+        } catch (InterruptedException e) {
+            throw new IOException(logError(e, "failed to shutdown output. fd: %s", localFd), e);
+        }
+    }
+
+    @SuppressWarnings("ObjectToString")
+    public void closeServerSocket(FileDescriptor serverSocketFd) throws IOException {
+        // remove service record
+        UUID uuid = mSdpHandler.getUuid(serverSocketFd);
+        mSdpHandler.removeServiceRecord(uuid);
+        // unblock accept()
+        try {
+            mPageScanHandler.cancelServerSocket(serverSocketFd);
+        } catch (InterruptedException e) {
+            throw new IOException(
+                    logError(e, "failed to cancel server socket, serverSocketFd: %s",
+                            serverSocketFd),
+                    e);
+        }
+    }
+
+    public FileDescriptor getServerFd(FileDescriptor clientFd) {
+        return mPageScanHandler.getServerFd(clientFd);
+    }
+
+    @VisibleForTesting
+    public void addPhysicalChannel(String remoteAddress, PhysicalLink channel) {
+        mConnectionMap.put(remoteAddress, channel);
+    }
+
+    @SuppressWarnings("ObjectToString")
+    public void initiateConnectToClient(FileDescriptor clientFd, int port)
+            throws IOException {
+        checkInterrupt();
+        String clientAddress = FileDescriptorFactory.getInstance().getAddress(clientFd);
+        LOGGER.d(String.format("Address %s: init connection to %s, clientFd: %s",
+                mAddress, clientAddress, clientFd));
+        try {
+            mPageScanHandler.writeInitialConnectionInfo(clientFd, mAddress, port);
+        } catch (InterruptedException e) {
+            throw new IOException(
+                    logError(e,
+                            "failed to write initial connection info to %s, clientFd: %s",
+                            clientAddress, clientFd),
+                    e);
+        }
+    }
+
+    @SuppressWarnings("ObjectToString")
+    private void initiateConnectToServer(FileDescriptor clientFd, ServiceRecord serviceRecord,
+            String serverAddress) throws IOException {
+        checkInterrupt();
+        LOGGER.d(
+                String.format("Address %s: init connection to %s, serverSocketFd: %s, clientFd: %s",
+                        mAddress, serverAddress, serviceRecord.mServerSocketFd, clientFd));
+        try {
+            ConnectionRequest request = new ConnectionRequest(clientFd, mAddress, serverAddress,
+                    serviceRecord.mPort);
+            mPageScanHandler.postConnectionRequest(serviceRecord.mServerSocketFd, request);
+        } catch (InterruptedException e) {
+            throw new IOException(
+                    logError(e,
+                            "failed to post connection request, serverSocketFd: %s, "
+                                    + "clientFd: %s",
+                            serviceRecord.mServerSocketFd, clientFd),
+                    e);
+        }
+    }
+
+    public void checkInterrupt() throws IOException {
+        mInterrupter.checkInterrupt();
+    }
+
+    private ParcelFileDescriptor parcelFileDescriptor(FileDescriptor fd) {
+        return ReflectionHelpers.callConstructor(ParcelFileDescriptor.class,
+                ReflectionHelpers.ClassParameter.from(FileDescriptor.class, fd));
+    }
+
+    @FormatMethod
+    private String logError(Exception e, String msgTmpl, Object... args) {
+        String errMsg = String.format("Address %s: ", mAddress) + String.format(msgTmpl, args);
+        LOGGER.e(errMsg, e);
+        return errMsg;
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/SdpHandler.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/SdpHandler.java
new file mode 100644
index 0000000..dbe8651
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/bluetooth/connection/SdpHandler.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.bluetooth.connection;
+
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+
+import java.io.FileDescriptor;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Encapsulates SDP operations including creating service record and allocating channel.
+ * <p>Listen on port and connect on port are not supported. </p>
+ */
+public class SdpHandler {
+
+    // intended to use "RfcommDelegate"
+    private static final Logger LOGGER = Logger.create("RfcommDelegate");
+
+    private final Object mLock;
+    private final String mAddress;
+    private final Map<UUID, ServiceRecord> mServiceRecords;
+    private final Map<FileDescriptor, UUID> mFdUuidMap;
+    private final Set<Integer> mAvailablePortPool;
+    private final Set<Integer> mInUsePortPool;
+
+    public SdpHandler(String address) {
+        mLock = new Object();
+        this.mAddress = address;
+        mServiceRecords = new ConcurrentHashMap<>();
+        mFdUuidMap = new ConcurrentHashMap<>();
+        mAvailablePortPool = Sets.newConcurrentHashSet();
+        mInUsePortPool = Sets.newConcurrentHashSet();
+        // 1 to 30 are valid RFCOMM port
+        for (int i = 1; i <= 30; i++) {
+            mAvailablePortPool.add(i);
+        }
+    }
+
+    public ServiceRecord createServiceRecord(UUID uuid, String serviceName) {
+        Preconditions.checkNotNull(uuid);
+        LOGGER.d(String.format("Address %s: createServiceRecord with uuid %s", mAddress, uuid));
+        if (isUuidRegistered(uuid) || !checkChannelAvailability()) {
+            return null;
+        }
+        synchronized (mLock) {
+            // ensure uuid is not registered and there's available channel
+            if (isUuidRegistered(uuid) || !checkChannelAvailability()) {
+                return null;
+            }
+            Iterator<Integer> available = mAvailablePortPool.iterator();
+            int port = available.next();
+            mAvailablePortPool.remove(port);
+            mInUsePortPool.add(port);
+            ServiceRecord record = new ServiceRecord(mAddress, serviceName, port);
+            mServiceRecords.put(uuid, record);
+            mFdUuidMap.put(record.mServerSocketFd, uuid);
+            PageScanHandler.getInstance().addServerSocket(record.mServerSocketFd);
+            return record;
+        }
+    }
+
+    public void removeServiceRecord(UUID uuid) {
+        Preconditions.checkNotNull(uuid);
+        LOGGER.d(String.format("Address %s: removeServiceRecord with uuid %s", mAddress, uuid));
+        if (!isUuidRegistered(uuid)) {
+            return;
+        }
+        synchronized (mLock) {
+            if (!isUuidRegistered(uuid)) {
+                return;
+            }
+            ServiceRecord record = mServiceRecords.get(uuid);
+            mServiceRecords.remove(uuid);
+            mInUsePortPool.remove(record.mPort);
+            mAvailablePortPool.add(record.mPort);
+            mFdUuidMap.remove(record.mServerSocketFd);
+        }
+    }
+
+    public ServiceRecord lookupChannel(UUID uuid) {
+        ServiceRecord record = mServiceRecords.get(uuid);
+        if (record == null) {
+            LOGGER.e(String.format("Address %s: uuid %s not registered.", mAddress, uuid));
+        }
+        return record;
+    }
+
+    public UUID getUuid(FileDescriptor serverSocketFd) {
+        return mFdUuidMap.get(serverSocketFd);
+    }
+
+    private boolean isUuidRegistered(UUID uuid) {
+        if (mServiceRecords.containsKey(uuid)) {
+            LOGGER.d(String.format("Address %s: Uuid %s in use.", mAddress, uuid));
+            return true;
+        }
+        LOGGER.d(String.format("Address %s: Uuid %s not registered.", mAddress, uuid));
+        return false;
+    }
+
+    private boolean checkChannelAvailability() {
+        if (mAvailablePortPool.isEmpty()) {
+            LOGGER.e(String.format("Address %s: No available channel.", mAddress));
+            return false;
+        }
+        return true;
+    }
+
+    static class ServiceRecord {
+
+        final FileDescriptor mServerSocketFd;
+        final String mServiceName;
+        final int mPort;
+
+        ServiceRecord(String address, String serviceName, int port) {
+            mServerSocketFd = FileDescriptorFactory.getInstance().createFileDescriptor(address);
+            this.mServiceName = serviceName;
+            this.mPort = port;
+        }
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/BroadcastManager.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/BroadcastManager.java
new file mode 100644
index 0000000..0b309ae
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/BroadcastManager.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.common;
+
+import android.content.BroadcastReceiver;
+import android.content.BroadcastReceiver.PendingResult;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build.VERSION;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * Manager for broadcasting of one virtual Device Shadower device.
+ *
+ * <p>Inspired by {@link ShadowApplication} and {@link LocalBroadcastManager}.
+ * <li>Broadcast permission is not supported until manifest is supported.
+ * <li>Send Broadcast is asynchronous.
+ */
+public class BroadcastManager {
+
+    private static final Logger LOGGER = Logger.create("BroadcastManager");
+
+    private static final Comparator<ReceiverRecord> RECEIVER_RECORD_COMPARATOR =
+            new Comparator<ReceiverRecord>() {
+                @Override
+                public int compare(ReceiverRecord o1, ReceiverRecord o2) {
+                    return o2.mIntentFilter.getPriority() - o1.mIntentFilter.getPriority();
+                }
+            };
+
+    private final Scheduler mScheduler;
+    private final Map<String, Intent> mStickyIntents;
+
+    @GuardedBy("mRegisteredReceivers")
+    private final Map<BroadcastReceiver, Set<String>> mRegisteredReceivers;
+
+    @GuardedBy("mRegisteredReceivers")
+    private final Map<String, List<ReceiverRecord>> mActions;
+
+    public BroadcastManager(Scheduler scheduler) {
+        this(
+                scheduler,
+                new HashMap<String, Intent>(),
+                new HashMap<BroadcastReceiver, Set<String>>(),
+                new HashMap<String, List<ReceiverRecord>>());
+    }
+
+    @VisibleForTesting
+    BroadcastManager(
+            Scheduler scheduler,
+            Map<String, Intent> stickyIntents,
+            Map<BroadcastReceiver, Set<String>> registeredReceivers,
+            Map<String, List<ReceiverRecord>> actions) {
+        this.mScheduler = scheduler;
+        this.mStickyIntents = stickyIntents;
+        this.mRegisteredReceivers = registeredReceivers;
+        this.mActions = actions;
+    }
+
+    /**
+     * Registers a {@link BroadcastReceiver} with given {@link Context}.
+     *
+     * @see Context#registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
+     */
+    @Nullable
+    public Intent registerReceiver(
+            @Nullable BroadcastReceiver receiver,
+            IntentFilter filter,
+            @Nullable String broadcastPermission,
+            @Nullable Handler handler,
+            Context context) {
+        // Ignore broadcastPermission before fully supporting manifest
+        Preconditions.checkNotNull(filter);
+        Preconditions.checkNotNull(context);
+        if (receiver != null) {
+            synchronized (mRegisteredReceivers) {
+                ReceiverRecord receiverRecord = new ReceiverRecord(receiver, filter, context,
+                        handler);
+                Set<String> actionSet = mRegisteredReceivers.get(receiver);
+                if (actionSet == null) {
+                    actionSet = new HashSet<>();
+                    mRegisteredReceivers.put(receiver, actionSet);
+                }
+                for (int i = 0; i < filter.countActions(); i++) {
+                    String action = filter.getAction(i);
+                    actionSet.add(action);
+                    List<ReceiverRecord> receiverRecords = mActions.get(action);
+                    if (receiverRecords == null) {
+                        receiverRecords = new ArrayList<>();
+                        mActions.put(action, receiverRecords);
+                    }
+                    receiverRecords.add(receiverRecord);
+                }
+            }
+        }
+        return processStickyIntents(receiver, filter, context);
+    }
+
+    // Broadcast all sticky intents matching the given IntentFilter.
+    @SuppressWarnings("FutureReturnValueIgnored")
+    @Nullable
+    private Intent processStickyIntents(
+            @Nullable final BroadcastReceiver receiver,
+            IntentFilter intentFilter,
+            final Context context) {
+        Intent result = null;
+        final List<Intent> matchedIntents = new ArrayList<>();
+        for (Intent intent : mStickyIntents.values()) {
+            if (match(intentFilter, intent)) {
+                if (result == null) {
+                    result = intent;
+                }
+                if (receiver == null) {
+                    return result;
+                }
+                matchedIntents.add(intent);
+            }
+        }
+        if (!matchedIntents.isEmpty()) {
+            mScheduler.post(
+                    NamedRunnable.create(
+                            "Broadcast.processStickyIntents",
+                            () -> {
+                                for (Intent intent : matchedIntents) {
+                                    receiver.onReceive(context, intent);
+                                }
+                            }));
+        }
+        return result;
+    }
+
+    /**
+     * Unregisters a {@link BroadcastReceiver}.
+     *
+     * @see Context#unregisterReceiver(BroadcastReceiver)
+     */
+    public void unregisterReceiver(BroadcastReceiver broadcastReceiver) {
+        synchronized (mRegisteredReceivers) {
+            if (!mRegisteredReceivers.containsKey(broadcastReceiver)) {
+                LOGGER.w("Receiver not registered: " + broadcastReceiver);
+                return;
+            }
+            Set<String> actionSet = mRegisteredReceivers.remove(broadcastReceiver);
+            for (String action : actionSet) {
+                List<ReceiverRecord> receiverRecords = mActions.get(action);
+                Iterator<ReceiverRecord> iterator = receiverRecords.iterator();
+                while (iterator.hasNext()) {
+                    if (iterator.next().mBroadcastReceiver == broadcastReceiver) {
+                        iterator.remove();
+                    }
+                }
+                if (receiverRecords.isEmpty()) {
+                    mActions.remove(action);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sends sticky broadcast with given {@link Intent}. This call is asynchronous.
+     *
+     * @see Context#sendStickyBroadcast(Intent)
+     */
+    public void sendStickyBroadcast(Intent intent) {
+        mStickyIntents.put(intent.getAction(), intent);
+        sendBroadcast(intent, null /* broadcastPermission */);
+    }
+
+    /**
+     * Sends broadcast with given {@link Intent}. Receiver permission is not supported. This call is
+     * asynchronous.
+     *
+     * @see Context#sendBroadcast(Intent, String)
+     */
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void sendBroadcast(final Intent intent, @Nullable String receiverPermission) {
+        // Ignore permission matching before fully supporting manifest
+        final List<ReceiverRecord> receivers =
+                getMatchingReceivers(intent, false /* isOrdered */);
+        if (receivers.isEmpty()) {
+            return;
+        }
+        mScheduler.post(
+                NamedRunnable.create(
+                        "Broadcast.sendBroadcast",
+                        () -> {
+                            for (ReceiverRecord receiverRecord : receivers) {
+                                // Hacky: Call the shadow method, otherwise abort() NPEs after
+                                // calling onReceive().
+                                // TODO(b/200231384): Sending these, via context.sendBroadcast(),
+                                //  won't NPE...but it may not be possible on each simulated
+                                //  "device"'s main thread. Check if possible.
+                                BroadcastReceiver broadcastReceiver =
+                                        receiverRecord.mBroadcastReceiver;
+                                Shadows.shadowOf(broadcastReceiver)
+                                        .onReceive(receiverRecord.mContext, intent, /*abort=*/
+                                                new AtomicBoolean(false));
+                            }
+                        }));
+    }
+
+    /**
+     * Sends ordered broadcast with given {@link Intent}. Receiver permission is not supported. This
+     * call is asynchronous.
+     *
+     * @see Context#sendOrderedBroadcast(Intent, String)
+     */
+    public void sendOrderedBroadcast(Intent intent, @Nullable String receiverPermission) {
+        sendOrderedBroadcast(
+                intent,
+                receiverPermission,
+                null /* resultReceiver */,
+                null /* handler */,
+                0 /* initialCode */,
+                null /* initialData */,
+                null /* initialExtras */,
+                null /* context */);
+    }
+
+    /**
+     * Sends ordered broadcast with given {@link Intent} and result {@link BroadcastReceiver}.
+     * Receiver permission is not supported. This call is asynchronous.
+     *
+     * @see Context#sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String,
+     * Bundle)
+     */
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void sendOrderedBroadcast(
+            final Intent intent,
+            @Nullable String receiverPermission,
+            @Nullable BroadcastReceiver resultReceiver,
+            @Nullable Handler handler,
+            int initialCode,
+            @Nullable String initialData,
+            @Nullable Bundle initialExtras,
+            @Nullable Context context) {
+        // Ignore permission matching before fully supporting manifest
+        final List<ReceiverRecord> receivers =
+                getMatchingReceivers(intent, true /* isOrdered */);
+        if (receivers.isEmpty()) {
+            return;
+        }
+        if (resultReceiver != null) {
+            receivers.add(
+                    new ReceiverRecord(
+                            resultReceiver, null /* intentFilter */, context, handler));
+        }
+        mScheduler.post(
+                NamedRunnable.create(
+                        "Broadcast.sendOrderedBroadcast",
+                        () -> {
+                            postOrderedIntent(
+                                    receivers,
+                                    intent,
+                                    0 /* initialCode */,
+                                    null /* initialData */,
+                                    null /* initialExtras */);
+                        }));
+    }
+
+    @VisibleForTesting
+    void postOrderedIntent(
+            List<ReceiverRecord> receivers,
+            final Intent intent,
+            int initialCode,
+            @Nullable String initialData,
+            @Nullable Bundle initialExtras) {
+        final AtomicBoolean abort = new AtomicBoolean(false);
+        ListenableFuture<BroadcastResult> resultFuture =
+                Futures.immediateFuture(
+                        new BroadcastResult(initialCode, initialData, initialExtras));
+
+        for (ReceiverRecord receiverRecord : receivers) {
+            final BroadcastReceiver receiver = receiverRecord.mBroadcastReceiver;
+            final Context context = receiverRecord.mContext;
+            resultFuture =
+                    Futures.transformAsync(
+                            resultFuture,
+                            new AsyncFunction<BroadcastResult, BroadcastResult>() {
+                                @Override
+                                public ListenableFuture<BroadcastResult> apply(
+                                        BroadcastResult input) {
+                                    PendingResult result = newPendingResult(
+                                            input.mCode, input.mData, input.mExtras,
+                                            true /* isOrdered */);
+                                    ReflectionHelpers.callInstanceMethod(
+                                            receiver, "setPendingResult",
+                                            ClassParameter.from(PendingResult.class, result));
+                                    Shadows.shadowOf(receiver).onReceive(context, intent, abort);
+                                    return BroadcastResult.transform(result);
+                                }
+                            },
+                            MoreExecutors.directExecutor());
+        }
+        Futures.addCallback(
+                resultFuture,
+                new FutureCallback<BroadcastResult>() {
+                    @Override
+                    public void onSuccess(BroadcastResult result) {
+                        return;
+                    }
+
+                    @Override
+                    public void onFailure(Throwable t) {
+                        throw new RuntimeException(t);
+                    }
+                },
+                MoreExecutors.directExecutor());
+    }
+
+    private List<ReceiverRecord> getMatchingReceivers(Intent intent, boolean isOrdered) {
+        synchronized (mRegisteredReceivers) {
+            List<ReceiverRecord> result = new ArrayList<>();
+            if (!mActions.containsKey(intent.getAction())) {
+                return result;
+            }
+            Iterator<ReceiverRecord> iterator = mActions.get(intent.getAction()).iterator();
+            while (iterator.hasNext()) {
+                ReceiverRecord next = iterator.next();
+                if (match(next.mIntentFilter, intent)) {
+                    result.add(next);
+                }
+            }
+            if (isOrdered) {
+                Collections.sort(result, RECEIVER_RECORD_COMPARATOR);
+            }
+            return result;
+        }
+    }
+
+    private boolean match(IntentFilter intentFilter, Intent intent) {
+        // Action test
+        if (!intentFilter.matchAction(intent.getAction())) {
+            return false;
+        }
+        // Category test
+        if (intentFilter.matchCategories(intent.getCategories()) != null) {
+            return false;
+        }
+        // Data test
+        int matchResult =
+                intentFilter.matchData(intent.getType(), intent.getScheme(), intent.getData());
+        return matchResult != IntentFilter.NO_MATCH_TYPE
+                && matchResult != IntentFilter.NO_MATCH_DATA;
+    }
+
+    private static PendingResult newPendingResult(
+            int resultCode, String resultData, Bundle resultExtras, boolean isOrdered) {
+        ClassParameter<?>[] parameters;
+        // PendingResult constructor takes different parameters in different SDK levels.
+        if (VERSION.SDK_INT < 17) {
+            parameters =
+                    ClassParameter.fromComponentLists(
+                            new Class<?>[]{
+                                    int.class,
+                                    String.class,
+                                    Bundle.class,
+                                    int.class,
+                                    boolean.class,
+                                    boolean.class,
+                                    IBinder.class
+                            },
+                            new Object[]{
+                                    resultCode,
+                                    resultData,
+                                    resultExtras,
+                                    0 /* type */,
+                                    isOrdered,
+                                    false /* sticky */,
+                                    null /* IBinder */
+                            });
+        } else if (VERSION.SDK_INT < 23) {
+            parameters =
+                    ClassParameter.fromComponentLists(
+                            new Class<?>[]{
+                                    int.class,
+                                    String.class,
+                                    Bundle.class,
+                                    int.class,
+                                    boolean.class,
+                                    boolean.class,
+                                    IBinder.class,
+                                    int.class
+                            },
+                            new Object[]{
+                                    resultCode,
+                                    resultData,
+                                    resultExtras,
+                                    0 /* type */,
+                                    isOrdered,
+                                    false /* sticky */,
+                                    null /* IBinder */,
+                                    0 /* userId */
+                            });
+        } else {
+            parameters =
+                    ClassParameter.fromComponentLists(
+                            new Class<?>[]{
+                                    int.class,
+                                    String.class,
+                                    Bundle.class,
+                                    int.class,
+                                    boolean.class,
+                                    boolean.class,
+                                    IBinder.class,
+                                    int.class,
+                                    int.class
+                            },
+                            new Object[]{
+                                    resultCode,
+                                    resultData,
+                                    resultExtras,
+                                    0 /* type */,
+                                    isOrdered,
+                                    false /* sticky */,
+                                    null /* IBinder */,
+                                    0 /* userId */,
+                                    0 /* flags */
+                            });
+        }
+        return ReflectionHelpers.callConstructor(PendingResult.class, parameters);
+    }
+
+    /**
+     * Holder of broadcast result from previous receiver.
+     */
+    private static final class BroadcastResult {
+
+        private final int mCode;
+        private final String mData;
+        private final Bundle mExtras;
+
+        BroadcastResult(int code, String data, Bundle extras) {
+            this.mCode = code;
+            this.mData = data;
+            this.mExtras = extras;
+        }
+
+        private static ListenableFuture<BroadcastResult> transform(PendingResult result) {
+            return Futures.transform(
+                    Shadows.shadowOf(result).getFuture(),
+                    new Function<PendingResult, BroadcastResult>() {
+                        @Override
+                        public BroadcastResult apply(PendingResult input) {
+                            return new BroadcastResult(
+                                    input.getResultCode(), input.getResultData(),
+                                    input.getResultExtras(false));
+                        }
+                    },
+                    MoreExecutors.directExecutor());
+        }
+    }
+
+    /**
+     * Information of a registered BroadcastReceiver.
+     */
+    @VisibleForTesting
+    static final class ReceiverRecord {
+
+        final BroadcastReceiver mBroadcastReceiver;
+        final IntentFilter mIntentFilter;
+        final Context mContext;
+        final Handler mHandler;
+
+        @VisibleForTesting
+        ReceiverRecord(
+                BroadcastReceiver broadcastReceiver,
+                IntentFilter intentFilter,
+                Context context,
+                Handler handler) {
+            this.mBroadcastReceiver = broadcastReceiver;
+            this.mIntentFilter = intentFilter;
+            this.mContext = context;
+            this.mHandler = handler;
+        }
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/ContentDatabase.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/ContentDatabase.java
new file mode 100644
index 0000000..1f4d778
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/ContentDatabase.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.common;
+
+import android.database.Cursor;
+
+import org.robolectric.fakes.RoboCursor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Simulate Sqlite database for Android content provider.
+ */
+public class ContentDatabase {
+
+    private final List<String> mColumnNames;
+    private final List<List<Object>> mData;
+
+    public ContentDatabase(String... names) {
+        mColumnNames = Arrays.asList(names);
+        mData = new ArrayList<>();
+    }
+
+    public void addData(Object... items) {
+        mData.add(Arrays.asList(items));
+    }
+
+    public Cursor getCursor() {
+        RoboCursor cursor = new RoboCursor();
+        cursor.setColumnNames(mColumnNames);
+        Object[][] dataArr = new Object[mData.size()][mColumnNames.size()];
+        for (int i = 0; i < mData.size(); i++) {
+            dataArr[i] = new Object[mColumnNames.size()];
+            mData.get(i).toArray(dataArr[i]);
+        }
+        cursor.setResults(dataArr);
+        return cursor;
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/Interrupter.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/Interrupter.java
new file mode 100644
index 0000000..66e9cb0
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/Interrupter.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.common;
+
+import com.android.libraries.testing.deviceshadower.Enums;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Interrupter sets and checks interruptible point, and interrupt operation by throwing
+ * IOException.
+ */
+public class Interrupter {
+
+    private final InheritableThreadLocal<Integer> mCurrentIdentifier;
+    private int mInterruptIdentifier;
+
+    private final Set<Enums.Operation> mInterruptOperations = new HashSet<>();
+
+    public Interrupter() {
+        mCurrentIdentifier = new InheritableThreadLocal<Integer>() {
+            @Override
+            protected Integer initialValue() {
+                return -1;
+            }
+        };
+    }
+
+    public void checkInterrupt() throws IOException {
+        if (mCurrentIdentifier.get() == mInterruptIdentifier) {
+            throw new IOException(
+                    "Bluetooth interrupted at identifier: " + mCurrentIdentifier.get());
+        }
+    }
+
+    public void setInterruptible(int identifier) {
+        mCurrentIdentifier.set(identifier);
+    }
+
+    public void interrupt(int identifier) {
+        mInterruptIdentifier = identifier;
+    }
+
+    public void addInterruptOperation(Enums.Operation operation) {
+        mInterruptOperations.add(operation);
+    }
+
+    public boolean shouldInterrupt(Enums.Operation operation) {
+        return mInterruptOperations.contains(operation);
+    }
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/NamedRunnable.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/NamedRunnable.java
new file mode 100644
index 0000000..4e84d71
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/NamedRunnable.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.common;
+
+/**
+ * Runnable with a name defined.
+ */
+public abstract class NamedRunnable implements Runnable {
+
+    private final String mName;
+
+    private NamedRunnable(String name) {
+        this.mName = name;
+    }
+
+    public static NamedRunnable create(String name, Runnable runnable) {
+        return new NamedRunnable(name) {
+            @Override
+            public void run() {
+                runnable.run();
+            }
+        };
+    }
+
+    @Override
+    public String toString() {
+        return mName;
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/Scheduler.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/Scheduler.java
new file mode 100644
index 0000000..96e9b15
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/common/Scheduler.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.common;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * Scheduler to post runnables to a single thread.
+ */
+public class Scheduler {
+
+    private static final Logger LOGGER = Logger.create("Scheduler");
+
+    @GuardedBy("Scheduler.class")
+    private static int sTotalRunnables = 0;
+
+    private static CountDownLatch sCompleteLatch;
+
+    public Scheduler() {
+        this(null);
+    }
+
+    public Scheduler(String name) {
+        mExecutor =
+                Executors.newSingleThreadExecutor(
+                        r -> {
+                            Thread thread = Executors.defaultThreadFactory().newThread(r);
+                            if (name != null) {
+                                thread.setName(name);
+                            }
+                            return thread;
+                        });
+    }
+
+    public static boolean await(long timeoutMillis) throws InterruptedException {
+
+        synchronized (Scheduler.class) {
+            if (isComplete()) {
+                return true;
+            }
+            if (sCompleteLatch == null) {
+                sCompleteLatch = new CountDownLatch(1);
+            }
+        }
+
+        // TODO(b/200231384): solve potential NPE caused by race condition.
+        boolean result = sCompleteLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
+        synchronized (Scheduler.class) {
+            sCompleteLatch = null;
+        }
+        return result;
+    }
+
+    private final ExecutorService mExecutor;
+
+    @GuardedBy("this")
+    private final List<ScheduledRunnable> mRunnables = new ArrayList<>();
+
+    @GuardedBy("this")
+    private long mCurrentTimeMillis = 0;
+
+    @GuardedBy("this")
+    private List<ScheduledRunnable> mRunningRunnables = new ArrayList<>();
+
+    /**
+     * Post a {@link NamedRunnable} to scheduler.
+     *
+     * <p>Return value can be ignored because exception will be handled by {@link
+     * DeviceShadowEnvironmentImpl#catchInternalException}.
+     */
+    // @CanIgnoreReturnValue
+    public synchronized Future<?> post(NamedRunnable r) {
+        synchronized (Scheduler.class) {
+            sTotalRunnables++;
+        }
+        advance(0);
+        return mExecutor.submit(new ScheduledRunnable(r, mCurrentTimeMillis).mRunnable);
+    }
+
+    public synchronized void post(NamedRunnable r, long delayMillis) {
+        synchronized (Scheduler.class) {
+            sTotalRunnables++;
+        }
+        addRunnables(new ScheduledRunnable(r, mCurrentTimeMillis + delayMillis));
+        advance(0);
+    }
+
+    public synchronized void shutdown() {
+        mExecutor.shutdown();
+    }
+
+    @VisibleForTesting
+    synchronized void advance(long durationMillis) {
+        mCurrentTimeMillis += durationMillis;
+        while (mRunnables.size() > 0) {
+            ScheduledRunnable r = mRunnables.get(0);
+            if (r.mTimeMillis <= mCurrentTimeMillis) {
+                mRunnables.remove(0);
+                mExecutor.execute(r.mRunnable);
+            } else {
+                break;
+            }
+        }
+    }
+
+    private synchronized void addRunnables(ScheduledRunnable r) {
+        int index = 0;
+        while (index < mRunnables.size() && mRunnables.get(index).mTimeMillis <= r.mTimeMillis) {
+            index++;
+        }
+        mRunnables.add(index, r);
+    }
+
+    @VisibleForTesting
+    static synchronized boolean isComplete() {
+        return sTotalRunnables == 0;
+    }
+
+    // Can only be called by DeviceShadowEnvironmentImpl when reset.
+    public static synchronized void clear() {
+        sTotalRunnables = 0;
+    }
+
+    class ScheduledRunnable {
+
+        final NamedRunnable mRunnable;
+        final long mTimeMillis;
+
+        ScheduledRunnable(final NamedRunnable r, long timeMillis) {
+            this.mTimeMillis = timeMillis;
+            this.mRunnable =
+                    NamedRunnable.create(
+                            r.toString(),
+                            () -> {
+                                synchronized (Scheduler.this) {
+                                    Scheduler.this.mRunningRunnables.add(ScheduledRunnable.this);
+                                }
+
+                                try {
+                                    r.run();
+                                } catch (Exception e) {
+                                    LOGGER.e("Error in scheduler runnable " + r, e);
+                                    DeviceShadowEnvironmentImpl.catchInternalException(e);
+                                }
+
+                                synchronized (Scheduler.this) {
+                                    // Remove the last one.
+                                    Scheduler.this.mRunningRunnables.remove(
+                                            Scheduler.this.mRunningRunnables.size() - 1);
+                                }
+
+                                // If this is last runnable,
+                                // When this section runs before await:
+                                //   totalRunnable will be 0, await will return directly.
+                                // When this section runs after await:
+                                //   latch will not be null, count down will terminate await.
+
+                                // TODO(b/200231384): when there are two threads running at same
+                                // time, there will be a case when totalRunnable is 0, but another
+                                // thread pending to acquire Scheduler.class lock to post a
+                                // runnable. Hence, await here might not be correct in this case.
+                                synchronized (Scheduler.class) {
+                                    sTotalRunnables--;
+                                    if (isComplete()) {
+                                        if (sCompleteLatch != null) {
+                                            sCompleteLatch.countDown();
+                                        }
+                                    }
+                                }
+                            });
+        }
+
+        @Override
+        public String toString() {
+            return mRunnable.toString();
+        }
+    }
+
+    @Override
+    public synchronized String toString() {
+        return String.format(
+                "\t%d scheduled runnables %s\n\t%d still running or aborted %s",
+                mRunnables.size(), mRunnables, mRunningRunnables.size(), mRunningRunnables);
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/nfc/INfcAdapterImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/nfc/INfcAdapterImpl.java
new file mode 100644
index 0000000..01dcac2
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/nfc/INfcAdapterImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.nfc;
+
+import android.nfc.IAppCallback;
+import android.nfc.INfcAdapter;
+
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+
+/**
+ * Implementation of INfcAdapter
+ */
+public class INfcAdapterImpl implements INfcAdapter {
+
+    public INfcAdapterImpl() {
+    }
+
+    @Override
+    public void setAppCallback(IAppCallback callback) {
+        DeviceShadowEnvironmentImpl.getLocalNfcletImpl().mAppCallback = callback;
+    }
+
+    @Override
+    public boolean enable() {
+        return DeviceShadowEnvironmentImpl.getLocalNfcletImpl().enable();
+    }
+
+    @Override
+    public boolean disable(boolean saveState) {
+        // We do not need to save state because test only run once.
+        return DeviceShadowEnvironmentImpl.getLocalNfcletImpl().disable();
+    }
+
+    @Override
+    public int getState() {
+        return DeviceShadowEnvironmentImpl.getLocalNfcletImpl().getState();
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/nfc/NfcletImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/nfc/NfcletImpl.java
new file mode 100644
index 0000000..137f6b8
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/nfc/NfcletImpl.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.nfc;
+
+import android.content.Intent;
+import android.nfc.BeamShareData;
+import android.nfc.IAppCallback;
+import android.nfc.NdefMessage;
+import android.nfc.NfcAdapter;
+
+import com.android.libraries.testing.deviceshadower.Enums.NfcOperation;
+import com.android.libraries.testing.deviceshadower.Nfclet;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.common.Interrupter;
+import com.android.libraries.testing.deviceshadower.internal.utils.Logger;
+
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * Implementation of Nfclet.
+ */
+public class NfcletImpl implements Nfclet {
+
+    private static final Logger LOGGER = Logger.create("NfcletImpl");
+
+    IAppCallback mAppCallback;
+    private final Interrupter mInterrupter;
+
+    @GuardedBy("this")
+    private int mCurrentState;
+
+    public NfcletImpl() {
+        mInterrupter = new Interrupter();
+        mCurrentState = NfcAdapter.STATE_OFF;
+    }
+
+    public void onNear(NfcletImpl remote) {
+        if (remote.mAppCallback != null) {
+            LOGGER.v("NFC receiver get beam share data from remote");
+            BeamShareData data = remote.mAppCallback.createBeamShareData();
+            DeviceShadowEnvironmentImpl.getLocalDeviceletImpl().getBroadcastManager()
+                    .sendBroadcast(createNdefDiscoveredIntent(data), null);
+        }
+        if (mAppCallback != null) {
+            LOGGER.v("NFC sender onNdefPushComplete");
+            mAppCallback.onNdefPushComplete();
+        }
+    }
+
+    public synchronized int getState() {
+        return mCurrentState;
+    }
+
+    public boolean enable() {
+        if (shouldInterrupt(NfcOperation.ENABLE)) {
+            return false;
+        }
+        LOGGER.v("Enable NFC Adapter");
+        updateState(NfcAdapter.STATE_TURNING_ON);
+        updateState(NfcAdapter.STATE_ON);
+        return true;
+    }
+
+    public boolean disable() {
+        if (shouldInterrupt(NfcOperation.DISABLE)) {
+            return false;
+        }
+        LOGGER.v("Disable NFC Adapter");
+        updateState(NfcAdapter.STATE_TURNING_OFF);
+        updateState(NfcAdapter.STATE_OFF);
+        return true;
+    }
+
+    @Override
+    public synchronized Nfclet setInitialState(int state) {
+        mCurrentState = state;
+        return this;
+    }
+
+    @Override
+    public Nfclet setInterruptOperation(NfcOperation operation) {
+        mInterrupter.addInterruptOperation(operation);
+        return this;
+    }
+
+    public boolean shouldInterrupt(NfcOperation operation) {
+        return mInterrupter.shouldInterrupt(operation);
+    }
+
+    private synchronized void updateState(int state) {
+        if (mCurrentState != state) {
+            mCurrentState = state;
+            DeviceShadowEnvironmentImpl.getLocalDeviceletImpl().getBroadcastManager()
+                    .sendBroadcast(createAdapterStateChangedIntent(state), null);
+        }
+    }
+
+    private Intent createAdapterStateChangedIntent(int state) {
+        Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
+        intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, state);
+        return intent;
+    }
+
+    private Intent createNdefDiscoveredIntent(BeamShareData data) {
+        Intent intent = new Intent();
+        intent.setAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
+        intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, new NdefMessage[]{data.ndefMessage});
+        // TODO(b/200231384): uncomment when uri and mime type implemented.
+        // ndefUri = message.getRecords()[0].toUri();
+        // ndefMimeType = message.getRecords()[0].toMimeType();
+        return intent;
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/sms/SmsContentProvider.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/sms/SmsContentProvider.java
new file mode 100644
index 0000000..6bc535b
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/sms/SmsContentProvider.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.sms;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+
+/**
+ * Content provider for SMS query.
+ */
+public class SmsContentProvider extends ContentProvider {
+
+    public SmsContentProvider() {
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    @Override
+    public Cursor query(
+            Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return DeviceShadowEnvironmentImpl.getLocalSmsletImpl().getCursor(uri);
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/sms/SmsletImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/sms/SmsletImpl.java
new file mode 100644
index 0000000..00a581e
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/sms/SmsletImpl.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.sms;
+
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.Telephony;
+
+import com.android.libraries.testing.deviceshadower.Smslet;
+import com.android.libraries.testing.deviceshadower.internal.common.ContentDatabase;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implementation of SMS functionality.
+ */
+public class SmsletImpl implements Smslet {
+
+    private final Map<Uri, ContentDatabase> mUriToDataMap;
+
+    public SmsletImpl() {
+        mUriToDataMap = new HashMap<>();
+        mUriToDataMap.put(
+                Telephony.Sms.Inbox.CONTENT_URI, new ContentDatabase(Telephony.Sms.Inbox.BODY));
+        mUriToDataMap.put(Telephony.Sms.Sent.CONTENT_URI,
+                new ContentDatabase(Telephony.Sms.Inbox.BODY));
+        // TODO(b/200231384): implement Outbox, Intents, Conversations.
+    }
+
+    @Override
+    public Smslet addSms(Uri contentUri, String body) {
+        mUriToDataMap.get(contentUri).addData(body);
+        return this;
+    }
+
+    public Cursor getCursor(Uri uri) {
+        return mUriToDataMap.get(uri).getCursor();
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/utils/GattHelper.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/utils/GattHelper.java
new file mode 100644
index 0000000..f45b125
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/utils/GattHelper.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.utils;
+
+import android.bluetooth.le.AdvertiseData;
+import android.os.ParcelUuid;
+import android.util.SparseArray;
+
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.BluetoothConstants;
+
+import com.google.common.io.ByteArrayDataOutput;
+import com.google.common.io.ByteStreams;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+/**
+ * Helper class for Gatt functionality.
+ */
+public class GattHelper {
+
+    public static byte[] convertAdvertiseData(
+            AdvertiseData data, int txPowerLevel, String localName, boolean isConnectable) {
+        if (data == null) {
+            return new byte[0];
+        }
+        ByteArrayDataOutput result = ByteStreams.newDataOutput();
+        if (isConnectable) {
+            writeDataUnit(
+                    result,
+                    BluetoothConstants.DATA_TYPE_FLAGS,
+                    new byte[]{BluetoothConstants.FLAGS_IN_CONNECTABLE_PACKETS});
+        }
+        // tx power level is signed 8-bit int, range -100 to 20.
+        if (data.getIncludeTxPowerLevel()) {
+            writeDataUnit(
+                    result,
+                    BluetoothConstants.DATA_TYPE_TX_POWER_LEVEL,
+                    new byte[]{(byte) txPowerLevel});
+        }
+        // Local name
+        if (data.getIncludeDeviceName()) {
+            writeDataUnit(
+                    result,
+                    BluetoothConstants.DATA_TYPE_LOCAL_NAME_COMPLETE,
+                    localName.getBytes(Charset.defaultCharset()));
+        }
+        // Manufacturer data
+        SparseArray<byte[]> manufacturerData = data.getManufacturerSpecificData();
+        for (int i = 0; i < manufacturerData.size(); i++) {
+            int manufacturerId = manufacturerData.keyAt(i);
+            writeDataUnit(
+                    result,
+                    BluetoothConstants.DATA_TYPE_MANUFACTURER_SPECIFIC_DATA,
+                    parseManufacturerData(manufacturerId, manufacturerData.get(manufacturerId))
+            );
+        }
+        // Service data
+        Map<ParcelUuid, byte[]> serviceData = data.getServiceData();
+        for (Entry<ParcelUuid, byte[]> entry : serviceData.entrySet()) {
+            writeDataUnit(
+                    result,
+                    BluetoothConstants.DATA_TYPE_SERVICE_DATA,
+                    parseServiceData(entry.getKey().getUuid(), entry.getValue())
+            );
+        }
+        // Service UUID, 128-bit UUID in little endian
+        if (data.getServiceUuids() != null && !data.getServiceUuids().isEmpty()) {
+            ByteBuffer uuidBytes =
+                    ByteBuffer.allocate(data.getServiceUuids().size() * 16)
+                            .order(ByteOrder.LITTLE_ENDIAN);
+            for (ParcelUuid parcelUuid : data.getServiceUuids()) {
+                UUID uuid = parcelUuid.getUuid();
+                uuidBytes.putLong(uuid.getLeastSignificantBits())
+                        .putLong(uuid.getMostSignificantBits());
+            }
+            writeDataUnit(
+                    result,
+                    BluetoothConstants.DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE,
+                    uuidBytes.array()
+            );
+        }
+        return result.toByteArray();
+    }
+
+    private static byte[] parseServiceData(UUID uuid, byte[] serviceData) {
+        // First two bytes of the data are data UUID in little endian
+        int length = 2 + serviceData.length;
+        byte[] result = new byte[length];
+        // extract 16-bit UUID value
+        int uuidValue = (int) ((uuid.getMostSignificantBits() & 0x0000FFFF00000000L) >>> 32);
+        result[0] = (byte) (uuidValue & 0xFF);
+        result[1] = (byte) ((uuidValue >> 8) & 0xFF);
+        System.arraycopy(serviceData, 0, result, 2, serviceData.length);
+        return result;
+
+    }
+
+    private static byte[] parseManufacturerData(int manufacturerId, byte[] manufacturerData) {
+        // First two bytes are manufacturer id in little endian.
+        int length = 2 + manufacturerData.length;
+        byte[] result = new byte[length];
+        result[0] = (byte) (manufacturerId & 0xFF);
+        result[1] = (byte) ((manufacturerId >> 8) & 0xFF);
+        System.arraycopy(manufacturerData, 0, result, 2, manufacturerData.length);
+        return result;
+    }
+
+    private static void writeDataUnit(ByteArrayDataOutput output, int type, byte[] data) {
+        // Length includes the length of the field type, which is 1 byte.
+        int length = 1 + data.length;
+        // Length and type are unsigned 8-bit int. Assume the values are valid.
+        output.write(length);
+        output.write(type);
+        output.write(data);
+    }
+
+    private GattHelper() {
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/utils/Logger.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/utils/Logger.java
new file mode 100644
index 0000000..31f7202
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/utils/Logger.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.utils;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Logger class to provide formatted log for Device Shadower.
+ *
+ * <p>Log is formatted as "[TAG] [Keyword1, Keyword2 ...] Log Message Body".</p>
+ */
+public class Logger {
+
+    private static final String TAG = "DeviceShadower";
+
+    private final String mTag;
+    private final String mPrefix;
+
+    public Logger(String tag, String... keywords) {
+        mTag = tag;
+        mPrefix = buildPrefix(keywords);
+    }
+
+    public static Logger create(String... keywords) {
+        return new Logger(TAG, keywords);
+    }
+
+    private static String buildPrefix(String... keywords) {
+        if (keywords.length == 0) {
+            return "";
+        }
+        return String.format(" [%s] ", TextUtils.join(", ", keywords));
+    }
+
+    /**
+     * @see Log#e(String, String)
+     */
+    public void e(String msg) {
+        Log.e(mTag, format(msg));
+    }
+
+    /**
+     * @see Log#e(String, String, Throwable)
+     */
+    public void e(String msg, Throwable throwable) {
+        Log.e(mTag, format(msg), throwable);
+    }
+
+    /**
+     * @see Log#d(String, String)
+     */
+    public void d(String msg) {
+        Log.d(mTag, format(msg));
+    }
+
+    /**
+     * @see Log#d(String, String, Throwable)
+     */
+    public void d(String msg, Throwable throwable) {
+        Log.d(mTag, format(msg), throwable);
+    }
+
+    /**
+     * @see Log#i(String, String)
+     */
+    public void i(String msg) {
+        Log.i(mTag, format(msg));
+    }
+
+    /**
+     * @see Log#i(String, String, Throwable)
+     */
+    public void i(String msg, Throwable throwable) {
+        Log.i(mTag, format(msg), throwable);
+    }
+
+    /**
+     * @see Log#v(String, String)
+     */
+    public void v(String msg) {
+        Log.v(mTag, format(msg));
+    }
+
+    /**
+     * @see Log#v(String, String, Throwable)
+     */
+    public void v(String msg, Throwable throwable) {
+        Log.v(mTag, format(msg), throwable);
+    }
+
+    /**
+     * @see Log#w(String, String)
+     */
+    public void w(String msg) {
+        Log.w(mTag, format(msg));
+    }
+
+    /**
+     * @see Log#w(String, Throwable)
+     */
+    public void w(Throwable throwable) {
+        Log.w(mTag, null, throwable);
+    }
+
+    /**
+     * @see Log#w(String, String, Throwable)
+     */
+    public void w(String msg, Throwable throwable) {
+        Log.w(mTag, format(msg), throwable);
+    }
+
+    /**
+     * @see Log#wtf(String, String)
+     */
+    public void wtf(String msg) {
+        Log.wtf(mTag, format(msg));
+    }
+
+    /**
+     * @see Log#wtf(String, String, Throwable)
+     */
+    public void wtf(String msg, Throwable throwable) {
+        Log.wtf(mTag, format(msg), throwable);
+    }
+
+    /**
+     * @see Log#isLoggable(String, int)
+     */
+    public boolean isLoggable(int level) {
+        return Log.isLoggable(mTag, level);
+    }
+
+    /**
+     * @see Log#println(int, String, String)
+     */
+    public int println(int priority, String msg) {
+        return Log.println(priority, mTag, format(msg));
+    }
+
+    private String format(String msg) {
+        return mPrefix + msg;
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/utils/MacAddressGenerator.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/utils/MacAddressGenerator.java
new file mode 100644
index 0000000..f8d3193
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/internal/utils/MacAddressGenerator.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.internal.utils;
+
+import android.bluetooth.BluetoothAdapter;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Locale;
+
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * A class which generates and converts valid Bluetooth MAC addresses.
+ */
+public class MacAddressGenerator {
+
+    @GuardedBy("MacAddressGenerator.class")
+    private static MacAddressGenerator sInstance = new MacAddressGenerator();
+
+    @VisibleForTesting
+    public static synchronized void setInstanceForTest(MacAddressGenerator generator) {
+        sInstance = generator;
+    }
+
+    public static synchronized MacAddressGenerator get() {
+        return sInstance;
+    }
+
+    private long mLastAddress = 0x0L;
+
+    private MacAddressGenerator() {
+    }
+
+    public String generateMacAddress() {
+        byte[] bytes = generateMacAddressBytes();
+        return convertByteMacAddress(bytes);
+    }
+
+    public byte[] generateMacAddressBytes() {
+        long addr = mLastAddress++;
+        byte[] bytes = new byte[6];
+        for (int i = 5; i >= 0; i--) {
+            bytes[i] = (byte) (addr & 0xFF);
+            addr = addr >> 8;
+        }
+        return bytes;
+    }
+
+    public static byte[] convertStringMacAddress(String address) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+            throw new IllegalArgumentException("Not a valid bluetooth mac hex string: " + address);
+        }
+        byte[] bytes = new byte[6];
+        String[] macValues = address.split(":");
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = Integer.decode("0x" + macValues[i]).byteValue();
+        }
+        return bytes;
+    }
+
+    public static String convertByteMacAddress(byte[] address) {
+        if (address == null || address.length != 6) {
+            throw new IllegalArgumentException("Bluetooth address must have 6 bytes");
+        }
+        return String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
+                address[0], address[1], address[2], address[3], address[4], address[5]);
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothA2dp.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothA2dp.java
new file mode 100644
index 0000000..344103b
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothA2dp.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.bluetooth;
+
+import static com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl.getBlueletImpl;
+import static com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl.getLocalBlueletImpl;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothProfile.ServiceListener;
+import android.content.Context;
+import android.content.Intent;
+
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.BlueletImpl;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Shadow of the Bluetooth A2DP service.
+ */
+@Implements(BluetoothA2dp.class)
+public class ShadowBluetoothA2dp {
+
+    /**
+     * Hidden in {@link BluetoothProfile}.
+     */
+    public static final int A2DP_SINK = 11;
+
+    private final Map<BluetoothDevice, Integer> mDeviceToConnectionState = new HashMap<>();
+    private Context mContext;
+    @RealObject
+    private BluetoothA2dp mRealObject;
+
+    public void __constructor__(Context context, ServiceListener l) {
+        this.mContext = context;
+        l.onServiceConnected(BluetoothProfile.A2DP, mRealObject);
+    }
+
+    @Implementation
+    public List<BluetoothDevice> getConnectedDevices() {
+        List<BluetoothDevice> result = new ArrayList<>();
+        for (BluetoothDevice device : mDeviceToConnectionState.keySet()) {
+            if (getConnectionState(device) == BluetoothProfile.STATE_CONNECTED) {
+                result.add(device);
+            }
+        }
+        return result;
+    }
+
+    @Implementation
+    public int getConnectionState(BluetoothDevice device) {
+        return mDeviceToConnectionState.containsKey(device)
+                ? mDeviceToConnectionState.get(device)
+                : BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    @Implementation
+    public boolean connect(BluetoothDevice device) {
+        setConnectionState(BluetoothProfile.STATE_CONNECTING, device);
+        // Only successfully connect if the device is in the environment (i.e. nearby) and accepts
+        // connections.
+        BlueletImpl blueLet = getBlueletImpl(device.getAddress());
+        if (blueLet != null && !blueLet.getRefuseConnections()) {
+            setConnectionState(BluetoothProfile.STATE_CONNECTED, device);
+        } else {
+            // If the device isn't in the environment, still return true (no immediate failure, i.e.
+            // we're trying to connect) but send CONNECTING -> DISCONNECTED (like the OS does).
+            setConnectionState(BluetoothProfile.STATE_DISCONNECTED, device);
+        }
+        return true;
+    }
+
+    @Implementation
+    public void close() {
+    }
+
+    private void setConnectionState(int state, BluetoothDevice device) {
+        int previousState = getConnectionState(device);
+        mDeviceToConnectionState.put(device, state);
+
+        getLocalBlueletImpl()
+                .setProfileConnectionState(BluetoothProfile.A2DP, state, device.getAddress());
+        BlueletImpl remoteDevice = getBlueletImpl(device.getAddress());
+        if (remoteDevice != null) {
+            remoteDevice.setProfileConnectionState(A2DP_SINK, state, getLocalBlueletImpl().address);
+        }
+
+        mContext.sendBroadcast(
+                new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)
+                        .putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, previousState)
+                        .putExtra(BluetoothProfile.EXTRA_STATE, state)
+                        .putExtra(BluetoothDevice.EXTRA_DEVICE, device));
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothAdapter.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothAdapter.java
new file mode 100644
index 0000000..394afbc
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothAdapter.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.AttributionSource;
+
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.BlueletImpl;
+import com.android.libraries.testing.deviceshadower.internal.utils.MacAddressGenerator;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+
+/**
+ * Shadow of {@link BluetoothAdapter} to be used with Device Shadower in Robolectric test.
+ */
+@Implements(BluetoothAdapter.class)
+public class ShadowBluetoothAdapter {
+
+    @RealObject
+    BluetoothAdapter mRealAdapter;
+
+    public ShadowBluetoothAdapter() {
+    }
+
+    @Implementation
+    public static synchronized BluetoothAdapter getDefaultAdapter() {
+        // Add a device and set local devicelet in case no local bluelet set
+        if (!DeviceShadowEnvironmentImpl.hasLocalDeviceletImpl()) {
+            String address = MacAddressGenerator.get().generateMacAddress();
+            DeviceShadowEnvironmentImpl.addDevice(address);
+            DeviceShadowEnvironmentImpl.setLocalDevice(address);
+        }
+        BlueletImpl localBluelet = DeviceShadowEnvironmentImpl.getLocalBlueletImpl();
+        return localBluelet.getAdapter();
+    }
+
+    @Implementation
+    public static BluetoothAdapter createAdapter(AttributionSource attributionSource) {
+        // Add a device and set local devicelet in case no local bluelet set
+        if (!DeviceShadowEnvironmentImpl.hasLocalDeviceletImpl()) {
+            String address = MacAddressGenerator.get().generateMacAddress();
+            DeviceShadowEnvironmentImpl.addDevice(address);
+            DeviceShadowEnvironmentImpl.setLocalDevice(address);
+        }
+        BlueletImpl localBluelet = DeviceShadowEnvironmentImpl.getLocalBlueletImpl();
+        return localBluelet.getAdapter();
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothDevice.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothDevice.java
new file mode 100644
index 0000000..247f46e
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothDevice.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.IBluetoothImpl;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Placeholder for BluetoothDevice improvements
+ */
+@Implements(BluetoothDevice.class)
+public class ShadowBluetoothDevice {
+
+    @RealObject
+    private BluetoothDevice mBluetoothDevice;
+    private static final Map<String, Integer> sBondTransport = new HashMap<>();
+    private static Map<String, Boolean> sPairingConfirmation = new HashMap<>();
+
+    public ShadowBluetoothDevice() {
+    }
+
+    @Implementation
+    public boolean setPasskey(int passkey) {
+        return new IBluetoothImpl().setPasskey(mBluetoothDevice, passkey);
+    }
+
+    @Implementation
+    public boolean createBond(int transport) {
+        sBondTransport.put(mBluetoothDevice.getAddress(), transport);
+        return Shadow.directlyOn(
+                mBluetoothDevice,
+                BluetoothDevice.class,
+                "createBond",
+                ClassParameter.from(int.class, transport));
+    }
+
+    public static int getBondTransport(String address) {
+        return sBondTransport.containsKey(address)
+                ? sBondTransport.get(address)
+                : BluetoothDevice.TRANSPORT_AUTO;
+    }
+
+    @Implementation
+    public boolean setPairingConfirmation(boolean confirm) {
+        sPairingConfirmation.put(mBluetoothDevice.getAddress(), confirm);
+        return Shadow.directlyOn(
+                mBluetoothDevice,
+                BluetoothDevice.class,
+                "setPairingConfirmation",
+                ClassParameter.from(boolean.class, confirm));
+    }
+
+    /**
+     * Gets the confirmation value previously set with a call to {@link
+     * BluetoothDevice#setPairingConfirmation(boolean)}. Default is false.
+     */
+    public static boolean getPairingConfirmation(String address) {
+        return sPairingConfirmation.containsKey(address) && sPairingConfirmation.get(address);
+    }
+
+    /**
+     * Resets the confirmation values.
+     */
+    public static void resetPairingConfirmation() {
+        sPairingConfirmation = new HashMap<>();
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothLeScanner.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothLeScanner.java
new file mode 100644
index 0000000..1f7da14
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothLeScanner.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.bluetooth;
+
+import android.bluetooth.le.BluetoothLeScanner;
+
+import org.robolectric.annotation.Implements;
+
+/**
+ * Shadow of {@link BluetoothLeScanner} to be used with Device Shadower in Robolectric test.
+ */
+@Implements(BluetoothLeScanner.class)
+public class ShadowBluetoothLeScanner {
+
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothServerSocket.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothServerSocket.java
new file mode 100644
index 0000000..bffcf32
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothServerSocket.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.bluetooth;
+
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.net.LocalSocket;
+import android.os.ParcelFileDescriptor;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.connection.RfcommDelegate;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * Placeholder for BluetoothServerSocket updates
+ */
+@Implements(BluetoothServerSocket.class)
+public class ShadowBluetoothServerSocket {
+
+    @RealObject
+    BluetoothServerSocket mRealServerSocket;
+
+    public ShadowBluetoothServerSocket() {
+    }
+
+    @Implementation
+    public BluetoothSocket accept(int timeout) throws IOException {
+        FileDescriptor serverSocketFd = getServerSocketFileDescriptor();
+        if (serverSocketFd == null) {
+            throw new IOException("socket is closed.");
+        }
+        RfcommDelegate local = getLocalRfcommDelegate();
+        local.checkInterrupt();
+        FileDescriptor clientFd = local.processNextConnectionRequest(serverSocketFd);
+        // configure the LocalSocket of the BluetoothServerSocket
+        BluetoothSocket internalSocket = ReflectionHelpers.getField(mRealServerSocket, "mSocket");
+        ShadowLocalSocket internalLocalSocket = getLocalSocketShadow(internalSocket);
+        internalLocalSocket.setAncillaryFd(local.getServerFd(clientFd));
+
+        // call original method
+        BluetoothSocket socket = Shadow.directlyOn(mRealServerSocket, BluetoothServerSocket.class,
+                "accept", ClassParameter.from(int.class, timeout));
+
+        // setup local socket of the returned BluetoothSocket
+        String remoteAddress = socket.getRemoteDevice().getAddress();
+        ShadowLocalSocket shadowLocalSocket = getLocalSocketShadow(socket);
+        shadowLocalSocket.setRemoteAddress(remoteAddress);
+        // init connection to client
+        local.initiateConnectToClient(clientFd, getPort());
+        local.waitForConnectionEstablished(clientFd);
+        return socket;
+    }
+
+    @Implementation
+    public void close() throws IOException {
+        getLocalRfcommDelegate().closeServerSocket(getServerSocketFileDescriptor());
+        Shadow.directlyOn(mRealServerSocket, BluetoothServerSocket.class, "close");
+    }
+
+    @VisibleForTesting
+    FileDescriptor getServerSocketFileDescriptor() {
+        BluetoothSocket socket = ReflectionHelpers.getField(mRealServerSocket, "mSocket");
+        ParcelFileDescriptor pfd = ReflectionHelpers.getField(socket, "mPfd");
+        if (pfd == null) {
+            return null;
+        }
+        return pfd.getFileDescriptor();
+    }
+
+    @VisibleForTesting
+    int getPort() {
+        BluetoothSocket socket = ReflectionHelpers.getField(mRealServerSocket, "mSocket");
+        return ReflectionHelpers.getField(socket, "mPort");
+    }
+
+    private ShadowLocalSocket getLocalSocketShadow(BluetoothSocket socket) {
+        LocalSocket localSocket = ReflectionHelpers.getField(socket, "mSocket");
+        return (ShadowLocalSocket) Shadow.extract(localSocket);
+    }
+
+    private RfcommDelegate getLocalRfcommDelegate() {
+        return DeviceShadowEnvironmentImpl.getLocalBlueletImpl().getRfcommDelegate();
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothSocket.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothSocket.java
new file mode 100644
index 0000000..5d417cf
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowBluetoothSocket.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.bluetooth;
+
+import android.bluetooth.BluetoothSocket;
+import android.os.ParcelFileDescriptor;
+
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.connection.RfcommDelegate;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Shadow implementation of a Bluetooth Socket
+ */
+@Implements(BluetoothSocket.class)
+public class ShadowBluetoothSocket {
+
+    @RealObject
+    BluetoothSocket mRealSocket;
+
+    public ShadowBluetoothSocket() {
+    }
+
+    @Implementation
+    public void connect() throws IOException {
+        Shadow.directlyOn(mRealSocket, BluetoothSocket.class, "connect");
+
+        boolean isEncrypted = ReflectionHelpers.getField(mRealSocket, "mEncrypt");
+        FileDescriptor localFd =
+                ((ParcelFileDescriptor) ReflectionHelpers.getField(mRealSocket,
+                        "mPfd")).getFileDescriptor();
+        RfcommDelegate local = DeviceShadowEnvironmentImpl.getLocalBlueletImpl()
+                .getRfcommDelegate();
+        String remoteAddress = mRealSocket.getRemoteDevice().getAddress();
+        local.finishPendingConnection(remoteAddress, localFd, isEncrypted);
+
+        ShadowLocalSocket shadowLocalSocket = getLocalSocketShadow();
+        shadowLocalSocket.setRemoteAddress(remoteAddress);
+    }
+
+    @Implementation
+    public InputStream getInputStream() throws IOException {
+        ShadowLocalSocket socket = getLocalSocketShadow();
+        return socket.getInputStream();
+    }
+
+    @Implementation
+    public OutputStream getOutputStream() throws IOException {
+        ShadowLocalSocket socket = getLocalSocketShadow();
+        return socket.getOutputStream();
+    }
+
+    private ShadowLocalSocket getLocalSocketShadow() throws IOException {
+        try {
+            return (ShadowLocalSocket) Shadow.extract(
+                    ReflectionHelpers.getField(mRealSocket, "mSocket"));
+        } catch (NullPointerException e) {
+            throw new IOException(e);
+        }
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowLocalSocket.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowLocalSocket.java
new file mode 100644
index 0000000..5189330
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowLocalSocket.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.bluetooth;
+
+import android.net.LocalSocket;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.BluetoothConstants;
+import com.android.libraries.testing.deviceshadower.internal.bluetooth.connection.RfcommDelegate;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Shadow implementation of a LocalSocket to make bluetooth connections function.
+ */
+@Implements(LocalSocket.class)
+public class ShadowLocalSocket {
+
+    private String mRemoteAddress;
+    private FileDescriptor mFd;
+    private FileDescriptor mAncillaryFd;
+
+    public ShadowLocalSocket() {
+    }
+
+    public void __constructor__(FileDescriptor fd) {
+        this.mFd = fd;
+    }
+
+    @Implementation
+    public FileDescriptor[] getAncillaryFileDescriptors() throws IOException {
+        return new FileDescriptor[]{mAncillaryFd};
+    }
+
+    @Implementation
+    @SuppressWarnings("InputStreamSlowMultibyteRead")
+    public InputStream getInputStream() throws IOException {
+        final RfcommDelegate local = getLocalRfcommDelegate();
+        return new InputStream() {
+            @Override
+            public int read() throws IOException {
+                int res = local.read(mRemoteAddress, mFd);
+                if (res == BluetoothConstants.SOCKET_CLOSE) {
+                    throw new IOException("closed");
+                }
+                return res & 0xFF;
+            }
+        };
+    }
+
+    @Implementation
+    public OutputStream getOutputStream() throws IOException {
+        final RfcommDelegate local = getLocalRfcommDelegate();
+        return new OutputStream() {
+            @Override
+            public void write(int b) throws IOException {
+                local.write(mRemoteAddress, mFd, b);
+            }
+        };
+    }
+
+    @Implementation
+    public void setSoTimeout(int n) throws IOException {
+        // Nothing
+    }
+
+    @Implementation
+    public void shutdownInput() throws IOException {
+        getLocalRfcommDelegate().shutdownInput(mRemoteAddress, mFd);
+    }
+
+    @Implementation
+    public void shutdownOutput() throws IOException {
+        if (mRemoteAddress == null) {
+            return;
+        }
+        getLocalRfcommDelegate().shutdownOutput(mRemoteAddress, mFd);
+    }
+
+    void setAncillaryFd(FileDescriptor fd) {
+        mAncillaryFd = fd;
+    }
+
+    void setRemoteAddress(String address) {
+        mRemoteAddress = address;
+    }
+
+    @VisibleForTesting
+    void setFileDescriptorForTest(FileDescriptor fd) {
+        this.mFd = fd;
+    }
+
+    private RfcommDelegate getLocalRfcommDelegate() {
+        return DeviceShadowEnvironmentImpl.getLocalBlueletImpl().getRfcommDelegate();
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowParcelFileDescriptor.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowParcelFileDescriptor.java
new file mode 100644
index 0000000..585939b
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/bluetooth/ShadowParcelFileDescriptor.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.bluetooth;
+
+import android.os.ParcelFileDescriptor;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * Inert implementation of a ParcelFileDescriptor to make bluetooth connections function.
+ */
+@Implements(ParcelFileDescriptor.class)
+public class ShadowParcelFileDescriptor {
+
+    private FileDescriptor mFd;
+
+    public ShadowParcelFileDescriptor() {
+    }
+
+    public void __constructor__(FileDescriptor fd) {
+        this.mFd = fd;
+    }
+
+    @Implementation
+    public FileDescriptor getFileDescriptor() {
+        return mFd;
+    }
+
+    @Implementation
+    public void close() throws IOException {
+        // Nothing
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/common/DeviceShadowContextImpl.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/common/DeviceShadowContextImpl.java
new file mode 100644
index 0000000..9bbcee7
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/common/DeviceShadowContextImpl.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.common;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.DeviceletImpl;
+import com.android.libraries.testing.deviceshadower.internal.common.BroadcastManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadows.ShadowContextImpl;
+
+import javax.annotation.Nullable;
+
+/**
+ * Extends {@link ShadowContextImpl} to achieve automatic method redirection to correct virtual
+ * device.
+ *
+ * <p>Supports:
+ * <li>Broadcasting</li>
+ * Includes send regular, regular sticky, ordered broadcast, and register/unregister receiver.
+ * </p>
+ */
+@Implements(className = "android.app.ContextImpl")
+public class DeviceShadowContextImpl extends ShadowContextImpl {
+
+    private static final String TAG = "DeviceShadowContextImpl";
+
+    @RealObject
+    private Context mContextImpl;
+
+    @Override
+    @Implementation
+    @Nullable
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+        if (receiver == null) {
+            return null;
+        }
+        BroadcastManager manager = getLocalBroadcastManager();
+        if (manager == null) {
+            Log.w(TAG, "Receiver registered before any devices added: " + receiver);
+            return null;
+        }
+        return manager.registerReceiver(
+                receiver, filter, null /* permission */, null /* handler */, mContextImpl);
+    }
+
+    @Override
+    @Implementation
+    @Nullable
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+            @Nullable String broadcastPermission, @Nullable Handler scheduler) {
+        return getLocalBroadcastManager().registerReceiver(
+                receiver, filter, broadcastPermission, scheduler, mContextImpl);
+    }
+
+    @Override
+    @Implementation
+    public void unregisterReceiver(BroadcastReceiver broadcastReceiver) {
+        getLocalBroadcastManager().unregisterReceiver(broadcastReceiver);
+    }
+
+    @Override
+    @Implementation
+    public void sendBroadcast(Intent intent) {
+        getLocalBroadcastManager().sendBroadcast(intent, null /* permission */);
+    }
+
+    @Override
+    @Implementation
+    public void sendBroadcast(Intent intent, @Nullable String receiverPermission) {
+        getLocalBroadcastManager().sendBroadcast(intent, receiverPermission);
+    }
+
+    @Override
+    @Implementation
+    public void sendOrderedBroadcast(Intent intent, @Nullable String receiverPermission) {
+        getLocalBroadcastManager().sendOrderedBroadcast(intent, receiverPermission);
+    }
+
+    @Override
+    @Implementation
+    public void sendOrderedBroadcast(Intent intent, @Nullable String receiverPermission,
+            @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
+            int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) {
+        getLocalBroadcastManager().sendOrderedBroadcast(intent, receiverPermission, resultReceiver,
+                scheduler, initialCode, initialData, initialExtras, mContextImpl);
+    }
+
+    @Override
+    @Implementation
+    public void sendStickyBroadcast(Intent intent) {
+        getLocalBroadcastManager().sendStickyBroadcast(intent);
+    }
+
+    private BroadcastManager getLocalBroadcastManager() {
+        DeviceletImpl devicelet = DeviceShadowEnvironmentImpl.getLocalDeviceletImpl();
+        if (devicelet == null) {
+            return null;
+        }
+        return devicelet.getBroadcastManager();
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/nfc/ShadowNfcAdapter.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/nfc/ShadowNfcAdapter.java
new file mode 100644
index 0000000..e7112fb
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/shadows/nfc/ShadowNfcAdapter.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.shadows.nfc;
+
+import static org.robolectric.util.ReflectionHelpers.callConstructor;
+
+import android.content.Context;
+import android.nfc.NfcAdapter;
+
+import com.android.libraries.testing.deviceshadower.Enums.NfcOperation;
+import com.android.libraries.testing.deviceshadower.internal.DeviceShadowEnvironmentImpl;
+import com.android.libraries.testing.deviceshadower.internal.nfc.INfcAdapterImpl;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+/**
+ * Shadow implementation of Nfc Adapter.
+ */
+@Implements(NfcAdapter.class)
+public class ShadowNfcAdapter {
+
+    @Implementation
+    public static NfcAdapter getDefaultAdapter(Context context) {
+        if (DeviceShadowEnvironmentImpl.getLocalNfcletImpl()
+                .shouldInterrupt(NfcOperation.GET_ADAPTER)) {
+            return null;
+        }
+        ReflectionHelpers.setStaticField(NfcAdapter.class, "sService", new INfcAdapterImpl());
+        return callConstructor(NfcAdapter.class, ClassParameter.from(Context.class, context));
+    }
+
+    // TODO(b/200231384): support state change.
+    public ShadowNfcAdapter() {
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/BaseTestCase.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/BaseTestCase.java
new file mode 100644
index 0000000..8a3c0e7
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/BaseTestCase.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.testcases;
+
+import android.app.Application;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+import com.android.libraries.testing.deviceshadower.shadows.bluetooth.ShadowLocalSocket;
+import com.android.libraries.testing.deviceshadower.shadows.bluetooth.ShadowParcelFileDescriptor;
+import com.android.libraries.testing.deviceshadower.shadows.common.DeviceShadowContextImpl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+/**
+ * Base class for all DeviceShadower client.
+ */
+@Config(
+        // sdk = 21,
+        shadows = {
+                DeviceShadowContextImpl.class,
+                ShadowParcelFileDescriptor.class,
+                ShadowLocalSocket.class
+        })
+public class BaseTestCase {
+
+    protected Application mContext = RuntimeEnvironment.application;
+
+    /**
+     * Test Watcher which logs test starting and finishing so log messages are easier to read.
+     */
+    @Rule
+    public TestWatcher watcher = new TestWatcher() {
+        @Override
+        protected void succeeded(Description description) {
+            super.succeeded(description);
+            logMessage(
+                    String.format("Test %s finished successfully.", description.getDisplayName()));
+        }
+
+        @Override
+        protected void failed(Throwable e, Description description) {
+            super.failed(e, description);
+            logMessage(String.format("Test %s failed.", description.getDisplayName()));
+        }
+
+        @Override
+        protected void skipped(AssumptionViolatedException e, Description description) {
+            super.skipped(e, description);
+            logMessage(String.format("Test %s is skipped.", description.getDisplayName()));
+        }
+
+        @Override
+        protected void starting(Description description) {
+            super.starting(description);
+            logMessage(String.format("Test %s started.", description.getDisplayName()));
+        }
+
+        @Override
+        protected void finished(Description description) {
+            super.finished(description);
+        }
+
+        private void logMessage(String message) {
+            System.out.println("\n*** " + message);
+        }
+    };
+
+    @Before
+    public void setUp() throws Exception {
+        DeviceShadowEnvironment.init();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        DeviceShadowEnvironment.reset();
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/BluetoothTestCase.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/BluetoothTestCase.java
new file mode 100644
index 0000000..cddc6fe
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/BluetoothTestCase.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.testcases;
+
+import static org.robolectric.Shadows.shadowOf;
+import static org.robolectric.util.ReflectionHelpers.callConstructor;
+
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
+
+import com.android.libraries.testing.deviceshadower.shadows.bluetooth.ShadowBluetoothA2dp;
+import com.android.libraries.testing.deviceshadower.shadows.bluetooth.ShadowBluetoothAdapter;
+import com.android.libraries.testing.deviceshadower.shadows.bluetooth.ShadowBluetoothDevice;
+import com.android.libraries.testing.deviceshadower.shadows.bluetooth.ShadowBluetoothLeScanner;
+import com.android.libraries.testing.deviceshadower.shadows.bluetooth.ShadowBluetoothServerSocket;
+import com.android.libraries.testing.deviceshadower.shadows.bluetooth.ShadowBluetoothSocket;
+
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+/**
+ * Base class for Bluetooth Test
+ */
+@Config(
+        shadows = {
+                ShadowBluetoothAdapter.class,
+                ShadowBluetoothDevice.class,
+                ShadowBluetoothLeScanner.class,
+                ShadowBluetoothSocket.class,
+                ShadowBluetoothServerSocket.class,
+                ShadowBluetoothA2dp.class
+        })
+public class BluetoothTestCase extends BaseTestCase {
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        // TODO(b/28087747): Get bluetooth Manager from robolectric framework.
+        shadowOf(RuntimeEnvironment.application)
+                .setSystemService(
+                        Context.BLUETOOTH_SERVICE,
+                        callConstructor(BluetoothManager.class,
+                                ClassParameter.from(Context.class, mContext)));
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/Matchers.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/Matchers.java
new file mode 100644
index 0000000..3bfe43b
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/Matchers.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.testcases;
+
+import static org.mockito.ArgumentMatchers.argThat;
+
+import android.bluetooth.BluetoothSocket;
+
+import org.mockito.ArgumentMatcher;
+
+/**
+ * Convenient methods to create mockito matchers.
+ */
+public class Matchers {
+
+    private Matchers() {
+    }
+
+    public static <T extends Exception> T exception(final Class<T> clazz, final String... msgs) {
+        return argThat(
+                new ArgumentMatcher<T>() {
+                    @Override
+                    public boolean matches(T obj) {
+                        if (!clazz.isInstance(obj)) {
+                            return false;
+                        }
+                        Throwable exception = clazz.cast(obj);
+                        for (String msg : msgs) {
+                            if (exception == null || !exception.getMessage().contains(msg)) {
+                                return false;
+                            }
+                            exception = exception.getCause();
+                        }
+                        return true;
+                    }
+                });
+    }
+
+    public static BluetoothSocket socket(final String addr) {
+        return argThat(
+                new ArgumentMatcher<BluetoothSocket>() {
+                    @Override
+                    public boolean matches(BluetoothSocket obj) {
+                        return ((BluetoothSocket) obj)
+                                .getRemoteDevice()
+                                .getAddress()
+                                .toUpperCase()
+                                .equals(addr.toUpperCase());
+                    }
+                });
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/NfcTestCase.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/NfcTestCase.java
new file mode 100644
index 0000000..a80164b
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/NfcTestCase.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.testcases;
+
+import com.android.libraries.testing.deviceshadower.shadows.nfc.ShadowNfcAdapter;
+
+import org.robolectric.annotation.Config;
+
+/**
+ * Base class for NFC Test
+ */
+@Config(shadows = {ShadowNfcAdapter.class})
+public class NfcTestCase extends BaseTestCase {
+
+}
+
diff --git a/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/SmsTestCase.java b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/SmsTestCase.java
new file mode 100644
index 0000000..edfcc6d
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/libraries/testing/deviceshadower/testcases/SmsTestCase.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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.libraries.testing.deviceshadower.testcases;
+
+import android.content.pm.ProviderInfo;
+import android.provider.Telephony;
+
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironmentInternal;
+
+import org.robolectric.Robolectric;
+
+/**
+ * Base class for SMS Test
+ */
+public class SmsTestCase extends BaseTestCase {
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        ProviderInfo info = new ProviderInfo();
+        info.authority = Telephony.Sms.CONTENT_URI.getAuthority();
+        Robolectric.buildContentProvider(
+                        DeviceShadowEnvironmentInternal.getSmsContentProviderClass())
+                .create(info);
+    }
+}
diff --git a/nearby/tests/robotests/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothClassicPairerTest.java b/nearby/tests/robotests/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothClassicPairerTest.java
new file mode 100644
index 0000000..1ac2aaf
--- /dev/null
+++ b/nearby/tests/robotests/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothClassicPairerTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 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.server.nearby.common.bluetooth.fastpair;
+
+import static org.robolectric.Shadows.shadowOf;
+
+import android.Manifest.permission;
+import android.bluetooth.BluetoothAdapter;
+
+import com.android.libraries.testing.deviceshadower.Bluelet.IoCapabilities;
+import com.android.libraries.testing.deviceshadower.DeviceShadowEnvironment;
+import com.android.libraries.testing.deviceshadower.shadows.bluetooth.ShadowBluetoothDevice;
+import com.android.libraries.testing.deviceshadower.testcases.BluetoothTestCase;
+
+import com.google.common.base.VerifyException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Tests for {@link BluetoothClassicPairer}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class BluetoothClassicPairerTest extends BluetoothTestCase {
+
+    private static final String LOCAL_DEVICE_ADDRESS = "AA:AA:AA:AA:AA:01";
+
+    /**
+     * The remote device's Bluetooth Classic address.
+     */
+    private static final String REMOTE_DEVICE_PUBLIC_ADDRESS = "BB:BB:BB:BB:BB:0C";
+
+    private Preferences.Builder mPrefsBuilder;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mPrefsBuilder = Preferences.builder().setCreateBondTimeoutSeconds(10);
+
+        ShadowBluetoothDevice.resetPairingConfirmation();
+        shadowOf(mContext)
+                .grantPermissions(
+                        permission.BLUETOOTH, permission.BLUETOOTH_ADMIN,
+                        permission.BLUETOOTH_PRIVILEGED);
+
+        DeviceShadowEnvironment.addDevice(LOCAL_DEVICE_ADDRESS)
+                .bluetooth()
+                .setAdapterInitialState(BluetoothAdapter.STATE_ON)
+                .setIoCapabilities(IoCapabilities.DISPLAY_YES_NO);
+        DeviceShadowEnvironment.addDevice(REMOTE_DEVICE_PUBLIC_ADDRESS)
+                .bluetooth()
+                .setAdapterInitialState(BluetoothAdapter.STATE_ON)
+                .setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)
+                .setIoCapabilities(IoCapabilities.DISPLAY_YES_NO);
+
+        // By default, code runs as if it's on this virtual "device".
+        DeviceShadowEnvironment.setLocalDevice(LOCAL_DEVICE_ADDRESS);
+    }
+
+    @Test
+    public void pair_setPairingConfirmationTrue_deviceBonded() throws Exception {
+    // TODO(b/217195327): replace deviceshadower with injector.
+    /*
+        AtomicReference<BluetoothDevice> targetRemoteDevice = new AtomicReference<>();
+        BluetoothClassicPairer bluetoothClassicPairer =
+                new BluetoothClassicPairer(
+                        mContext,
+                        BluetoothAdapter.getDefaultAdapter()
+                                .getRemoteDevice(REMOTE_DEVICE_PUBLIC_ADDRESS),
+                        mPrefsBuilder.build(),
+                        (BluetoothDevice remoteDevice, int key) -> {
+                            targetRemoteDevice.set(remoteDevice);
+                            // Confirms at remote device to pair with local one.
+                            setPairingConfirmationAtRemoteDevice(true);
+
+                            // Confirms to pair with remote device.
+                            remoteDevice.setPairingConfirmation(true);
+                        });
+
+        bluetoothClassicPairer.pair();
+
+        assertThat(targetRemoteDevice.get()).isNotNull();
+        assertThat(targetRemoteDevice.get().getAddress()).isEqualTo(REMOTE_DEVICE_PUBLIC_ADDRESS);
+        assertThat(targetRemoteDevice.get().getBondState()).isEqualTo(BluetoothDevice.BOND_BONDED);
+        assertThat(bluetoothClassicPairer.isPaired()).isTrue();
+    */
+    }
+
+    @Test
+    public void pair_setPairingConfirmationFalse_throwsExceptionDeviceNotBonded() throws Exception {
+    // TODO(b/217195327): replace deviceshadower with injector.
+    /*
+        AtomicReference<BluetoothDevice> targetRemoteDevice = new AtomicReference<>();
+        BluetoothClassicPairer bluetoothClassicPairer =
+                new BluetoothClassicPairer(
+                        mContext,
+                        BluetoothAdapter.getDefaultAdapter()
+                                .getRemoteDevice(REMOTE_DEVICE_PUBLIC_ADDRESS),
+                        mPrefsBuilder.build(),
+                        (BluetoothDevice remoteDevice, int key) -> {
+                            targetRemoteDevice.set(remoteDevice);
+                            // Confirms at remote device to pair with local one.
+                            setPairingConfirmationAtRemoteDevice(true);
+
+                            // Confirms NOT to pair with remote device.
+                            remoteDevice.setPairingConfirmation(false);
+                        });
+
+        assertThrows(PairingException.class, bluetoothClassicPairer::pair);
+
+        assertThat(targetRemoteDevice.get()).isNotNull();
+        assertThat(targetRemoteDevice.get().getAddress()).isEqualTo(REMOTE_DEVICE_PUBLIC_ADDRESS);
+        assertThat(targetRemoteDevice.get().getBondState()).isNotEqualTo(
+                BluetoothDevice.BOND_BONDED);
+        assertThat(bluetoothClassicPairer.isPaired()).isFalse();
+    */
+    }
+
+    @Test
+    public void pair_setPairingConfirmationIgnored_throwsExceptionDeviceNotBonded()
+            throws Exception {
+    // TODO(b/217195327): replace deviceshadower with injector.
+    /*
+        AtomicReference<BluetoothDevice> targetRemoteDevice = new AtomicReference<>();
+        BluetoothClassicPairer bluetoothClassicPairer =
+                new BluetoothClassicPairer(
+                        mContext,
+                        BluetoothAdapter.getDefaultAdapter()
+                                .getRemoteDevice(REMOTE_DEVICE_PUBLIC_ADDRESS),
+                        mPrefsBuilder.build(),
+                        (BluetoothDevice remoteDevice, int key) -> {
+                            targetRemoteDevice.set(remoteDevice);
+                            // Confirms at remote device to pair with local one.
+                            setPairingConfirmationAtRemoteDevice(true);
+
+                            // Ignores the setPairingConfirmation.
+                        });
+
+        assertThrows(PairingException.class, bluetoothClassicPairer::pair);
+        assertThat(targetRemoteDevice.get()).isNotNull();
+        assertThat(targetRemoteDevice.get().getAddress()).isEqualTo(REMOTE_DEVICE_PUBLIC_ADDRESS);
+        assertThat(targetRemoteDevice.get().getBondState()).isNotEqualTo(
+                BluetoothDevice.BOND_BONDED);
+        assertThat(bluetoothClassicPairer.isPaired()).isFalse();
+    */
+    }
+
+    private static void setPairingConfirmationAtRemoteDevice(boolean confirm) {
+        try {
+            DeviceShadowEnvironment.run(REMOTE_DEVICE_PUBLIC_ADDRESS,
+                    () -> BluetoothAdapter.getDefaultAdapter()
+                            .getRemoteDevice(LOCAL_DEVICE_ADDRESS)
+                            .setPairingConfirmation(confirm)).get();
+        } catch (InterruptedException | ExecutionException e) {
+            throw new VerifyException("failed to set pairing confirmation at remote device", e);
+        }
+    }
+}
diff --git a/nearby/tests/unit/Android.bp b/nearby/tests/unit/Android.bp
new file mode 100644
index 0000000..9b35452
--- /dev/null
+++ b/nearby/tests/unit/Android.bp
@@ -0,0 +1,57 @@
+// 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "NearbyUnitTests",
+    defaults: ["mts-target-sdk-version-current"],
+    sdk_version: "test_current",
+    min_sdk_version: "31",
+
+    // Include all test java files.
+    srcs: ["src/**/*.java"],
+
+    libs: [
+        "android.test.base",
+        "android.test.mock",
+        "android.test.runner",
+    ],
+    compile_multilib: "both",
+
+    static_libs: [
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "framework-nearby-static",
+        "guava",
+        "junit",
+        "libprotobuf-java-lite",
+        "mockito-target-extended-minus-junit4",
+        "platform-test-annotations",
+        "service-nearby-pre-jarjar",
+        "truth-prebuilt",
+        // "Robolectric_all-target",
+    ],
+    // these are needed for Extended Mockito
+    jni_libs: [
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+    test_suites: [
+        "general-tests",
+        "mts-tethering",
+    ],
+}
diff --git a/nearby/tests/unit/AndroidManifest.xml b/nearby/tests/unit/AndroidManifest.xml
new file mode 100644
index 0000000..88c0f5f
--- /dev/null
+++ b/nearby/tests/unit/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.nearby.test">
+
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
+
+    <application android:debuggable="true">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.nearby.test"
+        android:label="Nearby Mainline Module Tests" />
+</manifest>
diff --git a/nearby/tests/unit/AndroidTest.xml b/nearby/tests/unit/AndroidTest.xml
new file mode 100644
index 0000000..fdf665d
--- /dev/null
+++ b/nearby/tests/unit/AndroidTest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+<configuration description="Runs Nearby Mainline API Tests.">
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="test-file-name" value="NearbyUnitTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-tag" value="NearbyUnitTests" />
+    <option name="config-descriptor:metadata" key="mainline-param"
+            value="com.google.android.tethering.next.apex" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.nearby.test" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+
+    <!-- Only run NearbyUnitTests in MTS if the Nearby Mainline module is installed. -->
+    <object type="module_controller"
+            class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+        <option name="mainline-module-package-name" value="com.google.android.tethering" />
+    </object>
+</configuration>
diff --git a/nearby/tests/unit/src/android/nearby/ScanRequestTest.java b/nearby/tests/unit/src/android/nearby/ScanRequestTest.java
new file mode 100644
index 0000000..020f6d6
--- /dev/null
+++ b/nearby/tests/unit/src/android/nearby/ScanRequestTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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 android.nearby;
+
+import static android.nearby.ScanRequest.SCAN_MODE_BALANCED;
+import static android.nearby.ScanRequest.SCAN_MODE_LOW_POWER;
+import static android.nearby.ScanRequest.SCAN_TYPE_EXPOSURE_NOTIFICATION;
+import static android.nearby.ScanRequest.SCAN_TYPE_FAST_PAIR;
+import static android.nearby.ScanRequest.SCAN_TYPE_NEARBY_PRESENCE;
+import static android.nearby.ScanRequest.SCAN_TYPE_NEARBY_SHARE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.os.WorkSource;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Units tests for {@link ScanRequest}. */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ScanRequestTest {
+
+    private static WorkSource getWorkSource() {
+        final int uid = 1001;
+        final String appName = "android.nearby.tests";
+        return new WorkSource(uid, appName);
+    }
+
+    /** Test creating a scan request. */
+    @Test
+    public void testScanRequestBuilder() {
+        final int scanType = SCAN_TYPE_FAST_PAIR;
+        ScanRequest request = new ScanRequest.Builder().setScanType(scanType).build();
+
+        assertThat(request.getScanType()).isEqualTo(scanType);
+        assertThat(request.getScanMode()).isEqualTo(SCAN_MODE_LOW_POWER);
+        // Work source is null if not set.
+        assertThat(request.getWorkSource().isEmpty()).isTrue();
+    }
+
+    /** Verify RuntimeException is thrown when creating scan request with invalid scan type. */
+    @Test(expected = RuntimeException.class)
+    public void testScanRequestBuilder_invalidScanType() {
+        final int invalidScanType = -1;
+        ScanRequest.Builder builder = new ScanRequest.Builder().setScanType(invalidScanType);
+
+        builder.build();
+    }
+
+    /** Verify RuntimeException is thrown when creating scan mode with invalid scan mode. */
+    @Test(expected = RuntimeException.class)
+    public void testScanModeBuilder_invalidScanType() {
+        final int invalidScanMode = -5;
+        ScanRequest.Builder builder = new ScanRequest.Builder().setScanType(
+                SCAN_TYPE_FAST_PAIR).setScanMode(invalidScanMode);
+        builder.build();
+    }
+
+    /** Verify setting work source in the scan request. */
+    @Test
+    public void testSetWorkSource() {
+        WorkSource workSource = getWorkSource();
+        ScanRequest request = new ScanRequest.Builder()
+                .setScanType(SCAN_TYPE_NEARBY_SHARE)
+                .setWorkSource(workSource)
+                .build();
+
+        assertThat(request.getWorkSource()).isEqualTo(workSource);
+    }
+
+    /** Verify setting work source with null value in the scan request. */
+    @Test
+    public void testSetWorkSource_nullValue() {
+        ScanRequest request = new ScanRequest.Builder()
+                .setScanType(SCAN_TYPE_EXPOSURE_NOTIFICATION)
+                .setWorkSource(null)
+                .build();
+
+        // Null work source is allowed.
+        assertThat(request.getWorkSource().isEmpty()).isTrue();
+    }
+
+    /** Verify toString returns expected string. */
+    @Test
+    public void testToString() {
+        WorkSource workSource = getWorkSource();
+        ScanRequest request = new ScanRequest.Builder()
+                .setScanType(SCAN_TYPE_NEARBY_SHARE)
+                .setScanMode(SCAN_MODE_BALANCED)
+                .setBleEnabled(true)
+                .setWorkSource(workSource)
+                .build();
+
+        assertThat(request.toString()).isEqualTo(
+                "Request[scanType=2, scanMode=SCAN_MODE_BALANCED, "
+                        + "enableBle=true, workSource=WorkSource{1001 android.nearby.tests}, "
+                        + "scanFilters=[]]");
+    }
+
+    /** Verify toString works correctly with null WorkSource. */
+    @Test
+    public void testToString_nullWorkSource() {
+        ScanRequest request = new ScanRequest.Builder().setScanType(
+                SCAN_TYPE_FAST_PAIR).setWorkSource(null).build();
+
+        assertThat(request.toString()).isEqualTo("Request[scanType=1, "
+                + "scanMode=SCAN_MODE_LOW_POWER, enableBle=true, workSource=WorkSource{}, "
+                + "scanFilters=[]]");
+    }
+
+    /** Verify writing and reading from parcel for scan request. */
+    @Test
+    public void testParceling() {
+        final int scanType = SCAN_TYPE_NEARBY_PRESENCE;
+        WorkSource workSource = getWorkSource();
+        ScanRequest originalRequest = new ScanRequest.Builder()
+                .setScanType(scanType)
+                .setScanMode(SCAN_MODE_BALANCED)
+                .setBleEnabled(true)
+                .setWorkSource(workSource)
+                .build();
+
+        // Write the scan request to parcel, then read from it.
+        ScanRequest request = writeReadFromParcel(originalRequest);
+
+        // Verify the request read from parcel equals to the original request.
+        assertThat(request).isEqualTo(originalRequest);
+    }
+
+    /** Verify parceling with null WorkSource. */
+    @Test
+    public void testParceling_nullWorkSource() {
+        final int scanType = SCAN_TYPE_NEARBY_PRESENCE;
+        ScanRequest originalRequest = new ScanRequest.Builder()
+                .setScanType(scanType).build();
+
+        ScanRequest request = writeReadFromParcel(originalRequest);
+
+        assertThat(request).isEqualTo(originalRequest);
+    }
+
+    private ScanRequest writeReadFromParcel(ScanRequest originalRequest) {
+        Parcel parcel = Parcel.obtain();
+        originalRequest.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        return ScanRequest.CREATOR.createFromParcel(parcel);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/NearbyServiceTest.java b/nearby/tests/unit/src/com/android/server/nearby/NearbyServiceTest.java
new file mode 100644
index 0000000..31965a4
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/NearbyServiceTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby;
+
+import static android.Manifest.permission.READ_DEVICE_CONFIG;
+
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.nearby.IScanListener;
+import android.nearby.ScanRequest;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+public final class NearbyServiceTest {
+
+    private Context mContext;
+    private NearbyService mService;
+    private ScanRequest mScanRequest;
+    private UiAutomation mUiAutomation =
+            InstrumentationRegistry.getInstrumentation().getUiAutomation();
+
+    @Mock
+    private IScanListener mScanListener;
+
+    @Before
+    public void setup() {
+        initMocks(this);
+        mUiAutomation.adoptShellPermissionIdentity(READ_DEVICE_CONFIG);
+        mContext = InstrumentationRegistry.getInstrumentation().getContext();
+        mService = new NearbyService(mContext);
+        mScanRequest = createScanRequest();
+    }
+
+    @Test
+    public void test_register() {
+        mService.registerScanListener(mScanRequest, mScanListener);
+    }
+
+    @Test
+    public void test_unregister() {
+        mService.unregisterScanListener(mScanListener);
+    }
+
+    private ScanRequest createScanRequest() {
+        return new ScanRequest.Builder()
+                .setScanType(ScanRequest.SCAN_TYPE_FAST_PAIR)
+                .setBleEnabled(true)
+                .build();
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/ble/BleFilterTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/ble/BleFilterTest.java
new file mode 100644
index 0000000..1d3653b
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/ble/BleFilterTest.java
@@ -0,0 +1,476 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.common.ble;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+
+import android.bluetooth.BluetoothDevice;
+import android.os.ParcelUuid;
+import android.util.SparseArray;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.server.nearby.common.ble.testing.FastPairTestData;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+@RunWith(AndroidJUnit4.class)
+public class BleFilterTest {
+
+
+    public static final ParcelUuid EDDYSTONE_SERVICE_DATA_PARCELUUID =
+            ParcelUuid.fromString("0000FEAA-0000-1000-8000-00805F9B34FB");
+
+    private ParcelUuid mServiceDataUuid;
+    private BleSighting mBleSighting;
+    private BleFilter.Builder mFilterBuilder;
+
+    @Before
+    public void setUp() throws Exception {
+        // This is the service data UUID in TestData.sd1.
+        // Can't be static because of Robolectric.
+        mServiceDataUuid = ParcelUuid.fromString("000000E0-0000-1000-8000-00805F9B34FB");
+
+        byte[] bleRecordBytes =
+                new byte[]{
+                        0x02,
+                        0x01,
+                        0x1a, // advertising flags
+                        0x05,
+                        0x02,
+                        0x0b,
+                        0x11,
+                        0x0a,
+                        0x11, // 16 bit service uuids
+                        0x04,
+                        0x09,
+                        0x50,
+                        0x65,
+                        0x64, // setName
+                        0x02,
+                        0x0A,
+                        (byte) 0xec, // tx power level
+                        0x05,
+                        0x16,
+                        0x0b,
+                        0x11,
+                        0x50,
+                        0x64, // service data
+                        0x05,
+                        (byte) 0xff,
+                        (byte) 0xe0,
+                        0x00,
+                        0x02,
+                        0x15, // manufacturer specific data
+                        0x03,
+                        0x50,
+                        0x01,
+                        0x02, // an unknown data type won't cause trouble
+                };
+
+        mBleSighting = new BleSighting(null /* device */, bleRecordBytes,
+                -10, 1397545200000000L);
+        mFilterBuilder = new BleFilter.Builder();
+    }
+
+    @Test
+    public void setNameFilter() {
+        BleFilter filter = mFilterBuilder.setDeviceName("Ped").build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        filter = mFilterBuilder.setDeviceName("Pem").build();
+        assertThat(filter.matches(mBleSighting)).isFalse();
+    }
+
+    @Test
+    public void setServiceUuidFilter() {
+        BleFilter filter =
+                mFilterBuilder.setServiceUuid(
+                        ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB"))
+                        .build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        filter =
+                mFilterBuilder.setServiceUuid(
+                        ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB"))
+                        .build();
+        assertThat(filter.matches(mBleSighting)).isFalse();
+
+        filter =
+                mFilterBuilder
+                        .setServiceUuid(
+                                ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB"),
+                                ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF"))
+                        .build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+    }
+
+    @Test
+    public void setServiceDataFilter() {
+        byte[] setServiceData = new byte[]{0x50, 0x64};
+        ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+        BleFilter filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        byte[] emptyData = new byte[0];
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, emptyData).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        byte[] prefixData = new byte[]{0x50};
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, prefixData).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        byte[] nonMatchData = new byte[]{0x51, 0x64};
+        byte[] mask = new byte[]{(byte) 0x00, (byte) 0xFF};
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData, mask).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build();
+        assertThat(filter.matches(mBleSighting)).isFalse();
+    }
+
+    @Test
+    public void manufacturerSpecificData() {
+        byte[] setManufacturerData = new byte[]{0x02, 0x15};
+        int manufacturerId = 0xE0;
+        BleFilter filter =
+                mFilterBuilder.setManufacturerData(manufacturerId, setManufacturerData).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        byte[] emptyData = new byte[0];
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, emptyData).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        byte[] prefixData = new byte[]{0x02};
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, prefixData).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        // Data and mask are nullable. Check that we still match when they're null.
+        filter = mFilterBuilder.setManufacturerData(manufacturerId,
+                null /* data */).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+        filter = mFilterBuilder.setManufacturerData(manufacturerId,
+                null /* data */, null /* mask */).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+
+        // Test data mask
+        byte[] nonMatchData = new byte[]{0x02, 0x14};
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData).build();
+        assertThat(filter.matches(mBleSighting)).isFalse();
+        byte[] mask = new byte[]{(byte) 0xFF, (byte) 0x00};
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData, mask).build();
+        assertThat(filter.matches(mBleSighting)).isTrue();
+    }
+
+    @Test
+    public void manufacturerDataNotInBleRecord() {
+        byte[] bleRecord = FastPairTestData.adv_2;
+        // Verify manufacturer with no data
+        byte[] data = {(byte) 0xe0, (byte) 0x00};
+        BleFilter filter = mFilterBuilder.setManufacturerData(0x00e0, data).build();
+        assertThat(matches(filter, null, 0, bleRecord)).isFalse();
+    }
+
+    @Test
+    public void manufacturerDataMaskNotInBleRecord() {
+        byte[] bleRecord = FastPairTestData.adv_2;
+
+        // Verify matching partial manufacturer with data and mask
+        byte[] data = {(byte) 0x15};
+        byte[] mask = {(byte) 0xff};
+
+        BleFilter filter = mFilterBuilder
+                .setManufacturerData(0x00e0, data, mask).build();
+        assertThat(matches(filter, null, 0, bleRecord)).isFalse();
+    }
+
+
+    @Test
+    public void serviceData() throws Exception {
+        byte[] bleRecord = FastPairTestData.sd1;
+        byte[] serviceData = {(byte) 0x15};
+
+        // Verify manufacturer 2-byte UUID with no data
+        BleFilter filter = mFilterBuilder.setServiceData(mServiceDataUuid, serviceData).build();
+        assertMatches(filter, null, 0, bleRecord);
+    }
+
+    @Test
+    public void serviceDataNoMatch() {
+        byte[] bleRecord = FastPairTestData.sd1;
+        byte[] serviceData = {(byte) 0xe1, (byte) 0x00};
+
+        // Verify manufacturer 2-byte UUID with no data
+        BleFilter filter = mFilterBuilder.setServiceData(mServiceDataUuid, serviceData).build();
+        assertThat(matches(filter, null, 0, bleRecord)).isFalse();
+    }
+
+    @Test
+    public void serviceDataMask() {
+        byte[] bleRecord = FastPairTestData.sd1;
+        BleFilter filter;
+
+        // Verify matching partial manufacturer with data and mask
+        byte[] serviceData1 = {(byte) 0x15};
+        byte[] mask1 = {(byte) 0xff};
+        filter = mFilterBuilder.setServiceData(mServiceDataUuid, serviceData1, mask1).build();
+        assertMatches(filter, null, 0, bleRecord);
+    }
+
+    @Test
+    public void serviceDataMaskNoMatch() {
+        byte[] bleRecord = FastPairTestData.sd1;
+        BleFilter filter;
+
+        // Verify non-matching partial manufacturer with data and mask
+        byte[] serviceData2 = {(byte) 0xe0, (byte) 0x00, (byte) 0x10};
+        byte[] mask2 = {(byte) 0xff, (byte) 0xff, (byte) 0xff};
+        filter = mFilterBuilder.setServiceData(mServiceDataUuid, serviceData2, mask2).build();
+        assertThat(matches(filter, null, 0, bleRecord)).isFalse();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void serviceDataMaskWithDifferentLength() {
+        // Different lengths for data and mask.
+        byte[] serviceData = {(byte) 0xe0, (byte) 0x00, (byte) 0x10};
+        byte[] mask = {(byte) 0xff, (byte) 0xff};
+
+        //expected.expect(IllegalArgumentException.class);
+
+        mFilterBuilder.setServiceData(mServiceDataUuid, serviceData, mask).build();
+    }
+
+
+    @Test
+    public void deviceNameTest() {
+        // Verify the name filter matches
+        byte[] bleRecord = FastPairTestData.adv_1;
+        BleFilter filter = mFilterBuilder.setDeviceName("Pedometer").build();
+        assertMatches(filter, null, 0, bleRecord);
+    }
+
+    @Test
+    public void deviceNameNoMatch() {
+        // Verify the name filter does not match
+        byte[] bleRecord = FastPairTestData.adv_1;
+        BleFilter filter = mFilterBuilder.setDeviceName("Foo").build();
+        assertThat(matches(filter, null, 0, bleRecord)).isFalse();
+    }
+
+    private static boolean matches(
+            BleFilter filter, BluetoothDevice device, int rssi, byte[] bleRecord) {
+        return filter.matches(new BleSighting(device,
+                bleRecord, rssi, 0 /* timestampNanos */));
+    }
+
+
+    private static void assertMatches(
+            BleFilter filter, BluetoothDevice device, int rssi, byte[] bleRecordBytes) {
+
+        // Device match.
+        if (filter.getDeviceAddress() != null
+                && (device == null || !filter.getDeviceAddress().equals(device.getAddress()))) {
+            fail("Filter specified a device address ("
+                    + filter.getDeviceAddress()
+                    + ") which doesn't match the actual value: ["
+                    + (device == null ? "null device" : device.getAddress())
+                    + "]");
+        }
+
+        // BLE record is null but there exist filters on it.
+        BleRecord bleRecord = BleRecord.parseFromBytes(bleRecordBytes);
+        if (bleRecord == null
+                && (filter.getDeviceName() != null
+                || filter.getServiceUuid() != null
+                || filter.getManufacturerData() != null
+                || filter.getServiceData() != null)) {
+            fail(
+                    "The bleRecordBytes given parsed to a null bleRecord, but the filter"
+                            + "has a non-null field which depends on the scan record");
+        }
+
+        // Local name match.
+        if (filter.getDeviceName() != null
+                && !filter.getDeviceName().equals(bleRecord.getDeviceName())) {
+            fail(
+                    "The filter's device name ("
+                            + filter.getDeviceName()
+                            + ") doesn't match the scan record device name ("
+                            + bleRecord.getDeviceName()
+                            + ")");
+        }
+
+        // UUID match.
+        if (filter.getServiceUuid() != null
+                && !matchesServiceUuids(filter.getServiceUuid(), filter.getServiceUuidMask(),
+                bleRecord.getServiceUuids())) {
+            fail("The filter specifies a service UUID but it doesn't match "
+                    + "what's in the scan record");
+        }
+
+        // Service data match
+        if (filter.getServiceDataUuid() != null
+                && !BleFilter.matchesPartialData(
+                filter.getServiceData(),
+                filter.getServiceDataMask(),
+                bleRecord.getServiceData(filter.getServiceDataUuid()))) {
+            fail(
+                    "The filter's service data doesn't match what's in the scan record.\n"
+                            + "Service data: "
+                            + byteString(filter.getServiceData())
+                            + "\n"
+                            + "Service data UUID: "
+                            + filter.getServiceDataUuid().toString()
+                            + "\n"
+                            + "Service data mask: "
+                            + byteString(filter.getServiceDataMask())
+                            + "\n"
+                            + "Scan record service data: "
+                            + byteString(bleRecord.getServiceData(filter.getServiceDataUuid()))
+                            + "\n"
+                            + "Scan record data map:\n"
+                            + byteString(bleRecord.getServiceData()));
+        }
+
+        // Manufacturer data match.
+        if (filter.getManufacturerId() >= 0
+                && !BleFilter.matchesPartialData(
+                filter.getManufacturerData(),
+                filter.getManufacturerDataMask(),
+                bleRecord.getManufacturerSpecificData(filter.getManufacturerId()))) {
+            fail(
+                    "The filter's manufacturer data doesn't match what's in the scan record.\n"
+                            + "Manufacturer ID: "
+                            + filter.getManufacturerId()
+                            + "\n"
+                            + "Manufacturer data: "
+                            + byteString(filter.getManufacturerData())
+                            + "\n"
+                            + "Manufacturer data mask: "
+                            + byteString(filter.getManufacturerDataMask())
+                            + "\n"
+                            + "Scan record manufacturer-specific data: "
+                            + byteString(bleRecord.getManufacturerSpecificData(
+                            filter.getManufacturerId()))
+                            + "\n"
+                            + "Manufacturer data array:\n"
+                            + byteString(bleRecord.getManufacturerSpecificData()));
+        }
+
+        // All filters match.
+        assertThat(
+                matches(filter, device, rssi, bleRecordBytes)).isTrue();
+    }
+
+
+    private static String byteString(byte[] bytes) {
+        if (bytes == null) {
+            return "[null]";
+        } else {
+            final char[] hexArray = "0123456789ABCDEF".toCharArray();
+            char[] hexChars = new char[bytes.length * 2];
+            for (int i = 0; i < bytes.length; i++) {
+                int v = bytes[i] & 0xFF;
+                hexChars[i * 2] = hexArray[v >>> 4];
+                hexChars[i * 2 + 1] = hexArray[v & 0x0F];
+            }
+            return new String(hexChars);
+        }
+    }
+
+    // Ref to beacon.decode.AppleBeaconDecoder.getFilterData
+    private static byte[] getFilterData(ParcelUuid uuid) {
+        byte[] data = new byte[18];
+        data[0] = (byte) 0x02;
+        data[1] = (byte) 0x15;
+        // Check if UUID is needed in data
+        if (uuid != null) {
+            // Convert UUID to array in big endian order
+            byte[] uuidBytes = uuidToByteArray(uuid);
+            for (int i = 0; i < 16; i++) {
+                // Adding uuid bytes in big-endian order to match iBeacon format
+                data[i + 2] = uuidBytes[i];
+            }
+        }
+        return data;
+    }
+
+    // Ref to beacon.decode.AppleBeaconDecoder.uuidToByteArray
+    private static byte[] uuidToByteArray(ParcelUuid uuid) {
+        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
+        bb.putLong(uuid.getUuid().getMostSignificantBits());
+        bb.putLong(uuid.getUuid().getLeastSignificantBits());
+        return bb.array();
+    }
+
+    private static boolean matchesServiceUuids(
+            ParcelUuid uuid, ParcelUuid parcelUuidMask, List<ParcelUuid> uuids) {
+        if (uuid == null) {
+            return true;
+        }
+
+        for (ParcelUuid parcelUuid : uuids) {
+            UUID uuidMask = parcelUuidMask == null ? null : parcelUuidMask.getUuid();
+            if (matchesServiceUuid(uuid.getUuid(), uuidMask, parcelUuid.getUuid())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Check if the uuid pattern matches the particular service uuid.
+    private static boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
+        if (mask == null) {
+            return uuid.equals(data);
+        }
+        if ((uuid.getLeastSignificantBits() & mask.getLeastSignificantBits())
+                != (data.getLeastSignificantBits() & mask.getLeastSignificantBits())) {
+            return false;
+        }
+        return ((uuid.getMostSignificantBits() & mask.getMostSignificantBits())
+                == (data.getMostSignificantBits() & mask.getMostSignificantBits()));
+    }
+
+    private static String byteString(Map<ParcelUuid, byte[]> bytesMap) {
+        StringBuilder builder = new StringBuilder();
+        for (Map.Entry<ParcelUuid, byte[]> entry : bytesMap.entrySet()) {
+            builder.append(builder.toString().isEmpty() ? "  " : "\n  ");
+            builder.append(entry.getKey().toString());
+            builder.append(" --> ");
+            builder.append(byteString(entry.getValue()));
+        }
+        return builder.toString();
+    }
+
+    private static String byteString(SparseArray<byte[]> bytesArray) {
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < bytesArray.size(); i++) {
+            builder.append(builder.toString().isEmpty() ? "  " : "\n  ");
+            builder.append(byteString(bytesArray.valueAt(i)));
+        }
+        return builder.toString();
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/ble/BleRecordTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/ble/BleRecordTest.java
new file mode 100644
index 0000000..5da98e2
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/ble/BleRecordTest.java
@@ -0,0 +1,250 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.server.nearby.common.ble;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+
+/** Test for Bluetooth LE {@link BleRecord}. */
+public class BleRecordTest {
+
+    // iBeacon (Apple) Packet 1
+    private static final byte[] BEACON = {
+            // Flags
+            (byte) 0x02,
+            (byte) 0x01,
+            (byte) 0x06,
+            // Manufacturer-specific data header
+            (byte) 0x1a,
+            (byte) 0xff,
+            (byte) 0x4c,
+            (byte) 0x00,
+            // iBeacon Type
+            (byte) 0x02,
+            // Frame length
+            (byte) 0x15,
+            // iBeacon Proximity UUID
+            (byte) 0xf7,
+            (byte) 0x82,
+            (byte) 0x6d,
+            (byte) 0xa6,
+            (byte) 0x4f,
+            (byte) 0xa2,
+            (byte) 0x4e,
+            (byte) 0x98,
+            (byte) 0x80,
+            (byte) 0x24,
+            (byte) 0xbc,
+            (byte) 0x5b,
+            (byte) 0x71,
+            (byte) 0xe0,
+            (byte) 0x89,
+            (byte) 0x3e,
+            // iBeacon Instance ID (Major/Minor)
+            (byte) 0x44,
+            (byte) 0xd0,
+            (byte) 0x25,
+            (byte) 0x22,
+            // Tx Power
+            (byte) 0xb3,
+            // RSP
+            (byte) 0x08,
+            (byte) 0x09,
+            (byte) 0x4b,
+            (byte) 0x6f,
+            (byte) 0x6e,
+            (byte) 0x74,
+            (byte) 0x61,
+            (byte) 0x6b,
+            (byte) 0x74,
+            (byte) 0x02,
+            (byte) 0x0a,
+            (byte) 0xf4,
+            (byte) 0x0a,
+            (byte) 0x16,
+            (byte) 0x0d,
+            (byte) 0xd0,
+            (byte) 0x74,
+            (byte) 0x6d,
+            (byte) 0x4d,
+            (byte) 0x6b,
+            (byte) 0x32,
+            (byte) 0x36,
+            (byte) 0x64,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00
+    };
+
+    // iBeacon (Apple) Packet 1
+    private static final byte[] SAME_BEACON = {
+            // Flags
+            (byte) 0x02,
+            (byte) 0x01,
+            (byte) 0x06,
+            // Manufacturer-specific data header
+            (byte) 0x1a,
+            (byte) 0xff,
+            (byte) 0x4c,
+            (byte) 0x00,
+            // iBeacon Type
+            (byte) 0x02,
+            // Frame length
+            (byte) 0x15,
+            // iBeacon Proximity UUID
+            (byte) 0xf7,
+            (byte) 0x82,
+            (byte) 0x6d,
+            (byte) 0xa6,
+            (byte) 0x4f,
+            (byte) 0xa2,
+            (byte) 0x4e,
+            (byte) 0x98,
+            (byte) 0x80,
+            (byte) 0x24,
+            (byte) 0xbc,
+            (byte) 0x5b,
+            (byte) 0x71,
+            (byte) 0xe0,
+            (byte) 0x89,
+            (byte) 0x3e,
+            // iBeacon Instance ID (Major/Minor)
+            (byte) 0x44,
+            (byte) 0xd0,
+            (byte) 0x25,
+            (byte) 0x22,
+            // Tx Power
+            (byte) 0xb3,
+            // RSP
+            (byte) 0x08,
+            (byte) 0x09,
+            (byte) 0x4b,
+            (byte) 0x6f,
+            (byte) 0x6e,
+            (byte) 0x74,
+            (byte) 0x61,
+            (byte) 0x6b,
+            (byte) 0x74,
+            (byte) 0x02,
+            (byte) 0x0a,
+            (byte) 0xf4,
+            (byte) 0x0a,
+            (byte) 0x16,
+            (byte) 0x0d,
+            (byte) 0xd0,
+            (byte) 0x74,
+            (byte) 0x6d,
+            (byte) 0x4d,
+            (byte) 0x6b,
+            (byte) 0x32,
+            (byte) 0x36,
+            (byte) 0x64,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00,
+            (byte) 0x00
+    };
+
+    // iBeacon (Apple) Packet 1 with a modified second field.
+    private static final byte[] OTHER_BEACON = {
+            (byte) 0x02, // Length of this Data
+            (byte) 0x02, // <<Flags>>
+            (byte) 0x04, // BR/EDR Not Supported.
+            // Apple Specific Data
+            26, // length of data that follows
+            (byte) 0xff, // <<Manufacturer Specific Data>>
+            // Company Identifier Code = Apple
+            (byte) 0x4c, // LSB
+            (byte) 0x00, // MSB
+            // iBeacon Header
+            0x02,
+            // iBeacon Length
+            0x15,
+            // UUID = PROXIMITY_NOW
+            // IEEE 128-bit UUID represented as UUID[15]: msb To UUID[0]: lsb
+            (byte) 0x14,
+            (byte) 0xe4,
+            (byte) 0xfd,
+            (byte) 0x9f, // UUID[15] - UUID[12]
+            (byte) 0x66,
+            (byte) 0x67,
+            (byte) 0x4c,
+            (byte) 0xcb, // UUID[11] - UUID[08]
+            (byte) 0xa6,
+            (byte) 0x1b,
+            (byte) 0x24,
+            (byte) 0xd0, // UUID[07] - UUID[04]
+            (byte) 0x9a,
+            (byte) 0xb1,
+            (byte) 0x7e,
+            (byte) 0x93, // UUID[03] - UUID[00]
+            // ID as an int (decimal) = 1297482358
+            (byte) 0x76, // Major H
+            (byte) 0x02, // Major L
+            (byte) 0x56, // Minor H
+            (byte) 0x4d, // Minor L
+            // Normalized Tx Power of -77dbm
+            (byte) 0xb3,
+            0x00, // Zero padding for testing
+    };
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEquals() {
+        BleRecord record = BleRecord.parseFromBytes(BEACON);
+        BleRecord record2 = BleRecord.parseFromBytes(SAME_BEACON);
+
+
+        assertThat(record).isEqualTo(record2);
+
+        // Different items.
+        record2 = BleRecord.parseFromBytes(OTHER_BEACON);
+        assertThat(record).isNotEqualTo(record2);
+        assertThat(record.hashCode()).isNotEqualTo(record2.hashCode());
+    }
+}
+
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/ble/decode/FastPairDecoderTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/ble/decode/FastPairDecoderTest.java
new file mode 100644
index 0000000..1ad04f8
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/ble/decode/FastPairDecoderTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.common.ble.decode;
+
+import static com.android.server.nearby.common.ble.BleRecord.parseFromBytes;
+import static com.android.server.nearby.common.ble.testing.FastPairTestData.FAST_PAIR_MODEL_ID;
+import static com.android.server.nearby.common.ble.testing.FastPairTestData.getFastPairRecord;
+import static com.android.server.nearby.common.ble.testing.FastPairTestData.newFastPairRecord;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.server.nearby.common.ble.BleRecord;
+import com.android.server.nearby.util.Hex;
+
+import com.google.common.primitives.Bytes;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class FastPairDecoderTest {
+    private static final String LONG_MODEL_ID = "1122334455667788";
+    private final FastPairDecoder mDecoder = new FastPairDecoder();
+    // Bits 3-6 are model ID length bits = 0b1000 = 8
+    private static final byte LONG_MODEL_ID_HEADER = 0b00010000;
+    private static final String PADDED_LONG_MODEL_ID = "00001111";
+    // Bits 3-6 are model ID length bits = 0b0100 = 4
+    private static final byte PADDED_LONG_MODEL_ID_HEADER = 0b00001000;
+    private static final String TRIMMED_LONG_MODEL_ID = "001111";
+    private static final byte MODEL_ID_HEADER = 0b00000110;
+    private static final String MODEL_ID = "112233";
+    private static final byte BLOOM_FILTER_HEADER = 0b01100000;
+    private static final String BLOOM_FILTER = "112233445566";
+    private static final byte BLOOM_FILTER_SALT_HEADER = 0b00010001;
+    private static final String BLOOM_FILTER_SALT = "01";
+    private static final byte RANDOM_RESOLVABLE_DATA_HEADER = 0b01000110;
+    private static final String RANDOM_RESOLVABLE_DATA = "11223344";
+    private static final byte BLOOM_FILTER_NO_NOTIFICATION_HEADER = 0b01100010;
+
+
+    @Test
+    public void getModelId() {
+        assertThat(mDecoder.getBeaconIdBytes(parseFromBytes(getFastPairRecord())))
+                .isEqualTo(FAST_PAIR_MODEL_ID);
+        FastPairServiceData fastPairServiceData1 =
+                new FastPairServiceData(LONG_MODEL_ID_HEADER,
+                        LONG_MODEL_ID);
+        assertThat(
+                mDecoder.getBeaconIdBytes(
+                        newBleRecord(fastPairServiceData1.createServiceData())))
+                .isEqualTo(Hex.stringToBytes(LONG_MODEL_ID));
+        FastPairServiceData fastPairServiceData =
+                new FastPairServiceData(PADDED_LONG_MODEL_ID_HEADER,
+                        PADDED_LONG_MODEL_ID);
+        assertThat(
+                mDecoder.getBeaconIdBytes(
+                        newBleRecord(fastPairServiceData.createServiceData())))
+                .isEqualTo(Hex.stringToBytes(TRIMMED_LONG_MODEL_ID));
+    }
+
+    @Test
+    public void getBloomFilter() {
+        FastPairServiceData fastPairServiceData = new FastPairServiceData(MODEL_ID_HEADER,
+                MODEL_ID);
+        fastPairServiceData.mExtraFieldHeaders.add(BLOOM_FILTER_HEADER);
+        fastPairServiceData.mExtraFields.add(BLOOM_FILTER);
+        assertThat(FastPairDecoder.getBloomFilter(fastPairServiceData.createServiceData()))
+                .isEqualTo(Hex.stringToBytes(BLOOM_FILTER));
+    }
+
+    @Test
+    public void getBloomFilter_smallModelId() {
+        FastPairServiceData fastPairServiceData = new FastPairServiceData(null, MODEL_ID);
+        assertThat(FastPairDecoder.getBloomFilter(fastPairServiceData.createServiceData()))
+                .isNull();
+    }
+
+    @Test
+    public void getBloomFilterSalt_modelIdAndMultipleExtraFields() {
+        FastPairServiceData fastPairServiceData = new FastPairServiceData(MODEL_ID_HEADER,
+                MODEL_ID);
+        fastPairServiceData.mExtraFieldHeaders.add(BLOOM_FILTER_HEADER);
+        fastPairServiceData.mExtraFieldHeaders.add(BLOOM_FILTER_SALT_HEADER);
+        fastPairServiceData.mExtraFields.add(BLOOM_FILTER);
+        fastPairServiceData.mExtraFields.add(BLOOM_FILTER_SALT);
+        assertThat(
+                FastPairDecoder.getBloomFilterSalt(fastPairServiceData.createServiceData()))
+                .isEqualTo(Hex.stringToBytes(BLOOM_FILTER_SALT));
+    }
+
+    @Test
+    public void getRandomResolvableData_whenContainConnectionState() {
+        FastPairServiceData fastPairServiceData = new FastPairServiceData(MODEL_ID_HEADER,
+                MODEL_ID);
+        fastPairServiceData.mExtraFieldHeaders.add(RANDOM_RESOLVABLE_DATA_HEADER);
+        fastPairServiceData.mExtraFields.add(RANDOM_RESOLVABLE_DATA);
+        assertThat(
+                FastPairDecoder.getRandomResolvableData(fastPairServiceData
+                                .createServiceData()))
+                .isEqualTo(Hex.stringToBytes(RANDOM_RESOLVABLE_DATA));
+    }
+
+    @Test
+    public void getBloomFilterNoNotification() {
+        FastPairServiceData fastPairServiceData =
+                new FastPairServiceData(MODEL_ID_HEADER, MODEL_ID);
+        fastPairServiceData.mExtraFieldHeaders.add(BLOOM_FILTER_NO_NOTIFICATION_HEADER);
+        fastPairServiceData.mExtraFields.add(BLOOM_FILTER);
+        assertThat(FastPairDecoder.getBloomFilterNoNotification(fastPairServiceData
+                        .createServiceData())).isEqualTo(Hex.stringToBytes(BLOOM_FILTER));
+    }
+
+    private static BleRecord newBleRecord(byte[] serviceDataBytes) {
+        return parseFromBytes(newFastPairRecord(serviceDataBytes));
+    }
+    class FastPairServiceData {
+        private Byte mHeader;
+        private String mModelId;
+        List<Byte> mExtraFieldHeaders = new ArrayList<>();
+        List<String> mExtraFields = new ArrayList<>();
+
+        FastPairServiceData(Byte header, String modelId) {
+            this.mHeader = header;
+            this.mModelId = modelId;
+        }
+        private byte[] createServiceData() {
+            if (mExtraFieldHeaders.size() != mExtraFields.size()) {
+                throw new RuntimeException("Number of headers and extra fields must match.");
+            }
+            byte[] serviceData =
+                    Bytes.concat(
+                            mHeader == null ? new byte[0] : new byte[] {mHeader},
+                            mModelId == null ? new byte[0] : Hex.stringToBytes(mModelId));
+            for (int i = 0; i < mExtraFieldHeaders.size(); i++) {
+                serviceData =
+                        Bytes.concat(
+                                serviceData,
+                                mExtraFieldHeaders.get(i) != null
+                                        ? new byte[] {mExtraFieldHeaders.get(i)}
+                                        : new byte[0],
+                                mExtraFields.get(i) != null
+                                        ? Hex.stringToBytes(mExtraFields.get(i))
+                                        : new byte[0]);
+            }
+            return serviceData;
+        }
+    }
+
+
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/ble/util/RangingUtilsTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/ble/util/RangingUtilsTest.java
new file mode 100644
index 0000000..2926015
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/ble/util/RangingUtilsTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.common.ble.util;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RangingUtilsTest {
+    // relative error to be used in comparing doubles
+    private static final double DELTA = 1e-5;
+
+    @Test
+    public void distanceFromRssi_getCorrectValue() {
+        // Distance expected to be 1.0 meters based on an RSSI/TxPower of -41dBm
+        // Using params: int rssi (dBm), int calibratedTxPower (dBm)
+        double distance = RangingUtils.distanceFromRssi(-41, -41);
+        assertThat(distance).isWithin(DELTA).of(1.0);
+
+        double distance2 = RangingUtils.distanceFromRssi(-70, -50);
+        assertThat(distance2).isWithin(DELTA).of(10.0);
+
+        // testing that the double values are not casted to integers
+        double distance3 = RangingUtils.distanceFromRssi(-67, -77);
+        assertThat(distance3).isWithin(DELTA).of(0.31622776601683794);
+
+        double distance4 = RangingUtils.distanceFromRssi(-50, -70);
+        assertThat(distance4).isWithin(DELTA).of(0.1);
+    }
+
+    @Test
+    public void testRssiFromDistance() {
+        // RSSI expected at 1 meter based on the calibrated tx field of -41dBm
+        // Using params: distance (m), int calibratedTxPower (dBm),
+        int rssi = RangingUtils.rssiFromDistance(1.0, -41);
+
+        assertThat(rssi).isEqualTo(-41);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AccountKeyGeneratorTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AccountKeyGeneratorTest.java
new file mode 100644
index 0000000..35a45c0
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AccountKeyGeneratorTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.AccountKeyCharacteristic;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Unit tests for {@link AccountKeyGenerator}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AccountKeyGeneratorTest {
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void createAccountKey() throws NoSuchAlgorithmException {
+        byte[] accountKey = AccountKeyGenerator.createAccountKey();
+
+        assertThat(accountKey).hasLength(16);
+        assertThat(accountKey[0]).isEqualTo(AccountKeyCharacteristic.TYPE);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AdditionalDataEncoderTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AdditionalDataEncoderTest.java
new file mode 100644
index 0000000..28d2fca
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AdditionalDataEncoderTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AdditionalDataEncoder.MAX_LENGTH_OF_DATA;
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.KEY_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.NONCE_SIZE;
+import static com.android.server.nearby.common.bluetooth.fastpair.NamingEncoder.EXTRACT_HMAC_SIZE;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Unit tests for {@link AdditionalDataEncoder}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AdditionalDataEncoderTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void decodeEncodedAdditionalDataPacket_mustGetSameRawData()
+            throws GeneralSecurityException {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        byte[] rawData = base16().decode("00112233445566778899AABBCCDDEEFF");
+
+        byte[] encodedAdditionalDataPacket =
+                AdditionalDataEncoder.encodeAdditionalDataPacket(secret, rawData);
+        byte[] additionalData =
+                AdditionalDataEncoder
+                        .decodeAdditionalDataPacket(secret, encodedAdditionalDataPacket);
+
+        assertThat(additionalData).isEqualTo(rawData);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectKeySizeToEncode_mustThrowException() {
+        byte[] secret = new byte[KEY_LENGTH - 1];
+        byte[] rawData = base16().decode("00112233445566778899AABBCCDDEEFF");
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> AdditionalDataEncoder.encodeAdditionalDataPacket(secret, rawData));
+
+        assertThat(exception)
+                .hasMessageThat()
+                .contains("Incorrect secret for encoding additional data packet");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectKeySizeToDecode_mustThrowException() {
+        byte[] secret = new byte[KEY_LENGTH - 1];
+        byte[] packet = base16().decode("01234567890123456789");
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> AdditionalDataEncoder.decodeAdditionalDataPacket(secret, packet));
+
+        assertThat(exception)
+                .hasMessageThat()
+                .contains("Incorrect secret for decoding additional data packet");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputTooSmallPacketSize_mustThrowException() {
+        byte[] secret = new byte[KEY_LENGTH];
+        byte[] packet = new byte[EXTRACT_HMAC_SIZE - 1];
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> AdditionalDataEncoder.decodeAdditionalDataPacket(secret, packet));
+
+        assertThat(exception).hasMessageThat().contains("Additional data packet size is incorrect");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputTooLargePacketSize_mustThrowException() throws GeneralSecurityException {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        byte[] packet = new byte[MAX_LENGTH_OF_DATA + EXTRACT_HMAC_SIZE + NONCE_SIZE + 1];
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> AdditionalDataEncoder.decodeAdditionalDataPacket(secret, packet));
+
+        assertThat(exception).hasMessageThat().contains("Additional data packet size is incorrect");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectHmacToDecode_mustThrowException() throws GeneralSecurityException {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        byte[] rawData = base16().decode("00112233445566778899AABBCCDDEEFF");
+
+        byte[] additionalDataPacket = AdditionalDataEncoder
+                .encodeAdditionalDataPacket(secret, rawData);
+        additionalDataPacket[0] = (byte) ~additionalDataPacket[0];
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> AdditionalDataEncoder
+                                .decodeAdditionalDataPacket(secret, additionalDataPacket));
+
+        assertThat(exception)
+                .hasMessageThat()
+                .contains("Verify HMAC failed, could be incorrect key or packet.");
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AesCtrMultipleBlockEncryptionTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AesCtrMultipleBlockEncryptionTest.java
new file mode 100644
index 0000000..7d86037
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AesCtrMultipleBlockEncryptionTest.java
@@ -0,0 +1,214 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.NONCE_SIZE;
+import static com.android.server.nearby.common.bluetooth.fastpair.AesEcbSingleBlockEncryption.KEY_LENGTH;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+/** Unit tests for {@link AesCtrMultpleBlockEncryption}. */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AesCtrMultipleBlockEncryptionTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void decryptEncryptedData_nonBlockSizeAligned_mustEqualToPlaintext() throws Exception {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        byte[] plaintext = "Someone's Google Headphone 2019".getBytes(UTF_8); // The length is 31.
+
+        byte[] encrypted = AesCtrMultipleBlockEncryption.encrypt(secret, plaintext);
+        byte[] decrypted = AesCtrMultipleBlockEncryption.decrypt(secret, encrypted);
+
+        assertThat(decrypted).isEqualTo(plaintext);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void decryptEncryptedData_blockSizeAligned_mustEqualToPlaintext() throws Exception {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        byte[] plaintext =
+                // The length is 32.
+                base16().decode("0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF");
+
+        byte[] encrypted = AesCtrMultipleBlockEncryption.encrypt(secret, plaintext);
+        byte[] decrypted = AesCtrMultipleBlockEncryption.decrypt(secret, encrypted);
+
+        assertThat(decrypted).isEqualTo(plaintext);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void generateNonceTwice_mustBeDifferent() {
+        byte[] nonce1 = AesCtrMultipleBlockEncryption.generateNonce();
+        byte[] nonce2 = AesCtrMultipleBlockEncryption.generateNonce();
+
+        assertThat(nonce1).isNotEqualTo(nonce2);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void encryptedSamePlaintext_mustBeDifferentEncryptedResult() throws Exception {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        byte[] plaintext = "Someone's Google Headphone 2019".getBytes(UTF_8);
+
+        byte[] encrypted1 = AesCtrMultipleBlockEncryption.encrypt(secret, plaintext);
+        byte[] encrypted2 = AesCtrMultipleBlockEncryption.encrypt(secret, plaintext);
+
+        assertThat(encrypted1).isNotEqualTo(encrypted2);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void encryptData_mustBeDifferentToUnencrypted() throws Exception {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        byte[] plaintext = "Someone's Google Headphone 2019".getBytes(UTF_8);
+
+        byte[] encrypted = AesCtrMultipleBlockEncryption.encrypt(secret, plaintext);
+
+        assertThat(encrypted).isNotEqualTo(plaintext);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectKeySizeToEncrypt_mustThrowException() {
+        byte[] secret = new byte[KEY_LENGTH + 1];
+        byte[] plaintext = "Someone's Google Headphone 2019".getBytes(UTF_8);
+
+        IllegalArgumentException exception =
+                assertThrows(
+                        IllegalArgumentException.class,
+                        () -> AesCtrMultipleBlockEncryption.encrypt(secret, plaintext));
+
+        assertThat(exception)
+                .hasMessageThat()
+                .contains("Incorrect key length for encryption, only supports 16-byte AES Key.");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectKeySizeToDecrypt_mustThrowException() {
+        byte[] secret = new byte[KEY_LENGTH - 1];
+        byte[] plaintext = "Someone's Google Headphone 2019".getBytes(UTF_8);
+
+        IllegalArgumentException exception =
+                assertThrows(
+                        IllegalArgumentException.class,
+                        () -> AesCtrMultipleBlockEncryption.decrypt(secret, plaintext));
+
+        assertThat(exception)
+                .hasMessageThat()
+                .contains("Incorrect key length for encryption, only supports 16-byte AES Key.");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectDataSizeToDecrypt_mustThrowException()
+            throws GeneralSecurityException {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        byte[] plaintext = "Someone's Google Headphone 2019".getBytes(UTF_8);
+
+        byte[] encryptedData = Arrays.copyOfRange(
+                AesCtrMultipleBlockEncryption.encrypt(secret, plaintext), /*from=*/ 0, NONCE_SIZE);
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> AesCtrMultipleBlockEncryption.decrypt(secret, encryptedData));
+
+        assertThat(exception).hasMessageThat().contains("Incorrect data length");
+    }
+
+    // Add some random tests that for a certain amount of random plaintext of random length to prove
+    // our encryption/decryption is correct. This is suggested by security team.
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void decryptEncryptedRandomDataForCertainAmount_mustEqualToOriginalData()
+            throws Exception {
+        SecureRandom random = new SecureRandom();
+        for (int i = 0; i < 1000; i++) {
+            byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+            int dataLength = random.nextInt(64) + 1;
+            byte[] data = new byte[dataLength];
+            random.nextBytes(data);
+
+            byte[] encrypted = AesCtrMultipleBlockEncryption.encrypt(secret, data);
+            byte[] decrypted = AesCtrMultipleBlockEncryption.decrypt(secret, encrypted);
+
+            assertThat(decrypted).isEqualTo(data);
+        }
+    }
+
+    // Add some random tests that for a certain amount of random plaintext of random length to prove
+    // our encryption is correct. This is suggested by security team.
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void twoDistinctEncryptionOnSameRandomData_mustBeDifferentResult() throws Exception {
+        SecureRandom random = new SecureRandom();
+        for (int i = 0; i < 1000; i++) {
+            byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+            int dataLength = random.nextInt(64) + 1;
+            byte[] data = new byte[dataLength];
+            random.nextBytes(data);
+
+            byte[] encrypted1 = AesCtrMultipleBlockEncryption.encrypt(secret, data);
+            byte[] encrypted2 = AesCtrMultipleBlockEncryption.encrypt(secret, data);
+
+            assertThat(encrypted1).isNotEqualTo(encrypted2);
+        }
+    }
+
+    // Adds this test example on spec. Also we can easily change the parameters(e.g. secret, data,
+    // nonce) to clarify test results with partners.
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputTestExampleToEncrypt_getCorrectResult() throws GeneralSecurityException {
+        byte[] secret = base16().decode("0123456789ABCDEF0123456789ABCDEF");
+        byte[] nonce = base16().decode("0001020304050607");
+
+        // "Someone's Google Headphone".getBytes(UTF_8) is
+        // base16().decode("536F6D656F6E65277320476F6F676C65204865616470686F6E65");
+        byte[] encryptedData =
+                AesCtrMultipleBlockEncryption.doAesCtr(
+                        secret,
+                        "Someone's Google Headphone".getBytes(UTF_8),
+                        nonce);
+
+        assertThat(encryptedData)
+                .isEqualTo(base16().decode("EE4A2483738052E44E9B2A145E5DDFAA44B9E5536AF438E1E5C6"));
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AesEcbSingleBlockEncryptionTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AesEcbSingleBlockEncryptionTest.java
new file mode 100644
index 0000000..eccbd01
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/AesEcbSingleBlockEncryptionTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.primitives.Bytes;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Unit tests for {@link AesEcbSingleBlockEncryption}. */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AesEcbSingleBlockEncryptionTest {
+
+    private static final byte[] PLAINTEXT = base16().decode("F30F4E786C59A7BBF3873B5A49BA97EA");
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void encryptDecryptSuccessful() throws Exception {
+        byte[] secret = AesEcbSingleBlockEncryption.generateKey();
+        byte[] encrypted = AesEcbSingleBlockEncryption.encrypt(secret, PLAINTEXT);
+        assertThat(encrypted).isNotEqualTo(PLAINTEXT);
+        byte[] decrypted = AesEcbSingleBlockEncryption.decrypt(secret, encrypted);
+        assertThat(decrypted).isEqualTo(PLAINTEXT);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void encryptionSizeLimitationEnforced() throws Exception {
+        byte[] secret = AesEcbSingleBlockEncryption.generateKey();
+        byte[] largePacket = Bytes.concat(PLAINTEXT, PLAINTEXT);
+        AesEcbSingleBlockEncryption.encrypt(secret, largePacket);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void decryptionSizeLimitationEnforced() throws Exception {
+        byte[] secret = AesEcbSingleBlockEncryption.generateKey();
+        byte[] largePacket = Bytes.concat(PLAINTEXT, PLAINTEXT);
+        AesEcbSingleBlockEncryption.decrypt(secret, largePacket);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAddressTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAddressTest.java
new file mode 100644
index 0000000..6c95558
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAddressTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.bluetooth.BluetoothAdapter;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Unit tests for {@link BluetoothAddress}. */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BluetoothAddressTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void maskBluetoothAddress_whenInputIsNull() {
+        assertThat(BluetoothAddress.maskBluetoothAddress(null)).isEqualTo("");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void maskBluetoothAddress_whenInputStringNotMatchFormat() {
+        assertThat(BluetoothAddress.maskBluetoothAddress("AA:BB:CC")).isEqualTo("AA:BB:CC");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void maskBluetoothAddress_whenInputStringMatchFormat() {
+        assertThat(BluetoothAddress.maskBluetoothAddress("AA:BB:CC:DD:EE:FF"))
+                .isEqualTo("XX:XX:XX:XX:EE:FF");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void maskBluetoothAddress_whenInputStringContainLowerCaseMatchFormat() {
+        assertThat(BluetoothAddress.maskBluetoothAddress("Aa:Bb:cC:dD:eE:Ff"))
+                .isEqualTo("XX:XX:XX:XX:EE:FF");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void maskBluetoothAddress_whenInputBluetoothDevice() {
+        assertThat(
+                BluetoothAddress.maskBluetoothAddress(
+                        BluetoothAdapter.getDefaultAdapter().getRemoteDevice("FF:EE:DD:CC:BB:AA")))
+                .isEqualTo("XX:XX:XX:XX:BB:AA");
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAudioPairerTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAudioPairerTest.java
new file mode 100644
index 0000000..0a56f2f
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothAudioPairerTest.java
@@ -0,0 +1,198 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.google.common.collect.Iterables;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+
+/** Unit tests for {@link BluetoothAudioPairer}. */
+@Presubmit
+@SmallTest
+public class BluetoothAudioPairerTest extends TestCase {
+
+    private static final byte[] SECRET = new byte[]{3, 0};
+    private static final boolean PRIVATE_INITIAL_PAIRING = false;
+    private static final String EVENT_NAME = "EVENT_NAME";
+    private static final BluetoothDevice BLUETOOTH_DEVICE = BluetoothAdapter.getDefaultAdapter()
+            .getRemoteDevice("11:22:33:44:55:66");
+    private static final int BOND_TIMEOUT_SECONDS = 1;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        initMocks(this);
+        BluetoothAudioPairer.enableTestMode();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testKeyBasedPairingInfoConstructor() {
+        assertThat(new BluetoothAudioPairer.KeyBasedPairingInfo(
+                SECRET,
+                null /* GattConnectionManager */,
+                PRIVATE_INITIAL_PAIRING)).isNotNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothAudioPairerConstructor() {
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        try {
+            assertThat(new BluetoothAudioPairer(
+                    context,
+                    BLUETOOTH_DEVICE,
+                    Preferences.builder().build(),
+                    new EventLoggerWrapper(new TestEventLogger()),
+                    null /* KeyBasePairingInfo */,
+                    null /*PasskeyConfirmationHandler */,
+                    new TimingLogger(EVENT_NAME, Preferences.builder().build()))).isNotNull();
+        } catch (PairingException e) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothAudioPairerUnpairNoCrash() {
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        try {
+            new BluetoothAudioPairer(
+                    context,
+                    BLUETOOTH_DEVICE,
+                    Preferences.builder().build(),
+                    new EventLoggerWrapper(new TestEventLogger()),
+                    null /* KeyBasePairingInfo */,
+                    null /*PasskeyConfirmationHandler */,
+                    new TimingLogger(EVENT_NAME, Preferences.builder().build())).unpair();
+        } catch (PairingException | InterruptedException | ExecutionException
+                | TimeoutException e) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothAudioPairerPairNoCrash() {
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        try {
+            new BluetoothAudioPairer(
+                    context,
+                    BLUETOOTH_DEVICE,
+                    Preferences.builder().setCreateBondTimeoutSeconds(BOND_TIMEOUT_SECONDS).build(),
+                    new EventLoggerWrapper(new TestEventLogger()),
+                    null /* KeyBasePairingInfo */,
+                    null /*PasskeyConfirmationHandler */,
+                    new TimingLogger(EVENT_NAME, Preferences.builder().build())).pair();
+        } catch (PairingException | InterruptedException | ExecutionException
+                | TimeoutException e) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothAudioPairerConnectNoCrash() {
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        try {
+            new BluetoothAudioPairer(
+                    context,
+                    BLUETOOTH_DEVICE,
+                    Preferences.builder().setCreateBondTimeoutSeconds(BOND_TIMEOUT_SECONDS).build(),
+                    new EventLoggerWrapper(new TestEventLogger()),
+                    null /* KeyBasePairingInfo */,
+                    null /*PasskeyConfirmationHandler */,
+                    new TimingLogger(EVENT_NAME, Preferences.builder().build()))
+                    .connect(Constants.A2DP_SINK_SERVICE_UUID, true /* enable pairing behavior */);
+        } catch (PairingException | InterruptedException | ExecutionException
+                | TimeoutException | ReflectionException e) {
+        }
+    }
+
+    static class TestEventLogger implements EventLogger {
+
+        private List<Item> mLogs = new ArrayList<>();
+
+        @Override
+        public void logEventSucceeded(Event event) {
+            mLogs.add(new Item(event));
+        }
+
+        @Override
+        public void logEventFailed(Event event, Exception e) {
+            mLogs.add(new ItemFailed(event, e));
+        }
+
+        List<Item> getErrorLogs() {
+            return mLogs.stream().filter(item -> item instanceof ItemFailed)
+                    .collect(Collectors.toList());
+        }
+
+        List<Item> getLogs() {
+            return mLogs;
+        }
+
+        List<Item> getLast() {
+            return mLogs.subList(mLogs.size() - 1, mLogs.size());
+        }
+
+        BluetoothDevice getDevice() {
+            return Iterables.getLast(mLogs).mEvent.getBluetoothDevice();
+        }
+
+        public static class Item {
+
+            final Event mEvent;
+
+            Item(Event event) {
+                this.mEvent = event;
+            }
+
+            @Override
+            public String toString() {
+                return "Item{" + "event=" + mEvent + '}';
+            }
+        }
+
+        public static class ItemFailed extends Item {
+
+            final Exception mException;
+
+            ItemFailed(Event event, Exception e) {
+                super(event);
+                this.mException = e;
+            }
+
+            @Override
+            public String toString() {
+                return "ItemFailed{" + "event=" + mEvent + ", exception=" + mException + '}';
+            }
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothUuidsTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothUuidsTest.java
new file mode 100644
index 0000000..fa977ed
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/BluetoothUuidsTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.UUID;
+
+/** Unit tests for {@link BluetoothUuids}. */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BluetoothUuidsTest {
+
+    // According to {@code android.bluetooth.BluetoothUuid}
+    private static final short A2DP_SINK_SHORT_UUID = (short) 0x110B;
+    private static final UUID A2DP_SINK_CHARACTERISTICS =
+            UUID.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+
+    // According to {go/fastpair-128bit-gatt}, the short uuid locates at the 3rd and 4th bytes based
+    // on the Fast Pair custom GATT characteristics 128-bit UUIDs base -
+    // "FE2C0000-8366-4814-8EB0-01DE32100BEA".
+    private static final short CUSTOM_SHORT_UUID = (short) 0x9487;
+    private static final UUID CUSTOM_CHARACTERISTICS =
+            UUID.fromString("FE2C9487-8366-4814-8EB0-01DE32100BEA");
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void get16BitUuid() {
+        assertThat(BluetoothUuids.get16BitUuid(A2DP_SINK_CHARACTERISTICS))
+                .isEqualTo(A2DP_SINK_SHORT_UUID);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void is16BitUuid() {
+        assertThat(BluetoothUuids.is16BitUuid(A2DP_SINK_CHARACTERISTICS)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void to128BitUuid() {
+        assertThat(BluetoothUuids.to128BitUuid(A2DP_SINK_SHORT_UUID))
+                .isEqualTo(A2DP_SINK_CHARACTERISTICS);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void toFastPair128BitUuid() {
+        assertThat(BluetoothUuids.toFastPair128BitUuid(CUSTOM_SHORT_UUID))
+                .isEqualTo(CUSTOM_CHARACTERISTICS);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/ConstantsTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/ConstantsTest.java
new file mode 100644
index 0000000..f7ffa24
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/ConstantsTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothUuids.to128BitUuid;
+import static com.android.server.nearby.common.bluetooth.fastpair.BluetoothUuids.toFastPair128BitUuid;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.bluetooth.BluetoothGattCharacteristic;
+
+import androidx.test.filters.SdkSuppress;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.fastpair.Constants.FastPairService.KeyBasedPairingCharacteristic;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mock;
+
+import java.util.UUID;
+
+/**
+ * Unit tests for {@link Constants}.
+ */
+public class ConstantsTest extends TestCase {
+
+    @Mock
+    private BluetoothGattConnection mMockGattConnection;
+
+    private static final UUID OLD_KEY_BASE_PAIRING_CHARACTERISTICS = to128BitUuid((short) 0x1234);
+
+    private static final UUID NEW_KEY_BASE_PAIRING_CHARACTERISTICS =
+            toFastPair128BitUuid((short) 0x1234);
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        initMocks(this);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getId_whenSupportNewCharacteristics() throws BluetoothException {
+        when(mMockGattConnection.getCharacteristic(any(UUID.class), any(UUID.class)))
+                .thenReturn(new BluetoothGattCharacteristic(NEW_KEY_BASE_PAIRING_CHARACTERISTICS, 0,
+                        0));
+
+        assertThat(KeyBasedPairingCharacteristic.getId(mMockGattConnection))
+                .isEqualTo(NEW_KEY_BASE_PAIRING_CHARACTERISTICS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getId_whenNotSupportNewCharacteristics() throws BluetoothException {
+        // {@link BluetoothGattConnection#getCharacteristic(UUID, UUID)} throws {@link
+        // BluetoothException} if the characteristic not found .
+        when(mMockGattConnection.getCharacteristic(any(UUID.class), any(UUID.class)))
+                .thenThrow(new BluetoothException(""));
+
+        assertThat(KeyBasedPairingCharacteristic.getId(mMockGattConnection))
+                .isEqualTo(OLD_KEY_BASE_PAIRING_CHARACTERISTICS);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/EllipticCurveDiffieHellmanExchangeTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/EllipticCurveDiffieHellmanExchangeTest.java
new file mode 100644
index 0000000..3719783
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/EllipticCurveDiffieHellmanExchangeTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.io.BaseEncoding.base64;
+import static com.google.common.primitives.Bytes.concat;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for {@link EllipticCurveDiffieHellmanExchange}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EllipticCurveDiffieHellmanExchangeTest {
+
+    public static final byte[] ANTI_SPOOF_PUBLIC_KEY = base64().decode(
+            "d2JTfvfdS6u7LmGfMOmco3C7ra3lW1k17AOly0LrBydDZURacfTYIMmo5K1ejfD9e8b6qHs"
+                    + "DTNzselhifi10kQ==");
+    public static final byte[] ANTI_SPOOF_PRIVATE_KEY =
+            base64().decode("Rn9GbLRPQTFc2O7WFVGkydzcUS9Tuj7R9rLh6EpLtuU=");
+
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void generateCommonKey() throws Exception {
+        EllipticCurveDiffieHellmanExchange bob = EllipticCurveDiffieHellmanExchange.create();
+        EllipticCurveDiffieHellmanExchange alice = EllipticCurveDiffieHellmanExchange.create();
+
+        assertThat(bob.getPublicKey()).isNotEqualTo(alice.getPublicKey());
+        assertThat(bob.getPrivateKey()).isNotEqualTo(alice.getPrivateKey());
+
+        assertThat(bob.generateSecret(alice.getPublicKey()))
+                .isEqualTo(alice.generateSecret(bob.getPublicKey()));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void generateCommonKey_withExistingPrivateKey() throws Exception {
+        EllipticCurveDiffieHellmanExchange bob = EllipticCurveDiffieHellmanExchange.create();
+        EllipticCurveDiffieHellmanExchange alice =
+                EllipticCurveDiffieHellmanExchange.create(ANTI_SPOOF_PRIVATE_KEY);
+
+        assertThat(alice.generateSecret(bob.getPublicKey()))
+                .isEqualTo(bob.generateSecret(ANTI_SPOOF_PUBLIC_KEY));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void generateCommonKey_soundcoreAntiSpoofingKey_generatedTooShort() throws Exception {
+        // This soundcore device has a public key that was generated which starts with 0x0. This was
+        // stripped out in our database, but this test confirms that adding that byte back fixes the
+        // issue and allows the generated secrets to match each other.
+        byte[] soundCorePublicKey = concat(new byte[]{0}, base64().decode(
+                "EYapuIsyw/nwHAdMxr12FCtAi4gY3EtuW06JuKDg4SA76IoIDVeol2vsGKy0Ea2Z00"
+                        + "ArOTiBDsk0L+4Xo9AA"));
+        byte[] soundCorePrivateKey = base64()
+                .decode("lW5idsrfX7cBC8kO/kKn3w3GXirqt9KnJoqXUcOMhjM=");
+        EllipticCurveDiffieHellmanExchange bob = EllipticCurveDiffieHellmanExchange.create();
+        EllipticCurveDiffieHellmanExchange alice =
+                EllipticCurveDiffieHellmanExchange.create(soundCorePrivateKey);
+
+        assertThat(alice.generateSecret(bob.getPublicKey()))
+                .isEqualTo(bob.generateSecret(soundCorePublicKey));
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/EventTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/EventTest.java
new file mode 100644
index 0000000..28e925f
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/EventTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.android.server.nearby.intdefs.NearbyEventIntDefs.EventCode;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for {@link Event}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EventTest {
+
+    private static final String EXCEPTION_MESSAGE = "Test exception";
+    private static final long TIMESTAMP = 1234L;
+    private static final @EventCode int EVENT_CODE = EventCode.CREATE_BOND;
+    private static final BluetoothDevice BLUETOOTH_DEVICE = BluetoothAdapter.getDefaultAdapter()
+            .getRemoteDevice("11:22:33:44:55:66");
+    private static final Short PROFILE = (short) 1;
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void createAndReadFromParcel() {
+        Event event =
+                Event.builder()
+                        .setException(new Exception(EXCEPTION_MESSAGE))
+                        .setTimestamp(TIMESTAMP)
+                        .setEventCode(EVENT_CODE)
+                        .setBluetoothDevice(BLUETOOTH_DEVICE)
+                        .setProfile(PROFILE)
+                        .build();
+
+        Parcel parcel = Parcel.obtain();
+        event.writeToParcel(parcel, event.describeContents());
+        parcel.setDataPosition(0);
+        Event result = Event.CREATOR.createFromParcel(parcel);
+
+        assertThat(result.getException()).hasMessageThat()
+                .isEqualTo(event.getException().getMessage());
+        assertThat(result.getTimestamp()).isEqualTo(event.getTimestamp());
+        assertThat(result.getEventCode()).isEqualTo(event.getEventCode());
+        assertThat(result.getBluetoothDevice()).isEqualTo(event.getBluetoothDevice());
+        assertThat(result.getProfile()).isEqualTo(event.getProfile());
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnectionTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnectionTest.java
new file mode 100644
index 0000000..a103a72
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnectionTest.java
@@ -0,0 +1,370 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED;
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST;
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.GATT_ERROR_CODE_TIMEOUT;
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.appendMoreErrorCode;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.Mockito.doNothing;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.BluetoothOperationTimeoutException;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.protobuf.ByteString;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+
+/**
+ * Unit tests for {@link FastPairDualConnection}.
+ */
+@Presubmit
+@SmallTest
+public class FastPairDualConnectionTest extends TestCase {
+
+    private static final String BLE_ADDRESS = "00:11:22:33:FF:EE";
+    private static final String MASKED_BLE_ADDRESS = "MASKED_BLE_ADDRESS";
+    private static final short[] PROFILES = {Constants.A2DP_SINK_SERVICE_UUID};
+    private static final int NUM_CONNECTION_ATTEMPTS = 1;
+    private static final boolean ENABLE_PAIRING_BEHAVIOR = true;
+    private static final BluetoothDevice BLUETOOTH_DEVICE = BluetoothAdapter.getDefaultAdapter()
+            .getRemoteDevice("11:22:33:44:55:66");
+    private static final String DEVICE_NAME = "DEVICE_NAME";
+    private static final byte[] ACCOUNT_KEY = new byte[]{1, 3};
+    private static final byte[] HASH_VALUE = new byte[]{7};
+
+    private TestEventLogger mEventLogger;
+    @Mock private TimingLogger mTimingLogger;
+    @Mock private BluetoothAudioPairer mBluetoothAudioPairer;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        BluetoothAudioPairer.enableTestMode();
+        FastPairDualConnection.enableTestMode();
+        MockitoAnnotations.initMocks(this);
+
+        doNothing().when(mBluetoothAudioPairer).connect(anyShort(), anyBoolean());
+        mEventLogger = new TestEventLogger();
+    }
+
+    private FastPairDualConnection newFastPairDualConnection(
+            String bleAddress, Preferences.Builder prefsBuilder) {
+        return new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                bleAddress,
+                prefsBuilder.build(),
+                mEventLogger,
+                mTimingLogger);
+    }
+
+    private FastPairDualConnection newFastPairDualConnection2(
+            String bleAddress, Preferences.Builder prefsBuilder) {
+        return new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                bleAddress,
+                prefsBuilder.build(),
+                mEventLogger);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testFastPairDualConnectionConstructor() {
+        assertThat(newFastPairDualConnection(BLE_ADDRESS, Preferences.builder())).isNotNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testFastPairDualConnectionConstructor2() {
+        assertThat(newFastPairDualConnection2(BLE_ADDRESS, Preferences.builder())).isNotNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testAttemptConnectProfiles() {
+        try {
+            new FastPairDualConnection(
+                    ApplicationProvider.getApplicationContext(),
+                    BLE_ADDRESS,
+                    Preferences.builder().build(),
+                    mEventLogger,
+                    mTimingLogger)
+                    .attemptConnectProfiles(
+                            mBluetoothAudioPairer,
+                            MASKED_BLE_ADDRESS,
+                            PROFILES,
+                            NUM_CONNECTION_ATTEMPTS,
+                            ENABLE_PAIRING_BEHAVIOR);
+        } catch (PairingException e) {
+            // Mocked pair doesn't throw Pairing Exception.
+        }
+    }
+
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testAppendMoreErrorCode_gattError() {
+        assertThat(
+                appendMoreErrorCode(
+                        GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED,
+                        new BluetoothGattException("Test", 133)))
+                .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED + 133);
+        assertThat(
+                appendMoreErrorCode(
+                        GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED,
+                        new BluetoothGattException("Test", 257)))
+                .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED + 257);
+        assertThat(
+                appendMoreErrorCode(
+                        GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED, new BluetoothException("Test")))
+                .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED);
+        assertThat(
+                appendMoreErrorCode(
+                        GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED,
+                        new BluetoothOperationTimeoutException("Test")))
+                .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED + GATT_ERROR_CODE_TIMEOUT);
+        assertThat(
+                appendMoreErrorCode(
+                        GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST,
+                        new BluetoothGattException("Test", 41)))
+                .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST + 41);
+        assertThat(
+                appendMoreErrorCode(
+                        GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST,
+                        new BluetoothGattException("Test", 788)))
+                .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST + 788);
+        assertThat(
+                appendMoreErrorCode(
+                        GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST, new BluetoothException("Test")))
+                .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST);
+        assertThat(
+                appendMoreErrorCode(
+                        GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST,
+                        new BluetoothOperationTimeoutException("Test")))
+                .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST + GATT_ERROR_CODE_TIMEOUT);
+        assertThat(appendMoreErrorCode(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST, /* cause= */ null))
+                .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testUnpairNotCrash() {
+        try {
+            new FastPairDualConnection(
+                    ApplicationProvider.getApplicationContext(),
+                    BLE_ADDRESS,
+                    Preferences.builder().build(),
+                    mEventLogger,
+                    mTimingLogger).unpair(BLUETOOTH_DEVICE);
+        } catch (ExecutionException | InterruptedException | ReflectionException
+                | TimeoutException | PairingException e) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSetFastPairHistory() {
+        new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                BLE_ADDRESS,
+                Preferences.builder().build(),
+                mEventLogger,
+                mTimingLogger).setFastPairHistory(ImmutableList.of());
+    }
+
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSetGetProviderDeviceName() {
+        FastPairDualConnection connection = new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                BLE_ADDRESS,
+                Preferences.builder().build(),
+                mEventLogger,
+                mTimingLogger);
+        connection.setProviderDeviceName(DEVICE_NAME);
+        connection.getProviderDeviceName();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGetExistingAccountKey() {
+        FastPairDualConnection connection = new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                BLE_ADDRESS,
+                Preferences.builder().build(),
+                mEventLogger,
+                mTimingLogger);
+        connection.getExistingAccountKey();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testPair() {
+        FastPairDualConnection connection = new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                BLE_ADDRESS,
+                Preferences.builder().setNumSdpAttempts(0)
+                        .setLogPairWithCachedModelId(false).build(),
+                mEventLogger,
+                mTimingLogger);
+        try {
+            connection.pair();
+        } catch (BluetoothException | InterruptedException | ReflectionException
+                | ExecutionException | TimeoutException | PairingException e) {
+        }
+    }
+
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGetPublicAddress() {
+        FastPairDualConnection connection = new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                BLE_ADDRESS,
+                Preferences.builder().setNumSdpAttempts(0)
+                        .setLogPairWithCachedModelId(false).build(),
+                mEventLogger,
+                mTimingLogger);
+        connection.getPublicAddress();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testShouldWriteAccountKeyForExistingCase() {
+        FastPairDualConnection connection = new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                BLE_ADDRESS,
+                Preferences.builder().setNumSdpAttempts(0)
+                        .setLogPairWithCachedModelId(false).build(),
+                mEventLogger,
+                mTimingLogger);
+        connection.shouldWriteAccountKeyForExistingCase(ACCOUNT_KEY);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testReadFirmwareVersion() {
+        FastPairDualConnection connection = new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                BLE_ADDRESS,
+                Preferences.builder().setNumSdpAttempts(0)
+                        .setLogPairWithCachedModelId(false).build(),
+                mEventLogger,
+                mTimingLogger);
+        try {
+            connection.readFirmwareVersion();
+        } catch (BluetoothException | InterruptedException | ExecutionException
+                | TimeoutException e) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHistoryItem() {
+        FastPairDualConnection connection = new FastPairDualConnection(
+                ApplicationProvider.getApplicationContext(),
+                BLE_ADDRESS,
+                Preferences.builder().setNumSdpAttempts(0)
+                        .setLogPairWithCachedModelId(false).build(),
+                mEventLogger,
+                mTimingLogger);
+        ImmutableList.Builder<FastPairHistoryItem> historyBuilder = ImmutableList.builder();
+        FastPairHistoryItem historyItem1 =
+                FastPairHistoryItem.create(
+                        ByteString.copyFrom(ACCOUNT_KEY), ByteString.copyFrom(HASH_VALUE));
+        historyBuilder.add(historyItem1);
+
+        connection.setFastPairHistory(historyBuilder.build());
+        assertThat(connection.mPairedHistoryFinder.isInPairedHistory("11:22:33:44:55:88"))
+                .isFalse();
+    }
+
+    static class TestEventLogger implements EventLogger {
+
+        private List<Item> mLogs = new ArrayList<>();
+
+        @Override
+        public void logEventSucceeded(Event event) {
+            mLogs.add(new Item(event));
+        }
+
+        @Override
+        public void logEventFailed(Event event, Exception e) {
+            mLogs.add(new ItemFailed(event, e));
+        }
+
+        List<Item> getErrorLogs() {
+            return mLogs.stream().filter(item -> item instanceof ItemFailed)
+                    .collect(Collectors.toList());
+        }
+
+        List<Item> getLogs() {
+            return mLogs;
+        }
+
+        List<Item> getLast() {
+            return mLogs.subList(mLogs.size() - 1, mLogs.size());
+        }
+
+        BluetoothDevice getDevice() {
+            return Iterables.getLast(mLogs).mEvent.getBluetoothDevice();
+        }
+
+        public static class Item {
+
+            final Event mEvent;
+
+            Item(Event event) {
+                this.mEvent = event;
+            }
+
+            @Override
+            public String toString() {
+                return "Item{" + "event=" + mEvent + '}';
+            }
+        }
+
+        public static class ItemFailed extends Item {
+
+            final Exception mException;
+
+            ItemFailed(Event event, Exception e) {
+                super(event);
+                this.mException = e;
+            }
+
+            @Override
+            public String toString() {
+                return "ItemFailed{" + "event=" + mEvent + ", exception=" + mException + '}';
+            }
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/FastPairHistoryItemTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/FastPairHistoryItemTest.java
new file mode 100644
index 0000000..b47fd89
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/FastPairHistoryItemTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.primitives.Bytes.concat;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.hash.Hashing;
+import com.google.protobuf.ByteString;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for {@link FastPairHistoryItem}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class FastPairHistoryItemTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputMatchedPublicAddress_isMatchedReturnTrue() {
+        final byte[] accountKey = base16().decode("0123456789ABCDEF");
+        final byte[] publicAddress = BluetoothAddress.decode("11:22:33:44:55:66");
+        final byte[] hashValue =
+                Hashing.sha256().hashBytes(concat(accountKey, publicAddress)).asBytes();
+
+        FastPairHistoryItem historyItem =
+                FastPairHistoryItem
+                        .create(ByteString.copyFrom(accountKey), ByteString.copyFrom(hashValue));
+
+        assertThat(historyItem.isMatched(publicAddress)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputNotMatchedPublicAddress_isMatchedReturnFalse() {
+        final byte[] accountKey = base16().decode("0123456789ABCDEF");
+        final byte[] publicAddress1 = BluetoothAddress.decode("11:22:33:44:55:66");
+        final byte[] publicAddress2 = BluetoothAddress.decode("11:22:33:44:55:77");
+        final byte[] hashValue =
+                Hashing.sha256().hashBytes(concat(accountKey, publicAddress1)).asBytes();
+
+        FastPairHistoryItem historyItem =
+                FastPairHistoryItem
+                        .create(ByteString.copyFrom(accountKey), ByteString.copyFrom(hashValue));
+
+        assertThat(historyItem.isMatched(publicAddress2)).isFalse();
+    }
+}
+
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/GattConnectionManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/GattConnectionManagerTest.java
new file mode 100644
index 0000000..2f80a30
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/GattConnectionManagerTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.Nullable;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothAdapter;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.BluetoothOperationTimeoutException;
+
+import com.google.common.collect.ImmutableSet;
+
+import junit.framework.TestCase;
+
+import java.time.Duration;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Unit tests for {@link GattConnectionManager}.
+ */
+@Presubmit
+@SmallTest
+public class GattConnectionManagerTest extends TestCase {
+
+    private static final String FAST_PAIR_ADDRESS = "BB:BB:BB:BB:BB:1E";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        GattConnectionManager.enableTestMode();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGattConnectionManagerConstructor() throws Exception {
+        GattConnectionManager manager = createManager(Preferences.builder());
+        try {
+            manager.getConnection();
+        } catch (ExecutionException e) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testIsNoRetryError() {
+        Preferences preferences =
+                Preferences.builder()
+                        .setGattConnectionAndSecretHandshakeNoRetryGattError(
+                                ImmutableSet.of(257, 999))
+                        .build();
+
+        assertThat(
+                GattConnectionManager.isNoRetryError(
+                        preferences, new BluetoothGattException("Test", 133)))
+                .isFalse();
+        assertThat(
+                GattConnectionManager.isNoRetryError(
+                        preferences, new BluetoothGattException("Test", 257)))
+                .isTrue();
+        assertThat(
+                GattConnectionManager.isNoRetryError(
+                        preferences, new BluetoothGattException("Test", 999)))
+                .isTrue();
+        assertThat(GattConnectionManager.isNoRetryError(
+                preferences, new BluetoothException("Test")))
+                .isFalse();
+        assertThat(
+                GattConnectionManager.isNoRetryError(
+                        preferences, new BluetoothOperationTimeoutException("Test")))
+                .isFalse();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGetTimeoutNotOverShortRetryMaxSpentTimeGetShort() {
+        Preferences preferences = Preferences.builder().build();
+
+        assertThat(
+                createManager(Preferences.builder(), () -> {})
+                        .getTimeoutMs(
+                                preferences.getGattConnectShortTimeoutRetryMaxSpentTimeMs() - 1))
+                .isEqualTo(preferences.getGattConnectShortTimeoutMs());
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGetTimeoutOverShortRetryMaxSpentTimeGetLong() {
+        Preferences preferences = Preferences.builder().build();
+
+        assertThat(
+                createManager(Preferences.builder(), () -> {})
+                        .getTimeoutMs(
+                                preferences.getGattConnectShortTimeoutRetryMaxSpentTimeMs() + 1))
+                .isEqualTo(preferences.getGattConnectLongTimeoutMs());
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGetTimeoutRetryNotEnabledGetOrigin() {
+        Preferences preferences = Preferences.builder().build();
+
+        assertThat(
+                createManager(
+                        Preferences.builder().setRetryGattConnectionAndSecretHandshake(false),
+                        () -> {})
+                        .getTimeoutMs(0))
+                .isEqualTo(Duration.ofSeconds(
+                        preferences.getGattConnectionTimeoutSeconds()).toMillis());
+    }
+
+    private GattConnectionManager createManager(Preferences.Builder prefs) {
+        return createManager(prefs, () -> {});
+    }
+
+    private GattConnectionManager createManager(
+            Preferences.Builder prefs, ToggleBluetoothTask toggleBluetooth) {
+        return createManager(prefs, toggleBluetooth,
+                /* fastPairSignalChecker= */ null);
+    }
+
+    private GattConnectionManager createManager(
+            Preferences.Builder prefs,
+            ToggleBluetoothTask toggleBluetooth,
+            @Nullable FastPairConnection.FastPairSignalChecker fastPairSignalChecker) {
+        return new GattConnectionManager(
+                ApplicationProvider.getApplicationContext(),
+                prefs.build(),
+                new EventLoggerWrapper(null),
+                BluetoothAdapter.getDefaultAdapter(),
+                toggleBluetooth,
+                FAST_PAIR_ADDRESS,
+                new TimingLogger("GattConnectionManager", prefs.build()),
+                fastPairSignalChecker,
+                /* setMtu= */ false);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/HeadsetPieceTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/HeadsetPieceTest.java
new file mode 100644
index 0000000..670b2ca
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/HeadsetPieceTest.java
@@ -0,0 +1,200 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for {@link HeadsetPiece}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class HeadsetPieceTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void parcelAndUnparcel() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().build();
+        Parcel expectedParcel = Parcel.obtain();
+        headsetPiece.writeToParcel(expectedParcel, 0);
+        expectedParcel.setDataPosition(0);
+
+        HeadsetPiece fromParcel = HeadsetPiece.CREATOR.createFromParcel(expectedParcel);
+
+        assertThat(fromParcel).isEqualTo(headsetPiece);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void parcelAndUnparcel_nullImageContentUri() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().setImageContentUri(null).build();
+        Parcel expectedParcel = Parcel.obtain();
+        headsetPiece.writeToParcel(expectedParcel, 0);
+        expectedParcel.setDataPosition(0);
+
+        HeadsetPiece fromParcel = HeadsetPiece.CREATOR.createFromParcel(expectedParcel);
+
+        assertThat(fromParcel).isEqualTo(headsetPiece);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void equals() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().build();
+
+        HeadsetPiece compareTo = createDefaultHeadset().build();
+
+        assertThat(headsetPiece).isEqualTo(compareTo);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void equals_nullImageContentUri() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().setImageContentUri(null).build();
+
+        HeadsetPiece compareTo = createDefaultHeadset().setImageContentUri(null).build();
+
+        assertThat(headsetPiece).isEqualTo(compareTo);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void notEquals_differentLowLevelThreshold() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().build();
+
+        HeadsetPiece compareTo = createDefaultHeadset().setLowLevelThreshold(1).build();
+
+        assertThat(headsetPiece).isNotEqualTo(compareTo);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void notEquals_differentBatteryLevel() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().build();
+
+        HeadsetPiece compareTo = createDefaultHeadset().setBatteryLevel(99).build();
+
+        assertThat(headsetPiece).isNotEqualTo(compareTo);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void notEquals_differentImageUrl() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().build();
+
+        HeadsetPiece compareTo =
+                createDefaultHeadset().setImageUrl("http://fake.image.path/different.png").build();
+
+        assertThat(headsetPiece).isNotEqualTo(compareTo);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void notEquals_differentChargingState() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().build();
+
+        HeadsetPiece compareTo = createDefaultHeadset().setCharging(false).build();
+
+        assertThat(headsetPiece).isNotEqualTo(compareTo);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void notEquals_differentImageContentUri() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().build();
+
+        HeadsetPiece compareTo =
+                createDefaultHeadset().setImageContentUri(Uri.parse("content://different.png"))
+                        .build();
+
+        assertThat(headsetPiece).isNotEqualTo(compareTo);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void notEquals_nullImageContentUri() {
+        HeadsetPiece headsetPiece = createDefaultHeadset().build();
+
+        HeadsetPiece compareTo = createDefaultHeadset().setImageContentUri(null).build();
+
+        assertThat(headsetPiece).isNotEqualTo(compareTo);
+    }
+
+    private static HeadsetPiece.Builder createDefaultHeadset() {
+        return HeadsetPiece.builder()
+                .setLowLevelThreshold(30)
+                .setBatteryLevel(18)
+                .setImageUrl("http://fake.image.path/image.png")
+                .setImageContentUri(Uri.parse("content://image.png"))
+                .setCharging(true);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void isLowBattery() {
+        HeadsetPiece headsetPiece =
+                HeadsetPiece.builder()
+                        .setLowLevelThreshold(30)
+                        .setBatteryLevel(18)
+                        .setImageUrl("http://fake.image.path/image.png")
+                        .setCharging(false)
+                        .build();
+
+        assertThat(headsetPiece.isBatteryLow()).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void isNotLowBattery() {
+        HeadsetPiece headsetPiece =
+                HeadsetPiece.builder()
+                        .setLowLevelThreshold(30)
+                        .setBatteryLevel(31)
+                        .setImageUrl("http://fake.image.path/image.png")
+                        .setCharging(false)
+                        .build();
+
+        assertThat(headsetPiece.isBatteryLow()).isFalse();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void isNotLowBattery_whileCharging() {
+        HeadsetPiece headsetPiece =
+                HeadsetPiece.builder()
+                        .setLowLevelThreshold(30)
+                        .setBatteryLevel(18)
+                        .setImageUrl("http://fake.image.path/image.png")
+                        .setCharging(true)
+                        .build();
+
+        assertThat(headsetPiece.isBatteryLow()).isFalse();
+    }
+}
+
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/HmacSha256Test.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/HmacSha256Test.java
new file mode 100644
index 0000000..8db3b97
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/HmacSha256Test.java
@@ -0,0 +1,153 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.KEY_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.HmacSha256.HMAC_SHA256_BLOCK_SIZE;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.primitives.Bytes.concat;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.base.Preconditions;
+import com.google.common.hash.Hashing;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Unit tests for {@link HmacSha256}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class HmacSha256Test {
+
+    private static final int EXTRACT_HMAC_SIZE = 8;
+    private static final byte OUTER_PADDING_BYTE = 0x5c;
+    private static final byte INNER_PADDING_BYTE = 0x36;
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void compareResultWithOurImplementation_mustBeIdentical()
+            throws GeneralSecurityException {
+        Random random = new Random(0xFE2C);
+
+        for (int i = 0; i < 1000; i++) {
+            byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+            // Avoid too small data size that may cause false alarm.
+            int dataLength = random.nextInt(64);
+            byte[] data = new byte[dataLength];
+            random.nextBytes(data);
+
+            assertThat(HmacSha256.build(secret, data)).isEqualTo(doHmacSha256(secret, data));
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectKeySizeToDecrypt_mustThrowException() {
+        byte[] secret = new byte[KEY_LENGTH - 1];
+        byte[] data = base16().decode("1234567890ABCDEF1234567890ABCDEF1234567890ABCD");
+
+        GeneralSecurityException exception =
+                assertThrows(GeneralSecurityException.class, () -> HmacSha256.build(secret, data));
+
+        assertThat(exception)
+                .hasMessageThat()
+                .contains("Incorrect key length, should be the AES-128 key.");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputTwoIdenticalArrays_compareTwoHmacMustReturnTrue() {
+        Random random = new Random(0x1237);
+        byte[] array1 = new byte[EXTRACT_HMAC_SIZE];
+        random.nextBytes(array1);
+        byte[] array2 = Arrays.copyOf(array1, array1.length);
+
+        assertThat(HmacSha256.compareTwoHMACs(array1, array2)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputTwoRandomArrays_compareTwoHmacMustReturnFalse() {
+        Random random = new Random(0xff);
+        byte[] array1 = new byte[EXTRACT_HMAC_SIZE];
+        random.nextBytes(array1);
+        byte[] array2 = new byte[EXTRACT_HMAC_SIZE];
+        random.nextBytes(array2);
+
+        assertThat(HmacSha256.compareTwoHMACs(array1, array2)).isFalse();
+    }
+
+    // HMAC-SHA256 may not be previously defined on Bluetooth platforms, so we explicitly create
+    // the code on test case. This will allow us to easily detect where partner implementation might
+    // have gone wrong or where our spec isn't clear enough.
+    static byte[] doHmacSha256(byte[] key, byte[] data) {
+
+        Preconditions.checkArgument(
+                key != null && key.length == KEY_LENGTH && data != null,
+                "Parameters can't be null.");
+
+        // Performs SHA256(concat((key ^ opad),SHA256(concat((key ^ ipad), data)))), where
+        // key is the given secret extended to 64 bytes by concat(secret, ZEROS).
+        // opad is 64 bytes outer padding, consisting of repeated bytes valued 0x5c.
+        // ipad is 64 bytes inner padding, consisting of repeated bytes valued 0x36.
+        byte[] keyIpad = new byte[HMAC_SHA256_BLOCK_SIZE];
+        byte[] keyOpad = new byte[HMAC_SHA256_BLOCK_SIZE];
+
+        for (int i = 0; i < KEY_LENGTH; i++) {
+            keyIpad[i] = (byte) (key[i] ^ INNER_PADDING_BYTE);
+            keyOpad[i] = (byte) (key[i] ^ OUTER_PADDING_BYTE);
+        }
+        Arrays.fill(keyIpad, KEY_LENGTH, HMAC_SHA256_BLOCK_SIZE, INNER_PADDING_BYTE);
+        Arrays.fill(keyOpad, KEY_LENGTH, HMAC_SHA256_BLOCK_SIZE, OUTER_PADDING_BYTE);
+
+        byte[] innerSha256Result = Hashing.sha256().hashBytes(concat(keyIpad, data)).asBytes();
+        return Hashing.sha256().hashBytes(concat(keyOpad, innerSha256Result)).asBytes();
+    }
+
+    // Adds this test example on spec. Also we can easily change the parameters(e.g. secret, data)
+    // to clarify test results with partners.
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputTestExampleToHmacSha256_getCorrectResult() {
+        byte[] secret = base16().decode("0123456789ABCDEF0123456789ABCDEF");
+        byte[] data =
+                base16().decode(
+                        "0001020304050607EE4A2483738052E44E9B2A145E5DDFAA44B9E5536AF438E1E5C6");
+
+        byte[] hmacResult = doHmacSha256(secret, data);
+
+        assertThat(hmacResult)
+                .isEqualTo(base16().decode(
+                        "55EC5E6055AF6E92618B7D8710D4413709AB5DA27CA26A66F52E5AD4E8209052"));
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/MessageStreamHmacEncoderTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/MessageStreamHmacEncoderTest.java
new file mode 100644
index 0000000..d4c3342
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/MessageStreamHmacEncoderTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.MessageStreamHmacEncoder.EXTRACT_HMAC_SIZE;
+import static com.android.server.nearby.common.bluetooth.fastpair.MessageStreamHmacEncoder.SECTION_NONCE_LENGTH;
+
+import static com.google.common.primitives.Bytes.concat;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+/**
+ * Unit tests for {@link MessageStreamHmacEncoder}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class MessageStreamHmacEncoderTest {
+
+    private static final int ACCOUNT_KEY_LENGTH = 16;
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void encodeMessagePacket() throws GeneralSecurityException {
+        int messageLength = 2;
+        SecureRandom secureRandom = new SecureRandom();
+        byte[] accountKey = new byte[ACCOUNT_KEY_LENGTH];
+        secureRandom.nextBytes(accountKey);
+        byte[] data = new byte[messageLength];
+        secureRandom.nextBytes(data);
+        byte[] sectionNonce = new byte[SECTION_NONCE_LENGTH];
+        secureRandom.nextBytes(sectionNonce);
+
+        byte[] result = MessageStreamHmacEncoder
+                .encodeMessagePacket(accountKey, sectionNonce, data);
+
+        assertThat(result).hasLength(messageLength + SECTION_NONCE_LENGTH + EXTRACT_HMAC_SIZE);
+        // First bytes are raw message bytes.
+        assertThat(Arrays.copyOf(result, messageLength)).isEqualTo(data);
+        // Following by message nonce.
+        byte[] messageNonce =
+                Arrays.copyOfRange(result, messageLength, messageLength + SECTION_NONCE_LENGTH);
+        byte[] extractedHmac =
+                Arrays.copyOf(
+                        HmacSha256.buildWith64BytesKey(accountKey,
+                                concat(sectionNonce, messageNonce, data)),
+                        EXTRACT_HMAC_SIZE);
+        // Finally hash mac.
+        assertThat(Arrays.copyOfRange(result, messageLength + SECTION_NONCE_LENGTH, result.length))
+                .isEqualTo(extractedHmac);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void verifyHmac() throws GeneralSecurityException {
+        int messageLength = 2;
+        SecureRandom secureRandom = new SecureRandom();
+        byte[] accountKey = new byte[ACCOUNT_KEY_LENGTH];
+        secureRandom.nextBytes(accountKey);
+        byte[] data = new byte[messageLength];
+        secureRandom.nextBytes(data);
+        byte[] sectionNonce = new byte[SECTION_NONCE_LENGTH];
+        secureRandom.nextBytes(sectionNonce);
+        byte[] result = MessageStreamHmacEncoder
+                .encodeMessagePacket(accountKey, sectionNonce, data);
+
+        assertThat(MessageStreamHmacEncoder.verifyHmac(accountKey, sectionNonce, result)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void verifyHmac_failedByAccountKey() throws GeneralSecurityException {
+        int messageLength = 2;
+        SecureRandom secureRandom = new SecureRandom();
+        byte[] accountKey = new byte[ACCOUNT_KEY_LENGTH];
+        secureRandom.nextBytes(accountKey);
+        byte[] data = new byte[messageLength];
+        secureRandom.nextBytes(data);
+        byte[] sectionNonce = new byte[SECTION_NONCE_LENGTH];
+        secureRandom.nextBytes(sectionNonce);
+        byte[] result = MessageStreamHmacEncoder
+                .encodeMessagePacket(accountKey, sectionNonce, data);
+        secureRandom.nextBytes(accountKey);
+
+        assertThat(MessageStreamHmacEncoder.verifyHmac(accountKey, sectionNonce, result)).isFalse();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void verifyHmac_failedBySectionNonce() throws GeneralSecurityException {
+        int messageLength = 2;
+        SecureRandom secureRandom = new SecureRandom();
+        byte[] accountKey = new byte[ACCOUNT_KEY_LENGTH];
+        secureRandom.nextBytes(accountKey);
+        byte[] data = new byte[messageLength];
+        secureRandom.nextBytes(data);
+        byte[] sectionNonce = new byte[SECTION_NONCE_LENGTH];
+        secureRandom.nextBytes(sectionNonce);
+        byte[] result = MessageStreamHmacEncoder
+                .encodeMessagePacket(accountKey, sectionNonce, data);
+        secureRandom.nextBytes(sectionNonce);
+
+        assertThat(MessageStreamHmacEncoder.verifyHmac(accountKey, sectionNonce, result)).isFalse();
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/NamingEncoderTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/NamingEncoderTest.java
new file mode 100644
index 0000000..d66d209
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/NamingEncoderTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.KEY_LENGTH;
+import static com.android.server.nearby.common.bluetooth.fastpair.AesCtrMultipleBlockEncryption.NONCE_SIZE;
+import static com.android.server.nearby.common.bluetooth.fastpair.NamingEncoder.EXTRACT_HMAC_SIZE;
+import static com.android.server.nearby.common.bluetooth.fastpair.NamingEncoder.MAX_LENGTH_OF_NAME;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Unit tests for {@link NamingEncoder}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NamingEncoderTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void decodeEncodedNamingPacket_mustGetSameName() throws GeneralSecurityException {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        String name = "Someone's Google Headphone";
+
+        byte[] encodedNamingPacket = NamingEncoder.encodeNamingPacket(secret, name);
+
+        assertThat(NamingEncoder.decodeNamingPacket(secret, encodedNamingPacket)).isEqualTo(name);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectKeySizeToEncode_mustThrowException() {
+        byte[] secret = new byte[KEY_LENGTH - 1];
+        String data = "Someone's Google Headphone";
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> NamingEncoder.encodeNamingPacket(secret, data));
+
+        assertThat(exception).hasMessageThat()
+                .contains("Incorrect secret for encoding name packet");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectKeySizeToDecode_mustThrowException() {
+        byte[] secret = new byte[KEY_LENGTH - 1];
+        byte[] data = new byte[50];
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> NamingEncoder.decodeNamingPacket(secret, data));
+
+        assertThat(exception).hasMessageThat()
+                .contains("Incorrect secret for decoding name packet");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputTooSmallPacketSize_mustThrowException() {
+        byte[] secret = new byte[KEY_LENGTH];
+        byte[] data = new byte[EXTRACT_HMAC_SIZE - 1];
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> NamingEncoder.decodeNamingPacket(secret, data));
+
+        assertThat(exception).hasMessageThat().contains("Naming packet size is incorrect");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputTooLargePacketSize_mustThrowException() throws GeneralSecurityException {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        byte[] namingPacket = new byte[MAX_LENGTH_OF_NAME + EXTRACT_HMAC_SIZE + NONCE_SIZE + 1];
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> NamingEncoder.decodeNamingPacket(secret, namingPacket));
+
+        assertThat(exception).hasMessageThat().contains("Naming packet size is incorrect");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void inputIncorrectHmacToDecode_mustThrowException() throws GeneralSecurityException {
+        byte[] secret = AesCtrMultipleBlockEncryption.generateKey();
+        String name = "Someone's Google Headphone";
+
+        byte[] encodedNamingPacket = NamingEncoder.encodeNamingPacket(secret, name);
+        encodedNamingPacket[0] = (byte) ~encodedNamingPacket[0];
+
+        GeneralSecurityException exception =
+                assertThrows(
+                        GeneralSecurityException.class,
+                        () -> NamingEncoder.decodeNamingPacket(secret, encodedNamingPacket));
+
+        assertThat(exception)
+                .hasMessageThat()
+                .contains("Verify HMAC failed, could be incorrect key or naming packet.");
+    }
+
+    // Adds this test example on spec. Also we can easily change the parameters(e.g. secret, naming
+    // packet) to clarify test results with partners.
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void decodeTestNamingPacket_mustGetSameName() throws GeneralSecurityException {
+        byte[] secret = base16().decode("0123456789ABCDEF0123456789ABCDEF");
+        byte[] namingPacket = base16().decode(
+                "55EC5E6055AF6E920001020304050607EE4A2483738052E44E9B2A145E5DDFAA44B9E5536AF438"
+                        + "E1E5C6");
+
+        assertThat(NamingEncoder.decodeNamingPacket(secret, namingPacket))
+                .isEqualTo("Someone's Google Headphone");
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/PreferencesTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/PreferencesTest.java
new file mode 100644
index 0000000..b40a5a5
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/PreferencesTest.java
@@ -0,0 +1,1277 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for {@link Preferences}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PreferencesTest {
+
+    private static final int FIRST_INT = 1505;
+    private static final int SECOND_INT = 1506;
+    private static final boolean FIRST_BOOL = true;
+    private static final boolean SECOND_BOOL = false;
+    private static final short FIRST_SHORT = 32;
+    private static final short SECOND_SHORT = 73;
+    private static final long FIRST_LONG = 9838L;
+    private static final long SECOND_LONG = 93935L;
+    private static final String FIRST_STRING = "FIRST_STRING";
+    private static final String SECOND_STRING = "SECOND_STRING";
+    private static final byte[] FIRST_BYTES = new byte[] {7, 9};
+    private static final byte[] SECOND_BYTES = new byte[] {2};
+    private static final ImmutableSet<Integer> FIRST_INT_SETS = ImmutableSet.of(6, 8);
+    private static final ImmutableSet<Integer> SECOND_INT_SETS = ImmutableSet.of(6, 8);
+    private static final Preferences.ExtraLoggingInformation FIRST_EXTRA_LOGGING_INFO =
+            Preferences.ExtraLoggingInformation.builder().setModelId("000006").build();
+    private static final Preferences.ExtraLoggingInformation SECOND_EXTRA_LOGGING_INFO =
+            Preferences.ExtraLoggingInformation.builder().setModelId("000007").build();
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGattOperationTimeoutSeconds() {
+        Preferences prefs =
+                Preferences.builder().setGattOperationTimeoutSeconds(FIRST_INT).build();
+        assertThat(prefs.getGattOperationTimeoutSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getGattOperationTimeoutSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setGattOperationTimeoutSeconds(SECOND_INT).build();
+        assertThat(prefs2.getGattOperationTimeoutSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGattConnectionTimeoutSeconds() {
+        Preferences prefs =
+                Preferences.builder().setGattConnectionTimeoutSeconds(FIRST_INT).build();
+        assertThat(prefs.getGattConnectionTimeoutSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getGattConnectionTimeoutSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setGattConnectionTimeoutSeconds(SECOND_INT).build();
+        assertThat(prefs2.getGattConnectionTimeoutSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothToggleTimeoutSeconds() {
+        Preferences prefs =
+                Preferences.builder().setBluetoothToggleTimeoutSeconds(FIRST_INT).build();
+        assertThat(prefs.getBluetoothToggleTimeoutSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getBluetoothToggleTimeoutSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setBluetoothToggleTimeoutSeconds(SECOND_INT).build();
+        assertThat(prefs2.getBluetoothToggleTimeoutSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothToggleSleepSeconds() {
+        Preferences prefs =
+                Preferences.builder().setBluetoothToggleSleepSeconds(FIRST_INT).build();
+        assertThat(prefs.getBluetoothToggleSleepSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getBluetoothToggleSleepSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setBluetoothToggleSleepSeconds(SECOND_INT).build();
+        assertThat(prefs2.getBluetoothToggleSleepSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testClassicDiscoveryTimeoutSeconds() {
+        Preferences prefs =
+                Preferences.builder().setClassicDiscoveryTimeoutSeconds(FIRST_INT).build();
+        assertThat(prefs.getClassicDiscoveryTimeoutSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getClassicDiscoveryTimeoutSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setClassicDiscoveryTimeoutSeconds(SECOND_INT).build();
+        assertThat(prefs2.getClassicDiscoveryTimeoutSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNumDiscoverAttempts() {
+        Preferences prefs =
+                Preferences.builder().setNumDiscoverAttempts(FIRST_INT).build();
+        assertThat(prefs.getNumDiscoverAttempts()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getNumDiscoverAttempts())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setNumDiscoverAttempts(SECOND_INT).build();
+        assertThat(prefs2.getNumDiscoverAttempts()).isEqualTo(SECOND_INT);
+    }
+
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testDiscoveryRetrySleepSeconds() {
+        Preferences prefs =
+                Preferences.builder().setDiscoveryRetrySleepSeconds(FIRST_INT).build();
+        assertThat(prefs.getDiscoveryRetrySleepSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getDiscoveryRetrySleepSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setDiscoveryRetrySleepSeconds(SECOND_INT).build();
+        assertThat(prefs2.getDiscoveryRetrySleepSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSdpTimeoutSeconds() {
+        Preferences prefs =
+                Preferences.builder().setSdpTimeoutSeconds(FIRST_INT).build();
+        assertThat(prefs.getSdpTimeoutSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getSdpTimeoutSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setSdpTimeoutSeconds(SECOND_INT).build();
+        assertThat(prefs2.getSdpTimeoutSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNumSdpAttempts() {
+        Preferences prefs =
+                Preferences.builder().setNumSdpAttempts(FIRST_INT).build();
+        assertThat(prefs.getNumSdpAttempts()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getNumSdpAttempts())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setNumSdpAttempts(SECOND_INT).build();
+        assertThat(prefs2.getNumSdpAttempts()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNumCreateBondAttempts() {
+        Preferences prefs =
+                Preferences.builder().setNumCreateBondAttempts(FIRST_INT).build();
+        assertThat(prefs.getNumCreateBondAttempts()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getNumCreateBondAttempts())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setNumCreateBondAttempts(SECOND_INT).build();
+        assertThat(prefs2.getNumCreateBondAttempts()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNumConnectAttempts() {
+        Preferences prefs =
+                Preferences.builder().setNumConnectAttempts(FIRST_INT).build();
+        assertThat(prefs.getNumConnectAttempts()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getNumConnectAttempts())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setNumConnectAttempts(SECOND_INT).build();
+        assertThat(prefs2.getNumConnectAttempts()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNumWriteAccountKeyAttempts() {
+        Preferences prefs =
+                Preferences.builder().setNumWriteAccountKeyAttempts(FIRST_INT).build();
+        assertThat(prefs.getNumWriteAccountKeyAttempts()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getNumWriteAccountKeyAttempts())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setNumWriteAccountKeyAttempts(SECOND_INT).build();
+        assertThat(prefs2.getNumWriteAccountKeyAttempts()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothStatePollingMillis() {
+        Preferences prefs =
+                Preferences.builder().setBluetoothStatePollingMillis(FIRST_INT).build();
+        assertThat(prefs.getBluetoothStatePollingMillis()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getBluetoothStatePollingMillis())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setBluetoothStatePollingMillis(SECOND_INT).build();
+        assertThat(prefs2.getBluetoothStatePollingMillis()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNumAttempts() {
+        Preferences prefs =
+                Preferences.builder().setNumAttempts(FIRST_INT).build();
+        assertThat(prefs.getNumAttempts()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getNumAttempts())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setNumAttempts(SECOND_INT).build();
+        assertThat(prefs2.getNumAttempts()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testRemoveBondTimeoutSeconds() {
+        Preferences prefs =
+                Preferences.builder().setRemoveBondTimeoutSeconds(FIRST_INT).build();
+        assertThat(prefs.getRemoveBondTimeoutSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getRemoveBondTimeoutSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setRemoveBondTimeoutSeconds(SECOND_INT).build();
+        assertThat(prefs2.getRemoveBondTimeoutSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testRemoveBondSleepMillis() {
+        Preferences prefs =
+                Preferences.builder().setRemoveBondSleepMillis(FIRST_INT).build();
+        assertThat(prefs.getRemoveBondSleepMillis()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getRemoveBondSleepMillis())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setRemoveBondSleepMillis(SECOND_INT).build();
+        assertThat(prefs2.getRemoveBondSleepMillis()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testCreateBondTimeoutSeconds() {
+        Preferences prefs =
+                Preferences.builder().setCreateBondTimeoutSeconds(FIRST_INT).build();
+        assertThat(prefs.getCreateBondTimeoutSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getCreateBondTimeoutSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setCreateBondTimeoutSeconds(SECOND_INT).build();
+        assertThat(prefs2.getCreateBondTimeoutSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHidCreateBondTimeoutSeconds() {
+        Preferences prefs =
+                Preferences.builder().setHidCreateBondTimeoutSeconds(FIRST_INT).build();
+        assertThat(prefs.getHidCreateBondTimeoutSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getHidCreateBondTimeoutSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setHidCreateBondTimeoutSeconds(SECOND_INT).build();
+        assertThat(prefs2.getHidCreateBondTimeoutSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testProxyTimeoutSeconds() {
+        Preferences prefs =
+                Preferences.builder().setProxyTimeoutSeconds(FIRST_INT).build();
+        assertThat(prefs.getProxyTimeoutSeconds()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getProxyTimeoutSeconds())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setProxyTimeoutSeconds(SECOND_INT).build();
+        assertThat(prefs2.getProxyTimeoutSeconds()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWriteAccountKeySleepMillis() {
+        Preferences prefs =
+                Preferences.builder().setWriteAccountKeySleepMillis(FIRST_INT).build();
+        assertThat(prefs.getWriteAccountKeySleepMillis()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getWriteAccountKeySleepMillis())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setWriteAccountKeySleepMillis(SECOND_INT).build();
+        assertThat(prefs2.getWriteAccountKeySleepMillis()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testPairFailureCounts() {
+        Preferences prefs =
+                Preferences.builder().setPairFailureCounts(FIRST_INT).build();
+        assertThat(prefs.getPairFailureCounts()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getPairFailureCounts())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setPairFailureCounts(SECOND_INT).build();
+        assertThat(prefs2.getPairFailureCounts()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testCreateBondTransportType() {
+        Preferences prefs =
+                Preferences.builder().setCreateBondTransportType(FIRST_INT).build();
+        assertThat(prefs.getCreateBondTransportType()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getCreateBondTransportType())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setCreateBondTransportType(SECOND_INT).build();
+        assertThat(prefs2.getCreateBondTransportType()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGattConnectRetryTimeoutMillis() {
+        Preferences prefs =
+                Preferences.builder().setGattConnectRetryTimeoutMillis(FIRST_INT).build();
+        assertThat(prefs.getGattConnectRetryTimeoutMillis()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getGattConnectRetryTimeoutMillis())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setGattConnectRetryTimeoutMillis(SECOND_INT).build();
+        assertThat(prefs2.getGattConnectRetryTimeoutMillis()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNumSdpAttemptsAfterBonded() {
+        Preferences prefs =
+                Preferences.builder().setNumSdpAttemptsAfterBonded(FIRST_INT).build();
+        assertThat(prefs.getNumSdpAttemptsAfterBonded()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getNumSdpAttemptsAfterBonded())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setNumSdpAttemptsAfterBonded(SECOND_INT).build();
+        assertThat(prefs2.getNumSdpAttemptsAfterBonded()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSameModelIdPairedDeviceCount() {
+        Preferences prefs =
+                Preferences.builder().setSameModelIdPairedDeviceCount(FIRST_INT).build();
+        assertThat(prefs.getSameModelIdPairedDeviceCount()).isEqualTo(FIRST_INT);
+        assertThat(prefs.toBuilder().build().getSameModelIdPairedDeviceCount())
+                .isEqualTo(FIRST_INT);
+
+        Preferences prefs2 =
+                Preferences.builder().setSameModelIdPairedDeviceCount(SECOND_INT).build();
+        assertThat(prefs2.getSameModelIdPairedDeviceCount()).isEqualTo(SECOND_INT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testIgnoreDiscoveryError() {
+        Preferences prefs =
+                Preferences.builder().setIgnoreDiscoveryError(FIRST_BOOL).build();
+        assertThat(prefs.getIgnoreDiscoveryError()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getIgnoreDiscoveryError())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setIgnoreDiscoveryError(SECOND_BOOL).build();
+        assertThat(prefs2.getIgnoreDiscoveryError()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testToggleBluetoothOnFailure() {
+        Preferences prefs =
+                Preferences.builder().setToggleBluetoothOnFailure(FIRST_BOOL).build();
+        assertThat(prefs.getToggleBluetoothOnFailure()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getToggleBluetoothOnFailure())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setToggleBluetoothOnFailure(SECOND_BOOL).build();
+        assertThat(prefs2.getToggleBluetoothOnFailure()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothStateUsesPolling() {
+        Preferences prefs =
+                Preferences.builder().setBluetoothStateUsesPolling(FIRST_BOOL).build();
+        assertThat(prefs.getBluetoothStateUsesPolling()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getBluetoothStateUsesPolling())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setBluetoothStateUsesPolling(SECOND_BOOL).build();
+        assertThat(prefs2.getBluetoothStateUsesPolling()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEnableBrEdrHandover() {
+        Preferences prefs =
+                Preferences.builder().setEnableBrEdrHandover(FIRST_BOOL).build();
+        assertThat(prefs.getEnableBrEdrHandover()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getEnableBrEdrHandover())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setEnableBrEdrHandover(SECOND_BOOL).build();
+        assertThat(prefs2.getEnableBrEdrHandover()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWaitForUuidsAfterBonding() {
+        Preferences prefs =
+                Preferences.builder().setWaitForUuidsAfterBonding(FIRST_BOOL).build();
+        assertThat(prefs.getWaitForUuidsAfterBonding()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getWaitForUuidsAfterBonding())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setWaitForUuidsAfterBonding(SECOND_BOOL).build();
+        assertThat(prefs2.getWaitForUuidsAfterBonding()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testReceiveUuidsAndBondedEventBeforeClose() {
+        Preferences prefs =
+                Preferences.builder().setReceiveUuidsAndBondedEventBeforeClose(FIRST_BOOL).build();
+        assertThat(prefs.getReceiveUuidsAndBondedEventBeforeClose()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getReceiveUuidsAndBondedEventBeforeClose())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setReceiveUuidsAndBondedEventBeforeClose(SECOND_BOOL).build();
+        assertThat(prefs2.getReceiveUuidsAndBondedEventBeforeClose()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testRejectPhonebookAccess() {
+        Preferences prefs =
+                Preferences.builder().setRejectPhonebookAccess(FIRST_BOOL).build();
+        assertThat(prefs.getRejectPhonebookAccess()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getRejectPhonebookAccess())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setRejectPhonebookAccess(SECOND_BOOL).build();
+        assertThat(prefs2.getRejectPhonebookAccess()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testRejectMessageAccess() {
+        Preferences prefs =
+                Preferences.builder().setRejectMessageAccess(FIRST_BOOL).build();
+        assertThat(prefs.getRejectMessageAccess()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getRejectMessageAccess())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setRejectMessageAccess(SECOND_BOOL).build();
+        assertThat(prefs2.getRejectMessageAccess()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testRejectSimAccess() {
+        Preferences prefs =
+                Preferences.builder().setRejectSimAccess(FIRST_BOOL).build();
+        assertThat(prefs.getRejectSimAccess()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getRejectSimAccess())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setRejectSimAccess(SECOND_BOOL).build();
+        assertThat(prefs2.getRejectSimAccess()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSkipDisconnectingGattBeforeWritingAccountKey() {
+        Preferences prefs =
+                Preferences.builder().setSkipDisconnectingGattBeforeWritingAccountKey(FIRST_BOOL)
+                        .build();
+        assertThat(prefs.getSkipDisconnectingGattBeforeWritingAccountKey()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getSkipDisconnectingGattBeforeWritingAccountKey())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setSkipDisconnectingGattBeforeWritingAccountKey(SECOND_BOOL)
+                        .build();
+        assertThat(prefs2.getSkipDisconnectingGattBeforeWritingAccountKey()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testMoreEventLogForQuality() {
+        Preferences prefs =
+                Preferences.builder().setMoreEventLogForQuality(FIRST_BOOL).build();
+        assertThat(prefs.getMoreEventLogForQuality()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getMoreEventLogForQuality())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setMoreEventLogForQuality(SECOND_BOOL).build();
+        assertThat(prefs2.getMoreEventLogForQuality()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testRetryGattConnectionAndSecretHandshake() {
+        Preferences prefs =
+                Preferences.builder().setRetryGattConnectionAndSecretHandshake(FIRST_BOOL).build();
+        assertThat(prefs.getRetryGattConnectionAndSecretHandshake()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getRetryGattConnectionAndSecretHandshake())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setRetryGattConnectionAndSecretHandshake(SECOND_BOOL).build();
+        assertThat(prefs2.getRetryGattConnectionAndSecretHandshake()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testRetrySecretHandshakeTimeout() {
+        Preferences prefs =
+                Preferences.builder().setRetrySecretHandshakeTimeout(FIRST_BOOL).build();
+        assertThat(prefs.getRetrySecretHandshakeTimeout()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getRetrySecretHandshakeTimeout())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setRetrySecretHandshakeTimeout(SECOND_BOOL).build();
+        assertThat(prefs2.getRetrySecretHandshakeTimeout()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testLogUserManualRetry() {
+        Preferences prefs =
+                Preferences.builder().setLogUserManualRetry(FIRST_BOOL).build();
+        assertThat(prefs.getLogUserManualRetry()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getLogUserManualRetry())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setLogUserManualRetry(SECOND_BOOL).build();
+        assertThat(prefs2.getLogUserManualRetry()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testIsDeviceFinishCheckAddressFromCache() {
+        Preferences prefs =
+                Preferences.builder().setIsDeviceFinishCheckAddressFromCache(FIRST_BOOL).build();
+        assertThat(prefs.getIsDeviceFinishCheckAddressFromCache()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getIsDeviceFinishCheckAddressFromCache())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setIsDeviceFinishCheckAddressFromCache(SECOND_BOOL).build();
+        assertThat(prefs2.getIsDeviceFinishCheckAddressFromCache()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testLogPairWithCachedModelId() {
+        Preferences prefs =
+                Preferences.builder().setLogPairWithCachedModelId(FIRST_BOOL).build();
+        assertThat(prefs.getLogPairWithCachedModelId()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getLogPairWithCachedModelId())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setLogPairWithCachedModelId(SECOND_BOOL).build();
+        assertThat(prefs2.getLogPairWithCachedModelId()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testDirectConnectProfileIfModelIdInCache() {
+        Preferences prefs =
+                Preferences.builder().setDirectConnectProfileIfModelIdInCache(FIRST_BOOL).build();
+        assertThat(prefs.getDirectConnectProfileIfModelIdInCache()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getDirectConnectProfileIfModelIdInCache())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setDirectConnectProfileIfModelIdInCache(SECOND_BOOL).build();
+        assertThat(prefs2.getDirectConnectProfileIfModelIdInCache()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testAcceptPasskey() {
+        Preferences prefs =
+                Preferences.builder().setAcceptPasskey(FIRST_BOOL).build();
+        assertThat(prefs.getAcceptPasskey()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getAcceptPasskey())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setAcceptPasskey(SECOND_BOOL).build();
+        assertThat(prefs2.getAcceptPasskey()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testProviderInitiatesBondingIfSupported() {
+        Preferences prefs =
+                Preferences.builder().setProviderInitiatesBondingIfSupported(FIRST_BOOL).build();
+        assertThat(prefs.getProviderInitiatesBondingIfSupported()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getProviderInitiatesBondingIfSupported())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setProviderInitiatesBondingIfSupported(SECOND_BOOL).build();
+        assertThat(prefs2.getProviderInitiatesBondingIfSupported()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testAttemptDirectConnectionWhenPreviouslyBonded() {
+        Preferences prefs =
+                Preferences.builder()
+                        .setAttemptDirectConnectionWhenPreviouslyBonded(FIRST_BOOL).build();
+        assertThat(prefs.getAttemptDirectConnectionWhenPreviouslyBonded()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getAttemptDirectConnectionWhenPreviouslyBonded())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder()
+                        .setAttemptDirectConnectionWhenPreviouslyBonded(SECOND_BOOL).build();
+        assertThat(prefs2.getAttemptDirectConnectionWhenPreviouslyBonded()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testAutomaticallyReconnectGattWhenNeeded() {
+        Preferences prefs =
+                Preferences.builder().setAutomaticallyReconnectGattWhenNeeded(FIRST_BOOL).build();
+        assertThat(prefs.getAutomaticallyReconnectGattWhenNeeded()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getAutomaticallyReconnectGattWhenNeeded())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setAutomaticallyReconnectGattWhenNeeded(SECOND_BOOL).build();
+        assertThat(prefs2.getAutomaticallyReconnectGattWhenNeeded()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSkipConnectingProfiles() {
+        Preferences prefs =
+                Preferences.builder().setSkipConnectingProfiles(FIRST_BOOL).build();
+        assertThat(prefs.getSkipConnectingProfiles()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getSkipConnectingProfiles())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setSkipConnectingProfiles(SECOND_BOOL).build();
+        assertThat(prefs2.getSkipConnectingProfiles()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testIgnoreUuidTimeoutAfterBonded() {
+        Preferences prefs =
+                Preferences.builder().setIgnoreUuidTimeoutAfterBonded(FIRST_BOOL).build();
+        assertThat(prefs.getIgnoreUuidTimeoutAfterBonded()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getIgnoreUuidTimeoutAfterBonded())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setIgnoreUuidTimeoutAfterBonded(SECOND_BOOL).build();
+        assertThat(prefs2.getIgnoreUuidTimeoutAfterBonded()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSpecifyCreateBondTransportType() {
+        Preferences prefs =
+                Preferences.builder().setSpecifyCreateBondTransportType(FIRST_BOOL).build();
+        assertThat(prefs.getSpecifyCreateBondTransportType()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getSpecifyCreateBondTransportType())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setSpecifyCreateBondTransportType(SECOND_BOOL).build();
+        assertThat(prefs2.getSpecifyCreateBondTransportType()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testIncreaseIntentFilterPriority() {
+        Preferences prefs =
+                Preferences.builder().setIncreaseIntentFilterPriority(FIRST_BOOL).build();
+        assertThat(prefs.getIncreaseIntentFilterPriority()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getIncreaseIntentFilterPriority())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setIncreaseIntentFilterPriority(SECOND_BOOL).build();
+        assertThat(prefs2.getIncreaseIntentFilterPriority()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEvaluatePerformance() {
+        Preferences prefs =
+                Preferences.builder().setEvaluatePerformance(FIRST_BOOL).build();
+        assertThat(prefs.getEvaluatePerformance()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getEvaluatePerformance())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setEvaluatePerformance(SECOND_BOOL).build();
+        assertThat(prefs2.getEvaluatePerformance()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEnableNamingCharacteristic() {
+        Preferences prefs =
+                Preferences.builder().setEnableNamingCharacteristic(FIRST_BOOL).build();
+        assertThat(prefs.getEnableNamingCharacteristic()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getEnableNamingCharacteristic())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setEnableNamingCharacteristic(SECOND_BOOL).build();
+        assertThat(prefs2.getEnableNamingCharacteristic()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEnableFirmwareVersionCharacteristic() {
+        Preferences prefs =
+                Preferences.builder().setEnableFirmwareVersionCharacteristic(FIRST_BOOL).build();
+        assertThat(prefs.getEnableFirmwareVersionCharacteristic()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getEnableFirmwareVersionCharacteristic())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setEnableFirmwareVersionCharacteristic(SECOND_BOOL).build();
+        assertThat(prefs2.getEnableFirmwareVersionCharacteristic()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testKeepSameAccountKeyWrite() {
+        Preferences prefs =
+                Preferences.builder().setKeepSameAccountKeyWrite(FIRST_BOOL).build();
+        assertThat(prefs.getKeepSameAccountKeyWrite()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getKeepSameAccountKeyWrite())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setKeepSameAccountKeyWrite(SECOND_BOOL).build();
+        assertThat(prefs2.getKeepSameAccountKeyWrite()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testIsRetroactivePairing() {
+        Preferences prefs =
+                Preferences.builder().setIsRetroactivePairing(FIRST_BOOL).build();
+        assertThat(prefs.getIsRetroactivePairing()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getIsRetroactivePairing())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setIsRetroactivePairing(SECOND_BOOL).build();
+        assertThat(prefs2.getIsRetroactivePairing()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSupportHidDevice() {
+        Preferences prefs =
+                Preferences.builder().setSupportHidDevice(FIRST_BOOL).build();
+        assertThat(prefs.getSupportHidDevice()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getSupportHidDevice())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setSupportHidDevice(SECOND_BOOL).build();
+        assertThat(prefs2.getSupportHidDevice()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEnablePairingWhileDirectlyConnecting() {
+        Preferences prefs =
+                Preferences.builder().setEnablePairingWhileDirectlyConnecting(FIRST_BOOL).build();
+        assertThat(prefs.getEnablePairingWhileDirectlyConnecting()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getEnablePairingWhileDirectlyConnecting())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setEnablePairingWhileDirectlyConnecting(SECOND_BOOL).build();
+        assertThat(prefs2.getEnablePairingWhileDirectlyConnecting()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testAcceptConsentForFastPairOne() {
+        Preferences prefs =
+                Preferences.builder().setAcceptConsentForFastPairOne(FIRST_BOOL).build();
+        assertThat(prefs.getAcceptConsentForFastPairOne()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getAcceptConsentForFastPairOne())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setAcceptConsentForFastPairOne(SECOND_BOOL).build();
+        assertThat(prefs2.getAcceptConsentForFastPairOne()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEnable128BitCustomGattCharacteristicsId() {
+        Preferences prefs =
+                Preferences.builder().setEnable128BitCustomGattCharacteristicsId(FIRST_BOOL)
+                        .build();
+        assertThat(prefs.getEnable128BitCustomGattCharacteristicsId()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getEnable128BitCustomGattCharacteristicsId())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setEnable128BitCustomGattCharacteristicsId(SECOND_BOOL)
+                        .build();
+        assertThat(prefs2.getEnable128BitCustomGattCharacteristicsId()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEnableSendExceptionStepToValidator() {
+        Preferences prefs =
+                Preferences.builder().setEnableSendExceptionStepToValidator(FIRST_BOOL).build();
+        assertThat(prefs.getEnableSendExceptionStepToValidator()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getEnableSendExceptionStepToValidator())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setEnableSendExceptionStepToValidator(SECOND_BOOL).build();
+        assertThat(prefs2.getEnableSendExceptionStepToValidator()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEnableAdditionalDataTypeWhenActionOverBle() {
+        Preferences prefs =
+                Preferences.builder().setEnableAdditionalDataTypeWhenActionOverBle(FIRST_BOOL)
+                        .build();
+        assertThat(prefs.getEnableAdditionalDataTypeWhenActionOverBle()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getEnableAdditionalDataTypeWhenActionOverBle())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setEnableAdditionalDataTypeWhenActionOverBle(SECOND_BOOL)
+                        .build();
+        assertThat(prefs2.getEnableAdditionalDataTypeWhenActionOverBle()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testCheckBondStateWhenSkipConnectingProfiles() {
+        Preferences prefs =
+                Preferences.builder().setCheckBondStateWhenSkipConnectingProfiles(FIRST_BOOL)
+                        .build();
+        assertThat(prefs.getCheckBondStateWhenSkipConnectingProfiles()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getCheckBondStateWhenSkipConnectingProfiles())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setCheckBondStateWhenSkipConnectingProfiles(SECOND_BOOL)
+                        .build();
+        assertThat(prefs2.getCheckBondStateWhenSkipConnectingProfiles()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHandlePasskeyConfirmationByUi() {
+        Preferences prefs =
+                Preferences.builder().setHandlePasskeyConfirmationByUi(FIRST_BOOL).build();
+        assertThat(prefs.getHandlePasskeyConfirmationByUi()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getHandlePasskeyConfirmationByUi())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setHandlePasskeyConfirmationByUi(SECOND_BOOL).build();
+        assertThat(prefs2.getHandlePasskeyConfirmationByUi()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testEnablePairFlowShowUiWithoutProfileConnection() {
+        Preferences prefs =
+                Preferences.builder().setEnablePairFlowShowUiWithoutProfileConnection(FIRST_BOOL)
+                        .build();
+        assertThat(prefs.getEnablePairFlowShowUiWithoutProfileConnection()).isEqualTo(FIRST_BOOL);
+        assertThat(prefs.toBuilder().build().getEnablePairFlowShowUiWithoutProfileConnection())
+                .isEqualTo(FIRST_BOOL);
+
+        Preferences prefs2 =
+                Preferences.builder().setEnablePairFlowShowUiWithoutProfileConnection(SECOND_BOOL)
+                        .build();
+        assertThat(prefs2.getEnablePairFlowShowUiWithoutProfileConnection()).isEqualTo(SECOND_BOOL);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBrHandoverDataCharacteristicId() {
+        Preferences prefs =
+                Preferences.builder().setBrHandoverDataCharacteristicId(FIRST_SHORT).build();
+        assertThat(prefs.getBrHandoverDataCharacteristicId()).isEqualTo(FIRST_SHORT);
+        assertThat(prefs.toBuilder().build().getBrHandoverDataCharacteristicId())
+                .isEqualTo(FIRST_SHORT);
+
+        Preferences prefs2 =
+                Preferences.builder().setBrHandoverDataCharacteristicId(SECOND_SHORT).build();
+        assertThat(prefs2.getBrHandoverDataCharacteristicId()).isEqualTo(SECOND_SHORT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothSigDataCharacteristicId() {
+        Preferences prefs =
+                Preferences.builder().setBluetoothSigDataCharacteristicId(FIRST_SHORT).build();
+        assertThat(prefs.getBluetoothSigDataCharacteristicId()).isEqualTo(FIRST_SHORT);
+        assertThat(prefs.toBuilder().build().getBluetoothSigDataCharacteristicId())
+                .isEqualTo(FIRST_SHORT);
+
+        Preferences prefs2 =
+                Preferences.builder().setBluetoothSigDataCharacteristicId(SECOND_SHORT).build();
+        assertThat(prefs2.getBluetoothSigDataCharacteristicId()).isEqualTo(SECOND_SHORT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testFirmwareVersionCharacteristicId() {
+        Preferences prefs =
+                Preferences.builder().setFirmwareVersionCharacteristicId(FIRST_SHORT).build();
+        assertThat(prefs.getFirmwareVersionCharacteristicId()).isEqualTo(FIRST_SHORT);
+        assertThat(prefs.toBuilder().build().getFirmwareVersionCharacteristicId())
+                .isEqualTo(FIRST_SHORT);
+
+        Preferences prefs2 =
+                Preferences.builder().setFirmwareVersionCharacteristicId(SECOND_SHORT).build();
+        assertThat(prefs2.getFirmwareVersionCharacteristicId()).isEqualTo(SECOND_SHORT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBrTransportBlockDataDescriptorId() {
+        Preferences prefs =
+                Preferences.builder().setBrTransportBlockDataDescriptorId(FIRST_SHORT).build();
+        assertThat(prefs.getBrTransportBlockDataDescriptorId()).isEqualTo(FIRST_SHORT);
+        assertThat(prefs.toBuilder().build().getBrTransportBlockDataDescriptorId())
+                .isEqualTo(FIRST_SHORT);
+
+        Preferences prefs2 =
+                Preferences.builder().setBrTransportBlockDataDescriptorId(SECOND_SHORT).build();
+        assertThat(prefs2.getBrTransportBlockDataDescriptorId()).isEqualTo(SECOND_SHORT);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGattConnectShortTimeoutMs() {
+        Preferences prefs =
+                Preferences.builder().setGattConnectShortTimeoutMs(FIRST_LONG).build();
+        assertThat(prefs.getGattConnectShortTimeoutMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getGattConnectShortTimeoutMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setGattConnectShortTimeoutMs(SECOND_LONG).build();
+        assertThat(prefs2.getGattConnectShortTimeoutMs()).isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGattConnectLongTimeoutMs() {
+        Preferences prefs =
+                Preferences.builder().setGattConnectLongTimeoutMs(FIRST_LONG).build();
+        assertThat(prefs.getGattConnectLongTimeoutMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getGattConnectLongTimeoutMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setGattConnectLongTimeoutMs(SECOND_LONG).build();
+        assertThat(prefs2.getGattConnectLongTimeoutMs()).isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGattConnectShortTimeoutRetryMaxSpentTimeMs() {
+        Preferences prefs =
+                Preferences.builder().setGattConnectShortTimeoutRetryMaxSpentTimeMs(FIRST_LONG)
+                        .build();
+        assertThat(prefs.getGattConnectShortTimeoutRetryMaxSpentTimeMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getGattConnectShortTimeoutRetryMaxSpentTimeMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setGattConnectShortTimeoutRetryMaxSpentTimeMs(SECOND_LONG)
+                        .build();
+        assertThat(prefs2.getGattConnectShortTimeoutRetryMaxSpentTimeMs()).isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testAddressRotateRetryMaxSpentTimeMs() {
+        Preferences prefs =
+                Preferences.builder().setAddressRotateRetryMaxSpentTimeMs(FIRST_LONG).build();
+        assertThat(prefs.getAddressRotateRetryMaxSpentTimeMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getAddressRotateRetryMaxSpentTimeMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setAddressRotateRetryMaxSpentTimeMs(SECOND_LONG).build();
+        assertThat(prefs2.getAddressRotateRetryMaxSpentTimeMs()).isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testPairingRetryDelayMs() {
+        Preferences prefs =
+                Preferences.builder().setPairingRetryDelayMs(FIRST_LONG).build();
+        assertThat(prefs.getPairingRetryDelayMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getPairingRetryDelayMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setPairingRetryDelayMs(SECOND_LONG).build();
+        assertThat(prefs2.getPairingRetryDelayMs()).isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSecretHandshakeShortTimeoutMs() {
+        Preferences prefs =
+                Preferences.builder().setSecretHandshakeShortTimeoutMs(FIRST_LONG).build();
+        assertThat(prefs.getSecretHandshakeShortTimeoutMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getSecretHandshakeShortTimeoutMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setSecretHandshakeShortTimeoutMs(SECOND_LONG).build();
+        assertThat(prefs2.getSecretHandshakeShortTimeoutMs()).isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSecretHandshakeLongTimeoutMs() {
+        Preferences prefs =
+                Preferences.builder().setSecretHandshakeLongTimeoutMs(FIRST_LONG).build();
+        assertThat(prefs.getSecretHandshakeLongTimeoutMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getSecretHandshakeLongTimeoutMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setSecretHandshakeLongTimeoutMs(SECOND_LONG).build();
+        assertThat(prefs2.getSecretHandshakeLongTimeoutMs()).isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSecretHandshakeShortTimeoutRetryMaxSpentTimeMs() {
+        Preferences prefs =
+                Preferences.builder().setSecretHandshakeShortTimeoutRetryMaxSpentTimeMs(FIRST_LONG)
+                        .build();
+        assertThat(prefs.getSecretHandshakeShortTimeoutRetryMaxSpentTimeMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getSecretHandshakeShortTimeoutRetryMaxSpentTimeMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setSecretHandshakeShortTimeoutRetryMaxSpentTimeMs(SECOND_LONG)
+                        .build();
+        assertThat(prefs2.getSecretHandshakeShortTimeoutRetryMaxSpentTimeMs())
+                .isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSecretHandshakeLongTimeoutRetryMaxSpentTimeMs() {
+        Preferences prefs =
+                Preferences.builder().setSecretHandshakeLongTimeoutRetryMaxSpentTimeMs(FIRST_LONG)
+                        .build();
+        assertThat(prefs.getSecretHandshakeLongTimeoutRetryMaxSpentTimeMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getSecretHandshakeLongTimeoutRetryMaxSpentTimeMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setSecretHandshakeLongTimeoutRetryMaxSpentTimeMs(SECOND_LONG)
+                        .build();
+        assertThat(prefs2.getSecretHandshakeLongTimeoutRetryMaxSpentTimeMs())
+                .isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSecretHandshakeRetryAttempts() {
+        Preferences prefs =
+                Preferences.builder().setSecretHandshakeRetryAttempts(FIRST_LONG).build();
+        assertThat(prefs.getSecretHandshakeRetryAttempts()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getSecretHandshakeRetryAttempts())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setSecretHandshakeRetryAttempts(SECOND_LONG).build();
+        assertThat(prefs2.getSecretHandshakeRetryAttempts()).isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSecretHandshakeRetryGattConnectionMaxSpentTimeMs() {
+        Preferences prefs =
+                Preferences.builder()
+                        .setSecretHandshakeRetryGattConnectionMaxSpentTimeMs(FIRST_LONG).build();
+        assertThat(prefs.getSecretHandshakeRetryGattConnectionMaxSpentTimeMs())
+                .isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getSecretHandshakeRetryGattConnectionMaxSpentTimeMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setSecretHandshakeRetryGattConnectionMaxSpentTimeMs(
+                        SECOND_LONG).build();
+        assertThat(prefs2.getSecretHandshakeRetryGattConnectionMaxSpentTimeMs())
+                .isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSignalLostRetryMaxSpentTimeMs() {
+        Preferences prefs =
+                Preferences.builder().setSignalLostRetryMaxSpentTimeMs(FIRST_LONG).build();
+        assertThat(prefs.getSignalLostRetryMaxSpentTimeMs()).isEqualTo(FIRST_LONG);
+        assertThat(prefs.toBuilder().build().getSignalLostRetryMaxSpentTimeMs())
+                .isEqualTo(FIRST_LONG);
+
+        Preferences prefs2 =
+                Preferences.builder().setSignalLostRetryMaxSpentTimeMs(SECOND_LONG).build();
+        assertThat(prefs2.getSignalLostRetryMaxSpentTimeMs()).isEqualTo(SECOND_LONG);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testCachedDeviceAddress() {
+        Preferences prefs =
+                Preferences.builder().setCachedDeviceAddress(FIRST_STRING).build();
+        assertThat(prefs.getCachedDeviceAddress()).isEqualTo(FIRST_STRING);
+        assertThat(prefs.toBuilder().build().getCachedDeviceAddress())
+                .isEqualTo(FIRST_STRING);
+
+        Preferences prefs2 =
+                Preferences.builder().setCachedDeviceAddress(SECOND_STRING).build();
+        assertThat(prefs2.getCachedDeviceAddress()).isEqualTo(SECOND_STRING);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testPossibleCachedDeviceAddress() {
+        Preferences prefs =
+                Preferences.builder().setPossibleCachedDeviceAddress(FIRST_STRING).build();
+        assertThat(prefs.getPossibleCachedDeviceAddress()).isEqualTo(FIRST_STRING);
+        assertThat(prefs.toBuilder().build().getPossibleCachedDeviceAddress())
+                .isEqualTo(FIRST_STRING);
+
+        Preferences prefs2 =
+                Preferences.builder().setPossibleCachedDeviceAddress(SECOND_STRING).build();
+        assertThat(prefs2.getPossibleCachedDeviceAddress()).isEqualTo(SECOND_STRING);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSupportedProfileUuids() {
+        Preferences prefs =
+                Preferences.builder().setSupportedProfileUuids(FIRST_BYTES).build();
+        assertThat(prefs.getSupportedProfileUuids()).isEqualTo(FIRST_BYTES);
+        assertThat(prefs.toBuilder().build().getSupportedProfileUuids())
+                .isEqualTo(FIRST_BYTES);
+
+        Preferences prefs2 =
+                Preferences.builder().setSupportedProfileUuids(SECOND_BYTES).build();
+        assertThat(prefs2.getSupportedProfileUuids()).isEqualTo(SECOND_BYTES);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGattConnectionAndSecretHandshakeNoRetryGattError() {
+        Preferences prefs =
+                Preferences.builder().setGattConnectionAndSecretHandshakeNoRetryGattError(
+                        FIRST_INT_SETS).build();
+        assertThat(prefs.getGattConnectionAndSecretHandshakeNoRetryGattError())
+                .isEqualTo(FIRST_INT_SETS);
+        assertThat(prefs.toBuilder().build().getGattConnectionAndSecretHandshakeNoRetryGattError())
+                .isEqualTo(FIRST_INT_SETS);
+
+        Preferences prefs2 =
+                Preferences.builder().setGattConnectionAndSecretHandshakeNoRetryGattError(
+                        SECOND_INT_SETS).build();
+        assertThat(prefs2.getGattConnectionAndSecretHandshakeNoRetryGattError())
+                .isEqualTo(SECOND_INT_SETS);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testExtraLoggingInformation() {
+        Preferences prefs =
+                Preferences.builder().setExtraLoggingInformation(FIRST_EXTRA_LOGGING_INFO).build();
+        assertThat(prefs.getExtraLoggingInformation()).isEqualTo(FIRST_EXTRA_LOGGING_INFO);
+        assertThat(prefs.toBuilder().build().getExtraLoggingInformation())
+                .isEqualTo(FIRST_EXTRA_LOGGING_INFO);
+
+        Preferences prefs2 =
+                Preferences.builder().setExtraLoggingInformation(SECOND_EXTRA_LOGGING_INFO).build();
+        assertThat(prefs2.getExtraLoggingInformation()).isEqualTo(SECOND_EXTRA_LOGGING_INFO);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/TimingLoggerTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/TimingLoggerTest.java
new file mode 100644
index 0000000..4672905
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/TimingLoggerTest.java
@@ -0,0 +1,218 @@
+/*
+ * 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.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.android.server.nearby.common.bluetooth.fastpair.TimingLogger.ScopedTiming;
+import com.android.server.nearby.common.bluetooth.fastpair.TimingLogger.Timing;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for {@link TimingLogger}.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TimingLoggerTest {
+
+    private final Preferences mPrefs = Preferences.builder().setEvaluatePerformance(true).build();
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void logPairedTiming() {
+        String label = "start";
+        TimingLogger timingLogger = new TimingLogger("paired", mPrefs);
+        timingLogger.start(label);
+        SystemClock.sleep(1000);
+        timingLogger.end();
+
+        assertThat(timingLogger.getTimings()).hasSize(2);
+
+        // Calculate execution time and only store result at "start" timing.
+        // Expected output:
+        // <pre>
+        //  I/FastPair: paired [Exclusive time] / [Total time]
+        //  I/FastPair:   start 1000ms
+        //  I/FastPair: paired end, 1000ms
+        // </pre>
+        timingLogger.dump();
+
+        assertPairedTiming(label, timingLogger.getTimings().get(0),
+                timingLogger.getTimings().get(1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void logScopedTiming() {
+        String label = "scopedTiming";
+        TimingLogger timingLogger = new TimingLogger("scoped", mPrefs);
+        try (ScopedTiming scopedTiming = new ScopedTiming(timingLogger, label)) {
+            SystemClock.sleep(1000);
+        }
+
+        assertThat(timingLogger.getTimings()).hasSize(2);
+
+        // Calculate execution time and only store result at "start" timings.
+        // Expected output:
+        // <pre>
+        //  I/FastPair: scoped [Exclusive time] / [Total time]
+        //  I/FastPair:   scopedTiming 1000ms
+        //  I/FastPair: scoped end, 1000ms
+        // </pre>
+        timingLogger.dump();
+
+        assertPairedTiming(label, timingLogger.getTimings().get(0),
+                timingLogger.getTimings().get(1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void logOrderedTiming() {
+        String label1 = "t1";
+        String label2 = "t2";
+        TimingLogger timingLogger = new TimingLogger("ordered", mPrefs);
+        try (ScopedTiming t1 = new ScopedTiming(timingLogger, label1)) {
+            SystemClock.sleep(1000);
+        }
+        try (ScopedTiming t2 = new ScopedTiming(timingLogger, label2)) {
+            SystemClock.sleep(1000);
+        }
+
+        assertThat(timingLogger.getTimings()).hasSize(4);
+
+        // Calculate execution time and only store result at "start" timings.
+        // Expected output:
+        // <pre>
+        //  I/FastPair: ordered [Exclusive time] / [Total time]
+        //  I/FastPair:   t1 1000ms
+        //  I/FastPair:   t2 1000ms
+        //  I/FastPair: ordered end, 2000ms
+        // </pre>
+        timingLogger.dump();
+
+        // We expect get timings in this order: t1 start, t1 end, t2 start, t2 end.
+        Timing start1 = timingLogger.getTimings().get(0);
+        Timing end1 = timingLogger.getTimings().get(1);
+        Timing start2 = timingLogger.getTimings().get(2);
+        Timing end2 = timingLogger.getTimings().get(3);
+
+        // Verify the paired timings.
+        assertPairedTiming(label1, start1, end1);
+        assertPairedTiming(label2, start2, end2);
+
+        // Verify the order and total time.
+        assertOrderedTiming(start1, start2);
+        assertThat(start1.getExclusiveTime() + start2.getExclusiveTime())
+                .isEqualTo(timingLogger.getTotalTime());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void logNestedTiming() {
+        String labelOuter = "outer";
+        String labelInner1 = "inner1";
+        String labelInner1Inner1 = "inner1inner1";
+        String labelInner2 = "inner2";
+        TimingLogger timingLogger = new TimingLogger("nested", mPrefs);
+        try (ScopedTiming outer = new ScopedTiming(timingLogger, labelOuter)) {
+            SystemClock.sleep(1000);
+            try (ScopedTiming inner1 = new ScopedTiming(timingLogger, labelInner1)) {
+                SystemClock.sleep(1000);
+                try (ScopedTiming inner1inner1 = new ScopedTiming(timingLogger,
+                        labelInner1Inner1)) {
+                    SystemClock.sleep(1000);
+                }
+            }
+            try (ScopedTiming inner2 = new ScopedTiming(timingLogger, labelInner2)) {
+                SystemClock.sleep(1000);
+            }
+        }
+
+        assertThat(timingLogger.getTimings()).hasSize(8);
+
+        // Calculate execution time and only store result at "start" timing.
+        // Expected output:
+        // <pre>
+        //  I/FastPair: nested [Exclusive time] / [Total time]
+        //  I/FastPair:   outer 1000ms / 4000ms
+        //  I/FastPair:     inner1 1000ms / 2000ms
+        //  I/FastPair:       inner1inner1 1000ms
+        //  I/FastPair:     inner2 1000ms
+        //  I/FastPair: nested end, 4000ms
+        // </pre>
+        timingLogger.dump();
+
+        // We expect get timings in this order: outer start, inner1 start, inner1inner1 start,
+        // inner1inner1 end, inner1 end, inner2 start, inner2 end, outer end.
+        Timing startOuter = timingLogger.getTimings().get(0);
+        Timing startInner1 = timingLogger.getTimings().get(1);
+        Timing startInner1Inner1 = timingLogger.getTimings().get(2);
+        Timing endInner1Inner1 = timingLogger.getTimings().get(3);
+        Timing endInner1 = timingLogger.getTimings().get(4);
+        Timing startInner2 = timingLogger.getTimings().get(5);
+        Timing endInner2 = timingLogger.getTimings().get(6);
+        Timing endOuter = timingLogger.getTimings().get(7);
+
+        // Verify the paired timings.
+        assertPairedTiming(labelOuter, startOuter, endOuter);
+        assertPairedTiming(labelInner1, startInner1, endInner1);
+        assertPairedTiming(labelInner1Inner1, startInner1Inner1, endInner1Inner1);
+        assertPairedTiming(labelInner2, startInner2, endInner2);
+
+        // Verify the order and total time.
+        assertOrderedTiming(startOuter, startInner1);
+        assertOrderedTiming(startInner1, startInner1Inner1);
+        assertOrderedTiming(startInner1Inner1, startInner2);
+        assertThat(
+                startOuter.getExclusiveTime() + startInner1.getTotalTime() + startInner2
+                        .getTotalTime())
+                .isEqualTo(timingLogger.getTotalTime());
+
+        // Verify the nested execution time.
+        assertThat(startInner1Inner1.getTotalTime()).isAtMost(startInner1.getTotalTime());
+        assertThat(startInner1.getTotalTime() + startInner2.getTotalTime())
+                .isAtMost(startOuter.getTotalTime());
+    }
+
+    private void assertPairedTiming(String label, Timing start, Timing end) {
+        assertThat(start.isStartTiming()).isTrue();
+        assertThat(start.getName()).isEqualTo(label);
+        assertThat(end.isEndTiming()).isTrue();
+        assertThat(end.getTimestamp()).isAtLeast(start.getTimestamp());
+
+        assertThat(start.getExclusiveTime() > 0).isTrue();
+        assertThat(start.getTotalTime()).isAtLeast(start.getExclusiveTime());
+        assertThat(end.getExclusiveTime() == 0).isTrue();
+        assertThat(end.getTotalTime() == 0).isTrue();
+    }
+
+    private void assertOrderedTiming(Timing t1, Timing t2) {
+        assertThat(t1.isStartTiming()).isTrue();
+        assertThat(t2.isStartTiming()).isTrue();
+        assertThat(t2.getTimestamp()).isAtLeast(t1.getTimestamp());
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnectionTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnectionTest.java
new file mode 100644
index 0000000..80bde63
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnectionTest.java
@@ -0,0 +1,848 @@
+/*
+ * 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.server.nearby.common.bluetooth.gatt;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothStatusCodes;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+
+import androidx.test.filters.SdkSuppress;
+
+import com.android.server.nearby.common.bluetooth.BluetoothConsts;
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.ReservedUuids;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection.ChangeObserver;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.OperationType;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattWrapper;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.Operation;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.SynchronousOperation;
+
+import junit.framework.TestCase;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Captor;
+import org.mockito.Mock;
+
+import java.util.Arrays;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Unit tests for {@link BluetoothGattConnection}.
+ */
+public class BluetoothGattConnectionTest extends TestCase {
+
+    private static final UUID SERVICE_UUID = UUID.randomUUID();
+    private static final UUID CHARACTERISTIC_UUID = UUID.randomUUID();
+    private static final UUID DESCRIPTOR_UUID = UUID.randomUUID();
+    private static final byte[] DATA = "data".getBytes();
+    private static final int RSSI = -63;
+    private static final int CONNECTION_PRIORITY = 128;
+    private static final int MTU_REQUEST = 512;
+    private static final BluetoothGattHelper.ConnectionOptions CONNECTION_OPTIONS =
+            BluetoothGattHelper.ConnectionOptions.builder().build();
+
+    @Mock
+    private BluetoothGattWrapper mMockBluetoothGattWrapper;
+    @Mock
+    private BluetoothDevice mMockBluetoothDevice;
+    @Mock
+    private BluetoothOperationExecutor mMockBluetoothOperationExecutor;
+    @Mock
+    private BluetoothGattService mMockBluetoothGattService;
+    @Mock
+    private BluetoothGattService mMockBluetoothGattService2;
+    @Mock
+    private BluetoothGattCharacteristic mMockBluetoothGattCharacteristic;
+    @Mock
+    private BluetoothGattCharacteristic mMockBluetoothGattCharacteristic2;
+    @Mock
+    private BluetoothGattDescriptor mMockBluetoothGattDescriptor;
+    @Mock
+    private BluetoothGattConnection.CharacteristicChangeListener mMockCharChangeListener;
+    @Mock
+    private BluetoothGattConnection.ChangeObserver mMockChangeObserver;
+    @Mock
+    private BluetoothGattConnection.ConnectionCloseListener mMockConnectionCloseListener;
+
+    @Captor
+    private ArgumentCaptor<Operation<?>> mOperationCaptor;
+    @Captor
+    private ArgumentCaptor<SynchronousOperation<?>> mSynchronousOperationCaptor;
+    @Captor
+    private ArgumentCaptor<BluetoothGattCharacteristic> mCharacteristicCaptor;
+    @Captor
+    private ArgumentCaptor<BluetoothGattDescriptor> mDescriptorCaptor;
+
+    private BluetoothGattConnection mBluetoothGattConnection;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        initMocks(this);
+
+        mBluetoothGattConnection = new BluetoothGattConnection(
+                mMockBluetoothGattWrapper,
+                mMockBluetoothOperationExecutor,
+                CONNECTION_OPTIONS);
+        mBluetoothGattConnection.onConnected();
+
+        when(mMockBluetoothGattWrapper.getDevice()).thenReturn(mMockBluetoothDevice);
+        when(mMockBluetoothGattWrapper.discoverServices()).thenReturn(true);
+        when(mMockBluetoothGattWrapper.refresh()).thenReturn(true);
+        when(mMockBluetoothGattWrapper.readCharacteristic(mMockBluetoothGattCharacteristic))
+                .thenReturn(true);
+        when(mMockBluetoothGattWrapper
+                .writeCharacteristic(ArgumentMatchers.<BluetoothGattCharacteristic>any(), any(),
+                        anyInt()))
+                .thenReturn(BluetoothStatusCodes.SUCCESS);
+        when(mMockBluetoothGattWrapper.readDescriptor(mMockBluetoothGattDescriptor))
+                .thenReturn(true);
+        when(mMockBluetoothGattWrapper.writeDescriptor(
+                ArgumentMatchers.<BluetoothGattDescriptor>any(), any()))
+                .thenReturn(BluetoothStatusCodes.SUCCESS);
+        when(mMockBluetoothGattWrapper.readRemoteRssi()).thenReturn(true);
+        when(mMockBluetoothGattWrapper.requestConnectionPriority(CONNECTION_PRIORITY))
+                .thenReturn(true);
+        when(mMockBluetoothGattWrapper.requestMtu(MTU_REQUEST)).thenReturn(true);
+        when(mMockBluetoothGattWrapper.getServices())
+                .thenReturn(Arrays.asList(mMockBluetoothGattService));
+        when(mMockBluetoothGattService.getUuid()).thenReturn(SERVICE_UUID);
+        when(mMockBluetoothGattService.getCharacteristics())
+                .thenReturn(Arrays.asList(mMockBluetoothGattCharacteristic));
+        when(mMockBluetoothGattCharacteristic.getUuid()).thenReturn(CHARACTERISTIC_UUID);
+        when(mMockBluetoothGattCharacteristic.getProperties())
+                .thenReturn(
+                        BluetoothGattCharacteristic.PROPERTY_NOTIFY
+                                | BluetoothGattCharacteristic.PROPERTY_WRITE);
+        BluetoothGattDescriptor clientConfigDescriptor =
+                new BluetoothGattDescriptor(
+                        ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION,
+                        BluetoothGattDescriptor.PERMISSION_WRITE);
+        when(mMockBluetoothGattCharacteristic.getDescriptor(
+                ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION))
+                .thenReturn(clientConfigDescriptor);
+        when(mMockBluetoothGattCharacteristic.getDescriptors())
+                .thenReturn(Arrays.asList(mMockBluetoothGattDescriptor, clientConfigDescriptor));
+        when(mMockBluetoothGattDescriptor.getUuid()).thenReturn(DESCRIPTOR_UUID);
+        when(mMockBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getDevice() {
+        BluetoothDevice result = mBluetoothGattConnection.getDevice();
+
+        assertThat(result).isEqualTo(mMockBluetoothDevice);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getConnectionOptions() {
+        BluetoothGattHelper.ConnectionOptions result = mBluetoothGattConnection
+                .getConnectionOptions();
+
+        assertThat(result).isSameInstanceAs(CONNECTION_OPTIONS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_isConnected_false_beforeConnection() {
+        mBluetoothGattConnection = new BluetoothGattConnection(
+                mMockBluetoothGattWrapper,
+                mMockBluetoothOperationExecutor,
+                CONNECTION_OPTIONS);
+
+        boolean result = mBluetoothGattConnection.isConnected();
+
+        assertThat(result).isFalse();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_isConnected_true_afterConnection() {
+        boolean result = mBluetoothGattConnection.isConnected();
+
+        assertThat(result).isTrue();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_isConnected_false_afterDisconnection() {
+        mBluetoothGattConnection.onClosed();
+
+        boolean result = mBluetoothGattConnection.isConnected();
+
+        assertThat(result).isFalse();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getService_notDiscovered() throws Exception {
+        BluetoothGattService result = mBluetoothGattConnection.getService(SERVICE_UUID);
+        verify(mMockBluetoothOperationExecutor).execute(mSynchronousOperationCaptor.capture());
+        mSynchronousOperationCaptor.getValue().call();
+        verify(mMockBluetoothOperationExecutor)
+                .execute(
+                        mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+
+        assertThat(result).isEqualTo(mMockBluetoothGattService);
+        verify(mMockBluetoothGattWrapper).discoverServices();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getService_alreadyDiscovered() throws Exception {
+        mBluetoothGattConnection.getService(SERVICE_UUID);
+        verify(mMockBluetoothOperationExecutor).execute(mSynchronousOperationCaptor.capture());
+        mSynchronousOperationCaptor.getValue().call();
+        reset(mMockBluetoothOperationExecutor);
+
+        BluetoothGattService result = mBluetoothGattConnection.getService(SERVICE_UUID);
+
+        assertThat(result).isEqualTo(mMockBluetoothGattService);
+        // Verify that service discovery has been done only once
+        verifyNoMoreInteractions(mMockBluetoothOperationExecutor);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getService_notFound() throws Exception {
+        when(mMockBluetoothGattWrapper.getServices()).thenReturn(
+                Arrays.<BluetoothGattService>asList());
+
+        try {
+            mBluetoothGattConnection.getService(SERVICE_UUID);
+            fail("Expected BluetoothException");
+        } catch (BluetoothException expected) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getService_moreThanOne() throws Exception {
+        when(mMockBluetoothGattWrapper.getServices())
+                .thenReturn(Arrays.asList(mMockBluetoothGattService, mMockBluetoothGattService));
+
+        try {
+            mBluetoothGattConnection.getService(SERVICE_UUID);
+            fail("Expected BluetoothException");
+        } catch (BluetoothException expected) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getCharacteristic() throws Exception {
+        BluetoothGattCharacteristic result =
+                mBluetoothGattConnection.getCharacteristic(SERVICE_UUID, CHARACTERISTIC_UUID);
+
+        assertThat(result).isEqualTo(mMockBluetoothGattCharacteristic);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getCharacteristic_notFound() throws Exception {
+        when(mMockBluetoothGattService.getCharacteristics())
+                .thenReturn(Arrays.<BluetoothGattCharacteristic>asList());
+
+        try {
+            mBluetoothGattConnection.getCharacteristic(SERVICE_UUID, CHARACTERISTIC_UUID);
+            fail("Expected BluetoothException");
+        } catch (BluetoothException expected) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getCharacteristic_moreThanOne() throws Exception {
+        when(mMockBluetoothGattService.getCharacteristics())
+                .thenReturn(
+                        Arrays.asList(mMockBluetoothGattCharacteristic,
+                                mMockBluetoothGattCharacteristic));
+
+        try {
+            mBluetoothGattConnection.getCharacteristic(SERVICE_UUID, CHARACTERISTIC_UUID);
+            fail("Expected BluetoothException");
+        } catch (BluetoothException expected) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getCharacteristic_moreThanOneService() throws Exception {
+        // Add a new service with the same service UUID as our existing one, but add a different
+        // characteristic inside of it.
+        when(mMockBluetoothGattWrapper.getServices())
+                .thenReturn(Arrays.asList(mMockBluetoothGattService, mMockBluetoothGattService2));
+        when(mMockBluetoothGattService2.getUuid()).thenReturn(SERVICE_UUID);
+        when(mMockBluetoothGattService2.getCharacteristics())
+                .thenReturn(Arrays.asList(mMockBluetoothGattCharacteristic2));
+        when(mMockBluetoothGattCharacteristic2.getUuid())
+                .thenReturn(
+                        new UUID(
+                                CHARACTERISTIC_UUID.getMostSignificantBits(),
+                                CHARACTERISTIC_UUID.getLeastSignificantBits() + 1));
+        when(mMockBluetoothGattCharacteristic2.getProperties())
+                .thenReturn(
+                        BluetoothGattCharacteristic.PROPERTY_NOTIFY
+                                | BluetoothGattCharacteristic.PROPERTY_WRITE);
+
+        mBluetoothGattConnection.getCharacteristic(SERVICE_UUID, CHARACTERISTIC_UUID);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getDescriptor() throws Exception {
+        when(mMockBluetoothGattCharacteristic.getDescriptors())
+                .thenReturn(Arrays.asList(mMockBluetoothGattDescriptor));
+
+        BluetoothGattDescriptor result =
+                mBluetoothGattConnection
+                        .getDescriptor(SERVICE_UUID, CHARACTERISTIC_UUID, DESCRIPTOR_UUID);
+
+        assertThat(result).isEqualTo(mMockBluetoothGattDescriptor);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getDescriptor_notFound() throws Exception {
+        when(mMockBluetoothGattCharacteristic.getDescriptors())
+                .thenReturn(Arrays.<BluetoothGattDescriptor>asList());
+
+        try {
+            mBluetoothGattConnection
+                    .getDescriptor(SERVICE_UUID, CHARACTERISTIC_UUID, DESCRIPTOR_UUID);
+            fail("Expected BluetoothException");
+        } catch (BluetoothException expected) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getDescriptor_moreThanOne() throws Exception {
+        when(mMockBluetoothGattCharacteristic.getDescriptors())
+                .thenReturn(
+                        Arrays.asList(mMockBluetoothGattDescriptor, mMockBluetoothGattDescriptor));
+
+        try {
+            mBluetoothGattConnection
+                    .getDescriptor(SERVICE_UUID, CHARACTERISTIC_UUID, DESCRIPTOR_UUID);
+            fail("Expected BluetoothException");
+        } catch (BluetoothException expected) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_discoverServices() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new SynchronousOperation<>(
+                        mMockBluetoothOperationExecutor, OperationType.NOTIFICATION_CHANGE)))
+                .thenReturn(mMockChangeObserver);
+
+        mBluetoothGattConnection.discoverServices();
+
+        verify(mMockBluetoothOperationExecutor).execute(mSynchronousOperationCaptor.capture());
+        mSynchronousOperationCaptor.getValue().call();
+        verify(mMockBluetoothOperationExecutor)
+                .execute(
+                        mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).discoverServices();
+        verify(mMockBluetoothGattWrapper, never()).refresh();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_discoverServices_serviceChange() throws Exception {
+        when(mMockBluetoothGattWrapper.getService(ReservedUuids.Services.GENERIC_ATTRIBUTE))
+                .thenReturn(mMockBluetoothGattService);
+        when(mMockBluetoothGattService
+                .getCharacteristic(ReservedUuids.Characteristics.SERVICE_CHANGE))
+                .thenReturn(mMockBluetoothGattCharacteristic);
+
+        mBluetoothGattConnection.discoverServices();
+
+        verify(mMockBluetoothOperationExecutor).execute(mSynchronousOperationCaptor.capture());
+        mSynchronousOperationCaptor.getValue().call();
+        verify(mMockBluetoothOperationExecutor, times(2))
+                .execute(
+                        mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
+        verify(mMockBluetoothGattWrapper).refresh();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_discoverServices_SelfDefinedServiceDynamic() throws Exception {
+        when(mMockBluetoothGattWrapper.getService(BluetoothConsts.SERVICE_DYNAMIC_SERVICE))
+                .thenReturn(mMockBluetoothGattService);
+        when(mMockBluetoothGattService
+                .getCharacteristic(BluetoothConsts.SERVICE_DYNAMIC_CHARACTERISTIC))
+                .thenReturn(mMockBluetoothGattCharacteristic);
+
+        mBluetoothGattConnection.discoverServices();
+
+        verify(mMockBluetoothOperationExecutor).execute(mSynchronousOperationCaptor.capture());
+        mSynchronousOperationCaptor.getValue().call();
+        verify(mMockBluetoothOperationExecutor, times(2))
+                .execute(
+                        mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
+        verify(mMockBluetoothGattWrapper).refresh();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_discoverServices_refreshWithGattErrorOnMncAbove() throws Exception {
+        if (VERSION.SDK_INT <= VERSION_CODES.LOLLIPOP_MR1) {
+            return;
+        }
+        mBluetoothGattConnection.discoverServices();
+        verify(mMockBluetoothOperationExecutor).execute(mSynchronousOperationCaptor.capture());
+
+        doThrow(new BluetoothGattException("fail", BluetoothGattConnection.GATT_ERROR))
+                .doReturn(null)
+                .when(mMockBluetoothOperationExecutor)
+                .execute(isA(Operation.class),
+                        eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
+        mSynchronousOperationCaptor.getValue().call();
+        verify(mMockBluetoothOperationExecutor, times(2))
+                .execute(
+                        mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
+        verify(mMockBluetoothGattWrapper).refresh();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_discoverServices_refreshWithGattInternalErrorOnMncAbove() throws Exception {
+        if (VERSION.SDK_INT <= VERSION_CODES.LOLLIPOP_MR1) {
+            return;
+        }
+        mBluetoothGattConnection.discoverServices();
+        verify(mMockBluetoothOperationExecutor).execute(mSynchronousOperationCaptor.capture());
+
+        doThrow(new BluetoothGattException("fail", BluetoothGattConnection.GATT_INTERNAL_ERROR))
+                .doReturn(null)
+                .when(mMockBluetoothOperationExecutor)
+                .execute(isA(Operation.class),
+                        eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
+        mSynchronousOperationCaptor.getValue().call();
+        verify(mMockBluetoothOperationExecutor, times(2))
+                .execute(
+                        mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
+        verify(mMockBluetoothGattWrapper).refresh();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_discoverServices_dynamicServices_notBonded() throws Exception {
+        when(mMockBluetoothGattWrapper.getService(ReservedUuids.Services.GENERIC_ATTRIBUTE))
+                .thenReturn(mMockBluetoothGattService);
+        when(mMockBluetoothGattService
+                .getCharacteristic(ReservedUuids.Characteristics.SERVICE_CHANGE))
+                .thenReturn(mMockBluetoothGattCharacteristic);
+        when(mMockBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+
+        mBluetoothGattConnection.discoverServices();
+
+        verify(mMockBluetoothGattWrapper, never()).refresh();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_readCharacteristic() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new Operation<byte[]>(
+                        OperationType.READ_CHARACTERISTIC,
+                        mMockBluetoothGattWrapper,
+                        mMockBluetoothGattCharacteristic),
+                BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
+                .thenReturn(DATA);
+
+        byte[] result = mBluetoothGattConnection
+                .readCharacteristic(mMockBluetoothGattCharacteristic);
+
+        assertThat(result).isEqualTo(DATA);
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mOperationCaptor.capture(), anyLong());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).readCharacteristic(mMockBluetoothGattCharacteristic);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_readCharacteristic_by_uuid() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new Operation<byte[]>(
+                        OperationType.READ_CHARACTERISTIC,
+                        mMockBluetoothGattWrapper,
+                        mMockBluetoothGattCharacteristic),
+                BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
+                .thenReturn(DATA);
+
+        byte[] result = mBluetoothGattConnection
+                .readCharacteristic(SERVICE_UUID, CHARACTERISTIC_UUID);
+
+        assertThat(result).isEqualTo(DATA);
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mOperationCaptor.capture(), anyLong());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).readCharacteristic(mMockBluetoothGattCharacteristic);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_writeCharacteristic() throws Exception {
+        BluetoothGattCharacteristic characteristic =
+                new BluetoothGattCharacteristic(
+                        CHARACTERISTIC_UUID, BluetoothGattCharacteristic.PROPERTY_WRITE, 0);
+        mBluetoothGattConnection.writeCharacteristic(characteristic, DATA);
+
+        verify(mMockBluetoothOperationExecutor)
+                .execute(mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).writeCharacteristic(mCharacteristicCaptor.capture(),
+                eq(DATA), eq(characteristic.getWriteType()));
+        BluetoothGattCharacteristic writtenCharacteristic = mCharacteristicCaptor.getValue();
+        assertThat(writtenCharacteristic.getUuid()).isEqualTo(CHARACTERISTIC_UUID);
+        assertThat(writtenCharacteristic).isEqualTo(characteristic);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_writeCharacteristic_by_uuid() throws Exception {
+        mBluetoothGattConnection.writeCharacteristic(SERVICE_UUID, CHARACTERISTIC_UUID, DATA);
+
+        verify(mMockBluetoothOperationExecutor)
+                .execute(mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).writeCharacteristic(mCharacteristicCaptor.capture(),
+                eq(DATA), anyInt());
+        BluetoothGattCharacteristic writtenCharacteristic = mCharacteristicCaptor.getValue();
+        assertThat(writtenCharacteristic.getUuid()).isEqualTo(CHARACTERISTIC_UUID);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_readDescriptor() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new Operation<byte[]>(
+                        OperationType.READ_DESCRIPTOR, mMockBluetoothGattWrapper,
+                        mMockBluetoothGattDescriptor),
+                BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
+                .thenReturn(DATA);
+
+        byte[] result = mBluetoothGattConnection.readDescriptor(mMockBluetoothGattDescriptor);
+
+        assertThat(result).isEqualTo(DATA);
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mOperationCaptor.capture(), anyLong());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).readDescriptor(mMockBluetoothGattDescriptor);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_readDescriptor_by_uuid() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new Operation<byte[]>(
+                        OperationType.READ_DESCRIPTOR, mMockBluetoothGattWrapper,
+                        mMockBluetoothGattDescriptor),
+                BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
+                .thenReturn(DATA);
+
+        byte[] result =
+                mBluetoothGattConnection
+                        .readDescriptor(SERVICE_UUID, CHARACTERISTIC_UUID, DESCRIPTOR_UUID);
+
+        assertThat(result).isEqualTo(DATA);
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mOperationCaptor.capture(), anyLong());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).readDescriptor(mMockBluetoothGattDescriptor);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_writeDescriptor() throws Exception {
+        BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(DESCRIPTOR_UUID, 0);
+        mBluetoothGattConnection.writeDescriptor(descriptor, DATA);
+
+        verify(mMockBluetoothOperationExecutor)
+                .execute(mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(), eq(DATA));
+        BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
+        assertThat(writtenDescriptor.getUuid()).isEqualTo(DESCRIPTOR_UUID);
+        assertThat(writtenDescriptor).isEqualTo(descriptor);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_writeDescriptor_by_uuid() throws Exception {
+        mBluetoothGattConnection.writeDescriptor(
+                SERVICE_UUID, CHARACTERISTIC_UUID, DESCRIPTOR_UUID, DATA);
+
+        verify(mMockBluetoothOperationExecutor)
+                .execute(mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(), eq(DATA));
+        BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
+        assertThat(writtenDescriptor.getUuid()).isEqualTo(DESCRIPTOR_UUID);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_readRemoteRssi() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new Operation<Integer>(OperationType.READ_RSSI, mMockBluetoothGattWrapper),
+                BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
+                .thenReturn(RSSI);
+
+        int result = mBluetoothGattConnection.readRemoteRssi();
+
+        assertThat(result).isEqualTo(RSSI);
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(
+                        mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).readRemoteRssi();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getMaxDataPacketSize() throws Exception {
+        int result = mBluetoothGattConnection.getMaxDataPacketSize();
+
+        assertThat(result).isEqualTo(mBluetoothGattConnection.getMtu() - 3);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSetNotificationEnabled_indication_enable() throws Exception {
+        when(mMockBluetoothGattCharacteristic.getProperties())
+                .thenReturn(BluetoothGattCharacteristic.PROPERTY_INDICATE);
+
+        mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic, true);
+
+        verify(mMockBluetoothGattWrapper)
+                .setCharacteristicNotification(mMockBluetoothGattCharacteristic, true);
+        verify(mMockBluetoothOperationExecutor).execute(mOperationCaptor.capture(), anyLong());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(),
+                eq(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE));
+        BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
+        assertThat(writtenDescriptor.getUuid())
+                .isEqualTo(ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_getNotificationEnabled_notification_enable() throws Exception {
+        mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic, true);
+
+        verify(mMockBluetoothGattWrapper)
+                .setCharacteristicNotification(mMockBluetoothGattCharacteristic, true);
+        verify(mMockBluetoothOperationExecutor).execute(mOperationCaptor.capture(), anyLong());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(),
+                eq(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
+        BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
+        assertThat(writtenDescriptor.getUuid())
+                .isEqualTo(ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_setNotificationEnabled_indication_disable() throws Exception {
+        when(mMockBluetoothGattCharacteristic.getProperties())
+                .thenReturn(BluetoothGattCharacteristic.PROPERTY_INDICATE);
+
+        mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic, false);
+
+        verify(mMockBluetoothGattWrapper)
+                .setCharacteristicNotification(mMockBluetoothGattCharacteristic, false);
+        verify(mMockBluetoothOperationExecutor).execute(mOperationCaptor.capture(), anyLong());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(),
+                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
+        BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
+        assertThat(writtenDescriptor.getUuid())
+                .isEqualTo(ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_setNotificationEnabled_notification_disable() throws Exception {
+        mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic, false);
+
+        verify(mMockBluetoothGattWrapper)
+                .setCharacteristicNotification(mMockBluetoothGattCharacteristic, false);
+        verify(mMockBluetoothOperationExecutor).execute(mOperationCaptor.capture(), anyLong());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(),
+                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
+        BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
+        assertThat(writtenDescriptor.getUuid())
+                .isEqualTo(ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_setNotificationEnabled_failure() throws Exception {
+        when(mMockBluetoothGattCharacteristic.getProperties())
+                .thenReturn(BluetoothGattCharacteristic.PROPERTY_READ);
+
+        try {
+            mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic,
+                    true);
+            fail("BluetoothException was expected");
+        } catch (BluetoothException expected) {
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_enableNotification_Uuid() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new SynchronousOperation<>(
+                        mMockBluetoothOperationExecutor,
+                        OperationType.NOTIFICATION_CHANGE,
+                        mMockBluetoothGattCharacteristic)))
+                .thenReturn(mMockChangeObserver);
+        mBluetoothGattConnection.enableNotification(SERVICE_UUID, CHARACTERISTIC_UUID);
+
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mSynchronousOperationCaptor.capture());
+        ((ChangeObserver) mSynchronousOperationCaptor.getValue().call())
+                .setListener(mMockCharChangeListener);
+        mBluetoothGattConnection.onCharacteristicChanged(mMockBluetoothGattCharacteristic, DATA);
+        verify(mMockCharChangeListener).onValueChange(DATA);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_enableNotification() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new SynchronousOperation<>(
+                        mMockBluetoothOperationExecutor,
+                        OperationType.NOTIFICATION_CHANGE,
+                        mMockBluetoothGattCharacteristic)))
+                .thenReturn(mMockChangeObserver);
+        mBluetoothGattConnection.enableNotification(mMockBluetoothGattCharacteristic);
+
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mSynchronousOperationCaptor.capture());
+        ((ChangeObserver) mSynchronousOperationCaptor.getValue().call())
+                .setListener(mMockCharChangeListener);
+
+        mBluetoothGattConnection.onCharacteristicChanged(mMockBluetoothGattCharacteristic, DATA);
+
+        verify(mMockCharChangeListener).onValueChange(DATA);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_enableNotification_observe() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new SynchronousOperation<>(
+                        mMockBluetoothOperationExecutor,
+                        OperationType.NOTIFICATION_CHANGE,
+                        mMockBluetoothGattCharacteristic)))
+                .thenReturn(mMockChangeObserver);
+        mBluetoothGattConnection.enableNotification(mMockBluetoothGattCharacteristic);
+
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mSynchronousOperationCaptor.capture());
+        ChangeObserver changeObserver = (ChangeObserver) mSynchronousOperationCaptor.getValue()
+                .call();
+        mBluetoothGattConnection.onCharacteristicChanged(mMockBluetoothGattCharacteristic, DATA);
+        assertThat(changeObserver.waitForUpdate(TimeUnit.SECONDS.toMillis(1))).isEqualTo(DATA);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_disableNotification_Uuid() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new SynchronousOperation<>(
+                        OperationType.NOTIFICATION_CHANGE, mMockBluetoothGattCharacteristic)))
+                .thenReturn(mMockChangeObserver);
+        mBluetoothGattConnection
+                .enableNotification(SERVICE_UUID, CHARACTERISTIC_UUID)
+                .setListener(mMockCharChangeListener);
+
+        mBluetoothGattConnection.disableNotification(SERVICE_UUID, CHARACTERISTIC_UUID);
+
+        mBluetoothGattConnection.onCharacteristicChanged(mMockBluetoothGattCharacteristic, DATA);
+        verify(mMockCharChangeListener, never()).onValueChange(DATA);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_disableNotification() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new SynchronousOperation<ChangeObserver>(
+                        OperationType.NOTIFICATION_CHANGE, mMockBluetoothGattCharacteristic)))
+                .thenReturn(mMockChangeObserver);
+        mBluetoothGattConnection
+                .enableNotification(mMockBluetoothGattCharacteristic)
+                .setListener(mMockCharChangeListener);
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mSynchronousOperationCaptor.capture());
+        mSynchronousOperationCaptor.getValue().call();
+
+        mBluetoothGattConnection.disableNotification(mMockBluetoothGattCharacteristic);
+        verify(mMockBluetoothOperationExecutor).execute(mSynchronousOperationCaptor.capture());
+        mSynchronousOperationCaptor.getValue().call();
+
+        mBluetoothGattConnection.onCharacteristicChanged(mMockBluetoothGattCharacteristic, DATA);
+        verify(mMockCharChangeListener, never()).onValueChange(DATA);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_addCloseListener() throws Exception {
+        mBluetoothGattConnection.addCloseListener(mMockConnectionCloseListener);
+
+        mBluetoothGattConnection.onClosed();
+        verify(mMockConnectionCloseListener).onClose();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_removeCloseListener() throws Exception {
+        mBluetoothGattConnection.addCloseListener(mMockConnectionCloseListener);
+
+        mBluetoothGattConnection.removeCloseListener(mMockConnectionCloseListener);
+
+        mBluetoothGattConnection.onClosed();
+        verify(mMockConnectionCloseListener, never()).onClose();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_close() throws Exception {
+        mBluetoothGattConnection.close();
+
+        verify(mMockBluetoothOperationExecutor)
+                .execute(mOperationCaptor.capture(),
+                        eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_onClosed() throws Exception {
+        mBluetoothGattConnection.onClosed();
+
+        verify(mMockBluetoothOperationExecutor, never())
+                .execute(mOperationCaptor.capture(), anyLong());
+        verify(mMockBluetoothGattWrapper).close();
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelperTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelperTest.java
new file mode 100644
index 0000000..7c20be1
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelperTest.java
@@ -0,0 +1,675 @@
+/*
+ * 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.server.nearby.common.bluetooth.gatt;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanSettings;
+import android.content.Context;
+import android.os.ParcelUuid;
+import android.test.mock.MockContext;
+
+import androidx.test.filters.SdkSuppress;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.ConnectionOptions;
+import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.OperationType;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothAdapter;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattWrapper;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.BluetoothLeScanner;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.ScanCallback;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.ScanResult;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.BluetoothOperationTimeoutException;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.Operation;
+
+import junit.framework.TestCase;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+
+import java.util.Arrays;
+import java.util.UUID;
+
+/**
+ * Unit tests for {@link BluetoothGattHelper}.
+ */
+public class BluetoothGattHelperTest extends TestCase {
+
+    private static final UUID SERVICE_UUID = UUID.randomUUID();
+    private static final int GATT_STATUS = 1234;
+    private static final Operation<BluetoothDevice> SCANNING_OPERATION =
+            new Operation<BluetoothDevice>(OperationType.SCAN);
+    private static final byte[] CHARACTERISTIC_VALUE = "characteristic_value".getBytes();
+    private static final byte[] DESCRIPTOR_VALUE = "descriptor_value".getBytes();
+    private static final int RSSI = -63;
+    private static final int MTU = 50;
+    private static final long CONNECT_TIMEOUT_MILLIS = 5000;
+
+    private Context mMockApplicationContext = new MockContext();
+    @Mock
+    private BluetoothAdapter mMockBluetoothAdapter;
+    @Mock
+    private BluetoothLeScanner mMockBluetoothLeScanner;
+    @Mock
+    private BluetoothOperationExecutor mMockBluetoothOperationExecutor;
+    @Mock
+    private BluetoothDevice mMockBluetoothDevice;
+    @Mock
+    private BluetoothGattConnection mMockBluetoothGattConnection;
+    @Mock
+    private BluetoothGattWrapper mMockBluetoothGattWrapper;
+    @Mock
+    private BluetoothGattCharacteristic mMockBluetoothGattCharacteristic;
+    @Mock
+    private BluetoothGattDescriptor mMockBluetoothGattDescriptor;
+    @Mock
+    private ScanResult mMockScanResult;
+
+    @Captor
+    private ArgumentCaptor<Operation<?>> mOperationCaptor;
+    @Captor
+    private ArgumentCaptor<ScanSettings> mScanSettingsCaptor;
+
+    private BluetoothGattHelper mBluetoothGattHelper;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        initMocks(this);
+
+        mBluetoothGattHelper = new BluetoothGattHelper(
+                mMockApplicationContext,
+                mMockBluetoothAdapter,
+                mMockBluetoothOperationExecutor);
+
+        when(mMockBluetoothAdapter.getBluetoothLeScanner()).thenReturn(mMockBluetoothLeScanner);
+        when(mMockBluetoothOperationExecutor.executeNonnull(SCANNING_OPERATION,
+                BluetoothGattHelper.LOW_LATENCY_SCAN_MILLIS)).thenReturn(mMockBluetoothDevice);
+        when(mMockBluetoothOperationExecutor.executeNonnull(SCANNING_OPERATION)).thenReturn(
+                mMockBluetoothDevice);
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new Operation<BluetoothGattConnection>(OperationType.CONNECT, mMockBluetoothDevice),
+                CONNECT_TIMEOUT_MILLIS))
+                .thenReturn(mMockBluetoothGattConnection);
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new Operation<BluetoothGattConnection>(OperationType.CONNECT,
+                        mMockBluetoothDevice)))
+                .thenReturn(mMockBluetoothGattConnection);
+        when(mMockBluetoothGattCharacteristic.getValue()).thenReturn(CHARACTERISTIC_VALUE);
+        when(mMockBluetoothGattDescriptor.getValue()).thenReturn(DESCRIPTOR_VALUE);
+        when(mMockScanResult.getDevice()).thenReturn(mMockBluetoothDevice);
+        when(mMockBluetoothGattWrapper.getDevice()).thenReturn(mMockBluetoothDevice);
+        when(mMockBluetoothDevice.connectGatt(eq(mMockApplicationContext), anyBoolean(),
+                eq(mBluetoothGattHelper.mBluetoothGattCallback))).thenReturn(
+                mMockBluetoothGattWrapper);
+        when(mMockBluetoothDevice.connectGatt(eq(mMockApplicationContext), anyBoolean(),
+                eq(mBluetoothGattHelper.mBluetoothGattCallback), anyInt()))
+                .thenReturn(mMockBluetoothGattWrapper);
+        when(mMockBluetoothGattConnection.getConnectionOptions())
+                .thenReturn(ConnectionOptions.builder().build());
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_autoConnect_uuid_success_lowLatency() throws Exception {
+        BluetoothGattConnection result = mBluetoothGattHelper.autoConnect(SERVICE_UUID);
+
+        assertThat(result).isEqualTo(mMockBluetoothGattConnection);
+        verify(mMockBluetoothOperationExecutor, atLeastOnce())
+                .executeNonnull(mOperationCaptor.capture(),
+                        anyLong());
+        for (Operation<?> operation : mOperationCaptor.getAllValues()) {
+            operation.run();
+        }
+        verify(mMockBluetoothLeScanner).startScan(eq(Arrays.asList(
+                new ScanFilter.Builder().setServiceUuid(new ParcelUuid(SERVICE_UUID)).build())),
+                mScanSettingsCaptor.capture(), eq(mBluetoothGattHelper.mScanCallback));
+        assertThat(mScanSettingsCaptor.getValue().getScanMode()).isEqualTo(
+                ScanSettings.SCAN_MODE_LOW_LATENCY);
+        verify(mMockBluetoothLeScanner).stopScan(mBluetoothGattHelper.mScanCallback);
+        verifyNoMoreInteractions(mMockBluetoothLeScanner);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_autoConnect_uuid_success_lowPower() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(SCANNING_OPERATION,
+                BluetoothGattHelper.LOW_LATENCY_SCAN_MILLIS)).thenThrow(
+                new BluetoothOperationTimeoutException("Timeout"));
+
+        BluetoothGattConnection result = mBluetoothGattHelper.autoConnect(SERVICE_UUID);
+
+        assertThat(result).isEqualTo(mMockBluetoothGattConnection);
+        verify(mMockBluetoothOperationExecutor).executeNonnull(mOperationCaptor.capture());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothLeScanner).startScan(eq(Arrays.asList(
+                new ScanFilter.Builder().setServiceUuid(new ParcelUuid(SERVICE_UUID)).build())),
+                mScanSettingsCaptor.capture(), eq(mBluetoothGattHelper.mScanCallback));
+        assertThat(mScanSettingsCaptor.getValue().getScanMode()).isEqualTo(
+                ScanSettings.SCAN_MODE_LOW_POWER);
+        verify(mMockBluetoothLeScanner, times(2)).stopScan(mBluetoothGattHelper.mScanCallback);
+        verifyNoMoreInteractions(mMockBluetoothLeScanner);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_autoConnect_uuid_success_afterRetry() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new Operation<BluetoothGattConnection>(OperationType.CONNECT, mMockBluetoothDevice),
+                BluetoothGattHelper.LOW_LATENCY_SCAN_MILLIS))
+                .thenThrow(new BluetoothException("first attempt fails!"))
+                .thenReturn(mMockBluetoothGattConnection);
+
+        BluetoothGattConnection result = mBluetoothGattHelper.autoConnect(SERVICE_UUID);
+
+        assertThat(result).isEqualTo(mMockBluetoothGattConnection);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_autoConnect_uuid_failure_scanning() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(SCANNING_OPERATION,
+                BluetoothGattHelper.LOW_LATENCY_SCAN_MILLIS)).thenThrow(
+                new BluetoothException("Scanning failed"));
+
+        try {
+            mBluetoothGattHelper.autoConnect(SERVICE_UUID);
+            fail("BluetoothException expected");
+        } catch (BluetoothException e) {
+            // expected
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_autoConnect_uuid_failure_connecting() throws Exception {
+        when(mMockBluetoothOperationExecutor.executeNonnull(
+                new Operation<BluetoothGattConnection>(OperationType.CONNECT, mMockBluetoothDevice),
+                CONNECT_TIMEOUT_MILLIS))
+                .thenThrow(new BluetoothException("Connect failed"));
+
+        try {
+            mBluetoothGattHelper.autoConnect(SERVICE_UUID);
+            fail("BluetoothException expected");
+        } catch (BluetoothException e) {
+            // expected
+        }
+        verify(mMockBluetoothOperationExecutor, times(3))
+                .executeNonnull(
+                        new Operation<BluetoothGattConnection>(OperationType.CONNECT,
+                                mMockBluetoothDevice),
+                        CONNECT_TIMEOUT_MILLIS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_autoConnect_uuid_failure_noBle() throws Exception {
+        when(mMockBluetoothAdapter.getBluetoothLeScanner()).thenReturn(null);
+
+        try {
+            mBluetoothGattHelper.autoConnect(SERVICE_UUID);
+            fail("BluetoothException expected");
+        } catch (BluetoothException e) {
+            // expected
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_connect() throws Exception {
+        BluetoothGattConnection result = mBluetoothGattHelper.connect(mMockBluetoothDevice);
+
+        assertThat(result).isEqualTo(mMockBluetoothGattConnection);
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mOperationCaptor.capture(), eq(CONNECT_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothDevice).connectGatt(mMockApplicationContext, false,
+                mBluetoothGattHelper.mBluetoothGattCallback,
+                android.bluetooth.BluetoothDevice.TRANSPORT_LE);
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper).getDevice())
+                .isEqualTo(mMockBluetoothDevice);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_connect_withOptionAutoConnect_success() throws Exception {
+        BluetoothGattConnection result = mBluetoothGattHelper
+                .connect(
+                        mMockBluetoothDevice,
+                        ConnectionOptions.builder()
+                                .setAutoConnect(true)
+                                .build());
+
+        assertThat(result).isEqualTo(mMockBluetoothGattConnection);
+        verify(mMockBluetoothOperationExecutor).executeNonnull(mOperationCaptor.capture());
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothDevice).connectGatt(mMockApplicationContext, true,
+                mBluetoothGattHelper.mBluetoothGattCallback,
+                android.bluetooth.BluetoothDevice.TRANSPORT_LE);
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)
+                .getConnectionOptions())
+                .isEqualTo(ConnectionOptions.builder()
+                        .setAutoConnect(true)
+                        .build());
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_connect_withOptionAutoConnect_failure_nullResult() throws Exception {
+        when(mMockBluetoothDevice.connectGatt(eq(mMockApplicationContext), anyBoolean(),
+                eq(mBluetoothGattHelper.mBluetoothGattCallback),
+                eq(android.bluetooth.BluetoothDevice.TRANSPORT_LE))).thenReturn(null);
+
+        try {
+            mBluetoothGattHelper.connect(
+                    mMockBluetoothDevice,
+                    ConnectionOptions.builder()
+                            .setAutoConnect(true)
+                            .build());
+            verify(mMockBluetoothOperationExecutor).executeNonnull(mOperationCaptor.capture());
+            mOperationCaptor.getValue().run();
+            fail("BluetoothException expected");
+        } catch (BluetoothException e) {
+            // expected
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_connect_withOptionRequestConnectionPriority_success() throws Exception {
+        // Operation succeeds on the 3rd try.
+        when(mMockBluetoothGattWrapper
+                .requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH))
+                .thenReturn(false)
+                .thenReturn(false)
+                .thenReturn(true);
+
+        BluetoothGattConnection result = mBluetoothGattHelper
+                .connect(
+                        mMockBluetoothDevice,
+                        ConnectionOptions.builder()
+                                .setConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH)
+                                .build());
+
+        assertThat(result).isEqualTo(mMockBluetoothGattConnection);
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mOperationCaptor.capture(), eq(CONNECT_TIMEOUT_MILLIS));
+        mOperationCaptor.getValue().run();
+        verify(mMockBluetoothDevice).connectGatt(mMockApplicationContext, false,
+                mBluetoothGattHelper.mBluetoothGattCallback,
+                android.bluetooth.BluetoothDevice.TRANSPORT_LE);
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)
+                .getConnectionOptions())
+                .isEqualTo(ConnectionOptions.builder()
+                        .setConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH)
+                        .build());
+        verify(mMockBluetoothGattWrapper, times(3))
+                .requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_connect_cancel() throws Exception {
+        mBluetoothGattHelper.connect(mMockBluetoothDevice);
+
+        verify(mMockBluetoothOperationExecutor)
+                .executeNonnull(mOperationCaptor.capture(), eq(CONNECT_TIMEOUT_MILLIS));
+        Operation<?> operation = mOperationCaptor.getValue();
+        operation.run();
+        operation.cancel();
+
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onConnectionStateChange_connected_success()
+            throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
+                BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_CONNECTED);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(
+                new Operation<>(OperationType.CONNECT, mMockBluetoothDevice),
+                BluetoothGatt.GATT_SUCCESS,
+                mMockBluetoothGattConnection);
+        verify(mMockBluetoothGattConnection).onConnected();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onConnectionStateChange_connected_success_withMtuOption()
+            throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+        when(mMockBluetoothGattConnection.getConnectionOptions())
+                .thenReturn(BluetoothGattHelper.ConnectionOptions.builder()
+                        .setMtu(MTU)
+                        .build());
+        when(mMockBluetoothGattWrapper.requestMtu(MTU)).thenReturn(true);
+
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
+                BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_CONNECTED);
+
+        verifyZeroInteractions(mMockBluetoothOperationExecutor);
+        verify(mMockBluetoothGattConnection, never()).onConnected();
+        verify(mMockBluetoothGattWrapper).requestMtu(MTU);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onConnectionStateChange_connected_success_failMtuOption()
+            throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+        when(mMockBluetoothGattConnection.getConnectionOptions())
+                .thenReturn(BluetoothGattHelper.ConnectionOptions.builder()
+                        .setMtu(MTU)
+                        .build());
+        when(mMockBluetoothGattWrapper.requestMtu(MTU)).thenReturn(false);
+
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
+                BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_CONNECTED);
+
+        verify(mMockBluetoothOperationExecutor).notifyFailure(
+                eq(new Operation<>(OperationType.CONNECT, mMockBluetoothDevice)),
+                any(BluetoothException.class));
+        verify(mMockBluetoothGattConnection, never()).onConnected();
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onConnectionStateChange_connected_unexpectedSuccess()
+            throws Exception {
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
+                BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_CONNECTED);
+
+        verifyZeroInteractions(mMockBluetoothOperationExecutor);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onConnectionStateChange_connected_failure()
+            throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+
+        mBluetoothGattHelper.mBluetoothGattCallback
+                .onConnectionStateChange(
+                        mMockBluetoothGattWrapper,
+                        BluetoothGatt.GATT_FAILURE,
+                        BluetoothGatt.STATE_CONNECTED);
+
+        verify(mMockBluetoothOperationExecutor)
+                .notifyCompletion(
+                        new Operation<>(OperationType.CONNECT, mMockBluetoothDevice),
+                        BluetoothGatt.GATT_FAILURE,
+                        null);
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onConnectionStateChange_disconnected_unexpectedSuccess()
+            throws Exception {
+        mBluetoothGattHelper.mBluetoothGattCallback
+                .onConnectionStateChange(
+                        mMockBluetoothGattWrapper,
+                        BluetoothGatt.GATT_SUCCESS,
+                        BluetoothGatt.STATE_DISCONNECTED);
+
+        verifyZeroInteractions(mMockBluetoothOperationExecutor);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onConnectionStateChange_disconnected_notConnected()
+            throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+        when(mMockBluetoothGattConnection.isConnected()).thenReturn(false);
+
+        mBluetoothGattHelper.mBluetoothGattCallback
+                .onConnectionStateChange(
+                        mMockBluetoothGattWrapper,
+                        GATT_STATUS,
+                        BluetoothGatt.STATE_DISCONNECTED);
+
+        verify(mMockBluetoothOperationExecutor)
+                .notifyCompletion(
+                        new Operation<>(OperationType.CONNECT, mMockBluetoothDevice),
+                        GATT_STATUS,
+                        null);
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onConnectionStateChange_disconnected_success()
+            throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+        when(mMockBluetoothGattConnection.isConnected()).thenReturn(true);
+
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
+                BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_DISCONNECTED);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(
+                new Operation<>(OperationType.DISCONNECT, mMockBluetoothDevice),
+                BluetoothGatt.GATT_SUCCESS);
+        verify(mMockBluetoothGattConnection).onClosed();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onConnectionStateChange_disconnected_failure()
+            throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+        when(mMockBluetoothGattConnection.isConnected()).thenReturn(true);
+
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
+                BluetoothGatt.GATT_FAILURE, BluetoothGatt.STATE_DISCONNECTED);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(
+                new Operation<>(OperationType.DISCONNECT, mMockBluetoothDevice),
+                BluetoothGatt.GATT_FAILURE);
+        verify(mMockBluetoothGattConnection).onClosed();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onServicesDiscovered() throws Exception {
+        mBluetoothGattHelper.mBluetoothGattCallback.onServicesDiscovered(mMockBluetoothGattWrapper,
+                GATT_STATUS);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(
+                new Operation<Void>(OperationType.DISCOVER_SERVICES_INTERNAL,
+                        mMockBluetoothGattWrapper),
+                GATT_STATUS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onCharacteristicRead() throws Exception {
+        mBluetoothGattHelper.mBluetoothGattCallback.onCharacteristicRead(mMockBluetoothGattWrapper,
+                mMockBluetoothGattCharacteristic, GATT_STATUS);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(new Operation<byte[]>(
+                        OperationType.READ_CHARACTERISTIC, mMockBluetoothGattWrapper,
+                        mMockBluetoothGattCharacteristic),
+                GATT_STATUS, CHARACTERISTIC_VALUE);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onCharacteristicWrite() throws Exception {
+        mBluetoothGattHelper.mBluetoothGattCallback.onCharacteristicWrite(mMockBluetoothGattWrapper,
+                mMockBluetoothGattCharacteristic, GATT_STATUS);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(new Operation<Void>(
+                        OperationType.WRITE_CHARACTERISTIC, mMockBluetoothGattWrapper,
+                        mMockBluetoothGattCharacteristic),
+                GATT_STATUS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onDescriptorRead() throws Exception {
+        mBluetoothGattHelper.mBluetoothGattCallback.onDescriptorRead(mMockBluetoothGattWrapper,
+                mMockBluetoothGattDescriptor, GATT_STATUS);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(new Operation<byte[]>(
+                        OperationType.READ_DESCRIPTOR, mMockBluetoothGattWrapper,
+                        mMockBluetoothGattDescriptor),
+                GATT_STATUS,
+                DESCRIPTOR_VALUE);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onDescriptorWrite() throws Exception {
+        mBluetoothGattHelper.mBluetoothGattCallback.onDescriptorWrite(mMockBluetoothGattWrapper,
+                mMockBluetoothGattDescriptor, GATT_STATUS);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(new Operation<Void>(
+                        OperationType.WRITE_DESCRIPTOR, mMockBluetoothGattWrapper,
+                        mMockBluetoothGattDescriptor),
+                GATT_STATUS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onReadRemoteRssi() throws Exception {
+        mBluetoothGattHelper.mBluetoothGattCallback.onReadRemoteRssi(mMockBluetoothGattWrapper,
+                RSSI, GATT_STATUS);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(
+                new Operation<Integer>(OperationType.READ_RSSI, mMockBluetoothGattWrapper),
+                GATT_STATUS, RSSI);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onReliableWriteCompleted() throws Exception {
+        mBluetoothGattHelper.mBluetoothGattCallback.onReliableWriteCompleted(
+                mMockBluetoothGattWrapper,
+                GATT_STATUS);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(
+                new Operation<Void>(OperationType.WRITE_RELIABLE, mMockBluetoothGattWrapper),
+                GATT_STATUS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onMtuChanged() throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+        when(mMockBluetoothGattConnection.isConnected()).thenReturn(true);
+
+        mBluetoothGattHelper.mBluetoothGattCallback
+                .onMtuChanged(mMockBluetoothGattWrapper, MTU, GATT_STATUS);
+
+        verify(mMockBluetoothOperationExecutor).notifyCompletion(
+                new Operation<>(OperationType.CHANGE_MTU, mMockBluetoothGattWrapper), GATT_STATUS,
+                MTU);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothGattCallback_onMtuChangedDuringConnection_success() throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+        when(mMockBluetoothGattConnection.isConnected()).thenReturn(false);
+
+        mBluetoothGattHelper.mBluetoothGattCallback.onMtuChanged(
+                mMockBluetoothGattWrapper, MTU, BluetoothGatt.GATT_SUCCESS);
+
+        verify(mMockBluetoothGattConnection).onConnected();
+        verify(mMockBluetoothOperationExecutor)
+                .notifyCompletion(
+                        new Operation<>(OperationType.CONNECT, mMockBluetoothDevice),
+                        BluetoothGatt.GATT_SUCCESS,
+                        mMockBluetoothGattConnection);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testBluetoothGattCallback_onMtuChangedDuringConnection_fail() throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+        when(mMockBluetoothGattConnection.isConnected()).thenReturn(false);
+
+        mBluetoothGattHelper.mBluetoothGattCallback
+                .onMtuChanged(mMockBluetoothGattWrapper, MTU, GATT_STATUS);
+
+        verify(mMockBluetoothGattConnection).onConnected();
+        verify(mMockBluetoothOperationExecutor)
+                .notifyCompletion(
+                        new Operation<>(OperationType.CONNECT, mMockBluetoothDevice),
+                        GATT_STATUS,
+                        mMockBluetoothGattConnection);
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_BluetoothGattCallback_onCharacteristicChanged() throws Exception {
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
+
+        mBluetoothGattHelper.mBluetoothGattCallback.onCharacteristicChanged(
+                mMockBluetoothGattWrapper,
+                mMockBluetoothGattCharacteristic);
+
+        verify(mMockBluetoothGattConnection).onCharacteristicChanged(
+                mMockBluetoothGattCharacteristic,
+                CHARACTERISTIC_VALUE);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_ScanCallback_onScanFailed() throws Exception {
+        mBluetoothGattHelper.mScanCallback.onScanFailed(ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
+
+        verify(mMockBluetoothOperationExecutor).notifyFailure(
+                eq(new Operation<BluetoothDevice>(OperationType.SCAN)),
+                isA(BluetoothException.class));
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_ScanCallback_onScanResult() throws Exception {
+        mBluetoothGattHelper.mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES,
+                mMockScanResult);
+
+        verify(mMockBluetoothOperationExecutor).notifySuccess(
+                new Operation<BluetoothDevice>(OperationType.SCAN), mMockBluetoothDevice);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtilsTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtilsTest.java
new file mode 100644
index 0000000..47182c3
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtilsTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.server.nearby.common.bluetooth.util;
+
+import static com.android.server.nearby.common.bluetooth.util.BluetoothGattUtils.getMessageForStatusCode;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.bluetooth.BluetoothGatt;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.UUID;
+
+/** Unit tests for {@link BluetoothGattUtils}. */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BluetoothGattUtilsTest {
+    private static final UUID TEST_UUID = UUID.randomUUID();
+    private static final ImmutableSet<String> GATT_HIDDEN_CONSTANTS = ImmutableSet.of(
+            "GATT_WRITE_REQUEST_BUSY", "GATT_WRITE_REQUEST_FAIL", "GATT_WRITE_REQUEST_SUCCESS");
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGetMessageForStatusCode() throws Exception {
+        Field[] publicFields = BluetoothGatt.class.getFields();
+        for (Field field : publicFields) {
+            if ((field.getModifiers() & Modifier.STATIC) == 0
+                    || field.getDeclaringClass() != BluetoothGatt.class) {
+                continue;
+            }
+            String fieldName = field.getName();
+            if (!fieldName.startsWith("GATT_") || GATT_HIDDEN_CONSTANTS.contains(fieldName)) {
+                continue;
+            }
+            int fieldValue = (Integer) field.get(null);
+            assertThat(getMessageForStatusCode(fieldValue)).isEqualTo(fieldName);
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/util/BluetoothOperationExecutorTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/util/BluetoothOperationExecutorTest.java
new file mode 100644
index 0000000..7b3ebab
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/util/BluetoothOperationExecutorTest.java
@@ -0,0 +1,321 @@
+/*
+ * 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.server.nearby.common.bluetooth.util;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.bluetooth.BluetoothGatt;
+
+import androidx.test.filters.SdkSuppress;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.testability.NonnullProvider;
+import com.android.server.nearby.common.bluetooth.testability.TimeProvider;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.BluetoothOperationTimeoutException;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.Operation;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.SynchronousOperation;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mock;
+
+import java.util.Arrays;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+
+/**
+ * Unit tests for {@link BluetoothOperationExecutor}.
+ */
+public class BluetoothOperationExecutorTest extends TestCase {
+
+    private static final String OPERATION_RESULT = "result";
+    private static final String EXCEPTION_REASON = "exception";
+    private static final long TIME = 1234;
+    private static final long TIMEOUT = 121212;
+
+    @Mock
+    private NonnullProvider<BlockingQueue<Object>> mMockBlockingQueueProvider;
+    @Mock
+    private TimeProvider mMockTimeProvider;
+    @Mock
+    private BlockingQueue<Object> mMockBlockingQueue;
+    @Mock
+    private Semaphore mMockSemaphore;
+    @Mock
+    private Operation<String> mMockStringOperation;
+    @Mock
+    private Operation<Void> mMockVoidOperation;
+    @Mock
+    private Future<Object> mMockFuture;
+    @Mock
+    private Future<Object> mMockFuture2;
+
+    private BluetoothOperationExecutor mBluetoothOperationExecutor;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        initMocks(this);
+
+        when(mMockBlockingQueueProvider.get()).thenReturn(mMockBlockingQueue);
+        when(mMockSemaphore.tryAcquire()).thenReturn(true);
+        when(mMockTimeProvider.getTimeMillis()).thenReturn(TIME);
+
+        mBluetoothOperationExecutor =
+                new BluetoothOperationExecutor(mMockSemaphore, mMockTimeProvider,
+                        mMockBlockingQueueProvider);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testExecute() throws Exception {
+        when(mMockBlockingQueue.take()).thenReturn(OPERATION_RESULT);
+
+        String result = mBluetoothOperationExecutor.execute(mMockStringOperation);
+
+        verify(mMockStringOperation).execute(mBluetoothOperationExecutor);
+        assertThat(result).isEqualTo(OPERATION_RESULT);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testExecuteWithTimeout() throws Exception {
+        when(mMockBlockingQueue.poll(TIMEOUT, TimeUnit.MILLISECONDS)).thenReturn(OPERATION_RESULT);
+
+        String result = mBluetoothOperationExecutor.execute(mMockStringOperation, TIMEOUT);
+
+        verify(mMockStringOperation).execute(mBluetoothOperationExecutor);
+        assertThat(result).isEqualTo(OPERATION_RESULT);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testSchedule() throws Exception {
+        when(mMockBlockingQueue.poll(TIMEOUT, TimeUnit.MILLISECONDS)).thenReturn(OPERATION_RESULT);
+
+        Future<String> result = mBluetoothOperationExecutor.schedule(mMockStringOperation);
+
+        verify(mMockStringOperation).execute(mBluetoothOperationExecutor);
+        assertThat(result.get(TIMEOUT, TimeUnit.MILLISECONDS)).isEqualTo(OPERATION_RESULT);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testScheduleOtherOperationInProgress() throws Exception {
+        when(mMockSemaphore.tryAcquire()).thenReturn(false);
+        when(mMockBlockingQueue.poll(TIMEOUT, TimeUnit.MILLISECONDS)).thenReturn(OPERATION_RESULT);
+
+        Future<String> result = mBluetoothOperationExecutor.schedule(mMockStringOperation);
+
+        verify(mMockStringOperation, never()).run();
+
+        when(mMockSemaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)).thenReturn(true);
+
+        assertThat(result.get(TIMEOUT, TimeUnit.MILLISECONDS)).isEqualTo(OPERATION_RESULT);
+        verify(mMockStringOperation).execute(mBluetoothOperationExecutor);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNotifySuccessWithResult() throws Exception {
+        when(mMockBlockingQueueProvider.get()).thenReturn(new LinkedBlockingDeque<Object>());
+        Future<String> future = mBluetoothOperationExecutor.schedule(mMockStringOperation);
+
+        mBluetoothOperationExecutor.notifySuccess(mMockStringOperation, OPERATION_RESULT);
+
+        assertThat(future.get(1, TimeUnit.MILLISECONDS)).isEqualTo(OPERATION_RESULT);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNotifySuccessTwice() throws Exception {
+        BlockingQueue<Object> resultQueue = new LinkedBlockingDeque<Object>();
+        when(mMockBlockingQueueProvider.get()).thenReturn(resultQueue);
+        Future<String> future = mBluetoothOperationExecutor.schedule(mMockStringOperation);
+
+        mBluetoothOperationExecutor.notifySuccess(mMockStringOperation, OPERATION_RESULT);
+
+        assertThat(future.get(1, TimeUnit.MILLISECONDS)).isEqualTo(OPERATION_RESULT);
+
+        // the second notification should be ignored
+        mBluetoothOperationExecutor.notifySuccess(mMockStringOperation, OPERATION_RESULT);
+        assertThat(resultQueue).isEmpty();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNotifySuccessWithNullResult() throws Exception {
+        when(mMockBlockingQueueProvider.get()).thenReturn(new LinkedBlockingDeque<Object>());
+        Future<String> future = mBluetoothOperationExecutor.schedule(mMockStringOperation);
+
+        mBluetoothOperationExecutor.notifySuccess(mMockStringOperation, null);
+
+        assertThat(future.get(1, TimeUnit.MILLISECONDS)).isNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNotifySuccess() throws Exception {
+        when(mMockBlockingQueueProvider.get()).thenReturn(new LinkedBlockingDeque<Object>());
+        Future<Void> future = mBluetoothOperationExecutor.schedule(mMockVoidOperation);
+
+        mBluetoothOperationExecutor.notifySuccess(mMockVoidOperation);
+
+        future.get(1, TimeUnit.MILLISECONDS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNotifyCompletionSuccess() throws Exception {
+        when(mMockBlockingQueueProvider.get()).thenReturn(new LinkedBlockingDeque<Object>());
+        Future<Void> future = mBluetoothOperationExecutor.schedule(mMockVoidOperation);
+
+        mBluetoothOperationExecutor
+                .notifyCompletion(mMockVoidOperation, BluetoothGatt.GATT_SUCCESS);
+
+        future.get(1, TimeUnit.MILLISECONDS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNotifyCompletionFailure() throws Exception {
+        when(mMockBlockingQueueProvider.get()).thenReturn(new LinkedBlockingDeque<Object>());
+        Future<Void> future = mBluetoothOperationExecutor.schedule(mMockVoidOperation);
+
+        mBluetoothOperationExecutor
+                .notifyCompletion(mMockVoidOperation, BluetoothGatt.GATT_FAILURE);
+
+        try {
+            BluetoothOperationExecutor.getResult(future, 1);
+            fail("Expected BluetoothException");
+        } catch (BluetoothException e) {
+            //expected
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testNotifyFailure() throws Exception {
+        when(mMockBlockingQueueProvider.get()).thenReturn(new LinkedBlockingDeque<Object>());
+        Future<Void> future = mBluetoothOperationExecutor.schedule(mMockVoidOperation);
+
+        mBluetoothOperationExecutor
+                .notifyFailure(mMockVoidOperation, new BluetoothException("test"));
+
+        try {
+            BluetoothOperationExecutor.getResult(future, 1);
+            fail("Expected BluetoothException");
+        } catch (BluetoothException e) {
+            //expected
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWaitFor() throws Exception {
+        mBluetoothOperationExecutor.waitFor(Arrays.asList(mMockFuture, mMockFuture2));
+
+        verify(mMockFuture).get();
+        verify(mMockFuture2).get();
+    }
+
+    @SuppressWarnings("unchecked")
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testWaitForWithTimeout() throws Exception {
+        mBluetoothOperationExecutor.waitFor(
+                Arrays.asList(mMockFuture, mMockFuture2),
+                TIMEOUT);
+
+        verify(mMockFuture).get(TIMEOUT, TimeUnit.MILLISECONDS);
+        verify(mMockFuture2).get(TIMEOUT, TimeUnit.MILLISECONDS);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGetResult() throws Exception {
+        when(mMockFuture.get()).thenReturn(OPERATION_RESULT);
+
+        Object result = BluetoothOperationExecutor.getResult(mMockFuture);
+
+        assertThat(result).isEqualTo(OPERATION_RESULT);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testGetResultWithTimeout() throws Exception {
+        when(mMockFuture.get(TIMEOUT, TimeUnit.MILLISECONDS)).thenThrow(new TimeoutException());
+
+        try {
+            BluetoothOperationExecutor.getResult(mMockFuture, TIMEOUT);
+            fail("Expected BluetoothOperationTimeoutException");
+        } catch (BluetoothOperationTimeoutException e) {
+            //expected
+        }
+        verify(mMockFuture).cancel(true);
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_SynchronousOperation_execute() throws Exception {
+        when(mMockBlockingQueueProvider.get()).thenReturn(mMockBlockingQueue);
+        SynchronousOperation<String> synchronousOperation = new SynchronousOperation<String>() {
+            @Override
+            public String call() throws BluetoothException {
+                return OPERATION_RESULT;
+            }
+        };
+
+        @SuppressWarnings("unused") // future return.
+        Future<?> possiblyIgnoredError = mBluetoothOperationExecutor.schedule(synchronousOperation);
+
+        verify(mMockBlockingQueue).add(OPERATION_RESULT);
+        verify(mMockSemaphore).release();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_SynchronousOperation_exception() throws Exception {
+        final BluetoothException exception = new BluetoothException(EXCEPTION_REASON);
+        when(mMockBlockingQueueProvider.get()).thenReturn(mMockBlockingQueue);
+        SynchronousOperation<String> synchronousOperation = new SynchronousOperation<String>() {
+            @Override
+            public String call() throws BluetoothException {
+                throw exception;
+            }
+        };
+
+        @SuppressWarnings("unused") // future return.
+        Future<?> possiblyIgnoredError = mBluetoothOperationExecutor.schedule(synchronousOperation);
+
+        verify(mMockBlockingQueue).add(exception);
+        verify(mMockSemaphore).release();
+    }
+
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void test_AsynchronousOperation_exception() throws Exception {
+        final BluetoothException exception = new BluetoothException(EXCEPTION_REASON);
+        when(mMockBlockingQueueProvider.get()).thenReturn(mMockBlockingQueue);
+        Operation<String> operation = new Operation<String>() {
+            @Override
+            public void run() throws BluetoothException {
+                throw exception;
+            }
+        };
+
+        @SuppressWarnings("unused") // future return.
+        Future<?> possiblyIgnoredError = mBluetoothOperationExecutor.schedule(operation);
+
+        verify(mMockBlockingQueue).add(exception);
+        verify(mMockSemaphore).release();
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/eventloop/EventLoopTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/eventloop/EventLoopTest.java
new file mode 100644
index 0000000..70dcec8
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/eventloop/EventLoopTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.server.nearby.common.eventloop;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class EventLoopTest {
+    private static final String TAG = "EventLoopTest";
+
+    private final EventLoop mEventLoop = EventLoop.newInstance(TAG);
+    private final List<Integer> mExecutedRunnables = new ArrayList<>();
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    /*
+    @Test
+    public void remove() {
+        mEventLoop.postRunnable(new NumberedRunnable(0));
+        NumberedRunnable runnableToAddAndRemove = new NumberedRunnable(1);
+        mEventLoop.postRunnable(runnableToAddAndRemove);
+        mEventLoop.removeRunnable(runnableToAddAndRemove);
+        mEventLoop.postRunnable(new NumberedRunnable(2));
+
+        assertThat(mExecutedRunnables).containsExactly(0, 2);
+    }
+    */
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void isPosted() {
+        NumberedRunnable runnable = new NumberedRunnable(0);
+        mEventLoop.postRunnableDelayed(runnable, 10 * 1000L);
+        assertThat(mEventLoop.isPosted(runnable)).isTrue();
+        mEventLoop.removeRunnable(runnable);
+        assertThat(mEventLoop.isPosted(runnable)).isFalse();
+
+        // Let a runnable execute, then verify that it's not posted.
+        mEventLoop.postRunnable(runnable);
+        assertThat(mEventLoop.isPosted(runnable)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void postAndWaitAfterDestroy() throws InterruptedException {
+        mEventLoop.destroy();
+        mEventLoop.postAndWait(new NumberedRunnable(0));
+
+        assertThat(mExecutedRunnables).isEmpty();
+    }
+
+
+    private class NumberedRunnable extends NamedRunnable {
+        private final int mId;
+
+        private NumberedRunnable(int id) {
+            super("NumberedRunnable:" + id);
+            this.mId = id;
+        }
+
+        @Override
+        public void run() {
+            // Note: when running in robolectric, this is not actually executed on a different
+            // thread, it's executed in the same thread the test runs in, so this is safe.
+            mExecutedRunnables.add(mId);
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/FastPairManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/FastPairManagerTest.java
new file mode 100644
index 0000000..26d1847
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/FastPairManagerTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.server.nearby.fastpair;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import androidx.test.filters.SdkSuppress;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+
+public class FastPairManagerTest {
+    private FastPairManager mFastPairManager;
+    @Mock private Context mContext;
+    private LocatorContextWrapper mLocatorContextWrapper;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        mLocatorContextWrapper = new LocatorContextWrapper(mContext);
+        mFastPairManager = new FastPairManager(mLocatorContextWrapper);
+        when(mContext.getContentResolver()).thenReturn(
+                InstrumentationRegistry.getInstrumentation().getContext().getContentResolver());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testFastPairInit() {
+        mFastPairManager.initiate();
+
+        verify(mContext, times(1)).registerReceiver(any(), any());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testFastPairCleanUp() {
+        mFastPairManager.cleanUp();
+
+        verify(mContext, times(1)).unregisterReceiver(any());
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/ModuleTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/ModuleTest.java
new file mode 100644
index 0000000..bb4e3d0
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/ModuleTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+package src.com.android.server.nearby.fastpair;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SdkSuppress;
+
+import com.android.server.nearby.common.eventloop.EventLoop;
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.fastpair.FastPairAdvHandler;
+import com.android.server.nearby.fastpair.FastPairModule;
+import com.android.server.nearby.fastpair.cache.FastPairCacheManager;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+
+import java.time.Clock;
+
+import src.com.android.server.nearby.fastpair.testing.MockingLocator;
+
+public class ModuleTest {
+    private Locator mLocator;
+
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mLocator = MockingLocator.withMocksOnly(ApplicationProvider.getApplicationContext());
+        mLocator.bind(new FastPairModule());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void genericConstructor() {
+        assertThat(mLocator.get(FastPairCacheManager.class)).isNotNull();
+        assertThat(mLocator.get(FootprintsDeviceManager.class)).isNotNull();
+        assertThat(mLocator.get(EventLoop.class)).isNotNull();
+        assertThat(mLocator.get(FastPairHalfSheetManager.class)).isNotNull();
+        assertThat(mLocator.get(FastPairAdvHandler.class)).isNotNull();
+        assertThat(mLocator.get(Clock.class)).isNotNull();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void genericDestroy() {
+        mLocator.destroy();
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/cache/FastPairCacheManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/cache/FastPairCacheManagerTest.java
new file mode 100644
index 0000000..adae97d
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/cache/FastPairCacheManagerTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.server.nearby.fastpair.cache;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SdkSuppress;
+
+import com.google.protobuf.ByteString;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import service.proto.Cache;
+
+public class FastPairCacheManagerTest {
+
+    private static final String MODEL_ID = "001";
+    private static final String MODEL_ID2 = "002";
+    private static final String APP_NAME = "APP_NAME";
+    private static final String MAC_ADDRESS = "00:11:22:33";
+    private static final ByteString ACCOUNT_KEY = ByteString.copyFromUtf8("axgs");
+    private static final String MAC_ADDRESS_B = "00:11:22:44";
+    private static final ByteString ACCOUNT_KEY_B = ByteString.copyFromUtf8("axgb");
+
+    @Mock
+    DiscoveryItem mDiscoveryItem;
+    @Mock
+    DiscoveryItem mDiscoveryItem2;
+    @Mock
+    Cache.StoredFastPairItem mStoredFastPairItem;
+    Cache.StoredDiscoveryItem mStoredDiscoveryItem = Cache.StoredDiscoveryItem.newBuilder()
+            .setTriggerId(MODEL_ID)
+            .setAppName(APP_NAME).build();
+    Cache.StoredDiscoveryItem mStoredDiscoveryItem2 = Cache.StoredDiscoveryItem.newBuilder()
+            .setTriggerId(MODEL_ID2)
+            .setAppName(APP_NAME).build();
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void notSaveRetrieveInfo() {
+        Context mContext = ApplicationProvider.getApplicationContext();
+        when(mDiscoveryItem.getCopyOfStoredItem()).thenReturn(mStoredDiscoveryItem);
+        when(mDiscoveryItem.getTriggerId()).thenReturn(MODEL_ID);
+
+        FastPairCacheManager fastPairCacheManager = new FastPairCacheManager(mContext);
+
+        assertThat(fastPairCacheManager.getStoredDiscoveryItem(MODEL_ID).getAppName())
+                .isNotEqualTo(APP_NAME);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void saveRetrieveInfo() {
+        Context mContext = ApplicationProvider.getApplicationContext();
+        when(mDiscoveryItem.getCopyOfStoredItem()).thenReturn(mStoredDiscoveryItem);
+        when(mDiscoveryItem.getTriggerId()).thenReturn(MODEL_ID);
+
+        FastPairCacheManager fastPairCacheManager = new FastPairCacheManager(mContext);
+        fastPairCacheManager.saveDiscoveryItem(mDiscoveryItem);
+        assertThat(fastPairCacheManager.getStoredDiscoveryItem(MODEL_ID).getAppName())
+                .isEqualTo(APP_NAME);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void getAllInfo() {
+        Context mContext = ApplicationProvider.getApplicationContext();
+        when(mDiscoveryItem.getCopyOfStoredItem()).thenReturn(mStoredDiscoveryItem);
+        when(mDiscoveryItem.getTriggerId()).thenReturn(MODEL_ID);
+        when(mDiscoveryItem2.getCopyOfStoredItem()).thenReturn(mStoredDiscoveryItem2);
+        when(mDiscoveryItem2.getTriggerId()).thenReturn(MODEL_ID2);
+
+        FastPairCacheManager fastPairCacheManager = new FastPairCacheManager(mContext);
+        fastPairCacheManager.saveDiscoveryItem(mDiscoveryItem);
+
+        assertThat(fastPairCacheManager.getAllSavedStoreDiscoveryItem()).hasSize(2);
+
+        fastPairCacheManager.saveDiscoveryItem(mDiscoveryItem2);
+
+        assertThat(fastPairCacheManager.getAllSavedStoreDiscoveryItem()).hasSize(3);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void saveRetrieveInfoStoredFastPairItem() {
+        Context mContext = ApplicationProvider.getApplicationContext();
+        Cache.StoredFastPairItem storedFastPairItem = Cache.StoredFastPairItem.newBuilder()
+                .setMacAddress(MAC_ADDRESS)
+                .setAccountKey(ACCOUNT_KEY)
+                .build();
+
+
+        FastPairCacheManager fastPairCacheManager = new FastPairCacheManager(mContext);
+        fastPairCacheManager.putStoredFastPairItem(storedFastPairItem);
+
+        assertThat(fastPairCacheManager.getStoredFastPairItemFromMacAddress(
+                MAC_ADDRESS).getAccountKey())
+                .isEqualTo(ACCOUNT_KEY);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void checkGetAllFastPairItems() {
+        Context mContext = ApplicationProvider.getApplicationContext();
+        Cache.StoredFastPairItem storedFastPairItem = Cache.StoredFastPairItem.newBuilder()
+                .setMacAddress(MAC_ADDRESS)
+                .setAccountKey(ACCOUNT_KEY)
+                .build();
+        Cache.StoredFastPairItem storedFastPairItemB = Cache.StoredFastPairItem.newBuilder()
+                .setMacAddress(MAC_ADDRESS_B)
+                .setAccountKey(ACCOUNT_KEY_B)
+                .build();
+
+        FastPairCacheManager fastPairCacheManager = new FastPairCacheManager(mContext);
+        fastPairCacheManager.putStoredFastPairItem(storedFastPairItem);
+        fastPairCacheManager.putStoredFastPairItem(storedFastPairItemB);
+
+        assertThat(fastPairCacheManager.getAllSavedStoredFastPairItem().size())
+                .isEqualTo(2);
+
+        fastPairCacheManager.removeStoredFastPairItem(MAC_ADDRESS_B);
+
+        assertThat(fastPairCacheManager.getAllSavedStoredFastPairItem().size())
+                .isEqualTo(1);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java
new file mode 100644
index 0000000..58e4c47
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.fastpair.halfsheet;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+import com.android.server.nearby.fastpair.FastPairController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import service.proto.Cache;
+
+public class FastPairHalfSheetManagerTest {
+    private static final String BLEADDRESS = "11:22:44:66";
+    private static final String NAME = "device_name";
+    private FastPairHalfSheetManager mFastPairHalfSheetManager;
+    private Cache.ScanFastPairStoreItem mScanFastPairStoreItem;
+    @Mock
+    LocatorContextWrapper mContextWrapper;
+    @Mock
+    ResolveInfo mResolveInfo;
+    @Mock
+    PackageManager mPackageManager;
+    @Mock
+    Locator mLocator;
+    @Mock
+    FastPairController mFastPairController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        mScanFastPairStoreItem = Cache.ScanFastPairStoreItem.newBuilder()
+                .setAddress(BLEADDRESS)
+                .setDeviceName(NAME)
+                .build();
+    }
+
+    @Test
+    public void verifyFastPairHalfSheetManagerBehavior() {
+        mLocator.overrideBindingForTest(FastPairController.class, mFastPairController);
+        ResolveInfo resolveInfo = new ResolveInfo();
+        List<ResolveInfo> resolveInfoList = new ArrayList<>();
+
+        mPackageManager = mock(PackageManager.class);
+        when(mContextWrapper.getPackageManager()).thenReturn(mPackageManager);
+        resolveInfo.activityInfo = new ActivityInfo();
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.sourceDir = "/apex/com.android.tethering";
+        applicationInfo.packageName = "test.package";
+        resolveInfo.activityInfo.applicationInfo = applicationInfo;
+        resolveInfoList.add(resolveInfo);
+        when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(resolveInfoList);
+        when(mPackageManager.canRequestPackageInstalls()).thenReturn(false);
+
+        mFastPairHalfSheetManager =
+                new FastPairHalfSheetManager(mContextWrapper);
+
+        when(mContextWrapper.getLocator()).thenReturn(mLocator);
+
+        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+
+        mFastPairHalfSheetManager.showHalfSheet(mScanFastPairStoreItem);
+
+        verify(mContextWrapper, atLeastOnce())
+                .startActivityAsUser(intentArgumentCaptor.capture(), eq(UserHandle.CURRENT));
+    }
+
+    @Test
+    public void verifyFastPairHalfSheetManagerHalfSheetApkNotValidBehavior() {
+        mLocator.overrideBindingForTest(FastPairController.class, mFastPairController);
+        ResolveInfo resolveInfo = new ResolveInfo();
+        List<ResolveInfo> resolveInfoList = new ArrayList<>();
+
+        mPackageManager = mock(PackageManager.class);
+        when(mContextWrapper.getPackageManager()).thenReturn(mPackageManager);
+        resolveInfo.activityInfo = new ActivityInfo();
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        // application directory is wrong
+        applicationInfo.sourceDir = "/apex/com.android.nearby";
+        applicationInfo.packageName = "test.package";
+        resolveInfo.activityInfo.applicationInfo = applicationInfo;
+        resolveInfoList.add(resolveInfo);
+        when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(resolveInfoList);
+        when(mPackageManager.canRequestPackageInstalls()).thenReturn(false);
+
+        mFastPairHalfSheetManager =
+                new FastPairHalfSheetManager(mContextWrapper);
+
+        when(mContextWrapper.getLocator()).thenReturn(mLocator);
+
+        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+
+        mFastPairHalfSheetManager.showHalfSheet(mScanFastPairStoreItem);
+
+        verify(mContextWrapper, never())
+                .startActivityAsUser(intentArgumentCaptor.capture(), eq(UserHandle.CURRENT));
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBaseTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBaseTest.java
new file mode 100644
index 0000000..2ade5f2
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBaseTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.fastpair.pairinghandler;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+import com.android.server.nearby.fastpair.cache.FastPairCacheManager;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+import com.android.server.nearby.fastpair.notification.FastPairNotificationManager;
+import com.android.server.nearby.fastpair.testing.FakeDiscoveryItems;
+
+import com.google.protobuf.ByteString;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.time.Clock;
+
+import service.proto.Cache;
+import service.proto.Rpcs;
+
+public class PairingProgressHandlerBaseTest {
+    @Mock
+    Locator mLocator;
+    @Mock
+    LocatorContextWrapper mContextWrapper;
+    @Mock
+    Clock mClock;
+    @Mock
+    FastPairCacheManager mFastPairCacheManager;
+    @Mock
+    FootprintsDeviceManager mFootprintsDeviceManager;
+    private static final byte[] ACCOUNT_KEY = new byte[]{0x01, 0x02};
+
+    @Before
+    public void setup() {
+
+        MockitoAnnotations.initMocks(this);
+        when(mContextWrapper.getLocator()).thenReturn(mLocator);
+        mLocator.overrideBindingForTest(FastPairCacheManager.class,
+                mFastPairCacheManager);
+        mLocator.overrideBindingForTest(Clock.class, mClock);
+    }
+
+    @Test
+    public void createHandler_halfSheetSubsequentPairing_notificationPairingHandlerCreated() {
+
+        DiscoveryItem discoveryItem = FakeDiscoveryItems.newFastPairDiscoveryItem(mContextWrapper);
+        discoveryItem.setStoredItemForTest(
+                discoveryItem.getStoredItemForTest().toBuilder()
+                        .setAuthenticationPublicKeySecp256R1(ByteString.copyFrom(ACCOUNT_KEY))
+                        .setFastPairInformation(
+                                Cache.FastPairInformation.newBuilder()
+                                        .setDeviceType(Rpcs.DeviceType.HEADPHONES).build())
+                        .build());
+
+        PairingProgressHandlerBase progressHandler =
+                createProgressHandler(ACCOUNT_KEY, discoveryItem, /* isRetroactivePair= */ false);
+
+        assertThat(progressHandler).isInstanceOf(NotificationPairingProgressHandler.class);
+    }
+
+    @Test
+    public void createHandler_halfSheetInitialPairing_halfSheetPairingHandlerCreated() {
+        // No account key
+        DiscoveryItem discoveryItem = FakeDiscoveryItems.newFastPairDiscoveryItem(mContextWrapper);
+        discoveryItem.setStoredItemForTest(
+                discoveryItem.getStoredItemForTest().toBuilder()
+                        .setFastPairInformation(
+                                Cache.FastPairInformation.newBuilder()
+                                        .setDeviceType(Rpcs.DeviceType.HEADPHONES).build())
+                        .build());
+
+        PairingProgressHandlerBase progressHandler =
+                createProgressHandler(null, discoveryItem, /* isRetroactivePair= */ false);
+
+        assertThat(progressHandler).isInstanceOf(HalfSheetPairingProgressHandler.class);
+    }
+
+    private PairingProgressHandlerBase createProgressHandler(
+            @Nullable byte[] accountKey, DiscoveryItem fastPairItem, boolean isRetroactivePair) {
+        FastPairNotificationManager fastPairNotificationManager =
+                new FastPairNotificationManager(mContextWrapper, fastPairItem, true);
+        FastPairHalfSheetManager fastPairHalfSheetManager =
+                new FastPairHalfSheetManager(mContextWrapper);
+        mLocator.overrideBindingForTest(FastPairHalfSheetManager.class, fastPairHalfSheetManager);
+        PairingProgressHandlerBase pairingProgressHandlerBase =
+                PairingProgressHandlerBase.create(
+                        mContextWrapper,
+                        fastPairItem,
+                        fastPairItem.getAppPackageName(),
+                        accountKey,
+                        mFootprintsDeviceManager,
+                        fastPairNotificationManager,
+                        fastPairHalfSheetManager,
+                        isRetroactivePair);
+        return pairingProgressHandlerBase;
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/FakeDiscoveryItems.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/FakeDiscoveryItems.java
new file mode 100644
index 0000000..aa7e6f6
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/FakeDiscoveryItems.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.fastpair.testing;
+
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+
+import service.proto.Cache;
+
+public class FakeDiscoveryItems {
+    public static final String DEFAULT_MAC_ADDRESS = "00:11:22:33:44:55";
+    public static final long DEFAULT_TIMESTAMP = 1000000000L;
+    public static final String DEFAULT_DESCRIPITON = "description";
+    public static final String TRIGGER_ID = "trigger.id";
+    private static final String FAST_PAIR_ID = "id";
+    private static final int RSSI = -80;
+    private static final int TX_POWER = -10;
+    public static DiscoveryItem newFastPairDiscoveryItem(LocatorContextWrapper contextWrapper) {
+        return new DiscoveryItem(contextWrapper, newFastPairDeviceStoredItem());
+    }
+
+    public static Cache.StoredDiscoveryItem newFastPairDeviceStoredItem() {
+        return newFastPairDeviceStoredItem(TRIGGER_ID);
+    }
+
+    public static Cache.StoredDiscoveryItem newFastPairDeviceStoredItem(String triggerId) {
+        Cache.StoredDiscoveryItem.Builder item = Cache.StoredDiscoveryItem.newBuilder();
+        item.setState(Cache.StoredDiscoveryItem.State.STATE_ENABLED);
+        item.setId(FAST_PAIR_ID);
+        item.setDescription(DEFAULT_DESCRIPITON);
+        item.setType(Cache.NearbyType.NEARBY_DEVICE);
+        item.setTriggerId(triggerId);
+        item.setMacAddress(DEFAULT_MAC_ADDRESS);
+        item.setFirstObservationTimestampMillis(DEFAULT_TIMESTAMP);
+        item.setLastObservationTimestampMillis(DEFAULT_TIMESTAMP);
+        item.setRssi(RSSI);
+        item.setTxPower(TX_POWER);
+        return item.build();
+    }
+
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingLocator.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingLocator.java
new file mode 100644
index 0000000..b261b26
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingLocator.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+package src.com.android.server.nearby.fastpair.testing;
+
+import android.content.Context;
+
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+
+/** A locator for tests that, by default, installs mocks for everything that's requested of it. */
+public class MockingLocator extends Locator {
+    private final LocatorContextWrapper mLocatorContextWrapper;
+
+    /**
+     * Creates a MockingLocator with the explicit bindings already configured on the given locator.
+     */
+    public static MockingLocator withBindings(Context context, Locator locator) {
+        Locator mockingLocator = new Locator(context);
+        mockingLocator.bind(new MockingModule());
+        locator.attachParent(mockingLocator);
+        return new MockingLocator(context, locator);
+    }
+
+    /** Creates a MockingLocator with no explicit bindings. */
+    public static MockingLocator withMocksOnly(Context context) {
+        return withBindings(context, new Locator(context));
+    }
+
+    @SuppressWarnings("nullness") // due to passing in this before initialized.
+    private MockingLocator(Context context, Locator locator) {
+        super(context, locator);
+        this.mLocatorContextWrapper = new LocatorContextWrapper(context, this);
+    }
+
+    /** Returns a LocatorContextWrapper with this Locator attached. */
+    public LocatorContextWrapper getContextForTest() {
+        return mLocatorContextWrapper;
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingModule.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingModule.java
new file mode 100644
index 0000000..7938c55
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/MockingModule.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package src.com.android.server.nearby.fastpair.testing;
+
+import android.content.Context;
+
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.Module;
+
+
+import org.mockito.Mockito;
+
+/** Module for tests that just provides mocks for anything that's requested of it. */
+public class MockingModule extends Module {
+
+    @Override
+    public void configure(Context context, Class<?> type, Locator locator) {
+        configureMock(type, locator);
+    }
+
+    private <T> void configureMock(Class<T> type, Locator locator) {
+        T mock = Mockito.mock(type);
+        locator.bind(type, mock);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/metrics/NearbyMetricsTest.java b/nearby/tests/unit/src/com/android/server/nearby/metrics/NearbyMetricsTest.java
new file mode 100644
index 0000000..c4d1ee2
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/metrics/NearbyMetricsTest.java
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.metrics;
+
+import static android.nearby.ScanRequest.SCAN_MODE_BALANCED;
+import static android.nearby.ScanRequest.SCAN_TYPE_NEARBY_SHARE;
+
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.PublicCredential;
+import android.nearby.ScanRequest;
+import android.os.WorkSource;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.server.nearby.proto.NearbyStatsLog;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+public class NearbyMetricsTest {
+    private static final int SESSION_ID = 11111;
+    private static final int WORK_SOURCE_UID = 2222;
+
+    private static final String DEVICE_NAME = "testDevice";
+    private static final int SCAN_MEDIUM = 1;
+    private static final int RSSI = -60;
+    private static final String FAST_PAIR_MODEL_ID = "1234";
+    private static final String BLUETOOTH_ADDRESS = "00:11:22:33:FF:EE";
+    private static final byte[] SCAN_DATA = new byte[] {1, 2, 3, 4};
+    private static final PublicCredential PUBLIC_CREDENTIAL =
+            new PublicCredential.Builder(
+                            new byte[] {1},
+                            new byte[] {2},
+                            new byte[] {3},
+                            new byte[] {4},
+                            new byte[] {5})
+                    .build();
+
+    private final WorkSource mWorkSource = new WorkSource(WORK_SOURCE_UID);
+    private final WorkSource mEmptyWorkSource = new WorkSource();
+
+    private final ScanRequest.Builder mScanRequestBuilder =
+            new ScanRequest.Builder()
+                    .setScanMode(SCAN_MODE_BALANCED)
+                    .setScanType(SCAN_TYPE_NEARBY_SHARE);
+    private final ScanRequest mScanRequest = mScanRequestBuilder.setWorkSource(mWorkSource).build();
+    private final ScanRequest mScanRequestWithEmptyWorkSource =
+            mScanRequestBuilder.setWorkSource(mEmptyWorkSource).build();
+
+    private final NearbyDeviceParcelable mNearbyDevice =
+            new NearbyDeviceParcelable.Builder()
+                    .setName(DEVICE_NAME)
+                    .setMedium(SCAN_MEDIUM)
+                    .setTxPower(1)
+                    .setRssi(RSSI)
+                    .setAction(1)
+                    .setPublicCredential(PUBLIC_CREDENTIAL)
+                    .setFastPairModelId(FAST_PAIR_MODEL_ID)
+                    .setBluetoothAddress(BLUETOOTH_ADDRESS)
+                    .setData(SCAN_DATA)
+                    .build();
+
+    private MockitoSession mSession;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mSession =
+                ExtendedMockito.mockitoSession()
+                        .strictness(Strictness.LENIENT)
+                        .mockStatic(NearbyStatsLog.class)
+                        .startMocking();
+    }
+
+    @After
+    public void tearDown() {
+        mSession.finishMocking();
+    }
+
+    @Test
+    public void testLogScanStart() {
+        NearbyMetrics.logScanStarted(SESSION_ID, mScanRequest);
+        ExtendedMockito.verify(() -> NearbyStatsLog.write(
+                NearbyStatsLog.NEARBY_DEVICE_SCAN_STATE_CHANGED,
+                WORK_SOURCE_UID,
+                SESSION_ID,
+                NearbyStatsLog
+                        .NEARBY_DEVICE_SCAN_STATE_CHANGED__SCAN_STATE__NEARBY_SCAN_STATE_STARTED,
+                SCAN_TYPE_NEARBY_SHARE,
+                0,
+                0,
+                "",
+                ""));
+    }
+
+    @Test
+    public void testLogScanStart_emptyWorkSource() {
+        NearbyMetrics.logScanStarted(SESSION_ID, mScanRequestWithEmptyWorkSource);
+        ExtendedMockito.verify(() -> NearbyStatsLog.write(
+                NearbyStatsLog.NEARBY_DEVICE_SCAN_STATE_CHANGED,
+                -1,
+                SESSION_ID,
+                NearbyStatsLog
+                        .NEARBY_DEVICE_SCAN_STATE_CHANGED__SCAN_STATE__NEARBY_SCAN_STATE_STARTED,
+                SCAN_TYPE_NEARBY_SHARE,
+                0,
+                0,
+                "",
+                ""));
+    }
+
+    @Test
+    public void testLogScanStopped() {
+        NearbyMetrics.logScanStopped(SESSION_ID, mScanRequest);
+        ExtendedMockito.verify(() -> NearbyStatsLog.write(
+                NearbyStatsLog.NEARBY_DEVICE_SCAN_STATE_CHANGED,
+                WORK_SOURCE_UID,
+                SESSION_ID,
+                NearbyStatsLog
+                        .NEARBY_DEVICE_SCAN_STATE_CHANGED__SCAN_STATE__NEARBY_SCAN_STATE_STOPPED,
+                SCAN_TYPE_NEARBY_SHARE,
+                0,
+                0,
+                "",
+                ""));
+    }
+
+    @Test
+    public void testLogScanStopped_emptyWorkSource() {
+        NearbyMetrics.logScanStopped(SESSION_ID, mScanRequestWithEmptyWorkSource);
+        ExtendedMockito.verify(() -> NearbyStatsLog.write(
+                NearbyStatsLog.NEARBY_DEVICE_SCAN_STATE_CHANGED,
+                -1,
+                SESSION_ID,
+                NearbyStatsLog
+                        .NEARBY_DEVICE_SCAN_STATE_CHANGED__SCAN_STATE__NEARBY_SCAN_STATE_STOPPED,
+                SCAN_TYPE_NEARBY_SHARE,
+                0,
+                0,
+                "",
+                ""));
+    }
+
+    @Test
+    public void testLogScanDeviceDiscovered() {
+        NearbyMetrics.logScanDeviceDiscovered(SESSION_ID, mScanRequest, mNearbyDevice);
+        ExtendedMockito.verify(() -> NearbyStatsLog.write(
+                NearbyStatsLog.NEARBY_DEVICE_SCAN_STATE_CHANGED,
+                WORK_SOURCE_UID,
+                SESSION_ID,
+                NearbyStatsLog
+                        .NEARBY_DEVICE_SCAN_STATE_CHANGED__SCAN_STATE__NEARBY_SCAN_STATE_DISCOVERED,
+                SCAN_TYPE_NEARBY_SHARE,
+                SCAN_MEDIUM,
+                RSSI,
+                FAST_PAIR_MODEL_ID,
+                ""));
+    }
+
+    @Test
+    public void testLogScanDeviceDiscovered_emptyWorkSource() {
+        NearbyMetrics.logScanDeviceDiscovered(
+                SESSION_ID, mScanRequestWithEmptyWorkSource, mNearbyDevice);
+        ExtendedMockito.verify(() -> NearbyStatsLog.write(
+                NearbyStatsLog.NEARBY_DEVICE_SCAN_STATE_CHANGED,
+                -1,
+                SESSION_ID,
+                NearbyStatsLog
+                        .NEARBY_DEVICE_SCAN_STATE_CHANGED__SCAN_STATE__NEARBY_SCAN_STATE_DISCOVERED,
+                SCAN_TYPE_NEARBY_SHARE,
+                SCAN_MEDIUM,
+                RSSI,
+                FAST_PAIR_MODEL_ID,
+                ""));
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/presence/FastAdvertisementTest.java b/nearby/tests/unit/src/com/android/server/nearby/presence/FastAdvertisementTest.java
new file mode 100644
index 0000000..5e0ccbe
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/presence/FastAdvertisementTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.presence;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.BroadcastRequest;
+import android.nearby.PresenceBroadcastRequest;
+import android.nearby.PresenceCredential;
+import android.nearby.PrivateCredential;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+
+/**
+ * Unit test for {@link FastAdvertisement}.
+ */
+public class FastAdvertisementTest {
+
+    private static final int IDENTITY_TYPE = PresenceCredential.IDENTITY_TYPE_PRIVATE;
+    private static final byte[] IDENTITY = new byte[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+    private static final int MEDIUM_TYPE_BLE = 0;
+    private static final byte[] SALT = {2, 3};
+    private static final byte TX_POWER = 4;
+    private static final int PRESENCE_ACTION = 123;
+    private static final byte[] SECRET_ID = new byte[]{1, 2, 3, 4};
+    private static final byte[] AUTHENTICITY_KEY = new byte[]{12, 13, 14};
+    private static final byte[] EXPECTED_ADV_BYTES =
+            new byte[]{2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 123};
+    private static final String DEVICE_NAME = "test_device";
+
+    private PresenceBroadcastRequest.Builder mBuilder;
+    private PrivateCredential mCredential;
+
+    @Before
+    public void setUp() {
+        mCredential =
+                new PrivateCredential.Builder(SECRET_ID, AUTHENTICITY_KEY, IDENTITY, DEVICE_NAME)
+                        .setIdentityType(PresenceCredential.IDENTITY_TYPE_PRIVATE)
+                        .build();
+        mBuilder =
+                new PresenceBroadcastRequest.Builder(Collections.singletonList(MEDIUM_TYPE_BLE),
+                        SALT, mCredential)
+                        .setTxPower(TX_POWER)
+                        .setVersion(BroadcastRequest.PRESENCE_VERSION_V0)
+                        .addAction(PRESENCE_ACTION);
+    }
+
+    @Test
+    public void testFastAdvertisementCreateFromRequest() {
+        FastAdvertisement originalAdvertisement = FastAdvertisement.createFromRequest(
+                mBuilder.build());
+
+        assertThat(originalAdvertisement.getActions()).containsExactly(PRESENCE_ACTION);
+        assertThat(originalAdvertisement.getIdentity()).isEqualTo(IDENTITY);
+        assertThat(originalAdvertisement.getIdentityType()).isEqualTo(IDENTITY_TYPE);
+        assertThat(originalAdvertisement.getLtvFieldCount()).isEqualTo(4);
+        assertThat(originalAdvertisement.getLength()).isEqualTo(19);
+        assertThat(originalAdvertisement.getVersion()).isEqualTo(
+                BroadcastRequest.PRESENCE_VERSION_V0);
+        assertThat(originalAdvertisement.getSalt()).isEqualTo(SALT);
+    }
+
+    @Test
+    public void testFastAdvertisementSerialization() {
+        FastAdvertisement originalAdvertisement = FastAdvertisement.createFromRequest(
+                mBuilder.build());
+        byte[] bytes = originalAdvertisement.toBytes();
+
+        assertThat(bytes).hasLength(originalAdvertisement.getLength());
+        assertThat(bytes).isEqualTo(EXPECTED_ADV_BYTES);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/presence/PresenceDiscoveryResultTest.java b/nearby/tests/unit/src/com/android/server/nearby/presence/PresenceDiscoveryResultTest.java
new file mode 100644
index 0000000..39cab94
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/presence/PresenceDiscoveryResultTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.presence;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.PresenceCredential;
+import android.nearby.PresenceDevice;
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
+
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * Unit tests for {@link PresenceDiscoveryResult}.
+ */
+public class PresenceDiscoveryResultTest {
+    private static final int PRESENCE_ACTION = 123;
+    private static final int TX_POWER = -1;
+    private static final int RSSI = -41;
+    private static final byte[] SALT = new byte[]{12, 34};
+    private static final byte[] SECRET_ID = new byte[]{1, 2, 3, 4};
+    private static final byte[] AUTHENTICITY_KEY = new byte[]{12, 13, 14};
+    private static final byte[] PUBLIC_KEY = new byte[]{1, 1, 2, 2};
+    private static final byte[] ENCRYPTED_METADATA = new byte[]{1, 2, 3, 4, 5};
+    private static final byte[] METADATA_ENCRYPTION_KEY_TAG = new byte[]{1, 1, 3, 4, 5};
+
+    private PresenceDiscoveryResult.Builder mBuilder;
+    private PublicCredential mCredential;
+
+    @Before
+    public void setUp() {
+        mCredential =
+                new PublicCredential.Builder(SECRET_ID, AUTHENTICITY_KEY, PUBLIC_KEY,
+                        ENCRYPTED_METADATA, METADATA_ENCRYPTION_KEY_TAG)
+                        .setIdentityType(PresenceCredential.IDENTITY_TYPE_PRIVATE)
+                        .build();
+        mBuilder = new PresenceDiscoveryResult.Builder()
+                .setPublicCredential(mCredential)
+                .setSalt(SALT)
+                .setTxPower(TX_POWER)
+                .setRssi(RSSI)
+                .addPresenceAction(PRESENCE_ACTION);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testToDevice() {
+        PresenceDiscoveryResult discoveryResult = mBuilder.build();
+        PresenceDevice presenceDevice = discoveryResult.toPresenceDevice();
+
+        assertThat(presenceDevice.getRssi()).isEqualTo(RSSI);
+        assertThat(Arrays.equals(presenceDevice.getSalt(), SALT)).isTrue();
+        assertThat(Arrays.equals(presenceDevice.getSecretId(), SECRET_ID)).isTrue();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testMatches() {
+        PresenceScanFilter scanFilter = new PresenceScanFilter.Builder()
+                .setMaxPathLoss(80)
+                .addPresenceAction(PRESENCE_ACTION)
+                .addCredential(mCredential)
+                .build();
+
+        PresenceDiscoveryResult discoveryResult = mBuilder.build();
+        assertThat(discoveryResult.matches(scanFilter)).isTrue();
+    }
+
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/presence/PresenceManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/presence/PresenceManagerTest.java
new file mode 100644
index 0000000..d32e325
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/presence/PresenceManagerTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.presence;
+
+
+
+
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+
+public class PresenceManagerTest {
+    private PresenceManager mPresenceManager;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testInit() {}
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/provider/BleBroadcastProviderTest.java b/nearby/tests/unit/src/com/android/server/nearby/provider/BleBroadcastProviderTest.java
new file mode 100644
index 0000000..f485e18
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/provider/BleBroadcastProviderTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.le.AdvertiseSettings;
+import android.content.Context;
+import android.nearby.BroadcastCallback;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.server.nearby.injector.ContextHubManagerAdapter;
+import com.android.server.nearby.injector.Injector;
+
+import com.google.common.util.concurrent.MoreExecutors;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+/**
+ * Unit test for {@link BleBroadcastProvider}.
+ */
+public class BleBroadcastProviderTest {
+    @Rule
+    public final MockitoRule mocks = MockitoJUnit.rule();
+
+    @Mock
+    private BleBroadcastProvider.BroadcastListener mBroadcastListener;
+    private BleBroadcastProvider mBleBroadcastProvider;
+
+    @Before
+    public void setUp() {
+        mBleBroadcastProvider = new BleBroadcastProvider(new TestInjector(),
+                MoreExecutors.directExecutor());
+    }
+
+    @Test
+    public void testOnStatus_success() {
+        byte[] advertiseBytes = new byte[]{1, 2, 3, 4};
+        mBleBroadcastProvider.start(advertiseBytes, mBroadcastListener);
+        verify(mBroadcastListener).onStatusChanged(eq(BroadcastCallback.STATUS_FAILURE));
+
+        AdvertiseSettings settings = new AdvertiseSettings.Builder().build();
+        mBleBroadcastProvider.onStartSuccess(settings);
+        verify(mBroadcastListener).onStatusChanged(eq(BroadcastCallback.STATUS_OK));
+    }
+
+    @Test
+    public void testOnStatus_failure() {
+        byte[] advertiseBytes = new byte[]{1, 2, 3, 4};
+        mBleBroadcastProvider.start(advertiseBytes, mBroadcastListener);
+
+        mBleBroadcastProvider.onStartFailure(BroadcastCallback.STATUS_FAILURE);
+        verify(mBroadcastListener, times(2)).onStatusChanged(eq(BroadcastCallback.STATUS_FAILURE));
+    }
+
+    private static class TestInjector implements Injector {
+
+        @Override
+        public BluetoothAdapter getBluetoothAdapter() {
+            Context context = ApplicationProvider.getApplicationContext();
+            BluetoothManager bluetoothManager = context.getSystemService(BluetoothManager.class);
+            return bluetoothManager.getAdapter();
+        }
+
+        @Override
+        public ContextHubManagerAdapter getContextHubManagerAdapter() {
+            return null;
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/provider/BleDiscoveryProviderTest.java b/nearby/tests/unit/src/com/android/server/nearby/provider/BleDiscoveryProviderTest.java
new file mode 100644
index 0000000..8e97443
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/provider/BleDiscoveryProviderTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.nearby.injector.ContextHubManagerAdapter;
+import com.android.server.nearby.injector.Injector;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public final class BleDiscoveryProviderTest {
+
+    private BluetoothAdapter mBluetoothAdapter;
+    private BleDiscoveryProvider mBleDiscoveryProvider;
+    @Mock
+    private AbstractDiscoveryProvider.Listener mListener;
+
+    @Before
+    public void setup() {
+        initMocks(this);
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        Injector injector = new TestInjector();
+
+        mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
+        mBleDiscoveryProvider = new BleDiscoveryProvider(context, injector);
+    }
+
+    @Test
+    public void test_callback() throws InterruptedException {
+        mBleDiscoveryProvider.getController().setListener(mListener);
+        mBleDiscoveryProvider.onStart();
+        mBleDiscoveryProvider.getScanCallback()
+                .onScanResult(CALLBACK_TYPE_ALL_MATCHES, createScanResult());
+
+        // Wait for callback to be invoked
+        Thread.sleep(500);
+        verify(mListener, times(1)).onNearbyDeviceDiscovered(any());
+    }
+
+    @Test
+    public void test_stopScan() {
+        mBleDiscoveryProvider.onStart();
+        mBleDiscoveryProvider.onStop();
+    }
+
+    private class TestInjector implements Injector {
+        @Override
+        public BluetoothAdapter getBluetoothAdapter() {
+            return mBluetoothAdapter;
+        }
+
+        @Override
+        public ContextHubManagerAdapter getContextHubManagerAdapter() {
+            return null;
+        }
+    }
+
+    private ScanResult createScanResult() {
+        BluetoothDevice bluetoothDevice = mBluetoothAdapter
+                .getRemoteDevice("11:22:33:44:55:66");
+        byte[] scanRecord = new byte[] {2, 1, 6, 6, 22, 44, -2, 113, -116, 23, 2, 10, -11, 0, 0, 0,
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+        return new ScanResult(
+                bluetoothDevice,
+                /* eventType= */ 0,
+                /* primaryPhy= */ 0,
+                /* secondaryPhy= */ 0,
+                /* advertisingSid= */ 0,
+                -31,
+                -50,
+                /* periodicAdvertisingInterval= */ 0,
+                parseScanRecord(scanRecord),
+                1645579363003L);
+    }
+
+    private static ScanRecord parseScanRecord(byte[] bytes) {
+        Class<?> scanRecordClass = ScanRecord.class;
+        try {
+            Method method = scanRecordClass
+                    .getDeclaredMethod("parseFromBytes", byte[].class);
+            return (ScanRecord) method.invoke(null, bytes);
+        } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException
+                | InvocationTargetException e) {
+            return null;
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/provider/BroadcastProviderManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/provider/BroadcastProviderManagerTest.java
new file mode 100644
index 0000000..d45d570
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/provider/BroadcastProviderManagerTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import static android.Manifest.permission.READ_DEVICE_CONFIG;
+import static android.Manifest.permission.WRITE_DEVICE_CONFIG;
+import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
+
+import static com.android.server.nearby.NearbyConfiguration.NEARBY_ENABLE_PRESENCE_BROADCAST_LEGACY;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.verify;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.nearby.BroadcastCallback;
+import android.nearby.BroadcastRequest;
+import android.nearby.IBroadcastListener;
+import android.nearby.PresenceBroadcastRequest;
+import android.nearby.PresenceCredential;
+import android.nearby.PrivateCredential;
+import android.provider.DeviceConfig;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.google.common.util.concurrent.MoreExecutors;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.Collections;
+
+/**
+ * Unit test for {@link BroadcastProviderManager}.
+ */
+public class BroadcastProviderManagerTest {
+    private static final byte[] IDENTITY = new byte[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+    private static final int MEDIUM_TYPE_BLE = 0;
+    private static final byte[] SALT = {2, 3};
+    private static final byte TX_POWER = 4;
+    private static final int PRESENCE_ACTION = 123;
+    private static final byte[] SECRET_ID = new byte[]{1, 2, 3, 4};
+    private static final byte[] AUTHENTICITY_KEY = new byte[]{12, 13, 14};
+    private static final String DEVICE_NAME = "test_device";
+
+    @Rule
+    public final MockitoRule mocks = MockitoJUnit.rule();
+
+    @Mock
+    IBroadcastListener mBroadcastListener;
+    @Mock
+    BleBroadcastProvider mBleBroadcastProvider;
+    private Context mContext;
+    private BroadcastProviderManager mBroadcastProviderManager;
+    private BroadcastRequest mBroadcastRequest;
+    private UiAutomation mUiAutomation =
+            InstrumentationRegistry.getInstrumentation().getUiAutomation();
+
+    @Before
+    public void setUp() {
+        mUiAutomation.adoptShellPermissionIdentity(WRITE_DEVICE_CONFIG, READ_DEVICE_CONFIG);
+        DeviceConfig.setProperty(NAMESPACE_TETHERING, NEARBY_ENABLE_PRESENCE_BROADCAST_LEGACY,
+                "true", false);
+
+        mContext = ApplicationProvider.getApplicationContext();
+        mBroadcastProviderManager = new BroadcastProviderManager(MoreExecutors.directExecutor(),
+                mBleBroadcastProvider);
+
+        PrivateCredential privateCredential =
+                new PrivateCredential.Builder(SECRET_ID, AUTHENTICITY_KEY, IDENTITY, DEVICE_NAME)
+                        .setIdentityType(PresenceCredential.IDENTITY_TYPE_PRIVATE)
+                        .build();
+        mBroadcastRequest =
+                new PresenceBroadcastRequest.Builder(Collections.singletonList(MEDIUM_TYPE_BLE),
+                        SALT, privateCredential)
+                        .setTxPower(TX_POWER)
+                        .setVersion(BroadcastRequest.PRESENCE_VERSION_V0)
+                        .addAction(PRESENCE_ACTION).build();
+    }
+
+    @Test
+    public void testStartAdvertising() {
+        mBroadcastProviderManager.startBroadcast(mBroadcastRequest, mBroadcastListener);
+        verify(mBleBroadcastProvider).start(any(byte[].class), any(
+                BleBroadcastProvider.BroadcastListener.class));
+    }
+
+    @Test
+    public void testStartAdvertising_featureDisabled() throws Exception {
+        DeviceConfig.setProperty(NAMESPACE_TETHERING, NEARBY_ENABLE_PRESENCE_BROADCAST_LEGACY,
+                "false", false);
+        mBroadcastProviderManager = new BroadcastProviderManager(MoreExecutors.directExecutor(),
+                mBleBroadcastProvider);
+        mBroadcastProviderManager.startBroadcast(mBroadcastRequest, mBroadcastListener);
+        verify(mBroadcastListener).onStatusChanged(eq(BroadcastCallback.STATUS_FAILURE));
+    }
+
+    @Test
+    public void testOnStatusChanged() throws Exception {
+        mBroadcastProviderManager.startBroadcast(mBroadcastRequest, mBroadcastListener);
+        mBroadcastProviderManager.onStatusChanged(BroadcastCallback.STATUS_OK);
+        verify(mBroadcastListener).onStatusChanged(eq(BroadcastCallback.STATUS_OK));
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/provider/ChreCommunicationTest.java b/nearby/tests/unit/src/com/android/server/nearby/provider/ChreCommunicationTest.java
new file mode 100644
index 0000000..1b29b52
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/provider/ChreCommunicationTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.location.ContextHubClient;
+import android.hardware.location.ContextHubInfo;
+import android.hardware.location.ContextHubTransaction;
+import android.hardware.location.NanoAppMessage;
+import android.hardware.location.NanoAppState;
+
+import com.android.server.nearby.injector.ContextHubManagerAdapter;
+import com.android.server.nearby.injector.Injector;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+public class ChreCommunicationTest {
+    @Mock Injector mInjector;
+    @Mock ContextHubManagerAdapter mManager;
+    @Mock ContextHubTransaction<List<NanoAppState>> mTransaction;
+    @Mock ContextHubTransaction.Response<List<NanoAppState>> mTransactionResponse;
+    @Mock ContextHubClient mClient;
+    @Mock ChreCommunication.ContextHubCommsCallback mChreCallback;
+
+    @Captor
+    ArgumentCaptor<ChreCommunication.OnQueryCompleteListener> mOnQueryCompleteListenerCaptor;
+
+    private ChreCommunication mChreCommunication;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mInjector.getContextHubManagerAdapter()).thenReturn(mManager);
+        when(mManager.getContextHubs()).thenReturn(Collections.singletonList(new ContextHubInfo()));
+        when(mManager.queryNanoApps(any())).thenReturn(mTransaction);
+        when(mManager.createClient(any(), any(), any())).thenReturn(mClient);
+        when(mTransactionResponse.getResult()).thenReturn(ContextHubTransaction.RESULT_SUCCESS);
+        when(mTransactionResponse.getContents())
+                .thenReturn(
+                        Collections.singletonList(
+                                new NanoAppState(ChreDiscoveryProvider.NANOAPP_ID, 1, true)));
+
+        mChreCommunication = new ChreCommunication(mInjector, new InlineExecutor());
+        mChreCommunication.start(
+                mChreCallback, Collections.singleton(ChreDiscoveryProvider.NANOAPP_ID));
+
+        verify(mTransaction).setOnCompleteListener(mOnQueryCompleteListenerCaptor.capture(), any());
+        mOnQueryCompleteListenerCaptor.getValue().onComplete(mTransaction, mTransactionResponse);
+    }
+
+    @Test
+    public void testStart() {
+        verify(mChreCallback).started(true);
+    }
+
+    @Test
+    public void testStop() {
+        mChreCommunication.stop();
+        verify(mClient).close();
+    }
+
+    @Test
+    public void testSendMessageToNanApp() {
+        NanoAppMessage message =
+                NanoAppMessage.createMessageToNanoApp(
+                        ChreDiscoveryProvider.NANOAPP_ID,
+                        ChreDiscoveryProvider.NANOAPP_MESSAGE_TYPE_FILTER,
+                        new byte[] {1, 2, 3});
+        mChreCommunication.sendMessageToNanoApp(message);
+        verify(mClient).sendMessageToNanoApp(eq(message));
+    }
+
+    @Test
+    public void testOnMessageFromNanoApp() {
+        NanoAppMessage message =
+                NanoAppMessage.createMessageToNanoApp(
+                        ChreDiscoveryProvider.NANOAPP_ID,
+                        ChreDiscoveryProvider.NANOAPP_MESSAGE_TYPE_FILTER_RESULT,
+                        new byte[] {1, 2, 3});
+        mChreCommunication.onMessageFromNanoApp(mClient, message);
+        verify(mChreCallback).onMessageFromNanoApp(eq(message));
+    }
+
+    @Test
+    public void testOnHubReset() {
+        mChreCommunication.onHubReset(mClient);
+        verify(mChreCallback).onHubReset();
+    }
+
+    @Test
+    public void testOnNanoAppLoaded() {
+        mChreCommunication.onNanoAppLoaded(mClient, ChreDiscoveryProvider.NANOAPP_ID);
+        verify(mChreCallback).onNanoAppRestart(eq(ChreDiscoveryProvider.NANOAPP_ID));
+    }
+
+    private static class InlineExecutor implements Executor {
+        @Override
+        public void execute(Runnable command) {
+            command.run();
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/provider/ChreDiscoveryProviderTest.java b/nearby/tests/unit/src/com/android/server/nearby/provider/ChreDiscoveryProviderTest.java
new file mode 100644
index 0000000..7c0dd92
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/provider/ChreDiscoveryProviderTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.hardware.location.NanoAppMessage;
+import android.nearby.ScanFilter;
+
+import androidx.test.filters.SdkSuppress;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.google.protobuf.ByteString;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import service.proto.Blefilter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+public class ChreDiscoveryProviderTest {
+    @Mock AbstractDiscoveryProvider.Listener mListener;
+    @Mock ChreCommunication mChreCommunication;
+
+    @Captor ArgumentCaptor<ChreCommunication.ContextHubCommsCallback> mChreCallbackCaptor;
+
+    private ChreDiscoveryProvider mChreDiscoveryProvider;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        mChreDiscoveryProvider =
+                new ChreDiscoveryProvider(context, mChreCommunication, new InLineExecutor());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testOnStart() {
+        List<ScanFilter> scanFilters = new ArrayList<>();
+        mChreDiscoveryProvider.getController().setProviderScanFilters(scanFilters);
+        mChreDiscoveryProvider.onStart();
+        verify(mChreCommunication).start(mChreCallbackCaptor.capture(), any());
+        mChreCallbackCaptor.getValue().started(true);
+        verify(mChreCommunication).sendMessageToNanoApp(any());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testOnNearbyDeviceDiscovered() {
+        Blefilter.PublicCredential credential =
+                Blefilter.PublicCredential.newBuilder()
+                        .setSecretId(ByteString.copyFrom(new byte[] {1}))
+                        .setAuthenticityKey(ByteString.copyFrom(new byte[2]))
+                        .setPublicKey(ByteString.copyFrom(new byte[3]))
+                        .setEncryptedMetadata(ByteString.copyFrom(new byte[4]))
+                        .setEncryptedMetadataTag(ByteString.copyFrom(new byte[5]))
+                        .build();
+        Blefilter.BleFilterResult result =
+                Blefilter.BleFilterResult.newBuilder()
+                        .setTxPower(2)
+                        .setRssi(1)
+                        .setPublicCredential(credential)
+                        .build();
+        Blefilter.BleFilterResults results =
+                Blefilter.BleFilterResults.newBuilder().addResult(result).build();
+        NanoAppMessage chre_message =
+                NanoAppMessage.createMessageToNanoApp(
+                        ChreDiscoveryProvider.NANOAPP_ID,
+                        ChreDiscoveryProvider.NANOAPP_MESSAGE_TYPE_FILTER_RESULT,
+                        results.toByteArray());
+        mChreDiscoveryProvider.getController().setListener(mListener);
+        mChreDiscoveryProvider.onStart();
+        verify(mChreCommunication).start(mChreCallbackCaptor.capture(), any());
+        mChreCallbackCaptor.getValue().onMessageFromNanoApp(chre_message);
+        verify(mListener).onNearbyDeviceDiscovered(any());
+    }
+
+    private static class InLineExecutor implements Executor {
+        @Override
+        public void execute(Runnable command) {
+            command.run();
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/provider/UtilsTest.java b/nearby/tests/unit/src/com/android/server/nearby/provider/UtilsTest.java
new file mode 100644
index 0000000..205d5c2
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/provider/UtilsTest.java
@@ -0,0 +1,733 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.accounts.Account;
+import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
+import android.nearby.aidl.FastPairAntispoofKeyDeviceMetadataParcel;
+import android.nearby.aidl.FastPairDeviceMetadataParcel;
+import android.nearby.aidl.FastPairDiscoveryItemParcel;
+import android.nearby.aidl.FastPairEligibleAccountParcel;
+
+import androidx.test.filters.SdkSuppress;
+
+import com.android.server.nearby.fastpair.footprint.FastPairUploadInfo;
+
+import com.google.protobuf.ByteString;
+
+import org.junit.Test;
+
+import java.util.List;
+
+import service.proto.Cache;
+import service.proto.Data;
+import service.proto.FastPairString.FastPairStrings;
+import service.proto.Rpcs;
+
+public class UtilsTest {
+
+    private static final String ASSISTANT_SETUP_HALFSHEET = "ASSISTANT_SETUP_HALFSHEET";
+    private static final String ASSISTANT_SETUP_NOTIFICATION = "ASSISTANT_SETUP_NOTIFICATION";
+    private static final int BLE_TX_POWER = 5;
+    private static final String CONFIRM_PIN_DESCRIPTION = "CONFIRM_PIN_DESCRIPTION";
+    private static final String CONFIRM_PIN_TITLE = "CONFIRM_PIN_TITLE";
+    private static final String CONNECT_SUCCESS_COMPANION_APP_INSTALLED =
+            "CONNECT_SUCCESS_COMPANION_APP_INSTALLED";
+    private static final String CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED =
+            "CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED";
+    private static final int DEVICE_TYPE = 1;
+    private static final String DOWNLOAD_COMPANION_APP_DESCRIPTION =
+            "DOWNLOAD_COMPANION_APP_DESCRIPTION";
+    private static final Account ELIGIBLE_ACCOUNT_1 = new Account("abc@google.com", "type1");
+    private static final String FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION =
+            "FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION";
+    private static final String FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION =
+            "FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION";
+    private static final byte[] IMAGE = new byte[]{7, 9};
+    private static final String IMAGE_URL = "IMAGE_URL";
+    private static final String INITIAL_NOTIFICATION_DESCRIPTION =
+            "INITIAL_NOTIFICATION_DESCRIPTION";
+    private static final String INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT =
+            "INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT";
+    private static final String INITIAL_PAIRING_DESCRIPTION = "INITIAL_PAIRING_DESCRIPTION";
+    private static final String INTENT_URI = "INTENT_URI";
+    private static final String LOCALE = "LOCALE";
+    private static final String OPEN_COMPANION_APP_DESCRIPTION = "OPEN_COMPANION_APP_DESCRIPTION";
+    private static final String RETRO_ACTIVE_PAIRING_DESCRIPTION =
+            "RETRO_ACTIVE_PAIRING_DESCRIPTION";
+    private static final String SUBSEQUENT_PAIRING_DESCRIPTION = "SUBSEQUENT_PAIRING_DESCRIPTION";
+    private static final String SYNC_CONTACT_DESCRPTION = "SYNC_CONTACT_DESCRPTION";
+    private static final String SYNC_CONTACTS_TITLE = "SYNC_CONTACTS_TITLE";
+    private static final String SYNC_SMS_DESCRIPTION = "SYNC_SMS_DESCRIPTION";
+    private static final String SYNC_SMS_TITLE = "SYNC_SMS_TITLE";
+    private static final float TRIGGER_DISTANCE = 111;
+    private static final String TRUE_WIRELESS_IMAGE_URL_CASE = "TRUE_WIRELESS_IMAGE_URL_CASE";
+    private static final String TRUE_WIRELESS_IMAGE_URL_LEFT_BUD =
+            "TRUE_WIRELESS_IMAGE_URL_LEFT_BUD";
+    private static final String TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD =
+            "TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD";
+    private static final String UNABLE_TO_CONNECT_DESCRIPTION = "UNABLE_TO_CONNECT_DESCRIPTION";
+    private static final String UNABLE_TO_CONNECT_TITLE = "UNABLE_TO_CONNECT_TITLE";
+    private static final String UPDATE_COMPANION_APP_DESCRIPTION =
+            "UPDATE_COMPANION_APP_DESCRIPTION";
+    private static final String WAIT_LAUNCH_COMPANION_APP_DESCRIPTION =
+            "WAIT_LAUNCH_COMPANION_APP_DESCRIPTION";
+    private static final byte[] ACCOUNT_KEY = new byte[]{3};
+    private static final byte[] SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS = new byte[]{2, 8};
+    private static final byte[] ANTI_SPOOFING_KEY = new byte[]{4, 5, 6};
+    private static final String ACTION_URL = "ACTION_URL";
+    private static final int ACTION_URL_TYPE = 1;
+    private static final String APP_NAME = "APP_NAME";
+    private static final int ATTACHMENT_TYPE = 1;
+    private static final byte[] AUTHENTICATION_PUBLIC_KEY_SEC_P256R1 = new byte[]{5, 7};
+    private static final byte[] BLE_RECORD_BYTES = new byte[]{2, 4};
+    private static final int DEBUG_CATEGORY = 1;
+    private static final String DEBUG_MESSAGE = "DEBUG_MESSAGE";
+    private static final String DESCRIPTION = "DESCRIPTION";
+    private static final String DEVICE_NAME = "DEVICE_NAME";
+    private static final String DISPLAY_URL = "DISPLAY_URL";
+    private static final String ENTITY_ID = "ENTITY_ID";
+    private static final String FEATURE_GRAPHIC_URL = "FEATURE_GRAPHIC_URL";
+    private static final long FIRST_OBSERVATION_TIMESTAMP_MILLIS = 8393L;
+    private static final String GROUP_ID = "GROUP_ID";
+    private static final String ICON_FIFE_URL = "ICON_FIFE_URL";
+    private static final byte[] ICON_PNG = new byte[]{2, 5};
+    private static final String ID = "ID";
+    private static final long LAST_OBSERVATION_TIMESTAMP_MILLIS = 934234L;
+    private static final int LAST_USER_EXPERIENCE = 1;
+    private static final long LOST_MILLIS = 393284L;
+    private static final String MAC_ADDRESS = "MAC_ADDRESS";
+    private static final String NAME = "NAME";
+    private static final String PACKAGE_NAME = "PACKAGE_NAME";
+    private static final long PENDING_APP_INSTALL_TIMESTAMP_MILLIS = 832393L;
+    private static final int RSSI = 9;
+    private static final int STATE = 1;
+    private static final String TITLE = "TITLE";
+    private static final String TRIGGER_ID = "TRIGGER_ID";
+    private static final int TX_POWER = 63;
+    private static final int TYPE = 1;
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHappyPathConvertToFastPairDevicesWithAccountKey() {
+        FastPairAccountKeyDeviceMetadataParcel[] array = {
+                genHappyPathFastPairAccountkeyDeviceMetadataParcel()};
+
+        List<Data.FastPairDeviceWithAccountKey> deviceWithAccountKey =
+                Utils.convertToFastPairDevicesWithAccountKey(array);
+        assertThat(deviceWithAccountKey.size()).isEqualTo(1);
+        assertThat(deviceWithAccountKey.get(0)).isEqualTo(
+                genHappyPathFastPairDeviceWithAccountKey());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToFastPairDevicesWithAccountKeyWithNullArray() {
+        FastPairAccountKeyDeviceMetadataParcel[] array = null;
+        assertThat(Utils.convertToFastPairDevicesWithAccountKey(array).size()).isEqualTo(0);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToFastPairDevicesWithAccountKeyWithNullElement() {
+        FastPairAccountKeyDeviceMetadataParcel[] array = {null};
+        assertThat(Utils.convertToFastPairDevicesWithAccountKey(array).size()).isEqualTo(0);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToFastPairDevicesWithAccountKeyWithEmptyElementNoCrash() {
+        FastPairAccountKeyDeviceMetadataParcel[] array = {
+                genEmptyFastPairAccountkeyDeviceMetadataParcel()};
+
+        List<Data.FastPairDeviceWithAccountKey> deviceWithAccountKey =
+                Utils.convertToFastPairDevicesWithAccountKey(array);
+        assertThat(deviceWithAccountKey.size()).isEqualTo(1);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToFastPairDevicesWithAccountKeyWithEmptyMetadataDiscoveryNoCrash() {
+        FastPairAccountKeyDeviceMetadataParcel[] array = {
+                genFastPairAccountkeyDeviceMetadataParcelWithEmptyMetadataDiscoveryItem()};
+
+        List<Data.FastPairDeviceWithAccountKey> deviceWithAccountKey =
+                Utils.convertToFastPairDevicesWithAccountKey(array);
+        assertThat(deviceWithAccountKey.size()).isEqualTo(1);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToFastPairDevicesWithAccountKeyWithMixedArrayElements() {
+        FastPairAccountKeyDeviceMetadataParcel[] array = {
+                null,
+                genHappyPathFastPairAccountkeyDeviceMetadataParcel(),
+                genEmptyFastPairAccountkeyDeviceMetadataParcel(),
+                genFastPairAccountkeyDeviceMetadataParcelWithEmptyMetadataDiscoveryItem()};
+
+        assertThat(Utils.convertToFastPairDevicesWithAccountKey(array).size()).isEqualTo(3);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHappyPathConvertToAccountList() {
+        FastPairEligibleAccountParcel[] array = {genHappyPathFastPairEligibleAccountParcel()};
+
+        List<Account> accountList = Utils.convertToAccountList(array);
+        assertThat(accountList.size()).isEqualTo(1);
+        assertThat(accountList.get(0)).isEqualTo(ELIGIBLE_ACCOUNT_1);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToAccountListNullArray() {
+        FastPairEligibleAccountParcel[] array = null;
+
+        List<Account> accountList = Utils.convertToAccountList(array);
+        assertThat(accountList.size()).isEqualTo(0);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToAccountListWithNullElement() {
+        FastPairEligibleAccountParcel[] array = {null};
+
+        List<Account> accountList = Utils.convertToAccountList(array);
+        assertThat(accountList.size()).isEqualTo(0);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToAccountListWithEmptyElementNotCrash() {
+        FastPairEligibleAccountParcel[] array =
+                {genEmptyFastPairEligibleAccountParcel()};
+
+        List<Account> accountList = Utils.convertToAccountList(array);
+        assertThat(accountList.size()).isEqualTo(0);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToAccountListWithMixedArrayElements() {
+        FastPairEligibleAccountParcel[] array = {
+                genHappyPathFastPairEligibleAccountParcel(),
+                genEmptyFastPairEligibleAccountParcel(),
+                null,
+                genHappyPathFastPairEligibleAccountParcel()};
+
+        List<Account> accountList = Utils.convertToAccountList(array);
+        assertThat(accountList.size()).isEqualTo(2);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHappyPathConvertToGetObservedDeviceResponse() {
+        Rpcs.GetObservedDeviceResponse response =
+                Utils.convertToGetObservedDeviceResponse(
+                        genHappyPathFastPairAntispoofKeyDeviceMetadataParcel());
+        assertThat(response).isEqualTo(genHappyPathObservedDeviceResponse());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToGetObservedDeviceResponseWithNullInput() {
+        assertThat(Utils.convertToGetObservedDeviceResponse(null))
+                .isEqualTo(null);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToGetObservedDeviceResponseWithEmptyInputNotCrash() {
+        Utils.convertToGetObservedDeviceResponse(
+                genEmptyFastPairAntispoofKeyDeviceMetadataParcel());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToGetObservedDeviceResponseWithEmptyDeviceMetadataNotCrash() {
+        Utils.convertToGetObservedDeviceResponse(
+                genFastPairAntispoofKeyDeviceMetadataParcelWithEmptyDeviceMetadata());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testHappyPathConvertToFastPairAccountKeyDeviceMetadata() {
+        FastPairAccountKeyDeviceMetadataParcel metadataParcel =
+                Utils.convertToFastPairAccountKeyDeviceMetadata(genHappyPathFastPairUploadInfo());
+        ensureHappyPathAsExpected(metadataParcel);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToFastPairAccountKeyDeviceMetadataWithNullInput() {
+        assertThat(Utils.convertToFastPairAccountKeyDeviceMetadata(null)).isEqualTo(null);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 32, codeName = "T")
+    public void testConvertToFastPairAccountKeyDeviceMetadataWithEmptyFieldsNotCrash() {
+        Utils.convertToFastPairAccountKeyDeviceMetadata(
+                new FastPairUploadInfo(
+                        null /* discoveryItem */,
+                        null /* accountKey */,
+                        null /* sha256AccountKeyPublicAddress */));
+    }
+
+    private static FastPairUploadInfo genHappyPathFastPairUploadInfo() {
+        return new FastPairUploadInfo(
+                genHappyPathStoredDiscoveryItem(),
+                ByteString.copyFrom(ACCOUNT_KEY),
+                ByteString.copyFrom(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS));
+
+    }
+
+    private static void ensureHappyPathAsExpected(
+            FastPairAccountKeyDeviceMetadataParcel metadataParcel) {
+        assertThat(metadataParcel).isNotNull();
+        assertThat(metadataParcel.deviceAccountKey).isEqualTo(ACCOUNT_KEY);
+        assertThat(metadataParcel.sha256DeviceAccountKeyPublicAddress)
+                .isEqualTo(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS);
+        ensureHappyPathAsExpected(metadataParcel.metadata);
+        ensureHappyPathAsExpected(metadataParcel.discoveryItem);
+    }
+
+    private static void ensureHappyPathAsExpected(FastPairDeviceMetadataParcel metadataParcel) {
+        assertThat(metadataParcel).isNotNull();
+
+        assertThat(metadataParcel.assistantSetupHalfSheet).isEqualTo(ASSISTANT_SETUP_HALFSHEET);
+        assertThat(metadataParcel.assistantSetupNotification).isEqualTo(
+                ASSISTANT_SETUP_NOTIFICATION);
+
+
+        assertThat(metadataParcel.confirmPinDescription).isEqualTo(CONFIRM_PIN_DESCRIPTION);
+        assertThat(metadataParcel.confirmPinTitle).isEqualTo(CONFIRM_PIN_TITLE);
+        assertThat(metadataParcel.connectSuccessCompanionAppInstalled).isEqualTo(
+                CONNECT_SUCCESS_COMPANION_APP_INSTALLED);
+        assertThat(metadataParcel.connectSuccessCompanionAppNotInstalled).isEqualTo(
+                CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED);
+
+        assertThat(metadataParcel.deviceType).isEqualTo(DEVICE_TYPE);
+
+        assertThat(metadataParcel.failConnectGoToSettingsDescription).isEqualTo(
+                FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION);
+        assertThat(metadataParcel.fastPairTvConnectDeviceNoAccountDescription).isEqualTo(
+                FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION);
+
+        assertThat(metadataParcel.initialNotificationDescription).isEqualTo(
+                INITIAL_NOTIFICATION_DESCRIPTION);
+        assertThat(metadataParcel.initialNotificationDescriptionNoAccount).isEqualTo(
+                INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT);
+        assertThat(metadataParcel.initialPairingDescription).isEqualTo(INITIAL_PAIRING_DESCRIPTION);
+
+
+        assertThat(metadataParcel.retroactivePairingDescription).isEqualTo(
+                RETRO_ACTIVE_PAIRING_DESCRIPTION);
+
+        assertThat(metadataParcel.subsequentPairingDescription).isEqualTo(
+                SUBSEQUENT_PAIRING_DESCRIPTION);
+        assertThat(metadataParcel.syncContactsDescription).isEqualTo(SYNC_CONTACT_DESCRPTION);
+        assertThat(metadataParcel.syncContactsTitle).isEqualTo(SYNC_CONTACTS_TITLE);
+        assertThat(metadataParcel.syncSmsDescription).isEqualTo(SYNC_SMS_DESCRIPTION);
+        assertThat(metadataParcel.syncSmsTitle).isEqualTo(SYNC_SMS_TITLE);
+
+        assertThat(metadataParcel.trueWirelessImageUrlCase).isEqualTo(TRUE_WIRELESS_IMAGE_URL_CASE);
+        assertThat(metadataParcel.trueWirelessImageUrlLeftBud).isEqualTo(
+                TRUE_WIRELESS_IMAGE_URL_LEFT_BUD);
+        assertThat(metadataParcel.trueWirelessImageUrlRightBud).isEqualTo(
+                TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD);
+        assertThat(metadataParcel.waitLaunchCompanionAppDescription).isEqualTo(
+                WAIT_LAUNCH_COMPANION_APP_DESCRIPTION);
+
+        /* do we need upload this? */
+        // assertThat(metadataParcel.locale).isEqualTo(LOCALE);
+        // assertThat(metadataParcel.name).isEqualTo(NAME);
+        // assertThat(metadataParcel.downloadCompanionAppDescription).isEqualTo(
+        //        DOWNLOAD_COMPANION_APP_DESCRIPTION);
+        // assertThat(metadataParcel.openCompanionAppDescription).isEqualTo(
+        //        OPEN_COMPANION_APP_DESCRIPTION);
+        // assertThat(metadataParcel.triggerDistance).isWithin(DELTA).of(TRIGGER_DISTANCE);
+        // assertThat(metadataParcel.unableToConnectDescription).isEqualTo(
+        //        UNABLE_TO_CONNECT_DESCRIPTION);
+        // assertThat(metadataParcel.unableToConnectTitle).isEqualTo(UNABLE_TO_CONNECT_TITLE);
+        // assertThat(metadataParcel.updateCompanionAppDescription).isEqualTo(
+        //        UPDATE_COMPANION_APP_DESCRIPTION);
+
+        // assertThat(metadataParcel.bleTxPower).isEqualTo(BLE_TX_POWER);
+        // assertThat(metadataParcel.image).isEqualTo(IMAGE);
+        // assertThat(metadataParcel.imageUrl).isEqualTo(IMAGE_URL);
+        // assertThat(metadataParcel.intentUri).isEqualTo(INTENT_URI);
+    }
+
+    private static void ensureHappyPathAsExpected(FastPairDiscoveryItemParcel itemParcel) {
+        assertThat(itemParcel.actionUrl).isEqualTo(ACTION_URL);
+        assertThat(itemParcel.actionUrlType).isEqualTo(ACTION_URL_TYPE);
+        assertThat(itemParcel.appName).isEqualTo(APP_NAME);
+        assertThat(itemParcel.attachmentType).isEqualTo(ATTACHMENT_TYPE);
+        assertThat(itemParcel.authenticationPublicKeySecp256r1)
+                .isEqualTo(AUTHENTICATION_PUBLIC_KEY_SEC_P256R1);
+        assertThat(itemParcel.bleRecordBytes).isEqualTo(BLE_RECORD_BYTES);
+        assertThat(itemParcel.debugCategory).isEqualTo(DEBUG_CATEGORY);
+        assertThat(itemParcel.debugMessage).isEqualTo(DEBUG_MESSAGE);
+        assertThat(itemParcel.description).isEqualTo(DESCRIPTION);
+        assertThat(itemParcel.deviceName).isEqualTo(DEVICE_NAME);
+        assertThat(itemParcel.displayUrl).isEqualTo(DISPLAY_URL);
+        assertThat(itemParcel.entityId).isEqualTo(ENTITY_ID);
+        assertThat(itemParcel.featureGraphicUrl).isEqualTo(FEATURE_GRAPHIC_URL);
+        assertThat(itemParcel.firstObservationTimestampMillis)
+                .isEqualTo(FIRST_OBSERVATION_TIMESTAMP_MILLIS);
+        assertThat(itemParcel.groupId).isEqualTo(GROUP_ID);
+        assertThat(itemParcel.iconFifeUrl).isEqualTo(ICON_FIFE_URL);
+        assertThat(itemParcel.iconPng).isEqualTo(ICON_PNG);
+        assertThat(itemParcel.id).isEqualTo(ID);
+        assertThat(itemParcel.lastObservationTimestampMillis)
+                .isEqualTo(LAST_OBSERVATION_TIMESTAMP_MILLIS);
+        assertThat(itemParcel.lastUserExperience).isEqualTo(LAST_USER_EXPERIENCE);
+        assertThat(itemParcel.lostMillis).isEqualTo(LOST_MILLIS);
+        assertThat(itemParcel.macAddress).isEqualTo(MAC_ADDRESS);
+        assertThat(itemParcel.packageName).isEqualTo(PACKAGE_NAME);
+        assertThat(itemParcel.pendingAppInstallTimestampMillis)
+                .isEqualTo(PENDING_APP_INSTALL_TIMESTAMP_MILLIS);
+        assertThat(itemParcel.rssi).isEqualTo(RSSI);
+        assertThat(itemParcel.state).isEqualTo(STATE);
+        assertThat(itemParcel.title).isEqualTo(TITLE);
+        assertThat(itemParcel.triggerId).isEqualTo(TRIGGER_ID);
+        assertThat(itemParcel.txPower).isEqualTo(TX_POWER);
+        assertThat(itemParcel.type).isEqualTo(TYPE);
+    }
+
+    private static FastPairEligibleAccountParcel genHappyPathFastPairEligibleAccountParcel() {
+        FastPairEligibleAccountParcel parcel = new FastPairEligibleAccountParcel();
+        parcel.account = ELIGIBLE_ACCOUNT_1;
+        parcel.optIn = true;
+
+        return parcel;
+    }
+
+    private static FastPairEligibleAccountParcel genEmptyFastPairEligibleAccountParcel() {
+        return new FastPairEligibleAccountParcel();
+    }
+
+    private static FastPairDeviceMetadataParcel genEmptyFastPairDeviceMetadataParcel() {
+        return new FastPairDeviceMetadataParcel();
+    }
+
+    private static FastPairDiscoveryItemParcel genEmptyFastPairDiscoveryItemParcel() {
+        return new FastPairDiscoveryItemParcel();
+    }
+
+    private static FastPairAccountKeyDeviceMetadataParcel
+            genEmptyFastPairAccountkeyDeviceMetadataParcel() {
+        return new FastPairAccountKeyDeviceMetadataParcel();
+    }
+
+    private static FastPairAccountKeyDeviceMetadataParcel
+            genFastPairAccountkeyDeviceMetadataParcelWithEmptyMetadataDiscoveryItem() {
+        FastPairAccountKeyDeviceMetadataParcel parcel =
+                new FastPairAccountKeyDeviceMetadataParcel();
+        parcel.metadata = genEmptyFastPairDeviceMetadataParcel();
+        parcel.discoveryItem = genEmptyFastPairDiscoveryItemParcel();
+
+        return parcel;
+    }
+
+    private static FastPairAccountKeyDeviceMetadataParcel
+            genHappyPathFastPairAccountkeyDeviceMetadataParcel() {
+        FastPairAccountKeyDeviceMetadataParcel parcel =
+                new FastPairAccountKeyDeviceMetadataParcel();
+        parcel.deviceAccountKey = ACCOUNT_KEY;
+        parcel.metadata = genHappyPathFastPairDeviceMetadataParcel();
+        parcel.sha256DeviceAccountKeyPublicAddress = SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS;
+        parcel.discoveryItem = genHappyPathFastPairDiscoveryItemParcel();
+
+        return parcel;
+    }
+
+    private static FastPairDeviceMetadataParcel genHappyPathFastPairDeviceMetadataParcel() {
+        FastPairDeviceMetadataParcel parcel = new FastPairDeviceMetadataParcel();
+
+        parcel.assistantSetupHalfSheet = ASSISTANT_SETUP_HALFSHEET;
+        parcel.assistantSetupNotification = ASSISTANT_SETUP_NOTIFICATION;
+        parcel.bleTxPower = BLE_TX_POWER;
+        parcel.confirmPinDescription = CONFIRM_PIN_DESCRIPTION;
+        parcel.confirmPinTitle = CONFIRM_PIN_TITLE;
+        parcel.connectSuccessCompanionAppInstalled = CONNECT_SUCCESS_COMPANION_APP_INSTALLED;
+        parcel.connectSuccessCompanionAppNotInstalled =
+                CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED;
+        parcel.deviceType = DEVICE_TYPE;
+        parcel.downloadCompanionAppDescription = DOWNLOAD_COMPANION_APP_DESCRIPTION;
+        parcel.failConnectGoToSettingsDescription = FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION;
+        parcel.fastPairTvConnectDeviceNoAccountDescription =
+                FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION;
+        parcel.image = IMAGE;
+        parcel.imageUrl = IMAGE_URL;
+        parcel.initialNotificationDescription = INITIAL_NOTIFICATION_DESCRIPTION;
+        parcel.initialNotificationDescriptionNoAccount =
+                INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT;
+        parcel.initialPairingDescription = INITIAL_PAIRING_DESCRIPTION;
+        parcel.intentUri = INTENT_URI;
+        parcel.locale = LOCALE;
+        parcel.name = NAME;
+        parcel.openCompanionAppDescription = OPEN_COMPANION_APP_DESCRIPTION;
+        parcel.retroactivePairingDescription = RETRO_ACTIVE_PAIRING_DESCRIPTION;
+        parcel.subsequentPairingDescription = SUBSEQUENT_PAIRING_DESCRIPTION;
+        parcel.syncContactsDescription = SYNC_CONTACT_DESCRPTION;
+        parcel.syncContactsTitle = SYNC_CONTACTS_TITLE;
+        parcel.syncSmsDescription = SYNC_SMS_DESCRIPTION;
+        parcel.syncSmsTitle = SYNC_SMS_TITLE;
+        parcel.triggerDistance = TRIGGER_DISTANCE;
+        parcel.trueWirelessImageUrlCase = TRUE_WIRELESS_IMAGE_URL_CASE;
+        parcel.trueWirelessImageUrlLeftBud = TRUE_WIRELESS_IMAGE_URL_LEFT_BUD;
+        parcel.trueWirelessImageUrlRightBud = TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD;
+        parcel.unableToConnectDescription = UNABLE_TO_CONNECT_DESCRIPTION;
+        parcel.unableToConnectTitle = UNABLE_TO_CONNECT_TITLE;
+        parcel.updateCompanionAppDescription = UPDATE_COMPANION_APP_DESCRIPTION;
+        parcel.waitLaunchCompanionAppDescription = WAIT_LAUNCH_COMPANION_APP_DESCRIPTION;
+
+        return parcel;
+    }
+
+    private static Cache.StoredDiscoveryItem genHappyPathStoredDiscoveryItem() {
+        Cache.StoredDiscoveryItem.Builder storedDiscoveryItemBuilder =
+                Cache.StoredDiscoveryItem.newBuilder();
+        storedDiscoveryItemBuilder.setActionUrl(ACTION_URL);
+        storedDiscoveryItemBuilder.setActionUrlType(Cache.ResolvedUrlType.WEBPAGE);
+        storedDiscoveryItemBuilder.setAppName(APP_NAME);
+        storedDiscoveryItemBuilder.setAttachmentType(
+                Cache.DiscoveryAttachmentType.DISCOVERY_ATTACHMENT_TYPE_NORMAL);
+        storedDiscoveryItemBuilder.setAuthenticationPublicKeySecp256R1(
+                ByteString.copyFrom(AUTHENTICATION_PUBLIC_KEY_SEC_P256R1));
+        storedDiscoveryItemBuilder.setBleRecordBytes(ByteString.copyFrom(BLE_RECORD_BYTES));
+        storedDiscoveryItemBuilder.setDebugCategory(
+                Cache.StoredDiscoveryItem.DebugMessageCategory.STATUS_VALID_NOTIFICATION);
+        storedDiscoveryItemBuilder.setDebugMessage(DEBUG_MESSAGE);
+        storedDiscoveryItemBuilder.setDescription(DESCRIPTION);
+        storedDiscoveryItemBuilder.setDeviceName(DEVICE_NAME);
+        storedDiscoveryItemBuilder.setDisplayUrl(DISPLAY_URL);
+        storedDiscoveryItemBuilder.setEntityId(ENTITY_ID);
+        storedDiscoveryItemBuilder.setFeatureGraphicUrl(FEATURE_GRAPHIC_URL);
+        storedDiscoveryItemBuilder.setFirstObservationTimestampMillis(
+                FIRST_OBSERVATION_TIMESTAMP_MILLIS);
+        storedDiscoveryItemBuilder.setGroupId(GROUP_ID);
+        storedDiscoveryItemBuilder.setIconFifeUrl(ICON_FIFE_URL);
+        storedDiscoveryItemBuilder.setIconPng(ByteString.copyFrom(ICON_PNG));
+        storedDiscoveryItemBuilder.setId(ID);
+        storedDiscoveryItemBuilder.setLastObservationTimestampMillis(
+                LAST_OBSERVATION_TIMESTAMP_MILLIS);
+        storedDiscoveryItemBuilder.setLastUserExperience(
+                Cache.StoredDiscoveryItem.ExperienceType.EXPERIENCE_GOOD);
+        storedDiscoveryItemBuilder.setLostMillis(LOST_MILLIS);
+        storedDiscoveryItemBuilder.setMacAddress(MAC_ADDRESS);
+        storedDiscoveryItemBuilder.setPackageName(PACKAGE_NAME);
+        storedDiscoveryItemBuilder.setPendingAppInstallTimestampMillis(
+                PENDING_APP_INSTALL_TIMESTAMP_MILLIS);
+        storedDiscoveryItemBuilder.setRssi(RSSI);
+        storedDiscoveryItemBuilder.setState(Cache.StoredDiscoveryItem.State.STATE_ENABLED);
+        storedDiscoveryItemBuilder.setTitle(TITLE);
+        storedDiscoveryItemBuilder.setTriggerId(TRIGGER_ID);
+        storedDiscoveryItemBuilder.setTxPower(TX_POWER);
+        storedDiscoveryItemBuilder.setType(Cache.NearbyType.NEARBY_PROXIMITY_BEACON);
+
+        FastPairStrings.Builder stringsBuilder = FastPairStrings.newBuilder();
+        stringsBuilder.setAssistantHalfSheetDescription(ASSISTANT_SETUP_HALFSHEET);
+        stringsBuilder.setAssistantNotificationDescription(ASSISTANT_SETUP_NOTIFICATION);
+        stringsBuilder.setConfirmPinDescription(CONFIRM_PIN_DESCRIPTION);
+        stringsBuilder.setConfirmPinTitle(CONFIRM_PIN_TITLE);
+        stringsBuilder.setPairingFinishedCompanionAppInstalled(
+                CONNECT_SUCCESS_COMPANION_APP_INSTALLED);
+        stringsBuilder.setPairingFinishedCompanionAppNotInstalled(
+                CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED);
+        stringsBuilder.setPairingFailDescription(
+                FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION);
+        stringsBuilder.setFastPairTvConnectDeviceNoAccountDescription(
+                FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION);
+        stringsBuilder.setTapToPairWithAccount(
+                INITIAL_NOTIFICATION_DESCRIPTION);
+        stringsBuilder.setTapToPairWithoutAccount(
+                INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT);
+        stringsBuilder.setInitialPairingDescription(INITIAL_PAIRING_DESCRIPTION);
+        stringsBuilder.setRetroactivePairingDescription(RETRO_ACTIVE_PAIRING_DESCRIPTION);
+        stringsBuilder.setSubsequentPairingDescription(SUBSEQUENT_PAIRING_DESCRIPTION);
+        stringsBuilder.setSyncContactsDescription(SYNC_CONTACT_DESCRPTION);
+        stringsBuilder.setSyncContactsTitle(SYNC_CONTACTS_TITLE);
+        stringsBuilder.setSyncSmsDescription(SYNC_SMS_DESCRIPTION);
+        stringsBuilder.setSyncSmsTitle(SYNC_SMS_TITLE);
+        stringsBuilder.setWaitAppLaunchDescription(WAIT_LAUNCH_COMPANION_APP_DESCRIPTION);
+        storedDiscoveryItemBuilder.setFastPairStrings(stringsBuilder.build());
+
+        Cache.FastPairInformation.Builder fpInformationBuilder =
+                Cache.FastPairInformation.newBuilder();
+        Rpcs.TrueWirelessHeadsetImages.Builder imagesBuilder =
+                Rpcs.TrueWirelessHeadsetImages.newBuilder();
+        imagesBuilder.setCaseUrl(TRUE_WIRELESS_IMAGE_URL_CASE);
+        imagesBuilder.setLeftBudUrl(TRUE_WIRELESS_IMAGE_URL_LEFT_BUD);
+        imagesBuilder.setRightBudUrl(TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD);
+        fpInformationBuilder.setTrueWirelessImages(imagesBuilder.build());
+        fpInformationBuilder.setDeviceType(Rpcs.DeviceType.HEADPHONES);
+
+        storedDiscoveryItemBuilder.setFastPairInformation(fpInformationBuilder.build());
+        storedDiscoveryItemBuilder.setTxPower(TX_POWER);
+
+        storedDiscoveryItemBuilder.setIconPng(ByteString.copyFrom(ICON_PNG));
+        storedDiscoveryItemBuilder.setIconFifeUrl(ICON_FIFE_URL);
+        storedDiscoveryItemBuilder.setActionUrl(ACTION_URL);
+
+        return storedDiscoveryItemBuilder.build();
+    }
+
+    private static Data.FastPairDeviceWithAccountKey genHappyPathFastPairDeviceWithAccountKey() {
+        Data.FastPairDeviceWithAccountKey.Builder fpDeviceBuilder =
+                Data.FastPairDeviceWithAccountKey.newBuilder();
+        fpDeviceBuilder.setAccountKey(ByteString.copyFrom(ACCOUNT_KEY));
+        fpDeviceBuilder.setSha256AccountKeyPublicAddress(
+                ByteString.copyFrom(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS));
+        fpDeviceBuilder.setDiscoveryItem(genHappyPathStoredDiscoveryItem());
+
+        return fpDeviceBuilder.build();
+    }
+
+    private static FastPairDiscoveryItemParcel genHappyPathFastPairDiscoveryItemParcel() {
+        FastPairDiscoveryItemParcel parcel = new FastPairDiscoveryItemParcel();
+        parcel.actionUrl = ACTION_URL;
+        parcel.actionUrlType = ACTION_URL_TYPE;
+        parcel.appName = APP_NAME;
+        parcel.attachmentType = ATTACHMENT_TYPE;
+        parcel.authenticationPublicKeySecp256r1 = AUTHENTICATION_PUBLIC_KEY_SEC_P256R1;
+        parcel.bleRecordBytes = BLE_RECORD_BYTES;
+        parcel.debugCategory = DEBUG_CATEGORY;
+        parcel.debugMessage = DEBUG_MESSAGE;
+        parcel.description = DESCRIPTION;
+        parcel.deviceName = DEVICE_NAME;
+        parcel.displayUrl = DISPLAY_URL;
+        parcel.entityId = ENTITY_ID;
+        parcel.featureGraphicUrl = FEATURE_GRAPHIC_URL;
+        parcel.firstObservationTimestampMillis = FIRST_OBSERVATION_TIMESTAMP_MILLIS;
+        parcel.groupId = GROUP_ID;
+        parcel.iconFifeUrl = ICON_FIFE_URL;
+        parcel.iconPng = ICON_PNG;
+        parcel.id = ID;
+        parcel.lastObservationTimestampMillis = LAST_OBSERVATION_TIMESTAMP_MILLIS;
+        parcel.lastUserExperience = LAST_USER_EXPERIENCE;
+        parcel.lostMillis = LOST_MILLIS;
+        parcel.macAddress = MAC_ADDRESS;
+        parcel.packageName = PACKAGE_NAME;
+        parcel.pendingAppInstallTimestampMillis = PENDING_APP_INSTALL_TIMESTAMP_MILLIS;
+        parcel.rssi = RSSI;
+        parcel.state = STATE;
+        parcel.title = TITLE;
+        parcel.triggerId = TRIGGER_ID;
+        parcel.txPower = TX_POWER;
+        parcel.type = TYPE;
+
+        return parcel;
+    }
+
+    private static Rpcs.GetObservedDeviceResponse genHappyPathObservedDeviceResponse() {
+        Rpcs.Device.Builder deviceBuilder = Rpcs.Device.newBuilder();
+        deviceBuilder.setAntiSpoofingKeyPair(Rpcs.AntiSpoofingKeyPair.newBuilder()
+                .setPublicKey(ByteString.copyFrom(ANTI_SPOOFING_KEY))
+                .build());
+        Rpcs.TrueWirelessHeadsetImages.Builder imagesBuilder =
+                Rpcs.TrueWirelessHeadsetImages.newBuilder();
+        imagesBuilder.setLeftBudUrl(TRUE_WIRELESS_IMAGE_URL_LEFT_BUD);
+        imagesBuilder.setRightBudUrl(TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD);
+        imagesBuilder.setCaseUrl(TRUE_WIRELESS_IMAGE_URL_CASE);
+        deviceBuilder.setTrueWirelessImages(imagesBuilder.build());
+        deviceBuilder.setImageUrl(IMAGE_URL);
+        deviceBuilder.setIntentUri(INTENT_URI);
+        deviceBuilder.setName(NAME);
+        deviceBuilder.setBleTxPower(BLE_TX_POWER);
+        deviceBuilder.setTriggerDistance(TRIGGER_DISTANCE);
+        deviceBuilder.setDeviceType(Rpcs.DeviceType.HEADPHONES);
+
+        return Rpcs.GetObservedDeviceResponse.newBuilder()
+                .setDevice(deviceBuilder.build())
+                .setImage(ByteString.copyFrom(IMAGE))
+                .setStrings(Rpcs.ObservedDeviceStrings.newBuilder()
+                        .setAssistantSetupHalfSheet(ASSISTANT_SETUP_HALFSHEET)
+                        .setAssistantSetupNotification(ASSISTANT_SETUP_NOTIFICATION)
+                        .setConfirmPinDescription(CONFIRM_PIN_DESCRIPTION)
+                        .setConfirmPinTitle(CONFIRM_PIN_TITLE)
+                        .setConnectSuccessCompanionAppInstalled(
+                                CONNECT_SUCCESS_COMPANION_APP_INSTALLED)
+                        .setConnectSuccessCompanionAppNotInstalled(
+                                CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED)
+                        .setDownloadCompanionAppDescription(
+                                DOWNLOAD_COMPANION_APP_DESCRIPTION)
+                        .setFailConnectGoToSettingsDescription(
+                                FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION)
+                        .setFastPairTvConnectDeviceNoAccountDescription(
+                                FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION)
+                        .setInitialNotificationDescription(
+                                INITIAL_NOTIFICATION_DESCRIPTION)
+                        .setInitialNotificationDescriptionNoAccount(
+                                INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT)
+                        .setInitialPairingDescription(
+                                INITIAL_PAIRING_DESCRIPTION)
+                        .setLocale(LOCALE)
+                        .setOpenCompanionAppDescription(
+                                OPEN_COMPANION_APP_DESCRIPTION)
+                        .setRetroactivePairingDescription(
+                                RETRO_ACTIVE_PAIRING_DESCRIPTION)
+                        .setSubsequentPairingDescription(
+                                SUBSEQUENT_PAIRING_DESCRIPTION)
+                        .setSyncContactsDescription(
+                                SYNC_CONTACT_DESCRPTION)
+                        .setSyncContactsTitle(
+                                SYNC_CONTACTS_TITLE)
+                        .setSyncSmsDescription(
+                                SYNC_SMS_DESCRIPTION)
+                        .setSyncSmsTitle(
+                                SYNC_SMS_TITLE)
+                        .setUnableToConnectDescription(
+                                UNABLE_TO_CONNECT_DESCRIPTION)
+                        .setUnableToConnectTitle(
+                                UNABLE_TO_CONNECT_TITLE)
+                        .setUpdateCompanionAppDescription(
+                                UPDATE_COMPANION_APP_DESCRIPTION)
+                        .setWaitLaunchCompanionAppDescription(
+                                WAIT_LAUNCH_COMPANION_APP_DESCRIPTION)
+                        .build())
+                .build();
+    }
+
+    private static FastPairAntispoofKeyDeviceMetadataParcel
+            genHappyPathFastPairAntispoofKeyDeviceMetadataParcel() {
+        FastPairAntispoofKeyDeviceMetadataParcel parcel =
+                new FastPairAntispoofKeyDeviceMetadataParcel();
+        parcel.antispoofPublicKey = ANTI_SPOOFING_KEY;
+        parcel.deviceMetadata = genHappyPathFastPairDeviceMetadataParcel();
+
+        return parcel;
+    }
+
+    private static FastPairAntispoofKeyDeviceMetadataParcel
+            genFastPairAntispoofKeyDeviceMetadataParcelWithEmptyDeviceMetadata() {
+        FastPairAntispoofKeyDeviceMetadataParcel parcel =
+                new FastPairAntispoofKeyDeviceMetadataParcel();
+        parcel.antispoofPublicKey = ANTI_SPOOFING_KEY;
+        parcel.deviceMetadata = genEmptyFastPairDeviceMetadataParcel();
+
+        return parcel;
+    }
+
+    private static FastPairAntispoofKeyDeviceMetadataParcel
+            genEmptyFastPairAntispoofKeyDeviceMetadataParcel() {
+        return new FastPairAntispoofKeyDeviceMetadataParcel();
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/util/DataUtilsTest.java b/nearby/tests/unit/src/com/android/server/nearby/util/DataUtilsTest.java
new file mode 100644
index 0000000..9152c07
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/util/DataUtilsTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ */
+
+package com.android.server.nearby.util;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.protobuf.ByteString;
+
+import org.junit.Test;
+
+import service.proto.Cache;
+import service.proto.FastPairString.FastPairStrings;
+import service.proto.Rpcs;
+import service.proto.Rpcs.GetObservedDeviceResponse;
+
+public final class DataUtilsTest {
+    private static final String BLUETOOTH_ADDRESS = "00:11:22:33:FF:EE";
+    private static final String APP_PACKAGE = "test_package";
+    private static final String APP_ACTION_URL =
+            "intent:#Intent;action=cto_be_set%3AACTION_MAGIC_PAIR;"
+                    + "package=to_be_set;"
+                    + "component=to_be_set;"
+                    + "to_be_set%3AEXTRA_COMPANION_APP="
+                    + APP_PACKAGE
+                    + ";end";
+    private static final long DEVICE_ID = 12;
+    private static final String DEVICE_NAME = "My device";
+    private static final byte[] DEVICE_PUBLIC_KEY = base16().decode("0123456789ABCDEF");
+    private static final String DEVICE_COMPANY = "Company name";
+    private static final byte[] DEVICE_IMAGE = new byte[] {0x00, 0x01, 0x10, 0x11};
+    private static final String DEVICE_IMAGE_URL = "device_image_url";
+    private static final String AUTHORITY = "com.android.test";
+    private static final String SIGNATURE_HASH = "as8dfbyu2duas7ikanvklpaclo2";
+    private static final String ACCOUNT = "test@gmail.com";
+
+    private static final String MESSAGE_INIT_NOTIFY_DESCRIPTION = "message 1";
+    private static final String MESSAGE_INIT_NOTIFY_DESCRIPTION_NO_ACCOUNT = "message 2";
+    private static final String MESSAGE_INIT_PAIR_DESCRIPTION = "message 3 %s";
+    private static final String MESSAGE_COMPANION_INSTALLED = "message 4";
+    private static final String MESSAGE_COMPANION_NOT_INSTALLED = "message 5";
+    private static final String MESSAGE_SUBSEQUENT_PAIR_DESCRIPTION = "message 6";
+    private static final String MESSAGE_RETROACTIVE_PAIR_DESCRIPTION = "message 7";
+    private static final String MESSAGE_WAIT_LAUNCH_COMPANION_APP_DESCRIPTION = "message 8";
+    private static final String MESSAGE_FAIL_CONNECT_DESCRIPTION = "message 9";
+    private static final String MESSAGE_FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION =
+            "message 10";
+    private static final String MESSAGE_ASSISTANT_HALF_SHEET_DESCRIPTION = "message 11";
+    private static final String MESSAGE_ASSISTANT_NOTIFICATION_DESCRIPTION = "message 12";
+
+    @Test
+    public void test_toScanFastPairStoreItem_withAccount() {
+        Cache.ScanFastPairStoreItem item = DataUtils.toScanFastPairStoreItem(
+                createObservedDeviceResponse(), BLUETOOTH_ADDRESS, ACCOUNT);
+        assertThat(item.getAddress()).isEqualTo(BLUETOOTH_ADDRESS);
+        assertThat(item.getActionUrl()).isEqualTo(APP_ACTION_URL);
+        assertThat(item.getDeviceName()).isEqualTo(DEVICE_NAME);
+        assertThat(item.getIconPng()).isEqualTo(ByteString.copyFrom(DEVICE_IMAGE));
+        assertThat(item.getIconFifeUrl()).isEqualTo(DEVICE_IMAGE_URL);
+        assertThat(item.getAntiSpoofingPublicKey())
+                .isEqualTo(ByteString.copyFrom(DEVICE_PUBLIC_KEY));
+
+        FastPairStrings strings = item.getFastPairStrings();
+        assertThat(strings.getTapToPairWithAccount()).isEqualTo(MESSAGE_INIT_NOTIFY_DESCRIPTION);
+        assertThat(strings.getTapToPairWithoutAccount())
+                .isEqualTo(MESSAGE_INIT_NOTIFY_DESCRIPTION_NO_ACCOUNT);
+        assertThat(strings.getInitialPairingDescription())
+                .isEqualTo(String.format(MESSAGE_INIT_PAIR_DESCRIPTION, DEVICE_NAME));
+        assertThat(strings.getPairingFinishedCompanionAppInstalled())
+                .isEqualTo(MESSAGE_COMPANION_INSTALLED);
+        assertThat(strings.getPairingFinishedCompanionAppNotInstalled())
+                .isEqualTo(MESSAGE_COMPANION_NOT_INSTALLED);
+        assertThat(strings.getSubsequentPairingDescription())
+                .isEqualTo(MESSAGE_SUBSEQUENT_PAIR_DESCRIPTION);
+        assertThat(strings.getRetroactivePairingDescription())
+                .isEqualTo(MESSAGE_RETROACTIVE_PAIR_DESCRIPTION);
+        assertThat(strings.getWaitAppLaunchDescription())
+                .isEqualTo(MESSAGE_WAIT_LAUNCH_COMPANION_APP_DESCRIPTION);
+        assertThat(strings.getPairingFailDescription())
+                .isEqualTo(MESSAGE_FAIL_CONNECT_DESCRIPTION);
+        assertThat(strings.getAssistantHalfSheetDescription())
+                .isEqualTo(MESSAGE_ASSISTANT_HALF_SHEET_DESCRIPTION);
+        assertThat(strings.getAssistantNotificationDescription())
+                .isEqualTo(MESSAGE_ASSISTANT_NOTIFICATION_DESCRIPTION);
+        assertThat(strings.getFastPairTvConnectDeviceNoAccountDescription())
+                .isEqualTo(MESSAGE_FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION);
+    }
+
+    @Test
+    public void test_toScanFastPairStoreItem_withoutAccount() {
+        Cache.ScanFastPairStoreItem item = DataUtils.toScanFastPairStoreItem(
+                createObservedDeviceResponse(), BLUETOOTH_ADDRESS, /* account= */ null);
+        FastPairStrings strings = item.getFastPairStrings();
+        assertThat(strings.getInitialPairingDescription())
+                .isEqualTo(MESSAGE_INIT_NOTIFY_DESCRIPTION_NO_ACCOUNT);
+    }
+
+    @Test
+    public void test_toString() {
+        Cache.ScanFastPairStoreItem item = DataUtils.toScanFastPairStoreItem(
+                createObservedDeviceResponse(), BLUETOOTH_ADDRESS, ACCOUNT);
+        FastPairStrings strings = item.getFastPairStrings();
+
+        assertThat(DataUtils.toString(strings))
+                .isEqualTo("FastPairStrings[tapToPairWithAccount=message 1, "
+                        + "tapToPairWithoutAccount=message 2, "
+                        + "initialPairingDescription=message 3 " + DEVICE_NAME + ", "
+                        + "pairingFinishedCompanionAppInstalled=message 4, "
+                        + "pairingFinishedCompanionAppNotInstalled=message 5, "
+                        + "subsequentPairingDescription=message 6, "
+                        + "retroactivePairingDescription=message 7, "
+                        + "waitAppLaunchDescription=message 8, "
+                        + "pairingFailDescription=message 9, "
+                        + "assistantHalfSheetDescription=message 11, "
+                        + "assistantNotificationDescription=message 12, "
+                        + "fastPairTvConnectDeviceNoAccountDescription=message 10]");
+    }
+
+    private static GetObservedDeviceResponse createObservedDeviceResponse() {
+        return GetObservedDeviceResponse.newBuilder()
+                .setDevice(
+                        Rpcs.Device.newBuilder()
+                                .setId(DEVICE_ID)
+                                .setName(DEVICE_NAME)
+                                .setAntiSpoofingKeyPair(
+                                        Rpcs.AntiSpoofingKeyPair
+                                                .newBuilder()
+                                                .setPublicKey(
+                                                        ByteString.copyFrom(DEVICE_PUBLIC_KEY)))
+                                .setIntentUri(APP_ACTION_URL)
+                                .setDataOnlyConnection(true)
+                                .setAssistantSupported(false)
+                                .setCompanionDetail(
+                                        Rpcs.CompanionAppDetails.newBuilder()
+                                                .setAuthority(AUTHORITY)
+                                                .setCertificateHash(SIGNATURE_HASH)
+                                                .build())
+                                .setCompanyName(DEVICE_COMPANY)
+                                .setImageUrl(DEVICE_IMAGE_URL))
+                .setImage(ByteString.copyFrom(DEVICE_IMAGE))
+                .setStrings(
+                        Rpcs.ObservedDeviceStrings.newBuilder()
+                                .setInitialNotificationDescription(MESSAGE_INIT_NOTIFY_DESCRIPTION)
+                                .setInitialNotificationDescriptionNoAccount(
+                                        MESSAGE_INIT_NOTIFY_DESCRIPTION_NO_ACCOUNT)
+                                .setInitialPairingDescription(MESSAGE_INIT_PAIR_DESCRIPTION)
+                                .setConnectSuccessCompanionAppInstalled(MESSAGE_COMPANION_INSTALLED)
+                                .setConnectSuccessCompanionAppNotInstalled(
+                                        MESSAGE_COMPANION_NOT_INSTALLED)
+                                .setSubsequentPairingDescription(
+                                        MESSAGE_SUBSEQUENT_PAIR_DESCRIPTION)
+                                .setRetroactivePairingDescription(
+                                        MESSAGE_RETROACTIVE_PAIR_DESCRIPTION)
+                                .setWaitLaunchCompanionAppDescription(
+                                        MESSAGE_WAIT_LAUNCH_COMPANION_APP_DESCRIPTION)
+                                .setFailConnectGoToSettingsDescription(
+                                        MESSAGE_FAIL_CONNECT_DESCRIPTION)
+                                .setAssistantSetupHalfSheet(
+                                        MESSAGE_ASSISTANT_HALF_SHEET_DESCRIPTION)
+                                .setAssistantSetupNotification(
+                                        MESSAGE_ASSISTANT_NOTIFICATION_DESCRIPTION)
+                                .setFastPairTvConnectDeviceNoAccountDescription(
+                                        MESSAGE_FAST_PAIR_TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION))
+                .build();
+    }
+}
diff --git a/service-t/Android.bp b/service-t/Android.bp
index 8851554..50dd995 100644
--- a/service-t/Android.bp
+++ b/service-t/Android.bp
@@ -19,6 +19,9 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+// Include build rules from Sources.bp
+build = ["Sources.bp"]
+
 // This builds T+ services depending on framework-connectivity-t
 // hidden symbols separately from the S+ services, to ensure that S+
 // services cannot accidentally depend on T+ hidden symbols from
diff --git a/service-t/Sources.bp b/service-t/Sources.bp
new file mode 100644
index 0000000..04866fb
--- /dev/null
+++ b/service-t/Sources.bp
@@ -0,0 +1,151 @@
+//
+// 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.
+//
+
+// NetworkStats related libraries.
+
+filegroup {
+    name: "services.connectivity-netstats-sources",
+    srcs: [
+        "src/com/android/server/net/NetworkIdentity*.java",
+        "src/com/android/server/net/NetworkStats*.java",
+        "src/com/android/server/net/BpfInterfaceMapUpdater.java",
+        "src/com/android/server/net/InterfaceMapValue.java",
+        "src/com/android/server/net/CookieTagMapKey.java",
+        "src/com/android/server/net/CookieTagMapValue.java",
+        "src/com/android/server/net/StatsMapKey.java",
+        "src/com/android/server/net/StatsMapValue.java",
+        "src/com/android/server/net/UidStatsMapKey.java",
+    ],
+    path: "src",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+// For test code only.
+filegroup {
+    name: "lib_networkStatsFactory_native",
+    srcs: [
+        "jni/com_android_server_net_NetworkStatsFactory.cpp",
+    ],
+    path: "jni",
+    visibility: [
+        "//packages/modules/Connectivity:__subpackages__",
+    ],
+}
+
+filegroup {
+    name: "services.connectivity-netstats-jni-sources",
+    srcs: [
+        "jni/com_android_server_net_NetworkStatsFactory.cpp",
+        "jni/com_android_server_net_NetworkStatsService.cpp",
+    ],
+    path: "jni",
+    visibility: [
+        "//packages/modules/Connectivity:__subpackages__",
+    ],
+}
+
+// Nsd related libraries.
+
+filegroup {
+    name: "services.connectivity-nsd-sources",
+    srcs: [
+        "src/com/android/server/INativeDaemon*.java",
+        "src/com/android/server/NativeDaemon*.java",
+        "src/com/android/server/Nsd*.java",
+    ],
+    path: "src",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+// IpSec related libraries.
+
+filegroup {
+    name: "services.connectivity-ipsec-sources",
+    srcs: [
+        "src/com/android/server/IpSecService.java",
+    ],
+    path: "src",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+// Ethernet related libraries.
+
+filegroup {
+    name: "services.connectivity-ethernet-sources",
+    srcs: [
+        "src/com/android/server/net/DelayedDiskWrite.java",
+        "src/com/android/server/net/IpConfigStore.java",
+    ],
+    path: "src",
+    visibility: [
+        "//frameworks/opt/net/ethernet/tests",
+    ],
+}
+
+// Connectivity-T common libraries.
+
+// TODO: remove this empty filegroup.
+filegroup {
+    name: "services.connectivity-tiramisu-sources",
+    srcs: [],
+    path: "src",
+    visibility: ["//frameworks/base/services/core"],
+}
+
+filegroup {
+    name: "services.connectivity-tiramisu-updatable-sources",
+    srcs: [
+        ":services.connectivity-ethernet-sources",
+        ":services.connectivity-ipsec-sources",
+        ":services.connectivity-netstats-sources",
+        ":services.connectivity-nsd-sources",
+    ],
+    path: "src",
+    visibility: [
+        "//packages/modules/Connectivity:__subpackages__",
+    ],
+}
+
+cc_library_shared {
+    name: "libcom_android_net_module_util_jni",
+    min_sdk_version: "30",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-parameter",
+        "-Wthread-safety",
+    ],
+    srcs: [
+        "jni/onload.cpp",
+    ],
+    stl: "libc++_static",
+    static_libs: [
+        "libnet_utils_device_common_bpfjni",
+    ],
+    shared_libs: [
+        "liblog",
+        "libnativehelper",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+    ],
+}
diff --git a/service-t/jni/com_android_server_net_NetworkStatsFactory.cpp b/service-t/jni/com_android_server_net_NetworkStatsFactory.cpp
new file mode 100644
index 0000000..8b6526f
--- /dev/null
+++ b/service-t/jni/com_android_server_net_NetworkStatsFactory.cpp
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NetworkStats"
+
+#include <errno.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <vector>
+
+#include <jni.h>
+
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+
+#include <utils/Log.h>
+#include <utils/misc.h>
+
+#include "android-base/unique_fd.h"
+#include "bpf/BpfUtils.h"
+#include "netdbpf/BpfNetworkStats.h"
+
+using android::bpf::parseBpfNetworkStatsDetail;
+using android::bpf::stats_line;
+
+namespace android {
+
+static jclass gStringClass;
+
+static struct {
+    jfieldID size;
+    jfieldID capacity;
+    jfieldID iface;
+    jfieldID uid;
+    jfieldID set;
+    jfieldID tag;
+    jfieldID metered;
+    jfieldID roaming;
+    jfieldID defaultNetwork;
+    jfieldID rxBytes;
+    jfieldID rxPackets;
+    jfieldID txBytes;
+    jfieldID txPackets;
+    jfieldID operations;
+} gNetworkStatsClassInfo;
+
+static jobjectArray get_string_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
+{
+    if (!grow) {
+        jobjectArray array = (jobjectArray)env->GetObjectField(obj, field);
+        if (array != NULL) {
+            return array;
+        }
+    }
+    return env->NewObjectArray(size, gStringClass, NULL);
+}
+
+static jintArray get_int_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
+{
+    if (!grow) {
+        jintArray array = (jintArray)env->GetObjectField(obj, field);
+        if (array != NULL) {
+            return array;
+        }
+    }
+    return env->NewIntArray(size);
+}
+
+static jlongArray get_long_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
+{
+    if (!grow) {
+        jlongArray array = (jlongArray)env->GetObjectField(obj, field);
+        if (array != NULL) {
+            return array;
+        }
+    }
+    return env->NewLongArray(size);
+}
+
+static int legacyReadNetworkStatsDetail(std::vector<stats_line>* lines,
+                                        const std::vector<std::string>& limitIfaces,
+                                        int limitTag, int limitUid, const char* path) {
+    FILE* fp = fopen(path, "re");
+    if (fp == NULL) {
+        return -1;
+    }
+
+    int lastIdx = 1;
+    int idx;
+    char buffer[384];
+    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
+        stats_line s;
+        int64_t rawTag;
+        char* pos = buffer;
+        char* endPos;
+        // First field is the index.
+        idx = (int)strtol(pos, &endPos, 10);
+        //ALOGI("Index #%d: %s", idx, buffer);
+        if (pos == endPos) {
+            // Skip lines that don't start with in index.  In particular,
+            // this will skip the initial header line.
+            continue;
+        }
+        if (idx != lastIdx + 1) {
+            ALOGE("inconsistent idx=%d after lastIdx=%d: %s", idx, lastIdx, buffer);
+            fclose(fp);
+            return -1;
+        }
+        lastIdx = idx;
+        pos = endPos;
+        // Skip whitespace.
+        while (*pos == ' ') {
+            pos++;
+        }
+        // Next field is iface.
+        int ifaceIdx = 0;
+        while (*pos != ' ' && *pos != 0 && ifaceIdx < (int)(sizeof(s.iface)-1)) {
+            s.iface[ifaceIdx] = *pos;
+            ifaceIdx++;
+            pos++;
+        }
+        if (*pos != ' ') {
+            ALOGE("bad iface: %s", buffer);
+            fclose(fp);
+            return -1;
+        }
+        s.iface[ifaceIdx] = 0;
+        if (limitIfaces.size() > 0) {
+            // Is this an iface the caller is interested in?
+            int i = 0;
+            while (i < (int)limitIfaces.size()) {
+                if (limitIfaces[i] == s.iface) {
+                    break;
+                }
+                i++;
+            }
+            if (i >= (int)limitIfaces.size()) {
+                // Nothing matched; skip this line.
+                //ALOGI("skipping due to iface: %s", buffer);
+                continue;
+            }
+        }
+
+        // Ignore whitespace
+        while (*pos == ' ') pos++;
+
+        // Find end of tag field
+        endPos = pos;
+        while (*endPos != ' ') endPos++;
+
+        // Three digit field is always 0x0, otherwise parse
+        if (endPos - pos == 3) {
+            rawTag = 0;
+        } else {
+            if (sscanf(pos, "%" PRIx64, &rawTag) != 1) {
+                ALOGE("bad tag: %s", pos);
+                fclose(fp);
+                return -1;
+            }
+        }
+        s.tag = rawTag >> 32;
+        if (limitTag != -1 && s.tag != static_cast<uint32_t>(limitTag)) {
+            //ALOGI("skipping due to tag: %s", buffer);
+            continue;
+        }
+        pos = endPos;
+
+        // Ignore whitespace
+        while (*pos == ' ') pos++;
+
+        // Parse remaining fields.
+        if (sscanf(pos, "%u %u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64,
+                &s.uid, &s.set, &s.rxBytes, &s.rxPackets,
+                &s.txBytes, &s.txPackets) == 6) {
+            if (limitUid != -1 && static_cast<uint32_t>(limitUid) != s.uid) {
+                //ALOGI("skipping due to uid: %s", buffer);
+                continue;
+            }
+            lines->push_back(s);
+        } else {
+            //ALOGI("skipping due to bad remaining fields: %s", pos);
+        }
+    }
+
+    if (fclose(fp) != 0) {
+        ALOGE("Failed to close netstats file");
+        return -1;
+    }
+    return 0;
+}
+
+static int statsLinesToNetworkStats(JNIEnv* env, jclass clazz, jobject stats,
+                            std::vector<stats_line>& lines) {
+    int size = lines.size();
+
+    bool grow = size > env->GetIntField(stats, gNetworkStatsClassInfo.capacity);
+
+    ScopedLocalRef<jobjectArray> iface(env, get_string_array(env, stats,
+            gNetworkStatsClassInfo.iface, size, grow));
+    if (iface.get() == NULL) return -1;
+    ScopedIntArrayRW uid(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.uid, size, grow));
+    if (uid.get() == NULL) return -1;
+    ScopedIntArrayRW set(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.set, size, grow));
+    if (set.get() == NULL) return -1;
+    ScopedIntArrayRW tag(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.tag, size, grow));
+    if (tag.get() == NULL) return -1;
+    ScopedIntArrayRW metered(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.metered, size, grow));
+    if (metered.get() == NULL) return -1;
+    ScopedIntArrayRW roaming(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.roaming, size, grow));
+    if (roaming.get() == NULL) return -1;
+    ScopedIntArrayRW defaultNetwork(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.defaultNetwork, size, grow));
+    if (defaultNetwork.get() == NULL) return -1;
+    ScopedLongArrayRW rxBytes(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.rxBytes, size, grow));
+    if (rxBytes.get() == NULL) return -1;
+    ScopedLongArrayRW rxPackets(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.rxPackets, size, grow));
+    if (rxPackets.get() == NULL) return -1;
+    ScopedLongArrayRW txBytes(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.txBytes, size, grow));
+    if (txBytes.get() == NULL) return -1;
+    ScopedLongArrayRW txPackets(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.txPackets, size, grow));
+    if (txPackets.get() == NULL) return -1;
+    ScopedLongArrayRW operations(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.operations, size, grow));
+    if (operations.get() == NULL) return -1;
+
+    for (int i = 0; i < size; i++) {
+        ScopedLocalRef<jstring> ifaceString(env, env->NewStringUTF(lines[i].iface));
+        env->SetObjectArrayElement(iface.get(), i, ifaceString.get());
+
+        uid[i] = lines[i].uid;
+        set[i] = lines[i].set;
+        tag[i] = lines[i].tag;
+        // Metered, roaming and defaultNetwork are populated in Java-land.
+        rxBytes[i] = lines[i].rxBytes;
+        rxPackets[i] = lines[i].rxPackets;
+        txBytes[i] = lines[i].txBytes;
+        txPackets[i] = lines[i].txPackets;
+    }
+
+    env->SetIntField(stats, gNetworkStatsClassInfo.size, size);
+    if (grow) {
+        env->SetIntField(stats, gNetworkStatsClassInfo.capacity, size);
+        env->SetObjectField(stats, gNetworkStatsClassInfo.iface, iface.get());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.metered, metered.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.roaming, roaming.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.defaultNetwork,
+                defaultNetwork.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray());
+    }
+    return 0;
+}
+
+static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path,
+                                  jint limitUid, jobjectArray limitIfacesObj, jint limitTag,
+                                  jboolean useBpfStats) {
+
+    std::vector<std::string> limitIfaces;
+    if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) {
+        int num = env->GetArrayLength(limitIfacesObj);
+        for (int i = 0; i < num; i++) {
+            jstring string = (jstring)env->GetObjectArrayElement(limitIfacesObj, i);
+            ScopedUtfChars string8(env, string);
+            if (string8.c_str() != NULL) {
+                limitIfaces.push_back(std::string(string8.c_str()));
+            }
+        }
+    }
+    std::vector<stats_line> lines;
+
+
+    if (useBpfStats) {
+        if (parseBpfNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid) < 0)
+            return -1;
+    } else {
+        ScopedUtfChars path8(env, path);
+        if (path8.c_str() == NULL) {
+            ALOGE("the qtaguid legacy path is invalid: %s", path8.c_str());
+            return -1;
+        }
+        if (legacyReadNetworkStatsDetail(&lines, limitIfaces, limitTag,
+                                         limitUid, path8.c_str()) < 0)
+            return -1;
+    }
+
+    return statsLinesToNetworkStats(env, clazz, stats, lines);
+}
+
+static int readNetworkStatsDev(JNIEnv* env, jclass clazz, jobject stats) {
+    std::vector<stats_line> lines;
+
+    if (parseBpfNetworkStatsDev(&lines) < 0)
+            return -1;
+
+    return statsLinesToNetworkStats(env, clazz, stats, lines);
+}
+
+static const JNINativeMethod gMethods[] = {
+        { "nativeReadNetworkStatsDetail",
+                "(Landroid/net/NetworkStats;Ljava/lang/String;I[Ljava/lang/String;IZ)I",
+                (void*) readNetworkStatsDetail },
+        { "nativeReadNetworkStatsDev", "(Landroid/net/NetworkStats;)I",
+                (void*) readNetworkStatsDev },
+};
+
+int register_android_server_net_NetworkStatsFactory(JNIEnv* env) {
+    int err = jniRegisterNativeMethods(env, "com/android/server/net/NetworkStatsFactory", gMethods,
+            NELEM(gMethods));
+    gStringClass = env->FindClass("java/lang/String");
+    gStringClass = static_cast<jclass>(env->NewGlobalRef(gStringClass));
+
+    jclass clazz = env->FindClass("android/net/NetworkStats");
+    gNetworkStatsClassInfo.size = env->GetFieldID(clazz, "size", "I");
+    gNetworkStatsClassInfo.capacity = env->GetFieldID(clazz, "capacity", "I");
+    gNetworkStatsClassInfo.iface = env->GetFieldID(clazz, "iface", "[Ljava/lang/String;");
+    gNetworkStatsClassInfo.uid = env->GetFieldID(clazz, "uid", "[I");
+    gNetworkStatsClassInfo.set = env->GetFieldID(clazz, "set", "[I");
+    gNetworkStatsClassInfo.tag = env->GetFieldID(clazz, "tag", "[I");
+    gNetworkStatsClassInfo.metered = env->GetFieldID(clazz, "metered", "[I");
+    gNetworkStatsClassInfo.roaming = env->GetFieldID(clazz, "roaming", "[I");
+    gNetworkStatsClassInfo.defaultNetwork = env->GetFieldID(clazz, "defaultNetwork", "[I");
+    gNetworkStatsClassInfo.rxBytes = env->GetFieldID(clazz, "rxBytes", "[J");
+    gNetworkStatsClassInfo.rxPackets = env->GetFieldID(clazz, "rxPackets", "[J");
+    gNetworkStatsClassInfo.txBytes = env->GetFieldID(clazz, "txBytes", "[J");
+    gNetworkStatsClassInfo.txPackets = env->GetFieldID(clazz, "txPackets", "[J");
+    gNetworkStatsClassInfo.operations = env->GetFieldID(clazz, "operations", "[J");
+
+    return err;
+}
+
+}
diff --git a/service-t/jni/com_android_server_net_NetworkStatsService.cpp b/service-t/jni/com_android_server_net_NetworkStatsService.cpp
new file mode 100644
index 0000000..39cbaf7
--- /dev/null
+++ b/service-t/jni/com_android_server_net_NetworkStatsService.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NetworkStatsNative"
+
+#include <cutils/qtaguid.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <jni.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+#include <utils/misc.h>
+
+#include "bpf/BpfUtils.h"
+#include "netdbpf/BpfNetworkStats.h"
+
+using android::bpf::bpfGetUidStats;
+using android::bpf::bpfGetIfaceStats;
+
+namespace android {
+
+// NOTE: keep these in sync with TrafficStats.java
+static const uint64_t UNKNOWN = -1;
+
+enum StatsType {
+    RX_BYTES = 0,
+    RX_PACKETS = 1,
+    TX_BYTES = 2,
+    TX_PACKETS = 3,
+    TCP_RX_PACKETS = 4,
+    TCP_TX_PACKETS = 5
+};
+
+static uint64_t getStatsType(Stats* stats, StatsType type) {
+    switch (type) {
+        case RX_BYTES:
+            return stats->rxBytes;
+        case RX_PACKETS:
+            return stats->rxPackets;
+        case TX_BYTES:
+            return stats->txBytes;
+        case TX_PACKETS:
+            return stats->txPackets;
+        case TCP_RX_PACKETS:
+            return stats->tcpRxPackets;
+        case TCP_TX_PACKETS:
+            return stats->tcpTxPackets;
+        default:
+            return UNKNOWN;
+    }
+}
+
+static jlong getTotalStat(JNIEnv* env, jclass clazz, jint type) {
+    Stats stats = {};
+
+    if (bpfGetIfaceStats(NULL, &stats) == 0) {
+        return getStatsType(&stats, (StatsType) type);
+    } else {
+        return UNKNOWN;
+    }
+}
+
+static jlong getIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint type) {
+    ScopedUtfChars iface8(env, iface);
+    if (iface8.c_str() == NULL) {
+        return UNKNOWN;
+    }
+
+    Stats stats = {};
+
+    if (bpfGetIfaceStats(iface8.c_str(), &stats) == 0) {
+        return getStatsType(&stats, (StatsType) type);
+    } else {
+        return UNKNOWN;
+    }
+}
+
+static jlong getUidStat(JNIEnv* env, jclass clazz, jint uid, jint type) {
+    Stats stats = {};
+
+    if (bpfGetUidStats(uid, &stats) == 0) {
+        return getStatsType(&stats, (StatsType) type);
+    } else {
+        return UNKNOWN;
+    }
+}
+
+static const JNINativeMethod gMethods[] = {
+        {"nativeGetTotalStat", "(I)J", (void*)getTotalStat},
+        {"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*)getIfaceStat},
+        {"nativeGetUidStat", "(II)J", (void*)getUidStat},
+};
+
+int register_android_server_net_NetworkStatsService(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/server/net/NetworkStatsService", gMethods,
+                                    NELEM(gMethods));
+}
+
+}
diff --git a/service-t/jni/onload.cpp b/service-t/jni/onload.cpp
new file mode 100644
index 0000000..bca4697
--- /dev/null
+++ b/service-t/jni/onload.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include <log/log.h>
+
+namespace android {
+
+int register_com_android_net_module_util_BpfMap(JNIEnv* env, char const* class_name);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        ALOGE("GetEnv failed");
+        return JNI_ERR;
+    }
+
+    if (register_com_android_net_module_util_BpfMap(env,
+            "com/android/net/module/util/BpfMap") < 0) return JNI_ERR;
+
+    return JNI_VERSION_1_6;
+}
+
+};
+
diff --git a/service-t/src/com/android/server/INativeDaemonConnectorCallbacks.java b/service-t/src/com/android/server/INativeDaemonConnectorCallbacks.java
new file mode 100644
index 0000000..0cf9dcd
--- /dev/null
+++ b/service-t/src/com/android/server/INativeDaemonConnectorCallbacks.java
@@ -0,0 +1,25 @@
+
+/*
+ * Copyright (C) 2007 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.server;
+
+interface INativeDaemonConnectorCallbacks {
+
+    void onDaemonConnected();
+    boolean onCheckHoldWakeLock(int code);
+    boolean onEvent(int code, String raw, String[] cooked);
+}
diff --git a/service-t/src/com/android/server/IpSecService.java b/service-t/src/com/android/server/IpSecService.java
new file mode 100644
index 0000000..4bc40ea
--- /dev/null
+++ b/service-t/src/com/android/server/IpSecService.java
@@ -0,0 +1,1878 @@
+/*
+ * Copyright (C) 2017 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.server;
+
+import static android.Manifest.permission.DUMP;
+import static android.net.IpSecManager.INVALID_RESOURCE_ID;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNSPEC;
+import static android.system.OsConstants.EINVAL;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_DGRAM;
+
+import android.annotation.NonNull;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.IIpSecService;
+import android.net.INetd;
+import android.net.InetAddresses;
+import android.net.IpSecAlgorithm;
+import android.net.IpSecConfig;
+import android.net.IpSecManager;
+import android.net.IpSecSpiResponse;
+import android.net.IpSecTransform;
+import android.net.IpSecTransformResponse;
+import android.net.IpSecTunnelInterfaceResponse;
+import android.net.IpSecUdpEncapResponse;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.TrafficStats;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Range;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
+import com.android.net.module.util.BinderUtils;
+import com.android.net.module.util.NetdUtils;
+import com.android.net.module.util.PermissionUtils;
+
+import libcore.io.IoUtils;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A service to manage multiple clients that want to access the IpSec API. The service is
+ * responsible for maintaining a list of clients and managing the resources (and related quotas)
+ * that each of them own.
+ *
+ * <p>Synchronization in IpSecService is done on all entrypoints due to potential race conditions at
+ * the kernel/xfrm level. Further, this allows the simplifying assumption to be made that only one
+ * thread is ever running at a time.
+ *
+ * @hide
+ */
+public class IpSecService extends IIpSecService.Stub {
+    private static final String TAG = "IpSecService";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final int[] ADDRESS_FAMILIES =
+            new int[] {OsConstants.AF_INET, OsConstants.AF_INET6};
+
+    private static final int NETD_FETCH_TIMEOUT_MS = 5000; // ms
+    private static final InetAddress INADDR_ANY;
+
+    @VisibleForTesting static final int MAX_PORT_BIND_ATTEMPTS = 10;
+
+    private final INetd mNetd;
+
+    static {
+        try {
+            INADDR_ANY = InetAddress.getByAddress(new byte[] {0, 0, 0, 0});
+        } catch (UnknownHostException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static final int FREE_PORT_MIN = 1024; // ports 1-1023 are reserved
+    static final int PORT_MAX = 0xFFFF; // ports are an unsigned 16-bit integer
+
+    /* Binder context for this service */
+    private final Context mContext;
+    private final Dependencies mDeps;
+
+    /**
+     * The next non-repeating global ID for tracking resources between users, this service, and
+     * kernel data structures. Accessing this variable is not thread safe, so it is only read or
+     * modified within blocks synchronized on IpSecService.this. We want to avoid -1
+     * (INVALID_RESOURCE_ID) and 0 (we probably forgot to initialize it).
+     */
+    @GuardedBy("IpSecService.this")
+    private int mNextResourceId = 1;
+
+    /**
+     * Dependencies of IpSecService, for injection in tests.
+     */
+    @VisibleForTesting
+    public static class Dependencies {
+        /**
+         * Get a reference to INetd.
+         */
+        public INetd getNetdInstance(Context context) throws RemoteException {
+            final INetd netd = INetd.Stub.asInterface((IBinder)
+                    context.getSystemService(Context.NETD_SERVICE));
+            if (netd == null) {
+                throw new RemoteException("Failed to Get Netd Instance");
+            }
+            return netd;
+        }
+    }
+
+    final UidFdTagger mUidFdTagger;
+
+    /**
+     * Interface for user-reference and kernel-resource cleanup.
+     *
+     * <p>This interface must be implemented for a resource to be reference counted.
+     */
+    @VisibleForTesting
+    public interface IResource {
+        /**
+         * Invalidates a IResource object, ensuring it is invalid for the purposes of allocating new
+         * objects dependent on it.
+         *
+         * <p>Implementations of this method are expected to remove references to the IResource
+         * object from the IpSecService's tracking arrays. The removal from the arrays ensures that
+         * the resource is considered invalid for user access or allocation or use in other
+         * resources.
+         *
+         * <p>References to the IResource object may be held by other RefcountedResource objects,
+         * and as such, the underlying resources and quota may not be cleaned up.
+         */
+        void invalidate() throws RemoteException;
+
+        /**
+         * Releases underlying resources and related quotas.
+         *
+         * <p>Implementations of this method are expected to remove all system resources that are
+         * tracked by the IResource object. Due to other RefcountedResource objects potentially
+         * having references to the IResource object, freeUnderlyingResources may not always be
+         * called from releaseIfUnreferencedRecursively().
+         */
+        void freeUnderlyingResources() throws RemoteException;
+    }
+
+    /**
+     * RefcountedResource manages references and dependencies in an exclusively acyclic graph.
+     *
+     * <p>RefcountedResource implements both explicit and implicit resource management. Creating a
+     * RefcountedResource object creates an explicit reference that must be freed by calling
+     * userRelease(). Additionally, adding this object as a child of another RefcountedResource
+     * object will add an implicit reference.
+     *
+     * <p>Resources are cleaned up when all references, both implicit and explicit, are released
+     * (ie, when userRelease() is called and when all parents have called releaseReference() on this
+     * object.)
+     */
+    @VisibleForTesting
+    public class RefcountedResource<T extends IResource> implements IBinder.DeathRecipient {
+        private final T mResource;
+        private final List<RefcountedResource> mChildren;
+        int mRefCount = 1; // starts at 1 for user's reference.
+        IBinder mBinder;
+
+        RefcountedResource(T resource, IBinder binder, RefcountedResource... children) {
+            synchronized (IpSecService.this) {
+                this.mResource = resource;
+                this.mChildren = new ArrayList<>(children.length);
+                this.mBinder = binder;
+
+                for (RefcountedResource child : children) {
+                    mChildren.add(child);
+                    child.mRefCount++;
+                }
+
+                try {
+                    mBinder.linkToDeath(this, 0);
+                } catch (RemoteException e) {
+                    binderDied();
+                    e.rethrowFromSystemServer();
+                }
+            }
+        }
+
+        /**
+         * If the Binder object dies, this function is called to free the system resources that are
+         * being tracked by this record and to subsequently release this record for garbage
+         * collection
+         */
+        @Override
+        public void binderDied() {
+            synchronized (IpSecService.this) {
+                try {
+                    userRelease();
+                } catch (Exception e) {
+                    Log.e(TAG, "Failed to release resource: " + e);
+                }
+            }
+        }
+
+        public T getResource() {
+            return mResource;
+        }
+
+        /**
+         * Unlinks from binder and performs IpSecService resource cleanup (removes from resource
+         * arrays)
+         *
+         * <p>If this method has been previously called, the RefcountedResource's binder field will
+         * be null, and the method will return without performing the cleanup a second time.
+         *
+         * <p>Note that calling this function does not imply that kernel resources will be freed at
+         * this time, or that the related quota will be returned. Such actions will only be
+         * performed upon the reference count reaching zero.
+         */
+        @GuardedBy("IpSecService.this")
+        public void userRelease() throws RemoteException {
+            // Prevent users from putting reference counts into a bad state by calling
+            // userRelease() multiple times.
+            if (mBinder == null) {
+                return;
+            }
+
+            mBinder.unlinkToDeath(this, 0);
+            mBinder = null;
+
+            mResource.invalidate();
+
+            releaseReference();
+        }
+
+        /**
+         * Removes a reference to this resource. If the resultant reference count is zero, the
+         * underlying resources are freed, and references to all child resources are also dropped
+         * recursively (resulting in them freeing their resources and children, etcetera)
+         *
+         * <p>This method also sets the reference count to an invalid value (-1) to signify that it
+         * has been fully released. Any subsequent calls to this method will result in an
+         * IllegalStateException being thrown due to resource already having been previously
+         * released
+         */
+        @VisibleForTesting
+        @GuardedBy("IpSecService.this")
+        public void releaseReference() throws RemoteException {
+            mRefCount--;
+
+            if (mRefCount > 0) {
+                return;
+            } else if (mRefCount < 0) {
+                throw new IllegalStateException(
+                        "Invalid operation - resource has already been released.");
+            }
+
+            // Cleanup own resources
+            mResource.freeUnderlyingResources();
+
+            // Cleanup child resources as needed
+            for (RefcountedResource<? extends IResource> child : mChildren) {
+                child.releaseReference();
+            }
+
+            // Enforce that resource cleanup can only be called once
+            // By decrementing the refcount (from 0 to -1), the next call will throw an
+            // IllegalStateException - it has already been released fully.
+            mRefCount--;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                    .append("{mResource=")
+                    .append(mResource)
+                    .append(", mRefCount=")
+                    .append(mRefCount)
+                    .append(", mChildren=")
+                    .append(mChildren)
+                    .append("}")
+                    .toString();
+        }
+    }
+
+    /**
+     * Very simple counting class that looks much like a counting semaphore
+     *
+     * <p>This class is not thread-safe, and expects that that users of this class will ensure
+     * synchronization and thread safety by holding the IpSecService.this instance lock.
+     */
+    @VisibleForTesting
+    static class ResourceTracker {
+        private final int mMax;
+        int mCurrent;
+
+        ResourceTracker(int max) {
+            mMax = max;
+            mCurrent = 0;
+        }
+
+        boolean isAvailable() {
+            return (mCurrent < mMax);
+        }
+
+        void take() {
+            if (!isAvailable()) {
+                Log.wtf(TAG, "Too many resources allocated!");
+            }
+            mCurrent++;
+        }
+
+        void give() {
+            if (mCurrent <= 0) {
+                Log.wtf(TAG, "We've released this resource too many times");
+            }
+            mCurrent--;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                    .append("{mCurrent=")
+                    .append(mCurrent)
+                    .append(", mMax=")
+                    .append(mMax)
+                    .append("}")
+                    .toString();
+        }
+    }
+
+    @VisibleForTesting
+    static final class UserRecord {
+        /* Maximum number of each type of resource that a single UID may possess */
+
+        // Up to 4 active VPNs/IWLAN with potential soft handover.
+        public static final int MAX_NUM_TUNNEL_INTERFACES = 8;
+        public static final int MAX_NUM_ENCAP_SOCKETS = 16;
+
+        // SPIs and Transforms are both cheap, and are 1:1 correlated.
+        public static final int MAX_NUM_TRANSFORMS = 64;
+        public static final int MAX_NUM_SPIS = 64;
+
+        /**
+         * Store each of the OwnedResource types in an (thinly wrapped) sparse array for indexing
+         * and explicit (user) reference management.
+         *
+         * <p>These are stored in separate arrays to improve debuggability and dump output clarity.
+         *
+         * <p>Resources are removed from this array when the user releases their explicit reference
+         * by calling one of the releaseResource() methods.
+         */
+        final RefcountedResourceArray<SpiRecord> mSpiRecords =
+                new RefcountedResourceArray<>(SpiRecord.class.getSimpleName());
+        final RefcountedResourceArray<TransformRecord> mTransformRecords =
+                new RefcountedResourceArray<>(TransformRecord.class.getSimpleName());
+        final RefcountedResourceArray<EncapSocketRecord> mEncapSocketRecords =
+                new RefcountedResourceArray<>(EncapSocketRecord.class.getSimpleName());
+        final RefcountedResourceArray<TunnelInterfaceRecord> mTunnelInterfaceRecords =
+                new RefcountedResourceArray<>(TunnelInterfaceRecord.class.getSimpleName());
+
+        /**
+         * Trackers for quotas for each of the OwnedResource types.
+         *
+         * <p>These trackers are separate from the resource arrays, since they are incremented and
+         * decremented at different points in time. Specifically, quota is only returned upon final
+         * resource deallocation (after all explicit and implicit references are released). Note
+         * that it is possible that calls to releaseResource() will not return the used quota if
+         * there are other resources that depend on (are parents of) the resource being released.
+         */
+        final ResourceTracker mSpiQuotaTracker = new ResourceTracker(MAX_NUM_SPIS);
+        final ResourceTracker mTransformQuotaTracker = new ResourceTracker(MAX_NUM_TRANSFORMS);
+        final ResourceTracker mSocketQuotaTracker = new ResourceTracker(MAX_NUM_ENCAP_SOCKETS);
+        final ResourceTracker mTunnelQuotaTracker = new ResourceTracker(MAX_NUM_TUNNEL_INTERFACES);
+
+        void removeSpiRecord(int resourceId) {
+            mSpiRecords.remove(resourceId);
+        }
+
+        void removeTransformRecord(int resourceId) {
+            mTransformRecords.remove(resourceId);
+        }
+
+        void removeTunnelInterfaceRecord(int resourceId) {
+            mTunnelInterfaceRecords.remove(resourceId);
+        }
+
+        void removeEncapSocketRecord(int resourceId) {
+            mEncapSocketRecords.remove(resourceId);
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                    .append("{mSpiQuotaTracker=")
+                    .append(mSpiQuotaTracker)
+                    .append(", mTransformQuotaTracker=")
+                    .append(mTransformQuotaTracker)
+                    .append(", mSocketQuotaTracker=")
+                    .append(mSocketQuotaTracker)
+                    .append(", mTunnelQuotaTracker=")
+                    .append(mTunnelQuotaTracker)
+                    .append(", mSpiRecords=")
+                    .append(mSpiRecords)
+                    .append(", mTransformRecords=")
+                    .append(mTransformRecords)
+                    .append(", mEncapSocketRecords=")
+                    .append(mEncapSocketRecords)
+                    .append(", mTunnelInterfaceRecords=")
+                    .append(mTunnelInterfaceRecords)
+                    .append("}")
+                    .toString();
+        }
+    }
+
+    /**
+     * This class is not thread-safe, and expects that that users of this class will ensure
+     * synchronization and thread safety by holding the IpSecService.this instance lock.
+     */
+    @VisibleForTesting
+    static final class UserResourceTracker {
+        private final SparseArray<UserRecord> mUserRecords = new SparseArray<>();
+
+        /** Lazy-initialization/getter that populates or retrieves the UserRecord as needed */
+        public UserRecord getUserRecord(int uid) {
+            checkCallerUid(uid);
+
+            UserRecord r = mUserRecords.get(uid);
+            if (r == null) {
+                r = new UserRecord();
+                mUserRecords.put(uid, r);
+            }
+            return r;
+        }
+
+        /** Safety method; guards against access of other user's UserRecords */
+        private void checkCallerUid(int uid) {
+            if (uid != Binder.getCallingUid() && Process.SYSTEM_UID != Binder.getCallingUid()) {
+                throw new SecurityException("Attempted access of unowned resources");
+            }
+        }
+
+        @Override
+        public String toString() {
+            return mUserRecords.toString();
+        }
+    }
+
+    @VisibleForTesting final UserResourceTracker mUserResourceTracker = new UserResourceTracker();
+
+    /**
+     * The OwnedResourceRecord class provides a facility to cleanly and reliably track system
+     * resources. It relies on a provided resourceId that should uniquely identify the kernel
+     * resource. To use this class, the user should implement the invalidate() and
+     * freeUnderlyingResources() methods that are responsible for cleaning up IpSecService resource
+     * tracking arrays and kernel resources, respectively.
+     *
+     * <p>This class associates kernel resources with the UID that owns and controls them.
+     */
+    private abstract class OwnedResourceRecord implements IResource {
+        final int mPid;
+        final int mUid;
+        protected final int mResourceId;
+
+        OwnedResourceRecord(int resourceId) {
+            super();
+            if (resourceId == INVALID_RESOURCE_ID) {
+                throw new IllegalArgumentException("Resource ID must not be INVALID_RESOURCE_ID");
+            }
+            mResourceId = resourceId;
+            mPid = Binder.getCallingPid();
+            mUid = Binder.getCallingUid();
+
+            getResourceTracker().take();
+        }
+
+        @Override
+        public abstract void invalidate() throws RemoteException;
+
+        /** Convenience method; retrieves the user resource record for the stored UID. */
+        protected UserRecord getUserRecord() {
+            return mUserResourceTracker.getUserRecord(mUid);
+        }
+
+        @Override
+        public abstract void freeUnderlyingResources() throws RemoteException;
+
+        /** Get the resource tracker for this resource */
+        protected abstract ResourceTracker getResourceTracker();
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                    .append("{mResourceId=")
+                    .append(mResourceId)
+                    .append(", pid=")
+                    .append(mPid)
+                    .append(", uid=")
+                    .append(mUid)
+                    .append("}")
+                    .toString();
+        }
+    };
+
+    /**
+     * Thin wrapper over SparseArray to ensure resources exist, and simplify generic typing.
+     *
+     * <p>RefcountedResourceArray prevents null insertions, and throws an IllegalArgumentException
+     * if a key is not found during a retrieval process.
+     */
+    static class RefcountedResourceArray<T extends IResource> {
+        SparseArray<RefcountedResource<T>> mArray = new SparseArray<>();
+        private final String mTypeName;
+
+        RefcountedResourceArray(String typeName) {
+            this.mTypeName = typeName;
+        }
+
+        /**
+         * Accessor method to get inner resource object.
+         *
+         * @throws IllegalArgumentException if no resource with provided key is found.
+         */
+        T getResourceOrThrow(int key) {
+            return getRefcountedResourceOrThrow(key).getResource();
+        }
+
+        /**
+         * Accessor method to get reference counting wrapper.
+         *
+         * @throws IllegalArgumentException if no resource with provided key is found.
+         */
+        RefcountedResource<T> getRefcountedResourceOrThrow(int key) {
+            RefcountedResource<T> resource = mArray.get(key);
+            if (resource == null) {
+                throw new IllegalArgumentException(
+                        String.format("No such %s found for given id: %d", mTypeName, key));
+            }
+
+            return resource;
+        }
+
+        void put(int key, RefcountedResource<T> obj) {
+            Objects.requireNonNull(obj, "Null resources cannot be added");
+            mArray.put(key, obj);
+        }
+
+        void remove(int key) {
+            mArray.remove(key);
+        }
+
+        @Override
+        public String toString() {
+            return mArray.toString();
+        }
+    }
+
+    /**
+     * Tracks an SA in the kernel, and manages cleanup paths. Once a TransformRecord is
+     * created, the SpiRecord that originally tracked the SAs will reliquish the
+     * responsibility of freeing the underlying SA to this class via the mOwnedByTransform flag.
+     */
+    private final class TransformRecord extends OwnedResourceRecord {
+        private final IpSecConfig mConfig;
+        private final SpiRecord mSpi;
+        private final EncapSocketRecord mSocket;
+
+        TransformRecord(
+                int resourceId, IpSecConfig config, SpiRecord spi, EncapSocketRecord socket) {
+            super(resourceId);
+            mConfig = config;
+            mSpi = spi;
+            mSocket = socket;
+
+            spi.setOwnedByTransform();
+        }
+
+        public IpSecConfig getConfig() {
+            return mConfig;
+        }
+
+        public SpiRecord getSpiRecord() {
+            return mSpi;
+        }
+
+        public EncapSocketRecord getSocketRecord() {
+            return mSocket;
+        }
+
+        /** always guarded by IpSecService#this */
+        @Override
+        public void freeUnderlyingResources() {
+            int spi = mSpi.getSpi();
+            try {
+                mNetd.ipSecDeleteSecurityAssociation(
+                        mUid,
+                        mConfig.getSourceAddress(),
+                        mConfig.getDestinationAddress(),
+                        spi,
+                        mConfig.getMarkValue(),
+                        mConfig.getMarkMask(),
+                        mConfig.getXfrmInterfaceId());
+            } catch (RemoteException | ServiceSpecificException e) {
+                Log.e(TAG, "Failed to delete SA with ID: " + mResourceId, e);
+            }
+
+            getResourceTracker().give();
+        }
+
+        @Override
+        public void invalidate() throws RemoteException {
+            getUserRecord().removeTransformRecord(mResourceId);
+        }
+
+        @Override
+        protected ResourceTracker getResourceTracker() {
+            return getUserRecord().mTransformQuotaTracker;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder strBuilder = new StringBuilder();
+            strBuilder
+                    .append("{super=")
+                    .append(super.toString())
+                    .append(", mSocket=")
+                    .append(mSocket)
+                    .append(", mSpi.mResourceId=")
+                    .append(mSpi.mResourceId)
+                    .append(", mConfig=")
+                    .append(mConfig)
+                    .append("}");
+            return strBuilder.toString();
+        }
+    }
+
+    /**
+     * Tracks a single SA in the kernel, and manages cleanup paths. Once used in a Transform, the
+     * responsibility for cleaning up underlying resources will be passed to the TransformRecord
+     * object
+     */
+    private final class SpiRecord extends OwnedResourceRecord {
+        private final String mSourceAddress;
+        private final String mDestinationAddress;
+        private int mSpi;
+
+        private boolean mOwnedByTransform = false;
+
+        SpiRecord(int resourceId, String sourceAddress,
+                String destinationAddress, int spi) {
+            super(resourceId);
+            mSourceAddress = sourceAddress;
+            mDestinationAddress = destinationAddress;
+            mSpi = spi;
+        }
+
+        /** always guarded by IpSecService#this */
+        @Override
+        public void freeUnderlyingResources() {
+            try {
+                if (!mOwnedByTransform) {
+                    mNetd.ipSecDeleteSecurityAssociation(
+                            mUid, mSourceAddress, mDestinationAddress, mSpi, 0 /* mark */,
+                            0 /* mask */, 0 /* if_id */);
+                }
+            } catch (ServiceSpecificException | RemoteException e) {
+                Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e);
+            }
+
+            mSpi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
+
+            getResourceTracker().give();
+        }
+
+        public int getSpi() {
+            return mSpi;
+        }
+
+        public String getDestinationAddress() {
+            return mDestinationAddress;
+        }
+
+        public void setOwnedByTransform() {
+            if (mOwnedByTransform) {
+                // Programming error
+                throw new IllegalStateException("Cannot own an SPI twice!");
+            }
+
+            mOwnedByTransform = true;
+        }
+
+        public boolean getOwnedByTransform() {
+            return mOwnedByTransform;
+        }
+
+        @Override
+        public void invalidate() throws RemoteException {
+            getUserRecord().removeSpiRecord(mResourceId);
+        }
+
+        @Override
+        protected ResourceTracker getResourceTracker() {
+            return getUserRecord().mSpiQuotaTracker;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder strBuilder = new StringBuilder();
+            strBuilder
+                    .append("{super=")
+                    .append(super.toString())
+                    .append(", mSpi=")
+                    .append(mSpi)
+                    .append(", mSourceAddress=")
+                    .append(mSourceAddress)
+                    .append(", mDestinationAddress=")
+                    .append(mDestinationAddress)
+                    .append(", mOwnedByTransform=")
+                    .append(mOwnedByTransform)
+                    .append("}");
+            return strBuilder.toString();
+        }
+    }
+
+    private final SparseBooleanArray mTunnelNetIds = new SparseBooleanArray();
+    final Range<Integer> mNetIdRange = ConnectivityManager.getIpSecNetIdRange();
+    private int mNextTunnelNetId = mNetIdRange.getLower();
+
+    /**
+     * Reserves a netId within the range of netIds allocated for IPsec tunnel interfaces
+     *
+     * <p>This method should only be called from Binder threads. Do not call this from within the
+     * system server as it will crash the system on failure.
+     *
+     * @return an integer key within the netId range, if successful
+     * @throws IllegalStateException if unsuccessful (all netId are currently reserved)
+     */
+    @VisibleForTesting
+    int reserveNetId() {
+        final int range = mNetIdRange.getUpper() - mNetIdRange.getLower() + 1;
+        synchronized (mTunnelNetIds) {
+            for (int i = 0; i < range; i++) {
+                final int netId = mNextTunnelNetId;
+                if (++mNextTunnelNetId > mNetIdRange.getUpper()) {
+                    mNextTunnelNetId = mNetIdRange.getLower();
+                }
+                if (!mTunnelNetIds.get(netId)) {
+                    mTunnelNetIds.put(netId, true);
+                    return netId;
+                }
+            }
+        }
+        throw new IllegalStateException("No free netIds to allocate");
+    }
+
+    @VisibleForTesting
+    void releaseNetId(int netId) {
+        synchronized (mTunnelNetIds) {
+            mTunnelNetIds.delete(netId);
+        }
+    }
+
+    /**
+     * Tracks an tunnel interface, and manages cleanup paths.
+     *
+     * <p>This class is not thread-safe, and expects that that users of this class will ensure
+     * synchronization and thread safety by holding the IpSecService.this instance lock
+     */
+    @VisibleForTesting
+    final class TunnelInterfaceRecord extends OwnedResourceRecord {
+        private final String mInterfaceName;
+
+        // outer addresses
+        private final String mLocalAddress;
+        private final String mRemoteAddress;
+
+        private final int mIkey;
+        private final int mOkey;
+
+        private final int mIfId;
+
+        private Network mUnderlyingNetwork;
+
+        TunnelInterfaceRecord(
+                int resourceId,
+                String interfaceName,
+                Network underlyingNetwork,
+                String localAddr,
+                String remoteAddr,
+                int ikey,
+                int okey,
+                int intfId) {
+            super(resourceId);
+
+            mInterfaceName = interfaceName;
+            mUnderlyingNetwork = underlyingNetwork;
+            mLocalAddress = localAddr;
+            mRemoteAddress = remoteAddr;
+            mIkey = ikey;
+            mOkey = okey;
+            mIfId = intfId;
+        }
+
+        /** always guarded by IpSecService#this */
+        @Override
+        public void freeUnderlyingResources() {
+            // Calls to netd
+            //       Teardown VTI
+            //       Delete global policies
+            try {
+                mNetd.ipSecRemoveTunnelInterface(mInterfaceName);
+
+                for (int selAddrFamily : ADDRESS_FAMILIES) {
+                    mNetd.ipSecDeleteSecurityPolicy(
+                            mUid,
+                            selAddrFamily,
+                            IpSecManager.DIRECTION_OUT,
+                            mOkey,
+                            0xffffffff,
+                            mIfId);
+                    mNetd.ipSecDeleteSecurityPolicy(
+                            mUid,
+                            selAddrFamily,
+                            IpSecManager.DIRECTION_IN,
+                            mIkey,
+                            0xffffffff,
+                            mIfId);
+                }
+            } catch (ServiceSpecificException | RemoteException e) {
+                Log.e(
+                        TAG,
+                        "Failed to delete VTI with interface name: "
+                                + mInterfaceName
+                                + " and id: "
+                                + mResourceId, e);
+            }
+
+            getResourceTracker().give();
+            releaseNetId(mIkey);
+            releaseNetId(mOkey);
+        }
+
+        @GuardedBy("IpSecService.this")
+        public void setUnderlyingNetwork(Network underlyingNetwork) {
+            // When #applyTunnelModeTransform is called, this new underlying network will be used to
+            // update the output mark of the input transform.
+            mUnderlyingNetwork = underlyingNetwork;
+        }
+
+        @GuardedBy("IpSecService.this")
+        public Network getUnderlyingNetwork() {
+            return mUnderlyingNetwork;
+        }
+
+        public String getInterfaceName() {
+            return mInterfaceName;
+        }
+
+        /** Returns the local, outer address for the tunnelInterface */
+        public String getLocalAddress() {
+            return mLocalAddress;
+        }
+
+        /** Returns the remote, outer address for the tunnelInterface */
+        public String getRemoteAddress() {
+            return mRemoteAddress;
+        }
+
+        public int getIkey() {
+            return mIkey;
+        }
+
+        public int getOkey() {
+            return mOkey;
+        }
+
+        public int getIfId() {
+            return mIfId;
+        }
+
+        @Override
+        protected ResourceTracker getResourceTracker() {
+            return getUserRecord().mTunnelQuotaTracker;
+        }
+
+        @Override
+        public void invalidate() {
+            getUserRecord().removeTunnelInterfaceRecord(mResourceId);
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                    .append("{super=")
+                    .append(super.toString())
+                    .append(", mInterfaceName=")
+                    .append(mInterfaceName)
+                    .append(", mUnderlyingNetwork=")
+                    .append(mUnderlyingNetwork)
+                    .append(", mLocalAddress=")
+                    .append(mLocalAddress)
+                    .append(", mRemoteAddress=")
+                    .append(mRemoteAddress)
+                    .append(", mIkey=")
+                    .append(mIkey)
+                    .append(", mOkey=")
+                    .append(mOkey)
+                    .append("}")
+                    .toString();
+        }
+    }
+
+    /**
+     * Tracks a UDP encap socket, and manages cleanup paths
+     *
+     * <p>While this class does not manage non-kernel resources, race conditions around socket
+     * binding require that the service creates the encap socket, binds it and applies the socket
+     * policy before handing it to a user.
+     */
+    private final class EncapSocketRecord extends OwnedResourceRecord {
+        private FileDescriptor mSocket;
+        private final int mPort;
+
+        EncapSocketRecord(int resourceId, FileDescriptor socket, int port) {
+            super(resourceId);
+            mSocket = socket;
+            mPort = port;
+        }
+
+        /** always guarded by IpSecService#this */
+        @Override
+        public void freeUnderlyingResources() {
+            Log.d(TAG, "Closing port " + mPort);
+            IoUtils.closeQuietly(mSocket);
+            mSocket = null;
+
+            getResourceTracker().give();
+        }
+
+        public int getPort() {
+            return mPort;
+        }
+
+        public FileDescriptor getFileDescriptor() {
+            return mSocket;
+        }
+
+        @Override
+        protected ResourceTracker getResourceTracker() {
+            return getUserRecord().mSocketQuotaTracker;
+        }
+
+        @Override
+        public void invalidate() {
+            getUserRecord().removeEncapSocketRecord(mResourceId);
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                    .append("{super=")
+                    .append(super.toString())
+                    .append(", mSocket=")
+                    .append(mSocket)
+                    .append(", mPort=")
+                    .append(mPort)
+                    .append("}")
+                    .toString();
+        }
+    }
+
+    /**
+     * Constructs a new IpSecService instance
+     *
+     * @param context Binder context for this service
+     */
+    public IpSecService(Context context) {
+        this(context, new Dependencies());
+    }
+
+    @NonNull
+    private AppOpsManager getAppOpsManager() {
+        AppOpsManager appOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+        if (appOps == null) throw new RuntimeException("System Server couldn't get AppOps");
+        return appOps;
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public IpSecService(Context context, Dependencies deps) {
+        this(
+                context,
+                deps,
+                (fd, uid) -> {
+                    try {
+                        TrafficStats.setThreadStatsUid(uid);
+                        TrafficStats.tagFileDescriptor(fd);
+                    } finally {
+                        TrafficStats.clearThreadStatsUid();
+                    }
+                });
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public IpSecService(Context context, Dependencies deps, UidFdTagger uidFdTagger) {
+        mContext = context;
+        mDeps = Objects.requireNonNull(deps, "Missing dependencies.");
+        mUidFdTagger = uidFdTagger;
+        try {
+            mNetd = mDeps.getNetdInstance(mContext);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Checks that the provided InetAddress is valid for use in an IPsec SA. The address must not be
+     * a wildcard address and must be in a numeric form such as 1.2.3.4 or 2001::1.
+     */
+    private static void checkInetAddress(String inetAddress) {
+        if (TextUtils.isEmpty(inetAddress)) {
+            throw new IllegalArgumentException("Unspecified address");
+        }
+
+        InetAddress checkAddr = InetAddresses.parseNumericAddress(inetAddress);
+
+        if (checkAddr.isAnyLocalAddress()) {
+            throw new IllegalArgumentException("Inappropriate wildcard address: " + inetAddress);
+        }
+    }
+
+    /**
+     * Checks the user-provided direction field and throws an IllegalArgumentException if it is not
+     * DIRECTION_IN or DIRECTION_OUT
+     */
+    private void checkDirection(int direction) {
+        switch (direction) {
+            case IpSecManager.DIRECTION_OUT:
+            case IpSecManager.DIRECTION_IN:
+                return;
+            case IpSecManager.DIRECTION_FWD:
+                // Only NETWORK_STACK or MAINLINE_NETWORK_STACK allowed to use forward policies
+                PermissionUtils.enforceNetworkStackPermission(mContext);
+                return;
+        }
+        throw new IllegalArgumentException("Invalid Direction: " + direction);
+    }
+
+    /** Get a new SPI and maintain the reservation in the system server */
+    @Override
+    public synchronized IpSecSpiResponse allocateSecurityParameterIndex(
+            String destinationAddress, int requestedSpi, IBinder binder) throws RemoteException {
+        checkInetAddress(destinationAddress);
+        // RFC 4303 Section 2.1 - 0=local, 1-255=reserved.
+        if (requestedSpi > 0 && requestedSpi < 256) {
+            throw new IllegalArgumentException("ESP SPI must not be in the range of 0-255.");
+        }
+        Objects.requireNonNull(binder, "Null Binder passed to allocateSecurityParameterIndex");
+
+        int callingUid = Binder.getCallingUid();
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
+        final int resourceId = mNextResourceId++;
+
+        int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
+        try {
+            if (!userRecord.mSpiQuotaTracker.isAvailable()) {
+                return new IpSecSpiResponse(
+                        IpSecManager.Status.RESOURCE_UNAVAILABLE, INVALID_RESOURCE_ID, spi);
+            }
+
+            spi = mNetd.ipSecAllocateSpi(callingUid, "", destinationAddress, requestedSpi);
+            Log.d(TAG, "Allocated SPI " + spi);
+            userRecord.mSpiRecords.put(
+                    resourceId,
+                    new RefcountedResource<SpiRecord>(
+                            new SpiRecord(resourceId, "",
+                            destinationAddress, spi), binder));
+        } catch (ServiceSpecificException e) {
+            if (e.errorCode == OsConstants.ENOENT) {
+                return new IpSecSpiResponse(
+                        IpSecManager.Status.SPI_UNAVAILABLE, INVALID_RESOURCE_ID, spi);
+            }
+            throw e;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return new IpSecSpiResponse(IpSecManager.Status.OK, resourceId, spi);
+    }
+
+    /* This method should only be called from Binder threads. Do not call this from
+     * within the system server as it will crash the system on failure.
+     */
+    private void releaseResource(RefcountedResourceArray resArray, int resourceId)
+            throws RemoteException {
+        resArray.getRefcountedResourceOrThrow(resourceId).userRelease();
+    }
+
+    /** Release a previously allocated SPI that has been registered with the system server */
+    @Override
+    public synchronized void releaseSecurityParameterIndex(int resourceId) throws RemoteException {
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+        releaseResource(userRecord.mSpiRecords, resourceId);
+    }
+
+    /**
+     * This function finds and forcibly binds to a random system port, ensuring that the port cannot
+     * be unbound.
+     *
+     * <p>A socket cannot be un-bound from a port if it was bound to that port by number. To select
+     * a random open port and then bind by number, this function creates a temp socket, binds to a
+     * random port (specifying 0), gets that port number, and then uses is to bind the user's UDP
+     * Encapsulation Socket forcibly, so that it cannot be un-bound by the user with the returned
+     * FileHandle.
+     *
+     * <p>The loop in this function handles the inherent race window between un-binding to a port
+     * and re-binding, during which the system could *technically* hand that port out to someone
+     * else.
+     */
+    private int bindToRandomPort(FileDescriptor sockFd) throws IOException {
+        for (int i = MAX_PORT_BIND_ATTEMPTS; i > 0; i--) {
+            try {
+                FileDescriptor probeSocket = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+                Os.bind(probeSocket, INADDR_ANY, 0);
+                int port = ((InetSocketAddress) Os.getsockname(probeSocket)).getPort();
+                Os.close(probeSocket);
+                Log.v(TAG, "Binding to port " + port);
+                Os.bind(sockFd, INADDR_ANY, port);
+                return port;
+            } catch (ErrnoException e) {
+                // Someone miraculously claimed the port just after we closed probeSocket.
+                if (e.errno == OsConstants.EADDRINUSE) {
+                    continue;
+                }
+                throw e.rethrowAsIOException();
+            }
+        }
+        throw new IOException("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port");
+    }
+
+    /**
+     * Functional interface to do traffic tagging of given sockets to UIDs.
+     *
+     * <p>Specifically used by openUdpEncapsulationSocket to ensure data usage on the UDP encap
+     * sockets are billed to the UID that the UDP encap socket was created on behalf of.
+     *
+     * <p>Separate class so that the socket tagging logic can be mocked; TrafficStats uses static
+     * methods that cannot be easily mocked/tested.
+     */
+    @VisibleForTesting
+    public interface UidFdTagger {
+        /**
+         * Sets socket tag to assign all traffic to the provided UID.
+         *
+         * <p>Since the socket is created on behalf of an unprivileged application, all traffic
+         * should be accounted to the UID of the unprivileged application.
+         */
+        void tag(FileDescriptor fd, int uid) throws IOException;
+    }
+
+    /**
+     * Open a socket via the system server and bind it to the specified port (random if port=0).
+     * This will return a PFD to the user that represent a bound UDP socket. The system server will
+     * cache the socket and a record of its owner so that it can and must be freed when no longer
+     * needed.
+     */
+    @Override
+    public synchronized IpSecUdpEncapResponse openUdpEncapsulationSocket(int port, IBinder binder)
+            throws RemoteException {
+        if (port != 0 && (port < FREE_PORT_MIN || port > PORT_MAX)) {
+            throw new IllegalArgumentException(
+                    "Specified port number must be a valid non-reserved UDP port");
+        }
+        Objects.requireNonNull(binder, "Null Binder passed to openUdpEncapsulationSocket");
+
+        int callingUid = Binder.getCallingUid();
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
+        final int resourceId = mNextResourceId++;
+
+        ParcelFileDescriptor pFd = null;
+        try {
+            if (!userRecord.mSocketQuotaTracker.isAvailable()) {
+                return new IpSecUdpEncapResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
+            }
+
+            FileDescriptor sockFd = null;
+            try {
+                sockFd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+                pFd = ParcelFileDescriptor.dup(sockFd);
+            } finally {
+                IoUtils.closeQuietly(sockFd);
+            }
+
+            mUidFdTagger.tag(pFd.getFileDescriptor(), callingUid);
+            // This code is common to both the unspecified and specified port cases
+            Os.setsockoptInt(
+                    pFd.getFileDescriptor(),
+                    OsConstants.IPPROTO_UDP,
+                    OsConstants.UDP_ENCAP,
+                    OsConstants.UDP_ENCAP_ESPINUDP);
+
+            mNetd.ipSecSetEncapSocketOwner(pFd, callingUid);
+            if (port != 0) {
+                Log.v(TAG, "Binding to port " + port);
+                Os.bind(pFd.getFileDescriptor(), INADDR_ANY, port);
+            } else {
+                port = bindToRandomPort(pFd.getFileDescriptor());
+            }
+
+            userRecord.mEncapSocketRecords.put(
+                    resourceId,
+                    new RefcountedResource<EncapSocketRecord>(
+                            new EncapSocketRecord(resourceId, pFd.getFileDescriptor(), port),
+                            binder));
+            return new IpSecUdpEncapResponse(IpSecManager.Status.OK, resourceId, port,
+                    pFd.getFileDescriptor());
+        } catch (IOException | ErrnoException e) {
+            try {
+                if (pFd != null) {
+                    pFd.close();
+                }
+            } catch (IOException ex) {
+                // Nothing can be done at this point
+                Log.e(TAG, "Failed to close pFd.");
+            }
+        }
+        // If we make it to here, then something has gone wrong and we couldn't open a socket.
+        // The only reasonable condition that would cause that is resource unavailable.
+        return new IpSecUdpEncapResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
+    }
+
+    /** close a socket that has been been allocated by and registered with the system server */
+    @Override
+    public synchronized void closeUdpEncapsulationSocket(int resourceId) throws RemoteException {
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+        releaseResource(userRecord.mEncapSocketRecords, resourceId);
+    }
+
+    /**
+     * Create a tunnel interface for use in IPSec tunnel mode. The system server will cache the
+     * tunnel interface and a record of its owner so that it can and must be freed when no longer
+     * needed.
+     */
+    @Override
+    public synchronized IpSecTunnelInterfaceResponse createTunnelInterface(
+            String localAddr, String remoteAddr, Network underlyingNetwork, IBinder binder,
+            String callingPackage) {
+        enforceTunnelFeatureAndPermissions(callingPackage);
+        Objects.requireNonNull(binder, "Null Binder passed to createTunnelInterface");
+        Objects.requireNonNull(underlyingNetwork, "No underlying network was specified");
+        checkInetAddress(localAddr);
+        checkInetAddress(remoteAddr);
+
+        // TODO: Check that underlying network exists, and IP addresses not assigned to a different
+        //       network (b/72316676).
+
+        int callerUid = Binder.getCallingUid();
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(callerUid);
+        if (!userRecord.mTunnelQuotaTracker.isAvailable()) {
+            return new IpSecTunnelInterfaceResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
+        }
+
+        final int resourceId = mNextResourceId++;
+        final int ikey = reserveNetId();
+        final int okey = reserveNetId();
+        String intfName = String.format("%s%d", INetd.IPSEC_INTERFACE_PREFIX, resourceId);
+
+        try {
+            // Calls to netd:
+            //       Create VTI
+            //       Add inbound/outbound global policies
+            //              (use reqid = 0)
+            mNetd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
+
+            BinderUtils.withCleanCallingIdentity(() -> {
+                NetdUtils.setInterfaceUp(mNetd, intfName);
+            });
+
+            for (int selAddrFamily : ADDRESS_FAMILIES) {
+                // Always send down correct local/remote addresses for template.
+                mNetd.ipSecAddSecurityPolicy(
+                        callerUid,
+                        selAddrFamily,
+                        IpSecManager.DIRECTION_OUT,
+                        localAddr,
+                        remoteAddr,
+                        0,
+                        okey,
+                        0xffffffff,
+                        resourceId);
+                mNetd.ipSecAddSecurityPolicy(
+                        callerUid,
+                        selAddrFamily,
+                        IpSecManager.DIRECTION_IN,
+                        remoteAddr,
+                        localAddr,
+                        0,
+                        ikey,
+                        0xffffffff,
+                        resourceId);
+
+                // Add a forwarding policy on the tunnel interface. In order to support forwarding
+                // the IpSecTunnelInterface must have a forwarding policy matching the incoming SA.
+                //
+                // Unless a IpSecTransform is also applied against this interface in DIRECTION_FWD,
+                // forwarding will be blocked by default (as would be the case if this policy was
+                // absent).
+                //
+                // This is necessary only on the tunnel interface, and not any the interface to
+                // which traffic will be forwarded to.
+                mNetd.ipSecAddSecurityPolicy(
+                        callerUid,
+                        selAddrFamily,
+                        IpSecManager.DIRECTION_FWD,
+                        remoteAddr,
+                        localAddr,
+                        0,
+                        ikey,
+                        0xffffffff,
+                        resourceId);
+            }
+
+            userRecord.mTunnelInterfaceRecords.put(
+                    resourceId,
+                    new RefcountedResource<TunnelInterfaceRecord>(
+                            new TunnelInterfaceRecord(
+                                    resourceId,
+                                    intfName,
+                                    underlyingNetwork,
+                                    localAddr,
+                                    remoteAddr,
+                                    ikey,
+                                    okey,
+                                    resourceId),
+                            binder));
+            return new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName);
+        } catch (RemoteException e) {
+            // Release keys if we got an error.
+            releaseNetId(ikey);
+            releaseNetId(okey);
+            throw e.rethrowFromSystemServer();
+        } catch (Throwable t) {
+            // Release keys if we got an error.
+            releaseNetId(ikey);
+            releaseNetId(okey);
+            throw t;
+        }
+    }
+
+    /**
+     * Adds a new local address to the tunnel interface. This allows packets to be sent and received
+     * from multiple local IP addresses over the same tunnel.
+     */
+    @Override
+    public synchronized void addAddressToTunnelInterface(
+            int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
+        enforceTunnelFeatureAndPermissions(callingPackage);
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+
+        // Get tunnelInterface record; if no such interface is found, will throw
+        // IllegalArgumentException
+        TunnelInterfaceRecord tunnelInterfaceInfo =
+                userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
+
+        try {
+            // We can assume general validity of the IP address, since we get them as a
+            // LinkAddress, which does some validation.
+            mNetd.interfaceAddAddress(
+                    tunnelInterfaceInfo.mInterfaceName,
+                    localAddr.getAddress().getHostAddress(),
+                    localAddr.getPrefixLength());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Remove a new local address from the tunnel interface. After removal, the address will no
+     * longer be available to send from, or receive on.
+     */
+    @Override
+    public synchronized void removeAddressFromTunnelInterface(
+            int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
+        enforceTunnelFeatureAndPermissions(callingPackage);
+
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+        // Get tunnelInterface record; if no such interface is found, will throw
+        // IllegalArgumentException
+        TunnelInterfaceRecord tunnelInterfaceInfo =
+                userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
+
+        try {
+            // We can assume general validity of the IP address, since we get them as a
+            // LinkAddress, which does some validation.
+            mNetd.interfaceDelAddress(
+                            tunnelInterfaceInfo.mInterfaceName,
+                            localAddr.getAddress().getHostAddress(),
+                            localAddr.getPrefixLength());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Set TunnelInterface to use a specific underlying network. */
+    @Override
+    public synchronized void setNetworkForTunnelInterface(
+            int tunnelResourceId, Network underlyingNetwork, String callingPackage) {
+        enforceTunnelFeatureAndPermissions(callingPackage);
+        Objects.requireNonNull(underlyingNetwork, "No underlying network was specified");
+
+        final UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+
+        // Get tunnelInterface record; if no such interface is found, will throw
+        // IllegalArgumentException. userRecord.mTunnelInterfaceRecords is never null
+        final TunnelInterfaceRecord tunnelInterfaceInfo =
+                userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
+
+        final ConnectivityManager connectivityManager =
+                mContext.getSystemService(ConnectivityManager.class);
+        final LinkProperties lp = connectivityManager.getLinkProperties(underlyingNetwork);
+        if (tunnelInterfaceInfo.getInterfaceName().equals(lp.getInterfaceName())) {
+            throw new IllegalArgumentException(
+                    "Underlying network cannot be the network being exposed by this tunnel");
+        }
+
+        // It is meaningless to check if the network exists or is valid because the network might
+        // disconnect at any time after it passes the check.
+
+        tunnelInterfaceInfo.setUnderlyingNetwork(underlyingNetwork);
+    }
+
+    /**
+     * Delete a TunnelInterface that has been been allocated by and registered with the system
+     * server
+     */
+    @Override
+    public synchronized void deleteTunnelInterface(
+            int resourceId, String callingPackage) throws RemoteException {
+        enforceTunnelFeatureAndPermissions(callingPackage);
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+        releaseResource(userRecord.mTunnelInterfaceRecords, resourceId);
+    }
+
+    @VisibleForTesting
+    void validateAlgorithms(IpSecConfig config) throws IllegalArgumentException {
+        IpSecAlgorithm auth = config.getAuthentication();
+        IpSecAlgorithm crypt = config.getEncryption();
+        IpSecAlgorithm aead = config.getAuthenticatedEncryption();
+
+        // Validate the algorithm set
+        Preconditions.checkArgument(
+                aead != null || crypt != null || auth != null,
+                "No Encryption or Authentication algorithms specified");
+        Preconditions.checkArgument(
+                auth == null || auth.isAuthentication(),
+                "Unsupported algorithm for Authentication");
+        Preconditions.checkArgument(
+                crypt == null || crypt.isEncryption(), "Unsupported algorithm for Encryption");
+        Preconditions.checkArgument(
+                aead == null || aead.isAead(),
+                "Unsupported algorithm for Authenticated Encryption");
+        Preconditions.checkArgument(
+                aead == null || (auth == null && crypt == null),
+                "Authenticated Encryption is mutually exclusive with other Authentication "
+                        + "or Encryption algorithms");
+    }
+
+    private int getFamily(String inetAddress) {
+        int family = AF_UNSPEC;
+        InetAddress checkAddress = InetAddresses.parseNumericAddress(inetAddress);
+        if (checkAddress instanceof Inet4Address) {
+            family = AF_INET;
+        } else if (checkAddress instanceof Inet6Address) {
+            family = AF_INET6;
+        }
+        return family;
+    }
+
+    /**
+     * Checks an IpSecConfig parcel to ensure that the contents are valid and throws an
+     * IllegalArgumentException if they are not.
+     */
+    private void checkIpSecConfig(IpSecConfig config) {
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+
+        switch (config.getEncapType()) {
+            case IpSecTransform.ENCAP_NONE:
+                break;
+            case IpSecTransform.ENCAP_ESPINUDP:
+            case IpSecTransform.ENCAP_ESPINUDP_NON_IKE:
+                // Retrieve encap socket record; will throw IllegalArgumentException if not found
+                userRecord.mEncapSocketRecords.getResourceOrThrow(
+                        config.getEncapSocketResourceId());
+
+                int port = config.getEncapRemotePort();
+                if (port <= 0 || port > 0xFFFF) {
+                    throw new IllegalArgumentException("Invalid remote UDP port: " + port);
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid Encap Type: " + config.getEncapType());
+        }
+
+        validateAlgorithms(config);
+
+        // Retrieve SPI record; will throw IllegalArgumentException if not found
+        SpiRecord s = userRecord.mSpiRecords.getResourceOrThrow(config.getSpiResourceId());
+
+        // Check to ensure that SPI has not already been used.
+        if (s.getOwnedByTransform()) {
+            throw new IllegalStateException("SPI already in use; cannot be used in new Transforms");
+        }
+
+        // If no remote address is supplied, then use one from the SPI.
+        if (TextUtils.isEmpty(config.getDestinationAddress())) {
+            config.setDestinationAddress(s.getDestinationAddress());
+        }
+
+        // All remote addresses must match
+        if (!config.getDestinationAddress().equals(s.getDestinationAddress())) {
+            throw new IllegalArgumentException("Mismatched remote addresseses.");
+        }
+
+        // This check is technically redundant due to the chain of custody between the SPI and
+        // the IpSecConfig, but in the future if the dest is allowed to be set explicitly in
+        // the transform, this will prevent us from messing up.
+        checkInetAddress(config.getDestinationAddress());
+
+        // Require a valid source address for all transforms.
+        checkInetAddress(config.getSourceAddress());
+
+        // Check to ensure source and destination have the same address family.
+        String sourceAddress = config.getSourceAddress();
+        String destinationAddress = config.getDestinationAddress();
+        int sourceFamily = getFamily(sourceAddress);
+        int destinationFamily = getFamily(destinationAddress);
+        if (sourceFamily != destinationFamily) {
+            throw new IllegalArgumentException(
+                    "Source address ("
+                            + sourceAddress
+                            + ") and destination address ("
+                            + destinationAddress
+                            + ") have different address families.");
+        }
+
+        // Throw an error if UDP Encapsulation is not used in IPv4.
+        if (config.getEncapType() != IpSecTransform.ENCAP_NONE && sourceFamily != AF_INET) {
+            throw new IllegalArgumentException(
+                    "UDP Encapsulation is not supported for this address family");
+        }
+
+        switch (config.getMode()) {
+            case IpSecTransform.MODE_TRANSPORT:
+                break;
+            case IpSecTransform.MODE_TUNNEL:
+                break;
+            default:
+                throw new IllegalArgumentException(
+                        "Invalid IpSecTransform.mode: " + config.getMode());
+        }
+
+        config.setMarkValue(0);
+        config.setMarkMask(0);
+    }
+
+    private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS;
+
+    private void enforceTunnelFeatureAndPermissions(String callingPackage) {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) {
+            throw new UnsupportedOperationException(
+                    "IPsec Tunnel Mode requires PackageManager.FEATURE_IPSEC_TUNNELS");
+        }
+
+        Objects.requireNonNull(callingPackage, "Null calling package cannot create IpSec tunnels");
+
+        // OP_MANAGE_IPSEC_TUNNELS will return MODE_ERRORED by default, including for the system
+        // server. If the appop is not granted, require that the caller has the MANAGE_IPSEC_TUNNELS
+        // permission or is the System Server.
+        if (AppOpsManager.MODE_ALLOWED == getAppOpsManager().noteOpNoThrow(
+                TUNNEL_OP, Binder.getCallingUid(), callingPackage)) {
+            return;
+        }
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService");
+    }
+
+    private void createOrUpdateTransform(
+            IpSecConfig c, int resourceId, SpiRecord spiRecord, EncapSocketRecord socketRecord)
+            throws RemoteException {
+
+        int encapType = c.getEncapType(), encapLocalPort = 0, encapRemotePort = 0;
+        if (encapType != IpSecTransform.ENCAP_NONE) {
+            encapLocalPort = socketRecord.getPort();
+            encapRemotePort = c.getEncapRemotePort();
+        }
+
+        IpSecAlgorithm auth = c.getAuthentication();
+        IpSecAlgorithm crypt = c.getEncryption();
+        IpSecAlgorithm authCrypt = c.getAuthenticatedEncryption();
+
+        String cryptName;
+        if (crypt == null) {
+            cryptName = (authCrypt == null) ? IpSecAlgorithm.CRYPT_NULL : "";
+        } else {
+            cryptName = crypt.getName();
+        }
+
+        mNetd.ipSecAddSecurityAssociation(
+                Binder.getCallingUid(),
+                c.getMode(),
+                c.getSourceAddress(),
+                c.getDestinationAddress(),
+                (c.getNetwork() != null) ? c.getNetwork().getNetId() : 0,
+                spiRecord.getSpi(),
+                c.getMarkValue(),
+                c.getMarkMask(),
+                (auth != null) ? auth.getName() : "",
+                (auth != null) ? auth.getKey() : new byte[] {},
+                (auth != null) ? auth.getTruncationLengthBits() : 0,
+                cryptName,
+                (crypt != null) ? crypt.getKey() : new byte[] {},
+                (crypt != null) ? crypt.getTruncationLengthBits() : 0,
+                (authCrypt != null) ? authCrypt.getName() : "",
+                (authCrypt != null) ? authCrypt.getKey() : new byte[] {},
+                (authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0,
+                encapType,
+                encapLocalPort,
+                encapRemotePort,
+                c.getXfrmInterfaceId());
+    }
+
+    /**
+     * Create a IPsec transform, which represents a single security association in the kernel. The
+     * transform will be cached by the system server and must be freed when no longer needed. It is
+     * possible to free one, deleting the SA from underneath sockets that are using it, which will
+     * result in all of those sockets becoming unable to send or receive data.
+     */
+    @Override
+    public synchronized IpSecTransformResponse createTransform(
+            IpSecConfig c, IBinder binder, String callingPackage) throws RemoteException {
+        Objects.requireNonNull(c);
+        if (c.getMode() == IpSecTransform.MODE_TUNNEL) {
+            enforceTunnelFeatureAndPermissions(callingPackage);
+        }
+        checkIpSecConfig(c);
+        Objects.requireNonNull(binder, "Null Binder passed to createTransform");
+        final int resourceId = mNextResourceId++;
+
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+        List<RefcountedResource> dependencies = new ArrayList<>();
+
+        if (!userRecord.mTransformQuotaTracker.isAvailable()) {
+            return new IpSecTransformResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
+        }
+
+        EncapSocketRecord socketRecord = null;
+        if (c.getEncapType() != IpSecTransform.ENCAP_NONE) {
+            RefcountedResource<EncapSocketRecord> refcountedSocketRecord =
+                    userRecord.mEncapSocketRecords.getRefcountedResourceOrThrow(
+                            c.getEncapSocketResourceId());
+            dependencies.add(refcountedSocketRecord);
+            socketRecord = refcountedSocketRecord.getResource();
+        }
+
+        RefcountedResource<SpiRecord> refcountedSpiRecord =
+                userRecord.mSpiRecords.getRefcountedResourceOrThrow(c.getSpiResourceId());
+        dependencies.add(refcountedSpiRecord);
+        SpiRecord spiRecord = refcountedSpiRecord.getResource();
+
+        createOrUpdateTransform(c, resourceId, spiRecord, socketRecord);
+
+        // SA was created successfully, time to construct a record and lock it away
+        userRecord.mTransformRecords.put(
+                resourceId,
+                new RefcountedResource<TransformRecord>(
+                        new TransformRecord(resourceId, c, spiRecord, socketRecord),
+                        binder,
+                        dependencies.toArray(new RefcountedResource[dependencies.size()])));
+        return new IpSecTransformResponse(IpSecManager.Status.OK, resourceId);
+    }
+
+    /**
+     * Delete a transport mode transform that was previously allocated by + registered with the
+     * system server. If this is called on an inactive (or non-existent) transform, it will not
+     * return an error. It's safe to de-allocate transforms that may have already been deleted for
+     * other reasons.
+     */
+    @Override
+    public synchronized void deleteTransform(int resourceId) throws RemoteException {
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+        releaseResource(userRecord.mTransformRecords, resourceId);
+    }
+
+    /**
+     * Apply an active transport mode transform to a socket, which will apply the IPsec security
+     * association as a correspondent policy to the provided socket
+     */
+    @Override
+    public synchronized void applyTransportModeTransform(
+            ParcelFileDescriptor socket, int direction, int resourceId) throws RemoteException {
+        int callingUid = Binder.getCallingUid();
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
+        checkDirection(direction);
+        // Get transform record; if no transform is found, will throw IllegalArgumentException
+        TransformRecord info = userRecord.mTransformRecords.getResourceOrThrow(resourceId);
+
+        // TODO: make this a function.
+        if (info.mPid != getCallingPid() || info.mUid != callingUid) {
+            throw new SecurityException("Only the owner of an IpSec Transform may apply it!");
+        }
+
+        // Get config and check that to-be-applied transform has the correct mode
+        IpSecConfig c = info.getConfig();
+        Preconditions.checkArgument(
+                c.getMode() == IpSecTransform.MODE_TRANSPORT,
+                "Transform mode was not Transport mode; cannot be applied to a socket");
+
+        mNetd.ipSecApplyTransportModeTransform(
+                socket,
+                callingUid,
+                direction,
+                c.getSourceAddress(),
+                c.getDestinationAddress(),
+                info.getSpiRecord().getSpi());
+    }
+
+    /**
+     * Remove transport mode transforms from a socket, applying the default (empty) policy. This
+     * ensures that NO IPsec policy is applied to the socket (would be the equivalent of applying a
+     * policy that performs no IPsec). Today the resourceId parameter is passed but not used:
+     * reserved for future improved input validation.
+     */
+    @Override
+    public synchronized void removeTransportModeTransforms(ParcelFileDescriptor socket)
+            throws RemoteException {
+        mNetd.ipSecRemoveTransportModeTransform(socket);
+    }
+
+    /**
+     * Apply an active tunnel mode transform to a TunnelInterface, which will apply the IPsec
+     * security association as a correspondent policy to the provided interface
+     */
+    @Override
+    public synchronized void applyTunnelModeTransform(
+            int tunnelResourceId, int direction,
+            int transformResourceId, String callingPackage) throws RemoteException {
+        enforceTunnelFeatureAndPermissions(callingPackage);
+        checkDirection(direction);
+
+        int callingUid = Binder.getCallingUid();
+        UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
+
+        // Get transform record; if no transform is found, will throw IllegalArgumentException
+        TransformRecord transformInfo =
+                userRecord.mTransformRecords.getResourceOrThrow(transformResourceId);
+
+        // Get tunnelInterface record; if no such interface is found, will throw
+        // IllegalArgumentException
+        TunnelInterfaceRecord tunnelInterfaceInfo =
+                userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
+
+        // Get config and check that to-be-applied transform has the correct mode
+        IpSecConfig c = transformInfo.getConfig();
+        Preconditions.checkArgument(
+                c.getMode() == IpSecTransform.MODE_TUNNEL,
+                "Transform mode was not Tunnel mode; cannot be applied to a tunnel interface");
+
+        EncapSocketRecord socketRecord = null;
+        if (c.getEncapType() != IpSecTransform.ENCAP_NONE) {
+            socketRecord =
+                    userRecord.mEncapSocketRecords.getResourceOrThrow(c.getEncapSocketResourceId());
+        }
+        SpiRecord spiRecord = transformInfo.getSpiRecord();
+
+        int mark =
+                (direction == IpSecManager.DIRECTION_OUT)
+                        ? tunnelInterfaceInfo.getOkey()
+                        : tunnelInterfaceInfo.getIkey(); // Ikey also used for FWD policies
+
+        try {
+            // Default to using the invalid SPI of 0 for inbound SAs. This allows policies to skip
+            // SPI matching as part of the template resolution.
+            int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
+            c.setXfrmInterfaceId(tunnelInterfaceInfo.getIfId());
+
+            // TODO: enable this when UPDSA supports updating marks. Adding kernel support upstream
+            //     (and backporting) would allow us to narrow the mark space, and ensure that the SA
+            //     and SPs have matching marks (as VTI are meant to be built).
+            // Currently update does nothing with marks. Leave empty (defaulting to 0) to ensure the
+            //     config matches the actual allocated resources in the kernel.
+            // All SAs will have zero marks (from creation time), and any policy that matches the
+            //     same src/dst could match these SAs. Non-IpSecService governed processes that
+            //     establish floating policies with the same src/dst may result in undefined
+            //     behavior. This is generally limited to vendor code due to the permissions
+            //     (CAP_NET_ADMIN) required.
+            //
+            // c.setMarkValue(mark);
+            // c.setMarkMask(0xffffffff);
+
+            if (direction == IpSecManager.DIRECTION_OUT) {
+                // Set output mark via underlying network (output only)
+                c.setNetwork(tunnelInterfaceInfo.getUnderlyingNetwork());
+
+                // Set outbound SPI only. We want inbound to use any valid SA (old, new) on rekeys,
+                // but want to guarantee outbound packets are sent over the new SA.
+                spi = spiRecord.getSpi();
+            }
+
+            // Always update the policy with the relevant XFRM_IF_ID
+            for (int selAddrFamily : ADDRESS_FAMILIES) {
+                mNetd.ipSecUpdateSecurityPolicy(
+                        callingUid,
+                        selAddrFamily,
+                        direction,
+                        transformInfo.getConfig().getSourceAddress(),
+                        transformInfo.getConfig().getDestinationAddress(),
+                        spi, // If outbound, also add SPI to the policy.
+                        mark, // Must always set policy mark; ikey/okey for VTIs
+                        0xffffffff,
+                        c.getXfrmInterfaceId());
+            }
+
+            // Update SA with tunnel mark (ikey or okey based on direction)
+            createOrUpdateTransform(c, transformResourceId, spiRecord, socketRecord);
+        } catch (ServiceSpecificException e) {
+            if (e.errorCode == EINVAL) {
+                throw new IllegalArgumentException(e.toString());
+            } else {
+                throw e;
+            }
+        }
+    }
+
+    @Override
+    protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+
+        pw.println("IpSecService dump:");
+        pw.println();
+
+        pw.println("mUserResourceTracker:");
+        pw.println(mUserResourceTracker);
+    }
+}
diff --git a/service-t/src/com/android/server/NativeDaemonConnector.java b/service-t/src/com/android/server/NativeDaemonConnector.java
new file mode 100644
index 0000000..ec8d779
--- /dev/null
+++ b/service-t/src/com/android/server/NativeDaemonConnector.java
@@ -0,0 +1,704 @@
+/*
+ * Copyright (C) 2007 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.server;
+
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.util.LocalLog;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.Objects;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Generic connector class for interfacing with a native daemon which uses the
+ * {@code libsysutils} FrameworkListener protocol.
+ */
+final class NativeDaemonConnector implements Runnable, Handler.Callback {
+    private final static boolean VDBG = false;
+
+    private final String TAG;
+
+    private String mSocket;
+    private OutputStream mOutputStream;
+    private LocalLog mLocalLog;
+
+    private volatile boolean mDebug = false;
+    private volatile Object mWarnIfHeld;
+
+    private final ResponseQueue mResponseQueue;
+
+    private final PowerManager.WakeLock mWakeLock;
+
+    private final Looper mLooper;
+
+    private INativeDaemonConnectorCallbacks mCallbacks;
+    private Handler mCallbackHandler;
+
+    private AtomicInteger mSequenceNumber;
+
+    private static final long DEFAULT_TIMEOUT = 1 * 60 * 1000; /* 1 minute */
+    private static final long WARN_EXECUTE_DELAY_MS = 500; /* .5 sec */
+
+    /** Lock held whenever communicating with native daemon. */
+    private final Object mDaemonLock = new Object();
+
+    private final int BUFFER_SIZE = 4096;
+
+    NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks, String socket,
+            int responseQueueSize, String logTag, int maxLogSize, PowerManager.WakeLock wl) {
+        mCallbacks = callbacks;
+        mSocket = socket;
+        mResponseQueue = new ResponseQueue(responseQueueSize);
+        mWakeLock = wl;
+        if (mWakeLock != null) {
+            mWakeLock.setReferenceCounted(true);
+        }
+        mSequenceNumber = new AtomicInteger(0);
+        TAG = logTag != null ? logTag : "NativeDaemonConnector";
+        mLocalLog = new LocalLog(maxLogSize);
+        final HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        mLooper = thread.getLooper();
+    }
+
+    /**
+     * Enable Set debugging mode, which causes messages to also be written to both
+     * {@link Log} in addition to internal log.
+     */
+    public void setDebug(boolean debug) {
+        mDebug = debug;
+    }
+
+    /**
+     * Like SystemClock.uptimeMillis, except truncated to an int so it will fit in a message arg.
+     * Inaccurate across 49.7 days of uptime, but only used for debugging.
+     */
+    private int uptimeMillisInt() {
+        return (int) SystemClock.uptimeMillis() & Integer.MAX_VALUE;
+    }
+
+    /**
+     * Yell loudly if someone tries making future {@link #execute(Command)}
+     * calls while holding a lock on the given object.
+     */
+    public void setWarnIfHeld(Object warnIfHeld) {
+        if (mWarnIfHeld != null) {
+            throw new IllegalStateException("warnIfHeld is already set.");
+        }
+        mWarnIfHeld = Objects.requireNonNull(warnIfHeld);
+    }
+
+    @Override
+    public void run() {
+        mCallbackHandler = new Handler(mLooper, this);
+
+        while (true) {
+            try {
+                listenToSocket();
+            } catch (Exception e) {
+                loge("Error in NativeDaemonConnector: " + e);
+                SystemClock.sleep(5000);
+            }
+        }
+    }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        final String event = (String) msg.obj;
+        final int start = uptimeMillisInt();
+        final int sent = msg.arg1;
+        try {
+            if (!mCallbacks.onEvent(msg.what, event, NativeDaemonEvent.unescapeArgs(event))) {
+                log(String.format("Unhandled event '%s'", event));
+            }
+        } catch (Exception e) {
+            loge("Error handling '" + event + "': " + e);
+        } finally {
+            if (mCallbacks.onCheckHoldWakeLock(msg.what) && mWakeLock != null) {
+                mWakeLock.release();
+            }
+            final int end = uptimeMillisInt();
+            if (start > sent && start - sent > WARN_EXECUTE_DELAY_MS) {
+                loge(String.format("NDC event {%s} processed too late: %dms", event, start - sent));
+            }
+            if (end > start && end - start > WARN_EXECUTE_DELAY_MS) {
+                loge(String.format("NDC event {%s} took too long: %dms", event, end - start));
+            }
+        }
+        return true;
+    }
+
+    private LocalSocketAddress determineSocketAddress() {
+        // If we're testing, set up a socket in a namespace that's accessible to test code.
+        // In order to ensure that unprivileged apps aren't able to impersonate native daemons on
+        // production devices, even if said native daemons ill-advisedly pick a socket name that
+        // starts with __test__, only allow this on debug builds.
+        if (mSocket.startsWith("__test__") && Build.isDebuggable()) {
+            return new LocalSocketAddress(mSocket);
+        } else {
+            return new LocalSocketAddress(mSocket, LocalSocketAddress.Namespace.RESERVED);
+        }
+    }
+
+    private void listenToSocket() throws IOException {
+        LocalSocket socket = null;
+
+        try {
+            socket = new LocalSocket();
+            LocalSocketAddress address = determineSocketAddress();
+
+            socket.connect(address);
+
+            InputStream inputStream = socket.getInputStream();
+            synchronized (mDaemonLock) {
+                mOutputStream = socket.getOutputStream();
+            }
+
+            mCallbacks.onDaemonConnected();
+
+            FileDescriptor[] fdList = null;
+            byte[] buffer = new byte[BUFFER_SIZE];
+            int start = 0;
+
+            while (true) {
+                int count = inputStream.read(buffer, start, BUFFER_SIZE - start);
+                if (count < 0) {
+                    loge("got " + count + " reading with start = " + start);
+                    break;
+                }
+                fdList = socket.getAncillaryFileDescriptors();
+
+                // Add our starting point to the count and reset the start.
+                count += start;
+                start = 0;
+
+                for (int i = 0; i < count; i++) {
+                    if (buffer[i] == 0) {
+                        // Note - do not log this raw message since it may contain
+                        // sensitive data
+                        final String rawEvent = new String(
+                                buffer, start, i - start, StandardCharsets.UTF_8);
+
+                        boolean releaseWl = false;
+                        try {
+                            final NativeDaemonEvent event =
+                                    NativeDaemonEvent.parseRawEvent(rawEvent, fdList);
+
+                            log("RCV <- {" + event + "}");
+
+                            if (event.isClassUnsolicited()) {
+                                // TODO: migrate to sending NativeDaemonEvent instances
+                                if (mCallbacks.onCheckHoldWakeLock(event.getCode())
+                                        && mWakeLock != null) {
+                                    mWakeLock.acquire();
+                                    releaseWl = true;
+                                }
+                                Message msg = mCallbackHandler.obtainMessage(
+                                        event.getCode(), uptimeMillisInt(), 0, event.getRawEvent());
+                                if (mCallbackHandler.sendMessage(msg)) {
+                                    releaseWl = false;
+                                }
+                            } else {
+                                mResponseQueue.add(event.getCmdNumber(), event);
+                            }
+                        } catch (IllegalArgumentException e) {
+                            log("Problem parsing message " + e);
+                        } finally {
+                            if (releaseWl) {
+                                mWakeLock.release();
+                            }
+                        }
+
+                        start = i + 1;
+                    }
+                }
+
+                if (start == 0) {
+                    log("RCV incomplete");
+                }
+
+                // We should end at the amount we read. If not, compact then
+                // buffer and read again.
+                if (start != count) {
+                    final int remaining = BUFFER_SIZE - start;
+                    System.arraycopy(buffer, start, buffer, 0, remaining);
+                    start = remaining;
+                } else {
+                    start = 0;
+                }
+            }
+        } catch (IOException ex) {
+            loge("Communications error: " + ex);
+            throw ex;
+        } finally {
+            synchronized (mDaemonLock) {
+                if (mOutputStream != null) {
+                    try {
+                        loge("closing stream for " + mSocket);
+                        mOutputStream.close();
+                    } catch (IOException e) {
+                        loge("Failed closing output stream: " + e);
+                    }
+                    mOutputStream = null;
+                }
+            }
+
+            try {
+                if (socket != null) {
+                    socket.close();
+                }
+            } catch (IOException ex) {
+                loge("Failed closing socket: " + ex);
+            }
+        }
+    }
+
+    /**
+     * Wrapper around argument that indicates it's sensitive and shouldn't be
+     * logged.
+     */
+    public static class SensitiveArg {
+        private final Object mArg;
+
+        public SensitiveArg(Object arg) {
+            mArg = arg;
+        }
+
+        @Override
+        public String toString() {
+            return String.valueOf(mArg);
+        }
+    }
+
+    /**
+     * Make command for daemon, escaping arguments as needed.
+     */
+    @VisibleForTesting
+    static void makeCommand(StringBuilder rawBuilder, StringBuilder logBuilder, int sequenceNumber,
+            String cmd, Object... args) {
+        if (cmd.indexOf('\0') >= 0) {
+            throw new IllegalArgumentException("Unexpected command: " + cmd);
+        }
+        if (cmd.indexOf(' ') >= 0) {
+            throw new IllegalArgumentException("Arguments must be separate from command");
+        }
+
+        rawBuilder.append(sequenceNumber).append(' ').append(cmd);
+        logBuilder.append(sequenceNumber).append(' ').append(cmd);
+        for (Object arg : args) {
+            final String argString = String.valueOf(arg);
+            if (argString.indexOf('\0') >= 0) {
+                throw new IllegalArgumentException("Unexpected argument: " + arg);
+            }
+
+            rawBuilder.append(' ');
+            logBuilder.append(' ');
+
+            appendEscaped(rawBuilder, argString);
+            if (arg instanceof SensitiveArg) {
+                logBuilder.append("[scrubbed]");
+            } else {
+                appendEscaped(logBuilder, argString);
+            }
+        }
+
+        rawBuilder.append('\0');
+    }
+
+    /**
+     * Method that waits until all asychronous notifications sent by the native daemon have
+     * been processed. This method must not be called on the notification thread or an
+     * exception will be thrown.
+     */
+    public void waitForCallbacks() {
+        if (Thread.currentThread() == mLooper.getThread()) {
+            throw new IllegalStateException("Must not call this method on callback thread");
+        }
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        mCallbackHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                latch.countDown();
+            }
+        });
+        try {
+            latch.await();
+        } catch (InterruptedException e) {
+            Log.wtf(TAG, "Interrupted while waiting for unsolicited response handling", e);
+        }
+    }
+
+    /**
+     * Issue the given command to the native daemon and return a single expected
+     * response.
+     *
+     * @throws NativeDaemonConnectorException when problem communicating with
+     *             native daemon, or if the response matches
+     *             {@link NativeDaemonEvent#isClassClientError()} or
+     *             {@link NativeDaemonEvent#isClassServerError()}.
+     */
+    public NativeDaemonEvent execute(Command cmd) throws NativeDaemonConnectorException {
+        return execute(cmd.mCmd, cmd.mArguments.toArray());
+    }
+
+    /**
+     * Issue the given command to the native daemon and return a single expected
+     * response. Any arguments must be separated from base command so they can
+     * be properly escaped.
+     *
+     * @throws NativeDaemonConnectorException when problem communicating with
+     *             native daemon, or if the response matches
+     *             {@link NativeDaemonEvent#isClassClientError()} or
+     *             {@link NativeDaemonEvent#isClassServerError()}.
+     */
+    public NativeDaemonEvent execute(String cmd, Object... args)
+            throws NativeDaemonConnectorException {
+        return execute(DEFAULT_TIMEOUT, cmd, args);
+    }
+
+    public NativeDaemonEvent execute(long timeoutMs, String cmd, Object... args)
+            throws NativeDaemonConnectorException {
+        final NativeDaemonEvent[] events = executeForList(timeoutMs, cmd, args);
+        if (events.length != 1) {
+            throw new NativeDaemonConnectorException(
+                    "Expected exactly one response, but received " + events.length);
+        }
+        return events[0];
+    }
+
+    /**
+     * Issue the given command to the native daemon and return any
+     * {@link NativeDaemonEvent#isClassContinue()} responses, including the
+     * final terminal response.
+     *
+     * @throws NativeDaemonConnectorException when problem communicating with
+     *             native daemon, or if the response matches
+     *             {@link NativeDaemonEvent#isClassClientError()} or
+     *             {@link NativeDaemonEvent#isClassServerError()}.
+     */
+    public NativeDaemonEvent[] executeForList(Command cmd) throws NativeDaemonConnectorException {
+        return executeForList(cmd.mCmd, cmd.mArguments.toArray());
+    }
+
+    /**
+     * Issue the given command to the native daemon and return any
+     * {@link NativeDaemonEvent#isClassContinue()} responses, including the
+     * final terminal response. Any arguments must be separated from base
+     * command so they can be properly escaped.
+     *
+     * @throws NativeDaemonConnectorException when problem communicating with
+     *             native daemon, or if the response matches
+     *             {@link NativeDaemonEvent#isClassClientError()} or
+     *             {@link NativeDaemonEvent#isClassServerError()}.
+     */
+    public NativeDaemonEvent[] executeForList(String cmd, Object... args)
+            throws NativeDaemonConnectorException {
+        return executeForList(DEFAULT_TIMEOUT, cmd, args);
+    }
+
+    /**
+     * Issue the given command to the native daemon and return any {@linke
+     * NativeDaemonEvent@isClassContinue()} responses, including the final
+     * terminal response. Note that the timeout does not count time in deep
+     * sleep. Any arguments must be separated from base command so they can be
+     * properly escaped.
+     *
+     * @throws NativeDaemonConnectorException when problem communicating with
+     *             native daemon, or if the response matches
+     *             {@link NativeDaemonEvent#isClassClientError()} or
+     *             {@link NativeDaemonEvent#isClassServerError()}.
+     */
+    public NativeDaemonEvent[] executeForList(long timeoutMs, String cmd, Object... args)
+            throws NativeDaemonConnectorException {
+        if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) {
+            Log.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x"
+                    + Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable());
+        }
+
+        final long startTime = SystemClock.elapsedRealtime();
+
+        final ArrayList<NativeDaemonEvent> events = new ArrayList<>();
+
+        final StringBuilder rawBuilder = new StringBuilder();
+        final StringBuilder logBuilder = new StringBuilder();
+        final int sequenceNumber = mSequenceNumber.incrementAndGet();
+
+        makeCommand(rawBuilder, logBuilder, sequenceNumber, cmd, args);
+
+        final String rawCmd = rawBuilder.toString();
+        final String logCmd = logBuilder.toString();
+
+        log("SND -> {" + logCmd + "}");
+
+        synchronized (mDaemonLock) {
+            if (mOutputStream == null) {
+                throw new NativeDaemonConnectorException("missing output stream");
+            } else {
+                try {
+                    mOutputStream.write(rawCmd.getBytes(StandardCharsets.UTF_8));
+                } catch (IOException e) {
+                    throw new NativeDaemonConnectorException("problem sending command", e);
+                }
+            }
+        }
+
+        NativeDaemonEvent event = null;
+        do {
+            event = mResponseQueue.remove(sequenceNumber, timeoutMs, logCmd);
+            if (event == null) {
+                loge("timed-out waiting for response to " + logCmd);
+                throw new NativeDaemonTimeoutException(logCmd, event);
+            }
+            if (VDBG) log("RMV <- {" + event + "}");
+            events.add(event);
+        } while (event.isClassContinue());
+
+        final long endTime = SystemClock.elapsedRealtime();
+        if (endTime - startTime > WARN_EXECUTE_DELAY_MS) {
+            loge("NDC Command {" + logCmd + "} took too long (" + (endTime - startTime) + "ms)");
+        }
+
+        if (event.isClassClientError()) {
+            throw new NativeDaemonArgumentException(logCmd, event);
+        }
+        if (event.isClassServerError()) {
+            throw new NativeDaemonFailureException(logCmd, event);
+        }
+
+        return events.toArray(new NativeDaemonEvent[events.size()]);
+    }
+
+    /**
+     * Append the given argument to {@link StringBuilder}, escaping as needed,
+     * and surrounding with quotes when it contains spaces.
+     */
+    @VisibleForTesting
+    static void appendEscaped(StringBuilder builder, String arg) {
+        final boolean hasSpaces = arg.indexOf(' ') >= 0;
+        if (hasSpaces) {
+            builder.append('"');
+        }
+
+        final int length = arg.length();
+        for (int i = 0; i < length; i++) {
+            final char c = arg.charAt(i);
+
+            if (c == '"') {
+                builder.append("\\\"");
+            } else if (c == '\\') {
+                builder.append("\\\\");
+            } else {
+                builder.append(c);
+            }
+        }
+
+        if (hasSpaces) {
+            builder.append('"');
+        }
+    }
+
+    private static class NativeDaemonArgumentException extends NativeDaemonConnectorException {
+        public NativeDaemonArgumentException(String command, NativeDaemonEvent event) {
+            super(command, event);
+        }
+
+        @Override
+        public IllegalArgumentException rethrowAsParcelableException() {
+            throw new IllegalArgumentException(getMessage(), this);
+        }
+    }
+
+    private static class NativeDaemonFailureException extends NativeDaemonConnectorException {
+        public NativeDaemonFailureException(String command, NativeDaemonEvent event) {
+            super(command, event);
+        }
+    }
+
+    /**
+     * Command builder that handles argument list building. Any arguments must
+     * be separated from base command so they can be properly escaped.
+     */
+    public static class Command {
+        private String mCmd;
+        private ArrayList<Object> mArguments = new ArrayList<>();
+
+        public Command(String cmd, Object... args) {
+            mCmd = cmd;
+            for (Object arg : args) {
+                appendArg(arg);
+            }
+        }
+
+        public Command appendArg(Object arg) {
+            mArguments.add(arg);
+            return this;
+        }
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mLocalLog.dump(fd, pw, args);
+        pw.println();
+        mResponseQueue.dump(fd, pw, args);
+    }
+
+    private void log(String logstring) {
+        if (mDebug) Log.d(TAG, logstring);
+        mLocalLog.log(logstring);
+    }
+
+    private void loge(String logstring) {
+        Log.e(TAG, logstring);
+        mLocalLog.log(logstring);
+    }
+
+    private static class ResponseQueue {
+
+        private static class PendingCmd {
+            public final int cmdNum;
+            public final String logCmd;
+
+            public BlockingQueue<NativeDaemonEvent> responses =
+                    new ArrayBlockingQueue<NativeDaemonEvent>(10);
+
+            // The availableResponseCount member is used to track when we can remove this
+            // instance from the ResponseQueue.
+            // This is used under the protection of a sync of the mPendingCmds object.
+            // A positive value means we've had more writers retreive this object while
+            // a negative value means we've had more readers.  When we've had an equal number
+            // (it goes to zero) we can remove this object from the mPendingCmds list.
+            // Note that we may have more responses for this command (and more readers
+            // coming), but that would result in a new PendingCmd instance being created
+            // and added with the same cmdNum.
+            // Also note that when this goes to zero it just means a parity of readers and
+            // writers have retrieved this object - not that they are done using it.  The
+            // responses queue may well have more responses yet to be read or may get more
+            // responses added to it.  But all those readers/writers have retreived and
+            // hold references to this instance already so it can be removed from
+            // mPendingCmds queue.
+            public int availableResponseCount;
+
+            public PendingCmd(int cmdNum, String logCmd) {
+                this.cmdNum = cmdNum;
+                this.logCmd = logCmd;
+            }
+        }
+
+        private final LinkedList<PendingCmd> mPendingCmds;
+        private int mMaxCount;
+
+        ResponseQueue(int maxCount) {
+            mPendingCmds = new LinkedList<PendingCmd>();
+            mMaxCount = maxCount;
+        }
+
+        public void add(int cmdNum, NativeDaemonEvent response) {
+            PendingCmd found = null;
+            synchronized (mPendingCmds) {
+                for (PendingCmd pendingCmd : mPendingCmds) {
+                    if (pendingCmd.cmdNum == cmdNum) {
+                        found = pendingCmd;
+                        break;
+                    }
+                }
+                if (found == null) {
+                    // didn't find it - make sure our queue isn't too big before adding
+                    while (mPendingCmds.size() >= mMaxCount) {
+                        Log.e("NativeDaemonConnector.ResponseQueue",
+                                "more buffered than allowed: " + mPendingCmds.size() +
+                                " >= " + mMaxCount);
+                        // let any waiter timeout waiting for this
+                        PendingCmd pendingCmd = mPendingCmds.remove();
+                        Log.e("NativeDaemonConnector.ResponseQueue",
+                                "Removing request: " + pendingCmd.logCmd + " (" +
+                                pendingCmd.cmdNum + ")");
+                    }
+                    found = new PendingCmd(cmdNum, null);
+                    mPendingCmds.add(found);
+                }
+                found.availableResponseCount++;
+                // if a matching remove call has already retrieved this we can remove this
+                // instance from our list
+                if (found.availableResponseCount == 0) mPendingCmds.remove(found);
+            }
+            try {
+                found.responses.put(response);
+            } catch (InterruptedException e) { }
+        }
+
+        // note that the timeout does not count time in deep sleep.  If you don't want
+        // the device to sleep, hold a wakelock
+        public NativeDaemonEvent remove(int cmdNum, long timeoutMs, String logCmd) {
+            PendingCmd found = null;
+            synchronized (mPendingCmds) {
+                for (PendingCmd pendingCmd : mPendingCmds) {
+                    if (pendingCmd.cmdNum == cmdNum) {
+                        found = pendingCmd;
+                        break;
+                    }
+                }
+                if (found == null) {
+                    found = new PendingCmd(cmdNum, logCmd);
+                    mPendingCmds.add(found);
+                }
+                found.availableResponseCount--;
+                // if a matching add call has already retrieved this we can remove this
+                // instance from our list
+                if (found.availableResponseCount == 0) mPendingCmds.remove(found);
+            }
+            NativeDaemonEvent result = null;
+            try {
+                result = found.responses.poll(timeoutMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {}
+            if (result == null) {
+                Log.e("NativeDaemonConnector.ResponseQueue", "Timeout waiting for response");
+            }
+            return result;
+        }
+
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            pw.println("Pending requests:");
+            synchronized (mPendingCmds) {
+                for (PendingCmd pendingCmd : mPendingCmds) {
+                    pw.println("  Cmd " + pendingCmd.cmdNum + " - " + pendingCmd.logCmd);
+                }
+            }
+        }
+    }
+}
diff --git a/service-t/src/com/android/server/NativeDaemonConnectorException.java b/service-t/src/com/android/server/NativeDaemonConnectorException.java
new file mode 100644
index 0000000..4d8881c
--- /dev/null
+++ b/service-t/src/com/android/server/NativeDaemonConnectorException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2006 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.server;
+
+import android.os.Parcel;
+
+/**
+ * An exception that indicates there was an error with a
+ * {@link NativeDaemonConnector} operation.
+ */
+public class NativeDaemonConnectorException extends Exception {
+    private String mCmd;
+    private NativeDaemonEvent mEvent;
+
+    public NativeDaemonConnectorException(String detailMessage) {
+        super(detailMessage);
+    }
+
+    public NativeDaemonConnectorException(String detailMessage, Throwable throwable) {
+        super(detailMessage, throwable);
+    }
+
+    public NativeDaemonConnectorException(String cmd, NativeDaemonEvent event) {
+        super("command '" + cmd + "' failed with '" + event + "'");
+        mCmd = cmd;
+        mEvent = event;
+    }
+
+    public int getCode() {
+        return mEvent != null ? mEvent.getCode() : -1;
+    }
+
+    public String getCmd() {
+        return mCmd;
+    }
+
+    /**
+     * Rethrow as a {@link RuntimeException} subclass that is handled by
+     * {@link Parcel#writeException(Exception)}.
+     */
+    public IllegalArgumentException rethrowAsParcelableException() {
+        throw new IllegalStateException(getMessage(), this);
+    }
+}
diff --git a/service-t/src/com/android/server/NativeDaemonEvent.java b/service-t/src/com/android/server/NativeDaemonEvent.java
new file mode 100644
index 0000000..5683694
--- /dev/null
+++ b/service-t/src/com/android/server/NativeDaemonEvent.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.util.ArrayList;
+
+/**
+ * Parsed event from native side of {@link NativeDaemonConnector}.
+ */
+public class NativeDaemonEvent {
+
+    // TODO: keep class ranges in sync with ResponseCode.h
+    // TODO: swap client and server error ranges to roughly mirror HTTP spec
+
+    private final int mCmdNumber;
+    private final int mCode;
+    private final String mMessage;
+    private final String mRawEvent;
+    private final String mLogMessage;
+    private String[] mParsed;
+    private FileDescriptor[] mFdList;
+
+    private NativeDaemonEvent(int cmdNumber, int code, String message,
+                              String rawEvent, String logMessage, FileDescriptor[] fdList) {
+        mCmdNumber = cmdNumber;
+        mCode = code;
+        mMessage = message;
+        mRawEvent = rawEvent;
+        mLogMessage = logMessage;
+        mParsed = null;
+        mFdList = fdList;
+    }
+
+    static public final String SENSITIVE_MARKER = "{{sensitive}}";
+
+    public int getCmdNumber() {
+        return mCmdNumber;
+    }
+
+    public int getCode() {
+        return mCode;
+    }
+
+    public String getMessage() {
+        return mMessage;
+    }
+
+    public FileDescriptor[] getFileDescriptors() {
+        return mFdList;
+    }
+
+    @Deprecated
+    public String getRawEvent() {
+        return mRawEvent;
+    }
+
+    @Override
+    public String toString() {
+        return mLogMessage;
+    }
+
+    /**
+     * Test if event represents a partial response which is continued in
+     * additional subsequent events.
+     */
+    public boolean isClassContinue() {
+        return mCode >= 100 && mCode < 200;
+    }
+
+    /**
+     * Test if event represents a command success.
+     */
+    public boolean isClassOk() {
+        return mCode >= 200 && mCode < 300;
+    }
+
+    /**
+     * Test if event represents a remote native daemon error.
+     */
+    public boolean isClassServerError() {
+        return mCode >= 400 && mCode < 500;
+    }
+
+    /**
+     * Test if event represents a command syntax or argument error.
+     */
+    public boolean isClassClientError() {
+        return mCode >= 500 && mCode < 600;
+    }
+
+    /**
+     * Test if event represents an unsolicited event from native daemon.
+     */
+    public boolean isClassUnsolicited() {
+        return isClassUnsolicited(mCode);
+    }
+
+    private static boolean isClassUnsolicited(int code) {
+        return code >= 600 && code < 700;
+    }
+
+    /**
+     * Verify this event matches the given code.
+     *
+     * @throws IllegalStateException if {@link #getCode()} doesn't match.
+     */
+    public void checkCode(int code) {
+        if (mCode != code) {
+            throw new IllegalStateException("Expected " + code + " but was: " + this);
+        }
+    }
+
+    /**
+     * Parse the given raw event into {@link NativeDaemonEvent} instance.
+     *
+     * @throws IllegalArgumentException when line doesn't match format expected
+     *             from native side.
+     */
+    public static NativeDaemonEvent parseRawEvent(String rawEvent, FileDescriptor[] fdList) {
+        final String[] parsed = rawEvent.split(" ");
+        if (parsed.length < 2) {
+            throw new IllegalArgumentException("Insufficient arguments");
+        }
+
+        int skiplength = 0;
+
+        final int code;
+        try {
+            code = Integer.parseInt(parsed[0]);
+            skiplength = parsed[0].length() + 1;
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException("problem parsing code", e);
+        }
+
+        int cmdNumber = -1;
+        if (isClassUnsolicited(code) == false) {
+            if (parsed.length < 3) {
+                throw new IllegalArgumentException("Insufficient arguemnts");
+            }
+            try {
+                cmdNumber = Integer.parseInt(parsed[1]);
+                skiplength += parsed[1].length() + 1;
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("problem parsing cmdNumber", e);
+            }
+        }
+
+        String logMessage = rawEvent;
+        if (parsed.length > 2 && parsed[2].equals(SENSITIVE_MARKER)) {
+            skiplength += parsed[2].length() + 1;
+            logMessage = parsed[0] + " " + parsed[1] + " {}";
+        }
+
+        final String message = rawEvent.substring(skiplength);
+
+        return new NativeDaemonEvent(cmdNumber, code, message, rawEvent, logMessage, fdList);
+    }
+
+    /**
+     * Filter the given {@link NativeDaemonEvent} list, returning
+     * {@link #getMessage()} for any events matching the requested code.
+     */
+    public static String[] filterMessageList(NativeDaemonEvent[] events, int matchCode) {
+        final ArrayList<String> result = new ArrayList<>();
+        for (NativeDaemonEvent event : events) {
+            if (event.getCode() == matchCode) {
+                result.add(event.getMessage());
+            }
+        }
+        return result.toArray(new String[result.size()]);
+    }
+
+    /**
+     * Find the Nth field of the event.
+     *
+     * This ignores and code or cmdNum, the first return value is given for N=0.
+     * Also understands "\"quoted\" multiword responses" and tries them as a single field
+     */
+    public String getField(int n) {
+        if (mParsed == null) {
+            mParsed = unescapeArgs(mRawEvent);
+        }
+        n += 2; // skip code and command#
+        if (n > mParsed.length) return null;
+            return mParsed[n];
+        }
+
+    public static String[] unescapeArgs(String rawEvent) {
+        final boolean DEBUG_ROUTINE = false;
+        final String LOGTAG = "unescapeArgs";
+        final ArrayList<String> parsed = new ArrayList<String>();
+        final int length = rawEvent.length();
+        int current = 0;
+        int wordEnd = -1;
+        boolean quoted = false;
+
+        if (DEBUG_ROUTINE) Log.e(LOGTAG, "parsing '" + rawEvent + "'");
+        if (rawEvent.charAt(current) == '\"') {
+            quoted = true;
+            current++;
+        }
+        while (current < length) {
+            // find the end of the word
+            char terminator = quoted ? '\"' : ' ';
+            wordEnd = current;
+            while (wordEnd < length && rawEvent.charAt(wordEnd) != terminator) {
+                if (rawEvent.charAt(wordEnd) == '\\') {
+                    // skip the escaped char
+                    ++wordEnd;
+                }
+                ++wordEnd;
+            }
+            if (wordEnd > length) wordEnd = length;
+            String word = rawEvent.substring(current, wordEnd);
+            current += word.length();
+            if (!quoted) {
+                word = word.trim();
+            } else {
+                current++;  // skip the trailing quote
+            }
+            // unescape stuff within the word
+            word = word.replace("\\\\", "\\");
+            word = word.replace("\\\"", "\"");
+
+            if (DEBUG_ROUTINE) Log.e(LOGTAG, "found '" + word + "'");
+            parsed.add(word);
+
+            // find the beginning of the next word - either of these options
+            int nextSpace = rawEvent.indexOf(' ', current);
+            int nextQuote = rawEvent.indexOf(" \"", current);
+            if (DEBUG_ROUTINE) {
+                Log.e(LOGTAG, "nextSpace=" + nextSpace + ", nextQuote=" + nextQuote);
+            }
+            if (nextQuote > -1 && nextQuote <= nextSpace) {
+                quoted = true;
+                current = nextQuote + 2;
+            } else {
+                quoted = false;
+                if (nextSpace > -1) {
+                    current = nextSpace + 1;
+                }
+            } // else we just start the next word after the current and read til the end
+            if (DEBUG_ROUTINE) {
+                Log.e(LOGTAG, "next loop - current=" + current
+                        + ", length=" + length + ", quoted=" + quoted);
+            }
+        }
+        return parsed.toArray(new String[parsed.size()]);
+    }
+}
diff --git a/service-t/src/com/android/server/NativeDaemonTimeoutException.java b/service-t/src/com/android/server/NativeDaemonTimeoutException.java
new file mode 100644
index 0000000..658f7d6
--- /dev/null
+++ b/service-t/src/com/android/server/NativeDaemonTimeoutException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+/**
+ * An exception that indicates there was a timeout with a
+ * {@link NativeDaemonConnector} operation.
+ */
+public class NativeDaemonTimeoutException extends NativeDaemonConnectorException {
+    public NativeDaemonTimeoutException(String command, NativeDaemonEvent event) {
+        super(command, event);
+    }
+}
+
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
new file mode 100644
index 0000000..ddf6d2c
--- /dev/null
+++ b/service-t/src/com/android/server/NsdService.java
@@ -0,0 +1,1146 @@
+/*
+ * 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.server;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.nsd.INsdManager;
+import android.net.nsd.INsdManagerCallback;
+import android.net.nsd.INsdServiceConnector;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Base64;
+import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+import com.android.net.module.util.DnsSdTxtRecord;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Network Service Discovery Service handles remote service discovery operation requests by
+ * implementing the INsdManager interface.
+ *
+ * @hide
+ */
+public class NsdService extends INsdManager.Stub {
+    private static final String TAG = "NsdService";
+    private static final String MDNS_TAG = "mDnsConnector";
+
+    private static final boolean DBG = true;
+    private static final long CLEANUP_DELAY_MS = 10000;
+    private static final int IFACE_IDX_ANY = 0;
+
+    private final Context mContext;
+    private final NsdStateMachine mNsdStateMachine;
+    private final DaemonConnection mDaemon;
+    private final NativeCallbackReceiver mDaemonCallback;
+
+    /**
+     * Clients receiving asynchronous messages
+     */
+    private final HashMap<NsdServiceConnector, ClientInfo> mClients = new HashMap<>();
+
+    /* A map from unique id to client info */
+    private final SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<>();
+
+    private final long mCleanupDelayMs;
+
+    private static final int INVALID_ID = 0;
+    private int mUniqueId = 1;
+    // The count of the connected legacy clients.
+    private int mLegacyClientCount = 0;
+
+    private class NsdStateMachine extends StateMachine {
+
+        private final DefaultState mDefaultState = new DefaultState();
+        private final DisabledState mDisabledState = new DisabledState();
+        private final EnabledState mEnabledState = new EnabledState();
+
+        @Override
+        protected String getWhatToString(int what) {
+            return NsdManager.nameOf(what);
+        }
+
+        private void maybeStartDaemon() {
+            mDaemon.maybeStart();
+            maybeScheduleStop();
+        }
+
+        private boolean isAnyRequestActive() {
+            return mIdToClientInfoMap.size() != 0;
+        }
+
+        private void scheduleStop() {
+            sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs);
+        }
+        private void maybeScheduleStop() {
+            // The native daemon should stay alive and can't be cleanup
+            // if any legacy client connected.
+            if (!isAnyRequestActive() && mLegacyClientCount == 0) {
+                scheduleStop();
+            }
+        }
+
+        private void cancelStop() {
+            this.removeMessages(NsdManager.DAEMON_CLEANUP);
+        }
+
+        NsdStateMachine(String name, Handler handler) {
+            super(name, handler);
+            addState(mDefaultState);
+                addState(mDisabledState, mDefaultState);
+                addState(mEnabledState, mDefaultState);
+            State initialState = mEnabledState;
+            setInitialState(initialState);
+            setLogRecSize(25);
+        }
+
+        class DefaultState extends State {
+            @Override
+            public boolean processMessage(Message msg) {
+                final ClientInfo cInfo;
+                final int clientId = msg.arg2;
+                switch (msg.what) {
+                    case NsdManager.REGISTER_CLIENT:
+                        final Pair<NsdServiceConnector, INsdManagerCallback> arg =
+                                (Pair<NsdServiceConnector, INsdManagerCallback>) msg.obj;
+                        final INsdManagerCallback cb = arg.second;
+                        try {
+                            cb.asBinder().linkToDeath(arg.first, 0);
+                            cInfo = new ClientInfo(cb);
+                            mClients.put(arg.first, cInfo);
+                        } catch (RemoteException e) {
+                            Log.w(TAG, "Client " + clientId + " has already died");
+                        }
+                        break;
+                    case NsdManager.UNREGISTER_CLIENT:
+                        final NsdServiceConnector connector = (NsdServiceConnector) msg.obj;
+                        cInfo = mClients.remove(connector);
+                        if (cInfo != null) {
+                            cInfo.expungeAllRequests();
+                            if (cInfo.isLegacy()) {
+                                mLegacyClientCount -= 1;
+                            }
+                        }
+                        maybeScheduleStop();
+                        break;
+                    case NsdManager.DISCOVER_SERVICES:
+                        cInfo = getClientInfoForReply(msg);
+                        if (cInfo != null) {
+                            cInfo.onDiscoverServicesFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                       break;
+                    case NsdManager.STOP_DISCOVERY:
+                        cInfo = getClientInfoForReply(msg);
+                        if (cInfo != null) {
+                            cInfo.onStopDiscoveryFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        break;
+                    case NsdManager.REGISTER_SERVICE:
+                        cInfo = getClientInfoForReply(msg);
+                        if (cInfo != null) {
+                            cInfo.onRegisterServiceFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        break;
+                    case NsdManager.UNREGISTER_SERVICE:
+                        cInfo = getClientInfoForReply(msg);
+                        if (cInfo != null) {
+                            cInfo.onUnregisterServiceFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        break;
+                    case NsdManager.RESOLVE_SERVICE:
+                        cInfo = getClientInfoForReply(msg);
+                        if (cInfo != null) {
+                            cInfo.onResolveServiceFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        break;
+                    case NsdManager.DAEMON_CLEANUP:
+                        mDaemon.maybeStop();
+                        break;
+                    // This event should be only sent by the legacy (target SDK < S) clients.
+                    // Mark the sending client as legacy.
+                    case NsdManager.DAEMON_STARTUP:
+                        cInfo = getClientInfoForReply(msg);
+                        if (cInfo != null) {
+                            cancelStop();
+                            cInfo.setLegacy();
+                            mLegacyClientCount += 1;
+                            maybeStartDaemon();
+                        }
+                        break;
+                    case NsdManager.NATIVE_DAEMON_EVENT:
+                    default:
+                        Log.e(TAG, "Unhandled " + msg);
+                        return NOT_HANDLED;
+                }
+                return HANDLED;
+            }
+
+            private ClientInfo getClientInfoForReply(Message msg) {
+                final ListenerArgs args = (ListenerArgs) msg.obj;
+                return mClients.get(args.connector);
+            }
+        }
+
+        class DisabledState extends State {
+            @Override
+            public void enter() {
+                sendNsdStateChangeBroadcast(false);
+            }
+
+            @Override
+            public boolean processMessage(Message msg) {
+                switch (msg.what) {
+                    case NsdManager.ENABLE:
+                        transitionTo(mEnabledState);
+                        break;
+                    default:
+                        return NOT_HANDLED;
+                }
+                return HANDLED;
+            }
+        }
+
+        class EnabledState extends State {
+            @Override
+            public void enter() {
+                sendNsdStateChangeBroadcast(true);
+            }
+
+            @Override
+            public void exit() {
+                // TODO: it is incorrect to stop the daemon without expunging all requests
+                // and sending error callbacks to clients.
+                scheduleStop();
+            }
+
+            private boolean requestLimitReached(ClientInfo clientInfo) {
+                if (clientInfo.mClientIds.size() >= ClientInfo.MAX_LIMIT) {
+                    if (DBG) Log.d(TAG, "Exceeded max outstanding requests " + clientInfo);
+                    return true;
+                }
+                return false;
+            }
+
+            private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo, int what) {
+                clientInfo.mClientIds.put(clientId, globalId);
+                clientInfo.mClientRequests.put(clientId, what);
+                mIdToClientInfoMap.put(globalId, clientInfo);
+                // Remove the cleanup event because here comes a new request.
+                cancelStop();
+            }
+
+            private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+                clientInfo.mClientIds.delete(clientId);
+                clientInfo.mClientRequests.delete(clientId);
+                mIdToClientInfoMap.remove(globalId);
+                maybeScheduleStop();
+            }
+
+            @Override
+            public boolean processMessage(Message msg) {
+                final ClientInfo clientInfo;
+                final int id;
+                final int clientId = msg.arg2;
+                final ListenerArgs args;
+                switch (msg.what) {
+                    case NsdManager.DISABLE:
+                        //TODO: cleanup clients
+                        transitionTo(mDisabledState);
+                        break;
+                    case NsdManager.DISCOVER_SERVICES:
+                        if (DBG) Log.d(TAG, "Discover services");
+                        args = (ListenerArgs) msg.obj;
+                        clientInfo = mClients.get(args.connector);
+
+                        if (requestLimitReached(clientInfo)) {
+                            clientInfo.onDiscoverServicesFailed(
+                                    clientId, NsdManager.FAILURE_MAX_LIMIT);
+                            break;
+                        }
+
+                        maybeStartDaemon();
+                        id = getUniqueId();
+                        if (discoverServices(id, args.serviceInfo)) {
+                            if (DBG) {
+                                Log.d(TAG, "Discover " + msg.arg2 + " " + id
+                                        + args.serviceInfo.getServiceType());
+                            }
+                            storeRequestMap(clientId, id, clientInfo, msg.what);
+                            clientInfo.onDiscoverServicesStarted(clientId, args.serviceInfo);
+                        } else {
+                            stopServiceDiscovery(id);
+                            clientInfo.onDiscoverServicesFailed(clientId,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        break;
+                    case NsdManager.STOP_DISCOVERY:
+                        if (DBG) Log.d(TAG, "Stop service discovery");
+                        args = (ListenerArgs) msg.obj;
+                        clientInfo = mClients.get(args.connector);
+
+                        try {
+                            id = clientInfo.mClientIds.get(clientId);
+                        } catch (NullPointerException e) {
+                            clientInfo.onStopDiscoveryFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                            break;
+                        }
+                        removeRequestMap(clientId, id, clientInfo);
+                        if (stopServiceDiscovery(id)) {
+                            clientInfo.onStopDiscoverySucceeded(clientId);
+                        } else {
+                            clientInfo.onStopDiscoveryFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        break;
+                    case NsdManager.REGISTER_SERVICE:
+                        if (DBG) Log.d(TAG, "Register service");
+                        args = (ListenerArgs) msg.obj;
+                        clientInfo = mClients.get(args.connector);
+                        if (requestLimitReached(clientInfo)) {
+                            clientInfo.onRegisterServiceFailed(
+                                    clientId, NsdManager.FAILURE_MAX_LIMIT);
+                            break;
+                        }
+
+                        maybeStartDaemon();
+                        id = getUniqueId();
+                        if (registerService(id, args.serviceInfo)) {
+                            if (DBG) Log.d(TAG, "Register " + clientId + " " + id);
+                            storeRequestMap(clientId, id, clientInfo, msg.what);
+                            // Return success after mDns reports success
+                        } else {
+                            unregisterService(id);
+                            clientInfo.onRegisterServiceFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        break;
+                    case NsdManager.UNREGISTER_SERVICE:
+                        if (DBG) Log.d(TAG, "unregister service");
+                        args = (ListenerArgs) msg.obj;
+                        clientInfo = mClients.get(args.connector);
+                        if (clientInfo == null) {
+                            Log.e(TAG, "Unknown connector in unregistration");
+                            break;
+                        }
+                        id = clientInfo.mClientIds.get(clientId);
+                        removeRequestMap(clientId, id, clientInfo);
+                        if (unregisterService(id)) {
+                            clientInfo.onUnregisterServiceSucceeded(clientId);
+                        } else {
+                            clientInfo.onUnregisterServiceFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        break;
+                    case NsdManager.RESOLVE_SERVICE:
+                        if (DBG) Log.d(TAG, "Resolve service");
+                        args = (ListenerArgs) msg.obj;
+                        clientInfo = mClients.get(args.connector);
+
+                        if (clientInfo.mResolvedService != null) {
+                            clientInfo.onResolveServiceFailed(
+                                    clientId, NsdManager.FAILURE_ALREADY_ACTIVE);
+                            break;
+                        }
+
+                        maybeStartDaemon();
+                        id = getUniqueId();
+                        if (resolveService(id, args.serviceInfo)) {
+                            clientInfo.mResolvedService = new NsdServiceInfo();
+                            storeRequestMap(clientId, id, clientInfo, msg.what);
+                        } else {
+                            clientInfo.onResolveServiceFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        break;
+                    case NsdManager.NATIVE_DAEMON_EVENT:
+                        NativeEvent event = (NativeEvent) msg.obj;
+                        if (!handleNativeEvent(event.code, event.raw, event.cooked)) {
+                            return NOT_HANDLED;
+                        }
+                        break;
+                    default:
+                        return NOT_HANDLED;
+                }
+                return HANDLED;
+            }
+
+            private boolean handleNativeEvent(int code, String raw, String[] cooked) {
+                NsdServiceInfo servInfo;
+                int id = Integer.parseInt(cooked[1]);
+                ClientInfo clientInfo = mIdToClientInfoMap.get(id);
+                if (clientInfo == null) {
+                    String name = NativeResponseCode.nameOf(code);
+                    Log.e(TAG, String.format("id %d for %s has no client mapping", id, name));
+                    return false;
+                }
+
+                /* This goes in response as msg.arg2 */
+                int clientId = clientInfo.getClientId(id);
+                if (clientId < 0) {
+                    // This can happen because of race conditions. For example,
+                    // SERVICE_FOUND may race with STOP_SERVICE_DISCOVERY,
+                    // and we may get in this situation.
+                    String name = NativeResponseCode.nameOf(code);
+                    Log.d(TAG, String.format(
+                            "Notification %s for listener id %d that is no longer active",
+                            name, id));
+                    return false;
+                }
+                if (DBG) {
+                    String name = NativeResponseCode.nameOf(code);
+                    Log.d(TAG, String.format("Native daemon message %s: %s", name, raw));
+                }
+                switch (code) {
+                    case NativeResponseCode.SERVICE_FOUND:
+                        /* NNN uniqueId serviceName regType domain interfaceIdx netId */
+                        servInfo = new NsdServiceInfo(cooked[2], cooked[3]);
+                        final int foundNetId;
+                        try {
+                            foundNetId = Integer.parseInt(cooked[6]);
+                        } catch (NumberFormatException e) {
+                            Log.wtf(TAG, "Invalid network received from mdnsd: " + cooked[6]);
+                            break;
+                        }
+                        if (foundNetId == 0L) {
+                            // Ignore services that do not have a Network: they are not usable
+                            // by apps, as they would need privileged permissions to use
+                            // interfaces that do not have an associated Network.
+                            break;
+                        }
+                        servInfo.setNetwork(new Network(foundNetId));
+                        clientInfo.onServiceFound(clientId, servInfo);
+                        break;
+                    case NativeResponseCode.SERVICE_LOST:
+                        /* NNN uniqueId serviceName regType domain interfaceIdx netId */
+                        final int lostNetId;
+                        try {
+                            lostNetId = Integer.parseInt(cooked[6]);
+                        } catch (NumberFormatException e) {
+                            Log.wtf(TAG, "Invalid network received from mdnsd: " + cooked[6]);
+                            break;
+                        }
+                        servInfo = new NsdServiceInfo(cooked[2], cooked[3]);
+                        // The network could be null if it was torn down when the service is lost
+                        // TODO: avoid returning null in that case, possibly by remembering found
+                        // services on the same interface index and their network at the time
+                        servInfo.setNetwork(lostNetId == 0 ? null : new Network(lostNetId));
+                        clientInfo.onServiceLost(clientId, servInfo);
+                        break;
+                    case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
+                        /* NNN uniqueId errorCode */
+                        clientInfo.onDiscoverServicesFailed(
+                                clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        break;
+                    case NativeResponseCode.SERVICE_REGISTERED:
+                        /* NNN regId serviceName regType */
+                        servInfo = new NsdServiceInfo(cooked[2], null);
+                        clientInfo.onRegisterServiceSucceeded(clientId, servInfo);
+                        break;
+                    case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
+                        /* NNN regId errorCode */
+                        clientInfo.onRegisterServiceFailed(
+                                clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        break;
+                    case NativeResponseCode.SERVICE_UPDATED:
+                        /* NNN regId */
+                        break;
+                    case NativeResponseCode.SERVICE_UPDATE_FAILED:
+                        /* NNN regId errorCode */
+                        break;
+                    case NativeResponseCode.SERVICE_RESOLVED:
+                        /* NNN resolveId fullName hostName port txtlen txtdata interfaceIdx */
+                        int index = 0;
+                        while (index < cooked[2].length() && cooked[2].charAt(index) != '.') {
+                            if (cooked[2].charAt(index) == '\\') {
+                                ++index;
+                            }
+                            ++index;
+                        }
+                        if (index >= cooked[2].length()) {
+                            Log.e(TAG, "Invalid service found " + raw);
+                            break;
+                        }
+
+                        String name = cooked[2].substring(0, index);
+                        String rest = cooked[2].substring(index);
+                        String type = rest.replace(".local.", "");
+
+                        name = unescape(name);
+
+                        clientInfo.mResolvedService.setServiceName(name);
+                        clientInfo.mResolvedService.setServiceType(type);
+                        clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
+                        clientInfo.mResolvedService.setTxtRecords(cooked[6]);
+                        // Network will be added after SERVICE_GET_ADDR_SUCCESS
+
+                        stopResolveService(id);
+                        removeRequestMap(clientId, id, clientInfo);
+
+                        int id2 = getUniqueId();
+                        if (getAddrInfo(id2, cooked[3], cooked[7] /* interfaceIdx */)) {
+                            storeRequestMap(clientId, id2, clientInfo, NsdManager.RESOLVE_SERVICE);
+                        } else {
+                            clientInfo.onResolveServiceFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                            clientInfo.mResolvedService = null;
+                        }
+                        break;
+                    case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
+                        /* NNN resolveId errorCode */
+                        stopResolveService(id);
+                        removeRequestMap(clientId, id, clientInfo);
+                        clientInfo.mResolvedService = null;
+                        clientInfo.onResolveServiceFailed(
+                                clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        break;
+                    case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
+                        /* NNN resolveId errorCode */
+                        stopGetAddrInfo(id);
+                        removeRequestMap(clientId, id, clientInfo);
+                        clientInfo.mResolvedService = null;
+                        clientInfo.onResolveServiceFailed(
+                                clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        break;
+                    case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
+                        /* NNN resolveId hostname ttl addr interfaceIdx netId */
+                        Network network = null;
+                        try {
+                            final int netId = Integer.parseInt(cooked[6]);
+                            network = netId == 0L ? null : new Network(netId);
+                        } catch (NumberFormatException e) {
+                            Log.wtf(TAG, "Invalid network in GET_ADDR_SUCCESS: " + cooked[6], e);
+                        }
+
+                        InetAddress serviceHost = null;
+                        try {
+                            serviceHost = InetAddress.getByName(cooked[4]);
+                        } catch (UnknownHostException e) {
+                            Log.wtf(TAG, "Invalid host in GET_ADDR_SUCCESS", e);
+                        }
+
+                        // If the resolved service is on an interface without a network, consider it
+                        // as a failure: it would not be usable by apps as they would need
+                        // privileged permissions.
+                        if (network != null && serviceHost != null) {
+                            clientInfo.mResolvedService.setHost(serviceHost);
+                            clientInfo.mResolvedService.setNetwork(network);
+                            clientInfo.onResolveServiceSucceeded(
+                                    clientId, clientInfo.mResolvedService);
+                        } else {
+                            clientInfo.onResolveServiceFailed(
+                                    clientId, NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
+                        stopGetAddrInfo(id);
+                        removeRequestMap(clientId, id, clientInfo);
+                        clientInfo.mResolvedService = null;
+                        break;
+                    default:
+                        return false;
+                }
+                return true;
+            }
+       }
+    }
+
+    private String unescape(String s) {
+        StringBuilder sb = new StringBuilder(s.length());
+        for (int i = 0; i < s.length(); ++i) {
+            char c = s.charAt(i);
+            if (c == '\\') {
+                if (++i >= s.length()) {
+                    Log.e(TAG, "Unexpected end of escape sequence in: " + s);
+                    break;
+                }
+                c = s.charAt(i);
+                if (c != '.' && c != '\\') {
+                    if (i + 2 >= s.length()) {
+                        Log.e(TAG, "Unexpected end of escape sequence in: " + s);
+                        break;
+                    }
+                    c = (char) ((c-'0') * 100 + (s.charAt(i+1)-'0') * 10 + (s.charAt(i+2)-'0'));
+                    i += 2;
+                }
+            }
+            sb.append(c);
+        }
+        return sb.toString();
+    }
+
+    @VisibleForTesting
+    NsdService(Context ctx, Handler handler, DaemonConnectionSupplier fn, long cleanupDelayMs) {
+        mCleanupDelayMs = cleanupDelayMs;
+        mContext = ctx;
+        mNsdStateMachine = new NsdStateMachine(TAG, handler);
+        mNsdStateMachine.start();
+        mDaemonCallback = new NativeCallbackReceiver();
+        mDaemon = fn.get(mDaemonCallback);
+    }
+
+    public static NsdService create(Context context) throws InterruptedException {
+        HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        Handler handler = new Handler(thread.getLooper());
+        NsdService service =
+                new NsdService(context, handler, DaemonConnection::new, CLEANUP_DELAY_MS);
+        service.mDaemonCallback.awaitConnection();
+        return service;
+    }
+
+    @Override
+    public INsdServiceConnector connect(INsdManagerCallback cb) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET, "NsdService");
+        final INsdServiceConnector connector = new NsdServiceConnector();
+        mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
+                NsdManager.REGISTER_CLIENT, new Pair<>(connector, cb)));
+        return connector;
+    }
+
+    private static class ListenerArgs {
+        public final NsdServiceConnector connector;
+        public final NsdServiceInfo serviceInfo;
+        ListenerArgs(NsdServiceConnector connector, NsdServiceInfo serviceInfo) {
+            this.connector = connector;
+            this.serviceInfo = serviceInfo;
+        }
+    }
+
+    private class NsdServiceConnector extends INsdServiceConnector.Stub
+            implements IBinder.DeathRecipient  {
+        @Override
+        public void registerService(int listenerKey, NsdServiceInfo serviceInfo) {
+            mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
+                    NsdManager.REGISTER_SERVICE, 0, listenerKey,
+                    new ListenerArgs(this, serviceInfo)));
+        }
+
+        @Override
+        public void unregisterService(int listenerKey) {
+            mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
+                    NsdManager.UNREGISTER_SERVICE, 0, listenerKey,
+                    new ListenerArgs(this, null)));
+        }
+
+        @Override
+        public void discoverServices(int listenerKey, NsdServiceInfo serviceInfo) {
+            mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
+                    NsdManager.DISCOVER_SERVICES, 0, listenerKey,
+                    new ListenerArgs(this, serviceInfo)));
+        }
+
+        @Override
+        public void stopDiscovery(int listenerKey) {
+            mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
+                    NsdManager.STOP_DISCOVERY, 0, listenerKey, new ListenerArgs(this, null)));
+        }
+
+        @Override
+        public void resolveService(int listenerKey, NsdServiceInfo serviceInfo) {
+            mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
+                    NsdManager.RESOLVE_SERVICE, 0, listenerKey,
+                    new ListenerArgs(this, serviceInfo)));
+        }
+
+        @Override
+        public void startDaemon() {
+            mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
+                    NsdManager.DAEMON_STARTUP, new ListenerArgs(this, null)));
+        }
+
+        @Override
+        public void binderDied() {
+            mNsdStateMachine.sendMessage(
+                    mNsdStateMachine.obtainMessage(NsdManager.UNREGISTER_CLIENT, this));
+        }
+    }
+
+    private void sendNsdStateChangeBroadcast(boolean isEnabled) {
+        final Intent intent = new Intent(NsdManager.ACTION_NSD_STATE_CHANGED);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+        int nsdState = isEnabled ? NsdManager.NSD_STATE_ENABLED : NsdManager.NSD_STATE_DISABLED;
+        intent.putExtra(NsdManager.EXTRA_NSD_STATE, nsdState);
+        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+    }
+
+    private int getUniqueId() {
+        if (++mUniqueId == INVALID_ID) return ++mUniqueId;
+        return mUniqueId;
+    }
+
+    /* These should be in sync with system/netd/server/ResponseCode.h */
+    static final class NativeResponseCode {
+        public static final int SERVICE_DISCOVERY_FAILED    =   602;
+        public static final int SERVICE_FOUND               =   603;
+        public static final int SERVICE_LOST                =   604;
+
+        public static final int SERVICE_REGISTRATION_FAILED =   605;
+        public static final int SERVICE_REGISTERED          =   606;
+
+        public static final int SERVICE_RESOLUTION_FAILED   =   607;
+        public static final int SERVICE_RESOLVED            =   608;
+
+        public static final int SERVICE_UPDATED             =   609;
+        public static final int SERVICE_UPDATE_FAILED       =   610;
+
+        public static final int SERVICE_GET_ADDR_FAILED     =   611;
+        public static final int SERVICE_GET_ADDR_SUCCESS    =   612;
+
+        private static final SparseArray<String> CODE_NAMES = new SparseArray<>();
+        static {
+            CODE_NAMES.put(SERVICE_DISCOVERY_FAILED, "SERVICE_DISCOVERY_FAILED");
+            CODE_NAMES.put(SERVICE_FOUND, "SERVICE_FOUND");
+            CODE_NAMES.put(SERVICE_LOST, "SERVICE_LOST");
+            CODE_NAMES.put(SERVICE_REGISTRATION_FAILED, "SERVICE_REGISTRATION_FAILED");
+            CODE_NAMES.put(SERVICE_REGISTERED, "SERVICE_REGISTERED");
+            CODE_NAMES.put(SERVICE_RESOLUTION_FAILED, "SERVICE_RESOLUTION_FAILED");
+            CODE_NAMES.put(SERVICE_RESOLVED, "SERVICE_RESOLVED");
+            CODE_NAMES.put(SERVICE_UPDATED, "SERVICE_UPDATED");
+            CODE_NAMES.put(SERVICE_UPDATE_FAILED, "SERVICE_UPDATE_FAILED");
+            CODE_NAMES.put(SERVICE_GET_ADDR_FAILED, "SERVICE_GET_ADDR_FAILED");
+            CODE_NAMES.put(SERVICE_GET_ADDR_SUCCESS, "SERVICE_GET_ADDR_SUCCESS");
+        }
+
+        static String nameOf(int code) {
+            String name = CODE_NAMES.get(code);
+            if (name == null) {
+                return Integer.toString(code);
+            }
+            return name;
+        }
+    }
+
+    private class NativeEvent {
+        final int code;
+        final String raw;
+        final String[] cooked;
+
+        NativeEvent(int code, String raw, String[] cooked) {
+            this.code = code;
+            this.raw = raw;
+            this.cooked = cooked;
+        }
+    }
+
+    class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
+        private final CountDownLatch connected = new CountDownLatch(1);
+
+        public void awaitConnection() throws InterruptedException {
+            connected.await();
+        }
+
+        @Override
+        public void onDaemonConnected() {
+            connected.countDown();
+        }
+
+        @Override
+        public boolean onCheckHoldWakeLock(int code) {
+            return false;
+        }
+
+        @Override
+        public boolean onEvent(int code, String raw, String[] cooked) {
+            // TODO: NDC translates a message to a callback, we could enhance NDC to
+            // directly interact with a state machine through messages
+            NativeEvent event = new NativeEvent(code, raw, cooked);
+            mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event);
+            return true;
+        }
+    }
+
+    interface DaemonConnectionSupplier {
+        DaemonConnection get(NativeCallbackReceiver callback);
+    }
+
+    @VisibleForTesting
+    public static class DaemonConnection {
+        final NativeDaemonConnector mNativeConnector;
+        boolean mIsStarted = false;
+
+        DaemonConnection(NativeCallbackReceiver callback) {
+            mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null);
+            new Thread(mNativeConnector, MDNS_TAG).start();
+        }
+
+        /**
+         * Executes the specified cmd on the daemon.
+         */
+        public boolean execute(Object... args) {
+            if (DBG) {
+                Log.d(TAG, "mdnssd " + Arrays.toString(args));
+            }
+            try {
+                mNativeConnector.execute("mdnssd", args);
+            } catch (NativeDaemonConnectorException e) {
+                Log.e(TAG, "Failed to execute mdnssd " + Arrays.toString(args), e);
+                return false;
+            }
+            return true;
+        }
+
+        /**
+         * Starts the daemon if it is not already started.
+         */
+        public void maybeStart() {
+            if (mIsStarted) {
+                return;
+            }
+            execute("start-service");
+            mIsStarted = true;
+        }
+
+        /**
+         * Stops the daemon if it is started.
+         */
+        public void maybeStop() {
+            if (!mIsStarted) {
+                return;
+            }
+            execute("stop-service");
+            mIsStarted = false;
+        }
+    }
+
+    private boolean registerService(int regId, NsdServiceInfo service) {
+        if (DBG) {
+            Log.d(TAG, "registerService: " + regId + " " + service);
+        }
+        String name = service.getServiceName();
+        String type = service.getServiceType();
+        int port = service.getPort();
+        byte[] textRecord = service.getTxtRecord();
+        String record = Base64.encodeToString(textRecord, Base64.DEFAULT).replace("\n", "");
+        return mDaemon.execute("register", regId, name, type, port, record);
+    }
+
+    private boolean unregisterService(int regId) {
+        return mDaemon.execute("stop-register", regId);
+    }
+
+    private boolean updateService(int regId, DnsSdTxtRecord t) {
+        if (t == null) {
+            return false;
+        }
+        return mDaemon.execute("update", regId, t.size(), t.getRawData());
+    }
+
+    private boolean discoverServices(int discoveryId, NsdServiceInfo serviceInfo) {
+        final Network network = serviceInfo.getNetwork();
+        final int discoverInterface = getNetworkInterfaceIndex(network);
+        if (network != null && discoverInterface == IFACE_IDX_ANY) {
+            Log.e(TAG, "Interface to discover service on not found");
+            return false;
+        }
+        return mDaemon.execute("discover", discoveryId, serviceInfo.getServiceType(),
+                discoverInterface);
+    }
+
+    private boolean stopServiceDiscovery(int discoveryId) {
+        return mDaemon.execute("stop-discover", discoveryId);
+    }
+
+    private boolean resolveService(int resolveId, NsdServiceInfo service) {
+        final String name = service.getServiceName();
+        final String type = service.getServiceType();
+        final Network network = service.getNetwork();
+        final int resolveInterface = getNetworkInterfaceIndex(network);
+        if (network != null && resolveInterface == IFACE_IDX_ANY) {
+            Log.e(TAG, "Interface to resolve service on not found");
+            return false;
+        }
+        return mDaemon.execute("resolve", resolveId, name, type, "local.", resolveInterface);
+    }
+
+    /**
+     * Guess the interface to use to resolve or discover a service on a specific network.
+     *
+     * This is an imperfect guess, as for example the network may be gone or not yet fully
+     * registered. This is fine as failing is correct if the network is gone, and a client
+     * attempting to resolve/discover on a network not yet setup would have a bad time anyway; also
+     * this is to support the legacy mdnsresponder implementation, which historically resolved
+     * services on an unspecified network.
+     */
+    private int getNetworkInterfaceIndex(Network network) {
+        if (network == null) return IFACE_IDX_ANY;
+
+        final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+        if (cm == null) {
+            Log.wtf(TAG, "No ConnectivityManager for resolveService");
+            return IFACE_IDX_ANY;
+        }
+        final LinkProperties lp = cm.getLinkProperties(network);
+        if (lp == null) return IFACE_IDX_ANY;
+
+        // Only resolve on non-stacked interfaces
+        final NetworkInterface iface;
+        try {
+            iface = NetworkInterface.getByName(lp.getInterfaceName());
+        } catch (SocketException e) {
+            Log.e(TAG, "Error querying interface", e);
+            return IFACE_IDX_ANY;
+        }
+
+        if (iface == null) {
+            Log.e(TAG, "Interface not found: " + lp.getInterfaceName());
+            return IFACE_IDX_ANY;
+        }
+
+        return iface.getIndex();
+    }
+
+    private boolean stopResolveService(int resolveId) {
+        return mDaemon.execute("stop-resolve", resolveId);
+    }
+
+    private boolean getAddrInfo(int resolveId, String hostname, String interfaceIdx) {
+        // interfaceIdx is always obtained (as string) from the service resolved callback
+        return mDaemon.execute("getaddrinfo", resolveId, hostname, interfaceIdx);
+    }
+
+    private boolean stopGetAddrInfo(int resolveId) {
+        return mDaemon.execute("stop-getaddrinfo", resolveId);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump " + TAG
+                    + " due to missing android.permission.DUMP permission");
+            return;
+        }
+
+        for (ClientInfo client : mClients.values()) {
+            pw.println("Client Info");
+            pw.println(client);
+        }
+
+        mNsdStateMachine.dump(fd, pw, args);
+    }
+
+    /* Information tracked per client */
+    private class ClientInfo {
+
+        private static final int MAX_LIMIT = 10;
+        private final INsdManagerCallback mCb;
+        /* Remembers a resolved service until getaddrinfo completes */
+        private NsdServiceInfo mResolvedService;
+
+        /* A map from client id to unique id sent to mDns */
+        private final SparseIntArray mClientIds = new SparseIntArray();
+
+        /* A map from client id to the type of the request we had received */
+        private final SparseIntArray mClientRequests = new SparseIntArray();
+
+        // The target SDK of this client < Build.VERSION_CODES.S
+        private boolean mIsLegacy = false;
+
+        private ClientInfo(INsdManagerCallback cb) {
+            mCb = cb;
+            if (DBG) Log.d(TAG, "New client");
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("mResolvedService ").append(mResolvedService).append("\n");
+            sb.append("mIsLegacy ").append(mIsLegacy).append("\n");
+            for(int i = 0; i< mClientIds.size(); i++) {
+                int clientID = mClientIds.keyAt(i);
+                sb.append("clientId ").append(clientID).
+                    append(" mDnsId ").append(mClientIds.valueAt(i)).
+                    append(" type ").append(mClientRequests.get(clientID)).append("\n");
+            }
+            return sb.toString();
+        }
+
+        private boolean isLegacy() {
+            return mIsLegacy;
+        }
+
+        private void setLegacy() {
+            mIsLegacy = true;
+        }
+
+        // Remove any pending requests from the global map when we get rid of a client,
+        // and send cancellations to the daemon.
+        private void expungeAllRequests() {
+            int globalId, clientId, i;
+            // TODO: to keep handler responsive, do not clean all requests for that client at once.
+            for (i = 0; i < mClientIds.size(); i++) {
+                clientId = mClientIds.keyAt(i);
+                globalId = mClientIds.valueAt(i);
+                mIdToClientInfoMap.remove(globalId);
+                if (DBG) {
+                    Log.d(TAG, "Terminating client-ID " + clientId
+                            + " global-ID " + globalId + " type " + mClientRequests.get(clientId));
+                }
+                switch (mClientRequests.get(clientId)) {
+                    case NsdManager.DISCOVER_SERVICES:
+                        stopServiceDiscovery(globalId);
+                        break;
+                    case NsdManager.RESOLVE_SERVICE:
+                        stopResolveService(globalId);
+                        break;
+                    case NsdManager.REGISTER_SERVICE:
+                        unregisterService(globalId);
+                        break;
+                    default:
+                        break;
+                }
+            }
+            mClientIds.clear();
+            mClientRequests.clear();
+        }
+
+        // mClientIds is a sparse array of listener id -> mDnsClient id.  For a given mDnsClient id,
+        // return the corresponding listener id.  mDnsClient id is also called a global id.
+        private int getClientId(final int globalId) {
+            int idx = mClientIds.indexOfValue(globalId);
+            if (idx < 0) {
+                return idx;
+            }
+            return mClientIds.keyAt(idx);
+        }
+
+        void onDiscoverServicesStarted(int listenerKey, NsdServiceInfo info) {
+            try {
+                mCb.onDiscoverServicesStarted(listenerKey, info);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onDiscoverServicesStarted", e);
+            }
+        }
+
+        void onDiscoverServicesFailed(int listenerKey, int error) {
+            try {
+                mCb.onDiscoverServicesFailed(listenerKey, error);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onDiscoverServicesFailed", e);
+            }
+        }
+
+        void onServiceFound(int listenerKey, NsdServiceInfo info) {
+            try {
+                mCb.onServiceFound(listenerKey, info);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onServiceFound(", e);
+            }
+        }
+
+        void onServiceLost(int listenerKey, NsdServiceInfo info) {
+            try {
+                mCb.onServiceLost(listenerKey, info);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onServiceLost(", e);
+            }
+        }
+
+        void onStopDiscoveryFailed(int listenerKey, int error) {
+            try {
+                mCb.onStopDiscoveryFailed(listenerKey, error);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onStopDiscoveryFailed", e);
+            }
+        }
+
+        void onStopDiscoverySucceeded(int listenerKey) {
+            try {
+                mCb.onStopDiscoverySucceeded(listenerKey);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onStopDiscoverySucceeded", e);
+            }
+        }
+
+        void onRegisterServiceFailed(int listenerKey, int error) {
+            try {
+                mCb.onRegisterServiceFailed(listenerKey, error);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onRegisterServiceFailed", e);
+            }
+        }
+
+        void onRegisterServiceSucceeded(int listenerKey, NsdServiceInfo info) {
+            try {
+                mCb.onRegisterServiceSucceeded(listenerKey, info);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onRegisterServiceSucceeded", e);
+            }
+        }
+
+        void onUnregisterServiceFailed(int listenerKey, int error) {
+            try {
+                mCb.onUnregisterServiceFailed(listenerKey, error);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onUnregisterServiceFailed", e);
+            }
+        }
+
+        void onUnregisterServiceSucceeded(int listenerKey) {
+            try {
+                mCb.onUnregisterServiceSucceeded(listenerKey);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onUnregisterServiceSucceeded", e);
+            }
+        }
+
+        void onResolveServiceFailed(int listenerKey, int error) {
+            try {
+                mCb.onResolveServiceFailed(listenerKey, error);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onResolveServiceFailed", e);
+            }
+        }
+
+        void onResolveServiceSucceeded(int listenerKey, NsdServiceInfo info) {
+            try {
+                mCb.onResolveServiceSucceeded(listenerKey, info);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling onResolveServiceSucceeded", e);
+            }
+        }
+    }
+}
diff --git a/service-t/src/com/android/server/net/BpfInterfaceMapUpdater.java b/service-t/src/com/android/server/net/BpfInterfaceMapUpdater.java
new file mode 100644
index 0000000..25c88eb
--- /dev/null
+++ b/service-t/src/com/android/server/net/BpfInterfaceMapUpdater.java
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+package com.android.server.net;
+
+import android.content.Context;
+import android.net.INetd;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.system.ErrnoException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.net.module.util.BpfMap;
+import com.android.net.module.util.IBpfMap;
+import com.android.net.module.util.InterfaceParams;
+import com.android.net.module.util.Struct.U32;
+
+/**
+ * Monitor interface added (without removed) and right interface name and its index to bpf map.
+ */
+public class BpfInterfaceMapUpdater {
+    private static final String TAG = BpfInterfaceMapUpdater.class.getSimpleName();
+    // This is current path but may be changed soon.
+    private static final String IFACE_INDEX_NAME_MAP_PATH =
+            "/sys/fs/bpf/map_netd_iface_index_name_map";
+    private final IBpfMap<U32, InterfaceMapValue> mBpfMap;
+    private final INetd mNetd;
+    private final Handler mHandler;
+    private final Dependencies mDeps;
+
+    public BpfInterfaceMapUpdater(Context ctx, Handler handler) {
+        this(ctx, handler, new Dependencies());
+    }
+
+    @VisibleForTesting
+    public BpfInterfaceMapUpdater(Context ctx, Handler handler, Dependencies deps) {
+        mDeps = deps;
+        mBpfMap = deps.getInterfaceMap();
+        mNetd = deps.getINetd(ctx);
+        mHandler = handler;
+    }
+
+    /**
+     * Dependencies of BpfInerfaceMapUpdater, for injection in tests.
+     */
+    @VisibleForTesting
+    public static class Dependencies {
+        /** Create BpfMap for updating interface and index mapping. */
+        public IBpfMap<U32, InterfaceMapValue> getInterfaceMap() {
+            try {
+                return new BpfMap<>(IFACE_INDEX_NAME_MAP_PATH, BpfMap.BPF_F_RDWR,
+                    U32.class, InterfaceMapValue.class);
+            } catch (ErrnoException e) {
+                Log.e(TAG, "Cannot create interface map: " + e);
+                return null;
+            }
+        }
+
+        /** Get InterfaceParams for giving interface name. */
+        public InterfaceParams getInterfaceParams(String ifaceName) {
+            return InterfaceParams.getByName(ifaceName);
+        }
+
+        /** Get INetd binder object. */
+        public INetd getINetd(Context ctx) {
+            return INetd.Stub.asInterface((IBinder) ctx.getSystemService(Context.NETD_SERVICE));
+        }
+    }
+
+    /**
+     * Start listening interface update event.
+     * Query current interface names before listening.
+     */
+    public void start() {
+        mHandler.post(() -> {
+            if (mBpfMap == null) {
+                Log.wtf(TAG, "Fail to start: Null bpf map");
+                return;
+            }
+
+            try {
+                // TODO: use a NetlinkMonitor and listen for RTM_NEWLINK messages instead.
+                mNetd.registerUnsolicitedEventListener(new InterfaceChangeObserver());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Unable to register netd UnsolicitedEventListener, " + e);
+            }
+
+            final String[] ifaces;
+            try {
+                // TODO: use a netlink dump to get the current interface list.
+                ifaces = mNetd.interfaceGetList();
+            } catch (RemoteException | ServiceSpecificException e) {
+                Log.wtf(TAG, "Unable to query interface names by netd, " + e);
+                return;
+            }
+
+            for (String ifaceName : ifaces) {
+                addInterface(ifaceName);
+            }
+        });
+    }
+
+    private void addInterface(String ifaceName) {
+        final InterfaceParams iface = mDeps.getInterfaceParams(ifaceName);
+        if (iface == null) {
+            Log.e(TAG, "Unable to get InterfaceParams for " + ifaceName);
+            return;
+        }
+
+        try {
+            mBpfMap.updateEntry(new U32(iface.index), new InterfaceMapValue(ifaceName));
+        } catch (ErrnoException e) {
+            Log.e(TAG, "Unable to update entry for " + ifaceName + ", " + e);
+        }
+    }
+
+    private class InterfaceChangeObserver extends BaseNetdUnsolicitedEventListener {
+        @Override
+        public void onInterfaceAdded(String ifName) {
+            mHandler.post(() -> addInterface(ifName));
+        }
+    }
+}
diff --git a/service-t/src/com/android/server/net/CookieTagMapKey.java b/service-t/src/com/android/server/net/CookieTagMapKey.java
new file mode 100644
index 0000000..443e5b3
--- /dev/null
+++ b/service-t/src/com/android/server/net/CookieTagMapKey.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package com.android.server.net;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * Key for cookie tag map.
+ */
+public class CookieTagMapKey extends Struct {
+    @Field(order = 0, type = Type.S64)
+    public final long socketCookie;
+
+    public CookieTagMapKey(final long socketCookie) {
+        this.socketCookie = socketCookie;
+    }
+}
diff --git a/service-t/src/com/android/server/net/CookieTagMapValue.java b/service-t/src/com/android/server/net/CookieTagMapValue.java
new file mode 100644
index 0000000..93b9195
--- /dev/null
+++ b/service-t/src/com/android/server/net/CookieTagMapValue.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package com.android.server.net;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * Value for cookie tag map.
+ */
+public class CookieTagMapValue extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long uid;
+
+    @Field(order = 1, type = Type.U32)
+    public final long tag;
+
+    public CookieTagMapValue(final long uid, final long tag) {
+        this.uid = uid;
+        this.tag = tag;
+    }
+}
diff --git a/service-t/src/com/android/server/net/DelayedDiskWrite.java b/service-t/src/com/android/server/net/DelayedDiskWrite.java
new file mode 100644
index 0000000..35dc455
--- /dev/null
+++ b/service-t/src/com/android/server/net/DelayedDiskWrite.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 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.server.net;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * This class provides APIs to do a delayed data write to a given {@link OutputStream}.
+ */
+public class DelayedDiskWrite {
+    private static final String TAG = "DelayedDiskWrite";
+
+    private HandlerThread mDiskWriteHandlerThread;
+    private Handler mDiskWriteHandler;
+    /* Tracks multiple writes on the same thread */
+    private int mWriteSequence = 0;
+
+    /**
+     * Used to do a delayed data write to a given {@link OutputStream}.
+     */
+    public interface Writer {
+        /**
+         * write data to a given {@link OutputStream}.
+         */
+        void onWriteCalled(DataOutputStream out) throws IOException;
+    }
+
+    /**
+     * Do a delayed data write to a given output stream opened from filePath.
+     */
+    public void write(final String filePath, final Writer w) {
+        write(filePath, w, true);
+    }
+
+    /**
+     * Do a delayed data write to a given output stream opened from filePath.
+     */
+    public void write(final String filePath, final Writer w, final boolean open) {
+        if (TextUtils.isEmpty(filePath)) {
+            throw new IllegalArgumentException("empty file path");
+        }
+
+        /* Do a delayed write to disk on a separate handler thread */
+        synchronized (this) {
+            if (++mWriteSequence == 1) {
+                mDiskWriteHandlerThread = new HandlerThread("DelayedDiskWriteThread");
+                mDiskWriteHandlerThread.start();
+                mDiskWriteHandler = new Handler(mDiskWriteHandlerThread.getLooper());
+            }
+        }
+
+        mDiskWriteHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                doWrite(filePath, w, open);
+            }
+        });
+    }
+
+    private void doWrite(String filePath, Writer w, boolean open) {
+        DataOutputStream out = null;
+        try {
+            if (open) {
+                out = new DataOutputStream(new BufferedOutputStream(
+                        new FileOutputStream(filePath)));
+            }
+            w.onWriteCalled(out);
+        } catch (IOException e) {
+            loge("Error writing data file " + filePath);
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (Exception e) { }
+            }
+
+            // Quit if no more writes sent
+            synchronized (this) {
+                if (--mWriteSequence == 0) {
+                    mDiskWriteHandler.getLooper().quit();
+                    mDiskWriteHandler = null;
+                    mDiskWriteHandlerThread = null;
+                }
+            }
+        }
+    }
+
+    private void loge(String s) {
+        Log.e(TAG, s);
+    }
+}
+
diff --git a/service-t/src/com/android/server/net/InterfaceMapValue.java b/service-t/src/com/android/server/net/InterfaceMapValue.java
new file mode 100644
index 0000000..42c0044
--- /dev/null
+++ b/service-t/src/com/android/server/net/InterfaceMapValue.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+package com.android.server.net;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * The value of bpf interface index map which is used for NetworkStatsService.
+ */
+public class InterfaceMapValue extends Struct {
+    @Field(order = 0, type = Type.ByteArray, arraysize = 16)
+    public final byte[] interfaceName;
+
+    public InterfaceMapValue(String iface) {
+        final byte[] ifaceArray = iface.getBytes();
+        interfaceName = new byte[16];
+        // All array bytes after the interface name, if any, must be 0.
+        System.arraycopy(ifaceArray, 0, interfaceName, 0, ifaceArray.length);
+    }
+}
diff --git a/service-t/src/com/android/server/net/IpConfigStore.java b/service-t/src/com/android/server/net/IpConfigStore.java
new file mode 100644
index 0000000..3a9a544
--- /dev/null
+++ b/service-t/src/com/android/server/net/IpConfigStore.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2014 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.server.net;
+
+import android.net.InetAddresses;
+import android.net.IpConfiguration;
+import android.net.IpConfiguration.IpAssignment;
+import android.net.IpConfiguration.ProxySettings;
+import android.net.LinkAddress;
+import android.net.ProxyInfo;
+import android.net.StaticIpConfiguration;
+import android.net.Uri;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.ProxyUtils;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides an API to store and manage L3 network IP configuration.
+ */
+public class IpConfigStore {
+    private static final String TAG = "IpConfigStore";
+    private static final boolean DBG = false;
+
+    protected final DelayedDiskWrite mWriter;
+
+    /* IP and proxy configuration keys */
+    protected static final String ID_KEY = "id";
+    protected static final String IP_ASSIGNMENT_KEY = "ipAssignment";
+    protected static final String LINK_ADDRESS_KEY = "linkAddress";
+    protected static final String GATEWAY_KEY = "gateway";
+    protected static final String DNS_KEY = "dns";
+    protected static final String PROXY_SETTINGS_KEY = "proxySettings";
+    protected static final String PROXY_HOST_KEY = "proxyHost";
+    protected static final String PROXY_PORT_KEY = "proxyPort";
+    protected static final String PROXY_PAC_FILE = "proxyPac";
+    protected static final String EXCLUSION_LIST_KEY = "exclusionList";
+    protected static final String EOS = "eos";
+
+    protected static final int IPCONFIG_FILE_VERSION = 3;
+
+    public IpConfigStore(DelayedDiskWrite writer) {
+        mWriter = writer;
+    }
+
+    public IpConfigStore() {
+        this(new DelayedDiskWrite());
+    }
+
+    private static boolean writeConfig(DataOutputStream out, String configKey,
+            IpConfiguration config) throws IOException {
+        return writeConfig(out, configKey, config, IPCONFIG_FILE_VERSION);
+    }
+
+    /**
+     *  Write the IP configuration with the given parameters to {@link DataOutputStream}.
+     */
+    @VisibleForTesting
+    public static boolean writeConfig(DataOutputStream out, String configKey,
+                                IpConfiguration config, int version) throws IOException {
+        boolean written = false;
+
+        try {
+            switch (config.getIpAssignment()) {
+                case STATIC:
+                    out.writeUTF(IP_ASSIGNMENT_KEY);
+                    out.writeUTF(config.getIpAssignment().toString());
+                    StaticIpConfiguration staticIpConfiguration = config.getStaticIpConfiguration();
+                    if (staticIpConfiguration != null) {
+                        if (staticIpConfiguration.getIpAddress() != null) {
+                            LinkAddress ipAddress = staticIpConfiguration.getIpAddress();
+                            out.writeUTF(LINK_ADDRESS_KEY);
+                            out.writeUTF(ipAddress.getAddress().getHostAddress());
+                            out.writeInt(ipAddress.getPrefixLength());
+                        }
+                        if (staticIpConfiguration.getGateway() != null) {
+                            out.writeUTF(GATEWAY_KEY);
+                            out.writeInt(0);  // Default route.
+                            out.writeInt(1);  // Have a gateway.
+                            out.writeUTF(staticIpConfiguration.getGateway().getHostAddress());
+                        }
+                        for (InetAddress inetAddr : staticIpConfiguration.getDnsServers()) {
+                            out.writeUTF(DNS_KEY);
+                            out.writeUTF(inetAddr.getHostAddress());
+                        }
+                    }
+                    written = true;
+                    break;
+                case DHCP:
+                    out.writeUTF(IP_ASSIGNMENT_KEY);
+                    out.writeUTF(config.getIpAssignment().toString());
+                    written = true;
+                    break;
+                case UNASSIGNED:
+                /* Ignore */
+                    break;
+                default:
+                    loge("Ignore invalid ip assignment while writing");
+                    break;
+            }
+
+            switch (config.getProxySettings()) {
+                case STATIC:
+                    ProxyInfo proxyProperties = config.getHttpProxy();
+                    String exclusionList = ProxyUtils.exclusionListAsString(
+                            proxyProperties.getExclusionList());
+                    out.writeUTF(PROXY_SETTINGS_KEY);
+                    out.writeUTF(config.getProxySettings().toString());
+                    out.writeUTF(PROXY_HOST_KEY);
+                    out.writeUTF(proxyProperties.getHost());
+                    out.writeUTF(PROXY_PORT_KEY);
+                    out.writeInt(proxyProperties.getPort());
+                    if (exclusionList != null) {
+                        out.writeUTF(EXCLUSION_LIST_KEY);
+                        out.writeUTF(exclusionList);
+                    }
+                    written = true;
+                    break;
+                case PAC:
+                    ProxyInfo proxyPacProperties = config.getHttpProxy();
+                    out.writeUTF(PROXY_SETTINGS_KEY);
+                    out.writeUTF(config.getProxySettings().toString());
+                    out.writeUTF(PROXY_PAC_FILE);
+                    out.writeUTF(proxyPacProperties.getPacFileUrl().toString());
+                    written = true;
+                    break;
+                case NONE:
+                    out.writeUTF(PROXY_SETTINGS_KEY);
+                    out.writeUTF(config.getProxySettings().toString());
+                    written = true;
+                    break;
+                case UNASSIGNED:
+                    /* Ignore */
+                    break;
+                default:
+                    loge("Ignore invalid proxy settings while writing");
+                    break;
+            }
+
+            if (written) {
+                out.writeUTF(ID_KEY);
+                if (version < 3) {
+                    out.writeInt(Integer.valueOf(configKey));
+                } else {
+                    out.writeUTF(configKey);
+                }
+            }
+        } catch (NullPointerException e) {
+            loge("Failure in writing " + config + e);
+        }
+        out.writeUTF(EOS);
+
+        return written;
+    }
+
+    /**
+     * @deprecated use {@link #writeIpConfigurations(String, ArrayMap)} instead.
+     * New method uses string as network identifier which could be interface name or MAC address or
+     * other token.
+     */
+    @Deprecated
+    public void writeIpAndProxyConfigurationsToFile(String filePath,
+                                              final SparseArray<IpConfiguration> networks) {
+        mWriter.write(filePath, out -> {
+            out.writeInt(IPCONFIG_FILE_VERSION);
+            for (int i = 0; i < networks.size(); i++) {
+                writeConfig(out, String.valueOf(networks.keyAt(i)), networks.valueAt(i));
+            }
+        });
+    }
+
+    /**
+     *  Write the IP configuration associated to the target networks to the destination path.
+     */
+    public void writeIpConfigurations(String filePath,
+                                      ArrayMap<String, IpConfiguration> networks) {
+        mWriter.write(filePath, out -> {
+            out.writeInt(IPCONFIG_FILE_VERSION);
+            for (int i = 0; i < networks.size(); i++) {
+                writeConfig(out, networks.keyAt(i), networks.valueAt(i));
+            }
+        });
+    }
+
+    /**
+     * Read the IP configuration from the destination path to {@link BufferedInputStream}.
+     */
+    public static ArrayMap<String, IpConfiguration> readIpConfigurations(String filePath) {
+        BufferedInputStream bufferedInputStream;
+        try {
+            bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
+        } catch (FileNotFoundException e) {
+            // Return an empty array here because callers expect an empty array when the file is
+            // not present.
+            loge("Error opening configuration file: " + e);
+            return new ArrayMap<>(0);
+        }
+        return readIpConfigurations(bufferedInputStream);
+    }
+
+    /** @deprecated use {@link #readIpConfigurations(String)} */
+    @Deprecated
+    public static SparseArray<IpConfiguration> readIpAndProxyConfigurations(String filePath) {
+        BufferedInputStream bufferedInputStream;
+        try {
+            bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
+        } catch (FileNotFoundException e) {
+            // Return an empty array here because callers expect an empty array when the file is
+            // not present.
+            loge("Error opening configuration file: " + e);
+            return new SparseArray<>();
+        }
+        return readIpAndProxyConfigurations(bufferedInputStream);
+    }
+
+    /** @deprecated use {@link #readIpConfigurations(InputStream)} */
+    @Deprecated
+    public static SparseArray<IpConfiguration> readIpAndProxyConfigurations(
+            InputStream inputStream) {
+        ArrayMap<String, IpConfiguration> networks = readIpConfigurations(inputStream);
+        if (networks == null) {
+            return null;
+        }
+
+        SparseArray<IpConfiguration> networksById = new SparseArray<>();
+        for (int i = 0; i < networks.size(); i++) {
+            int id = Integer.valueOf(networks.keyAt(i));
+            networksById.put(id, networks.valueAt(i));
+        }
+
+        return networksById;
+    }
+
+    /** Returns a map of network identity token and {@link IpConfiguration}. */
+    public static ArrayMap<String, IpConfiguration> readIpConfigurations(
+            InputStream inputStream) {
+        ArrayMap<String, IpConfiguration> networks = new ArrayMap<>();
+        DataInputStream in = null;
+        try {
+            in = new DataInputStream(inputStream);
+
+            int version = in.readInt();
+            if (version != 3 && version != 2 && version != 1) {
+                loge("Bad version on IP configuration file, ignore read");
+                return null;
+            }
+
+            while (true) {
+                String uniqueToken = null;
+                // Default is DHCP with no proxy
+                IpAssignment ipAssignment = IpAssignment.DHCP;
+                ProxySettings proxySettings = ProxySettings.NONE;
+                StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+                LinkAddress linkAddress = null;
+                InetAddress gatewayAddress = null;
+                String proxyHost = null;
+                String pacFileUrl = null;
+                int proxyPort = -1;
+                String exclusionList = null;
+                String key;
+                final List<InetAddress> dnsServers = new ArrayList<>();
+
+                do {
+                    key = in.readUTF();
+                    try {
+                        if (key.equals(ID_KEY)) {
+                            if (version < 3) {
+                                int id = in.readInt();
+                                uniqueToken = String.valueOf(id);
+                            } else {
+                                uniqueToken = in.readUTF();
+                            }
+                        } else if (key.equals(IP_ASSIGNMENT_KEY)) {
+                            ipAssignment = IpAssignment.valueOf(in.readUTF());
+                        } else if (key.equals(LINK_ADDRESS_KEY)) {
+                            LinkAddress parsedLinkAddress =
+                                    new LinkAddress(
+                                            InetAddresses.parseNumericAddress(in.readUTF()),
+                                            in.readInt());
+                            if (parsedLinkAddress.getAddress() instanceof Inet4Address
+                                    && linkAddress == null) {
+                                linkAddress = parsedLinkAddress;
+                            } else {
+                                loge("Non-IPv4 or duplicate address: " + parsedLinkAddress);
+                            }
+                        } else if (key.equals(GATEWAY_KEY)) {
+                            LinkAddress dest = null;
+                            InetAddress gateway = null;
+                            if (version == 1) {
+                                // only supported default gateways - leave the dest/prefix empty
+                                gateway = InetAddresses.parseNumericAddress(in.readUTF());
+                                if (gatewayAddress == null) {
+                                    gatewayAddress = gateway;
+                                } else {
+                                    loge("Duplicate gateway: " + gateway.getHostAddress());
+                                }
+                            } else {
+                                if (in.readInt() == 1) {
+                                    dest =
+                                            new LinkAddress(
+                                                    InetAddresses.parseNumericAddress(in.readUTF()),
+                                                    in.readInt());
+                                }
+                                if (in.readInt() == 1) {
+                                    gateway = InetAddresses.parseNumericAddress(in.readUTF());
+                                }
+                                // If the destination is a default IPv4 route, use the gateway
+                                // address unless already set. If there is no destination, assume
+                                // it is default route and use the gateway address in all cases.
+                                if (dest == null) {
+                                    gatewayAddress = gateway;
+                                } else if (dest.getAddress() instanceof Inet4Address
+                                        && dest.getPrefixLength() == 0 && gatewayAddress == null) {
+                                    gatewayAddress = gateway;
+                                } else {
+                                    loge("Non-IPv4 default or duplicate route: "
+                                            + dest.getAddress());
+                                }
+                            }
+                        } else if (key.equals(DNS_KEY)) {
+                            dnsServers.add(InetAddresses.parseNumericAddress(in.readUTF()));
+                        } else if (key.equals(PROXY_SETTINGS_KEY)) {
+                            proxySettings = ProxySettings.valueOf(in.readUTF());
+                        } else if (key.equals(PROXY_HOST_KEY)) {
+                            proxyHost = in.readUTF();
+                        } else if (key.equals(PROXY_PORT_KEY)) {
+                            proxyPort = in.readInt();
+                        } else if (key.equals(PROXY_PAC_FILE)) {
+                            pacFileUrl = in.readUTF();
+                        } else if (key.equals(EXCLUSION_LIST_KEY)) {
+                            exclusionList = in.readUTF();
+                        } else if (key.equals(EOS)) {
+                            break;
+                        } else {
+                            loge("Ignore unknown key " + key + "while reading");
+                        }
+                    } catch (IllegalArgumentException e) {
+                        loge("Ignore invalid address while reading" + e);
+                    }
+                } while (true);
+
+                staticIpConfiguration = new StaticIpConfiguration.Builder()
+                    .setIpAddress(linkAddress)
+                    .setGateway(gatewayAddress)
+                    .setDnsServers(dnsServers)
+                    .build();
+
+                if (uniqueToken != null) {
+                    IpConfiguration config = new IpConfiguration();
+                    networks.put(uniqueToken, config);
+
+                    switch (ipAssignment) {
+                        case STATIC:
+                            config.setStaticIpConfiguration(staticIpConfiguration);
+                            config.setIpAssignment(ipAssignment);
+                            break;
+                        case DHCP:
+                            config.setIpAssignment(ipAssignment);
+                            break;
+                        case UNASSIGNED:
+                            loge("BUG: Found UNASSIGNED IP on file, use DHCP");
+                            config.setIpAssignment(IpAssignment.DHCP);
+                            break;
+                        default:
+                            loge("Ignore invalid ip assignment while reading.");
+                            config.setIpAssignment(IpAssignment.UNASSIGNED);
+                            break;
+                    }
+
+                    switch (proxySettings) {
+                        case STATIC:
+                            ProxyInfo proxyInfo = ProxyInfo.buildDirectProxy(proxyHost, proxyPort,
+                                    ProxyUtils.exclusionStringAsList(exclusionList));
+                            config.setProxySettings(proxySettings);
+                            config.setHttpProxy(proxyInfo);
+                            break;
+                        case PAC:
+                            ProxyInfo proxyPacProperties =
+                                    ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
+                            config.setProxySettings(proxySettings);
+                            config.setHttpProxy(proxyPacProperties);
+                            break;
+                        case NONE:
+                            config.setProxySettings(proxySettings);
+                            break;
+                        case UNASSIGNED:
+                            loge("BUG: Found UNASSIGNED proxy on file, use NONE");
+                            config.setProxySettings(ProxySettings.NONE);
+                            break;
+                        default:
+                            loge("Ignore invalid proxy settings while reading");
+                            config.setProxySettings(ProxySettings.UNASSIGNED);
+                            break;
+                    }
+                } else {
+                    if (DBG) log("Missing id while parsing configuration");
+                }
+            }
+        } catch (EOFException ignore) {
+        } catch (IOException e) {
+            loge("Error parsing configuration: " + e);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (Exception e) { }
+            }
+        }
+
+        return networks;
+    }
+
+    protected static void loge(String s) {
+        Log.e(TAG, s);
+    }
+
+    protected static void log(String s) {
+        Log.d(TAG, s);
+    }
+}
diff --git a/service-t/src/com/android/server/net/NetworkStatsFactory.java b/service-t/src/com/android/server/net/NetworkStatsFactory.java
new file mode 100644
index 0000000..3b93f1a
--- /dev/null
+++ b/service-t/src/com/android/server/net/NetworkStatsFactory.java
@@ -0,0 +1,505 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.net;
+
+import static android.net.NetworkStats.INTERFACES_ALL;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.TAG_ALL;
+import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkStats.UID_ALL;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.net.NetworkStats;
+import android.net.UnderlyingNetworkInfo;
+import android.os.ServiceSpecificException;
+import android.os.StrictMode;
+import android.os.SystemClock;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ProcFileReader;
+import com.android.net.module.util.CollectionUtils;
+import com.android.server.BpfNetMaps;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Creates {@link NetworkStats} instances by parsing various {@code /proc/}
+ * files as needed.
+ *
+ * @hide
+ */
+public class NetworkStatsFactory {
+    static {
+        System.loadLibrary("service-connectivity");
+    }
+
+    private static final String TAG = "NetworkStatsFactory";
+
+    private static final boolean USE_NATIVE_PARSING = true;
+    private static final boolean VALIDATE_NATIVE_STATS = false;
+
+    /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */
+    private final File mStatsXtIfaceAll;
+    /** Path to {@code /proc/net/xt_qtaguid/iface_stat_fmt}. */
+    private final File mStatsXtIfaceFmt;
+    /** Path to {@code /proc/net/xt_qtaguid/stats}. */
+    private final File mStatsXtUid;
+
+    private final boolean mUseBpfStats;
+
+    private final Context mContext;
+
+    private final BpfNetMaps mBpfNetMaps;
+
+    /**
+     * Guards persistent data access in this class
+     *
+     * <p>In order to prevent deadlocks, critical sections protected by this lock SHALL NOT call out
+     * to other code that will acquire other locks within the system server. See b/134244752.
+     */
+    private final Object mPersistentDataLock = new Object();
+
+    /** Set containing info about active VPNs and their underlying networks. */
+    private volatile UnderlyingNetworkInfo[] mUnderlyingNetworkInfos = new UnderlyingNetworkInfo[0];
+
+    // A persistent snapshot of cumulative stats since device start
+    @GuardedBy("mPersistentDataLock")
+    private NetworkStats mPersistSnapshot;
+
+    // The persistent snapshot of tun and 464xlat adjusted stats since device start
+    @GuardedBy("mPersistentDataLock")
+    private NetworkStats mTunAnd464xlatAdjustedStats;
+
+    /**
+     * (Stacked interface) -> (base interface) association for all connected ifaces since boot.
+     *
+     * Because counters must never roll backwards, once a given interface is stacked on top of an
+     * underlying interface, the stacked interface can never be stacked on top of
+     * another interface. */
+    private final ConcurrentHashMap<String, String> mStackedIfaces
+            = new ConcurrentHashMap<>();
+
+    /** Informs the factory of a new stacked interface. */
+    public void noteStackedIface(String stackedIface, String baseIface) {
+        if (stackedIface != null && baseIface != null) {
+            mStackedIfaces.put(stackedIface, baseIface);
+        }
+    }
+
+    /**
+     * Set active VPN information for data usage migration purposes
+     *
+     * <p>Traffic on TUN-based VPNs inherently all appear to be originated from the VPN providing
+     * app's UID. This method is used to support migration of VPN data usage, ensuring data is
+     * accurately billed to the real owner of the traffic.
+     *
+     * @param vpnArray The snapshot of the currently-running VPNs.
+     */
+    public void updateUnderlyingNetworkInfos(UnderlyingNetworkInfo[] vpnArray) {
+        mUnderlyingNetworkInfos = vpnArray.clone();
+    }
+
+    /**
+     * Get a set of interfaces containing specified ifaces and stacked interfaces.
+     *
+     * <p>The added stacked interfaces are ifaces stacked on top of the specified ones, or ifaces
+     * on which the specified ones are stacked. Stacked interfaces are those noted with
+     * {@link #noteStackedIface(String, String)}, but only interfaces noted before this method
+     * is called are guaranteed to be included.
+     */
+    public String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) {
+        if (requiredIfaces == NetworkStats.INTERFACES_ALL) {
+            return null;
+        }
+
+        HashSet<String> relatedIfaces = new HashSet<>(Arrays.asList(requiredIfaces));
+        // ConcurrentHashMap's EntrySet iterators are "guaranteed to traverse
+        // elements as they existed upon construction exactly once, and may
+        // (but are not guaranteed to) reflect any modifications subsequent to construction".
+        // This is enough here.
+        for (Map.Entry<String, String> entry : mStackedIfaces.entrySet()) {
+            if (relatedIfaces.contains(entry.getKey())) {
+                relatedIfaces.add(entry.getValue());
+            } else if (relatedIfaces.contains(entry.getValue())) {
+                relatedIfaces.add(entry.getKey());
+            }
+        }
+
+        String[] outArray = new String[relatedIfaces.size()];
+        return relatedIfaces.toArray(outArray);
+    }
+
+    /**
+     * Applies 464xlat adjustments with ifaces noted with {@link #noteStackedIface(String, String)}.
+     * @see NetworkStats#apply464xlatAdjustments(NetworkStats, NetworkStats, Map)
+     */
+    public void apply464xlatAdjustments(NetworkStats baseTraffic, NetworkStats stackedTraffic) {
+        NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, mStackedIfaces);
+    }
+
+    public NetworkStatsFactory(@NonNull Context ctx) {
+        this(ctx, new File("/proc/"), true);
+    }
+
+    @VisibleForTesting
+    public NetworkStatsFactory(@NonNull Context ctx, File procRoot, boolean useBpfStats) {
+        mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all");
+        mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
+        mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
+        mUseBpfStats = useBpfStats;
+        mBpfNetMaps = new BpfNetMaps();
+        synchronized (mPersistentDataLock) {
+            mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+            mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+        }
+        mContext = ctx;
+    }
+
+    public NetworkStats readBpfNetworkStatsDev() throws IOException {
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
+        if (nativeReadNetworkStatsDev(stats) != 0) {
+            throw new IOException("Failed to parse bpf iface stats");
+        }
+        return stats;
+    }
+
+    /**
+     * Parse and return interface-level summary {@link NetworkStats} measured
+     * using {@code /proc/net/dev} style hooks, which may include non IP layer
+     * traffic. Values monotonically increase since device boot, and may include
+     * details about inactive interfaces.
+     *
+     * @throws IllegalStateException when problem parsing stats.
+     */
+    public NetworkStats readNetworkStatsSummaryDev() throws IOException {
+
+        // Return xt_bpf stats if switched to bpf module.
+        if (mUseBpfStats)
+            return readBpfNetworkStatsDev();
+
+        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
+        final NetworkStats.Entry entry = new NetworkStats.Entry();
+
+        ProcFileReader reader = null;
+        try {
+            reader = new ProcFileReader(new FileInputStream(mStatsXtIfaceAll));
+
+            while (reader.hasMoreData()) {
+                entry.iface = reader.nextString();
+                entry.uid = UID_ALL;
+                entry.set = SET_ALL;
+                entry.tag = TAG_NONE;
+
+                final boolean active = reader.nextInt() != 0;
+
+                // always include snapshot values
+                entry.rxBytes = reader.nextLong();
+                entry.rxPackets = reader.nextLong();
+                entry.txBytes = reader.nextLong();
+                entry.txPackets = reader.nextLong();
+
+                // fold in active numbers, but only when active
+                if (active) {
+                    entry.rxBytes += reader.nextLong();
+                    entry.rxPackets += reader.nextLong();
+                    entry.txBytes += reader.nextLong();
+                    entry.txPackets += reader.nextLong();
+                }
+
+                stats.insertEntry(entry);
+                reader.finishLine();
+            }
+        } catch (NullPointerException|NumberFormatException e) {
+            throw protocolExceptionWithCause("problem parsing stats", e);
+        } finally {
+            IoUtils.closeQuietly(reader);
+            StrictMode.setThreadPolicy(savedPolicy);
+        }
+        return stats;
+    }
+
+    /**
+     * Parse and return interface-level summary {@link NetworkStats}. Designed
+     * to return only IP layer traffic. Values monotonically increase since
+     * device boot, and may include details about inactive interfaces.
+     *
+     * @throws IllegalStateException when problem parsing stats.
+     */
+    public NetworkStats readNetworkStatsSummaryXt() throws IOException {
+
+        // Return xt_bpf stats if qtaguid  module is replaced.
+        if (mUseBpfStats)
+            return readBpfNetworkStatsDev();
+
+        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
+        // return null when kernel doesn't support
+        if (!mStatsXtIfaceFmt.exists()) return null;
+
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
+        final NetworkStats.Entry entry = new NetworkStats.Entry();
+
+        ProcFileReader reader = null;
+        try {
+            // open and consume header line
+            reader = new ProcFileReader(new FileInputStream(mStatsXtIfaceFmt));
+            reader.finishLine();
+
+            while (reader.hasMoreData()) {
+                entry.iface = reader.nextString();
+                entry.uid = UID_ALL;
+                entry.set = SET_ALL;
+                entry.tag = TAG_NONE;
+
+                entry.rxBytes = reader.nextLong();
+                entry.rxPackets = reader.nextLong();
+                entry.txBytes = reader.nextLong();
+                entry.txPackets = reader.nextLong();
+
+                stats.insertEntry(entry);
+                reader.finishLine();
+            }
+        } catch (NullPointerException|NumberFormatException e) {
+            throw protocolExceptionWithCause("problem parsing stats", e);
+        } finally {
+            IoUtils.closeQuietly(reader);
+            StrictMode.setThreadPolicy(savedPolicy);
+        }
+        return stats;
+    }
+
+    public NetworkStats readNetworkStatsDetail() throws IOException {
+        return readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
+    }
+
+    @GuardedBy("mPersistentDataLock")
+    private void requestSwapActiveStatsMapLocked() throws IOException {
+        try {
+            // Do a active map stats swap. Once the swap completes, this code
+            // can read and clean the inactive map without races.
+            mBpfNetMaps.swapActiveStatsMap();
+        } catch (ServiceSpecificException e) {
+            throw new IOException(e);
+        }
+    }
+
+    /**
+     * Reads the detailed UID stats based on the provided parameters
+     *
+     * @param limitUid the UID to limit this query to
+     * @param limitIfaces the interfaces to limit this query to. Use {@link
+     *     NetworkStats.INTERFACES_ALL} to select all interfaces
+     * @param limitTag the tags to limit this query to
+     * @return the NetworkStats instance containing network statistics at the present time.
+     */
+    public NetworkStats readNetworkStatsDetail(
+            int limitUid, String[] limitIfaces, int limitTag) throws IOException {
+        // In order to prevent deadlocks, anything protected by this lock MUST NOT call out to other
+        // code that will acquire other locks within the system server. See b/134244752.
+        synchronized (mPersistentDataLock) {
+            // Take a reference. If this gets swapped out, we still have the old reference.
+            final UnderlyingNetworkInfo[] vpnArray = mUnderlyingNetworkInfos;
+            // Take a defensive copy. mPersistSnapshot is mutated in some cases below
+            final NetworkStats prev = mPersistSnapshot.clone();
+
+            if (USE_NATIVE_PARSING) {
+                final NetworkStats stats =
+                        new NetworkStats(SystemClock.elapsedRealtime(), 0 /* initialSize */);
+                if (mUseBpfStats) {
+                    requestSwapActiveStatsMapLocked();
+                    // Stats are always read from the inactive map, so they must be read after the
+                    // swap
+                    if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), UID_ALL,
+                            INTERFACES_ALL, TAG_ALL, mUseBpfStats) != 0) {
+                        throw new IOException("Failed to parse network stats");
+                    }
+
+                    // BPF stats are incremental; fold into mPersistSnapshot.
+                    mPersistSnapshot.setElapsedRealtime(stats.getElapsedRealtime());
+                    mPersistSnapshot.combineAllValues(stats);
+                } else {
+                    if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), UID_ALL,
+                            INTERFACES_ALL, TAG_ALL, mUseBpfStats) != 0) {
+                        throw new IOException("Failed to parse network stats");
+                    }
+                    if (VALIDATE_NATIVE_STATS) {
+                        final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid,
+                                UID_ALL, INTERFACES_ALL, TAG_ALL);
+                        assertEquals(javaStats, stats);
+                    }
+
+                    mPersistSnapshot = stats;
+                }
+            } else {
+                mPersistSnapshot = javaReadNetworkStatsDetail(mStatsXtUid, UID_ALL, INTERFACES_ALL,
+                        TAG_ALL);
+            }
+
+            NetworkStats adjustedStats = adjustForTunAnd464Xlat(mPersistSnapshot, prev, vpnArray);
+
+            // Filter return values
+            adjustedStats.filter(limitUid, limitIfaces, limitTag);
+            return adjustedStats;
+        }
+    }
+
+    @GuardedBy("mPersistentDataLock")
+    private NetworkStats adjustForTunAnd464Xlat(NetworkStats uidDetailStats,
+            NetworkStats previousStats, UnderlyingNetworkInfo[] vpnArray) {
+        // Calculate delta from last snapshot
+        final NetworkStats delta = uidDetailStats.subtract(previousStats);
+
+        // Apply 464xlat adjustments before VPN adjustments. If VPNs are using v4 on a v6 only
+        // network, the overhead is their fault.
+        // No locking here: apply464xlatAdjustments behaves fine with an add-only
+        // ConcurrentHashMap.
+        delta.apply464xlatAdjustments(mStackedIfaces);
+
+        // Migrate data usage over a VPN to the TUN network.
+        for (UnderlyingNetworkInfo info : vpnArray) {
+            delta.migrateTun(info.getOwnerUid(), info.getInterface(),
+                    info.getUnderlyingInterfaces());
+            // Filter out debug entries as that may lead to over counting.
+            delta.filterDebugEntries();
+        }
+
+        // Update mTunAnd464xlatAdjustedStats with migrated delta.
+        mTunAnd464xlatAdjustedStats.combineAllValues(delta);
+        mTunAnd464xlatAdjustedStats.setElapsedRealtime(uidDetailStats.getElapsedRealtime());
+
+        return mTunAnd464xlatAdjustedStats.clone();
+    }
+
+    /**
+     * Parse and return {@link NetworkStats} with UID-level details. Values are
+     * expected to monotonically increase since device boot.
+     */
+    @VisibleForTesting
+    public static NetworkStats javaReadNetworkStatsDetail(File detailPath, int limitUid,
+            String[] limitIfaces, int limitTag)
+            throws IOException {
+        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 24);
+        final NetworkStats.Entry entry = new NetworkStats.Entry();
+
+        int idx = 1;
+        int lastIdx = 1;
+
+        ProcFileReader reader = null;
+        try {
+            // open and consume header line
+            reader = new ProcFileReader(new FileInputStream(detailPath));
+            reader.finishLine();
+
+            while (reader.hasMoreData()) {
+                idx = reader.nextInt();
+                if (idx != lastIdx + 1) {
+                    throw new ProtocolException(
+                            "inconsistent idx=" + idx + " after lastIdx=" + lastIdx);
+                }
+                lastIdx = idx;
+
+                entry.iface = reader.nextString();
+                entry.tag = kernelToTag(reader.nextString());
+                entry.uid = reader.nextInt();
+                entry.set = reader.nextInt();
+                entry.rxBytes = reader.nextLong();
+                entry.rxPackets = reader.nextLong();
+                entry.txBytes = reader.nextLong();
+                entry.txPackets = reader.nextLong();
+
+                if ((limitIfaces == null || CollectionUtils.contains(limitIfaces, entry.iface))
+                        && (limitUid == UID_ALL || limitUid == entry.uid)
+                        && (limitTag == TAG_ALL || limitTag == entry.tag)) {
+                    stats.insertEntry(entry);
+                }
+
+                reader.finishLine();
+            }
+        } catch (NullPointerException|NumberFormatException e) {
+            throw protocolExceptionWithCause("problem parsing idx " + idx, e);
+        } finally {
+            IoUtils.closeQuietly(reader);
+            StrictMode.setThreadPolicy(savedPolicy);
+        }
+
+        return stats;
+    }
+
+    public void assertEquals(NetworkStats expected, NetworkStats actual) {
+        if (expected.size() != actual.size()) {
+            throw new AssertionError(
+                    "Expected size " + expected.size() + ", actual size " + actual.size());
+        }
+
+        NetworkStats.Entry expectedRow = null;
+        NetworkStats.Entry actualRow = null;
+        for (int i = 0; i < expected.size(); i++) {
+            expectedRow = expected.getValues(i, expectedRow);
+            actualRow = actual.getValues(i, actualRow);
+            if (!expectedRow.equals(actualRow)) {
+                throw new AssertionError(
+                        "Expected row " + i + ": " + expectedRow + ", actual row " + actualRow);
+            }
+        }
+    }
+
+    /**
+     * Convert {@code /proc/} tag format to {@link Integer}. Assumes incoming
+     * format like {@code 0x7fffffff00000000}.
+     */
+    public static int kernelToTag(String string) {
+        int length = string.length();
+        if (length > 10) {
+            return Long.decode(string.substring(0, length - 8)).intValue();
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Parse statistics from file into given {@link NetworkStats} object. Values
+     * are expected to monotonically increase since device boot.
+     */
+    @VisibleForTesting
+    public static native int nativeReadNetworkStatsDetail(NetworkStats stats, String path,
+        int limitUid, String[] limitIfaces, int limitTag, boolean useBpfStats);
+
+    @VisibleForTesting
+    public static native int nativeReadNetworkStatsDev(NetworkStats stats);
+
+    private static ProtocolException protocolExceptionWithCause(String message, Throwable cause) {
+        ProtocolException pe = new ProtocolException(message);
+        pe.initCause(cause);
+        return pe;
+    }
+}
diff --git a/service-t/src/com/android/server/net/NetworkStatsObservers.java b/service-t/src/com/android/server/net/NetworkStatsObservers.java
new file mode 100644
index 0000000..fdfc893
--- /dev/null
+++ b/service-t/src/com/android/server/net/NetworkStatsObservers.java
@@ -0,0 +1,451 @@
+/*
+ * 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.
+ */
+
+package com.android.server.net;
+
+import static android.app.usage.NetworkStatsManager.MIN_THRESHOLD_BYTES;
+
+import android.app.usage.NetworkStatsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.DataUsageRequest;
+import android.net.NetworkIdentitySet;
+import android.net.NetworkStack;
+import android.net.NetworkStats;
+import android.net.NetworkStatsAccess;
+import android.net.NetworkStatsCollection;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.netstats.IUsageCallback;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Manages observers of {@link NetworkStats}. Allows observers to be notified when
+ * data usage has been reported in {@link NetworkStatsService}. An observer can set
+ * a threshold of how much data it cares about to be notified.
+ */
+class NetworkStatsObservers {
+    private static final String TAG = "NetworkStatsObservers";
+    private static final boolean LOGV = false;
+
+    private static final int MSG_REGISTER = 1;
+    private static final int MSG_UNREGISTER = 2;
+    private static final int MSG_UPDATE_STATS = 3;
+
+    // All access to this map must be done from the handler thread.
+    // indexed by DataUsageRequest#requestId
+    private final SparseArray<RequestInfo> mDataUsageRequests = new SparseArray<>();
+
+    // Sequence number of DataUsageRequests
+    private final AtomicInteger mNextDataUsageRequestId = new AtomicInteger();
+
+    // Lazily instantiated when an observer is registered.
+    private volatile Handler mHandler;
+
+    /**
+     * Creates a wrapper that contains the caller context and a normalized request.
+     * The request should be returned to the caller app, and the wrapper should be sent to this
+     * object through #addObserver by the service handler.
+     *
+     * <p>It will register the observer asynchronously, so it is safe to call from any thread.
+     *
+     * @return the normalized request wrapped within {@link RequestInfo}.
+     */
+    public DataUsageRequest register(Context context, DataUsageRequest inputRequest,
+            IUsageCallback callback, int callingUid, @NetworkStatsAccess.Level int accessLevel) {
+        DataUsageRequest request = buildRequest(context, inputRequest, callingUid);
+        RequestInfo requestInfo = buildRequestInfo(request, callback, callingUid,
+                accessLevel);
+
+        if (LOGV) Log.v(TAG, "Registering observer for " + request);
+        getHandler().sendMessage(mHandler.obtainMessage(MSG_REGISTER, requestInfo));
+        return request;
+    }
+
+    /**
+     * Unregister a data usage observer.
+     *
+     * <p>It will unregister the observer asynchronously, so it is safe to call from any thread.
+     */
+    public void unregister(DataUsageRequest request, int callingUid) {
+        getHandler().sendMessage(mHandler.obtainMessage(MSG_UNREGISTER, callingUid, 0 /* ignore */,
+                request));
+    }
+
+    /**
+     * Updates data usage statistics of registered observers and notifies if limits are reached.
+     *
+     * <p>It will update stats asynchronously, so it is safe to call from any thread.
+     */
+    public void updateStats(NetworkStats xtSnapshot, NetworkStats uidSnapshot,
+                ArrayMap<String, NetworkIdentitySet> activeIfaces,
+                ArrayMap<String, NetworkIdentitySet> activeUidIfaces,
+                long currentTime) {
+        StatsContext statsContext = new StatsContext(xtSnapshot, uidSnapshot, activeIfaces,
+                activeUidIfaces, currentTime);
+        getHandler().sendMessage(mHandler.obtainMessage(MSG_UPDATE_STATS, statsContext));
+    }
+
+    private Handler getHandler() {
+        if (mHandler == null) {
+            synchronized (this) {
+                if (mHandler == null) {
+                    if (LOGV) Log.v(TAG, "Creating handler");
+                    mHandler = new Handler(getHandlerLooperLocked(), mHandlerCallback);
+                }
+            }
+        }
+        return mHandler;
+    }
+
+    @VisibleForTesting
+    protected Looper getHandlerLooperLocked() {
+        HandlerThread handlerThread = new HandlerThread(TAG);
+        handlerThread.start();
+        return handlerThread.getLooper();
+    }
+
+    private Handler.Callback mHandlerCallback = new Handler.Callback() {
+        @Override
+        public boolean handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_REGISTER: {
+                    handleRegister((RequestInfo) msg.obj);
+                    return true;
+                }
+                case MSG_UNREGISTER: {
+                    handleUnregister((DataUsageRequest) msg.obj, msg.arg1 /* callingUid */);
+                    return true;
+                }
+                case MSG_UPDATE_STATS: {
+                    handleUpdateStats((StatsContext) msg.obj);
+                    return true;
+                }
+                default: {
+                    return false;
+                }
+            }
+        }
+    };
+
+    /**
+     * Adds a {@link RequestInfo} as an observer.
+     * Should only be called from the handler thread otherwise there will be a race condition
+     * on mDataUsageRequests.
+     */
+    private void handleRegister(RequestInfo requestInfo) {
+        mDataUsageRequests.put(requestInfo.mRequest.requestId, requestInfo);
+    }
+
+    /**
+     * Removes a {@link DataUsageRequest} if the calling uid is authorized.
+     * Should only be called from the handler thread otherwise there will be a race condition
+     * on mDataUsageRequests.
+     */
+    private void handleUnregister(DataUsageRequest request, int callingUid) {
+        RequestInfo requestInfo;
+        requestInfo = mDataUsageRequests.get(request.requestId);
+        if (requestInfo == null) {
+            if (LOGV) Log.v(TAG, "Trying to unregister unknown request " + request);
+            return;
+        }
+        if (Process.SYSTEM_UID != callingUid && requestInfo.mCallingUid != callingUid) {
+            Log.w(TAG, "Caller uid " + callingUid + " is not owner of " + request);
+            return;
+        }
+
+        if (LOGV) Log.v(TAG, "Unregistering " + request);
+        mDataUsageRequests.remove(request.requestId);
+        requestInfo.unlinkDeathRecipient();
+        requestInfo.callCallback(NetworkStatsManager.CALLBACK_RELEASED);
+    }
+
+    private void handleUpdateStats(StatsContext statsContext) {
+        if (mDataUsageRequests.size() == 0) {
+            return;
+        }
+
+        for (int i = 0; i < mDataUsageRequests.size(); i++) {
+            RequestInfo requestInfo = mDataUsageRequests.valueAt(i);
+            requestInfo.updateStats(statsContext);
+        }
+    }
+
+    private DataUsageRequest buildRequest(Context context, DataUsageRequest request,
+                int callingUid) {
+        // For non-NETWORK_STACK permission uid, cap the minimum threshold to a safe default to
+        // avoid too many callbacks.
+        final long thresholdInBytes = (context.checkPermission(
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, Process.myPid(), callingUid)
+                == PackageManager.PERMISSION_GRANTED ? request.thresholdInBytes
+                : Math.max(MIN_THRESHOLD_BYTES, request.thresholdInBytes));
+        if (thresholdInBytes > request.thresholdInBytes) {
+            Log.w(TAG, "Threshold was too low for " + request
+                    + ". Overriding to a safer default of " + thresholdInBytes + " bytes");
+        }
+        return new DataUsageRequest(mNextDataUsageRequestId.incrementAndGet(),
+                request.template, thresholdInBytes);
+    }
+
+    private RequestInfo buildRequestInfo(DataUsageRequest request, IUsageCallback callback,
+            int callingUid, @NetworkStatsAccess.Level int accessLevel) {
+        if (accessLevel <= NetworkStatsAccess.Level.USER) {
+            return new UserUsageRequestInfo(this, request, callback, callingUid,
+                    accessLevel);
+        } else {
+            // Safety check in case a new access level is added and we forgot to update this
+            if (accessLevel < NetworkStatsAccess.Level.DEVICESUMMARY) {
+                throw new IllegalArgumentException(
+                        "accessLevel " + accessLevel + " is less than DEVICESUMMARY.");
+            }
+            return new NetworkUsageRequestInfo(this, request, callback, callingUid,
+                    accessLevel);
+        }
+    }
+
+    /**
+     * Tracks information relevant to a data usage observer.
+     * It will notice when the calling process dies so we can self-expire.
+     */
+    private abstract static class RequestInfo implements IBinder.DeathRecipient {
+        private final NetworkStatsObservers mStatsObserver;
+        protected final DataUsageRequest mRequest;
+        private final IUsageCallback mCallback;
+        protected final int mCallingUid;
+        protected final @NetworkStatsAccess.Level int mAccessLevel;
+        protected NetworkStatsRecorder mRecorder;
+        protected NetworkStatsCollection mCollection;
+
+        RequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request,
+                IUsageCallback callback, int callingUid,
+                    @NetworkStatsAccess.Level int accessLevel) {
+            mStatsObserver = statsObserver;
+            mRequest = request;
+            mCallback = callback;
+            mCallingUid = callingUid;
+            mAccessLevel = accessLevel;
+
+            try {
+                mCallback.asBinder().linkToDeath(this, 0);
+            } catch (RemoteException e) {
+                binderDied();
+            }
+        }
+
+        @Override
+        public void binderDied() {
+            if (LOGV) {
+                Log.v(TAG, "RequestInfo binderDied(" + mRequest + ", " + mCallback + ")");
+            }
+            mStatsObserver.unregister(mRequest, Process.SYSTEM_UID);
+            callCallback(NetworkStatsManager.CALLBACK_RELEASED);
+        }
+
+        @Override
+        public String toString() {
+            return "RequestInfo from uid:" + mCallingUid
+                    + " for " + mRequest + " accessLevel:" + mAccessLevel;
+        }
+
+        private void unlinkDeathRecipient() {
+            mCallback.asBinder().unlinkToDeath(this, 0);
+        }
+
+        /**
+         * Update stats given the samples and interface to identity mappings.
+         */
+        private void updateStats(StatsContext statsContext) {
+            if (mRecorder == null) {
+                // First run; establish baseline stats
+                resetRecorder();
+                recordSample(statsContext);
+                return;
+            }
+            recordSample(statsContext);
+
+            if (checkStats()) {
+                resetRecorder();
+                callCallback(NetworkStatsManager.CALLBACK_LIMIT_REACHED);
+            }
+        }
+
+        private void callCallback(int callbackType) {
+            try {
+                if (LOGV) {
+                    Log.v(TAG, "sending notification " + callbackTypeToName(callbackType)
+                            + " for " + mRequest);
+                }
+                switch (callbackType) {
+                    case NetworkStatsManager.CALLBACK_LIMIT_REACHED:
+                        mCallback.onThresholdReached(mRequest);
+                        break;
+                    case NetworkStatsManager.CALLBACK_RELEASED:
+                        mCallback.onCallbackReleased(mRequest);
+                        break;
+                }
+            } catch (RemoteException e) {
+                // May occur naturally in the race of binder death.
+                Log.w(TAG, "RemoteException caught trying to send a callback msg for " + mRequest);
+            }
+        }
+
+        private void resetRecorder() {
+            mRecorder = new NetworkStatsRecorder();
+            mCollection = mRecorder.getSinceBoot();
+        }
+
+        protected abstract boolean checkStats();
+
+        protected abstract void recordSample(StatsContext statsContext);
+
+        private String callbackTypeToName(int callbackType) {
+            switch (callbackType) {
+                case NetworkStatsManager.CALLBACK_LIMIT_REACHED:
+                    return "LIMIT_REACHED";
+                case NetworkStatsManager.CALLBACK_RELEASED:
+                    return "RELEASED";
+                default:
+                    return "UNKNOWN";
+            }
+        }
+    }
+
+    private static class NetworkUsageRequestInfo extends RequestInfo {
+        NetworkUsageRequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request,
+                IUsageCallback callback, int callingUid,
+                    @NetworkStatsAccess.Level int accessLevel) {
+            super(statsObserver, request, callback, callingUid, accessLevel);
+        }
+
+        @Override
+        protected boolean checkStats() {
+            long bytesSoFar = getTotalBytesForNetwork(mRequest.template);
+            if (LOGV) {
+                Log.v(TAG, bytesSoFar + " bytes so far since notification for "
+                        + mRequest.template);
+            }
+            if (bytesSoFar > mRequest.thresholdInBytes) {
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        protected void recordSample(StatsContext statsContext) {
+            // Recorder does not need to be locked in this context since only the handler
+            // thread will update it. We pass a null VPN array because usage is aggregated by uid
+            // for this snapshot, so VPN traffic can't be reattributed to responsible apps.
+            mRecorder.recordSnapshotLocked(statsContext.mXtSnapshot, statsContext.mActiveIfaces,
+                    statsContext.mCurrentTime);
+        }
+
+        /**
+         * Reads stats matching the given template. {@link NetworkStatsCollection} will aggregate
+         * over all buckets, which in this case should be only one since we built it big enough
+         * that it will outlive the caller. If it doesn't, then there will be multiple buckets.
+         */
+        private long getTotalBytesForNetwork(NetworkTemplate template) {
+            NetworkStats stats = mCollection.getSummary(template,
+                    Long.MIN_VALUE /* start */, Long.MAX_VALUE /* end */,
+                    mAccessLevel, mCallingUid);
+            return stats.getTotalBytes();
+        }
+    }
+
+    private static class UserUsageRequestInfo extends RequestInfo {
+        UserUsageRequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request,
+                    IUsageCallback callback, int callingUid,
+                    @NetworkStatsAccess.Level int accessLevel) {
+            super(statsObserver, request, callback, callingUid, accessLevel);
+        }
+
+        @Override
+        protected boolean checkStats() {
+            int[] uidsToMonitor = mCollection.getRelevantUids(mAccessLevel, mCallingUid);
+
+            for (int i = 0; i < uidsToMonitor.length; i++) {
+                long bytesSoFar = getTotalBytesForNetworkUid(mRequest.template, uidsToMonitor[i]);
+                if (bytesSoFar > mRequest.thresholdInBytes) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        protected void recordSample(StatsContext statsContext) {
+            // Recorder does not need to be locked in this context since only the handler
+            // thread will update it. We pass the VPN info so VPN traffic is reattributed to
+            // responsible apps.
+            mRecorder.recordSnapshotLocked(statsContext.mUidSnapshot, statsContext.mActiveUidIfaces,
+                    statsContext.mCurrentTime);
+        }
+
+        /**
+         * Reads all stats matching the given template and uid. Ther history will likely only
+         * contain one bucket per ident since we build it big enough that it will outlive the
+         * caller lifetime.
+         */
+        private long getTotalBytesForNetworkUid(NetworkTemplate template, int uid) {
+            try {
+                NetworkStatsHistory history = mCollection.getHistory(template, null, uid,
+                        NetworkStats.SET_ALL, NetworkStats.TAG_NONE,
+                        NetworkStatsHistory.FIELD_ALL,
+                        Long.MIN_VALUE /* start */, Long.MAX_VALUE /* end */,
+                        mAccessLevel, mCallingUid);
+                return history.getTotalBytes();
+            } catch (SecurityException e) {
+                if (LOGV) {
+                    Log.w(TAG, "CallerUid " + mCallingUid + " may have lost access to uid "
+                            + uid);
+                }
+                return 0;
+            }
+        }
+    }
+
+    private static class StatsContext {
+        NetworkStats mXtSnapshot;
+        NetworkStats mUidSnapshot;
+        ArrayMap<String, NetworkIdentitySet> mActiveIfaces;
+        ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces;
+        long mCurrentTime;
+
+        StatsContext(NetworkStats xtSnapshot, NetworkStats uidSnapshot,
+                ArrayMap<String, NetworkIdentitySet> activeIfaces,
+                ArrayMap<String, NetworkIdentitySet> activeUidIfaces,
+                long currentTime) {
+            mXtSnapshot = xtSnapshot;
+            mUidSnapshot = uidSnapshot;
+            mActiveIfaces = activeIfaces;
+            mActiveUidIfaces = activeUidIfaces;
+            mCurrentTime = currentTime;
+        }
+    }
+}
diff --git a/service-t/src/com/android/server/net/NetworkStatsRecorder.java b/service-t/src/com/android/server/net/NetworkStatsRecorder.java
new file mode 100644
index 0000000..f62765d
--- /dev/null
+++ b/service-t/src/com/android/server/net/NetworkStatsRecorder.java
@@ -0,0 +1,507 @@
+/*
+ * 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 com.android.server.net;
+
+import static android.net.NetworkStats.TAG_NONE;
+import static android.net.TrafficStats.KB_IN_BYTES;
+import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.text.format.DateUtils.YEAR_IN_MILLIS;
+
+import android.net.NetworkIdentitySet;
+import android.net.NetworkStats;
+import android.net.NetworkStats.NonMonotonicObserver;
+import android.net.NetworkStatsAccess;
+import android.net.NetworkStatsCollection;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.TrafficStats;
+import android.os.Binder;
+import android.os.DropBoxManager;
+import android.service.NetworkStatsRecorderProto;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.util.FileRotator;
+import com.android.net.module.util.NetworkStatsUtils;
+
+import libcore.io.IoUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Logic to record deltas between periodic {@link NetworkStats} snapshots into
+ * {@link NetworkStatsHistory} that belong to {@link NetworkStatsCollection}.
+ * Keeps pending changes in memory until they pass a specific threshold, in
+ * bytes. Uses {@link FileRotator} for persistence logic if present.
+ * <p>
+ * Not inherently thread safe.
+ */
+public class NetworkStatsRecorder {
+    private static final String TAG = "NetworkStatsRecorder";
+    private static final boolean LOGD = false;
+    private static final boolean LOGV = false;
+
+    private static final String TAG_NETSTATS_DUMP = "netstats_dump";
+
+    /** Dump before deleting in {@link #recoverFromWtf()}. */
+    private static final boolean DUMP_BEFORE_DELETE = true;
+
+    private final FileRotator mRotator;
+    private final NonMonotonicObserver<String> mObserver;
+    private final DropBoxManager mDropBox;
+    private final String mCookie;
+
+    private final long mBucketDuration;
+    private final boolean mOnlyTags;
+
+    private long mPersistThresholdBytes = 2 * MB_IN_BYTES;
+    private NetworkStats mLastSnapshot;
+
+    private final NetworkStatsCollection mPending;
+    private final NetworkStatsCollection mSinceBoot;
+
+    private final CombiningRewriter mPendingRewriter;
+
+    private WeakReference<NetworkStatsCollection> mComplete;
+
+    /**
+     * Non-persisted recorder, with only one bucket. Used by {@link NetworkStatsObservers}.
+     */
+    public NetworkStatsRecorder() {
+        mRotator = null;
+        mObserver = null;
+        mDropBox = null;
+        mCookie = null;
+
+        // set the bucket big enough to have all data in one bucket, but allow some
+        // slack to avoid overflow
+        mBucketDuration = YEAR_IN_MILLIS;
+        mOnlyTags = false;
+
+        mPending = null;
+        mSinceBoot = new NetworkStatsCollection(mBucketDuration);
+
+        mPendingRewriter = null;
+    }
+
+    /**
+     * Persisted recorder.
+     */
+    public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
+            DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags) {
+        mRotator = Objects.requireNonNull(rotator, "missing FileRotator");
+        mObserver = Objects.requireNonNull(observer, "missing NonMonotonicObserver");
+        mDropBox = Objects.requireNonNull(dropBox, "missing DropBoxManager");
+        mCookie = cookie;
+
+        mBucketDuration = bucketDuration;
+        mOnlyTags = onlyTags;
+
+        mPending = new NetworkStatsCollection(bucketDuration);
+        mSinceBoot = new NetworkStatsCollection(bucketDuration);
+
+        mPendingRewriter = new CombiningRewriter(mPending);
+    }
+
+    public void setPersistThreshold(long thresholdBytes) {
+        if (LOGV) Log.v(TAG, "setPersistThreshold() with " + thresholdBytes);
+        mPersistThresholdBytes = NetworkStatsUtils.constrain(
+                thresholdBytes, 1 * KB_IN_BYTES, 100 * MB_IN_BYTES);
+    }
+
+    public void resetLocked() {
+        mLastSnapshot = null;
+        if (mPending != null) {
+            mPending.reset();
+        }
+        if (mSinceBoot != null) {
+            mSinceBoot.reset();
+        }
+        if (mComplete != null) {
+            mComplete.clear();
+        }
+    }
+
+    public NetworkStats.Entry getTotalSinceBootLocked(NetworkTemplate template) {
+        return mSinceBoot.getSummary(template, Long.MIN_VALUE, Long.MAX_VALUE,
+                NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotal(null);
+    }
+
+    public NetworkStatsCollection getSinceBoot() {
+        return mSinceBoot;
+    }
+
+    /**
+     * Load complete history represented by {@link FileRotator}. Caches
+     * internally as a {@link WeakReference}, and updated with future
+     * {@link #recordSnapshotLocked(NetworkStats, Map, long)} snapshots as long
+     * as reference is valid.
+     */
+    public NetworkStatsCollection getOrLoadCompleteLocked() {
+        Objects.requireNonNull(mRotator, "missing FileRotator");
+        NetworkStatsCollection res = mComplete != null ? mComplete.get() : null;
+        if (res == null) {
+            res = loadLocked(Long.MIN_VALUE, Long.MAX_VALUE);
+            mComplete = new WeakReference<NetworkStatsCollection>(res);
+        }
+        return res;
+    }
+
+    public NetworkStatsCollection getOrLoadPartialLocked(long start, long end) {
+        Objects.requireNonNull(mRotator, "missing FileRotator");
+        NetworkStatsCollection res = mComplete != null ? mComplete.get() : null;
+        if (res == null) {
+            res = loadLocked(start, end);
+        }
+        return res;
+    }
+
+    private NetworkStatsCollection loadLocked(long start, long end) {
+        if (LOGD) Log.d(TAG, "loadLocked() reading from disk for " + mCookie);
+        final NetworkStatsCollection res = new NetworkStatsCollection(mBucketDuration);
+        try {
+            mRotator.readMatching(res, start, end);
+            res.recordCollection(mPending);
+        } catch (IOException e) {
+            Log.wtf(TAG, "problem completely reading network stats", e);
+            recoverFromWtf();
+        } catch (OutOfMemoryError e) {
+            Log.wtf(TAG, "problem completely reading network stats", e);
+            recoverFromWtf();
+        }
+        return res;
+    }
+
+    /**
+     * Record any delta that occurred since last {@link NetworkStats} snapshot, using the given
+     * {@link Map} to identify network interfaces. First snapshot is considered bootstrap, and is
+     * not counted as delta.
+     */
+    public void recordSnapshotLocked(NetworkStats snapshot,
+            Map<String, NetworkIdentitySet> ifaceIdent, long currentTimeMillis) {
+        final HashSet<String> unknownIfaces = new HashSet<>();
+
+        // skip recording when snapshot missing
+        if (snapshot == null) return;
+
+        // assume first snapshot is bootstrap and don't record
+        if (mLastSnapshot == null) {
+            mLastSnapshot = snapshot;
+            return;
+        }
+
+        final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null;
+
+        final NetworkStats delta = NetworkStats.subtract(
+                snapshot, mLastSnapshot, mObserver, mCookie);
+        final long end = currentTimeMillis;
+        final long start = end - delta.getElapsedRealtime();
+
+        NetworkStats.Entry entry = null;
+        for (int i = 0; i < delta.size(); i++) {
+            entry = delta.getValues(i, entry);
+
+            // As a last-ditch check, report any negative values and
+            // clamp them so recording below doesn't croak.
+            if (entry.isNegative()) {
+                if (mObserver != null) {
+                    mObserver.foundNonMonotonic(delta, i, mCookie);
+                }
+                entry.rxBytes = Math.max(entry.rxBytes, 0);
+                entry.rxPackets = Math.max(entry.rxPackets, 0);
+                entry.txBytes = Math.max(entry.txBytes, 0);
+                entry.txPackets = Math.max(entry.txPackets, 0);
+                entry.operations = Math.max(entry.operations, 0);
+            }
+
+            final NetworkIdentitySet ident = ifaceIdent.get(entry.iface);
+            if (ident == null) {
+                unknownIfaces.add(entry.iface);
+                continue;
+            }
+
+            // skip when no delta occurred
+            if (entry.isEmpty()) continue;
+
+            // only record tag data when requested
+            if ((entry.tag == TAG_NONE) != mOnlyTags) {
+                if (mPending != null) {
+                    mPending.recordData(ident, entry.uid, entry.set, entry.tag, start, end, entry);
+                }
+
+                // also record against boot stats when present
+                if (mSinceBoot != null) {
+                    mSinceBoot.recordData(ident, entry.uid, entry.set, entry.tag, start, end, entry);
+                }
+
+                // also record against complete dataset when present
+                if (complete != null) {
+                    complete.recordData(ident, entry.uid, entry.set, entry.tag, start, end, entry);
+                }
+            }
+        }
+
+        mLastSnapshot = snapshot;
+
+        if (LOGV && unknownIfaces.size() > 0) {
+            Log.w(TAG, "unknown interfaces " + unknownIfaces + ", ignoring those stats");
+        }
+    }
+
+    /**
+     * Consider persisting any pending deltas, if they are beyond
+     * {@link #mPersistThresholdBytes}.
+     */
+    public void maybePersistLocked(long currentTimeMillis) {
+        Objects.requireNonNull(mRotator, "missing FileRotator");
+        final long pendingBytes = mPending.getTotalBytes();
+        if (pendingBytes >= mPersistThresholdBytes) {
+            forcePersistLocked(currentTimeMillis);
+        } else {
+            mRotator.maybeRotate(currentTimeMillis);
+        }
+    }
+
+    /**
+     * Force persisting any pending deltas.
+     */
+    public void forcePersistLocked(long currentTimeMillis) {
+        Objects.requireNonNull(mRotator, "missing FileRotator");
+        if (mPending.isDirty()) {
+            if (LOGD) Log.d(TAG, "forcePersistLocked() writing for " + mCookie);
+            try {
+                mRotator.rewriteActive(mPendingRewriter, currentTimeMillis);
+                mRotator.maybeRotate(currentTimeMillis);
+                mPending.reset();
+            } catch (IOException e) {
+                Log.wtf(TAG, "problem persisting pending stats", e);
+                recoverFromWtf();
+            } catch (OutOfMemoryError e) {
+                Log.wtf(TAG, "problem persisting pending stats", e);
+                recoverFromWtf();
+            }
+        }
+    }
+
+    /**
+     * Remove the given UID from all {@link FileRotator} history, migrating it
+     * to {@link TrafficStats#UID_REMOVED}.
+     */
+    public void removeUidsLocked(int[] uids) {
+        if (mRotator != null) {
+            try {
+                // Rewrite all persisted data to migrate UID stats
+                mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uids));
+            } catch (IOException e) {
+                Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e);
+                recoverFromWtf();
+            } catch (OutOfMemoryError e) {
+                Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e);
+                recoverFromWtf();
+            }
+        }
+
+        // Remove any pending stats
+        if (mPending != null) {
+            mPending.removeUids(uids);
+        }
+        if (mSinceBoot != null) {
+            mSinceBoot.removeUids(uids);
+        }
+
+        // Clear UID from current stats snapshot
+        if (mLastSnapshot != null) {
+            mLastSnapshot.removeUids(uids);
+        }
+
+        final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null;
+        if (complete != null) {
+            complete.removeUids(uids);
+        }
+    }
+
+    /**
+     * Rewriter that will combine current {@link NetworkStatsCollection} values
+     * with anything read from disk, and write combined set to disk. Clears the
+     * original {@link NetworkStatsCollection} when finished writing.
+     */
+    private static class CombiningRewriter implements FileRotator.Rewriter {
+        private final NetworkStatsCollection mCollection;
+
+        public CombiningRewriter(NetworkStatsCollection collection) {
+            mCollection = Objects.requireNonNull(collection, "missing NetworkStatsCollection");
+        }
+
+        @Override
+        public void reset() {
+            // ignored
+        }
+
+        @Override
+        public void read(InputStream in) throws IOException {
+            mCollection.read(in);
+        }
+
+        @Override
+        public boolean shouldWrite() {
+            return true;
+        }
+
+        @Override
+        public void write(OutputStream out) throws IOException {
+            mCollection.write(out);
+            mCollection.reset();
+        }
+    }
+
+    /**
+     * Rewriter that will remove any {@link NetworkStatsHistory} attributed to
+     * the requested UID, only writing data back when modified.
+     */
+    public static class RemoveUidRewriter implements FileRotator.Rewriter {
+        private final NetworkStatsCollection mTemp;
+        private final int[] mUids;
+
+        public RemoveUidRewriter(long bucketDuration, int[] uids) {
+            mTemp = new NetworkStatsCollection(bucketDuration);
+            mUids = uids;
+        }
+
+        @Override
+        public void reset() {
+            mTemp.reset();
+        }
+
+        @Override
+        public void read(InputStream in) throws IOException {
+            mTemp.read(in);
+            mTemp.clearDirty();
+            mTemp.removeUids(mUids);
+        }
+
+        @Override
+        public boolean shouldWrite() {
+            return mTemp.isDirty();
+        }
+
+        @Override
+        public void write(OutputStream out) throws IOException {
+            mTemp.write(out);
+        }
+    }
+
+    public void importLegacyNetworkLocked(File file) throws IOException {
+        Objects.requireNonNull(mRotator, "missing FileRotator");
+
+        // legacy file still exists; start empty to avoid double importing
+        mRotator.deleteAll();
+
+        final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration);
+        collection.readLegacyNetwork(file);
+
+        final long startMillis = collection.getStartMillis();
+        final long endMillis = collection.getEndMillis();
+
+        if (!collection.isEmpty()) {
+            // process legacy data, creating active file at starting time, then
+            // using end time to possibly trigger rotation.
+            mRotator.rewriteActive(new CombiningRewriter(collection), startMillis);
+            mRotator.maybeRotate(endMillis);
+        }
+    }
+
+    public void importLegacyUidLocked(File file) throws IOException {
+        Objects.requireNonNull(mRotator, "missing FileRotator");
+
+        // legacy file still exists; start empty to avoid double importing
+        mRotator.deleteAll();
+
+        final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration);
+        collection.readLegacyUid(file, mOnlyTags);
+
+        final long startMillis = collection.getStartMillis();
+        final long endMillis = collection.getEndMillis();
+
+        if (!collection.isEmpty()) {
+            // process legacy data, creating active file at starting time, then
+            // using end time to possibly trigger rotation.
+            mRotator.rewriteActive(new CombiningRewriter(collection), startMillis);
+            mRotator.maybeRotate(endMillis);
+        }
+    }
+
+    public void dumpLocked(IndentingPrintWriter pw, boolean fullHistory) {
+        if (mPending != null) {
+            pw.print("Pending bytes: "); pw.println(mPending.getTotalBytes());
+        }
+        if (fullHistory) {
+            pw.println("Complete history:");
+            getOrLoadCompleteLocked().dump(pw);
+        } else {
+            pw.println("History since boot:");
+            mSinceBoot.dump(pw);
+        }
+    }
+
+    public void dumpDebugLocked(ProtoOutputStream proto, long tag) {
+        final long start = proto.start(tag);
+        if (mPending != null) {
+            proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES,
+                    mPending.getTotalBytes());
+        }
+        getOrLoadCompleteLocked().dumpDebug(proto,
+                NetworkStatsRecorderProto.COMPLETE_HISTORY);
+        proto.end(start);
+    }
+
+    public void dumpCheckin(PrintWriter pw, long start, long end) {
+        // Only load and dump stats from the requested window
+        getOrLoadPartialLocked(start, end).dumpCheckin(pw, start, end);
+    }
+
+    /**
+     * Recover from {@link FileRotator} failure by dumping state to
+     * {@link DropBoxManager} and deleting contents.
+     */
+    private void recoverFromWtf() {
+        if (DUMP_BEFORE_DELETE) {
+            final ByteArrayOutputStream os = new ByteArrayOutputStream();
+            try {
+                mRotator.dumpAll(os);
+            } catch (IOException e) {
+                // ignore partial contents
+                os.reset();
+            } finally {
+                IoUtils.closeQuietly(os);
+            }
+            mDropBox.addData(TAG_NETSTATS_DUMP, os.toByteArray(), 0);
+        }
+
+        mRotator.deleteAll();
+    }
+}
diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java
new file mode 100644
index 0000000..e3794e4
--- /dev/null
+++ b/service-t/src/com/android/server/net/NetworkStatsService.java
@@ -0,0 +1,2528 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.net;
+
+import static android.Manifest.permission.NETWORK_STATS_PROVIDER;
+import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
+import static android.Manifest.permission.UPDATE_DEVICE_STATS;
+import static android.app.usage.NetworkStatsManager.PREFIX_DEV;
+import static android.content.Intent.ACTION_SHUTDOWN;
+import static android.content.Intent.ACTION_UID_REMOVED;
+import static android.content.Intent.ACTION_USER_REMOVED;
+import static android.content.Intent.EXTRA_UID;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
+import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.IFACE_VT;
+import static android.net.NetworkStats.INTERFACES_ALL;
+import static android.net.NetworkStats.METERED_ALL;
+import static android.net.NetworkStats.ROAMING_ALL;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.SET_FOREGROUND;
+import static android.net.NetworkStats.STATS_PER_IFACE;
+import static android.net.NetworkStats.STATS_PER_UID;
+import static android.net.NetworkStats.TAG_ALL;
+import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkStats.UID_ALL;
+import static android.net.NetworkStatsHistory.FIELD_ALL;
+import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
+import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
+import static android.net.TrafficStats.KB_IN_BYTES;
+import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.net.TrafficStats.UID_TETHERING;
+import static android.net.TrafficStats.UNSUPPORTED;
+import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID;
+import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG;
+import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
+import static android.os.Trace.TRACE_TAG_NETWORK;
+import static android.system.OsConstants.ENOENT;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+import static android.text.format.DateUtils.DAY_IN_MILLIS;
+import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static android.text.format.DateUtils.SECOND_IN_MILLIS;
+
+import static com.android.net.module.util.NetworkCapabilitiesUtils.getDisplayTransport;
+import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TargetApi;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.usage.NetworkStatsManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.net.DataUsageRequest;
+import android.net.INetd;
+import android.net.INetworkStatsService;
+import android.net.INetworkStatsSession;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkIdentity;
+import android.net.NetworkIdentitySet;
+import android.net.NetworkPolicyManager;
+import android.net.NetworkSpecifier;
+import android.net.NetworkStack;
+import android.net.NetworkStateSnapshot;
+import android.net.NetworkStats;
+import android.net.NetworkStats.NonMonotonicObserver;
+import android.net.NetworkStatsAccess;
+import android.net.NetworkStatsCollection;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.TelephonyNetworkSpecifier;
+import android.net.TetherStatsParcel;
+import android.net.TetheringManager;
+import android.net.TrafficStats;
+import android.net.UnderlyingNetworkInfo;
+import android.net.Uri;
+import android.net.netstats.IUsageCallback;
+import android.net.netstats.provider.INetworkStatsProvider;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
+import android.os.Binder;
+import android.os.Build;
+import android.os.DropBoxManager;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.service.NetworkInterfaceProto;
+import android.service.NetworkStatsServiceDumpProto;
+import android.system.ErrnoException;
+import android.telephony.PhoneStateListener;
+import android.telephony.SubscriptionPlan;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.EventLog;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FileRotator;
+import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.net.module.util.BestClock;
+import com.android.net.module.util.BinderUtils;
+import com.android.net.module.util.BpfMap;
+import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.IBpfMap;
+import com.android.net.module.util.LocationPermissionChecker;
+import com.android.net.module.util.NetworkStatsUtils;
+import com.android.net.module.util.PermissionUtils;
+import com.android.net.module.util.Struct.U32;
+import com.android.net.module.util.Struct.U8;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.time.Clock;
+import java.time.ZoneOffset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Collect and persist detailed network statistics, and provide this data to
+ * other system services.
+ */
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
+public class NetworkStatsService extends INetworkStatsService.Stub {
+    static {
+        System.loadLibrary("service-connectivity");
+    }
+
+    static final String TAG = "NetworkStats";
+    static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
+    static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
+
+    // Perform polling and persist all (FLAG_PERSIST_ALL).
+    private static final int MSG_PERFORM_POLL = 1;
+    // Perform polling, persist network, and register the global alert again.
+    private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
+    private static final int MSG_NOTIFY_NETWORK_STATUS = 3;
+    // A message for broadcasting ACTION_NETWORK_STATS_UPDATED in handler thread to prevent
+    // deadlock.
+    private static final int MSG_BROADCAST_NETWORK_STATS_UPDATED = 4;
+
+    /** Flags to control detail level of poll event. */
+    private static final int FLAG_PERSIST_NETWORK = 0x1;
+    private static final int FLAG_PERSIST_UID = 0x2;
+    private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
+    private static final int FLAG_PERSIST_FORCE = 0x100;
+
+    /**
+     * When global alert quota is high, wait for this delay before processing each polling,
+     * and do not schedule further polls once there is already one queued.
+     * This avoids firing the global alert too often on devices with high transfer speeds and
+     * high quota.
+     */
+    private static final int DEFAULT_PERFORM_POLL_DELAY_MS = 1000;
+
+    private static final String TAG_NETSTATS_ERROR = "netstats_error";
+
+    /**
+     * EventLog tags used when logging into the event log. Note the values must be sync with
+     * frameworks/base/services/core/java/com/android/server/EventLogTags.logtags to get correct
+     * name translation.
+      */
+    private static final int LOG_TAG_NETSTATS_MOBILE_SAMPLE = 51100;
+    private static final int LOG_TAG_NETSTATS_WIFI_SAMPLE = 51101;
+
+    // TODO: Replace the hardcoded string and move it into ConnectivitySettingsManager.
+    private static final String NETSTATS_COMBINE_SUBTYPE_ENABLED =
+            "netstats_combine_subtype_enabled";
+
+    // This is current path but may be changed soon.
+    private static final String UID_COUNTERSET_MAP_PATH =
+            "/sys/fs/bpf/map_netd_uid_counterset_map";
+    private static final String COOKIE_TAG_MAP_PATH =
+            "/sys/fs/bpf/map_netd_cookie_tag_map";
+    private static final String APP_UID_STATS_MAP_PATH =
+            "/sys/fs/bpf/map_netd_app_uid_stats_map";
+    private static final String STATS_MAP_A_PATH =
+            "/sys/fs/bpf/map_netd_stats_map_A";
+    private static final String STATS_MAP_B_PATH =
+            "/sys/fs/bpf/map_netd_stats_map_B";
+
+    private final Context mContext;
+    private final NetworkStatsFactory mStatsFactory;
+    private final AlarmManager mAlarmManager;
+    private final Clock mClock;
+    private final NetworkStatsSettings mSettings;
+    private final NetworkStatsObservers mStatsObservers;
+
+    private final File mSystemDir;
+    private final File mBaseDir;
+
+    private final PowerManager.WakeLock mWakeLock;
+
+    private final ContentObserver mContentObserver;
+    private final ContentResolver mContentResolver;
+
+    protected INetd mNetd;
+    private final AlertObserver mAlertObserver = new AlertObserver();
+
+    @VisibleForTesting
+    public static final String ACTION_NETWORK_STATS_POLL =
+            "com.android.server.action.NETWORK_STATS_POLL";
+    public static final String ACTION_NETWORK_STATS_UPDATED =
+            "com.android.server.action.NETWORK_STATS_UPDATED";
+
+    private PendingIntent mPollIntent;
+
+    /**
+     * Settings that can be changed externally.
+     */
+    public interface NetworkStatsSettings {
+        long getPollInterval();
+        long getPollDelay();
+        boolean getSampleEnabled();
+        boolean getAugmentEnabled();
+        /**
+         * When enabled, all mobile data is reported under {@link NetworkTemplate#NETWORK_TYPE_ALL}.
+         * When disabled, mobile data is broken down by a granular ratType representative of the
+         * actual ratType. {@see android.app.usage.NetworkStatsManager#getCollapsedRatType}.
+         * Enabling this decreases the level of detail but saves performance, disk space and
+         * amount of data logged.
+         */
+        boolean getCombineSubtypeEnabled();
+
+        class Config {
+            public final long bucketDuration;
+            public final long rotateAgeMillis;
+            public final long deleteAgeMillis;
+
+            public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
+                this.bucketDuration = bucketDuration;
+                this.rotateAgeMillis = rotateAgeMillis;
+                this.deleteAgeMillis = deleteAgeMillis;
+            }
+        }
+
+        Config getDevConfig();
+        Config getXtConfig();
+        Config getUidConfig();
+        Config getUidTagConfig();
+
+        long getGlobalAlertBytes(long def);
+        long getDevPersistBytes(long def);
+        long getXtPersistBytes(long def);
+        long getUidPersistBytes(long def);
+        long getUidTagPersistBytes(long def);
+    }
+
+    private final Object mStatsLock = new Object();
+
+    /** Set of currently active ifaces. */
+    @GuardedBy("mStatsLock")
+    private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
+
+    /** Set of currently active ifaces for UID stats. */
+    @GuardedBy("mStatsLock")
+    private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
+
+    /** Current default active iface. */
+    @GuardedBy("mStatsLock")
+    private String mActiveIface;
+
+    /** Set of any ifaces associated with mobile networks since boot. */
+    private volatile String[] mMobileIfaces = new String[0];
+
+    /** Set of any ifaces associated with wifi networks since boot. */
+    private volatile String[] mWifiIfaces = new String[0];
+
+    /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
+    @GuardedBy("mStatsLock")
+    private Network[] mDefaultNetworks = new Network[0];
+
+    /** Last states of all networks sent from ConnectivityService. */
+    @GuardedBy("mStatsLock")
+    @Nullable
+    private NetworkStateSnapshot[] mLastNetworkStateSnapshots = null;
+
+    private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
+            new DropBoxNonMonotonicObserver();
+
+    private static final int MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS = 100;
+    private final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
+            new CopyOnWriteArrayList<>();
+    /** Semaphore used to wait for stats provider to respond to request stats update. */
+    private final Semaphore mStatsProviderSem = new Semaphore(0, true);
+
+    @GuardedBy("mStatsLock")
+    private NetworkStatsRecorder mDevRecorder;
+    @GuardedBy("mStatsLock")
+    private NetworkStatsRecorder mXtRecorder;
+    @GuardedBy("mStatsLock")
+    private NetworkStatsRecorder mUidRecorder;
+    @GuardedBy("mStatsLock")
+    private NetworkStatsRecorder mUidTagRecorder;
+
+    /** Cached {@link #mXtRecorder} stats. */
+    @GuardedBy("mStatsLock")
+    private NetworkStatsCollection mXtStatsCached;
+
+    /**
+     * Current counter sets for each UID.
+     * TODO: maybe remove mActiveUidCounterSet and read UidCouneterSet value from mUidCounterSetMap
+     * directly ? But if mActiveUidCounterSet would be accessed very frequently, maybe keep
+     * mActiveUidCounterSet to avoid accessing kernel too frequently.
+     */
+    private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
+    private final IBpfMap<U32, U8> mUidCounterSetMap;
+    private final IBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap;
+    private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapA;
+    private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapB;
+    private final IBpfMap<UidStatsMapKey, StatsMapValue> mAppUidStatsMap;
+
+    /** Data layer operation counters for splicing into other structures. */
+    private NetworkStats mUidOperations = new NetworkStats(0L, 10);
+
+    @NonNull
+    private final Handler mHandler;
+
+    private volatile boolean mSystemReady;
+    private long mPersistThreshold = 2 * MB_IN_BYTES;
+    private long mGlobalAlertBytes;
+
+    private static final long POLL_RATE_LIMIT_MS = 15_000;
+
+    private long mLastStatsSessionPoll;
+
+    /** Map from UID to number of opened sessions */
+    @GuardedBy("mOpenSessionCallsPerUid")
+    private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
+
+    private final static int DUMP_STATS_SESSION_COUNT = 20;
+
+    @NonNull
+    private final Dependencies mDeps;
+
+    @NonNull
+    private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
+
+    @NonNull
+    private final LocationPermissionChecker mLocationPermissionChecker;
+
+    @NonNull
+    private final BpfInterfaceMapUpdater mInterfaceMapUpdater;
+
+    private static @NonNull File getDefaultSystemDir() {
+        return new File(Environment.getDataDirectory(), "system");
+    }
+
+    private static @NonNull File getDefaultBaseDir() {
+        File baseDir = new File(getDefaultSystemDir(), "netstats");
+        baseDir.mkdirs();
+        return baseDir;
+    }
+
+    private static @NonNull Clock getDefaultClock() {
+        return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
+                Clock.systemUTC());
+    }
+
+    private final class NetworkStatsHandler extends Handler {
+        NetworkStatsHandler(@NonNull Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_PERFORM_POLL: {
+                    performPoll(FLAG_PERSIST_ALL);
+                    break;
+                }
+                case MSG_NOTIFY_NETWORK_STATUS: {
+                    // If no cached states, ignore.
+                    if (mLastNetworkStateSnapshots == null) break;
+                    // TODO (b/181642673): Protect mDefaultNetworks from concurrent accessing.
+                    handleNotifyNetworkStatus(
+                            mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface);
+                    break;
+                }
+                case MSG_PERFORM_POLL_REGISTER_ALERT: {
+                    performPoll(FLAG_PERSIST_NETWORK);
+                    registerGlobalAlert();
+                    break;
+                }
+                case MSG_BROADCAST_NETWORK_STATS_UPDATED: {
+                    final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
+                    updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                    mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
+                            READ_NETWORK_USAGE_HISTORY);
+                    break;
+                }
+            }
+        }
+    }
+
+    /** Creates a new NetworkStatsService */
+    public static NetworkStatsService create(Context context) {
+        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        PowerManager.WakeLock wakeLock =
+                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        final INetd netd = INetd.Stub.asInterface(
+                (IBinder) context.getSystemService(Context.NETD_SERVICE));
+        final NetworkStatsService service = new NetworkStatsService(context,
+                INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
+                alarmManager, wakeLock, getDefaultClock(),
+                new DefaultNetworkStatsSettings(), new NetworkStatsFactory(context),
+                new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
+                new Dependencies());
+
+        return service;
+    }
+
+    // This must not be called outside of tests, even within the same package, as this constructor
+    // does not register the local service. Use the create() helper above.
+    @VisibleForTesting
+    NetworkStatsService(Context context, INetd netd, AlarmManager alarmManager,
+            PowerManager.WakeLock wakeLock, Clock clock, NetworkStatsSettings settings,
+            NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
+            File baseDir, @NonNull Dependencies deps) {
+        mContext = Objects.requireNonNull(context, "missing Context");
+        mNetd = Objects.requireNonNull(netd, "missing Netd");
+        mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
+        mClock = Objects.requireNonNull(clock, "missing Clock");
+        mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
+        mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock");
+        mStatsFactory = Objects.requireNonNull(factory, "missing factory");
+        mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers");
+        mSystemDir = Objects.requireNonNull(systemDir, "missing systemDir");
+        mBaseDir = Objects.requireNonNull(baseDir, "missing baseDir");
+        mDeps = Objects.requireNonNull(deps, "missing Dependencies");
+
+        final HandlerThread handlerThread = mDeps.makeHandlerThread();
+        handlerThread.start();
+        mHandler = new NetworkStatsHandler(handlerThread.getLooper());
+        mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext,
+                (command) -> mHandler.post(command) , this);
+        mContentResolver = mContext.getContentResolver();
+        mContentObserver = mDeps.makeContentObserver(mHandler, mSettings,
+                mNetworkStatsSubscriptionsMonitor);
+        mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
+        mInterfaceMapUpdater = mDeps.makeBpfInterfaceMapUpdater(mContext, mHandler);
+        mInterfaceMapUpdater.start();
+        mUidCounterSetMap = mDeps.getUidCounterSetMap();
+        mCookieTagMap = mDeps.getCookieTagMap();
+        mStatsMapA = mDeps.getStatsMapA();
+        mStatsMapB = mDeps.getStatsMapB();
+        mAppUidStatsMap = mDeps.getAppUidStatsMap();
+    }
+
+    /**
+     * Dependencies of NetworkStatsService, for injection in tests.
+     */
+    // TODO: Move more stuff into dependencies object.
+    @VisibleForTesting
+    public static class Dependencies {
+        /**
+         * Create a HandlerThread to use in NetworkStatsService.
+         */
+        @NonNull
+        public HandlerThread makeHandlerThread() {
+            return new HandlerThread(TAG);
+        }
+
+        /**
+         * Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change
+         * event in NetworkStatsService.
+         */
+        @NonNull
+        public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context,
+                @NonNull Executor executor, @NonNull NetworkStatsService service) {
+            // TODO: Update RatType passively in NSS, instead of querying into the monitor
+            //  when notifyNetworkStatus.
+            return new NetworkStatsSubscriptionsMonitor(context, executor,
+                    (subscriberId, type) -> service.handleOnCollapsedRatTypeChanged());
+        }
+
+        /**
+         * Create a ContentObserver instance which is used to observe settings changes,
+         * and dispatch onChange events on handler thread.
+         */
+        public @NonNull ContentObserver makeContentObserver(@NonNull Handler handler,
+                @NonNull NetworkStatsSettings settings,
+                @NonNull NetworkStatsSubscriptionsMonitor monitor) {
+            return new ContentObserver(handler) {
+                @Override
+                public void onChange(boolean selfChange, @NonNull Uri uri) {
+                    if (!settings.getCombineSubtypeEnabled()) {
+                        monitor.start();
+                    } else {
+                        monitor.stop();
+                    }
+                }
+            };
+        }
+
+        /**
+         * @see LocationPermissionChecker
+         */
+        public LocationPermissionChecker makeLocationPermissionChecker(final Context context) {
+            return new LocationPermissionChecker(context);
+        }
+
+        /** Create BpfInterfaceMapUpdater to update bpf interface map. */
+        @NonNull
+        public BpfInterfaceMapUpdater makeBpfInterfaceMapUpdater(
+                @NonNull Context ctx, @NonNull Handler handler) {
+            return new BpfInterfaceMapUpdater(ctx, handler);
+        }
+
+        /** Get counter sets map for each UID. */
+        public IBpfMap<U32, U8> getUidCounterSetMap() {
+            try {
+                return new BpfMap<U32, U8>(UID_COUNTERSET_MAP_PATH, BpfMap.BPF_F_RDWR,
+                        U32.class, U8.class);
+            } catch (ErrnoException e) {
+                Log.wtf(TAG, "Cannot open uid counter set map: " + e);
+                return null;
+            }
+        }
+
+        /** Gets the cookie tag map */
+        public IBpfMap<CookieTagMapKey, CookieTagMapValue> getCookieTagMap() {
+            try {
+                return new BpfMap<CookieTagMapKey, CookieTagMapValue>(COOKIE_TAG_MAP_PATH,
+                        BpfMap.BPF_F_RDWR, CookieTagMapKey.class, CookieTagMapValue.class);
+            } catch (ErrnoException e) {
+                Log.wtf(TAG, "Cannot open cookie tag map: " + e);
+                return null;
+            }
+        }
+
+        /** Gets stats map A */
+        public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapA() {
+            try {
+                return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_A_PATH,
+                        BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class);
+            } catch (ErrnoException e) {
+                Log.wtf(TAG, "Cannot open stats map A: " + e);
+                return null;
+            }
+        }
+
+        /** Gets stats map B */
+        public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapB() {
+            try {
+                return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_B_PATH,
+                        BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class);
+            } catch (ErrnoException e) {
+                Log.wtf(TAG, "Cannot open stats map B: " + e);
+                return null;
+            }
+        }
+
+        /** Gets the uid stats map */
+        public IBpfMap<UidStatsMapKey, StatsMapValue> getAppUidStatsMap() {
+            try {
+                return new BpfMap<UidStatsMapKey, StatsMapValue>(APP_UID_STATS_MAP_PATH,
+                        BpfMap.BPF_F_RDWR, UidStatsMapKey.class, StatsMapValue.class);
+            } catch (ErrnoException e) {
+                Log.wtf(TAG, "Cannot open app uid stats map: " + e);
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Observer that watches for {@link INetdUnsolicitedEventListener} alerts.
+     */
+    @VisibleForTesting
+    public class AlertObserver extends BaseNetdUnsolicitedEventListener {
+        @Override
+        public void onQuotaLimitReached(@NonNull String alertName, @NonNull String ifName) {
+            PermissionUtils.enforceNetworkStackPermission(mContext);
+
+            if (LIMIT_GLOBAL_ALERT.equals(alertName)) {
+                // kick off background poll to collect network stats unless there is already
+                // such a call pending; UID stats are handled during normal polling interval.
+                if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
+                    mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
+                            mSettings.getPollDelay());
+                }
+            }
+        }
+    }
+
+    public void systemReady() {
+        synchronized (mStatsLock) {
+            mSystemReady = true;
+
+            // create data recorders along with historical rotators
+            mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
+            mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
+            mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
+            mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
+
+            updatePersistThresholdsLocked();
+
+            // upgrade any legacy stats, migrating them to rotated files
+            maybeUpgradeLegacyStatsLocked();
+
+            // read historical network stats from disk, since policy service
+            // might need them right away.
+            mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
+
+            // bootstrap initial stats to prevent double-counting later
+            bootstrapStatsLocked();
+        }
+
+        // watch for tethering changes
+        final TetheringManager tetheringManager = mContext.getSystemService(TetheringManager.class);
+        tetheringManager.registerTetheringEventCallback(
+                (command) -> mHandler.post(command), mTetherListener);
+
+        // listen for periodic polling events
+        final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
+        mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
+
+        // listen for uid removal to clean stats
+        final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
+        mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
+
+        // listen for user changes to clean stats
+        final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
+        mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
+
+        // persist stats during clean shutdown
+        final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
+        mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
+
+        try {
+            mNetd.registerUnsolicitedEventListener(mAlertObserver);
+        } catch (RemoteException | ServiceSpecificException e) {
+            Log.wtf(TAG, "Error registering event listener :", e);
+        }
+
+        //  schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
+        final PendingIntent pollIntent =
+                PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL),
+                        PendingIntent.FLAG_IMMUTABLE);
+
+        final long currentRealtime = SystemClock.elapsedRealtime();
+        mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
+                mSettings.getPollInterval(), pollIntent);
+
+        mContentResolver.registerContentObserver(Settings.Global
+                .getUriFor(NETSTATS_COMBINE_SUBTYPE_ENABLED),
+                        false /* notifyForDescendants */, mContentObserver);
+
+        // Post a runnable on handler thread to call onChange(). It's for getting current value of
+        // NETSTATS_COMBINE_SUBTYPE_ENABLED to decide start or stop monitoring RAT type changes.
+        mHandler.post(() -> mContentObserver.onChange(false, Settings.Global
+                .getUriFor(NETSTATS_COMBINE_SUBTYPE_ENABLED)));
+
+        registerGlobalAlert();
+    }
+
+    private NetworkStatsRecorder buildRecorder(
+            String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
+        final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
+                Context.DROPBOX_SERVICE);
+        return new NetworkStatsRecorder(new FileRotator(
+                mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
+                mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
+    }
+
+    @GuardedBy("mStatsLock")
+    private void shutdownLocked() {
+        final TetheringManager tetheringManager = mContext.getSystemService(TetheringManager.class);
+        tetheringManager.unregisterTetheringEventCallback(mTetherListener);
+        mContext.unregisterReceiver(mPollReceiver);
+        mContext.unregisterReceiver(mRemovedReceiver);
+        mContext.unregisterReceiver(mUserReceiver);
+        mContext.unregisterReceiver(mShutdownReceiver);
+
+        if (!mSettings.getCombineSubtypeEnabled()) {
+            mNetworkStatsSubscriptionsMonitor.stop();
+        }
+
+        mContentResolver.unregisterContentObserver(mContentObserver);
+
+        final long currentTime = mClock.millis();
+
+        // persist any pending stats
+        mDevRecorder.forcePersistLocked(currentTime);
+        mXtRecorder.forcePersistLocked(currentTime);
+        mUidRecorder.forcePersistLocked(currentTime);
+        mUidTagRecorder.forcePersistLocked(currentTime);
+
+        mSystemReady = false;
+    }
+
+    @GuardedBy("mStatsLock")
+    private void maybeUpgradeLegacyStatsLocked() {
+        File file;
+        try {
+            file = new File(mSystemDir, "netstats.bin");
+            if (file.exists()) {
+                mDevRecorder.importLegacyNetworkLocked(file);
+                file.delete();
+            }
+
+            file = new File(mSystemDir, "netstats_xt.bin");
+            if (file.exists()) {
+                file.delete();
+            }
+
+            file = new File(mSystemDir, "netstats_uid.bin");
+            if (file.exists()) {
+                mUidRecorder.importLegacyUidLocked(file);
+                mUidTagRecorder.importLegacyUidLocked(file);
+                file.delete();
+            }
+        } catch (IOException e) {
+            Log.wtf(TAG, "problem during legacy upgrade", e);
+        } catch (OutOfMemoryError e) {
+            Log.wtf(TAG, "problem during legacy upgrade", e);
+        }
+    }
+
+    /**
+     * Register for a global alert that is delivered through {@link AlertObserver}
+     * or {@link NetworkStatsProviderCallback#onAlertReached()} once a threshold amount of data has
+     * been transferred.
+     */
+    private void registerGlobalAlert() {
+        try {
+            mNetd.bandwidthSetGlobalAlert(mGlobalAlertBytes);
+        } catch (IllegalStateException e) {
+            Log.w(TAG, "problem registering for global alert: " + e);
+        } catch (RemoteException e) {
+            // ignored; service lives in system_server
+        }
+        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes));
+    }
+
+    @Override
+    public INetworkStatsSession openSession() {
+        return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
+    }
+
+    @Override
+    public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
+        return openSessionInternal(flags, callingPackage);
+    }
+
+    private boolean isRateLimitedForPoll(int callingUid) {
+        if (callingUid == android.os.Process.SYSTEM_UID) {
+            return false;
+        }
+
+        final long lastCallTime;
+        final long now = SystemClock.elapsedRealtime();
+        synchronized (mOpenSessionCallsPerUid) {
+            int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
+            mOpenSessionCallsPerUid.put(callingUid, calls + 1);
+            lastCallTime = mLastStatsSessionPoll;
+            mLastStatsSessionPoll = now;
+        }
+
+        return now - lastCallTime < POLL_RATE_LIMIT_MS;
+    }
+
+    private int restrictFlagsForCaller(int flags) {
+        // All non-privileged callers are not allowed to turn off POLL_ON_OPEN.
+        final boolean isPrivileged = PermissionUtils.checkAnyPermissionOf(mContext,
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+                android.Manifest.permission.NETWORK_STACK);
+        if (!isPrivileged) {
+            flags |= NetworkStatsManager.FLAG_POLL_ON_OPEN;
+        }
+        // Non-system uids are rate limited for POLL_ON_OPEN.
+        final int callingUid = Binder.getCallingUid();
+        flags = isRateLimitedForPoll(callingUid)
+                ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
+                : flags;
+        return flags;
+    }
+
+    private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
+        final int restrictedFlags = restrictFlagsForCaller(flags);
+        if ((restrictedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
+                | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                performPoll(FLAG_PERSIST_ALL);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        // return an IBinder which holds strong references to any loaded stats
+        // for its lifetime; when caller closes only weak references remain.
+
+        return new INetworkStatsSession.Stub() {
+            private final int mCallingUid = Binder.getCallingUid();
+            private final String mCallingPackage = callingPackage;
+            private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
+                    callingPackage);
+
+            private NetworkStatsCollection mUidComplete;
+            private NetworkStatsCollection mUidTagComplete;
+
+            private NetworkStatsCollection getUidComplete() {
+                synchronized (mStatsLock) {
+                    if (mUidComplete == null) {
+                        mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
+                    }
+                    return mUidComplete;
+                }
+            }
+
+            private NetworkStatsCollection getUidTagComplete() {
+                synchronized (mStatsLock) {
+                    if (mUidTagComplete == null) {
+                        mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
+                    }
+                    return mUidTagComplete;
+                }
+            }
+
+            @Override
+            public int[] getRelevantUids() {
+                return getUidComplete().getRelevantUids(mAccessLevel);
+            }
+
+            @Override
+            public NetworkStats getDeviceSummaryForNetwork(
+                    NetworkTemplate template, long start, long end) {
+                enforceTemplatePermissions(template, callingPackage);
+                return internalGetSummaryForNetwork(template, restrictedFlags, start, end,
+                        mAccessLevel, mCallingUid);
+            }
+
+            @Override
+            public NetworkStats getSummaryForNetwork(
+                    NetworkTemplate template, long start, long end) {
+                enforceTemplatePermissions(template, callingPackage);
+                return internalGetSummaryForNetwork(template, restrictedFlags, start, end,
+                        mAccessLevel, mCallingUid);
+            }
+
+            // TODO: Remove this after all callers are removed.
+            @Override
+            public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
+                enforceTemplatePermissions(template, callingPackage);
+                return internalGetHistoryForNetwork(template, restrictedFlags, fields,
+                        mAccessLevel, mCallingUid, Long.MIN_VALUE, Long.MAX_VALUE);
+            }
+
+            @Override
+            public NetworkStatsHistory getHistoryIntervalForNetwork(NetworkTemplate template,
+                    int fields, long start, long end) {
+                enforceTemplatePermissions(template, callingPackage);
+                // TODO(b/200768422): Redact returned history if the template is location
+                //  sensitive but the caller is not privileged.
+                return internalGetHistoryForNetwork(template, restrictedFlags, fields,
+                        mAccessLevel, mCallingUid, start, end);
+            }
+
+            @Override
+            public NetworkStats getSummaryForAllUid(
+                    NetworkTemplate template, long start, long end, boolean includeTags) {
+                enforceTemplatePermissions(template, callingPackage);
+                try {
+                    final NetworkStats stats = getUidComplete()
+                            .getSummary(template, start, end, mAccessLevel, mCallingUid);
+                    if (includeTags) {
+                        final NetworkStats tagStats = getUidTagComplete()
+                                .getSummary(template, start, end, mAccessLevel, mCallingUid);
+                        stats.combineAllValues(tagStats);
+                    }
+                    return stats;
+                } catch (NullPointerException e) {
+                    throw e;
+                }
+            }
+
+            @Override
+            public NetworkStats getTaggedSummaryForAllUid(
+                    NetworkTemplate template, long start, long end) {
+                enforceTemplatePermissions(template, callingPackage);
+                try {
+                    final NetworkStats tagStats = getUidTagComplete()
+                            .getSummary(template, start, end, mAccessLevel, mCallingUid);
+                    return tagStats;
+                } catch (NullPointerException e) {
+                    throw e;
+                }
+            }
+
+            @Override
+            public NetworkStatsHistory getHistoryForUid(
+                    NetworkTemplate template, int uid, int set, int tag, int fields) {
+                enforceTemplatePermissions(template, callingPackage);
+                // NOTE: We don't augment UID-level statistics
+                if (tag == TAG_NONE) {
+                    return getUidComplete().getHistory(template, null, uid, set, tag, fields,
+                            Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
+                } else {
+                    return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
+                            Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
+                }
+            }
+
+            @Override
+            public NetworkStatsHistory getHistoryIntervalForUid(
+                    NetworkTemplate template, int uid, int set, int tag, int fields,
+                    long start, long end) {
+                enforceTemplatePermissions(template, callingPackage);
+                // TODO(b/200768422): Redact returned history if the template is location
+                //  sensitive but the caller is not privileged.
+                // NOTE: We don't augment UID-level statistics
+                if (tag == TAG_NONE) {
+                    return getUidComplete().getHistory(template, null, uid, set, tag, fields,
+                            start, end, mAccessLevel, mCallingUid);
+                } else if (uid == Binder.getCallingUid()) {
+                    return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
+                            start, end, mAccessLevel, mCallingUid);
+                } else {
+                    throw new SecurityException("Calling package " + mCallingPackage
+                            + " cannot access tag information from a different uid");
+                }
+            }
+
+            @Override
+            public void close() {
+                mUidComplete = null;
+                mUidTagComplete = null;
+            }
+        };
+    }
+
+    private void enforceTemplatePermissions(@NonNull NetworkTemplate template,
+            @NonNull String callingPackage) {
+        // For a template with wifi network keys, it is possible for a malicious
+        // client to track the user locations via querying data usage. Thus, enforce
+        // fine location permission check.
+        if (!template.getWifiNetworkKeys().isEmpty()) {
+            final boolean canAccessFineLocation = mLocationPermissionChecker
+                    .checkCallersLocationPermission(callingPackage,
+                    null /* featureId */,
+                            Binder.getCallingUid(),
+                            false /* coarseForTargetSdkLessThanQ */,
+                            null /* message */);
+            if (!canAccessFineLocation) {
+                throw new SecurityException("Access fine location is required when querying"
+                        + " with wifi network keys, make sure the app has the necessary"
+                        + "permissions and the location toggle is on.");
+            }
+        }
+    }
+
+    private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
+        return NetworkStatsAccess.checkAccessLevel(
+                mContext, Binder.getCallingPid(), Binder.getCallingUid(), callingPackage);
+    }
+
+    /**
+     * Find the most relevant {@link SubscriptionPlan} for the given
+     * {@link NetworkTemplate} and flags. This is typically used to augment
+     * local measurement results to match a known anchor from the carrier.
+     */
+    private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
+        SubscriptionPlan plan = null;
+        if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
+                && mSettings.getAugmentEnabled()) {
+            if (LOGD) Log.d(TAG, "Resolving plan for " + template);
+            final long token = Binder.clearCallingIdentity();
+            try {
+                plan = mContext.getSystemService(NetworkPolicyManager.class)
+                        .getSubscriptionPlan(template);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+            if (LOGD) Log.d(TAG, "Resolved to plan " + plan);
+        }
+        return plan;
+    }
+
+    /**
+     * Return network summary, splicing between DEV and XT stats when
+     * appropriate.
+     */
+    private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
+            long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
+        // We've been using pure XT stats long enough that we no longer need to
+        // splice DEV and XT together.
+        final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
+                accessLevel, callingUid, start, end);
+
+        final long now = System.currentTimeMillis();
+        final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
+
+        final NetworkStats stats = new NetworkStats(end - start, 1);
+        stats.insertEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
+                entry.txBytes, entry.txPackets, entry.operations));
+        return stats;
+    }
+
+    /**
+     * Return network history, splicing between DEV and XT stats when
+     * appropriate.
+     */
+    private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
+            int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid,
+            long start, long end) {
+        // We've been using pure XT stats long enough that we no longer need to
+        // splice DEV and XT together.
+        final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
+        synchronized (mStatsLock) {
+            return mXtStatsCached.getHistory(template, augmentPlan,
+                    UID_ALL, SET_ALL, TAG_NONE, fields, start, end, accessLevel, callingUid);
+        }
+    }
+
+    private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
+        assertSystemReady();
+
+        return internalGetSummaryForNetwork(template,
+                NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
+                NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
+    }
+
+    private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
+        assertSystemReady();
+
+        final NetworkStatsCollection uidComplete;
+        synchronized (mStatsLock) {
+            uidComplete = mUidRecorder.getOrLoadCompleteLocked();
+        }
+        return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
+                android.os.Process.SYSTEM_UID);
+    }
+
+    @Override
+    public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
+        if (Binder.getCallingUid() != uid) {
+            Log.w(TAG, "Snapshots only available for calling UID");
+            return new NetworkStats(SystemClock.elapsedRealtime(), 0);
+        }
+
+        // TODO: switch to data layer stats once kernel exports
+        // for now, read network layer stats and flatten across all ifaces.
+        // This function is used to query NeworkStats for calle's uid. The only caller method
+        // TrafficStats#getDataLayerSnapshotForUid alrady claim no special permission to query
+        // its own NetworkStats.
+        final long ident = Binder.clearCallingIdentity();
+        final NetworkStats networkLayer;
+        try {
+            networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+
+        // splice in operation counts
+        networkLayer.spliceOperationsFrom(mUidOperations);
+
+        final NetworkStats dataLayer = new NetworkStats(
+                networkLayer.getElapsedRealtime(), networkLayer.size());
+
+        NetworkStats.Entry entry = null;
+        for (int i = 0; i < networkLayer.size(); i++) {
+            entry = networkLayer.getValues(i, entry);
+            entry.iface = IFACE_ALL;
+            dataLayer.combineValues(entry);
+        }
+
+        return dataLayer;
+    }
+
+    @Override
+    public NetworkStats getUidStatsForTransport(int transport) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
+        try {
+            final String[] relevantIfaces =
+                    transport == TRANSPORT_WIFI ? mWifiIfaces : mMobileIfaces;
+            // TODO(b/215633405) : mMobileIfaces and mWifiIfaces already contain the stacked
+            // interfaces, so this is not useful, remove it.
+            final String[] ifacesToQuery =
+                    mStatsFactory.augmentWithStackedInterfaces(relevantIfaces);
+            return getNetworkStatsUidDetail(ifacesToQuery);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error compiling UID stats", e);
+            return new NetworkStats(0L, 0);
+        }
+    }
+
+    @Override
+    public String[] getMobileIfaces() {
+        // TODO (b/192758557): Remove debug log.
+        if (CollectionUtils.contains(mMobileIfaces, null)) {
+            throw new NullPointerException(
+                    "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces));
+        }
+        return mMobileIfaces.clone();
+    }
+
+    @Override
+    public void incrementOperationCount(int uid, int tag, int operationCount) {
+        if (Binder.getCallingUid() != uid) {
+            mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
+        }
+
+        if (operationCount < 0) {
+            throw new IllegalArgumentException("operation count can only be incremented");
+        }
+        if (tag == TAG_NONE) {
+            throw new IllegalArgumentException("operation count must have specific tag");
+        }
+
+        synchronized (mStatsLock) {
+            final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
+            mUidOperations.combineValues(
+                    mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
+            mUidOperations.combineValues(
+                    mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
+        }
+    }
+
+    private void setKernelCounterSet(int uid, int set) {
+        if (mUidCounterSetMap == null) {
+            Log.wtf(TAG, "Fail to set UidCounterSet: Null bpf map");
+            return;
+        }
+
+        if (set == SET_DEFAULT) {
+            try {
+                mUidCounterSetMap.deleteEntry(new U32(uid));
+            } catch (ErrnoException e) {
+                Log.w(TAG, "UidCounterSetMap.deleteEntry(" + uid + ") failed with errno: " + e);
+            }
+            return;
+        }
+
+        try {
+            mUidCounterSetMap.updateEntry(new U32(uid), new U8((short) set));
+        } catch (ErrnoException e) {
+            Log.w(TAG, "UidCounterSetMap.updateEntry(" + uid + ", " + set
+                    + ") failed with errno: " + e);
+        }
+    }
+
+    @VisibleForTesting
+    public void noteUidForeground(int uid, boolean uidForeground) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
+        synchronized (mStatsLock) {
+            final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
+            final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
+            if (oldSet != set) {
+                mActiveUidCounterSet.put(uid, set);
+                setKernelCounterSet(uid, set);
+            }
+        }
+    }
+
+    /**
+     * Notify {@code NetworkStatsService} about network status changed.
+     */
+    public void notifyNetworkStatus(
+            @NonNull Network[] defaultNetworks,
+            @NonNull NetworkStateSnapshot[] networkStates,
+            @Nullable String activeIface,
+            @NonNull UnderlyingNetworkInfo[] underlyingNetworkInfos) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            handleNotifyNetworkStatus(defaultNetworks, networkStates, activeIface);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+
+        // Update the VPN underlying interfaces only after the poll is made and tun data has been
+        // migrated. Otherwise the migration would use the new interfaces instead of the ones that
+        // were current when the polled data was transferred.
+        mStatsFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
+    }
+
+    @Override
+    public void forceUpdate() {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            performPoll(FLAG_PERSIST_ALL);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /** Advise persistence threshold; may be overridden internally. */
+    public void advisePersistThreshold(long thresholdBytes) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
+        // clamp threshold into safe range
+        mPersistThreshold = NetworkStatsUtils.constrain(thresholdBytes,
+                128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
+        if (LOGV) {
+            Log.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
+                    + mPersistThreshold);
+        }
+
+        final long oldGlobalAlertBytes = mGlobalAlertBytes;
+
+        // update and persist if beyond new thresholds
+        final long currentTime = mClock.millis();
+        synchronized (mStatsLock) {
+            if (!mSystemReady) return;
+
+            updatePersistThresholdsLocked();
+
+            mDevRecorder.maybePersistLocked(currentTime);
+            mXtRecorder.maybePersistLocked(currentTime);
+            mUidRecorder.maybePersistLocked(currentTime);
+            mUidTagRecorder.maybePersistLocked(currentTime);
+        }
+
+        if (oldGlobalAlertBytes != mGlobalAlertBytes) {
+            registerGlobalAlert();
+        }
+    }
+
+    @Override
+    public DataUsageRequest registerUsageCallback(@NonNull String callingPackage,
+                @NonNull DataUsageRequest request, @NonNull IUsageCallback callback) {
+        Objects.requireNonNull(callingPackage, "calling package is null");
+        Objects.requireNonNull(request, "DataUsageRequest is null");
+        Objects.requireNonNull(request.template, "NetworkTemplate is null");
+        Objects.requireNonNull(callback, "callback is null");
+
+        int callingUid = Binder.getCallingUid();
+        @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
+        DataUsageRequest normalizedRequest;
+        final long token = Binder.clearCallingIdentity();
+        try {
+            normalizedRequest = mStatsObservers.register(mContext,
+                    request, callback, callingUid, accessLevel);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+
+        // Create baseline stats
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
+
+        return normalizedRequest;
+   }
+
+    @Override
+    public void unregisterUsageRequest(DataUsageRequest request) {
+        Objects.requireNonNull(request, "DataUsageRequest is null");
+
+        int callingUid = Binder.getCallingUid();
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mStatsObservers.unregister(request, callingUid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public long getUidStats(int uid, int type) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != android.os.Process.SYSTEM_UID && callingUid != uid) {
+            return UNSUPPORTED;
+        }
+        return nativeGetUidStat(uid, type);
+    }
+
+    @Override
+    public long getIfaceStats(@NonNull String iface, int type) {
+        Objects.requireNonNull(iface);
+        long nativeIfaceStats = nativeGetIfaceStat(iface, type);
+        if (nativeIfaceStats == -1) {
+            return nativeIfaceStats;
+        } else {
+            // When tethering offload is in use, nativeIfaceStats does not contain usage from
+            // offload, add it back here. Note that the included statistics might be stale
+            // since polling newest stats from hardware might impact system health and not
+            // suitable for TrafficStats API use cases.
+            return nativeIfaceStats + getProviderIfaceStats(iface, type);
+        }
+    }
+
+    @Override
+    public long getTotalStats(int type) {
+        long nativeTotalStats = nativeGetTotalStat(type);
+        if (nativeTotalStats == -1) {
+            return nativeTotalStats;
+        } else {
+            // Refer to comment in getIfaceStats
+            return nativeTotalStats + getProviderIfaceStats(IFACE_ALL, type);
+        }
+    }
+
+    private long getProviderIfaceStats(@Nullable String iface, int type) {
+        final NetworkStats providerSnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE);
+        final HashSet<String> limitIfaces;
+        if (iface == IFACE_ALL) {
+            limitIfaces = null;
+        } else {
+            limitIfaces = new HashSet<>();
+            limitIfaces.add(iface);
+        }
+        final NetworkStats.Entry entry = providerSnapshot.getTotal(null, limitIfaces);
+        switch (type) {
+            case TrafficStats.TYPE_RX_BYTES:
+                return entry.rxBytes;
+            case TrafficStats.TYPE_RX_PACKETS:
+                return entry.rxPackets;
+            case TrafficStats.TYPE_TX_BYTES:
+                return entry.txBytes;
+            case TrafficStats.TYPE_TX_PACKETS:
+                return entry.txPackets;
+            default:
+                return 0;
+        }
+    }
+
+    /**
+     * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
+     * reflect current {@link #mPersistThreshold} value. Always defers to
+     * {@link Global} values when defined.
+     */
+    @GuardedBy("mStatsLock")
+    private void updatePersistThresholdsLocked() {
+        mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
+        mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
+        mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
+        mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
+        mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
+    }
+
+    /**
+     * Listener that watches for {@link TetheringManager} to claim interface pairs.
+     */
+    private final TetheringManager.TetheringEventCallback mTetherListener =
+            new TetheringManager.TetheringEventCallback() {
+                @Override
+                public void onUpstreamChanged(@Nullable Network network) {
+                    performPoll(FLAG_PERSIST_NETWORK);
+                }
+            };
+
+    private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // on background handler thread, and verified UPDATE_DEVICE_STATS
+            // permission above.
+            performPoll(FLAG_PERSIST_ALL);
+
+            // verify that we're watching global alert
+            registerGlobalAlert();
+        }
+    };
+
+    private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // on background handler thread, and UID_REMOVED is protected
+            // broadcast.
+
+            final int uid = intent.getIntExtra(EXTRA_UID, -1);
+            if (uid == -1) return;
+
+            synchronized (mStatsLock) {
+                mWakeLock.acquire();
+                try {
+                    removeUidsLocked(uid);
+                } finally {
+                    mWakeLock.release();
+                }
+            }
+        }
+    };
+
+    private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // On background handler thread, and USER_REMOVED is protected
+            // broadcast.
+
+            final UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
+            if (userHandle == null) return;
+
+            synchronized (mStatsLock) {
+                mWakeLock.acquire();
+                try {
+                    removeUserLocked(userHandle);
+                } finally {
+                    mWakeLock.release();
+                }
+            }
+        }
+    };
+
+    private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // SHUTDOWN is protected broadcast.
+            synchronized (mStatsLock) {
+                shutdownLocked();
+            }
+        }
+    };
+
+    /**
+     * Handle collapsed RAT type changed event.
+     */
+    @VisibleForTesting
+    public void handleOnCollapsedRatTypeChanged() {
+        // Protect service from frequently updating. Remove pending messages if any.
+        mHandler.removeMessages(MSG_NOTIFY_NETWORK_STATUS);
+        mHandler.sendMessageDelayed(
+                mHandler.obtainMessage(MSG_NOTIFY_NETWORK_STATUS), mSettings.getPollDelay());
+    }
+
+    private void handleNotifyNetworkStatus(
+            Network[] defaultNetworks,
+            NetworkStateSnapshot[] snapshots,
+            String activeIface) {
+        synchronized (mStatsLock) {
+            mWakeLock.acquire();
+            try {
+                mActiveIface = activeIface;
+                handleNotifyNetworkStatusLocked(defaultNetworks, snapshots);
+            } finally {
+                mWakeLock.release();
+            }
+        }
+    }
+
+    /**
+     * Inspect all current {@link NetworkStateSnapshot}s to derive mapping from {@code iface} to
+     * {@link NetworkStatsHistory}. When multiple networks are active on a single {@code iface},
+     * they are combined under a single {@link NetworkIdentitySet}.
+     */
+    @GuardedBy("mStatsLock")
+    private void handleNotifyNetworkStatusLocked(@NonNull Network[] defaultNetworks,
+            @NonNull NetworkStateSnapshot[] snapshots) {
+        if (!mSystemReady) return;
+        if (LOGV) Log.v(TAG, "handleNotifyNetworkStatusLocked()");
+
+        // take one last stats snapshot before updating iface mapping. this
+        // isn't perfect, since the kernel may already be counting traffic from
+        // the updated network.
+
+        // poll, but only persist network stats to keep codepath fast. UID stats
+        // will be persisted during next alarm poll event.
+        performPollLocked(FLAG_PERSIST_NETWORK);
+
+        // Rebuild active interfaces based on connected networks
+        mActiveIfaces.clear();
+        mActiveUidIfaces.clear();
+        // Update the list of default networks.
+        mDefaultNetworks = defaultNetworks;
+
+        mLastNetworkStateSnapshots = snapshots;
+
+        final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
+        final ArraySet<String> mobileIfaces = new ArraySet<>();
+        final ArraySet<String> wifiIfaces = new ArraySet<>();
+        for (NetworkStateSnapshot snapshot : snapshots) {
+            final int displayTransport =
+                    getDisplayTransport(snapshot.getNetworkCapabilities().getTransportTypes());
+            final boolean isMobile = (NetworkCapabilities.TRANSPORT_CELLULAR == displayTransport);
+            final boolean isWifi = (NetworkCapabilities.TRANSPORT_WIFI == displayTransport);
+            final boolean isDefault = CollectionUtils.contains(
+                    mDefaultNetworks, snapshot.getNetwork());
+            final int ratType = combineSubtypeEnabled ? NetworkTemplate.NETWORK_TYPE_ALL
+                    : getRatTypeForStateSnapshot(snapshot);
+            final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot,
+                    isDefault, ratType);
+
+            // Traffic occurring on the base interface is always counted for
+            // both total usage and UID details.
+            final String baseIface = snapshot.getLinkProperties().getInterfaceName();
+            if (baseIface != null) {
+                findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
+                findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
+
+                // Build a separate virtual interface for VT (Video Telephony) data usage.
+                // Only do this when IMS is not metered, but VT is metered.
+                // If IMS is metered, then the IMS network usage has already included VT usage.
+                // VT is considered always metered in framework's layer. If VT is not metered
+                // per carrier's policy, modem will report 0 usage for VT calls.
+                if (snapshot.getNetworkCapabilities().hasCapability(
+                        NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.isMetered()) {
+
+                    // Copy the identify from IMS one but mark it as metered.
+                    NetworkIdentity vtIdent = new NetworkIdentity.Builder()
+                            .setType(ident.getType())
+                            .setRatType(ident.getRatType())
+                            .setSubscriberId(ident.getSubscriberId())
+                            .setWifiNetworkKey(ident.getWifiNetworkKey())
+                            .setRoaming(ident.isRoaming()).setMetered(true)
+                            .setDefaultNetwork(true)
+                            .setOemManaged(ident.getOemManaged())
+                            .setSubId(ident.getSubId()).build();
+                    final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot);
+                    findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent);
+                    findOrCreateNetworkIdentitySet(mActiveUidIfaces, ifaceVt).add(vtIdent);
+                }
+
+                if (isMobile) {
+                    mobileIfaces.add(baseIface);
+                }
+                if (isWifi) {
+                    wifiIfaces.add(baseIface);
+                }
+            }
+
+            // Traffic occurring on stacked interfaces is usually clatd.
+            //
+            // UID stats are always counted on the stacked interface and never on the base
+            // interface, because the packets on the base interface do not actually match
+            // application sockets (they're not IPv4) and thus the app uid is not known.
+            // For receive this is obvious: packets must be translated from IPv6 to IPv4
+            // before the application socket can be found.
+            // For transmit: either they go through the clat daemon which by virtue of going
+            // through userspace strips the original socket association during the IPv4 to
+            // IPv6 translation process, or they are offloaded by eBPF, which doesn't:
+            // However, on an ebpf device the accounting is done in cgroup ebpf hooks,
+            // which don't trigger again post ebpf translation.
+            // (as such stats accounted to the clat uid are ignored)
+            //
+            // Interface stats are more complicated.
+            //
+            // eBPF offloaded 464xlat'ed packets never hit base interface ip6tables, and thus
+            // *all* statistics are collected by iptables on the stacked v4-* interface.
+            //
+            // Additionally for ingress all packets bound for the clat IPv6 address are dropped
+            // in ip6tables raw prerouting and thus even non-offloaded packets are only
+            // accounted for on the stacked interface.
+            //
+            // For egress, packets subject to eBPF offload never appear on the base interface
+            // and only appear on the stacked interface. Thus to ensure packets increment
+            // interface stats, we must collate data from stacked interfaces. For xt_qtaguid
+            // (or non eBPF offloaded) TX they would appear on both, however egress interface
+            // accounting is explicitly bypassed for traffic from the clat uid.
+            //
+            // TODO: This code might be combined to above code.
+            for (String iface : snapshot.getLinkProperties().getAllInterfaceNames()) {
+                // baseIface has been handled, so ignore it.
+                if (TextUtils.equals(baseIface, iface)) continue;
+                if (iface != null) {
+                    findOrCreateNetworkIdentitySet(mActiveIfaces, iface).add(ident);
+                    findOrCreateNetworkIdentitySet(mActiveUidIfaces, iface).add(ident);
+                    if (isMobile) {
+                        mobileIfaces.add(iface);
+                    }
+                    if (isWifi) {
+                        wifiIfaces.add(iface);
+                    }
+
+                    mStatsFactory.noteStackedIface(iface, baseIface);
+                }
+            }
+        }
+
+        mMobileIfaces = mobileIfaces.toArray(new String[0]);
+        mWifiIfaces = wifiIfaces.toArray(new String[0]);
+        // TODO (b/192758557): Remove debug log.
+        if (CollectionUtils.contains(mMobileIfaces, null)) {
+            throw new NullPointerException(
+                    "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces));
+        }
+        if (CollectionUtils.contains(mWifiIfaces, null)) {
+            throw new NullPointerException(
+                    "null element in mWifiIfaces: " + Arrays.toString(mWifiIfaces));
+        }
+    }
+
+    private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) {
+        if (!state.getNetworkCapabilities().hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+            throw new IllegalArgumentException("Mobile state need capability TRANSPORT_CELLULAR");
+        }
+
+        final NetworkSpecifier spec = state.getNetworkCapabilities().getNetworkSpecifier();
+        if (spec instanceof TelephonyNetworkSpecifier) {
+             return ((TelephonyNetworkSpecifier) spec).getSubscriptionId();
+        } else {
+            Log.wtf(TAG, "getSubIdForState invalid NetworkSpecifier");
+            return INVALID_SUBSCRIPTION_ID;
+        }
+    }
+
+    /**
+     * For networks with {@code TRANSPORT_CELLULAR}, get ratType that was obtained through
+     * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different
+     * transport types do not actually fill this value.
+     */
+    private int getRatTypeForStateSnapshot(@NonNull NetworkStateSnapshot state) {
+        if (!state.getNetworkCapabilities().hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+            return 0;
+        }
+
+        return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.getSubscriberId());
+    }
+
+    private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
+            ArrayMap<K, NetworkIdentitySet> map, K key) {
+        NetworkIdentitySet ident = map.get(key);
+        if (ident == null) {
+            ident = new NetworkIdentitySet();
+            map.put(key, ident);
+        }
+        return ident;
+    }
+
+    @GuardedBy("mStatsLock")
+    private void recordSnapshotLocked(long currentTime) throws RemoteException {
+        // snapshot and record current counters; read UID stats first to
+        // avoid over counting dev stats.
+        Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
+        final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+        Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
+        final NetworkStats xtSnapshot = readNetworkStatsSummaryXt();
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+        Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
+        final NetworkStats devSnapshot = readNetworkStatsSummaryDev();
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+
+        // Snapshot for dev/xt stats from all custom stats providers. Counts per-interface data
+        // from stats providers that isn't already counted by dev and XT stats.
+        Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotStatsProvider");
+        final NetworkStats providersnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE);
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+        xtSnapshot.combineAllValues(providersnapshot);
+        devSnapshot.combineAllValues(providersnapshot);
+
+        // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
+        // can't be reattributed to responsible apps.
+        Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
+        mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+        Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
+        mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+
+        // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
+        Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
+        mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+        Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
+        mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+
+        // We need to make copies of member fields that are sent to the observer to avoid
+        // a race condition between the service handler thread and the observer's
+        mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
+                new ArrayMap<>(mActiveUidIfaces), currentTime);
+    }
+
+    /**
+     * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
+     * so we have baseline values without double-counting.
+     */
+    @GuardedBy("mStatsLock")
+    private void bootstrapStatsLocked() {
+        final long currentTime = mClock.millis();
+
+        try {
+            recordSnapshotLocked(currentTime);
+        } catch (IllegalStateException e) {
+            Log.w(TAG, "problem reading network stats: " + e);
+        } catch (RemoteException e) {
+            // ignored; service lives in system_server
+        }
+    }
+
+    private void performPoll(int flags) {
+        synchronized (mStatsLock) {
+            mWakeLock.acquire();
+
+            try {
+                performPollLocked(flags);
+            } finally {
+                mWakeLock.release();
+            }
+        }
+    }
+
+    /**
+     * Periodic poll operation, reading current statistics and recording into
+     * {@link NetworkStatsHistory}.
+     */
+    @GuardedBy("mStatsLock")
+    private void performPollLocked(int flags) {
+        if (!mSystemReady) return;
+        if (LOGV) Log.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
+        Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
+
+        final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
+        final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
+        final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
+
+        performPollFromProvidersLocked();
+
+        // TODO: consider marking "untrusted" times in historical stats
+        final long currentTime = mClock.millis();
+
+        try {
+            recordSnapshotLocked(currentTime);
+        } catch (IllegalStateException e) {
+            Log.wtf(TAG, "problem reading network stats", e);
+            return;
+        } catch (RemoteException e) {
+            // ignored; service lives in system_server
+            return;
+        }
+
+        // persist any pending data depending on requested flags
+        Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
+        if (persistForce) {
+            mDevRecorder.forcePersistLocked(currentTime);
+            mXtRecorder.forcePersistLocked(currentTime);
+            mUidRecorder.forcePersistLocked(currentTime);
+            mUidTagRecorder.forcePersistLocked(currentTime);
+        } else {
+            if (persistNetwork) {
+                mDevRecorder.maybePersistLocked(currentTime);
+                mXtRecorder.maybePersistLocked(currentTime);
+            }
+            if (persistUid) {
+                mUidRecorder.maybePersistLocked(currentTime);
+                mUidTagRecorder.maybePersistLocked(currentTime);
+            }
+        }
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+
+        if (mSettings.getSampleEnabled()) {
+            // sample stats after each full poll
+            performSampleLocked();
+        }
+
+        // finally, dispatch updated event to any listeners
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_BROADCAST_NETWORK_STATS_UPDATED));
+
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+    }
+
+    @GuardedBy("mStatsLock")
+    private void performPollFromProvidersLocked() {
+        // Request asynchronous stats update from all providers for next poll. And wait a bit of
+        // time to allow providers report-in given that normally binder call should be fast. Note
+        // that size of list might be changed because addition/removing at the same time. For
+        // addition, the stats of the missed provider can only be collected in next poll;
+        // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS
+        // once that happened.
+        // TODO: request with a valid token.
+        Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
+        final int registeredCallbackCount = mStatsProviderCbList.size();
+        mStatsProviderSem.drainPermits();
+        invokeForAllStatsProviderCallbacks(
+                (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
+        try {
+            mStatsProviderSem.tryAcquire(registeredCallbackCount,
+                    MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            // Strictly speaking it's possible a provider happened to deliver between the timeout
+            // and the log, and that doesn't matter too much as this is just a debug log.
+            Log.d(TAG, "requestStatsUpdate - providers responded "
+                    + mStatsProviderSem.availablePermits()
+                    + "/" + registeredCallbackCount + " : " + e);
+        }
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+    }
+
+    /**
+     * Sample recent statistics summary into {@link EventLog}.
+     */
+    @GuardedBy("mStatsLock")
+    private void performSampleLocked() {
+        // TODO: migrate trustedtime fixes to separate binary log events
+        final long currentTime = mClock.millis();
+
+        NetworkTemplate template;
+        NetworkStats.Entry devTotal;
+        NetworkStats.Entry xtTotal;
+        NetworkStats.Entry uidTotal;
+
+        // collect mobile sample
+        template = buildTemplateMobileWildcard();
+        devTotal = mDevRecorder.getTotalSinceBootLocked(template);
+        xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
+        uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
+
+        EventLog.writeEvent(LOG_TAG_NETSTATS_MOBILE_SAMPLE,
+                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
+                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
+                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
+                currentTime);
+
+        // collect wifi sample
+        template = buildTemplateWifiWildcard();
+        devTotal = mDevRecorder.getTotalSinceBootLocked(template);
+        xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
+        uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
+
+        EventLog.writeEvent(LOG_TAG_NETSTATS_WIFI_SAMPLE,
+                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
+                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
+                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
+                currentTime);
+    }
+
+    // deleteKernelTagData can ignore ENOENT; otherwise we should log an error
+    private void logErrorIfNotErrNoent(final ErrnoException e, final String msg) {
+        if (e.errno != ENOENT) Log.e(TAG, msg, e);
+    }
+
+    private <K extends StatsMapKey, V extends StatsMapValue> void deleteStatsMapTagData(
+            IBpfMap<K, V> statsMap, int uid) {
+        try {
+            statsMap.forEach((key, value) -> {
+                if (key.uid == uid) {
+                    try {
+                        statsMap.deleteEntry(key);
+                    } catch (ErrnoException e) {
+                        logErrorIfNotErrNoent(e, "Failed to delete data(uid = " + key.uid + ")");
+                    }
+                }
+            });
+        } catch (ErrnoException e) {
+            Log.e(TAG, "FAILED to delete tag data from stats map", e);
+        }
+    }
+
+    /**
+     * Deletes uid tag data from CookieTagMap, StatsMapA, StatsMapB, and UidStatsMap
+     * @param uid
+     */
+    private void deleteKernelTagData(int uid) {
+        try {
+            mCookieTagMap.forEach((key, value) -> {
+                // If SkDestroyListener deletes the socket tag while this code is running,
+                // forEach will either restart iteration from the beginning or return null,
+                // depending on when the deletion happens.
+                // If it returns null, continue iteration to delete the data and in fact it would
+                // just iterate from first key because BpfMap#getNextKey would return first key
+                // if the current key is not exist.
+                if (value != null && value.uid == uid) {
+                    try {
+                        mCookieTagMap.deleteEntry(key);
+                    } catch (ErrnoException e) {
+                        logErrorIfNotErrNoent(e, "Failed to delete data(cookie = " + key + ")");
+                    }
+                }
+            });
+        } catch (ErrnoException e) {
+            Log.e(TAG, "Failed to delete tag data from cookie tag map", e);
+        }
+
+        deleteStatsMapTagData(mStatsMapA, uid);
+        deleteStatsMapTagData(mStatsMapB, uid);
+
+        try {
+            mUidCounterSetMap.deleteEntry(new U32(uid));
+        } catch (ErrnoException e) {
+            logErrorIfNotErrNoent(e, "Failed to delete tag data from uid counter set map");
+        }
+
+        try {
+            mAppUidStatsMap.deleteEntry(new UidStatsMapKey(uid));
+        } catch (ErrnoException e) {
+            logErrorIfNotErrNoent(e, "Failed to delete tag data from app uid stats map");
+        }
+    }
+
+    /**
+     * Clean up {@link #mUidRecorder} after UID is removed.
+     */
+    @GuardedBy("mStatsLock")
+    private void removeUidsLocked(int... uids) {
+        if (LOGV) Log.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
+
+        // Perform one last poll before removing
+        performPollLocked(FLAG_PERSIST_ALL);
+
+        mUidRecorder.removeUidsLocked(uids);
+        mUidTagRecorder.removeUidsLocked(uids);
+
+        // Clear kernel stats associated with UID
+        for (int uid : uids) {
+            deleteKernelTagData(uid);
+        }
+    }
+
+    /**
+     * Clean up {@link #mUidRecorder} after user is removed.
+     */
+    @GuardedBy("mStatsLock")
+    private void removeUserLocked(@NonNull UserHandle userHandle) {
+        if (LOGV) Log.v(TAG, "removeUserLocked() for UserHandle=" + userHandle);
+
+        // Build list of UIDs that we should clean up
+        final ArrayList<Integer> uids = new ArrayList<>();
+        final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
+                PackageManager.MATCH_ANY_USER
+                | PackageManager.MATCH_DISABLED_COMPONENTS);
+        for (ApplicationInfo app : apps) {
+            final int uid = userHandle.getUid(app.uid);
+            uids.add(uid);
+        }
+
+        removeUidsLocked(CollectionUtils.toIntArray(uids));
+    }
+
+    /**
+     * Set the warning and limit to all registered custom network stats providers.
+     * Note that invocation of any interface will be sent to all providers.
+     */
+    public void setStatsProviderWarningAndLimitAsync(
+            @NonNull String iface, long warning, long limit) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
+        if (LOGV) {
+            Log.v(TAG, "setStatsProviderWarningAndLimitAsync("
+                    + iface + "," + warning + "," + limit + ")");
+        }
+        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetWarningAndLimit(iface,
+                warning, limit));
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
+        if (!PermissionUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
+
+        long duration = DateUtils.DAY_IN_MILLIS;
+        final HashSet<String> argSet = new HashSet<String>();
+        for (String arg : args) {
+            argSet.add(arg);
+
+            if (arg.startsWith("--duration=")) {
+                try {
+                    duration = Long.parseLong(arg.substring(11));
+                } catch (NumberFormatException ignored) {
+                }
+            }
+        }
+
+        // usage: dumpsys netstats --full --uid --tag --poll --checkin
+        final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
+        final boolean checkin = argSet.contains("--checkin");
+        final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
+        final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
+        final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
+
+        final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, "  ");
+
+        synchronized (mStatsLock) {
+            if (args.length > 0 && "--proto".equals(args[0])) {
+                // In this case ignore all other arguments.
+                dumpProtoLocked(fd);
+                return;
+            }
+
+            if (poll) {
+                performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
+                pw.println("Forced poll");
+                return;
+            }
+
+            if (checkin) {
+                final long end = System.currentTimeMillis();
+                final long start = end - duration;
+
+                pw.print("v1,");
+                pw.print(start / SECOND_IN_MILLIS); pw.print(',');
+                pw.print(end / SECOND_IN_MILLIS); pw.println();
+
+                pw.println("xt");
+                mXtRecorder.dumpCheckin(rawWriter, start, end);
+
+                if (includeUid) {
+                    pw.println("uid");
+                    mUidRecorder.dumpCheckin(rawWriter, start, end);
+                }
+                if (includeTag) {
+                    pw.println("tag");
+                    mUidTagRecorder.dumpCheckin(rawWriter, start, end);
+                }
+                return;
+            }
+
+            pw.println("Configs:");
+            pw.increaseIndent();
+            pw.print(NETSTATS_COMBINE_SUBTYPE_ENABLED, mSettings.getCombineSubtypeEnabled());
+            pw.println();
+            pw.decreaseIndent();
+
+            pw.println("Active interfaces:");
+            pw.increaseIndent();
+            for (int i = 0; i < mActiveIfaces.size(); i++) {
+                pw.print("iface", mActiveIfaces.keyAt(i));
+                pw.print("ident", mActiveIfaces.valueAt(i));
+                pw.println();
+            }
+            pw.decreaseIndent();
+
+            pw.println("Active UID interfaces:");
+            pw.increaseIndent();
+            for (int i = 0; i < mActiveUidIfaces.size(); i++) {
+                pw.print("iface", mActiveUidIfaces.keyAt(i));
+                pw.print("ident", mActiveUidIfaces.valueAt(i));
+                pw.println();
+            }
+            pw.decreaseIndent();
+
+            // Get the top openSession callers
+            final SparseIntArray calls;
+            synchronized (mOpenSessionCallsPerUid) {
+                calls = mOpenSessionCallsPerUid.clone();
+            }
+
+            final int N = calls.size();
+            final long[] values = new long[N];
+            for (int j = 0; j < N; j++) {
+                values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
+            }
+            Arrays.sort(values);
+
+            pw.println("Top openSession callers (uid=count):");
+            pw.increaseIndent();
+            final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
+            for (int j = N - 1; j >= end; j--) {
+                final int uid = (int) (values[j] & 0xffffffff);
+                final int count = (int) (values[j] >> 32);
+                pw.print(uid); pw.print("="); pw.println(count);
+            }
+            pw.decreaseIndent();
+            pw.println();
+
+            pw.println("Stats Providers:");
+            pw.increaseIndent();
+            invokeForAllStatsProviderCallbacks((cb) -> {
+                pw.println(cb.mTag + " Xt:");
+                pw.increaseIndent();
+                pw.print(cb.getCachedStats(STATS_PER_IFACE).toString());
+                pw.decreaseIndent();
+                if (includeUid) {
+                    pw.println(cb.mTag + " Uid:");
+                    pw.increaseIndent();
+                    pw.print(cb.getCachedStats(STATS_PER_UID).toString());
+                    pw.decreaseIndent();
+                }
+            });
+            pw.decreaseIndent();
+
+            pw.println("Dev stats:");
+            pw.increaseIndent();
+            mDevRecorder.dumpLocked(pw, fullHistory);
+            pw.decreaseIndent();
+
+            pw.println("Xt stats:");
+            pw.increaseIndent();
+            mXtRecorder.dumpLocked(pw, fullHistory);
+            pw.decreaseIndent();
+
+            if (includeUid) {
+                pw.println("UID stats:");
+                pw.increaseIndent();
+                mUidRecorder.dumpLocked(pw, fullHistory);
+                pw.decreaseIndent();
+            }
+
+            if (includeTag) {
+                pw.println("UID tag stats:");
+                pw.increaseIndent();
+                mUidTagRecorder.dumpLocked(pw, fullHistory);
+                pw.decreaseIndent();
+            }
+        }
+    }
+
+    @GuardedBy("mStatsLock")
+    private void dumpProtoLocked(FileDescriptor fd) {
+        final ProtoOutputStream proto = new ProtoOutputStream(new FileOutputStream(fd));
+
+        // TODO Right now it writes all history.  Should it limit to the "since-boot" log?
+
+        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES,
+                mActiveIfaces);
+        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES,
+                mActiveUidIfaces);
+        mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
+        mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
+        mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
+        mUidTagRecorder.dumpDebugLocked(proto,
+                NetworkStatsServiceDumpProto.UID_TAG_STATS);
+
+        proto.flush();
+    }
+
+    private static void dumpInterfaces(ProtoOutputStream proto, long tag,
+            ArrayMap<String, NetworkIdentitySet> ifaces) {
+        for (int i = 0; i < ifaces.size(); i++) {
+            final long start = proto.start(tag);
+
+            proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
+            ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES);
+
+            proto.end(start);
+        }
+    }
+
+    private NetworkStats readNetworkStatsSummaryDev() {
+        try {
+            return mStatsFactory.readNetworkStatsSummaryDev();
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private NetworkStats readNetworkStatsSummaryXt() {
+        try {
+            return mStatsFactory.readNetworkStatsSummaryXt();
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private NetworkStats readNetworkStatsUidDetail(int uid, String[] ifaces, int tag) {
+        try {
+            return mStatsFactory.readNetworkStatsDetail(uid, ifaces, tag);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    /**
+     * Return snapshot of current UID statistics, including any
+     * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
+     * values.
+     *
+     * @param ifaces A list of interfaces the stats should be restricted to, or
+     *               {@link NetworkStats#INTERFACES_ALL}.
+     */
+    private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
+            throws RemoteException {
+        final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL,  ifaces, TAG_ALL);
+
+        // fold tethering stats and operations into uid snapshot
+        final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
+        tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
+        mStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot);
+        uidSnapshot.combineAllValues(tetherSnapshot);
+
+        // get a stale copy of uid stats snapshot provided by providers.
+        final NetworkStats providerStats = getNetworkStatsFromProviders(STATS_PER_UID);
+        providerStats.filter(UID_ALL, ifaces, TAG_ALL);
+        mStatsFactory.apply464xlatAdjustments(uidSnapshot, providerStats);
+        uidSnapshot.combineAllValues(providerStats);
+
+        uidSnapshot.combineAllValues(mUidOperations);
+
+        return uidSnapshot;
+    }
+
+    /**
+     * Return snapshot of current non-offloaded tethering statistics. Will return empty
+     * {@link NetworkStats} if any problems are encountered, or queried by {@code STATS_PER_IFACE}
+     * since it is already included by {@link #nativeGetIfaceStat}.
+     * See {@code OffloadTetheringStatsProvider} for offloaded tethering stats.
+     */
+    // TODO: Remove this by implementing {@link NetworkStatsProvider} for non-offloaded
+    //  tethering stats.
+    private @NonNull NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
+         // We only need to return per-UID stats. Per-device stats are already counted by
+        // interface counters.
+        if (how != STATS_PER_UID) {
+            return new NetworkStats(SystemClock.elapsedRealtime(), 0);
+        }
+
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
+        try {
+            final TetherStatsParcel[] tetherStatsParcels = mNetd.tetherGetStats();
+            for (TetherStatsParcel tetherStats : tetherStatsParcels) {
+                try {
+                    stats.combineValues(new NetworkStats.Entry(tetherStats.iface, UID_TETHERING,
+                            SET_DEFAULT, TAG_NONE, tetherStats.rxBytes, tetherStats.rxPackets,
+                            tetherStats.txBytes, tetherStats.txPackets, 0L));
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    throw new IllegalStateException("invalid tethering stats " + e);
+                }
+            }
+        } catch (IllegalStateException e) {
+            Log.wtf(TAG, "problem reading network stats", e);
+        }
+        return stats;
+    }
+
+    // TODO: It is copied from ConnectivityService, consider refactor these check permission
+    //  functions to a proper util.
+    private boolean checkAnyPermissionOf(String... permissions) {
+        for (String permission : permissions) {
+            if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void enforceAnyPermissionOf(String... permissions) {
+        if (!checkAnyPermissionOf(permissions)) {
+            throw new SecurityException("Requires one of the following permissions: "
+                    + String.join(", ", permissions) + ".");
+        }
+    }
+
+    /**
+     * Registers a custom provider of {@link android.net.NetworkStats} to combine the network
+     * statistics that cannot be seen by the kernel to system. To unregister, invoke the
+     * {@code unregister()} of the returned callback.
+     *
+     * @param tag a human readable identifier of the custom network stats provider.
+     * @param provider the {@link INetworkStatsProvider} binder corresponding to the
+     *                 {@link NetworkStatsProvider} to be registered.
+     *
+     * @return a {@link INetworkStatsProviderCallback} binder
+     *         interface, which can be used to report events to the system.
+     */
+    public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider(
+            @NonNull String tag, @NonNull INetworkStatsProvider provider) {
+        enforceAnyPermissionOf(NETWORK_STATS_PROVIDER,
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+        Objects.requireNonNull(provider, "provider is null");
+        Objects.requireNonNull(tag, "tag is null");
+        final NetworkPolicyManager netPolicyManager = mContext
+                .getSystemService(NetworkPolicyManager.class);
+        try {
+            NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
+                    tag, provider, mStatsProviderSem, mAlertObserver,
+                    mStatsProviderCbList, netPolicyManager);
+            mStatsProviderCbList.add(callback);
+            Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
+                    + getCallingUid() + "/" + getCallingPid());
+            return callback;
+        } catch (RemoteException e) {
+            Log.e(TAG, "registerNetworkStatsProvider failed", e);
+        }
+        return null;
+    }
+
+    // Collect stats from local cache of providers.
+    private @NonNull NetworkStats getNetworkStatsFromProviders(int how) {
+        final NetworkStats ret = new NetworkStats(0L, 0);
+        invokeForAllStatsProviderCallbacks((cb) -> ret.combineAllValues(cb.getCachedStats(how)));
+        return ret;
+    }
+
+    @FunctionalInterface
+    private interface ThrowingConsumer<S, T extends Throwable> {
+        void accept(S s) throws T;
+    }
+
+    private void invokeForAllStatsProviderCallbacks(
+            @NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) {
+        for (final NetworkStatsProviderCallbackImpl cb : mStatsProviderCbList) {
+            try {
+                task.accept(cb);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e);
+            }
+        }
+    }
+
+    private static class NetworkStatsProviderCallbackImpl extends INetworkStatsProviderCallback.Stub
+            implements IBinder.DeathRecipient {
+        @NonNull final String mTag;
+
+        @NonNull final INetworkStatsProvider mProvider;
+        @NonNull private final Semaphore mSemaphore;
+        @NonNull final AlertObserver mAlertObserver;
+        @NonNull final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
+        @NonNull final NetworkPolicyManager mNetworkPolicyManager;
+
+        @NonNull private final Object mProviderStatsLock = new Object();
+
+        @GuardedBy("mProviderStatsLock")
+        // Track STATS_PER_IFACE and STATS_PER_UID separately.
+        private final NetworkStats mIfaceStats = new NetworkStats(0L, 0);
+        @GuardedBy("mProviderStatsLock")
+        private final NetworkStats mUidStats = new NetworkStats(0L, 0);
+
+        NetworkStatsProviderCallbackImpl(
+                @NonNull String tag, @NonNull INetworkStatsProvider provider,
+                @NonNull Semaphore semaphore,
+                @NonNull AlertObserver alertObserver,
+                @NonNull CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> cbList,
+                @NonNull NetworkPolicyManager networkPolicyManager)
+                throws RemoteException {
+            mTag = tag;
+            mProvider = provider;
+            mProvider.asBinder().linkToDeath(this, 0);
+            mSemaphore = semaphore;
+            mAlertObserver = alertObserver;
+            mStatsProviderCbList = cbList;
+            mNetworkPolicyManager = networkPolicyManager;
+        }
+
+        @NonNull
+        public NetworkStats getCachedStats(int how) {
+            synchronized (mProviderStatsLock) {
+                NetworkStats stats;
+                switch (how) {
+                    case STATS_PER_IFACE:
+                        stats = mIfaceStats;
+                        break;
+                    case STATS_PER_UID:
+                        stats = mUidStats;
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Invalid type: " + how);
+                }
+                // Callers might be able to mutate the returned object. Return a defensive copy
+                // instead of local reference.
+                return stats.clone();
+            }
+        }
+
+        @Override
+        public void notifyStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
+                @Nullable NetworkStats uidStats) {
+            // TODO: 1. Use token to map ifaces to correct NetworkIdentity.
+            //       2. Store the difference and store it directly to the recorder.
+            synchronized (mProviderStatsLock) {
+                if (ifaceStats != null) mIfaceStats.combineAllValues(ifaceStats);
+                if (uidStats != null) mUidStats.combineAllValues(uidStats);
+            }
+            mSemaphore.release();
+        }
+
+        @Override
+        public void notifyAlertReached() throws RemoteException {
+            // This binder object can only have been obtained by a process that holds
+            // NETWORK_STATS_PROVIDER. Thus, no additional permission check is required.
+            BinderUtils.withCleanCallingIdentity(() ->
+                    mAlertObserver.onQuotaLimitReached(LIMIT_GLOBAL_ALERT, null /* unused */));
+        }
+
+        @Override
+        public void notifyWarningReached() {
+            Log.d(TAG, mTag + ": notifyWarningReached");
+            BinderUtils.withCleanCallingIdentity(() ->
+                    mNetworkPolicyManager.notifyStatsProviderWarningReached());
+        }
+
+        @Override
+        public void notifyLimitReached() {
+            Log.d(TAG, mTag + ": notifyLimitReached");
+            BinderUtils.withCleanCallingIdentity(() ->
+                    mNetworkPolicyManager.notifyStatsProviderLimitReached());
+        }
+
+        @Override
+        public void binderDied() {
+            Log.d(TAG, mTag + ": binderDied");
+            mStatsProviderCbList.remove(this);
+        }
+
+        @Override
+        public void unregister() {
+            Log.d(TAG, mTag + ": unregister");
+            mStatsProviderCbList.remove(this);
+        }
+
+    }
+
+    private void assertSystemReady() {
+        if (!mSystemReady) {
+            throw new IllegalStateException("System not ready");
+        }
+    }
+
+    private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
+        @Override
+        public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
+                int rightIndex, String cookie) {
+            Log.w(TAG, "Found non-monotonic values; saving to dropbox");
+
+            // record error for debugging
+            final StringBuilder builder = new StringBuilder();
+            builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
+                    + "] - right[" + rightIndex + "]\n");
+            builder.append("left=").append(left).append('\n');
+            builder.append("right=").append(right).append('\n');
+
+            mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
+                    builder.toString());
+        }
+
+        @Override
+        public void foundNonMonotonic(
+                NetworkStats stats, int statsIndex, String cookie) {
+            Log.w(TAG, "Found non-monotonic values; saving to dropbox");
+
+            final StringBuilder builder = new StringBuilder();
+            builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
+            builder.append("stats=").append(stats).append('\n');
+
+            mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
+                    builder.toString());
+        }
+    }
+
+    /**
+     * Default external settings that read from
+     * {@link android.provider.Settings.Global}.
+     */
+    private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
+        DefaultNetworkStatsSettings() {}
+
+        @Override
+        public long getPollInterval() {
+            return 30 * MINUTE_IN_MILLIS;
+        }
+        @Override
+        public long getPollDelay() {
+            return DEFAULT_PERFORM_POLL_DELAY_MS;
+        }
+        @Override
+        public long getGlobalAlertBytes(long def) {
+            return def;
+        }
+        @Override
+        public boolean getSampleEnabled() {
+            return true;
+        }
+        @Override
+        public boolean getAugmentEnabled() {
+            return true;
+        }
+        @Override
+        public boolean getCombineSubtypeEnabled() {
+            return false;
+        }
+        @Override
+        public Config getDevConfig() {
+            return new Config(HOUR_IN_MILLIS, 15 * DAY_IN_MILLIS, 90 * DAY_IN_MILLIS);
+        }
+        @Override
+        public Config getXtConfig() {
+            return getDevConfig();
+        }
+        @Override
+        public Config getUidConfig() {
+            return new Config(2 * HOUR_IN_MILLIS, 15 * DAY_IN_MILLIS, 90 * DAY_IN_MILLIS);
+        }
+        @Override
+        public Config getUidTagConfig() {
+            return new Config(2 * HOUR_IN_MILLIS, 5 * DAY_IN_MILLIS, 15 * DAY_IN_MILLIS);
+        }
+        @Override
+        public long getDevPersistBytes(long def) {
+            return def;
+        }
+        @Override
+        public long getXtPersistBytes(long def) {
+            return def;
+        }
+        @Override
+        public long getUidPersistBytes(long def) {
+            return def;
+        }
+        @Override
+        public long getUidTagPersistBytes(long def) {
+            return def;
+        }
+    }
+
+    private static native long nativeGetTotalStat(int type);
+    private static native long nativeGetIfaceStat(String iface, int type);
+    private static native long nativeGetUidStat(int uid, int type);
+}
diff --git a/service-t/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/service-t/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
new file mode 100644
index 0000000..65ccd20
--- /dev/null
+++ b/service-t/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
@@ -0,0 +1,246 @@
+/*
+ * 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.server.net;
+
+import static android.app.usage.NetworkStatsManager.NETWORK_TYPE_5G_NSA;
+import static android.app.usage.NetworkStatsManager.getCollapsedRatType;
+import static android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED;
+import static android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
+
+import android.annotation.NonNull;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyCallback;
+import android.telephony.TelephonyDisplayInfo;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+
+/**
+ * Helper class that watches for events that are triggered per subscription.
+ */
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
+public class NetworkStatsSubscriptionsMonitor extends
+        SubscriptionManager.OnSubscriptionsChangedListener {
+
+    /**
+     * Interface that this monitor uses to delegate event handling to NetworkStatsService.
+     */
+    public interface Delegate {
+        /**
+         * Notify that the collapsed RAT type has been changed for any subscription. The method
+         * will also be triggered for any existing sub when start and stop monitoring.
+         *
+         * @param subscriberId IMSI of the subscription.
+         * @param collapsedRatType collapsed RAT type.
+         *                     @see android.app.usage.NetworkStatsManager#getCollapsedRatType(int).
+         */
+        void onCollapsedRatTypeChanged(@NonNull String subscriberId, int collapsedRatType);
+    }
+    private final Delegate mDelegate;
+
+    /**
+     * Receivers that watches for {@link TelephonyDisplayInfo} changes for each subscription, to
+     * monitor the transitioning between Radio Access Technology(RAT) types for each sub.
+     */
+    @NonNull
+    private final CopyOnWriteArrayList<RatTypeListener> mRatListeners =
+            new CopyOnWriteArrayList<>();
+
+    @NonNull
+    private final SubscriptionManager mSubscriptionManager;
+    @NonNull
+    private final TelephonyManager mTeleManager;
+
+    @NonNull
+    private final Executor mExecutor;
+
+    NetworkStatsSubscriptionsMonitor(@NonNull Context context,
+            @NonNull Executor executor, @NonNull Delegate delegate) {
+        super();
+        mSubscriptionManager = (SubscriptionManager) context.getSystemService(
+                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        mTeleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+        mExecutor = executor;
+        mDelegate = delegate;
+    }
+
+    @Override
+    public void onSubscriptionsChanged() {
+        // Collect active subId list, hidden subId such as opportunistic subscriptions are
+        // also needed to track CBRS.
+        final List<Integer> newSubs = getActiveSubIdList(mSubscriptionManager);
+
+        // IMSI is needed for every newly added sub. Listener stores subscriberId into it to
+        // prevent binder call to telephony when querying RAT. Keep listener registration with empty
+        // IMSI is meaningless since the RAT type changed is ambiguous for multi-SIM if reported
+        // with empty IMSI. So filter the subs w/o a valid IMSI to prevent such registration.
+        final List<Pair<Integer, String>> filteredNewSubs = new ArrayList<>();
+        for (final int subId : newSubs) {
+            final String subscriberId =
+                    mTeleManager.createForSubscriptionId(subId).getSubscriberId();
+            if (!TextUtils.isEmpty(subscriberId)) {
+                filteredNewSubs.add(new Pair(subId, subscriberId));
+            }
+        }
+
+        for (final Pair<Integer, String> sub : filteredNewSubs) {
+            // Fully match listener with subId and IMSI, since in some rare cases, IMSI might be
+            // suddenly change regardless of subId, such as switch IMSI feature in modem side.
+            // If that happens, register new listener with new IMSI and remove old one later.
+            if (CollectionUtils.any(mRatListeners, it -> it.equalsKey(sub.first, sub.second))) {
+                continue;
+            }
+
+            final RatTypeListener listener = new RatTypeListener(this, sub.first, sub.second);
+            mRatListeners.add(listener);
+
+            // Register listener to the telephony manager that associated with specific sub.
+            mTeleManager.createForSubscriptionId(sub.first)
+                    .registerTelephonyCallback(mExecutor, listener);
+            Log.d(NetworkStatsService.TAG, "RAT type listener registered for sub " + sub.first);
+        }
+
+        for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) {
+            // If there is no subId and IMSI matched the listener, removes it.
+            if (!CollectionUtils.any(filteredNewSubs,
+                    it -> listener.equalsKey(it.first, it.second))) {
+                handleRemoveRatTypeListener(listener);
+            }
+        }
+    }
+
+    @NonNull
+    private List<Integer> getActiveSubIdList(@NonNull SubscriptionManager subscriptionManager) {
+        final ArrayList<Integer> ret = new ArrayList<>();
+        final int[] ids = subscriptionManager.getCompleteActiveSubscriptionIdList();
+        for (int id : ids) ret.add(id);
+        return ret;
+    }
+
+    /**
+     * Get a collapsed RatType for the given subscriberId.
+     *
+     * @param subscriberId the target subscriberId
+     * @return collapsed RatType for the given subscriberId
+     */
+    public int getRatTypeForSubscriberId(@NonNull String subscriberId) {
+        final int index = CollectionUtils.indexOf(mRatListeners,
+                it -> TextUtils.equals(subscriberId, it.mSubscriberId));
+        return index != -1 ? mRatListeners.get(index).mLastCollapsedRatType
+                : TelephonyManager.NETWORK_TYPE_UNKNOWN;
+    }
+
+    /**
+     * Start monitoring events that triggered per subscription.
+     */
+    public void start() {
+        mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor, this);
+    }
+
+    /**
+     * Unregister subscription changes and all listeners for each subscription.
+     */
+    public void stop() {
+        mSubscriptionManager.removeOnSubscriptionsChangedListener(this);
+
+        for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) {
+            handleRemoveRatTypeListener(listener);
+        }
+    }
+
+    private void handleRemoveRatTypeListener(@NonNull RatTypeListener listener) {
+        mTeleManager.createForSubscriptionId(listener.mSubId)
+                .unregisterTelephonyCallback(listener);
+        Log.d(NetworkStatsService.TAG, "RAT type listener unregistered for sub " + listener.mSubId);
+        mRatListeners.remove(listener);
+
+        // Removal of subscriptions doesn't generate RAT changed event, fire it for every
+        // RatTypeListener.
+        mDelegate.onCollapsedRatTypeChanged(
+                listener.mSubscriberId, TelephonyManager.NETWORK_TYPE_UNKNOWN);
+    }
+
+    static class RatTypeListener extends TelephonyCallback
+            implements TelephonyCallback.DisplayInfoListener {
+        // Unique id for the subscription. See {@link SubscriptionInfo#getSubscriptionId}.
+        @NonNull
+        private final int mSubId;
+
+        // IMSI to identifying the corresponding network from {@link NetworkState}.
+        // See {@link TelephonyManager#getSubscriberId}.
+        @NonNull
+        private final String mSubscriberId;
+
+        private volatile int mLastCollapsedRatType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        @NonNull
+        private final NetworkStatsSubscriptionsMonitor mMonitor;
+
+        RatTypeListener(@NonNull NetworkStatsSubscriptionsMonitor monitor, int subId,
+                @NonNull String subscriberId) {
+            mSubId = subId;
+            mSubscriberId = subscriberId;
+            mMonitor = monitor;
+        }
+
+        @Override
+        public void onDisplayInfoChanged(TelephonyDisplayInfo displayInfo) {
+            // In 5G SA (Stand Alone) mode, the primary cell itself will be 5G hence telephony
+            // would report RAT = 5G_NR.
+            // However, in 5G NSA (Non Stand Alone) mode, the primary cell is still LTE and
+            // network allocates a secondary 5G cell so telephony reports RAT = LTE along with
+            // NR state as connected. In such case, attributes the data usage to NR.
+            // See b/160727498.
+            final boolean is5GNsa = displayInfo.getNetworkType() == NETWORK_TYPE_LTE
+                    && (displayInfo.getOverrideNetworkType() == OVERRIDE_NETWORK_TYPE_NR_NSA
+                    || displayInfo.getOverrideNetworkType() == OVERRIDE_NETWORK_TYPE_NR_ADVANCED);
+
+            final int networkType =
+                    (is5GNsa ? NETWORK_TYPE_5G_NSA : displayInfo.getNetworkType());
+            final int collapsedRatType = getCollapsedRatType(networkType);
+            if (collapsedRatType == mLastCollapsedRatType) return;
+
+            if (NetworkStatsService.LOGD) {
+                Log.d(NetworkStatsService.TAG, "subtype changed for sub(" + mSubId + "): "
+                        + mLastCollapsedRatType + " -> " + collapsedRatType);
+            }
+            mLastCollapsedRatType = collapsedRatType;
+            mMonitor.mDelegate.onCollapsedRatTypeChanged(mSubscriberId, mLastCollapsedRatType);
+        }
+
+        @VisibleForTesting
+        public int getSubId() {
+            return mSubId;
+        }
+
+        boolean equalsKey(int subId, @NonNull String subscriberId) {
+            return mSubId == subId && TextUtils.equals(mSubscriberId, subscriberId);
+        }
+    }
+}
diff --git a/service-t/src/com/android/server/net/StatsMapKey.java b/service-t/src/com/android/server/net/StatsMapKey.java
new file mode 100644
index 0000000..ea8d836
--- /dev/null
+++ b/service-t/src/com/android/server/net/StatsMapKey.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package com.android.server.net;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * Key for both stats maps.
+ */
+public class StatsMapKey extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long uid;
+
+    @Field(order = 1, type = Type.U32)
+    public final long tag;
+
+    @Field(order = 2, type = Type.U32)
+    public final long counterSet;
+
+    @Field(order = 3, type = Type.U32)
+    public final long ifaceIndex;
+
+    public StatsMapKey(final long uid, final long tag, final long counterSet,
+            final long ifaceIndex) {
+        this.uid = uid;
+        this.tag = tag;
+        this.counterSet = counterSet;
+        this.ifaceIndex = ifaceIndex;
+    }
+}
diff --git a/service-t/src/com/android/server/net/StatsMapValue.java b/service-t/src/com/android/server/net/StatsMapValue.java
new file mode 100644
index 0000000..48f26ce
--- /dev/null
+++ b/service-t/src/com/android/server/net/StatsMapValue.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package com.android.server.net;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * Value used for both stats maps and uid stats map.
+ */
+public class StatsMapValue extends Struct {
+    @Field(order = 0, type = Type.U63)
+    public final long rxPackets;
+
+    @Field(order = 1, type = Type.U63)
+    public final long rxBytes;
+
+    @Field(order = 2, type = Type.U63)
+    public final long txPackets;
+
+    @Field(order = 3, type = Type.U63)
+    public final long txBytes;
+
+    public StatsMapValue(final long rxPackets, final long rxBytes, final long txPackets,
+            final long txBytes) {
+        this.rxPackets = rxPackets;
+        this.rxBytes = rxBytes;
+        this.txPackets = txPackets;
+        this.txBytes = txBytes;
+    }
+}
diff --git a/service-t/src/com/android/server/net/UidStatsMapKey.java b/service-t/src/com/android/server/net/UidStatsMapKey.java
new file mode 100644
index 0000000..2849f94
--- /dev/null
+++ b/service-t/src/com/android/server/net/UidStatsMapKey.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package com.android.server.net;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * Key for uid stats map.
+ */
+public class UidStatsMapKey extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long uid;
+
+    public UidStatsMapKey(final long uid) {
+        this.uid = uid;
+    }
+}
diff --git a/service/Android.bp b/service/Android.bp
index ef5244c..0b8b25f 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -119,7 +119,7 @@
         "networkstack-client",
         "PlatformProperties",
         "service-connectivity-protos",
-        "NetworkStackApiStableShims",
+        "NetworkStackApiCurrentShims",
     ],
     apex_available: [
         "com.android.tethering",
@@ -166,6 +166,11 @@
     apex_available: [
         "com.android.tethering",
     ],
+    optimize: {
+        enabled: true,
+        shrink: true,
+        proguard_flags_files: ["proguard.flags"],
+    },
     lint: { strict_updatability_linting: true },
 }
 
diff --git a/service/jarjar-rules.txt b/service/jarjar-rules.txt
index e90b29b..5d51fdd 100644
--- a/service/jarjar-rules.txt
+++ b/service/jarjar-rules.txt
@@ -105,6 +105,9 @@
 # From the API shims
 rule com.android.networkstack.apishim.** com.android.connectivity.@0
 
+# From fast-pair-lite-protos
+rule service.proto.** com.android.server.nearby.@0
+
 # From filegroup framework-connectivity-protos
 rule android.service.*Proto com.android.connectivity.@0
 
diff --git a/service/proguard.flags b/service/proguard.flags
new file mode 100644
index 0000000..2b20ddd
--- /dev/null
+++ b/service/proguard.flags
@@ -0,0 +1,21 @@
+# Make sure proguard keeps all connectivity classes
+# TODO: instead of keeping everything, consider listing only "entry points"
+# (service loader, JNI registered methods, etc) and letting the optimizer do its job
+-keep class android.net.** { *; }
+-keep class com.android.connectivity.** { *; }
+-keep class com.android.net.** { *; }
+-keep class com.android.server.** { *; }
+
+# Prevent proguard from stripping out any nearby-service and fast-pair-lite-protos fields.
+# TODO: This could be optimized in the future to only keep the critical
+# entry points and then let proguard strip out any unused code within
+# the service. "com.android.server.nearby.service.proto" must be kept to prevent proguard
+# from stripping out any fast-pair-lite-protos fields.
+-keep class com.android.server.nearby.** { *; }
+
+# The lite proto runtime uses reflection to access fields based on the names in
+# the schema, keep all the fields.
+# This replicates the base proguard rule used by the build by default
+# (proguard_basic_keeps.flags), but needs to be specified here because the
+# com.google.protobuf package is jarjared to the below package.
+-keepclassmembers class * extends com.android.connectivity.com.google.protobuf.MessageLite { <fields>; }
diff --git a/tests/common/java/android/net/netstats/NetworkStatsCollectionTest.kt b/tests/common/java/android/net/netstats/NetworkStatsCollectionTest.kt
new file mode 100644
index 0000000..ca0e5ed
--- /dev/null
+++ b/tests/common/java/android/net/netstats/NetworkStatsCollectionTest.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+package android.net.netstats
+
+import android.net.NetworkIdentitySet
+import android.net.NetworkStatsCollection
+import android.net.NetworkStatsHistory
+import androidx.test.filters.SmallTest
+import com.android.testutils.ConnectivityModuleTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.SC_V2
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import kotlin.test.assertEquals
+import kotlin.test.fail
+
+@ConnectivityModuleTest
+@RunWith(JUnit4::class)
+@SmallTest
+class NetworkStatsCollectionTest {
+    @Rule
+    @JvmField
+    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = SC_V2)
+
+    @Test
+    fun testBuilder() {
+        val ident = NetworkIdentitySet()
+        val key1 = NetworkStatsCollection.Key(ident, /* uid */ 0, /* set */ 0, /* tag */ 0)
+        val key2 = NetworkStatsCollection.Key(ident, /* uid */ 1, /* set */ 0, /* tag */ 0)
+        val bucketDuration = 10L
+        val entry1 = NetworkStatsHistory.Entry(10, 10, 40, 4, 50, 5, 60)
+        val entry2 = NetworkStatsHistory.Entry(30, 10, 3, 41, 7, 1, 0)
+        val history1 = NetworkStatsHistory.Builder(10, 5)
+                .addEntry(entry1)
+                .addEntry(entry2)
+                .build()
+        val history2 = NetworkStatsHistory(10, 5)
+        val actualCollection = NetworkStatsCollection.Builder(bucketDuration)
+                .addEntry(key1, history1)
+                .addEntry(key2, history2)
+                .build()
+
+        // The builder will omit any entry with empty history. Thus, only history1
+        // is expected in the result collection.
+        val actualEntries = actualCollection.entries
+        assertEquals(1, actualEntries.size)
+        val actualHistory = actualEntries[key1] ?: fail("There should be an entry for $key1")
+        assertEquals(history1.entries, actualHistory.entries)
+    }
+}
\ No newline at end of file
diff --git a/tests/common/java/android/net/netstats/NetworkStatsHistoryTest.kt b/tests/common/java/android/net/netstats/NetworkStatsHistoryTest.kt
new file mode 100644
index 0000000..c2654c5
--- /dev/null
+++ b/tests/common/java/android/net/netstats/NetworkStatsHistoryTest.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+package android.net.netstats
+
+import android.net.NetworkStatsHistory
+import android.text.format.DateUtils
+import androidx.test.filters.SmallTest
+import com.android.testutils.ConnectivityModuleTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.SC_V2
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import kotlin.test.assertEquals
+
+@ConnectivityModuleTest
+@RunWith(JUnit4::class)
+@SmallTest
+class NetworkStatsHistoryTest {
+    @Rule
+    @JvmField
+    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = SC_V2)
+
+    @Test
+    fun testBuilder() {
+        val entry1 = NetworkStatsHistory.Entry(10, 30, 40, 4, 50, 5, 60)
+        val entry2 = NetworkStatsHistory.Entry(30, 15, 3, 41, 7, 1, 0)
+        val entry3 = NetworkStatsHistory.Entry(7, 301, 11, 14, 31, 2, 80)
+        val statsEmpty = NetworkStatsHistory
+                .Builder(DateUtils.HOUR_IN_MILLIS, /* initialCapacity */ 10).build()
+        assertEquals(0, statsEmpty.entries.size)
+        assertEquals(DateUtils.HOUR_IN_MILLIS, statsEmpty.bucketDuration)
+        val statsSingle = NetworkStatsHistory
+                .Builder(DateUtils.HOUR_IN_MILLIS, /* initialCapacity */ 8)
+                .addEntry(entry1)
+                .build()
+        statsSingle.assertEntriesEqual(entry1)
+        assertEquals(DateUtils.HOUR_IN_MILLIS, statsSingle.bucketDuration)
+        val statsMultiple = NetworkStatsHistory
+                .Builder(DateUtils.SECOND_IN_MILLIS, /* initialCapacity */ 0)
+                .addEntry(entry1).addEntry(entry2).addEntry(entry3)
+                .build()
+        assertEquals(DateUtils.SECOND_IN_MILLIS, statsMultiple.bucketDuration)
+        statsMultiple.assertEntriesEqual(entry1, entry2, entry3)
+    }
+
+    fun NetworkStatsHistory.assertEntriesEqual(vararg entries: NetworkStatsHistory.Entry) {
+        assertEquals(entries.size, this.entries.size)
+        entries.forEachIndexed { i, element ->
+            assertEquals(element, this.entries[i])
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/common/java/android/net/netstats/NetworkTemplateTest.kt b/tests/common/java/android/net/netstats/NetworkTemplateTest.kt
new file mode 100644
index 0000000..192694b
--- /dev/null
+++ b/tests/common/java/android/net/netstats/NetworkTemplateTest.kt
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+package android.net.netstats
+
+import android.net.NetworkStats.DEFAULT_NETWORK_ALL
+import android.net.NetworkStats.METERED_ALL
+import android.net.NetworkStats.METERED_YES
+import android.net.NetworkStats.ROAMING_YES
+import android.net.NetworkStats.ROAMING_ALL
+import android.net.NetworkTemplate
+import android.net.NetworkTemplate.MATCH_BLUETOOTH
+import android.net.NetworkTemplate.MATCH_CARRIER
+import android.net.NetworkTemplate.MATCH_ETHERNET
+import android.net.NetworkTemplate.MATCH_MOBILE
+import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
+import android.net.NetworkTemplate.MATCH_PROXY
+import android.net.NetworkTemplate.MATCH_WIFI
+import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
+import android.net.NetworkTemplate.NETWORK_TYPE_ALL
+import android.net.NetworkTemplate.OEM_MANAGED_ALL
+import android.telephony.TelephonyManager
+import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
+import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT
+import com.android.testutils.ConnectivityModuleTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.SC_V2
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+private const val TEST_IMSI1 = "imsi"
+private const val TEST_WIFI_KEY1 = "wifiKey1"
+private const val TEST_WIFI_KEY2 = "wifiKey2"
+
+@RunWith(JUnit4::class)
+@ConnectivityModuleTest
+class NetworkTemplateTest {
+    @Rule
+    @JvmField
+    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = SC_V2)
+
+    @Test
+    fun testBuilderMatchRules() {
+        // Verify unknown match rules cannot construct templates.
+        listOf(Integer.MIN_VALUE, -1, Integer.MAX_VALUE).forEach {
+            assertFailsWith<IllegalArgumentException> {
+                NetworkTemplate.Builder(it).build()
+            }
+        }
+
+        // Verify hidden match rules cannot construct templates.
+        listOf(MATCH_WIFI_WILDCARD, MATCH_MOBILE_WILDCARD, MATCH_PROXY).forEach {
+            assertFailsWith<IllegalArgumentException> {
+                NetworkTemplate.Builder(it).build()
+            }
+        }
+
+        // Verify template which matches metered cellular and carrier networks with
+        // the given IMSI. See buildTemplateMobileAll and buildTemplateCarrierMetered.
+        listOf(MATCH_MOBILE, MATCH_CARRIER).forEach { matchRule ->
+            NetworkTemplate.Builder(matchRule).setSubscriberIds(setOf(TEST_IMSI1))
+                    .setMeteredness(METERED_YES).build().let {
+                        val expectedTemplate = NetworkTemplate(matchRule, TEST_IMSI1,
+                                arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
+                                ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                                OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+                        assertEquals(expectedTemplate, it)
+                    }
+        }
+
+        // Verify template which matches roaming cellular and carrier networks with
+        // the given IMSI.
+        listOf(MATCH_MOBILE, MATCH_CARRIER).forEach { matchRule ->
+            NetworkTemplate.Builder(matchRule).setSubscriberIds(setOf(TEST_IMSI1))
+                    .setRoaming(ROAMING_YES).setMeteredness(METERED_YES).build().let {
+                        val expectedTemplate = NetworkTemplate(matchRule, TEST_IMSI1,
+                                arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
+                                ROAMING_YES, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                                OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+                        assertEquals(expectedTemplate, it)
+                    }
+        }
+
+        // Verify carrier template cannot be created without IMSI.
+        assertFailsWith<IllegalArgumentException> {
+            NetworkTemplate.Builder(MATCH_CARRIER).build()
+        }
+
+        // Verify template which matches metered cellular networks,
+        // regardless of IMSI. See buildTemplateMobileWildcard.
+        NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES).build().let {
+            val expectedTemplate = NetworkTemplate(MATCH_MOBILE_WILDCARD, null /*subscriberId*/,
+                    null /*subscriberIds*/, arrayOf<String>(),
+                    METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                    OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+            assertEquals(expectedTemplate, it)
+        }
+
+        // Verify template which matches metered cellular networks and ratType.
+        // See NetworkTemplate#buildTemplateMobileWithRatType.
+        NetworkTemplate.Builder(MATCH_MOBILE).setSubscriberIds(setOf(TEST_IMSI1))
+                .setMeteredness(METERED_YES).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
+                .build().let {
+                    val expectedTemplate = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1,
+                            arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
+                            ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_UMTS,
+                            OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+                    assertEquals(expectedTemplate, it)
+                }
+
+        // Verify template which matches all wifi networks,
+        // regardless of Wifi Network Key. See buildTemplateWifiWildcard and buildTemplateWifi.
+        NetworkTemplate.Builder(MATCH_WIFI).build().let {
+            val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
+                    null /*subscriberIds*/, arrayOf<String>(),
+                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                    OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+            assertEquals(expectedTemplate, it)
+        }
+
+        // Verify template which matches wifi networks with the given Wifi Network Key.
+        // See buildTemplateWifi(wifiNetworkKey).
+        NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
+            val expectedTemplate = NetworkTemplate(MATCH_WIFI, null /*subscriberId*/,
+                    null /*subscriberIds*/, arrayOf(TEST_WIFI_KEY1),
+                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                    OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+            assertEquals(expectedTemplate, it)
+        }
+
+        // Verify template which matches all wifi networks with the
+        // given Wifi Network Key, and IMSI. See buildTemplateWifi(wifiNetworkKey, subscriberId).
+        NetworkTemplate.Builder(MATCH_WIFI).setSubscriberIds(setOf(TEST_IMSI1))
+                .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
+                    val expectedTemplate = NetworkTemplate(MATCH_WIFI, TEST_IMSI1,
+                            arrayOf(TEST_IMSI1), arrayOf(TEST_WIFI_KEY1),
+                            METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                            OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+                    assertEquals(expectedTemplate, it)
+                }
+
+        // Verify template which matches ethernet and bluetooth networks.
+        // See buildTemplateEthernet and buildTemplateBluetooth.
+        listOf(MATCH_ETHERNET, MATCH_BLUETOOTH).forEach { matchRule ->
+            NetworkTemplate.Builder(matchRule).build().let {
+                val expectedTemplate = NetworkTemplate(matchRule, null /*subscriberId*/,
+                        null /*subscriberIds*/, arrayOf<String>(),
+                        METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                        OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+                assertEquals(expectedTemplate, it)
+            }
+        }
+    }
+
+    @Test
+    fun testBuilderWifiNetworkKeys() {
+        // Verify template builder which generates same template with the given different
+        // sequence keys.
+        NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
+                setOf(TEST_WIFI_KEY1, TEST_WIFI_KEY2)).build().let {
+            val expectedTemplate = NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
+                    setOf(TEST_WIFI_KEY2, TEST_WIFI_KEY1)).build()
+            assertEquals(expectedTemplate, it)
+        }
+
+        // Verify template which matches non-wifi networks with the given key is invalid.
+        listOf(MATCH_MOBILE, MATCH_CARRIER, MATCH_ETHERNET, MATCH_BLUETOOTH, -1,
+                Integer.MAX_VALUE).forEach { matchRule ->
+            assertFailsWith<IllegalArgumentException> {
+                NetworkTemplate.Builder(matchRule).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
+            }
+        }
+
+        // Verify template which matches wifi networks with the given null key is invalid.
+        assertFailsWith<IllegalArgumentException> {
+            NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(null)).build()
+        }
+
+        // Verify template which matches wifi wildcard with the given empty key set.
+        NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf<String>()).build().let {
+            val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
+                    arrayOf<String>() /*subscriberIds*/, arrayOf<String>(),
+                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                    OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+            assertEquals(expectedTemplate, it)
+        }
+    }
+}
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 a840242..9894444 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
@@ -53,6 +53,7 @@
 import android.os.BatteryManager;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.RemoteCallback;
 import android.os.SystemClock;
 import android.provider.DeviceConfig;
 import android.service.notification.NotificationListenerService;
@@ -140,6 +141,7 @@
 
     private static final int ACTIVITY_NETWORK_STATE_TIMEOUT_MS = 6_000;
     private static final int JOB_NETWORK_STATE_TIMEOUT_MS = 10_000;
+    private static final int LAUNCH_ACTIVITY_TIMEOUT_MS = 10_000;
 
     // Must be higher than NETWORK_TIMEOUT_MS
     private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4;
@@ -801,6 +803,22 @@
         mDeviceIdleDeviceConfigStateHelper.restoreOriginalValues();
     }
 
+    protected void launchActivity() throws Exception {
+        turnScreenOn();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final Intent launchIntent = getIntentForComponent(TYPE_COMPONENT_ACTIVTIY);
+        final RemoteCallback callback = new RemoteCallback(result -> latch.countDown());
+        launchIntent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);
+        mContext.startActivity(launchIntent);
+        // There might be a race when app2 is launched but ACTION_FINISH_ACTIVITY has not registered
+        // before test calls finishActivity(). When the issue is happened, there is no way to fix
+        // it, so have a callback design to make sure that the app is launched completely and
+        // ACTION_FINISH_ACTIVITY will be registered before leaving this method.
+        if (!latch.await(LAUNCH_ACTIVITY_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Timed out waiting for launching activity");
+        }
+    }
+
     protected void launchComponentAndAssertNetworkAccess(int type) throws Exception {
         launchComponentAndAssertNetworkAccess(type, true);
     }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java
index ad7ec9e..a0d88c9 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java
@@ -18,37 +18,28 @@
 
 import static android.os.Process.SYSTEM_UID;
 
+import static com.android.cts.net.hostside.NetworkPolicyTestUtils.assertIsUidRestrictedOnMeteredNetworks;
 import static com.android.cts.net.hostside.NetworkPolicyTestUtils.assertNetworkingBlockedStatusForUid;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness;
 import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isUidNetworkingBlocked;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isUidRestrictedOnMeteredNetworks;
 import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground;
 import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE;
 import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 
 public class NetworkPolicyManagerTest extends AbstractRestrictBackgroundNetworkTestCase {
     private static final boolean METERED = true;
     private static final boolean NON_METERED = false;
 
-    @Rule
-    public final MeterednessConfigurationRule mMeterednessConfiguration =
-            new MeterednessConfigurationRule();
-
     @Before
     public void setUp() throws Exception {
         super.setUp();
 
-        assumeTrue(canChangeActiveNetworkMeteredness());
-
         registerBroadcastReceiver();
 
         removeRestrictBackgroundWhitelist(mUid);
@@ -145,13 +136,14 @@
             removeRestrictBackgroundWhitelist(mUid);
 
             // Make TEST_APP2_PKG go to foreground and mUid will be allowed temporarily.
-            launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
+            launchActivity();
             assertForegroundState();
             assertNetworkingBlockedStatusForUid(mUid, METERED,
                     false /* expectedResult */); // Match NTWK_ALLOWED_TMP_ALLOWLIST
 
             // Back to background.
             finishActivity();
+            assertBackgroundState();
             assertNetworkingBlockedStatusForUid(mUid, METERED,
                     true /* expectedResult */); // Match NTWK_BLOCKED_BG_RESTRICT
         } finally {
@@ -222,26 +214,27 @@
             // enabled and mUid is not in the restrict background whitelist and TEST_APP2_PKG is not
             // in the foreground. For other cases, it will return false.
             setRestrictBackground(true);
-            assertTrue(isUidRestrictedOnMeteredNetworks(mUid));
+            assertIsUidRestrictedOnMeteredNetworks(mUid, true /* expectedResult */);
 
             // Make TEST_APP2_PKG go to foreground and isUidRestrictedOnMeteredNetworks() will
             // return false.
-            launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
+            launchActivity();
             assertForegroundState();
-            assertFalse(isUidRestrictedOnMeteredNetworks(mUid));
+            assertIsUidRestrictedOnMeteredNetworks(mUid, false /* expectedResult */);
             // Back to background.
             finishActivity();
+            assertBackgroundState();
 
             // Add mUid into restrict background whitelist and isUidRestrictedOnMeteredNetworks()
             // will return false.
             addRestrictBackgroundWhitelist(mUid);
-            assertFalse(isUidRestrictedOnMeteredNetworks(mUid));
+            assertIsUidRestrictedOnMeteredNetworks(mUid, false /* expectedResult */);
             removeRestrictBackgroundWhitelist(mUid);
         } finally {
             // Restrict background is disabled and isUidRestrictedOnMeteredNetworks() will return
             // false.
             setRestrictBackground(false);
-            assertFalse(isUidRestrictedOnMeteredNetworks(mUid));
+            assertIsUidRestrictedOnMeteredNetworks(mUid, false /* expectedResult */);
         }
     }
 }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
index 89a9bd6..9c4a348 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
@@ -439,6 +439,11 @@
         PollingCheck.waitFor(() -> (expectedResult == isUidNetworkingBlocked(uid, metered)));
     }
 
+    public static void assertIsUidRestrictedOnMeteredNetworks(int uid, boolean expectedResult)
+            throws Exception {
+        PollingCheck.waitFor(() -> (expectedResult == isUidRestrictedOnMeteredNetworks(uid)));
+    }
+
     public static boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork) {
         final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
         try {
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
index 5f0f6d6..4266aad 100644
--- 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
@@ -24,6 +24,7 @@
     @Before
     public void setUp() throws Exception {
         super.setUp();
+        setRestrictedNetworkingMode(false);
     }
 
     @After
@@ -34,8 +35,6 @@
 
     @Test
     public void testNetworkAccess() throws Exception {
-        setRestrictedNetworkingMode(false);
-
         // go to foreground state and enable restricted mode
         launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
         setRestrictedNetworkingMode(true);
@@ -54,4 +53,18 @@
         finishActivity();
         assertBackgroundNetworkAccess(true);
     }
+
+    @Test
+    public void testNetworkAccess_withBatterySaver() throws Exception {
+        setBatterySaverMode(true);
+        addPowerSaveModeWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(true);
+
+        setRestrictedNetworkingMode(true);
+        // App would be denied network access since Restricted mode is on.
+        assertBackgroundNetworkAccess(false);
+        setRestrictedNetworkingMode(false);
+        // Given that Restricted mode is turned off, app should be able to access network again.
+        assertBackgroundNetworkAccess(true);
+    }
 }
diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml
index 6c9b469..ff7240d 100644
--- a/tests/cts/hostside/app2/AndroidManifest.xml
+++ b/tests/cts/hostside/app2/AndroidManifest.xml
@@ -22,6 +22,7 @@
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
 
     <!--
      This application is used to listen to RESTRICT_BACKGROUND_CHANGED intents and store
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
index 9fdb9c9..eb7dca7 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
@@ -17,7 +17,6 @@
 
 import static com.android.cts.net.hostside.app2.Common.ACTION_FINISH_ACTIVITY;
 import static com.android.cts.net.hostside.app2.Common.TAG;
-import static com.android.cts.net.hostside.app2.Common.TEST_PKG;
 import static com.android.cts.net.hostside.app2.Common.TYPE_COMPONENT_ACTIVTY;
 
 import android.app.Activity;
@@ -25,13 +24,10 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.os.AsyncTask;
 import android.os.Bundle;
-import android.os.RemoteException;
+import android.os.RemoteCallback;
 import android.util.Log;
 
-import com.android.cts.net.hostside.INetworkStateObserver;
-
 /**
  * Activity used to bring process to foreground.
  */
@@ -51,7 +47,13 @@
                 MyActivity.this.finish();
             }
         };
-        registerReceiver(finishCommandReceiver, new IntentFilter(ACTION_FINISH_ACTIVITY));
+        registerReceiver(finishCommandReceiver, new IntentFilter(ACTION_FINISH_ACTIVITY),
+                Context.RECEIVER_EXPORTED);
+        final RemoteCallback callback = getIntent().getParcelableExtra(
+                Intent.EXTRA_REMOTE_CALLBACK);
+        if (callback != null) {
+            callback.sendResult(null);
+        }
     }
 
     @Override
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java
index 51c3157..8c112b6 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java
@@ -56,7 +56,8 @@
                 }
             }
         };
-        registerReceiver(mFinishCommandReceiver, new IntentFilter(ACTION_FINISH_JOB));
+        registerReceiver(mFinishCommandReceiver, new IntentFilter(ACTION_FINISH_JOB),
+                Context.RECEIVER_EXPORTED);
         return 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 a95fc64..f633df4 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -330,6 +330,11 @@
                 "testNetworkAccess");
     }
 
+    public void testNetworkAccess_restrictedMode_withBatterySaver() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".RestrictedModeTest",
+                "testNetworkAccess_withBatterySaver");
+    }
+
     /************************
      * Expedited job tests. *
      ************************/
diff --git a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
index fb720a7..de4f41b 100644
--- a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
@@ -29,6 +29,11 @@
 import static android.app.usage.NetworkStats.Bucket.STATE_FOREGROUND;
 import static android.app.usage.NetworkStats.Bucket.TAG_NONE;
 import static android.app.usage.NetworkStats.Bucket.UID_ALL;
+import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID;
+import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG;
+import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
 
 import android.app.AppOpsManager;
 import android.app.usage.NetworkStats;
@@ -40,7 +45,10 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkRequest;
+import android.net.NetworkStatsCollection;
+import android.net.NetworkStatsHistory;
 import android.net.TrafficStats;
+import android.net.netstats.NetworkStatsDataMigrationUtils;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Process;
@@ -49,10 +57,13 @@
 import android.platform.test.annotations.AppModeFull;
 import android.telephony.TelephonyManager;
 import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.compatibility.common.util.ShellIdentityUtils;
 import com.android.compatibility.common.util.SystemUtil;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.testutils.DevSdkIgnoreRule;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -62,6 +73,10 @@
 import java.net.UnknownHostException;
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 public class NetworkStatsManagerTest extends InstrumentationTestCase {
     private static final String LOG_TAG = "NetworkStatsManagerTest";
@@ -825,6 +840,43 @@
             // storing files of >2MB in CTS.
 
             mNsm.unregisterUsageCallback(usageCallback);
+
+            // For T- devices, the registerUsageCallback invocation below will need a looper
+            // from the thread that calls into the API, which is not available in the test.
+            if (SdkLevel.isAtLeastT()) {
+                mNsm.registerUsageCallback(mNetworkInterfacesToTest[i].getNetworkType(),
+                        getSubscriberId(i), THRESHOLD_BYTES, usageCallback);
+                mNsm.unregisterUsageCallback(usageCallback);
+            }
+        }
+    }
+
+    @AppModeFull
+    @DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+    public void testDataMigrationUtils() throws Exception {
+        final List<String> prefixes = List.of(PREFIX_UID, PREFIX_XT, PREFIX_UID_TAG);
+        for (final String prefix : prefixes) {
+            final long duration = TextUtils.equals(PREFIX_XT, prefix) ? TimeUnit.HOURS.toMillis(1)
+                    : TimeUnit.HOURS.toMillis(2);
+
+            final NetworkStatsCollection collection =
+                    NetworkStatsDataMigrationUtils.readPlatformCollection(prefix, duration);
+
+            final long now = System.currentTimeMillis();
+            final Set<Map.Entry<NetworkStatsCollection.Key, NetworkStatsHistory>> entries =
+                    collection.getEntries().entrySet();
+            for (final Map.Entry<NetworkStatsCollection.Key, NetworkStatsHistory> entry : entries) {
+                for (final NetworkStatsHistory.Entry historyEntry : entry.getValue().getEntries()) {
+                    // Verify all value fields are reasonable.
+                    assertTrue(historyEntry.getBucketStart() <= now);
+                    assertTrue(historyEntry.getActiveTime() <= duration);
+                    assertTrue(historyEntry.getRxBytes() >= 0);
+                    assertTrue(historyEntry.getRxPackets() >= 0);
+                    assertTrue(historyEntry.getTxBytes() >= 0);
+                    assertTrue(historyEntry.getTxPackets() >= 0);
+                    assertTrue(historyEntry.getOperations() >= 0);
+                }
+            }
         }
     }
 
diff --git a/tests/deflake/Android.bp b/tests/deflake/Android.bp
index b3d0363..8205f1c 100644
--- a/tests/deflake/Android.bp
+++ b/tests/deflake/Android.bp
@@ -21,7 +21,7 @@
 
 // FrameworksNetDeflakeTest depends on FrameworksNetTests so it should be disabled
 // if FrameworksNetTests is disabled.
-enable_frameworks_net_deflake_test = false
+enable_frameworks_net_deflake_test = true
 // Placeholder
 // This is a placeholder comment to minimize merge conflicts, as enable_frameworks_net_deflake_test
 // may have different values depending on the branch
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 901251c..988f21b 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -3,13 +3,17 @@
 //########################################################################
 package {
     // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "Android-Apache-2.0"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 // Whether to enable the FrameworksNetTests. Set to false in the branches that might have older
 // frameworks/base since FrameworksNetTests includes the test for classes that are not in
 // connectivity module.
-enable_frameworks_net_tests = false
+enable_frameworks_net_tests = true
 // Placeholder
 // This is a placeholder comment to minimize merge conflicts, as enable_frameworks_net_tests
 // may have different values depending on the branch
diff --git a/tests/unit/java/android/net/NetworkStatsCollectionTest.java b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
index 32c106d..0f02850 100644
--- a/tests/unit/java/android/net/NetworkStatsCollectionTest.java
+++ b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
@@ -38,13 +38,11 @@
 import static org.junit.Assert.fail;
 
 import android.content.res.Resources;
-import android.net.NetworkStatsCollection.Key;
 import android.os.Process;
 import android.os.UserHandle;
 import android.telephony.SubscriptionPlan;
 import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
-import android.util.ArrayMap;
 import android.util.RecurrenceRule;
 
 import androidx.test.InstrumentationRegistry;
@@ -75,7 +73,6 @@
 import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Tests for {@link NetworkStatsCollection}.
@@ -534,52 +531,6 @@
         assertThrows(ArithmeticException.class, () -> multiplySafeByRational(30, 3, 0));
     }
 
-    @Test
-    public void testBuilder() {
-        final Map<Key, NetworkStatsHistory> expectedEntries = new ArrayMap<>();
-        final NetworkStats.Entry entry = new NetworkStats.Entry();
-        final NetworkIdentitySet ident = new NetworkIdentitySet();
-        final Key key1 = new Key(ident, 0, 0, 0);
-        final Key key2 = new Key(ident, 1, 0, 0);
-        final long bucketDuration = 10;
-
-        final NetworkStatsHistory.Entry entry1 = new NetworkStatsHistory.Entry(10, 10, 40,
-                4, 50, 5, 60);
-        final NetworkStatsHistory.Entry entry2 = new NetworkStatsHistory.Entry(30, 10, 3,
-                41, 7, 1, 0);
-
-        NetworkStatsHistory history1 = new NetworkStatsHistory.Builder(10, 5)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .build();
-
-        NetworkStatsHistory history2 = new NetworkStatsHistory(10, 5);
-
-        NetworkStatsCollection actualCollection = new NetworkStatsCollection.Builder(bucketDuration)
-                .addEntry(key1, history1)
-                .addEntry(key2, history2)
-                .build();
-
-        // The builder will omit any entry with empty history. Thus, history2
-        // is not expected in the result collection.
-        expectedEntries.put(key1, history1);
-
-        final Map<Key, NetworkStatsHistory> actualEntries = actualCollection.getEntries();
-
-        assertEquals(expectedEntries.size(), actualEntries.size());
-        for (Key expectedKey : expectedEntries.keySet()) {
-            final NetworkStatsHistory expectedHistory = expectedEntries.get(expectedKey);
-
-            final NetworkStatsHistory actualHistory = actualEntries.get(expectedKey);
-            assertNotNull(actualHistory);
-
-            assertEquals(expectedHistory.getEntries(), actualHistory.getEntries());
-
-            actualEntries.remove(expectedKey);
-        }
-        assertEquals(0, actualEntries.size());
-    }
-
     /**
      * Copy a {@link Resources#openRawResource(int)} into {@link File} for
      * testing purposes.
diff --git a/tests/unit/java/android/net/NetworkStatsHistoryTest.java b/tests/unit/java/android/net/NetworkStatsHistoryTest.java
index c170605..c5f8c00 100644
--- a/tests/unit/java/android/net/NetworkStatsHistoryTest.java
+++ b/tests/unit/java/android/net/NetworkStatsHistoryTest.java
@@ -56,7 +56,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
-import java.util.List;
 import java.util.Random;
 
 @RunWith(DevSdkIgnoreRunner.class)
@@ -533,40 +532,6 @@
         assertEquals(512L + 4096L, stats.getTotalBytes());
     }
 
-    @Test
-    public void testBuilder() {
-        final NetworkStatsHistory.Entry entry1 = new NetworkStatsHistory.Entry(10, 30, 40,
-                4, 50, 5, 60);
-        final NetworkStatsHistory.Entry entry2 = new NetworkStatsHistory.Entry(30, 15, 3,
-                41, 7, 1, 0);
-        final NetworkStatsHistory.Entry entry3 = new NetworkStatsHistory.Entry(7, 301, 11,
-                14, 31, 2, 80);
-
-        final NetworkStatsHistory statsEmpty = new NetworkStatsHistory
-                .Builder(HOUR_IN_MILLIS, 10).build();
-        assertEquals(0, statsEmpty.getEntries().size());
-        assertEquals(HOUR_IN_MILLIS, statsEmpty.getBucketDuration());
-
-        NetworkStatsHistory statsSingle = new NetworkStatsHistory
-                .Builder(HOUR_IN_MILLIS, 8)
-                .addEntry(entry1)
-                .build();
-        assertEquals(1, statsSingle.getEntries().size());
-        assertEquals(HOUR_IN_MILLIS, statsSingle.getBucketDuration());
-        assertEquals(entry1, statsSingle.getEntries().get(0));
-
-        NetworkStatsHistory statsMultiple = new NetworkStatsHistory
-                .Builder(SECOND_IN_MILLIS, 0)
-                .addEntry(entry1).addEntry(entry2).addEntry(entry3)
-                .build();
-        final List<NetworkStatsHistory.Entry> entries = statsMultiple.getEntries();
-        assertEquals(3, entries.size());
-        assertEquals(SECOND_IN_MILLIS, statsMultiple.getBucketDuration());
-        assertEquals(entry1, entries.get(0));
-        assertEquals(entry2, entries.get(1));
-        assertEquals(entry3, entries.get(2));
-    }
-
     private static void assertIndexBeforeAfter(
             NetworkStatsHistory stats, int before, int after, long time) {
         assertEquals("unexpected before", before, stats.getIndexBefore(time));
diff --git a/tests/unit/java/android/net/NetworkTemplateTest.kt b/tests/unit/java/android/net/NetworkTemplateTest.kt
index 453612f..abd1825 100644
--- a/tests/unit/java/android/net/NetworkTemplateTest.kt
+++ b/tests/unit/java/android/net/NetworkTemplateTest.kt
@@ -29,12 +29,8 @@
 import android.net.NetworkStats.METERED_NO
 import android.net.NetworkStats.METERED_YES
 import android.net.NetworkStats.ROAMING_ALL
-import android.net.NetworkTemplate.MATCH_BLUETOOTH
-import android.net.NetworkTemplate.MATCH_CARRIER
-import android.net.NetworkTemplate.MATCH_ETHERNET
 import android.net.NetworkTemplate.MATCH_MOBILE
 import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
-import android.net.NetworkTemplate.MATCH_PROXY
 import android.net.NetworkTemplate.MATCH_WIFI
 import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
 import android.net.NetworkTemplate.NETWORK_TYPE_ALL
@@ -52,11 +48,9 @@
 import android.net.wifi.WifiInfo
 import android.os.Build
 import android.telephony.TelephonyManager
-import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
 import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT
 import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DevSdkIgnoreRunner
-import com.android.testutils.SC_V2
 import com.android.testutils.assertParcelSane
 import org.junit.Before
 import org.junit.Test
@@ -65,7 +59,6 @@
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
 import kotlin.test.assertFalse
 import kotlin.test.assertNotEquals
 import kotlin.test.assertTrue
@@ -555,140 +548,4 @@
             it.assertMatches(identMobileImsi3)
         }
     }
-
-    @DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
-    @Test
-    fun testBuilderMatchRules() {
-        // Verify unknown match rules cannot construct templates.
-        listOf(Integer.MIN_VALUE, -1, Integer.MAX_VALUE).forEach {
-            assertFailsWith<IllegalArgumentException> {
-                NetworkTemplate.Builder(it).build()
-            }
-        }
-
-        // Verify hidden match rules cannot construct templates.
-        listOf(MATCH_WIFI_WILDCARD, MATCH_MOBILE_WILDCARD, MATCH_PROXY).forEach {
-            assertFailsWith<IllegalArgumentException> {
-                NetworkTemplate.Builder(it).build()
-            }
-        }
-
-        // Verify template which matches metered cellular and carrier networks with
-        // the given IMSI. See buildTemplateMobileAll and buildTemplateCarrierMetered.
-        listOf(MATCH_MOBILE, MATCH_CARRIER).forEach { matchRule ->
-            NetworkTemplate.Builder(matchRule).setSubscriberIds(setOf(TEST_IMSI1))
-                    .setMeteredness(METERED_YES).build().let {
-                        val expectedTemplate = NetworkTemplate(matchRule, TEST_IMSI1,
-                                arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
-                                ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                                OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
-                        assertEquals(expectedTemplate, it)
-                    }
-        }
-
-        // Verify carrier template cannot be created without IMSI.
-        assertFailsWith<IllegalArgumentException> {
-            NetworkTemplate.Builder(MATCH_CARRIER).build()
-        }
-
-        // Verify template which matches metered cellular networks,
-        // regardless of IMSI. See buildTemplateMobileWildcard.
-        NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES).build().let {
-            val expectedTemplate = NetworkTemplate(MATCH_MOBILE_WILDCARD, null /*subscriberId*/,
-                    null /*subscriberIds*/, arrayOf<String>(),
-                    METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                    OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
-            assertEquals(expectedTemplate, it)
-        }
-
-        // Verify template which matches metered cellular networks and ratType.
-        // See NetworkTemplate#buildTemplateMobileWithRatType.
-        NetworkTemplate.Builder(MATCH_MOBILE).setSubscriberIds(setOf(TEST_IMSI1))
-                .setMeteredness(METERED_YES).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
-                .build().let {
-                    val expectedTemplate = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1,
-                            arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
-                            ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_UMTS,
-                            OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
-                    assertEquals(expectedTemplate, it)
-                }
-
-        // Verify template which matches all wifi networks,
-        // regardless of Wifi Network Key. See buildTemplateWifiWildcard and buildTemplateWifi.
-        NetworkTemplate.Builder(MATCH_WIFI).build().let {
-            val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
-                    null /*subscriberIds*/, arrayOf<String>(),
-                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                    OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
-            assertEquals(expectedTemplate, it)
-        }
-
-        // Verify template which matches wifi networks with the given Wifi Network Key.
-        // See buildTemplateWifi(wifiNetworkKey).
-        NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
-            val expectedTemplate = NetworkTemplate(MATCH_WIFI, null /*subscriberId*/,
-                    null /*subscriberIds*/, arrayOf(TEST_WIFI_KEY1),
-                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                    OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
-            assertEquals(expectedTemplate, it)
-        }
-
-        // Verify template which matches all wifi networks with the
-        // given Wifi Network Key, and IMSI. See buildTemplateWifi(wifiNetworkKey, subscriberId).
-        NetworkTemplate.Builder(MATCH_WIFI).setSubscriberIds(setOf(TEST_IMSI1))
-                .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
-                    val expectedTemplate = NetworkTemplate(MATCH_WIFI, TEST_IMSI1,
-                            arrayOf(TEST_IMSI1), arrayOf(TEST_WIFI_KEY1),
-                            METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                            OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
-                    assertEquals(expectedTemplate, it)
-                }
-
-        // Verify template which matches ethernet and bluetooth networks.
-        // See buildTemplateEthernet and buildTemplateBluetooth.
-        listOf(MATCH_ETHERNET, MATCH_BLUETOOTH).forEach { matchRule ->
-            NetworkTemplate.Builder(matchRule).build().let {
-                val expectedTemplate = NetworkTemplate(matchRule, null /*subscriberId*/,
-                        null /*subscriberIds*/, arrayOf<String>(),
-                        METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                        OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
-                assertEquals(expectedTemplate, it)
-            }
-        }
-    }
-
-    @DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
-    @Test
-    fun testBuilderWifiNetworkKeys() {
-        // Verify template builder which generates same template with the given different
-        // sequence keys.
-        NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
-                setOf(TEST_WIFI_KEY1, TEST_WIFI_KEY2)).build().let {
-            val expectedTemplate = NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
-                    setOf(TEST_WIFI_KEY2, TEST_WIFI_KEY1)).build()
-            assertEquals(expectedTemplate, it)
-        }
-
-        // Verify template which matches non-wifi networks with the given key is invalid.
-        listOf(MATCH_MOBILE, MATCH_CARRIER, MATCH_ETHERNET, MATCH_BLUETOOTH, -1,
-                Integer.MAX_VALUE).forEach { matchRule ->
-            assertFailsWith<IllegalArgumentException> {
-                NetworkTemplate.Builder(matchRule).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
-            }
-        }
-
-        // Verify template which matches wifi networks with the given null key is invalid.
-        assertFailsWith<IllegalArgumentException> {
-            NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(null)).build()
-        }
-
-        // Verify template which matches wifi wildcard with the given empty key set.
-        NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf<String>()).build().let {
-            val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
-                    arrayOf<String>() /*subscriberIds*/, arrayOf<String>(),
-                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                    OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
-            assertEquals(expectedTemplate, it)
-        }
-    }
 }
diff --git a/tests/unit/java/com/android/server/NativeDaemonConnectorTest.java b/tests/unit/java/com/android/server/NativeDaemonConnectorTest.java
new file mode 100644
index 0000000..e2253a2
--- /dev/null
+++ b/tests/unit/java/com/android/server/NativeDaemonConnectorTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static com.android.server.NativeDaemonConnector.appendEscaped;
+import static com.android.server.NativeDaemonConnector.makeCommand;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.server.NativeDaemonConnector.SensitiveArg;
+
+/**
+ * Tests for {@link NativeDaemonConnector}.
+ */
+@MediumTest
+public class NativeDaemonConnectorTest extends AndroidTestCase {
+    private static final String TAG = "NativeDaemonConnectorTest";
+
+    public void testArgumentNormal() throws Exception {
+        final StringBuilder builder = new StringBuilder();
+
+        builder.setLength(0);
+        appendEscaped(builder, "");
+        assertEquals("", builder.toString());
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo");
+        assertEquals("foo", builder.toString());
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo\"bar");
+        assertEquals("foo\\\"bar", builder.toString());
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo\\bar\\\"baz");
+        assertEquals("foo\\\\bar\\\\\\\"baz", builder.toString());
+    }
+
+    public void testArgumentWithSpaces() throws Exception {
+        final StringBuilder builder = new StringBuilder();
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo bar");
+        assertEquals("\"foo bar\"", builder.toString());
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo\"bar\\baz foo");
+        assertEquals("\"foo\\\"bar\\\\baz foo\"", builder.toString());
+    }
+
+    public void testArgumentWithUtf() throws Exception {
+        final StringBuilder builder = new StringBuilder();
+
+        builder.setLength(0);
+        appendEscaped(builder, "caf\u00E9 c\u00F6ffee");
+        assertEquals("\"caf\u00E9 c\u00F6ffee\"", builder.toString());
+    }
+
+    public void testSensitiveArgs() throws Exception {
+        final StringBuilder rawBuilder = new StringBuilder();
+        final StringBuilder logBuilder = new StringBuilder();
+
+        rawBuilder.setLength(0);
+        logBuilder.setLength(0);
+        makeCommand(rawBuilder, logBuilder, 1, "foo", "bar", "baz");
+        assertEquals("1 foo bar baz\0", rawBuilder.toString());
+        assertEquals("1 foo bar baz", logBuilder.toString());
+
+        rawBuilder.setLength(0);
+        logBuilder.setLength(0);
+        makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("bar"), "baz");
+        assertEquals("1 foo bar baz\0", rawBuilder.toString());
+        assertEquals("1 foo [scrubbed] baz", logBuilder.toString());
+
+        rawBuilder.setLength(0);
+        logBuilder.setLength(0);
+        makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("foo bar"), "baz baz",
+                new SensitiveArg("wat"));
+        assertEquals("1 foo \"foo bar\" \"baz baz\" wat\0", rawBuilder.toString());
+        assertEquals("1 foo [scrubbed] \"baz baz\" [scrubbed]", logBuilder.toString());
+    }
+}
diff --git a/tests/unit/java/com/android/server/net/IpConfigStoreTest.java b/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
new file mode 100644
index 0000000..e9a5309
--- /dev/null
+++ b/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+package com.android.server.net;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.net.InetAddresses;
+import android.net.IpConfiguration;
+import android.net.IpConfiguration.IpAssignment;
+import android.net.IpConfiguration.ProxySettings;
+import android.net.LinkAddress;
+import android.net.ProxyInfo;
+import android.net.StaticIpConfiguration;
+import android.util.ArrayMap;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Unit tests for {@link IpConfigStore}
+ */
+@RunWith(AndroidJUnit4.class)
+public class IpConfigStoreTest {
+    private static final int KEY_CONFIG = 17;
+    private static final String IFACE_1 = "eth0";
+    private static final String IFACE_2 = "eth1";
+    private static final String IP_ADDR_1 = "192.168.1.10/24";
+    private static final String IP_ADDR_2 = "192.168.1.20/24";
+    private static final String DNS_IP_ADDR_1 = "1.2.3.4";
+    private static final String DNS_IP_ADDR_2 = "5.6.7.8";
+
+    @Test
+    public void backwardCompatibility2to3() throws IOException {
+        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+        DataOutputStream outputStream = new DataOutputStream(byteStream);
+
+        final IpConfiguration expectedConfig =
+                newIpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null);
+
+        // Emulate writing to old format.
+        writeDhcpConfigV2(outputStream, KEY_CONFIG, expectedConfig);
+
+        InputStream in = new ByteArrayInputStream(byteStream.toByteArray());
+        ArrayMap<String, IpConfiguration> configurations = IpConfigStore.readIpConfigurations(in);
+
+        assertNotNull(configurations);
+        assertEquals(1, configurations.size());
+        IpConfiguration actualConfig = configurations.get(String.valueOf(KEY_CONFIG));
+        assertNotNull(actualConfig);
+        assertEquals(expectedConfig, actualConfig);
+    }
+
+    @Test
+    public void staticIpMultiNetworks() throws Exception {
+        final ArrayList<InetAddress> dnsServers = new ArrayList<>();
+        dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_1));
+        dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_2));
+        final StaticIpConfiguration staticIpConfiguration1 = new StaticIpConfiguration.Builder()
+                .setIpAddress(new LinkAddress(IP_ADDR_1))
+                .setDnsServers(dnsServers).build();
+        final StaticIpConfiguration staticIpConfiguration2 = new StaticIpConfiguration.Builder()
+                .setIpAddress(new LinkAddress(IP_ADDR_2))
+                .setDnsServers(dnsServers).build();
+
+        ProxyInfo proxyInfo =
+                ProxyInfo.buildDirectProxy("10.10.10.10", 88, Arrays.asList("host1", "host2"));
+
+        IpConfiguration expectedConfig1 = newIpConfiguration(IpAssignment.STATIC,
+                ProxySettings.STATIC, staticIpConfiguration1, proxyInfo);
+        IpConfiguration expectedConfig2 = newIpConfiguration(IpAssignment.STATIC,
+                ProxySettings.STATIC, staticIpConfiguration2, proxyInfo);
+
+        ArrayMap<String, IpConfiguration> expectedNetworks = new ArrayMap<>();
+        expectedNetworks.put(IFACE_1, expectedConfig1);
+        expectedNetworks.put(IFACE_2, expectedConfig2);
+
+        MockedDelayedDiskWrite writer = new MockedDelayedDiskWrite();
+        IpConfigStore store = new IpConfigStore(writer);
+        store.writeIpConfigurations("file/path/not/used/", expectedNetworks);
+
+        InputStream in = new ByteArrayInputStream(writer.mByteStream.toByteArray());
+        ArrayMap<String, IpConfiguration> actualNetworks = IpConfigStore.readIpConfigurations(in);
+        assertNotNull(actualNetworks);
+        assertEquals(2, actualNetworks.size());
+        assertEquals(expectedNetworks.get(IFACE_1), actualNetworks.get(IFACE_1));
+        assertEquals(expectedNetworks.get(IFACE_2), actualNetworks.get(IFACE_2));
+    }
+
+    private IpConfiguration newIpConfiguration(IpAssignment ipAssignment,
+            ProxySettings proxySettings, StaticIpConfiguration staticIpConfig, ProxyInfo info) {
+        final IpConfiguration config = new IpConfiguration();
+        config.setIpAssignment(ipAssignment);
+        config.setProxySettings(proxySettings);
+        config.setStaticIpConfiguration(staticIpConfig);
+        config.setHttpProxy(info);
+        return config;
+    }
+
+    // This is simplified snapshot of code that was used to store values in V2 format (key as int).
+    private static void writeDhcpConfigV2(DataOutputStream out, int configKey,
+            IpConfiguration config) throws IOException {
+        out.writeInt(2);  // VERSION 2
+        switch (config.getIpAssignment()) {
+            case DHCP:
+                out.writeUTF("ipAssignment");
+                out.writeUTF(config.getIpAssignment().toString());
+                break;
+            default:
+                fail("Not supported in test environment");
+        }
+
+        out.writeUTF("id");
+        out.writeInt(configKey);
+        out.writeUTF("eos");
+    }
+
+    /** Synchronously writes into given byte steam */
+    private static class MockedDelayedDiskWrite extends DelayedDiskWrite {
+        final ByteArrayOutputStream mByteStream = new ByteArrayOutputStream();
+
+        @Override
+        public void write(String filePath, Writer w) {
+            DataOutputStream outputStream = new DataOutputStream(mByteStream);
+
+            try {
+                w.onWriteCalled(outputStream);
+            } catch (IOException e) {
+                fail();
+            }
+        }
+    }
+}
