Extract FastPairTestDataProviderService out from the snippet.

The Mobly snippet is an Android instrumentation test which
AM(ActivityManager) will force stop the target package process.
This kill behavior will let Nearby Mainline onBind a new data
provider process. Therefore, this change extract the data provider
part to another package running in a sperate process and leverage
broadcast to do simple IPC for managing test data cache.

Test: atest -v CtsSeekerDiscoverProviderTest
Bug: 214015364
Change-Id: Ib1eb78c49a2c22b0651b9d9ccd66dd063d7e55d2
diff --git a/nearby/tests/multidevices/clients/Android.bp b/nearby/tests/multidevices/clients/Android.bp
index e3c8bb1..9c1f3f5 100644
--- a/nearby/tests/multidevices/clients/Android.bp
+++ b/nearby/tests/multidevices/clients/Android.bp
@@ -18,16 +18,13 @@
 
 android_library {
     name: "NearbyMultiDevicesClientsLib",
-    srcs: [
-        "src/**/*.java",
-        "src/**/*.kt",
-    ],
+    srcs: ["src/**/*.kt"],
     sdk_version: "test_current",
     static_libs: [
         "MoblySnippetHelperLib",
         "NearbyFastPairProviderLib",
+        "NearbyFastPairSeekerSharedLib",
         "androidx.test.core",
-        "gson-prebuilt-jar",
         "kotlin-stdlib",
         "mobly-snippet-lib",
     ],
diff --git a/nearby/tests/multidevices/clients/AndroidManifest.xml b/nearby/tests/multidevices/clients/AndroidManifest.xml
index 9641756..39140af 100644
--- a/nearby/tests/multidevices/clients/AndroidManifest.xml
+++ b/nearby/tests/multidevices/clients/AndroidManifest.xml
@@ -37,28 +37,6 @@
             android:name="mobly-snippets"
             android:value="android.nearby.multidevices.fastpair.seeker.FastPairSeekerSnippet,
                            android.nearby.multidevices.fastpair.provider.FastPairProviderSimulatorSnippet" />
-
-        <!-- 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=".fastpair.seeker.dataprovider.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>
 
     <instrumentation
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
index 522774c..54d4c67 100644
--- 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
@@ -17,11 +17,10 @@
 package android.nearby.multidevices.fastpair.seeker
 
 import android.content.Context
-import android.content.Intent
 import android.nearby.NearbyManager
 import android.nearby.ScanCallback
 import android.nearby.ScanRequest
-import android.nearby.multidevices.fastpair.seeker.dataprovider.FastPairTestDataCache
+import android.nearby.multidevices.fastpair.seeker.data.FastPairTestDataManager
 import androidx.test.core.app.ApplicationProvider
 import com.google.android.mobly.snippet.Snippet
 import com.google.android.mobly.snippet.rpc.AsyncRpc
@@ -32,6 +31,7 @@
 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
 
     /**
@@ -60,19 +60,6 @@
         nearbyManager.stopScan(scanCallback)
     }
 
-    /** Starts the Fast Pair seeker pairing. */
-    @Rpc(description = "Starts the Fast Pair seeker pairing.")
-    fun startPairing(modelId: String, address: String) {
-        Log.i("Starts the Fast Pair seeker pairing.")
-
-        val scanIntent = Intent().apply {
-            action = FAST_PAIR_MANAGER_ACTION_START_PAIRING
-            putExtra(FAST_PAIR_MANAGER_EXTRA_MODEL_ID, modelId.toByteArray())
-            putExtra(FAST_PAIR_MANAGER_EXTRA_ADDRESS, address)
-        }
-        appContext.sendBroadcast(scanIntent)
-    }
-
     /** Puts a model id to FastPairAntispoofKeyDeviceMetadata pair into test data cache.
      *
      * @param modelId a string of model id to be associated with.
@@ -81,7 +68,7 @@
     @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.")
-        FastPairTestDataCache.putAntispoofKeyDeviceMetadata(modelId, json)
+        fastPairTestDataManager.sendAntispoofKeyDeviceMetadata(modelId, json)
     }
 
     /** Puts an array of FastPairAccountKeyDeviceMetadata into test data cache.
@@ -91,14 +78,14 @@
     @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.")
-        FastPairTestDataCache.putAccountKeyDeviceMetadata(json)
+        fastPairTestDataManager.sendAccountKeyDeviceMetadata(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 FastPairTestDataCache.dumpAccountKeyDeviceMetadata()
+        return fastPairTestDataManager.testDataCache.dumpAccountKeyDeviceMetadataListAsJson()
     }
 
     /** Invokes when the snippet runner shutting down. */
@@ -106,12 +93,6 @@
         super.shutdown()
 
         Log.i("Resets the Fast Pair test data cache.")
-        FastPairTestDataCache.reset()
-    }
-
-    companion object {
-        private const val FAST_PAIR_MANAGER_ACTION_START_PAIRING = "NEARBY_START_PAIRING"
-        private const val FAST_PAIR_MANAGER_EXTRA_MODEL_ID = "MODELID"
-        private const val FAST_PAIR_MANAGER_EXTRA_ADDRESS = "ADDRESS"
+        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..291aad8
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/data/FastPairTestDataManager.kt
@@ -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 android.nearby.multidevices.fastpair.seeker.data
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.nearby.fastpair.seeker.*
+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()
+
+    /** 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 to local and remote cache.
+     *
+     * @param json a string of FastPairAccountKeyDeviceMetadata JSON array.
+     */
+    fun sendAccountKeyDeviceMetadata(json: String) {
+        Intent().also { intent ->
+            intent.action = ACTION_SEND_ACCOUNT_KEY_DEVICE_METADATA
+            intent.putExtra(DATA_JSON_STRING_KEY, json)
+            context.sendBroadcast(intent)
+        }
+        testDataCache.putAccountKeyDeviceMetadata(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.putAccountKeyDeviceMetadata(json)
+            }
+            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/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/src/android/nearby/multidevices/fastpair/seeker/dataprovider/FastPairTestDataCache.kt b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/shared/android/nearby/fastpair/seeker/FastPairTestDataCache.kt
similarity index 90%
rename from nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/dataprovider/FastPairTestDataCache.kt
rename to nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/shared/android/nearby/fastpair/seeker/FastPairTestDataCache.kt
index 3e9d6d3..80ca855 100644
--- a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/dataprovider/FastPairTestDataCache.kt
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/shared/android/nearby/fastpair/seeker/FastPairTestDataCache.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.nearby.multidevices.fastpair.seeker.dataprovider
+package android.nearby.fastpair.seeker
 
 import android.nearby.FastPairAccountKeyDeviceMetadata
 import android.nearby.FastPairAntispoofKeyDeviceMetadata
@@ -25,30 +25,46 @@
 import com.google.gson.annotations.SerializedName
 
 /** Manage a cache of Fast Pair test data for testing. */
-object FastPairTestDataCache {
+class FastPairTestDataCache {
     private val gson = Gson()
-    val accountKeyDeviceMetadata = mutableListOf<FastPairAccountKeyDeviceMetadata>()
-    val antispoofKeyDeviceMetadataMap =
-        mutableMapOf<String, FastPairAntispoofKeyDeviceMetadata>()
+    private val accountKeyDeviceMetadataList = mutableListOf<FastPairAccountKeyDeviceMetadata>()
+    private val antispoofKeyDeviceMetadataDataMap =
+        mutableMapOf<String, FastPairAntispoofKeyDeviceMetadataData>()
 
     fun putAccountKeyDeviceMetadata(json: String) {
-        accountKeyDeviceMetadata +=
+        accountKeyDeviceMetadataList +=
             gson.fromJson(json, Array<FastPairAccountKeyDeviceMetadataData>::class.java)
                 .map { it.toFastPairAccountKeyDeviceMetadata() }
     }
 
-    fun dumpAccountKeyDeviceMetadata(): String =
-        gson.toJson(accountKeyDeviceMetadata.map { FastPairAccountKeyDeviceMetadataData(it) })
-
-    fun putAntispoofKeyDeviceMetadata(modelId: String, json: String) {
-        antispoofKeyDeviceMetadataMap[modelId] =
-            gson.fromJson(json, FastPairAntispoofKeyDeviceMetadataData::class.java)
-                .toFastPairAntispoofKeyDeviceMetadata()
+    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() {
-        accountKeyDeviceMetadata.clear()
-        antispoofKeyDeviceMetadataMap.clear()
+        accountKeyDeviceMetadataList.clear()
+        antispoofKeyDeviceMetadataDataMap.clear()
     }
 
     data class FastPairAccountKeyDeviceMetadataData(
@@ -296,7 +312,8 @@
                 .build()
         }
     }
-
-    private fun String.base64Decode(): ByteArray = BaseEncoding.base64().decode(this)
-    private fun ByteArray.base64Encode(): String = BaseEncoding.base64().encode(this)
 }
+
+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..ffc02a0
--- /dev/null
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/data/FastPairTestDataManager.kt
@@ -0,0 +1,78 @@
+/*
+ * 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.*
+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.
+     */
+    fun writeAccountKeyDeviceMetadata(accountKeyDeviceMetadata: FastPairAccountKeyDeviceMetadata) {
+        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)
+        }
+    }
+
+    /**
+     * 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.putAccountKeyDeviceMetadata(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/src/android/nearby/multidevices/fastpair/seeker/dataprovider/FastPairTestDataProviderService.kt b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/dataprovider/FastPairTestDataProviderService.kt
similarity index 75%
rename from nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/dataprovider/FastPairTestDataProviderService.kt
rename to nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/dataprovider/FastPairTestDataProviderService.kt
index f1a3863..cec0607 100644
--- a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/dataprovider/FastPairTestDataProviderService.kt
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/src/android/nearby/fastpair/seeker/dataprovider/FastPairTestDataProviderService.kt
@@ -14,19 +14,39 @@
  * limitations under the License.
  */
 
-package android.nearby.multidevices.fastpair.seeker.dataprovider
+package android.nearby.fastpair.seeker.dataprovider
 
 import android.accounts.Account
-import android.content.Intent
+import android.content.IntentFilter
 import android.nearby.FastPairDataProviderService
 import android.nearby.FastPairEligibleAccount
-import android.os.IBinder
+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,
@@ -36,10 +56,11 @@
         Log.d(TAG, "onLoadFastPairAntispoofKeyDeviceMetadata(modelId: $requestedModelId)")
 
         val fastPairAntispoofKeyDeviceMetadata =
-            FastPairTestDataCache.antispoofKeyDeviceMetadataMap[requestedModelId]
+            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")
         }
     }
@@ -54,10 +75,10 @@
             TAG, "onLoadFastPairAccountDevicesMetadata(" +
                     "account: $requestedAccount, accountKeys:$requestedAccountKeys)"
         )
-        Log.d(TAG, FastPairTestDataCache.dumpAccountKeyDeviceMetadata())
+        Log.d(TAG, testDataManager.testDataCache.dumpAccountKeyDeviceMetadataListAsJson())
 
         callback.onFastPairAccountDevicesMetadataReceived(
-            FastPairTestDataCache.accountKeyDeviceMetadata
+            testDataManager.testDataCache.getAccountKeyDeviceMetadataList()
         )
     }
 
@@ -95,7 +116,7 @@
         Log.d(TAG, "requestedBleAddress: $requestedBleAddress,")
         Log.d(TAG, "requestedAccountKeyDeviceMetadata: $requestedAccountKeyDeviceMetadata)")
 
-        FastPairTestDataCache.accountKeyDeviceMetadata += requestedAccountKeyDeviceMetadata
+        testDataManager.writeAccountKeyDeviceMetadata(requestedAccountKeyDeviceMetadata)
 
         callback.onSuccess()
     }
@@ -104,7 +125,7 @@
         private const val TAG = "FastPairTestDataProviderService"
         private val ELIGIBLE_ACCOUNTS_TEST_CONSTANT = listOf(
             FastPairEligibleAccount.Builder()
-                .setAccount(Account("nearby-mainline-fpseeker@google.com", "FakeTestAccount"))
+                .setAccount(Account(FAKE_TEST_ACCOUNT_NAME, "FakeTestAccount"))
                 .setOptIn(true)
                 .build(),
         )
diff --git a/nearby/tests/multidevices/host/Android.bp b/nearby/tests/multidevices/host/Android.bp
index 533153a..8075bf2 100644
--- a/nearby/tests/multidevices/host/Android.bp
+++ b/nearby/tests/multidevices/host/Android.bp
@@ -30,12 +30,14 @@
         unit_test: false,
     },
     data: [
-        // Package the snippet with the Mobly test
+        // Package the snippet with the Mobly test.
         ":NearbyMultiDevicesClientsSnippets",
+        // Package the data provider with the Mobly test.
+        ":NearbyFastPairSeekerDataProvider",
     ],
 }
 
 python_library_host {
     name: "NearbyMultiDevicesHostHelper",
     srcs: ["test_helper/*.py"],
-}
\ No newline at end of file
+}
diff --git a/nearby/tests/multidevices/host/AndroidTest.xml b/nearby/tests/multidevices/host/AndroidTest.xml
index f8294f4..9453647 100644
--- a/nearby/tests/multidevices/host/AndroidTest.xml
+++ b/nearby/tests/multidevices/host/AndroidTest.xml
@@ -23,6 +23,7 @@
         -->
         <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">
@@ -42,6 +43,7 @@
     <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">