@@ -12,22 +12,30 @@ import android.os.Build
12
12
import android.os.Bundle
13
13
import android.os.PersistableBundle
14
14
import android.view.WindowManager
15
+ import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
15
16
import androidx.annotation.CallSuper
16
17
import androidx.annotation.StringRes
17
18
import androidx.appcompat.app.AppCompatActivity
19
+ import androidx.lifecycle.lifecycleScope
18
20
import app.passwordstore.R
21
+ import app.passwordstore.data.crypto.CryptoRepository
19
22
import app.passwordstore.injection.prefs.SettingsPreferences
23
+ import app.passwordstore.ui.pgp.PGPKeyImportActivity
24
+ import app.passwordstore.util.coroutines.DispatcherProvider
20
25
import app.passwordstore.util.extensions.clipboard
21
26
import app.passwordstore.util.extensions.getString
22
27
import app.passwordstore.util.extensions.snackbar
23
28
import app.passwordstore.util.extensions.unsafeLazy
24
29
import app.passwordstore.util.services.ClipboardService
25
30
import app.passwordstore.util.settings.Constants
26
31
import app.passwordstore.util.settings.PreferenceKeys
32
+ import com.google.android.material.dialog.MaterialAlertDialogBuilder
27
33
import com.google.android.material.snackbar.Snackbar
28
34
import dagger.hilt.android.AndroidEntryPoint
29
35
import java.io.File
30
36
import javax.inject.Inject
37
+ import kotlinx.coroutines.launch
38
+ import kotlinx.coroutines.withContext
31
39
32
40
@Suppress(" Registered" )
33
41
@AndroidEntryPoint
@@ -46,8 +54,22 @@ open class BasePgpActivity : AppCompatActivity() {
46
54
*/
47
55
val name: String by unsafeLazy { File (fullPath).nameWithoutExtension }
48
56
57
+ /* * Action to invoke if [keyImportAction] succeeds. */
58
+ var onKeyImport: (() -> Unit )? = null
59
+ private val keyImportAction =
60
+ registerForActivityResult(StartActivityForResult ()) {
61
+ if (it.resultCode == RESULT_OK ) {
62
+ onKeyImport?.invoke()
63
+ onKeyImport = null
64
+ } else {
65
+ finish()
66
+ }
67
+ }
68
+
49
69
/* * [SharedPreferences] instance used by subclasses to persist settings */
50
70
@SettingsPreferences @Inject lateinit var settings: SharedPreferences
71
+ @Inject lateinit var repository: CryptoRepository
72
+ @Inject lateinit var dispatcherProvider: DispatcherProvider
51
73
52
74
/* *
53
75
* [onCreate] sets the window up with the right flags to prevent auth leaks through screenshots or
@@ -80,14 +102,36 @@ open class BasePgpActivity : AppCompatActivity() {
80
102
}
81
103
}
82
104
105
+ /* *
106
+ * Function to execute [onKeysExist] only if there are PGP keys imported in the app's key manager.
107
+ */
108
+ fun requireKeysExist (onKeysExist : () -> Unit ) {
109
+ lifecycleScope.launch {
110
+ val hasKeys = repository.hasKeys()
111
+ if (! hasKeys) {
112
+ withContext(dispatcherProvider.main()) {
113
+ MaterialAlertDialogBuilder (this @BasePgpActivity)
114
+ .setTitle(resources.getString(R .string.no_keys_imported_dialog_title))
115
+ .setMessage(resources.getString(R .string.no_keys_imported_dialog_message))
116
+ .setPositiveButton(resources.getString(R .string.button_label_import)) { _, _ ->
117
+ onKeyImport = onKeysExist
118
+ keyImportAction.launch(Intent (this @BasePgpActivity, PGPKeyImportActivity ::class .java))
119
+ }
120
+ .show()
121
+ }
122
+ } else {
123
+ onKeysExist()
124
+ }
125
+ }
126
+ }
127
+
83
128
/* *
84
129
* Copies a provided [password] string to the clipboard. This wraps [copyTextToClipboard] to hide
85
130
* the default [Snackbar] and starts off an instance of [ClipboardService] to provide a way of
86
131
* clearing the clipboard.
87
132
*/
88
133
fun copyPasswordToClipboard (password : String? ) {
89
134
copyTextToClipboard(password)
90
-
91
135
val clearAfter =
92
136
settings.getString(PreferenceKeys .GENERAL_SHOW_TIME )?.toIntOrNull()
93
137
? : Constants .DEFAULT_DECRYPTION_TIMEOUT
0 commit comments