Resolve lock contention from lazy delegates (#1135)
This commit is contained in:
parent
8a43160673
commit
3ddd06679f
15 changed files with 27 additions and 29 deletions
|
@ -10,7 +10,6 @@ import android.app.PendingIntent
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
|
@ -32,7 +31,6 @@ import kotlinx.coroutines.withContext
|
||||||
class ClipboardService : Service() {
|
class ClipboardService : Service() {
|
||||||
|
|
||||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||||
private val settings: SharedPreferences by lazy { sharedPrefs }
|
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
|
@ -45,7 +43,7 @@ class ClipboardService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ACTION_START -> {
|
ACTION_START -> {
|
||||||
val time = settings.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toIntOrNull() ?: 45
|
val time = sharedPrefs.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toIntOrNull() ?: 45
|
||||||
|
|
||||||
if (time == 0) {
|
if (time == 0) {
|
||||||
stopSelf()
|
stopSelf()
|
||||||
|
@ -80,7 +78,7 @@ class ClipboardService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clearClipboard() {
|
private fun clearClipboard() {
|
||||||
val deepClear = settings.getBoolean(PreferenceKeys.CLEAR_CLIPBOARD_20X, false)
|
val deepClear = sharedPrefs.getBoolean(PreferenceKeys.CLEAR_CLIPBOARD_20X, false)
|
||||||
val clipboard = clipboard
|
val clipboard = clipboard
|
||||||
|
|
||||||
if (clipboard != null) {
|
if (clipboard != null) {
|
||||||
|
|
|
@ -139,7 +139,7 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel
|
||||||
|
|
||||||
private val root
|
private val root
|
||||||
get() = PasswordRepository.getRepositoryDirectory()
|
get() = PasswordRepository.getRepositoryDirectory()
|
||||||
private val settings by lazy { application.sharedPrefs }
|
private val settings by lazy(LazyThreadSafetyMode.NONE) { application.sharedPrefs }
|
||||||
private val showHiddenContents
|
private val showHiddenContents
|
||||||
get() = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false)
|
get() = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false)
|
||||||
private val defaultSearchMode
|
private val defaultSearchMode
|
||||||
|
|
|
@ -82,7 +82,7 @@ class AutofillSaveActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val formOrigin: FormOrigin? by lazy {
|
private val formOrigin by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
val shouldMatchApp: String? = intent.getStringExtra(EXTRA_SHOULD_MATCH_APP)
|
val shouldMatchApp: String? = intent.getStringExtra(EXTRA_SHOULD_MATCH_APP)
|
||||||
val shouldMatchWeb: String? = intent.getStringExtra(EXTRA_SHOULD_MATCH_WEB)
|
val shouldMatchWeb: String? = intent.getStringExtra(EXTRA_SHOULD_MATCH_WEB)
|
||||||
if (shouldMatchApp != null && shouldMatchWeb == null) {
|
if (shouldMatchApp != null && shouldMatchWeb == null) {
|
||||||
|
|
|
@ -45,24 +45,24 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
|
||||||
/**
|
/**
|
||||||
* Full path to the repository
|
* Full path to the repository
|
||||||
*/
|
*/
|
||||||
val repoPath: String by lazy { intent.getStringExtra("REPO_PATH") }
|
val repoPath: String by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra("REPO_PATH") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Full path to the password file being worked on
|
* Full path to the password file being worked on
|
||||||
*/
|
*/
|
||||||
val fullPath: String by lazy { intent.getStringExtra("FILE_PATH") }
|
val fullPath: String by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra("FILE_PATH") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the password file
|
* Name of the password file
|
||||||
*
|
*
|
||||||
* Converts personal/auth.foo.org/john_doe@example.org.gpg to john_doe.example.org
|
* Converts personal/auth.foo.org/john_doe@example.org.gpg to john_doe.example.org
|
||||||
*/
|
*/
|
||||||
val name: String by lazy { File(fullPath).nameWithoutExtension }
|
val name: String by lazy(LazyThreadSafetyMode.NONE) { File(fullPath).nameWithoutExtension }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the timestamp for when this file was last modified.
|
* Get the timestamp for when this file was last modified.
|
||||||
*/
|
*/
|
||||||
val lastChangedString: CharSequence by lazy {
|
val lastChangedString: CharSequence by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
getLastChangedString(
|
getLastChangedString(
|
||||||
intent.getLongExtra(
|
intent.getLongExtra(
|
||||||
"LAST_CHANGED_TIMESTAMP",
|
"LAST_CHANGED_TIMESTAMP",
|
||||||
|
@ -74,7 +74,7 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
|
||||||
/**
|
/**
|
||||||
* [SharedPreferences] instance used by subclasses to persist settings
|
* [SharedPreferences] instance used by subclasses to persist settings
|
||||||
*/
|
*/
|
||||||
val settings: SharedPreferences by lazy { sharedPrefs }
|
val settings: SharedPreferences by lazy(LazyThreadSafetyMode.NONE) { sharedPrefs }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle to the [OpenPgpApi] instance that is used by subclasses to interface with OpenKeychain.
|
* Handle to the [OpenPgpApi] instance that is used by subclasses to interface with OpenKeychain.
|
||||||
|
|
|
@ -39,7 +39,7 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound {
|
||||||
|
|
||||||
private val binding by viewBinding(DecryptLayoutBinding::inflate)
|
private val binding by viewBinding(DecryptLayoutBinding::inflate)
|
||||||
|
|
||||||
private val relativeParentPath by lazy { getParentPath(fullPath, repoPath) }
|
private val relativeParentPath by lazy(LazyThreadSafetyMode.NONE) { getParentPath(fullPath, repoPath) }
|
||||||
private var passwordEntry: PasswordEntry? = null
|
private var passwordEntry: PasswordEntry? = null
|
||||||
|
|
||||||
private val userInteractionRequiredResult = registerForActivityResult(StartIntentSenderForResult()) { result ->
|
private val userInteractionRequiredResult = registerForActivityResult(StartIntentSenderForResult()) { result ->
|
||||||
|
|
|
@ -56,12 +56,12 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB
|
||||||
|
|
||||||
private val binding by viewBinding(PasswordCreationActivityBinding::inflate)
|
private val binding by viewBinding(PasswordCreationActivityBinding::inflate)
|
||||||
|
|
||||||
private val suggestedName by lazy { intent.getStringExtra(EXTRA_FILE_NAME) }
|
private val suggestedName by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_FILE_NAME) }
|
||||||
private val suggestedPass by lazy { intent.getStringExtra(EXTRA_PASSWORD) }
|
private val suggestedPass by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_PASSWORD) }
|
||||||
private val suggestedExtra by lazy { intent.getStringExtra(EXTRA_EXTRA_CONTENT) }
|
private val suggestedExtra by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_EXTRA_CONTENT) }
|
||||||
private val shouldGeneratePassword by lazy { intent.getBooleanExtra(EXTRA_GENERATE_PASSWORD, false) }
|
private val shouldGeneratePassword by lazy(LazyThreadSafetyMode.NONE) { intent.getBooleanExtra(EXTRA_GENERATE_PASSWORD, false) }
|
||||||
private val editing by lazy { intent.getBooleanExtra(EXTRA_EDITING, false) }
|
private val editing by lazy(LazyThreadSafetyMode.NONE) { intent.getBooleanExtra(EXTRA_EDITING, false) }
|
||||||
private val oldFileName by lazy { intent.getStringExtra(EXTRA_FILE_NAME) }
|
private val oldFileName by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_FILE_NAME) }
|
||||||
private var oldCategory: String? = null
|
private var oldCategory: String? = null
|
||||||
private var copy: Boolean = false
|
private var copy: Boolean = false
|
||||||
private var encryptionIntent: Intent = Intent()
|
private var encryptionIntent: Intent = Intent()
|
||||||
|
|
|
@ -52,8 +52,8 @@ object GitSettings {
|
||||||
|
|
||||||
private const val DEFAULT_BRANCH = "master"
|
private const val DEFAULT_BRANCH = "master"
|
||||||
|
|
||||||
private val settings by lazy { Application.instance.sharedPrefs }
|
private val settings by lazy(LazyThreadSafetyMode.PUBLICATION) { Application.instance.sharedPrefs }
|
||||||
private val encryptedSettings by lazy { Application.instance.getEncryptedGitPrefs() }
|
private val encryptedSettings by lazy(LazyThreadSafetyMode.PUBLICATION) { Application.instance.getEncryptedGitPrefs() }
|
||||||
|
|
||||||
var authMode
|
var authMode
|
||||||
get() = AuthMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
|
get() = AuthMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
|
||||||
|
|
|
@ -41,7 +41,7 @@ class GitLogModel {
|
||||||
// This is because the commit graph is walked from HEAD to the last commit to obtain.
|
// This is because the commit graph is walked from HEAD to the last commit to obtain.
|
||||||
// Additionally, tests with 1000 commits in the log have not produced a significant delay in the
|
// Additionally, tests with 1000 commits in the log have not produced a significant delay in the
|
||||||
// user experience.
|
// user experience.
|
||||||
private val cache: MutableList<GitCommit> by lazy {
|
private val cache: MutableList<GitCommit> by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
commits().map {
|
commits().map {
|
||||||
GitCommit(it.hash, it.shortMessage, it.authorIdent.name, it.time)
|
GitCommit(it.hash, it.shortMessage, it.authorIdent.name, it.time)
|
||||||
}.toMutableList()
|
}.toMutableList()
|
||||||
|
|
|
@ -50,7 +50,7 @@ private const val PROVIDER_ANDROID_KEY_STORE = "AndroidKeyStore"
|
||||||
private const val KEYSTORE_ALIAS = "sshkey"
|
private const val KEYSTORE_ALIAS = "sshkey"
|
||||||
private const val ANDROIDX_SECURITY_KEYSET_PREF_NAME = "androidx_sshkey_keyset_prefs"
|
private const val ANDROIDX_SECURITY_KEYSET_PREF_NAME = "androidx_sshkey_keyset_prefs"
|
||||||
|
|
||||||
private val androidKeystore: KeyStore by lazy {
|
private val androidKeystore: KeyStore by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
KeyStore.getInstance(PROVIDER_ANDROID_KEY_STORE).apply { load(null) }
|
KeyStore.getInstance(PROVIDER_ANDROID_KEY_STORE).apply { load(null) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ object SshKey {
|
||||||
putString(PreferenceKeys.GIT_REMOTE_KEY_TYPE, value?.value)
|
putString(PreferenceKeys.GIT_REMOTE_KEY_TYPE, value?.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val isStrongBoxSupported by lazy {
|
private val isStrongBoxSupported by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
|
||||||
context.packageManager.hasSystemFeature(PackageManager.FEATURE_STRONGBOX_KEYSTORE)
|
context.packageManager.hasSystemFeature(PackageManager.FEATURE_STRONGBOX_KEYSTORE)
|
||||||
else
|
else
|
||||||
|
|
|
@ -59,7 +59,7 @@ class PasswordEntry(content: String, private val totpFinder: TotpFinder = UriTot
|
||||||
return Otp.calculateCode(totpSecret, Date().time / (1000 * totpPeriod), totpAlgorithm, digits).get()
|
return Otp.calculateCode(totpSecret, Date().time / (1000 * totpPeriod), totpAlgorithm, digits).get()
|
||||||
}
|
}
|
||||||
|
|
||||||
val extraContentWithoutAuthData by lazy {
|
val extraContentWithoutAuthData by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
extraContent.splitToSequence("\n").filter { line ->
|
extraContent.splitToSequence("\n").filter { line ->
|
||||||
return@filter when {
|
return@filter when {
|
||||||
USERNAME_FIELDS.any { prefix -> line.startsWith(prefix, ignoreCase = true) } -> {
|
USERNAME_FIELDS.any { prefix -> line.startsWith(prefix, ignoreCase = true) } -> {
|
||||||
|
|
|
@ -25,7 +25,7 @@ class CloneFragment : Fragment(R.layout.fragment_clone) {
|
||||||
|
|
||||||
private val binding by viewBinding(FragmentCloneBinding::bind)
|
private val binding by viewBinding(FragmentCloneBinding::bind)
|
||||||
|
|
||||||
private val settings by lazy { requireActivity().applicationContext.sharedPrefs }
|
private val settings by lazy(LazyThreadSafetyMode.NONE) { requireActivity().applicationContext.sharedPrefs }
|
||||||
|
|
||||||
private val cloneAction = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
private val cloneAction = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||||
if (result.resultCode == AppCompatActivity.RESULT_OK) {
|
if (result.resultCode == AppCompatActivity.RESULT_OK) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||||
|
|
||||||
class KeySelectionFragment : Fragment(R.layout.fragment_key_selection) {
|
class KeySelectionFragment : Fragment(R.layout.fragment_key_selection) {
|
||||||
|
|
||||||
private val settings by lazy { requireActivity().applicationContext.sharedPrefs }
|
private val settings by lazy(LazyThreadSafetyMode.NONE) { requireActivity().applicationContext.sharedPrefs }
|
||||||
private val binding by viewBinding(FragmentKeySelectionBinding::bind)
|
private val binding by viewBinding(FragmentKeySelectionBinding::bind)
|
||||||
|
|
||||||
private val gpgKeySelectAction = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
private val gpgKeySelectAction = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||||
|
|
|
@ -34,7 +34,7 @@ import java.io.File
|
||||||
|
|
||||||
class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
||||||
|
|
||||||
private val settings by lazy { requireActivity().applicationContext.sharedPrefs }
|
private val settings by lazy(LazyThreadSafetyMode.NONE) { requireActivity().applicationContext.sharedPrefs }
|
||||||
private val binding by viewBinding(FragmentRepoLocationBinding::bind)
|
private val binding by viewBinding(FragmentRepoLocationBinding::bind)
|
||||||
private val sortOrder: PasswordRepository.PasswordSortOrder
|
private val sortOrder: PasswordRepository.PasswordSortOrder
|
||||||
get() = PasswordRepository.PasswordSortOrder.getSortOrder(settings)
|
get() = PasswordRepository.PasswordSortOrder.getSortOrder(settings)
|
||||||
|
|
|
@ -93,7 +93,7 @@ open class PasswordRepository protected constructor() {
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private var repository: Repository? = null
|
private var repository: Repository? = null
|
||||||
private val settings by lazy { Application.instance.sharedPrefs }
|
private val settings by lazy(LazyThreadSafetyMode.NONE) { Application.instance.sharedPrefs }
|
||||||
private val filesDir
|
private val filesDir
|
||||||
get() = Application.instance.filesDir
|
get() = Application.instance.filesDir
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class PublicSuffixList(
|
||||||
private val scope: CoroutineScope = CoroutineScope(dispatcher)
|
private val scope: CoroutineScope = CoroutineScope(dispatcher)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val data: PublicSuffixListData by lazy { PublicSuffixListLoader.load(context) }
|
private val data: PublicSuffixListData by lazy(LazyThreadSafetyMode.PUBLICATION) { PublicSuffixListLoader.load(context) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prefetch the public suffix list from disk so that it is available in memory.
|
* Prefetch the public suffix list from disk so that it is available in memory.
|
||||||
|
|
Loading…
Reference in a new issue