Skip to content
This repository was archived by the owner on Oct 15, 2024. It is now read-only.

Commit 26abbbe

Browse files
committed
refactor: rework password dialog to avoid memory leak
1 parent 227a2bf commit 26abbbe

File tree

3 files changed

+21
-19
lines changed

3 files changed

+21
-19
lines changed

app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import android.content.IntentSender
1111
import android.os.Build
1212
import android.os.Bundle
1313
import android.view.autofill.AutofillManager
14+
import androidx.fragment.app.setFragmentResultListener
1415
import androidx.lifecycle.lifecycleScope
1516
import app.passwordstore.R
1617
import app.passwordstore.data.crypto.PGPPassphraseCache
@@ -35,7 +36,6 @@ import dagger.hilt.android.AndroidEntryPoint
3536
import java.io.ByteArrayOutputStream
3637
import java.io.File
3738
import javax.inject.Inject
38-
import kotlinx.coroutines.flow.collectLatest
3939
import kotlinx.coroutines.launch
4040
import kotlinx.coroutines.withContext
4141
import logcat.LogPriority.ERROR
@@ -120,16 +120,15 @@ class AutofillDecryptActivity : BasePGPActivity() {
120120

121121
private fun askPassphrase(filePath: String, clientState: Bundle, action: AutofillAction) {
122122
val dialog = PasswordDialog()
123-
lifecycleScope.launch {
124-
withContext(dispatcherProvider.main()) {
125-
dialog.password.collectLatest { value ->
126-
if (value != null) {
127-
decryptWithPassphrase(File(filePath), clientState, action, value)
128-
}
123+
dialog.show(supportFragmentManager, "PASSWORD_DIALOG")
124+
dialog.setFragmentResultListener(PasswordDialog.PASSWORD_RESULT_KEY) { key, bundle ->
125+
if (key == PasswordDialog.PASSWORD_RESULT_KEY) {
126+
val value = bundle.getString(PasswordDialog.PASSWORD_RESULT_KEY)!!
127+
lifecycleScope.launch(dispatcherProvider.main()) {
128+
decryptWithPassphrase(File(filePath), clientState, action, value)
129129
}
130130
}
131131
}
132-
dialog.show(supportFragmentManager, "PASSWORD_DIALOG")
133132
}
134133

135134
private suspend fun decryptWithPassphrase(

app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import android.content.Intent
99
import android.os.Bundle
1010
import android.view.Menu
1111
import android.view.MenuItem
12+
import androidx.fragment.app.setFragmentResultListener
1213
import androidx.lifecycle.lifecycleScope
1314
import app.passwordstore.R
1415
import app.passwordstore.crypto.PGPIdentifier
@@ -35,7 +36,6 @@ import java.io.File
3536
import javax.inject.Inject
3637
import kotlin.time.Duration.Companion.seconds
3738
import kotlinx.coroutines.delay
38-
import kotlinx.coroutines.flow.collectLatest
3939
import kotlinx.coroutines.flow.first
4040
import kotlinx.coroutines.launch
4141
import kotlinx.coroutines.withContext
@@ -189,9 +189,11 @@ class DecryptActivity : BasePGPActivity() {
189189
if (isError) {
190190
dialog.setError()
191191
}
192-
lifecycleScope.launch(dispatcherProvider.main()) {
193-
dialog.password.collectLatest { value ->
194-
if (value != null) {
192+
dialog.show(supportFragmentManager, "PASSWORD_DIALOG")
193+
dialog.setFragmentResultListener(PasswordDialog.PASSWORD_RESULT_KEY) { key, bundle ->
194+
if (key == PasswordDialog.PASSWORD_RESULT_KEY) {
195+
val value = bundle.getString(PasswordDialog.PASSWORD_RESULT_KEY)!!
196+
lifecycleScope.launch(dispatcherProvider.main()) {
195197
when (val result = decryptWithPassphrase(value, gpgIdentifiers)) {
196198
is Ok -> {
197199
val entry = passwordEntryFactory.create(result.value.toByteArray())
@@ -210,7 +212,6 @@ class DecryptActivity : BasePGPActivity() {
210212
}
211213
}
212214
}
213-
dialog.show(supportFragmentManager, "PASSWORD_DIALOG")
214215
}
215216

216217
private suspend fun decryptWithCachedPassphrase(

app/src/main/java/app/passwordstore/ui/crypto/PasswordDialog.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,21 @@ import android.content.DialogInterface
1010
import android.os.Bundle
1111
import android.view.KeyEvent
1212
import android.view.WindowManager
13+
import androidx.core.os.bundleOf
1314
import androidx.core.widget.doOnTextChanged
1415
import androidx.fragment.app.DialogFragment
16+
import androidx.fragment.app.setFragmentResult
1517
import app.passwordstore.R
1618
import app.passwordstore.databinding.DialogPasswordEntryBinding
1719
import app.passwordstore.util.extensions.finish
1820
import app.passwordstore.util.extensions.unsafeLazy
1921
import com.google.android.material.dialog.MaterialAlertDialogBuilder
20-
import kotlinx.coroutines.flow.MutableStateFlow
21-
import kotlinx.coroutines.flow.asStateFlow
22-
import kotlinx.coroutines.flow.update
2322

2423
/** [DialogFragment] to request a password from the user and forward it along. */
2524
class PasswordDialog : DialogFragment() {
2625

2726
private val binding by unsafeLazy { DialogPasswordEntryBinding.inflate(layoutInflater) }
2827
private var isError: Boolean = false
29-
private val _password = MutableStateFlow<String?>(null)
30-
val password = _password.asStateFlow()
3128

3229
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
3330
val builder = MaterialAlertDialogBuilder(requireContext())
@@ -66,7 +63,12 @@ class PasswordDialog : DialogFragment() {
6663
}
6764

6865
private fun setPasswordAndDismiss() {
69-
_password.update { binding.passwordEditText.text.toString() }
66+
val password = binding.passwordEditText.text.toString()
67+
setFragmentResult(PASSWORD_RESULT_KEY, bundleOf(PASSWORD_RESULT_KEY to password))
7068
dismissAllowingStateLoss()
7169
}
70+
71+
companion object {
72+
const val PASSWORD_RESULT_KEY = "password_result"
73+
}
7274
}

0 commit comments

Comments
 (0)