Make Fast Pair test data provider configurable.

Test: Send antispoofkey_devicemeta JSON to verify initial pairing works, go/paste/6463933310304256
Test: atest -v CtsSeekerDiscoverProviderTest
Bug: 214015364
Change-Id: I6f8cee96a7ef89e6341931ff7d33c1bc685b8506
diff --git a/nearby/tests/multidevices/clients/Android.bp b/nearby/tests/multidevices/clients/Android.bp
index 72b752b..5e0ca15 100644
--- a/nearby/tests/multidevices/clients/Android.bp
+++ b/nearby/tests/multidevices/clients/Android.bp
@@ -29,6 +29,7 @@
         "error_prone_annotations",
         "fast-pair-lite-protos",
         "framework-annotations-lib",
+        "gson-prebuilt-jar",
         "kotlin-stdlib",
         "mobly-snippet-lib",
         "service-nearby",
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 add0bc3..6c28b97 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
@@ -42,10 +42,10 @@
     @AsyncRpc(description = "Starts scanning as Fast Pair seeker to find Fast Pair provider devices.")
     fun startScan(callbackId: String) {
         val scanRequest = ScanRequest.Builder()
-                .setScanMode(ScanRequest.SCAN_MODE_LOW_LATENCY)
-                .setScanType(ScanRequest.SCAN_TYPE_FAST_PAIR)
-                .setEnableBle(true)
-                .build()
+            .setScanMode(ScanRequest.SCAN_MODE_LOW_LATENCY)
+            .setScanType(ScanRequest.SCAN_TYPE_FAST_PAIR)
+            .setEnableBle(true)
+            .build()
         scanCallback = ScanCallbackEvents(callbackId)
 
         Log.i("Start Fast Pair scanning via BLE...")
@@ -72,6 +72,42 @@
         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.
+     * @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.")
+        FastPairTestDataCache.putAntiSpoofKeyDeviceMetadata(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.")
+        FastPairTestDataCache.putAccountKeyDeviceMetadata(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()
+    }
+
+    /** Invokes when the snippet runner shutting down. */
+    override fun shutdown() {
+        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"
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairTestDataCache.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairTestDataCache.kt
new file mode 100644
index 0000000..28523c1
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairTestDataCache.kt
@@ -0,0 +1,302 @@
+/*
+ * 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.nearby.FastPairAccountKeyDeviceMetadata
+import android.nearby.FastPairAntispoofkeyDeviceMetadata
+import android.nearby.FastPairDeviceMetadata
+import android.nearby.FastPairDiscoveryItem
+import com.google.common.io.BaseEncoding.base64
+import com.google.gson.Gson
+import com.google.gson.annotations.SerializedName
+
+/** Manage a cache of Fast Pair test data for testing. */
+object FastPairTestDataCache {
+    private val gson = Gson()
+    val accountKeyDeviceMetadata = mutableListOf<FastPairAccountKeyDeviceMetadata>()
+    val antiSpoofKeyDeviceMetadataMap =
+        mutableMapOf<String, FastPairAntispoofkeyDeviceMetadata>()
+
+    fun putAccountKeyDeviceMetadata(json: String) {
+        accountKeyDeviceMetadata +=
+            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 reset() {
+        accountKeyDeviceMetadata.clear()
+        antiSpoofKeyDeviceMetadataMap.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.accountKey?.base64Encode(),
+            accountKeyPublicAddress = meta.sha256AccountKeyPublicAddress?.base64Encode(),
+            deviceMeta = meta.fastPairDeviceMetadata?.let { FastPairDeviceMetadataData(it) },
+            discoveryItem = meta.fastPairDiscoveryItem?.let { FastPairDiscoveryItemData(it) },
+        )
+
+        fun toFastPairAccountKeyDeviceMetadata(): FastPairAccountKeyDeviceMetadata {
+            return FastPairAccountKeyDeviceMetadata.Builder()
+                .setAccountKey(accountKey?.base64Decode())
+                .setSha256AccountKeyPublicAddress(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 = base64().decode(this)
+    private fun ByteArray.base64Encode(): String = base64().encode(this)
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairTestDataProvider.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairTestDataProvider.kt
index 5a30fcf..a1f0369 100644
--- a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairTestDataProvider.kt
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairTestDataProvider.kt
@@ -17,53 +17,11 @@
 package android.nearby.multidevices.fastpair.seeker
 
 import android.accounts.Account
-import android.nearby.*
+import android.nearby.FastPairDataProviderBase
+import android.nearby.FastPairEligibleAccount
 import android.util.Log
-import service.proto.Cache
-import service.proto.Rpcs.DeviceType
-import java.util.*
 
 class FastPairTestDataProvider : FastPairDataProviderBase(TAG) {
-    private val fastPairDeviceMetadata = FastPairDeviceMetadata.Builder()
-        .setAssistantSetupHalfSheet(ASSISTANT_SETUP_HALF_SHEET_TEST_CONSTANT)
-        .setAssistantSetupNotification(ASSISTANT_SETUP_NOTIFICATION_TEST_CONSTANT)
-        .setBleTxPower(BLE_TX_POWER_TEST_CONSTANT)
-        .setConfirmPinDescription(CONFIRM_PIN_DESCRIPTION_TEST_CONSTANT)
-        .setConfirmPinTitle(CONFIRM_PIN_TITLE_TEST_CONSTANT)
-        .setConnectSuccessCompanionAppInstalled(CONNECT_SUCCESS_COMPANION_APP_INSTALLED_TEST_CONSTANT)
-        .setConnectSuccessCompanionAppNotInstalled(CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED_TEST_CONSTANT)
-        .setDeviceType(DEVICE_TYPE_HEAD_PHONES_TEST_CONSTANT)
-        .setDownloadCompanionAppDescription(DOWNLOAD_COMPANION_APP_DESCRIPTION_TEST_CONSTANT)
-        .setFailConnectGoToSettingsDescription(FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION_TEST_CONSTANT)
-        .setFastPairTvConnectDeviceNoAccountDescription(TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION_TEST_CONSTANT)
-        .setInitialNotificationDescription(INITIAL_NOTIFICATION_DESCRIPTION_TEST_CONSTANT)
-        .setInitialNotificationDescriptionNoAccount(INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT_TEST_CONSTANT)
-        .setInitialPairingDescription(INITIAL_PAIRING_DESCRIPTION_TEST_CONSTANT)
-        .setLocale(LOCALE_US_LANGUAGE_TEST_CONSTANT)
-        .setImage(IMAGE_BYTE_ARRAY_FAKE_TEST_CONSTANT)
-        .setImageUrl(IMAGE_URL_TEST_CONSTANT)
-        .setIntentUri(
-            generateCompanionAppLaunchIntentUri(
-                companionAppPackageName = COMPANION_APP_PACKAGE_TEST_CONSTANT,
-                activityName = COMPANION_APP_ACTIVITY_TEST_CONSTANT,
-            )
-        )
-        .setOpenCompanionAppDescription(OPEN_COMPANION_APP_DESCRIPTION_TEST_CONSTANT)
-        .setRetroactivePairingDescription(RETRO_ACTIVE_PAIRING_DESCRIPTION_TEST_CONSTANT)
-        .setSubsequentPairingDescription(SUBSEQUENT_PAIRING_DESCRIPTION_TEST_CONSTANT)
-        .setSyncContactsDescription(SYNC_CONTACT_DESCRIPTION_TEST_CONSTANT)
-        .setSyncContactsTitle(SYNC_CONTACTS_TITLE_TEST_CONSTANT)
-        .setSyncSmsDescription(SYNC_SMS_DESCRIPTION_TEST_CONSTANT)
-        .setSyncSmsTitle(SYNC_SMS_TITLE_TEST_CONSTANT)
-        .setTriggerDistance(TRIGGER_DISTANCE_TEST_CONSTANT)
-        .setTrueWirelessImageUrlCase(TRUE_WIRELESS_IMAGE_URL_CASE_TEST_CONSTANT)
-        .setTrueWirelessImageUrlLeftBud(TRUE_WIRELESS_IMAGE_URL_LEFT_BUD_TEST_CONSTANT)
-        .setTrueWirelessImageUrlRightBud(TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD_TEST_CONSTANT)
-        .setUnableToConnectDescription(UNABLE_TO_CONNECT_DESCRIPTION_TEST_CONSTANT)
-        .setUnableToConnectTitle(UNABLE_TO_CONNECT_TITLE_TEST_CONSTANT)
-        .setUpdateCompanionAppDescription(UPDATE_COMPANION_APP_DESCRIPTION_TEST_CONSTANT)
-        .setWaitLaunchCompanionAppDescription(WAIT_LAUNCH_COMPANION_APP_DESCRIPTION_TEST_CONSTANT)
-        .build()
 
     override fun onLoadFastPairAntispoofkeyDeviceMetadata(
         request: FastPairAntispoofkeyDeviceMetadataRequest,
@@ -73,12 +31,12 @@
         Log.d(TAG, "onLoadFastPairAntispoofkeyDeviceMetadata(modelId: $requestedModelId)")
 
         val fastPairAntiSpoofKeyDeviceMetadata =
-            FastPairAntispoofkeyDeviceMetadata.Builder()
-                .setAntiSpoofPublicKey(ANTI_SPOOF_PUBLIC_KEY_BYTE_ARRAY)
-                .setFastPairDeviceMetadata(fastPairDeviceMetadata)
-                .build()
-
-        callback.onFastPairAntispoofkeyDeviceMetadataReceived(fastPairAntiSpoofKeyDeviceMetadata)
+            FastPairTestDataCache.antiSpoofKeyDeviceMetadataMap[requestedModelId]
+        if (fastPairAntiSpoofKeyDeviceMetadata != null) {
+            callback.onFastPairAntispoofkeyDeviceMetadataReceived(fastPairAntiSpoofKeyDeviceMetadata)
+        } else {
+            callback.onError(ERROR_CODE_BAD_REQUEST, "No metadata available for $requestedModelId")
+        }
     }
 
     override fun onLoadFastPairAccountDevicesMetadata(
@@ -87,48 +45,11 @@
     ) {
         val requestedAccount = request.account
         Log.d(TAG, "onLoadFastPairAccountDevicesMetadata(account: $requestedAccount)")
-        val discoveryItem = FastPairDiscoveryItem.Builder()
-            .setActionUrl(ACTION_URL_TEST_CONSTANT)
-            .setActionUrlType(ACTION_URL_TYPE_TEST_CONSTANT)
-            .setAppName(APP_NAME_TEST_CONSTANT)
-            .setAttachmentType(ATTACHMENT_TYPE_TEST_CONSTANT)
-            .setAuthenticationPublicKeySecp256r1(AUTHENTICATION_PUBLIC_KEY_SEC_P256R1_TEST_CONSTANT)
-            .setBleRecordBytes(BLE_RECORD_BYTES_TEST_CONSTANT)
-            .setDebugCategory(DEBUG_CATEGORY_TEST_CONSTANT)
-            .setDebugMessage(DEBUG_MESSAGE_TEST_CONSTANT)
-            .setDescription(DESCRIPTION_TEST_CONSTANT)
-            .setDeviceName(DEVICE_NAME_TEST_CONSTANT)
-            .setDisplayUrl(DISPLAY_URL_TEST_CONSTANT)
-            .setEntityId(ENTITY_ID_TEST_CONSTANT)
-            .setFeatureGraphicUrl(FEATURE_GRAPHIC_URL_TEST_CONSTANT)
-            .setFirstObservationTimestampMillis(FIRST_OBSERVATION_TIMESTAMP_MILLIS_TEST_CONSTANT)
-            .setGroupId(GROUP_ID_TEST_CONSTANT)
-            .setIconFfeUrl(ICON_FIFE_URL_TEST_CONSTANT)
-            .setIconPng(ICON_PNG_TEST_CONSTANT)
-            .setId(ID_TEST_CONSTANT)
-            .setLastObservationTimestampMillis(LAST_OBSERVATION_TIMESTAMP_MILLIS_TEST_CONSTANT)
-            .setLastUserExperience(LAST_USER_EXPERIENCE_TEST_CONSTANT)
-            .setLostMillis(LOST_MILLIS_TEST_CONSTANT)
-            .setMacAddress(MAC_ADDRESS_TEST_CONSTANT)
-            .setPackageName(PACKAGE_NAME_TEST_CONSTANT)
-            .setPendingAppInstallTimestampMillis(PENDING_APP_INSTALL_TIMESTAMP_MILLIS_TEST_CONSTANT)
-            .setRssi(RSSI_TEST_CONSTANT)
-            .setState(STATE_TEST_CONSTANT)
-            .setTitle(TITLE_TEST_CONSTANT)
-            .setTriggerId(TRIGGER_ID_TEST_CONSTANT)
-            .setTxPower(TX_POWER_TEST_CONSTANT)
-            .setType(TYPE_TEST_CONSTANT)
-            .build()
-        val accountDevicesMetadataList = listOf(
-            FastPairAccountKeyDeviceMetadata.Builder()
-                .setAccountKey(ACCOUNT_KEY_TEST_CONSTANT)
-                .setFastPairDeviceMetadata(fastPairDeviceMetadata)
-                .setSha256AccountKeyPublicAddress(SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS_TEST_CONSTANT)
-                .setFastPairDiscoveryItem(discoveryItem)
-                .build()
-        )
+        Log.d(TAG, FastPairTestDataCache.dumpAccountKeyDeviceMetadata())
 
-        callback.onFastPairAccountDevicesMetadataReceived(accountDevicesMetadataList)
+        callback.onFastPairAccountDevicesMetadataReceived(
+            FastPairTestDataCache.accountKeyDeviceMetadata
+        )
     }
 
     override fun onLoadFastPairEligibleAccounts(
@@ -154,128 +75,32 @@
     ) {
         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: $requestType,")
+        Log.d(
+            TAG,
+            "onManageFastPairAccountDevice(requestedAccount: $requestedAccount, " +
+                    "requestType: $requestTypeString,"
+        )
         Log.d(TAG, "requestedBleAddress: $requestedBleAddress,")
         Log.d(TAG, "requestedAccountKeyDeviceMetadata: $requestedAccountKeyDeviceMetadata)")
 
+        FastPairTestDataCache.accountKeyDeviceMetadata += requestedAccountKeyDeviceMetadata
+
         callback.onSuccess()
     }
 
     companion object {
         private const val TAG = "FastPairTestDataProvider"
-
-        private const val BLE_TX_POWER_TEST_CONSTANT = 5
-        private const val TRIGGER_DISTANCE_TEST_CONSTANT = 10f
-        private const val ACTION_URL_TEST_CONSTANT = "ACTION_URL_TEST_CONSTANT"
-        private const val ACTION_URL_TYPE_TEST_CONSTANT = Cache.ResolvedUrlType.APP_VALUE
-        private const val APP_NAME_TEST_CONSTANT = "Nearby Mainline Mobly Test Snippet"
-        private const val ATTACHMENT_TYPE_TEST_CONSTANT =
-            Cache.DiscoveryAttachmentType.DISCOVERY_ATTACHMENT_TYPE_NORMAL_VALUE
-        private const val DEBUG_CATEGORY_TEST_CONSTANT =
-            Cache.StoredDiscoveryItem.DebugMessageCategory.STATUS_VALID_NOTIFICATION_VALUE
-        private const val DEBUG_MESSAGE_TEST_CONSTANT = "DEBUG_MESSAGE_TEST_CONSTANT"
-        private const val DESCRIPTION_TEST_CONSTANT = "DESCRIPTION_TEST_CONSTANT"
-        private const val DEVICE_NAME_TEST_CONSTANT = "Fast Pair Headphone Simulator"
-        private const val DISPLAY_URL_TEST_CONSTANT = "DISPLAY_URL_TEST_CONSTANT"
-        private const val ENTITY_ID_TEST_CONSTANT = "ENTITY_ID_TEST_CONSTANT"
-        private const val FEATURE_GRAPHIC_URL_TEST_CONSTANT = "FEATURE_GRAPHIC_URL_TEST_CONSTANT"
-        private const val FIRST_OBSERVATION_TIMESTAMP_MILLIS_TEST_CONSTANT = 8_393L
-        private const val GROUP_ID_TEST_CONSTANT = "GROUP_ID_TEST_CONSTANT"
-        private const val ICON_FIFE_URL_TEST_CONSTANT = "ICON_FIFE_URL_TEST_CONSTANT"
-        private const val ID_TEST_CONSTANT = "ID_TEST_CONSTANT"
-        private const val LAST_OBSERVATION_TIMESTAMP_MILLIS_TEST_CONSTANT = 934_234L
-        private const val LAST_USER_EXPERIENCE_TEST_CONSTANT =
-            Cache.StoredDiscoveryItem.ExperienceType.EXPERIENCE_GOOD_VALUE
-        private const val LOST_MILLIS_TEST_CONSTANT = 393_284L
-        private const val MAC_ADDRESS_TEST_CONSTANT = "11:aa:22:bb:34:cd"
-        private const val PACKAGE_NAME_TEST_CONSTANT = "android.nearby.package.name.test.constant"
-        private const val PENDING_APP_INSTALL_TIMESTAMP_MILLIS_TEST_CONSTANT = 832_393L
-        private const val RSSI_TEST_CONSTANT = 9
-        private const val STATE_TEST_CONSTANT = Cache.StoredDiscoveryItem.State.STATE_ENABLED_VALUE
-        private const val TITLE_TEST_CONSTANT = "TITLE_TEST_CONSTANT"
-        private const val TRIGGER_ID_TEST_CONSTANT = "TRIGGER_ID_TEST_CONSTANT"
-        private const val TX_POWER_TEST_CONSTANT = 62
-        private const val TYPE_TEST_CONSTANT = Cache.NearbyType.NEARBY_DEVICE_VALUE
-
-        private val ANTI_SPOOF_PUBLIC_KEY_BYTE_ARRAY =
-            "Cbj9eCJrTdDgSYxLkqtfADQi86vIaMvxJsQ298sZYWE=".toByteArray()
-        private val LOCALE_US_LANGUAGE_TEST_CONSTANT = Locale.US.language
-        private val IMAGE_BYTE_ARRAY_FAKE_TEST_CONSTANT = byteArrayOf(7, 9)
-        private val IMAGE_URL_TEST_CONSTANT =
-            "2l9cq8LFjK4D7EvPiFAq08DMpUA1b2SoPv9FPw3q6iiwjDvh-hLfKsPCFy0j36rfjDNjSULvRgOodRDxfRHHxA".toFifeUrlString()
-        private val TRUE_WIRELESS_IMAGE_URL_CASE_TEST_CONSTANT =
-            "oNv4-sFfa0tM1uA7vZ8r7UJPBV8OreiKOFl-_KlFwrqnDD7MoOV4uX8NwGUdYb1dcMm7cfwjZ04628WTeS40".toFifeUrlString()
-        private val TRUE_WIRELESS_IMAGE_URL_LEFT_BUD_TEST_CONSTANT =
-            "RcGxVZRObx9Avn9AHwSMM4WvDbVNyYlqigW7PlDHL4RLU8W9lcENDMyaTWM9O7JIu1ewSX-FIe_GkQfDlItQkg".toFifeUrlString()
-        private val TRUE_WIRELESS_IMAGE_URL_RIGHT_BUD_TEST_CONSTANT =
-            "S7AuFqmr_hEqEFo_qfjxAiPz9moae0dkXUSUJV4gVFcysYpn4C95P77egPnuu35C3Eh_UY6_yNpQkmmUqn4N".toFifeUrlString()
         private val ELIGIBLE_ACCOUNTS_TEST_CONSTANT = listOf(
             FastPairEligibleAccount.Builder()
-                .setAccount(Account("nearby-mainline-fpseeker@google.com", "TestAccount"))
+                .setAccount(Account("nearby-mainline-fpseeker@google.com", "FakeTestAccount"))
                 .setOptIn(true)
                 .build(),
         )
-        private val ACCOUNT_KEY_TEST_CONSTANT = byteArrayOf(3)
-        private val SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS_TEST_CONSTANT = byteArrayOf(2, 8)
-        private val AUTHENTICATION_PUBLIC_KEY_SEC_P256R1_TEST_CONSTANT = byteArrayOf(5, 7)
-        private val BLE_RECORD_BYTES_TEST_CONSTANT = byteArrayOf(2, 4)
-        private val ICON_PNG_TEST_CONSTANT = byteArrayOf(2, 5)
-
-        private const val DEVICE_TYPE_HEAD_PHONES_TEST_CONSTANT = DeviceType.HEADPHONES_VALUE
-        private const val ASSISTANT_SETUP_HALF_SHEET_TEST_CONSTANT =
-            "This is a test description in half sheet to ask user setup google assistant."
-        private const val ASSISTANT_SETUP_NOTIFICATION_TEST_CONSTANT =
-            "This is a test description in notification to ask user setup google assistant."
-        private const val CONFIRM_PIN_DESCRIPTION_TEST_CONSTANT =
-            "Please confirm the pin code to fast pair your device."
-        private const val CONFIRM_PIN_TITLE_TEST_CONSTANT = "PIN code confirmation"
-        private const val CONNECT_SUCCESS_COMPANION_APP_INSTALLED_TEST_CONSTANT =
-            "This is a test description that let user open the companion app."
-        private const val CONNECT_SUCCESS_COMPANION_APP_NOT_INSTALLED_TEST_CONSTANT =
-            "This is a test description that let user download the companion app."
-        private const val DOWNLOAD_COMPANION_APP_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description for downloading companion app."
-        private const val FAIL_CONNECT_GOTO_SETTINGS_DESCRIPTION_TEST_CONSTANT = "This is a " +
-                "test description that indicates go to bluetooth settings when connection fail."
-        private const val TV_CONNECT_DEVICE_NO_ACCOUNT_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description of the connect device action on TV, " +
-                    "when user is not logged in."
-        private const val INITIAL_NOTIFICATION_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description for initial notification."
-        private const val INITIAL_NOTIFICATION_DESCRIPTION_NO_ACCOUNT_TEST_CONSTANT = "This is a " +
-                "test description of initial notification description when account is not present."
-        private const val INITIAL_PAIRING_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description for Fast Pair initial pairing."
-        private const val COMPANION_APP_PACKAGE_TEST_CONSTANT = "android.nearby.companion"
-        private const val COMPANION_APP_ACTIVITY_TEST_CONSTANT =
-            "android.nearby.companion.MainActivity"
-        private const val OPEN_COMPANION_APP_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description for opening companion app."
-        private const val RETRO_ACTIVE_PAIRING_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description that reminds users opt in their device."
-        private const val SUBSEQUENT_PAIRING_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description that reminds user there is a paired device nearby."
-        private const val SYNC_CONTACT_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description of the UI to ask the user to confirm to sync contacts."
-        private const val SYNC_CONTACTS_TITLE_TEST_CONSTANT = "Sync contacts to your device"
-        private const val SYNC_SMS_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description of the UI to ask the user to confirm to sync SMS."
-        private const val SYNC_SMS_TITLE_TEST_CONSTANT = "Sync SMS to your device"
-        private const val UNABLE_TO_CONNECT_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description when Fast Pair device is unable to be connected to."
-        private const val UNABLE_TO_CONNECT_TITLE_TEST_CONSTANT =
-            "Unable to connect your Fast Pair device"
-        private const val UPDATE_COMPANION_APP_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description for updating companion app."
-        private const val WAIT_LAUNCH_COMPANION_APP_DESCRIPTION_TEST_CONSTANT =
-            "This is a test description that indicates companion app is about to launch."
 
         private fun ByteArray.bytesToStringLowerCase(): String =
             joinToString(separator = "") { eachByte -> "%02x".format(eachByte) }
-
-        // Primary image serving domain for Google Photos and most other clients of FIFE.
-        private fun String.toFifeUrlString() = "https://lh3.googleusercontent.com/$this"
     }
 }
\ 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