From 3ddd06679f1e666716391450adaa687db33332c7 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Mon, 5 Oct 2020 08:29:44 +0530 Subject: [PATCH] Resolve lock contention from lazy delegates (#1135) --- .../main/java/com/zeapo/pwdstore/ClipboardService.kt | 6 ++---- .../zeapo/pwdstore/SearchableRepositoryViewModel.kt | 2 +- .../autofill/oreo/ui/AutofillSaveActivity.kt | 2 +- .../com/zeapo/pwdstore/crypto/BasePgpActivity.kt | 10 +++++----- .../com/zeapo/pwdstore/crypto/DecryptActivity.kt | 2 +- .../pwdstore/crypto/PasswordCreationActivity.kt | 12 ++++++------ .../com/zeapo/pwdstore/git/config/GitSettings.kt | 4 ++-- .../java/com/zeapo/pwdstore/git/log/GitLogModel.kt | 2 +- .../main/java/com/zeapo/pwdstore/git/sshj/SshKey.kt | 4 ++-- .../java/com/zeapo/pwdstore/model/PasswordEntry.kt | 2 +- .../ui/onboarding/fragments/CloneFragment.kt | 2 +- .../ui/onboarding/fragments/KeySelectionFragment.kt | 2 +- .../ui/onboarding/fragments/RepoLocationFragment.kt | 2 +- .../com/zeapo/pwdstore/utils/PasswordRepository.kt | 2 +- .../lib/publicsuffixlist/PublicSuffixList.kt | 2 +- 15 files changed, 27 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/zeapo/pwdstore/ClipboardService.kt b/app/src/main/java/com/zeapo/pwdstore/ClipboardService.kt index 46c4ecd3..0f27e5ef 100644 --- a/app/src/main/java/com/zeapo/pwdstore/ClipboardService.kt +++ b/app/src/main/java/com/zeapo/pwdstore/ClipboardService.kt @@ -10,7 +10,6 @@ import android.app.PendingIntent import android.app.Service import android.content.ClipData import android.content.Intent -import android.content.SharedPreferences import android.os.Build import android.os.IBinder import androidx.core.app.NotificationCompat @@ -32,7 +31,6 @@ import kotlinx.coroutines.withContext class ClipboardService : Service() { private val scope = CoroutineScope(Job() + Dispatchers.Main) - private val settings: SharedPreferences by lazy { sharedPrefs } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { if (intent != null) { @@ -45,7 +43,7 @@ class ClipboardService : Service() { } 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) { stopSelf() @@ -80,7 +78,7 @@ class ClipboardService : Service() { } private fun clearClipboard() { - val deepClear = settings.getBoolean(PreferenceKeys.CLEAR_CLIPBOARD_20X, false) + val deepClear = sharedPrefs.getBoolean(PreferenceKeys.CLEAR_CLIPBOARD_20X, false) val clipboard = clipboard if (clipboard != null) { diff --git a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt index 6da5de7a..a73dd40d 100644 --- a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt +++ b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt @@ -139,7 +139,7 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel private val root get() = PasswordRepository.getRepositoryDirectory() - private val settings by lazy { application.sharedPrefs } + private val settings by lazy(LazyThreadSafetyMode.NONE) { application.sharedPrefs } private val showHiddenContents get() = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false) private val defaultSearchMode diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt index 7f83d483..f4c296ee 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt @@ -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 shouldMatchWeb: String? = intent.getStringExtra(EXTRA_SHOULD_MATCH_WEB) if (shouldMatchApp != null && shouldMatchWeb == null) { diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/BasePgpActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/BasePgpActivity.kt index 8380d7d0..6b6c2032 100644 --- a/app/src/main/java/com/zeapo/pwdstore/crypto/BasePgpActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/crypto/BasePgpActivity.kt @@ -45,24 +45,24 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou /** * 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 */ - 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 * * 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. */ - val lastChangedString: CharSequence by lazy { + val lastChangedString: CharSequence by lazy(LazyThreadSafetyMode.NONE) { getLastChangedString( intent.getLongExtra( "LAST_CHANGED_TIMESTAMP", @@ -74,7 +74,7 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou /** * [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. diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/DecryptActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/DecryptActivity.kt index 3685cb17..cb43534d 100644 --- a/app/src/main/java/com/zeapo/pwdstore/crypto/DecryptActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/crypto/DecryptActivity.kt @@ -39,7 +39,7 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound { 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 val userInteractionRequiredResult = registerForActivityResult(StartIntentSenderForResult()) { result -> diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt index d0998d6d..01d85f2b 100644 --- a/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt @@ -56,12 +56,12 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB private val binding by viewBinding(PasswordCreationActivityBinding::inflate) - private val suggestedName by lazy { intent.getStringExtra(EXTRA_FILE_NAME) } - private val suggestedPass by lazy { intent.getStringExtra(EXTRA_PASSWORD) } - private val suggestedExtra by lazy { intent.getStringExtra(EXTRA_EXTRA_CONTENT) } - private val shouldGeneratePassword by lazy { intent.getBooleanExtra(EXTRA_GENERATE_PASSWORD, false) } - private val editing by lazy { intent.getBooleanExtra(EXTRA_EDITING, false) } - private val oldFileName by lazy { intent.getStringExtra(EXTRA_FILE_NAME) } + private val suggestedName by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_FILE_NAME) } + private val suggestedPass by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_PASSWORD) } + private val suggestedExtra by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_EXTRA_CONTENT) } + private val shouldGeneratePassword by lazy(LazyThreadSafetyMode.NONE) { intent.getBooleanExtra(EXTRA_GENERATE_PASSWORD, false) } + private val editing by lazy(LazyThreadSafetyMode.NONE) { intent.getBooleanExtra(EXTRA_EDITING, false) } + private val oldFileName by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_FILE_NAME) } private var oldCategory: String? = null private var copy: Boolean = false private var encryptionIntent: Intent = Intent() diff --git a/app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt b/app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt index e43deaf4..f928590d 100644 --- a/app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt +++ b/app/src/main/java/com/zeapo/pwdstore/git/config/GitSettings.kt @@ -52,8 +52,8 @@ object GitSettings { private const val DEFAULT_BRANCH = "master" - private val settings by lazy { Application.instance.sharedPrefs } - private val encryptedSettings by lazy { Application.instance.getEncryptedGitPrefs() } + private val settings by lazy(LazyThreadSafetyMode.PUBLICATION) { Application.instance.sharedPrefs } + private val encryptedSettings by lazy(LazyThreadSafetyMode.PUBLICATION) { Application.instance.getEncryptedGitPrefs() } var authMode get() = AuthMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH)) diff --git a/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogModel.kt b/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogModel.kt index ccd2f88a..15b9f64d 100644 --- a/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogModel.kt +++ b/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogModel.kt @@ -41,7 +41,7 @@ class GitLogModel { // 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 // user experience. - private val cache: MutableList by lazy { + private val cache: MutableList by lazy(LazyThreadSafetyMode.NONE) { commits().map { GitCommit(it.hash, it.shortMessage, it.authorIdent.name, it.time) }.toMutableList() diff --git a/app/src/main/java/com/zeapo/pwdstore/git/sshj/SshKey.kt b/app/src/main/java/com/zeapo/pwdstore/git/sshj/SshKey.kt index 73072f7d..5e6cfb1b 100644 --- a/app/src/main/java/com/zeapo/pwdstore/git/sshj/SshKey.kt +++ b/app/src/main/java/com/zeapo/pwdstore/git/sshj/SshKey.kt @@ -50,7 +50,7 @@ private const val PROVIDER_ANDROID_KEY_STORE = "AndroidKeyStore" private const val KEYSTORE_ALIAS = "sshkey" 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) } } @@ -119,7 +119,7 @@ object SshKey { 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) context.packageManager.hasSystemFeature(PackageManager.FEATURE_STRONGBOX_KEYSTORE) else diff --git a/app/src/main/java/com/zeapo/pwdstore/model/PasswordEntry.kt b/app/src/main/java/com/zeapo/pwdstore/model/PasswordEntry.kt index ea6255c4..556b2c87 100644 --- a/app/src/main/java/com/zeapo/pwdstore/model/PasswordEntry.kt +++ b/app/src/main/java/com/zeapo/pwdstore/model/PasswordEntry.kt @@ -59,7 +59,7 @@ class PasswordEntry(content: String, private val totpFinder: TotpFinder = UriTot 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 -> return@filter when { USERNAME_FIELDS.any { prefix -> line.startsWith(prefix, ignoreCase = true) } -> { diff --git a/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/CloneFragment.kt b/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/CloneFragment.kt index 19a14695..acd0151c 100644 --- a/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/CloneFragment.kt +++ b/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/CloneFragment.kt @@ -25,7 +25,7 @@ class CloneFragment : Fragment(R.layout.fragment_clone) { 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 -> if (result.resultCode == AppCompatActivity.RESULT_OK) { diff --git a/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/KeySelectionFragment.kt b/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/KeySelectionFragment.kt index 66017379..3dc03954 100644 --- a/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/KeySelectionFragment.kt +++ b/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/KeySelectionFragment.kt @@ -30,7 +30,7 @@ import me.msfjarvis.openpgpktx.util.OpenPgpApi 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 gpgKeySelectAction = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> diff --git a/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/RepoLocationFragment.kt b/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/RepoLocationFragment.kt index 2253dea8..d451fabe 100644 --- a/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/RepoLocationFragment.kt +++ b/app/src/main/java/com/zeapo/pwdstore/ui/onboarding/fragments/RepoLocationFragment.kt @@ -34,7 +34,7 @@ import java.io.File 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 sortOrder: PasswordRepository.PasswordSortOrder get() = PasswordRepository.PasswordSortOrder.getSortOrder(settings) diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt index f1655b3b..6e090ba3 100644 --- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt +++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt @@ -93,7 +93,7 @@ open class PasswordRepository protected constructor() { companion object { 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 get() = Application.instance.filesDir diff --git a/autofill-parser/src/main/java/mozilla/components/lib/publicsuffixlist/PublicSuffixList.kt b/autofill-parser/src/main/java/mozilla/components/lib/publicsuffixlist/PublicSuffixList.kt index d4d1c1af..f1cdb12a 100644 --- a/autofill-parser/src/main/java/mozilla/components/lib/publicsuffixlist/PublicSuffixList.kt +++ b/autofill-parser/src/main/java/mozilla/components/lib/publicsuffixlist/PublicSuffixList.kt @@ -32,7 +32,7 @@ class PublicSuffixList( 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.