Coverage Summary for Class: InAppWebViewLearnedHostsStore (cloud.mindbox.mobile_sdk.inapp.data.managers)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| InAppWebViewLearnedHostsStore |
100%
(4/4)
|
|
100%
(4/4)
|
100%
(21/21)
|
| InAppWebViewLearnedHostsStore$Companion |
|
| InAppWebViewLearnedHostsStore$hosts$1 |
100%
(1/1)
|
62.5%
(5/8)
|
100%
(6/6)
|
96.9%
(62/64)
|
| InAppWebViewLearnedHostsStore$merge$1 |
100%
(1/1)
|
100%
(4/4)
|
100%
(5/5)
|
100%
(56/56)
|
| Total |
100%
(6/6)
|
75%
(9/12)
|
100%
(15/15)
|
98.6%
(139/141)
|
package cloud.mindbox.mobile_sdk.inapp.data.managers
import cloud.mindbox.mobile_sdk.managers.SharedPreferencesManager
import cloud.mindbox.mobile_sdk.utils.loggingRunCatching
import org.json.JSONArray
/**
* Persists https hosts actually observed during webview in-app shows (per endpoint).
* The mobile config only reveals the bootstrap hosts; the heavy ones (image CDNs)
* are discovered at show time and fed to the next launch's preconnect prewarm.
*/
internal class InAppWebViewLearnedHostsStore {
companion object {
private const val KEY_PREFIX = "MBInAppWebViewLearnedHosts."
private const val MAX_HOSTS = 12
}
fun hosts(endpointId: String): List<String> = loggingRunCatching(defaultValue = emptyList()) {
val raw = SharedPreferencesManager.getString(key(endpointId))
?.takeIf { it.isNotBlank() }
?: return@loggingRunCatching emptyList()
val array = JSONArray(raw)
(0 until array.length()).mapNotNull { index ->
array.optString(index).takeIf { host -> host.isNotBlank() }
}
}
/**
* Newest-first merge capped at [MAX_HOSTS] so one weird show can't flood the list.
* Synchronized: merges arrive from evaluate callbacks/coroutines of concurrent closes,
* and an unsynchronized read-modify-write would silently drop one close's hosts.
*/
@Synchronized
fun merge(endpointId: String, observedHosts: List<String>): Unit = loggingRunCatching {
if (endpointId.isBlank()) return@loggingRunCatching
val incoming = observedHosts.map(String::trim).filter(String::isNotBlank)
if (incoming.isEmpty()) return@loggingRunCatching
val merged = (incoming + hosts(endpointId)).distinct().take(MAX_HOSTS)
SharedPreferencesManager.put(key(endpointId), JSONArray(merged).toString())
}
private fun key(endpointId: String): String = KEY_PREFIX + endpointId
}