1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package android.nearby.fastpair.seeker
18
19 import android.nearby.FastPairAccountKeyDeviceMetadata
20 import android.nearby.FastPairAntispoofKeyDeviceMetadata
21 import android.nearby.FastPairDeviceMetadata
22 import android.nearby.FastPairDiscoveryItem
23 import com.google.common.io.BaseEncoding
24 import com.google.gson.GsonBuilder
25 import com.google.gson.annotations.SerializedName
26
27 /** Manage a cache of Fast Pair test data for testing. */
28 class FastPairTestDataCache {
29 private val gson = GsonBuilder().disableHtmlEscaping().create()
30 private val accountKeyDeviceMetadataList = mutableListOf<FastPairAccountKeyDeviceMetadata>()
31 private val antispoofKeyDeviceMetadataDataMap =
32 mutableMapOf<String, FastPairAntispoofKeyDeviceMetadataData>()
33
putAccountKeyDeviceMetadataJsonArraynull34 fun putAccountKeyDeviceMetadataJsonArray(json: String) {
35 accountKeyDeviceMetadataList +=
36 gson.fromJson(json, Array<FastPairAccountKeyDeviceMetadataData>::class.java)
37 .map { it.toFastPairAccountKeyDeviceMetadata() }
38 }
39
putAccountKeyDeviceMetadataJsonObjectnull40 fun putAccountKeyDeviceMetadataJsonObject(json: String) {
41 accountKeyDeviceMetadataList +=
42 gson.fromJson(json, FastPairAccountKeyDeviceMetadataData::class.java)
43 .toFastPairAccountKeyDeviceMetadata()
44 }
45
putAccountKeyDeviceMetadatanull46 fun putAccountKeyDeviceMetadata(accountKeyDeviceMetadata: FastPairAccountKeyDeviceMetadata) {
47 accountKeyDeviceMetadataList += accountKeyDeviceMetadata
48 }
49
getAccountKeyDeviceMetadataListnull50 fun getAccountKeyDeviceMetadataList(): List<FastPairAccountKeyDeviceMetadata> =
51 accountKeyDeviceMetadataList.toList()
52
53 fun dumpAccountKeyDeviceMetadataAsJson(metadata: FastPairAccountKeyDeviceMetadata): String =
54 gson.toJson(FastPairAccountKeyDeviceMetadataData(metadata))
55
56 fun dumpAccountKeyDeviceMetadataListAsJson(): String =
57 gson.toJson(accountKeyDeviceMetadataList.map { FastPairAccountKeyDeviceMetadataData(it) })
58
putAntispoofKeyDeviceMetadatanull59 fun putAntispoofKeyDeviceMetadata(modelId: String, json: String) {
60 antispoofKeyDeviceMetadataDataMap[modelId] =
61 gson.fromJson(json, FastPairAntispoofKeyDeviceMetadataData::class.java)
62 }
63
getAntispoofKeyDeviceMetadatanull64 fun getAntispoofKeyDeviceMetadata(modelId: String): FastPairAntispoofKeyDeviceMetadata? {
65 return antispoofKeyDeviceMetadataDataMap[modelId]?.toFastPairAntispoofKeyDeviceMetadata()
66 }
67
getFastPairDeviceMetadatanull68 fun getFastPairDeviceMetadata(modelId: String): FastPairDeviceMetadata? =
69 antispoofKeyDeviceMetadataDataMap[modelId]?.deviceMeta?.toFastPairDeviceMetadata()
70
71 fun reset() {
72 accountKeyDeviceMetadataList.clear()
73 antispoofKeyDeviceMetadataDataMap.clear()
74 }
75
76 data class FastPairAccountKeyDeviceMetadataData(
77 @SerializedName("account_key") val accountKey: String?,
78 @SerializedName("sha256_account_key_public_address") val accountKeyPublicAddress: String?,
79 @SerializedName("fast_pair_device_metadata") val deviceMeta: FastPairDeviceMetadataData?,
80 @SerializedName("fast_pair_discovery_item") val discoveryItem: FastPairDiscoveryItemData?
81 ) {
82 constructor(meta: FastPairAccountKeyDeviceMetadata) : this(
83 accountKey = meta.deviceAccountKey?.base64Encode(),
84 accountKeyPublicAddress = meta.sha256DeviceAccountKeyPublicAddress?.base64Encode(),
<lambda>null85 deviceMeta = meta.fastPairDeviceMetadata?.let { FastPairDeviceMetadataData(it) },
<lambda>null86 discoveryItem = meta.fastPairDiscoveryItem?.let { FastPairDiscoveryItemData(it) }
87 )
88
toFastPairAccountKeyDeviceMetadatanull89 fun toFastPairAccountKeyDeviceMetadata(): FastPairAccountKeyDeviceMetadata {
90 return FastPairAccountKeyDeviceMetadata.Builder()
91 .setDeviceAccountKey(accountKey?.base64Decode())
92 .setSha256DeviceAccountKeyPublicAddress(accountKeyPublicAddress?.base64Decode())
93 .setFastPairDeviceMetadata(deviceMeta?.toFastPairDeviceMetadata())
94 .setFastPairDiscoveryItem(discoveryItem?.toFastPairDiscoveryItem())
95 .build()
96 }
97 }
98
99 data class FastPairAntispoofKeyDeviceMetadataData(
100 @SerializedName("anti_spoofing_public_key_str") val antispoofPublicKey: String?,
101 @SerializedName("fast_pair_device_metadata") val deviceMeta: FastPairDeviceMetadataData?
102 ) {
toFastPairAntispoofKeyDeviceMetadatanull103 fun toFastPairAntispoofKeyDeviceMetadata(): FastPairAntispoofKeyDeviceMetadata {
104 return FastPairAntispoofKeyDeviceMetadata.Builder()
105 .setAntispoofPublicKey(antispoofPublicKey?.base64Decode())
106 .setFastPairDeviceMetadata(deviceMeta?.toFastPairDeviceMetadata())
107 .build()
108 }
109 }
110
111 data class FastPairDeviceMetadataData(
112 @SerializedName("ble_tx_power") val bleTxPower: Int,
113 @SerializedName("connect_success_companion_app_installed") val compAppInstalled: String?,
114 @SerializedName("connect_success_companion_app_not_installed") val comAppNotIns: String?,
115 @SerializedName("device_type") val deviceType: Int,
116 @SerializedName("download_companion_app_description") val downloadComApp: String?,
117 @SerializedName("fail_connect_go_to_settings_description") val failConnectDes: String?,
118 @SerializedName("image_url") val imageUrl: String?,
119 @SerializedName("initial_notification_description") val initNotification: String?,
120 @SerializedName("initial_notification_description_no_account") val initNoAccount: String?,
121 @SerializedName("initial_pairing_description") val initialPairingDescription: String?,
122 @SerializedName("intent_uri") val intentUri: String?,
123 @SerializedName("name") val name: String?,
124 @SerializedName("open_companion_app_description") val openCompanionAppDescription: String?,
125 @SerializedName("retroactive_pairing_description") val retroactivePairingDes: String?,
126 @SerializedName("subsequent_pairing_description") val subsequentPairingDescription: String?,
127 @SerializedName("trigger_distance") val triggerDistance: Double,
128 @SerializedName("case_url") val trueWirelessImageUrlCase: String?,
129 @SerializedName("left_bud_url") val trueWirelessImageUrlLeftBud: String?,
130 @SerializedName("right_bud_url") val trueWirelessImageUrlRightBud: String?,
131 @SerializedName("unable_to_connect_description") val unableToConnectDescription: String?,
132 @SerializedName("unable_to_connect_title") val unableToConnectTitle: String?,
133 @SerializedName("update_companion_app_description") val updateCompAppDes: String?,
134 @SerializedName("wait_launch_companion_app_description") val waitLaunchCompApp: String?
135 ) {
136 constructor(meta: FastPairDeviceMetadata) : this(
137 bleTxPower = meta.bleTxPower,
138 compAppInstalled = meta.connectSuccessCompanionAppInstalled,
139 comAppNotIns = meta.connectSuccessCompanionAppNotInstalled,
140 deviceType = meta.deviceType,
141 downloadComApp = meta.downloadCompanionAppDescription,
142 failConnectDes = meta.failConnectGoToSettingsDescription,
143 imageUrl = meta.imageUrl,
144 initNotification = meta.initialNotificationDescription,
145 initNoAccount = meta.initialNotificationDescriptionNoAccount,
146 initialPairingDescription = meta.initialPairingDescription,
147 intentUri = meta.intentUri,
148 name = meta.name,
149 openCompanionAppDescription = meta.openCompanionAppDescription,
150 retroactivePairingDes = meta.retroactivePairingDescription,
151 subsequentPairingDescription = meta.subsequentPairingDescription,
152 triggerDistance = meta.triggerDistance.toDouble(),
153 trueWirelessImageUrlCase = meta.trueWirelessImageUrlCase,
154 trueWirelessImageUrlLeftBud = meta.trueWirelessImageUrlLeftBud,
155 trueWirelessImageUrlRightBud = meta.trueWirelessImageUrlRightBud,
156 unableToConnectDescription = meta.unableToConnectDescription,
157 unableToConnectTitle = meta.unableToConnectTitle,
158 updateCompAppDes = meta.updateCompanionAppDescription,
159 waitLaunchCompApp = meta.waitLaunchCompanionAppDescription
160 )
161
toFastPairDeviceMetadatanull162 fun toFastPairDeviceMetadata(): FastPairDeviceMetadata {
163 return FastPairDeviceMetadata.Builder()
164 .setBleTxPower(bleTxPower)
165 .setConnectSuccessCompanionAppInstalled(compAppInstalled)
166 .setConnectSuccessCompanionAppNotInstalled(comAppNotIns)
167 .setDeviceType(deviceType)
168 .setDownloadCompanionAppDescription(downloadComApp)
169 .setFailConnectGoToSettingsDescription(failConnectDes)
170 .setImageUrl(imageUrl)
171 .setInitialNotificationDescription(initNotification)
172 .setInitialNotificationDescriptionNoAccount(initNoAccount)
173 .setInitialPairingDescription(initialPairingDescription)
174 .setIntentUri(intentUri)
175 .setName(name)
176 .setOpenCompanionAppDescription(openCompanionAppDescription)
177 .setRetroactivePairingDescription(retroactivePairingDes)
178 .setSubsequentPairingDescription(subsequentPairingDescription)
179 .setTriggerDistance(triggerDistance.toFloat())
180 .setTrueWirelessImageUrlCase(trueWirelessImageUrlCase)
181 .setTrueWirelessImageUrlLeftBud(trueWirelessImageUrlLeftBud)
182 .setTrueWirelessImageUrlRightBud(trueWirelessImageUrlRightBud)
183 .setUnableToConnectDescription(unableToConnectDescription)
184 .setUnableToConnectTitle(unableToConnectTitle)
185 .setUpdateCompanionAppDescription(updateCompAppDes)
186 .setWaitLaunchCompanionAppDescription(waitLaunchCompApp)
187 .build()
188 }
189 }
190
191 data class FastPairDiscoveryItemData(
192 @SerializedName("action_url") val actionUrl: String?,
193 @SerializedName("action_url_type") val actionUrlType: Int,
194 @SerializedName("app_name") val appName: String?,
195 @SerializedName("authentication_public_key_secp256r1") val authenticationPublicKey: String?,
196 @SerializedName("description") val description: String?,
197 @SerializedName("device_name") val deviceName: String?,
198 @SerializedName("display_url") val displayUrl: String?,
199 @SerializedName("first_observation_timestamp_millis") val firstObservationMs: Long,
200 @SerializedName("icon_fife_url") val iconFfeUrl: String?,
201 @SerializedName("icon_png") val iconPng: String?,
202 @SerializedName("id") val id: String?,
203 @SerializedName("last_observation_timestamp_millis") val lastObservationMs: Long,
204 @SerializedName("mac_address") val macAddress: String?,
205 @SerializedName("package_name") val packageName: String?,
206 @SerializedName("pending_app_install_timestamp_millis") val pendingAppInstallMs: Long,
207 @SerializedName("rssi") val rssi: Int,
208 @SerializedName("state") val state: Int,
209 @SerializedName("title") val title: String?,
210 @SerializedName("trigger_id") val triggerId: String?,
211 @SerializedName("tx_power") val txPower: Int
212 ) {
213 constructor(item: FastPairDiscoveryItem) : this(
214 actionUrl = item.actionUrl,
215 actionUrlType = item.actionUrlType,
216 appName = item.appName,
217 authenticationPublicKey = item.authenticationPublicKeySecp256r1?.base64Encode(),
218 description = item.description,
219 deviceName = item.deviceName,
220 displayUrl = item.displayUrl,
221 firstObservationMs = item.firstObservationTimestampMillis,
222 iconFfeUrl = item.iconFfeUrl,
223 iconPng = item.iconPng?.base64Encode(),
224 id = item.id,
225 lastObservationMs = item.lastObservationTimestampMillis,
226 macAddress = item.macAddress,
227 packageName = item.packageName,
228 pendingAppInstallMs = item.pendingAppInstallTimestampMillis,
229 rssi = item.rssi,
230 state = item.state,
231 title = item.title,
232 triggerId = item.triggerId,
233 txPower = item.txPower
234 )
235
toFastPairDiscoveryItemnull236 fun toFastPairDiscoveryItem(): FastPairDiscoveryItem {
237 return FastPairDiscoveryItem.Builder()
238 .setActionUrl(actionUrl)
239 .setActionUrlType(actionUrlType)
240 .setAppName(appName)
241 .setAuthenticationPublicKeySecp256r1(authenticationPublicKey?.base64Decode())
242 .setDescription(description)
243 .setDeviceName(deviceName)
244 .setDisplayUrl(displayUrl)
245 .setFirstObservationTimestampMillis(firstObservationMs)
246 .setIconFfeUrl(iconFfeUrl)
247 .setIconPng(iconPng?.base64Decode())
248 .setId(id)
249 .setLastObservationTimestampMillis(lastObservationMs)
250 .setMacAddress(macAddress)
251 .setPackageName(packageName)
252 .setPendingAppInstallTimestampMillis(pendingAppInstallMs)
253 .setRssi(rssi)
254 .setState(state)
255 .setTitle(title)
256 .setTriggerId(triggerId)
257 .setTxPower(txPower)
258 .build()
259 }
260 }
261 }
262
Stringnull263 private fun String.base64Decode(): ByteArray = BaseEncoding.base64().decode(this)
264
265 private fun ByteArray.base64Encode(): String = BaseEncoding.base64().encode(this)
266