Merge branch 'main' into shielded-address-rotation
# Conflicts: # CHANGELOG.md
This commit is contained in:
commit
0ea712c9b4
|
@ -6,7 +6,8 @@ and this application adheres to [Semantic Versioning](https://semver.org/spec/v2
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
### Fixed
|
||||
- Shared preferences object cached in-memory and locked with semaphore in order to improve stability of security-crypto library
|
||||
- Shielded address is not rotated by navigating to Receive and Request screens from homepage
|
||||
|
||||
## [2.0.2 (962)] - 2025-05-14
|
||||
|
|
|
@ -30,7 +30,7 @@ import java.util.concurrent.Executors
|
|||
* this instance lives for the lifetime of the application. Constructing multiple instances will
|
||||
* potentially corrupt preference data and will leak resources.
|
||||
*/
|
||||
class AndroidPreferenceProvider private constructor(
|
||||
class AndroidPreferenceProvider(
|
||||
private val sharedPreferences: SharedPreferences,
|
||||
private val dispatcher: CoroutineDispatcher
|
||||
) : PreferenceProvider {
|
||||
|
@ -163,11 +163,22 @@ class AndroidPreferenceProvider private constructor(
|
|||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
suspend fun newStandard(
|
||||
context: Context,
|
||||
filename: String
|
||||
): PreferenceProvider {
|
||||
companion object Factory : AndroidPreferenceFactory by AndroidPreferenceFactoryImpl()
|
||||
}
|
||||
|
||||
interface AndroidPreferenceFactory {
|
||||
suspend fun newStandard(context: Context, filename: String): PreferenceProvider
|
||||
|
||||
suspend fun newEncrypted(context: Context, filename: String): PreferenceProvider
|
||||
}
|
||||
|
||||
private class AndroidPreferenceFactoryImpl : AndroidPreferenceFactory {
|
||||
private val semaphore = Mutex()
|
||||
private val standardCache = mutableMapOf<String, PreferenceProvider>()
|
||||
private val encryptedCache = mutableMapOf<String, PreferenceProvider>()
|
||||
|
||||
override suspend fun newStandard(context: Context, filename: String) =
|
||||
getOrCreate(standardCache, filename) {
|
||||
/*
|
||||
* Because of this line, we don't want multiple instances of this object created
|
||||
* because we don't clean up the thread afterwards.
|
||||
|
@ -182,10 +193,8 @@ class AndroidPreferenceProvider private constructor(
|
|||
return AndroidPreferenceProvider(sharedPreferences, singleThreadedDispatcher)
|
||||
}
|
||||
|
||||
suspend fun newEncrypted(
|
||||
context: Context,
|
||||
filename: String
|
||||
): PreferenceProvider {
|
||||
override suspend fun newEncrypted(context: Context, filename: String) =
|
||||
getOrCreate(encryptedCache, filename) {
|
||||
/*
|
||||
* Because of this line, we don't want multiple instances of this object created
|
||||
* because we don't clean up the thread afterwards.
|
||||
|
@ -212,5 +221,10 @@ class AndroidPreferenceProvider private constructor(
|
|||
|
||||
return AndroidPreferenceProvider(sharedPreferences, singleThreadedDispatcher)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend inline fun getOrCreate(
|
||||
map: MutableMap<String, PreferenceProvider>,
|
||||
filename: String,
|
||||
block: () -> PreferenceProvider
|
||||
): PreferenceProvider = semaphore.withLock { map.getOrPut(filename, block) }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue