1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.vauth.foxyvpn.data
import android.content.Context
import com.vauth.foxyvpn.data.model.ProxyCandidate
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
class ProxyStateStore(context: Context) {
private val prefs = context.getSharedPreferences("foxyvpn_proxy_state", Context.MODE_PRIVATE)
private val _selectedProxyFlow = MutableStateFlow<ProxyCandidate?>(load())
val selectedProxyFlow: StateFlow<ProxyCandidate?> = _selectedProxyFlow
fun load(): ProxyCandidate? {
val host = prefs.getString(KEY_HOST, null) ?: return null
val port = prefs.getInt(KEY_PORT, 0)
if (port == 0) return null
return ProxyCandidate(
host = host,
port = port,
countryCode = prefs.getString(KEY_COUNTRY_CODE, "").orEmpty(),
countryName = prefs.getString(KEY_COUNTRY_NAME, "").orEmpty(),
cityCode = prefs.getString(KEY_CITY_CODE, "").orEmpty(),
)
}
fun save(candidate: ProxyCandidate) {
prefs.edit()
.putString(KEY_HOST, candidate.host)
.putInt(KEY_PORT, candidate.port)
.putString(KEY_COUNTRY_CODE, candidate.countryCode)
.putString(KEY_COUNTRY_NAME, candidate.countryName)
.putString(KEY_CITY_CODE, candidate.cityCode)
.putInt(KEY_FAILURES, 0)
.apply()
_selectedProxyFlow.value = candidate
}
fun recordFailure(): Pair<Int, Boolean> {
val failures = prefs.getInt(KEY_FAILURES, 0) + 1
if (failures >= FAILURE_THRESHOLD) {
clear()
return failures to true
}
prefs.edit().putInt(KEY_FAILURES, failures).apply()
return failures to false
}
fun clear() {
prefs.edit().clear().apply()
_selectedProxyFlow.value = null
}
companion object {
private const val KEY_HOST = "host"
private const val KEY_PORT = "port"
private const val KEY_COUNTRY_CODE = "country_code"
private const val KEY_COUNTRY_NAME = "country_name"
private const val KEY_CITY_CODE = "city_code"
private const val KEY_FAILURES = "failures"
private const val FAILURE_THRESHOLD = 3
}
}