fix: Refactoring activity launcher

This commit is contained in:
J-Jamet
2025-09-25 16:32:25 +02:00
parent 1bfec67c02
commit e447388611
9 changed files with 508 additions and 733 deletions

View File

@@ -305,11 +305,11 @@ class EntryActivity : DatabaseLockActivity() {
mEntryViewModel.historySelected.observe(this) { historySelected -> mEntryViewModel.historySelected.observe(this) { historySelected ->
mDatabase?.let { database -> mDatabase?.let { database ->
launch( launch(
this, activity = this,
database, database = database,
historySelected.nodeId, entryId = historySelected.nodeId,
historySelected.historyPosition, historyPosition = historySelected.historyPosition,
mEntryActivityResultLauncher activityResultLauncher = mEntryActivityResultLauncher
) )
} }
} }
@@ -471,11 +471,12 @@ class EntryActivity : DatabaseLockActivity() {
R.id.menu_edit -> { R.id.menu_edit -> {
mDatabase?.let { database -> mDatabase?.let { database ->
mMainEntryId?.let { entryId -> mMainEntryId?.let { entryId ->
EntryEditActivity.launchToUpdate( EntryEditActivity.launch(
this, activity = this,
database, database = database,
entryId, registrationType = EntryEditActivity.RegistrationType.UPDATE,
mEntryActivityResultLauncher nodeId = entryId,
activityResultLauncher = mEntryActivityResultLauncher
) )
} }
} }
@@ -527,34 +528,22 @@ class EntryActivity : DatabaseLockActivity() {
const val ENTRY_FRAGMENT_TAG = "ENTRY_FRAGMENT_TAG" const val ENTRY_FRAGMENT_TAG = "ENTRY_FRAGMENT_TAG"
/** /**
* Open standard Entry activity * Open standard or history Entry activity
*/ */
fun launch(activity: Activity, fun launch(
database: ContextualDatabase, activity: Activity,
entryId: NodeId<UUID>, database: ContextualDatabase,
activityResultLauncher: ActivityResultLauncher<Intent>) { entryId: NodeId<UUID>,
historyPosition: Int? = null,
activityResultLauncher: ActivityResultLauncher<Intent>
) {
if (database.loaded) { if (database.loaded) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) { if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
val intent = Intent(activity, EntryActivity::class.java) val intent = Intent(activity, EntryActivity::class.java)
intent.putExtra(KEY_ENTRY, entryId) intent.putExtra(KEY_ENTRY, entryId)
activityResultLauncher.launch(intent) historyPosition?.let {
} intent.putExtra(KEY_ENTRY_HISTORY_POSITION, historyPosition)
} }
}
/**
* Open history Entry activity
*/
fun launch(activity: Activity,
database: ContextualDatabase,
entryId: NodeId<UUID>,
historyPosition: Int,
activityResultLauncher: ActivityResultLauncher<Intent>) {
if (database.loaded) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
val intent = Intent(activity, EntryActivity::class.java)
intent.putExtra(KEY_ENTRY, entryId)
intent.putExtra(KEY_ENTRY_HISTORY_POSITION, historyPosition)
activityResultLauncher.launch(intent) activityResultLauncher.launch(intent)
} }
} }

View File

@@ -36,13 +36,10 @@ import android.widget.Spinner
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
@@ -791,6 +788,10 @@ class EntryEditActivity : DatabaseLockActivity(),
} }
} }
enum class RegistrationType {
UPDATE, CREATE
}
companion object { companion object {
private val TAG = EntryEditActivity::class.java.name private val TAG = EntryEditActivity::class.java.name
@@ -800,21 +801,10 @@ class EntryEditActivity : DatabaseLockActivity(),
const val KEY_PARENT = "parent" const val KEY_PARENT = "parent"
const val ADD_OR_UPDATE_ENTRY_KEY = "ADD_OR_UPDATE_ENTRY_KEY" const val ADD_OR_UPDATE_ENTRY_KEY = "ADD_OR_UPDATE_ENTRY_KEY"
fun registerForEntryResult(fragment: Fragment, fun registerForEntryResult(
entryAddedOrUpdatedListener: (NodeId<UUID>?) -> Unit): ActivityResultLauncher<Intent> { activity: FragmentActivity,
return fragment.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> entryAddedOrUpdatedListener: (NodeId<UUID>?) -> Unit
if (result.resultCode == RESULT_OK) { ): ActivityResultLauncher<Intent> {
entryAddedOrUpdatedListener.invoke(
result.data?.getParcelableExtraCompat(ADD_OR_UPDATE_ENTRY_KEY)
)
} else {
entryAddedOrUpdatedListener.invoke(null)
}
}
}
fun registerForEntryResult(activity: FragmentActivity,
entryAddedOrUpdatedListener: (NodeId<UUID>?) -> Unit): ActivityResultLauncher<Intent> {
return activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> return activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) { if (result.resultCode == RESULT_OK) {
entryAddedOrUpdatedListener.invoke( entryAddedOrUpdatedListener.invoke(
@@ -827,142 +817,74 @@ class EntryEditActivity : DatabaseLockActivity(),
} }
/** /**
* Launch EntryEditActivity to update an existing entry by his [entryId] * Launch EntryEditActivity to update an existing entry or to add a new entry in an existing group
*/ */
fun launchToUpdate(activity: Activity, fun launch(
database: ContextualDatabase, activity: Activity,
entryId: NodeId<UUID>, database: ContextualDatabase,
activityResultLauncher: ActivityResultLauncher<Intent>) { registrationType: RegistrationType,
nodeId: NodeId<*>,
activityResultLauncher: ActivityResultLauncher<Intent>
) {
if (database.loaded && !database.isReadOnly) { if (database.loaded && !database.isReadOnly) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) { if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
val intent = Intent(activity, EntryEditActivity::class.java) val intent = Intent(activity, EntryEditActivity::class.java)
intent.putExtra(KEY_ENTRY, entryId) when (registrationType) {
RegistrationType.UPDATE -> intent.putExtra(KEY_ENTRY, nodeId)
RegistrationType.CREATE -> intent.putExtra(KEY_PARENT, nodeId)
}
activityResultLauncher.launch(intent) activityResultLauncher.launch(intent)
} }
} }
} }
/** /**
* Launch EntryEditActivity to add a new entry in an existent group * Launch EntryEditActivity to add a new entry in special selection
*/ */
fun launchToCreate(activity: Activity, fun launchForSelection(
database: ContextualDatabase, context: Context,
groupId: NodeId<*>, database: ContextualDatabase,
activityResultLauncher: ActivityResultLauncher<Intent>) { typeMode: TypeMode,
if (database.loaded && !database.isReadOnly) { groupId: NodeId<*>,
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) { searchInfo: SearchInfo? = null,
val intent = Intent(activity, EntryEditActivity::class.java) autofillComponent: AutofillComponent? = null,
intent.putExtra(KEY_PARENT, groupId) activityResultLauncher: ActivityResultLauncher<Intent>? = null,
activityResultLauncher.launch(intent) ) {
}
}
}
/**
* Launch EntryEditActivity to add a new entry in keyboard selection
*/
fun launchForKeyboardSelectionResult(context: Context,
database: ContextualDatabase,
groupId: NodeId<*>,
searchInfo: SearchInfo? = null) {
if (database.loaded && !database.isReadOnly) { if (database.loaded && !database.isReadOnly) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(context)) { if (TimeoutHelper.checkTimeAndLockIfTimeout(context)) {
val intent = Intent(context, EntryEditActivity::class.java) val intent = Intent(context, EntryEditActivity::class.java)
intent.putExtra(KEY_PARENT, groupId) intent.putExtra(KEY_PARENT, groupId)
EntrySelectionHelper.startActivityForKeyboardSelectionModeResult( EntrySelectionHelper.startActivityForSelectionModeResult(
context, context = context,
intent, intent = intent,
searchInfo typeMode = typeMode,
searchInfo = searchInfo,
autofillComponent = autofillComponent,
activityResultLauncher = activityResultLauncher
) )
} }
} }
} }
/** /**
* Launch EntryEditActivity to add a new entry in autofill selection * Launch EntryEditActivity to update an updated entry or register a new entry (from autofill)
*/ */
@RequiresApi(api = Build.VERSION_CODES.O) fun launchForRegistration(
fun launchForAutofillResult(activity: AppCompatActivity, context: Context,
database: ContextualDatabase, database: ContextualDatabase,
activityResultLauncher: ActivityResultLauncher<Intent>?, nodeId: NodeId<*>,
autofillComponent: AutofillComponent, registerInfo: RegisterInfo? = null,
groupId: NodeId<*>, typeMode: TypeMode,
searchInfo: SearchInfo? = null) { registrationType: RegistrationType,
if (database.loaded && !database.isReadOnly) { activityResultLauncher: ActivityResultLauncher<Intent>? = null,
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) { ) {
val intent = Intent(activity, EntryEditActivity::class.java)
intent.putExtra(KEY_PARENT, groupId)
EntrySelectionHelper.startActivityForAutofillSelectionModeResult(
activity,
intent,
activityResultLauncher,
autofillComponent,
searchInfo
)
}
}
}
/**
* Launch EntryEditActivity to add a new passkey entry
*/
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
fun launchForPasskeySelectionResult(context: Context,
database: ContextualDatabase,
activityResultLauncher: ActivityResultLauncher<Intent>?,
groupId: NodeId<*>,
searchInfo: SearchInfo? = null) {
if (database.loaded && !database.isReadOnly) { if (database.loaded && !database.isReadOnly) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(context)) { if (TimeoutHelper.checkTimeAndLockIfTimeout(context)) {
val intent = Intent(context, EntryEditActivity::class.java) val intent = Intent(context, EntryEditActivity::class.java)
intent.putExtra(KEY_PARENT, groupId) when (registrationType) {
EntrySelectionHelper.startActivityForPasskeySelectionModeResult( RegistrationType.UPDATE -> intent.putExtra(KEY_ENTRY, nodeId)
context, RegistrationType.CREATE -> intent.putExtra(KEY_PARENT, nodeId)
intent, }
activityResultLauncher,
searchInfo
)
}
}
}
/**
* Launch EntryEditActivity to register an updated entry (from autofill)
*/
fun launchToUpdateForRegistration(context: Context,
database: ContextualDatabase,
activityResultLauncher: ActivityResultLauncher<Intent>?,
entryId: NodeId<UUID>,
registerInfo: RegisterInfo?,
typeMode: TypeMode) {
if (database.loaded && !database.isReadOnly) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(context)) {
val intent = Intent(context, EntryEditActivity::class.java)
intent.putExtra(KEY_ENTRY, entryId)
EntrySelectionHelper.startActivityForRegistrationModeResult(
context,
activityResultLauncher,
intent,
registerInfo,
typeMode
)
}
}
}
/**
* Launch EntryEditActivity to register a new entry (from autofill)
*/
fun launchToCreateForRegistration(context: Context,
database: ContextualDatabase,
activityResultLauncher: ActivityResultLauncher<Intent>?,
groupId: NodeId<*>,
registerInfo: RegisterInfo? = null,
typeMode: TypeMode) {
if (database.loaded && !database.isReadOnly) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(context)) {
val intent = Intent(context, EntryEditActivity::class.java)
intent.putExtra(KEY_PARENT, groupId)
EntrySelectionHelper.startActivityForRegistrationModeResult( EntrySelectionHelper.startActivityForRegistrationModeResult(
context, context,
activityResultLauncher, activityResultLauncher,

View File

@@ -33,8 +33,6 @@ import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.isVisible import androidx.core.view.isVisible
@@ -50,7 +48,6 @@ import com.kunzisoft.keepass.activities.legacy.DatabaseModeActivity
import com.kunzisoft.keepass.adapters.FileDatabaseHistoryAdapter import com.kunzisoft.keepass.adapters.FileDatabaseHistoryAdapter
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.buildActivityResultLauncher
import com.kunzisoft.keepass.credentialprovider.SpecialMode import com.kunzisoft.keepass.credentialprovider.SpecialMode
import com.kunzisoft.keepass.credentialprovider.TypeMode import com.kunzisoft.keepass.credentialprovider.TypeMode
import com.kunzisoft.keepass.credentialprovider.autofill.AutofillComponent import com.kunzisoft.keepass.credentialprovider.autofill.AutofillComponent
@@ -128,7 +125,7 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
mExternalFileHelper = ExternalFileHelper(this) mExternalFileHelper = ExternalFileHelper(this)
mExternalFileHelper?.buildOpenDocument { uri -> mExternalFileHelper?.buildOpenDocument { uri ->
uri?.let { uri?.let {
launchPasswordActivityWithPath(uri) launchMainCredentialActivityWithPath(uri)
} }
} }
mExternalFileHelper?.buildCreateDocument("application/x-keepass") { databaseFileCreatedUri -> mExternalFileHelper?.buildCreateDocument("application/x-keepass") { databaseFileCreatedUri ->
@@ -157,7 +154,7 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
} }
mAdapterDatabaseHistory?.setOnFileDatabaseHistoryOpenListener { fileDatabaseHistoryEntityToOpen -> mAdapterDatabaseHistory?.setOnFileDatabaseHistoryOpenListener { fileDatabaseHistoryEntityToOpen ->
fileDatabaseHistoryEntityToOpen.databaseUri?.let { databaseFileUri -> fileDatabaseHistoryEntityToOpen.databaseUri?.let { databaseFileUri ->
launchPasswordActivity( launchMainCredentialActivity(
databaseFileUri, databaseFileUri,
fileDatabaseHistoryEntityToOpen.keyFileUri, fileDatabaseHistoryEntityToOpen.keyFileUri,
fileDatabaseHistoryEntityToOpen.hardwareKey fileDatabaseHistoryEntityToOpen.hardwareKey
@@ -176,7 +173,7 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
// Load default database the first time // Load default database the first time
databaseFilesViewModel.doForDefaultDatabase { databaseFileUri -> databaseFilesViewModel.doForDefaultDatabase { databaseFileUri ->
launchPasswordActivityWithPath(databaseFileUri) launchMainCredentialActivityWithPath(databaseFileUri)
} }
// Retrieve the database URI provided by file manager after an orientation change // Retrieve the database URI provided by file manager after an orientation change
@@ -284,17 +281,104 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
Snackbar.make(coordinatorLayout, error, Snackbar.LENGTH_LONG).asError().show() Snackbar.make(coordinatorLayout, error, Snackbar.LENGTH_LONG).asError().show()
} }
private fun launchPasswordActivity(databaseUri: Uri, keyFile: Uri?, hardwareKey: HardwareKey?) { private fun launchMainCredentialActivity(databaseUri: Uri, keyFile: Uri?, hardwareKey: HardwareKey?) {
MainCredentialActivity.launch(this, try {
databaseUri, EntrySelectionHelper.doSpecialAction(
keyFile, intent = this.intent,
hardwareKey, defaultAction = {
{ exception -> MainCredentialActivity.launch(
fileNoFoundAction(exception) activity = this,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey
)
}, },
{ onCancelSpecialMode() }, searchAction = { searchInfo ->
{ onLaunchActivitySpecialMode() }, MainCredentialActivity.launchForSearchResult(
mCredentialActivityResultLauncher) activity = this,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
searchInfo = searchInfo
)
onLaunchActivitySpecialMode()
},
registrationAction = { registerInfo ->
MainCredentialActivity.launchForRegistration(
activity = this,
activityResultLauncher = mCredentialActivityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
typeMode = TypeMode.DEFAULT,
registerInfo = registerInfo
)
onLaunchActivitySpecialMode()
},
keyboardSelectionAction = { searchInfo ->
MainCredentialActivity.launchForSelection(
activity = this,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
typeMode = TypeMode.MAGIKEYBOARD,
searchInfo = searchInfo
)
onLaunchActivitySpecialMode()
},
autofillSelectionAction = { searchInfo, autofillComponent ->
MainCredentialActivity.launchForSelection(
activity = this,
activityResultLauncher = mCredentialActivityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
typeMode = TypeMode.AUTOFILL,
searchInfo = searchInfo,
autofillComponent = autofillComponent,
)
onLaunchActivitySpecialMode()
},
autofillRegistrationAction = { registerInfo ->
MainCredentialActivity.launchForRegistration(
activity = this,
activityResultLauncher = mCredentialActivityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
typeMode = TypeMode.AUTOFILL,
registerInfo = registerInfo
)
onLaunchActivitySpecialMode()
},
passkeySelectionAction = { searchInfo ->
MainCredentialActivity.launchForSelection(
activity = this,
activityResultLauncher = mCredentialActivityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
typeMode = TypeMode.PASSKEY,
searchInfo = searchInfo
)
onLaunchActivitySpecialMode()
},
passkeyRegistrationAction = { registerInfo ->
MainCredentialActivity.launchForRegistration(
activity = this,
activityResultLauncher = mCredentialActivityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
typeMode = TypeMode.PASSKEY,
registerInfo = registerInfo
)
onLaunchActivitySpecialMode()
}
)
} catch (e: FileNotFoundException) {
fileNoFoundAction(e)
}
} }
private fun launchGroupActivityIfLoaded(database: ContextualDatabase) { private fun launchGroupActivityIfLoaded(database: ContextualDatabase) {
@@ -308,8 +392,8 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
} }
} }
private fun launchPasswordActivityWithPath(databaseUri: Uri) { private fun launchMainCredentialActivityWithPath(databaseUri: Uri) {
launchPasswordActivity(databaseUri, null, null) launchMainCredentialActivity(databaseUri, null, null)
// Delete flickering for kitkat <= // Delete flickering for kitkat <=
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
@@ -439,58 +523,37 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
* ------------------------- * -------------------------
*/ */
fun launchForSearchResult(context: Context, fun launchForSearchResult(
searchInfo: SearchInfo) { context: Context,
EntrySelectionHelper.startActivityForSearchModeResult(context, searchInfo: SearchInfo
Intent(context, FileDatabaseSelectActivity::class.java), ) {
searchInfo) EntrySelectionHelper.startActivityForSearchModeResult(
context = context,
intent = Intent(context, FileDatabaseSelectActivity::class.java),
searchInfo = searchInfo
)
} }
/* /*
* ------------------------- * -------------------------
* Keyboard Launch * Selection Launch
* ------------------------- * -------------------------
*/ */
fun launchForKeyboardSelectionResult(activity: Activity, fun launchForSelection(
searchInfo: SearchInfo? = null) { activity: Activity,
EntrySelectionHelper.startActivityForKeyboardSelectionModeResult(activity, typeMode: TypeMode,
Intent(activity, FileDatabaseSelectActivity::class.java), searchInfo: SearchInfo? = null,
searchInfo) autofillComponent: AutofillComponent? = null,
} activityResultLauncher: ActivityResultLauncher<Intent>? = null,
) {
/* EntrySelectionHelper.startActivityForSelectionModeResult(
* ------------------------- context = activity,
* Autofill Launch intent = Intent(activity, FileDatabaseSelectActivity::class.java),
* ------------------------- searchInfo = searchInfo,
*/ typeMode = typeMode,
autofillComponent = autofillComponent,
@RequiresApi(api = Build.VERSION_CODES.O) activityResultLauncher = activityResultLauncher
fun launchForAutofillResult(activity: AppCompatActivity,
activityResultLauncher: ActivityResultLauncher<Intent>?,
autofillComponent: AutofillComponent,
searchInfo: SearchInfo? = null) {
EntrySelectionHelper.startActivityForAutofillSelectionModeResult(activity,
Intent(activity, FileDatabaseSelectActivity::class.java),
activityResultLauncher,
autofillComponent,
searchInfo)
}
/*
* -------------------------
* Passkey Launch
* -------------------------
*/
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
fun launchForPasskeySelectionResult(activity: Activity,
activityResultLauncher: ActivityResultLauncher<Intent>?,
searchInfo: SearchInfo? = null) {
EntrySelectionHelper.startActivityForPasskeySelectionModeResult(
activity,
Intent(activity, FileDatabaseSelectActivity::class.java),
activityResultLauncher,
searchInfo
) )
} }
@@ -499,16 +562,18 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
* Registration Launch * Registration Launch
* ------------------------- * -------------------------
*/ */
fun launchForRegistration(context: Context, fun launchForRegistration(
activityResultLauncher: ActivityResultLauncher<Intent>?, context: Context,
registerInfo: RegisterInfo? = null, activityResultLauncher: ActivityResultLauncher<Intent>?,
typeMode: TypeMode) { registerInfo: RegisterInfo? = null,
typeMode: TypeMode
) {
EntrySelectionHelper.startActivityForRegistrationModeResult( EntrySelectionHelper.startActivityForRegistrationModeResult(
context, context = context,
activityResultLauncher, activityResultLauncher = activityResultLauncher,
Intent(context, FileDatabaseSelectActivity::class.java), intent = Intent(context, FileDatabaseSelectActivity::class.java),
registerInfo, registerInfo = registerInfo,
typeMode typeMode = typeMode
) )
} }
} }

View File

@@ -41,7 +41,6 @@ import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
@@ -66,7 +65,6 @@ import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.activities.legacy.DatabaseLockActivity import com.kunzisoft.keepass.activities.legacy.DatabaseLockActivity
import com.kunzisoft.keepass.adapters.BreadcrumbAdapter import com.kunzisoft.keepass.adapters.BreadcrumbAdapter
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.buildActivityResultLauncher
import com.kunzisoft.keepass.credentialprovider.SpecialMode import com.kunzisoft.keepass.credentialprovider.SpecialMode
import com.kunzisoft.keepass.credentialprovider.TypeMode import com.kunzisoft.keepass.credentialprovider.TypeMode
import com.kunzisoft.keepass.credentialprovider.autofill.AutofillComponent import com.kunzisoft.keepass.credentialprovider.autofill.AutofillComponent
@@ -486,10 +484,11 @@ class GroupActivity : DatabaseLockActivity(),
intent = intent, intent = intent,
defaultAction = { defaultAction = {
mMainGroup?.nodeId?.let { currentParentGroupId -> mMainGroup?.nodeId?.let { currentParentGroupId ->
EntryEditActivity.launchToCreate( EntryEditActivity.launch(
activity = this@GroupActivity, activity = this@GroupActivity,
database = database, database = database,
groupId = currentParentGroupId, registrationType = EntryEditActivity.RegistrationType.CREATE,
nodeId = currentParentGroupId,
activityResultLauncher = mEntryActivityResultLauncher activityResultLauncher = mEntryActivityResultLauncher
) )
} }
@@ -498,73 +497,69 @@ class GroupActivity : DatabaseLockActivity(),
// Search not used // Search not used
}, },
registrationAction = { registerInfo -> registrationAction = { registerInfo ->
EntryEditActivity.launchToCreateForRegistration( EntryEditActivity.launchForRegistration(
context = this@GroupActivity, context = this@GroupActivity,
database = database, database = database,
activityResultLauncher = null, nodeId = currentGroup.nodeId,
groupId = currentGroup.nodeId,
registerInfo = registerInfo, registerInfo = registerInfo,
typeMode = TypeMode.DEFAULT typeMode = TypeMode.DEFAULT,
registrationType = EntryEditActivity.RegistrationType.CREATE
) )
onLaunchActivitySpecialMode() onLaunchActivitySpecialMode()
}, },
keyboardSelectionAction = { searchInfo -> keyboardSelectionAction = { searchInfo ->
EntryEditActivity.launchForKeyboardSelectionResult( EntryEditActivity.launchForSelection(
context = this@GroupActivity, context = this@GroupActivity,
database = database, database = database,
typeMode = TypeMode.MAGIKEYBOARD,
groupId = currentGroup.nodeId, groupId = currentGroup.nodeId,
searchInfo = searchInfo searchInfo = searchInfo
) )
onLaunchActivitySpecialMode() onLaunchActivitySpecialMode()
}, },
autofillSelectionAction = { searchInfo, autofillComponent -> autofillSelectionAction = { searchInfo, autofillComponent ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { EntryEditActivity.launchForSelection(
EntryEditActivity.launchForAutofillResult(
activity = this@GroupActivity,
database = database,
activityResultLauncher = mCredentialActivityResultLauncher,
autofillComponent = autofillComponent,
groupId = currentGroup.nodeId,
searchInfo = searchInfo
)
onLaunchActivitySpecialMode()
} else {
onCancelSpecialMode()
}
},
autofillRegistrationAction = { registerInfo ->
EntryEditActivity.launchToCreateForRegistration(
context = this@GroupActivity, context = this@GroupActivity,
database = database, database = database,
activityResultLauncher = null, typeMode = TypeMode.AUTOFILL,
groupId = currentGroup.nodeId, groupId = currentGroup.nodeId,
searchInfo = searchInfo,
autofillComponent = autofillComponent,
activityResultLauncher = mCredentialActivityResultLauncher
)
onLaunchActivitySpecialMode()
},
autofillRegistrationAction = { registerInfo ->
EntryEditActivity.launchForRegistration(
context = this@GroupActivity,
database = database,
nodeId = currentGroup.nodeId,
registerInfo = registerInfo, registerInfo = registerInfo,
typeMode = TypeMode.AUTOFILL typeMode = TypeMode.AUTOFILL,
registrationType = EntryEditActivity.RegistrationType.CREATE
) )
onLaunchActivitySpecialMode() onLaunchActivitySpecialMode()
}, },
passkeySelectionAction = { searchInfo -> passkeySelectionAction = { searchInfo ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { EntryEditActivity.launchForSelection(
EntryEditActivity.launchForPasskeySelectionResult( context = this@GroupActivity,
context = this@GroupActivity, database = database,
database = database, typeMode = TypeMode.PASSKEY,
activityResultLauncher = mCredentialActivityResultLauncher, groupId = currentGroup.nodeId,
groupId = currentGroup.nodeId, searchInfo = searchInfo,
searchInfo = searchInfo, activityResultLauncher = mCredentialActivityResultLauncher
) )
onLaunchActivitySpecialMode() onLaunchActivitySpecialMode()
} else {
onCancelSpecialMode()
}
}, },
passkeyRegistrationAction = { registerInfo -> passkeyRegistrationAction = { registerInfo ->
EntryEditActivity.launchToCreateForRegistration( EntryEditActivity.launchForRegistration(
context = this@GroupActivity, context = this@GroupActivity,
database = database, database = database,
activityResultLauncher = mCredentialActivityResultLauncher, activityResultLauncher = mCredentialActivityResultLauncher,
groupId = currentGroup.nodeId, nodeId = currentGroup.nodeId,
registerInfo = registerInfo, registerInfo = registerInfo,
typeMode = TypeMode.PASSKEY typeMode = TypeMode.PASSKEY,
registrationType = EntryEditActivity.RegistrationType.CREATE
) )
onLaunchActivitySpecialMode() onLaunchActivitySpecialMode()
} }
@@ -1018,13 +1013,14 @@ class GroupActivity : DatabaseLockActivity(),
) { ) {
removeSearch() removeSearch()
// Registration to update the entry // Registration to update the entry
EntryEditActivity.launchToUpdateForRegistration( EntryEditActivity.launchForRegistration(
context = this@GroupActivity, context = this@GroupActivity,
database = database, database = database,
activityResultLauncher = activityResultLauncher, activityResultLauncher = activityResultLauncher,
entryId = entry.nodeId, nodeId = entry.nodeId,
registerInfo = registerInfo, registerInfo = registerInfo,
typeMode = typeMode typeMode = typeMode,
registrationType = EntryEditActivity.RegistrationType.UPDATE
) )
onLaunchActivitySpecialMode() onLaunchActivitySpecialMode()
} }
@@ -1094,11 +1090,12 @@ class GroupActivity : DatabaseLockActivity(),
launchDialogForGroupUpdate(node as Group) launchDialogForGroupUpdate(node as Group)
} }
Type.ENTRY -> { Type.ENTRY -> {
EntryEditActivity.launchToUpdate( EntryEditActivity.launch(
this@GroupActivity, activity = this@GroupActivity,
database, database = database,
(node as Entry).nodeId, registrationType = EntryEditActivity.RegistrationType.UPDATE,
mEntryActivityResultLauncher nodeId = (node as Entry).nodeId,
activityResultLauncher = mEntryActivityResultLauncher
) )
} }
} }
@@ -1536,9 +1533,11 @@ class GroupActivity : DatabaseLockActivity(),
private const val OLD_GROUP_TO_UPDATE_KEY = "OLD_GROUP_TO_UPDATE_KEY" private const val OLD_GROUP_TO_UPDATE_KEY = "OLD_GROUP_TO_UPDATE_KEY"
private const val AUTO_SEARCH_KEY = "AUTO_SEARCH_KEY" private const val AUTO_SEARCH_KEY = "AUTO_SEARCH_KEY"
private fun buildIntent(context: Context, private fun buildIntent(
groupState: GroupState?, context: Context,
intentBuildLauncher: (Intent) -> Unit) { groupState: GroupState?,
intentBuildLauncher: (Intent) -> Unit
) {
val intent = Intent(context, GroupActivity::class.java) val intent = Intent(context, GroupActivity::class.java)
if (groupState != null) { if (groupState != null) {
intent.putExtra(GROUP_STATE_KEY, groupState) intent.putExtra(GROUP_STATE_KEY, groupState)
@@ -1546,18 +1545,12 @@ class GroupActivity : DatabaseLockActivity(),
intentBuildLauncher.invoke(intent) intentBuildLauncher.invoke(intent)
} }
private fun checkTimeAndBuildIntent(activity: Activity, private fun checkTimeAndBuildIntent(
groupState: GroupState?, context: Context,
intentBuildLauncher: (Intent) -> Unit) { groupState: GroupState?,
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) { intentBuildLauncher: (Intent) -> Unit
buildIntent(activity, groupState, intentBuildLauncher) ) {
} if (TimeoutHelper.checkTimeAndLockIfTimeout(context)) {
}
private fun checkTimeAndBuildIntent(context: Context,
groupState: GroupState?,
intentBuildLauncher: (Intent) -> Unit) {
if (TimeoutHelper.checkTime(context)) {
buildIntent(context, groupState, intentBuildLauncher) buildIntent(context, groupState, intentBuildLauncher)
} }
} }
@@ -1567,9 +1560,11 @@ class GroupActivity : DatabaseLockActivity(),
* Standard Launch * Standard Launch
* ------------------------- * -------------------------
*/ */
fun launch(context: Context, fun launch(
database: ContextualDatabase, context: Context,
autoSearch: Boolean = false) { database: ContextualDatabase,
autoSearch: Boolean = false
) {
if (database.loaded) { if (database.loaded) {
checkTimeAndBuildIntent(context, null) { intent -> checkTimeAndBuildIntent(context, null) { intent ->
intent.putExtra(AUTO_SEARCH_KEY, autoSearch) intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
@@ -1583,10 +1578,12 @@ class GroupActivity : DatabaseLockActivity(),
* Search Launch * Search Launch
* ------------------------- * -------------------------
*/ */
fun launchForSearchResult(context: Context, fun launchForSearchResult(
database: ContextualDatabase, context: Context,
searchInfo: SearchInfo, database: ContextualDatabase,
autoSearch: Boolean = false) { searchInfo: SearchInfo,
autoSearch: Boolean = false
) {
if (database.loaded) { if (database.loaded) {
checkTimeAndBuildIntent(context, null) { intent -> checkTimeAndBuildIntent(context, null) { intent ->
intent.putExtra(AUTO_SEARCH_KEY, autoSearch) intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
@@ -1599,72 +1596,25 @@ class GroupActivity : DatabaseLockActivity(),
} }
} }
/* fun launchForSelection(
* ------------------------- context: Context,
* Keyboard Launch database: ContextualDatabase,
* ------------------------- typeMode: TypeMode,
*/ searchInfo: SearchInfo? = null,
fun launchForKeyboardSelectionResult(context: Context, autoSearch: Boolean = false,
database: ContextualDatabase, autofillComponent: AutofillComponent? = null,
searchInfo: SearchInfo? = null, activityResultLauncher: ActivityResultLauncher<Intent>? = null,
autoSearch: Boolean = false) { ) {
if (database.loaded) { if (database.loaded) {
checkTimeAndBuildIntent(context, null) { intent -> checkTimeAndBuildIntent(context, null) { intent ->
intent.putExtra(AUTO_SEARCH_KEY, autoSearch) intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
EntrySelectionHelper.startActivityForKeyboardSelectionModeResult( EntrySelectionHelper.startActivityForSelectionModeResult(
context, context = context,
intent, intent = intent,
searchInfo typeMode = typeMode,
) searchInfo = searchInfo,
} autofillComponent = autofillComponent,
} activityResultLauncher = activityResultLauncher
}
/*
* -------------------------
* Autofill Launch
* -------------------------
*/
@RequiresApi(api = Build.VERSION_CODES.O)
fun launchForAutofillSelectionResult(activity: AppCompatActivity,
database: ContextualDatabase,
activityResultLauncher: ActivityResultLauncher<Intent>?,
autofillComponent: AutofillComponent,
searchInfo: SearchInfo? = null,
autoSearch: Boolean = false) {
if (database.loaded) {
checkTimeAndBuildIntent(activity, null) { intent ->
intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
EntrySelectionHelper.startActivityForAutofillSelectionModeResult(
activity,
intent,
activityResultLauncher,
autofillComponent,
searchInfo
)
}
}
}
/*
* -------------------------
* Passkey Launch
* -------------------------
*/
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
fun launchForPasskeySelectionResult(context: Context,
database: ContextualDatabase,
activityResultLauncher: ActivityResultLauncher<Intent>?,
searchInfo: SearchInfo? = null,
autoSearch: Boolean = false) {
if (database.loaded) {
checkTimeAndBuildIntent(context, null) { intent ->
intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
EntrySelectionHelper.startActivityForPasskeySelectionModeResult(
context,
intent,
activityResultLauncher,
searchInfo
) )
} }
} }
@@ -1675,11 +1625,13 @@ class GroupActivity : DatabaseLockActivity(),
* Registration Launch * Registration Launch
* ------------------------- * -------------------------
*/ */
fun launchForRegistration(context: Context, fun launchForRegistration(
activityResultLauncher: ActivityResultLauncher<Intent>?, context: Context,
database: ContextualDatabase, activityResultLauncher: ActivityResultLauncher<Intent>?,
registerInfo: RegisterInfo? = null, database: ContextualDatabase,
typeMode: TypeMode) { registerInfo: RegisterInfo? = null,
typeMode: TypeMode
) {
if (database.loaded && !database.isReadOnly) { if (database.loaded && !database.isReadOnly) {
checkTimeAndBuildIntent(context, null) { intent -> checkTimeAndBuildIntent(context, null) { intent ->
intent.putExtra(AUTO_SEARCH_KEY, false) intent.putExtra(AUTO_SEARCH_KEY, false)
@@ -1699,12 +1651,14 @@ class GroupActivity : DatabaseLockActivity(),
* Global Launch * Global Launch
* ------------------------- * -------------------------
*/ */
fun launch(activity: AppCompatActivity, fun launch(
database: ContextualDatabase, activity: AppCompatActivity,
onValidateSpecialMode: () -> Unit, database: ContextualDatabase,
onCancelSpecialMode: () -> Unit, onValidateSpecialMode: () -> Unit,
onLaunchActivitySpecialMode: () -> Unit, onCancelSpecialMode: () -> Unit,
activityResultLauncher: ActivityResultLauncher<Intent>?) { onLaunchActivitySpecialMode: () -> Unit,
activityResultLauncher: ActivityResultLauncher<Intent>?
) {
EntrySelectionHelper.doSpecialAction( EntrySelectionHelper.doSpecialAction(
intent = activity.intent, intent = activity.intent,
defaultAction = { defaultAction = {
@@ -1764,20 +1718,26 @@ class GroupActivity : DatabaseLockActivity(),
onValidateSpecialMode() onValidateSpecialMode()
}, },
{ autoSearch -> { autoSearch ->
launchForKeyboardSelectionResult(activity, launchForSelection(
database, context = activity,
searchInfo, database = database,
autoSearch) typeMode = TypeMode.MAGIKEYBOARD,
searchInfo = searchInfo,
autoSearch = autoSearch
)
onLaunchActivitySpecialMode() onLaunchActivitySpecialMode()
} }
) )
}, },
onItemNotFound = { onItemNotFound = {
// Here no search info found, disable auto search // Here no search info found, disable auto search
launchForKeyboardSelectionResult(activity, launchForSelection(
database, context = activity,
searchInfo, database = database,
false) typeMode = TypeMode.MAGIKEYBOARD,
searchInfo = searchInfo,
autoSearch = false
)
onLaunchActivitySpecialMode() onLaunchActivitySpecialMode()
}, },
onDatabaseClosed = { onDatabaseClosed = {
@@ -1788,35 +1748,33 @@ class GroupActivity : DatabaseLockActivity(),
}, },
autofillSelectionAction = { searchInfo, autofillComponent -> autofillSelectionAction = { searchInfo, autofillComponent ->
// Autofill selection // Autofill selection
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { SearchHelper.checkAutoSearchInfo(
SearchHelper.checkAutoSearchInfo( context = activity,
context = activity, database = database,
database = database, searchInfo = searchInfo,
searchInfo = searchInfo, onItemsFound = { openedDatabase, items ->
onItemsFound = { openedDatabase, items -> // Response is build
// Response is build AutofillHelper.buildResponseAndSetResult(activity, openedDatabase, items)
AutofillHelper.buildResponseAndSetResult(activity, openedDatabase, items) onValidateSpecialMode()
onValidateSpecialMode() },
}, onItemNotFound = {
onItemNotFound = { // Here no search info found, disable auto search
// Here no search info found, disable auto search launchForSelection(
launchForAutofillSelectionResult( context = activity,
activity = activity, database = database,
database = database, typeMode = TypeMode.AUTOFILL,
autofillComponent = autofillComponent, searchInfo = searchInfo,
searchInfo = searchInfo, autoSearch = false,
autoSearch = false, autofillComponent = autofillComponent,
activityResultLauncher = activityResultLauncher) activityResultLauncher = activityResultLauncher
onLaunchActivitySpecialMode() )
}, onLaunchActivitySpecialMode()
onDatabaseClosed = { },
// Simply close if database not opened, normally not happened onDatabaseClosed = {
onCancelSpecialMode() // Simply close if database not opened, normally not happened
} onCancelSpecialMode()
) }
} else { )
onCancelSpecialMode()
}
}, },
autofillRegistrationAction = { registerInfo -> autofillRegistrationAction = { registerInfo ->
// Autofill registration // Autofill registration
@@ -1859,49 +1817,47 @@ class GroupActivity : DatabaseLockActivity(),
}, },
passkeySelectionAction = { searchInfo -> passkeySelectionAction = { searchInfo ->
// Passkey selection // Passkey selection
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { SearchHelper.checkAutoSearchInfo(
SearchHelper.checkAutoSearchInfo( context = activity,
context = activity, database = database,
database = database, searchInfo = searchInfo,
searchInfo = searchInfo, onItemsFound = { _, items ->
onItemsFound = { _, items -> // Response is build
// Response is build EntrySelectionHelper.performSelection(
EntrySelectionHelper.performSelection( items = items,
items = items, actionPopulateCredentialProvider = { entryInfo ->
actionPopulateCredentialProvider = { entryInfo -> activity.buildPasskeyResponseAndSetResult(entryInfo)
activity.buildPasskeyResponseAndSetResult(entryInfo) onValidateSpecialMode()
onValidateSpecialMode() },
}, actionEntrySelection = {
actionEntrySelection = { launchForSelection(
launchForPasskeySelectionResult( context = activity,
context = activity, database = database,
database = database, typeMode = TypeMode.PASSKEY,
searchInfo = searchInfo, searchInfo = searchInfo,
activityResultLauncher = activityResultLauncher, activityResultLauncher = activityResultLauncher,
autoSearch = true autoSearch = true
) )
onLaunchActivitySpecialMode() onLaunchActivitySpecialMode()
} }
) )
}, },
onItemNotFound = { onItemNotFound = {
// Here no search info found, disable auto search // Here no search info found, disable auto search
launchForPasskeySelectionResult( launchForSelection(
context = activity, context = activity,
database = database, database = database,
searchInfo = searchInfo, typeMode = TypeMode.PASSKEY,
activityResultLauncher = activityResultLauncher searchInfo = searchInfo,
) activityResultLauncher = activityResultLauncher
onLaunchActivitySpecialMode() )
}, onLaunchActivitySpecialMode()
onDatabaseClosed = { },
// Simply close if database not opened, normally not happened onDatabaseClosed = {
onCancelSpecialMode() // Simply close if database not opened, normally not happened
} onCancelSpecialMode()
) }
} else { )
onCancelSpecialMode()
}
}, },
passkeyRegistrationAction = { registerInfo -> passkeyRegistrationAction = { registerInfo ->
// Passkey registration // Passkey registration

View File

@@ -36,7 +36,6 @@ import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.biometric.BiometricManager import androidx.biometric.BiometricManager
@@ -56,7 +55,6 @@ import com.kunzisoft.keepass.biometric.DeviceUnlockFragment
import com.kunzisoft.keepass.biometric.DeviceUnlockManager import com.kunzisoft.keepass.biometric.DeviceUnlockManager
import com.kunzisoft.keepass.biometric.deviceUnlockError import com.kunzisoft.keepass.biometric.deviceUnlockError
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.buildActivityResultLauncher
import com.kunzisoft.keepass.credentialprovider.SpecialMode import com.kunzisoft.keepass.credentialprovider.SpecialMode
import com.kunzisoft.keepass.credentialprovider.TypeMode import com.kunzisoft.keepass.credentialprovider.TypeMode
import com.kunzisoft.keepass.credentialprovider.autofill.AutofillComponent import com.kunzisoft.keepass.credentialprovider.autofill.AutofillComponent
@@ -746,11 +744,13 @@ class MainCredentialActivity : DatabaseModeActivity() {
private const val KEY_PASSWORD = "password" private const val KEY_PASSWORD = "password"
private const val KEY_LAUNCH_IMMEDIATELY = "launchImmediately" private const val KEY_LAUNCH_IMMEDIATELY = "launchImmediately"
private fun buildAndLaunchIntent(activity: Activity, private fun buildAndLaunchIntent(
databaseFile: Uri, activity: Activity,
keyFile: Uri?, databaseFile: Uri,
hardwareKey: HardwareKey?, keyFile: Uri?,
intentBuildLauncher: (Intent) -> Unit) { hardwareKey: HardwareKey?,
intentBuildLauncher: (Intent) -> Unit
) {
val intent = Intent(activity, MainCredentialActivity::class.java) val intent = Intent(activity, MainCredentialActivity::class.java)
intent.putExtra(KEY_FILENAME, databaseFile) intent.putExtra(KEY_FILENAME, databaseFile)
if (keyFile != null) if (keyFile != null)
@@ -767,10 +767,12 @@ class MainCredentialActivity : DatabaseModeActivity() {
*/ */
@Throws(FileNotFoundException::class) @Throws(FileNotFoundException::class)
fun launch(activity: Activity, fun launch(
databaseFile: Uri, activity: Activity,
keyFile: Uri?, databaseFile: Uri,
hardwareKey: HardwareKey?) { keyFile: Uri?,
hardwareKey: HardwareKey?
) {
buildAndLaunchIntent(activity, databaseFile, keyFile, hardwareKey) { intent -> buildAndLaunchIntent(activity, databaseFile, keyFile, hardwareKey) { intent ->
activity.startActivity(intent) activity.startActivity(intent)
} }
@@ -783,92 +785,58 @@ class MainCredentialActivity : DatabaseModeActivity() {
*/ */
@Throws(FileNotFoundException::class) @Throws(FileNotFoundException::class)
fun launchForSearchResult(activity: Activity, fun launchForSearchResult(
databaseFile: Uri, activity: Activity,
keyFile: Uri?, databaseFile: Uri,
hardwareKey: HardwareKey?, keyFile: Uri?,
searchInfo: SearchInfo) { hardwareKey: HardwareKey?,
searchInfo: SearchInfo
) {
buildAndLaunchIntent(activity, databaseFile, keyFile, hardwareKey) { intent -> buildAndLaunchIntent(activity, databaseFile, keyFile, hardwareKey) { intent ->
EntrySelectionHelper.startActivityForSearchModeResult( EntrySelectionHelper.startActivityForSearchModeResult(
activity, context = activity,
intent, intent = intent,
searchInfo) searchInfo = searchInfo
}
}
/*
* -------------------------
* Keyboard Launch
* -------------------------
*/
@Throws(FileNotFoundException::class)
fun launchForKeyboardResult(activity: Activity,
databaseFile: Uri,
keyFile: Uri?,
hardwareKey: HardwareKey?,
searchInfo: SearchInfo?) {
buildAndLaunchIntent(activity, databaseFile, keyFile, hardwareKey) { intent ->
EntrySelectionHelper.startActivityForKeyboardSelectionModeResult(
activity,
intent,
searchInfo)
}
}
/*
* -------------------------
* Autofill Launch
* -------------------------
*/
@RequiresApi(api = Build.VERSION_CODES.O)
@Throws(FileNotFoundException::class)
fun launchForAutofillResult(activity: AppCompatActivity,
activityResultLauncher: ActivityResultLauncher<Intent>?,
databaseFile: Uri,
keyFile: Uri?,
hardwareKey: HardwareKey?,
autofillComponent: AutofillComponent,
searchInfo: SearchInfo?) {
buildAndLaunchIntent(activity, databaseFile, keyFile, hardwareKey) { intent ->
EntrySelectionHelper.startActivityForAutofillSelectionModeResult(
activity,
intent,
activityResultLauncher,
autofillComponent,
searchInfo)
}
}
/*
* -------------------------
* Passkey Launch
* -------------------------
*/
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@Throws(FileNotFoundException::class)
fun launchForPasskeyResult(activity: Activity,
activityResultLauncher: ActivityResultLauncher<Intent>?,
databaseFile: Uri,
keyFile: Uri?,
hardwareKey: HardwareKey?,
searchInfo: SearchInfo?) {
buildAndLaunchIntent(activity, databaseFile, keyFile, hardwareKey) { intent ->
EntrySelectionHelper.startActivityForPasskeySelectionModeResult(
activity,
intent,
activityResultLauncher,
searchInfo
) )
} }
} }
/* /*
* ------------------------- * -------------------------
* Registration Launch * Selection Launch
* ------------------------- * -------------------------
*/ */
@Throws(FileNotFoundException::class)
fun launchForSelection(
activity: AppCompatActivity,
databaseFile: Uri,
keyFile: Uri?,
hardwareKey: HardwareKey?,
typeMode: TypeMode,
searchInfo: SearchInfo?,
autofillComponent: AutofillComponent? = null,
activityResultLauncher: ActivityResultLauncher<Intent>? = null,
) {
buildAndLaunchIntent(activity, databaseFile, keyFile, hardwareKey) { intent ->
EntrySelectionHelper.startActivityForSelectionModeResult(
context = activity,
intent = intent,
typeMode = typeMode,
searchInfo = searchInfo,
autofillComponent = autofillComponent,
activityResultLauncher = activityResultLauncher
)
}
}
/*
* -------------------------
* Registration Launch
* -------------------------
*/
@Throws(FileNotFoundException::class)
fun launchForRegistration( fun launchForRegistration(
activity: Activity, activity: Activity,
activityResultLauncher: ActivityResultLauncher<Intent>?, activityResultLauncher: ActivityResultLauncher<Intent>?,
@@ -888,123 +856,5 @@ class MainCredentialActivity : DatabaseModeActivity() {
) )
} }
} }
/*
* -------------------------
* Global Launch
* -------------------------
*/
fun launch(activity: AppCompatActivity,
databaseUri: Uri,
keyFile: Uri?,
hardwareKey: HardwareKey?,
fileNoFoundAction: (exception: FileNotFoundException) -> Unit,
onCancelSpecialMode: () -> Unit,
onLaunchActivitySpecialMode: () -> Unit,
activityResultLauncher: ActivityResultLauncher<Intent>?) {
try {
EntrySelectionHelper.doSpecialAction(
intent = activity.intent,
defaultAction = {
launch(
activity = activity,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey
)
},
searchAction = { searchInfo ->
launchForSearchResult(
activity = activity,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
searchInfo = searchInfo
)
onLaunchActivitySpecialMode()
},
registrationAction = { registerInfo ->
launchForRegistration(
activity = activity,
activityResultLauncher = activityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
typeMode = TypeMode.DEFAULT,
registerInfo = registerInfo
)
onLaunchActivitySpecialMode()
},
keyboardSelectionAction = { searchInfo ->
launchForKeyboardResult(
activity = activity,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
searchInfo = searchInfo
)
onLaunchActivitySpecialMode()
},
autofillSelectionAction = { searchInfo, autofillComponent ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
launchForAutofillResult(
activity = activity,
activityResultLauncher = activityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
autofillComponent = autofillComponent,
searchInfo = searchInfo
)
onLaunchActivitySpecialMode()
} else {
onCancelSpecialMode()
}
},
autofillRegistrationAction = { registerInfo ->
launchForRegistration(
activity = activity,
activityResultLauncher = activityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
typeMode = TypeMode.AUTOFILL,
registerInfo = registerInfo
)
onLaunchActivitySpecialMode()
},
passkeySelectionAction = { searchInfo ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
launchForPasskeyResult(
activity = activity,
activityResultLauncher = activityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
searchInfo = searchInfo
)
onLaunchActivitySpecialMode()
} else {
onCancelSpecialMode()
}
},
passkeyRegistrationAction = { registerInfo ->
launchForRegistration(
activity = activity,
activityResultLauncher = activityResultLauncher,
databaseFile = databaseUri,
keyFile = keyFile,
hardwareKey = hardwareKey,
typeMode = TypeMode.PASSKEY,
registerInfo = registerInfo
)
onLaunchActivitySpecialMode()
}
)
} catch (e: FileNotFoundException) {
fileNoFoundAction(e)
}
}
} }
} }

View File

@@ -102,58 +102,41 @@ object EntrySelectionHelper {
} }
} }
fun startActivityForSearchModeResult(context: Context, fun startActivityForSearchModeResult(
intent: Intent, context: Context,
searchInfo: SearchInfo) { intent: Intent,
searchInfo: SearchInfo
) {
addSpecialModeInIntent(intent, SpecialMode.SEARCH) addSpecialModeInIntent(intent, SpecialMode.SEARCH)
addSearchInfoInIntent(intent, searchInfo) addSearchInfoInIntent(intent, searchInfo)
intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK
context.startActivity(intent) context.startActivity(intent)
} }
fun startActivityForKeyboardSelectionModeResult(context: Context, fun startActivityForSelectionModeResult(
intent: Intent,
searchInfo: SearchInfo?) {
addSpecialModeInIntent(intent, SpecialMode.SELECTION)
addTypeModeInIntent(intent, TypeMode.MAGIKEYBOARD)
addSearchInfoInIntent(intent, searchInfo)
intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK
context.startActivity(intent)
}
/**
* Utility method to start an activity with an Autofill for result
*/
@RequiresApi(Build.VERSION_CODES.O)
fun startActivityForAutofillSelectionModeResult(
context: Context, context: Context,
intent: Intent, intent: Intent,
activityResultLauncher: ActivityResultLauncher<Intent>?, typeMode: TypeMode,
autofillComponent: AutofillComponent, searchInfo: SearchInfo?,
searchInfo: SearchInfo? autofillComponent: AutofillComponent? = null,
activityResultLauncher: ActivityResultLauncher<Intent>? = null,
) { ) {
addSpecialModeInIntent(intent, SpecialMode.SELECTION) addSpecialModeInIntent(intent, SpecialMode.SELECTION)
addTypeModeInIntent(intent, TypeMode.AUTOFILL) addTypeModeInIntent(intent, typeMode)
intent.addAutofillComponent(context, autofillComponent)
addSearchInfoInIntent(intent, searchInfo) addSearchInfoInIntent(intent, searchInfo)
activityResultLauncher?.launch(intent) autofillComponent?.let {
} if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.addAutofillComponent(context, autofillComponent)
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) }
fun startActivityForPasskeySelectionModeResult( }
context: Context, if (activityResultLauncher == null) {
intent: Intent, intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK
activityResultLauncher: ActivityResultLauncher<Intent>?, }
searchInfo: SearchInfo? activityResultLauncher?.launch(intent) ?: context.startActivity(intent)
) {
addSpecialModeInIntent(intent, SpecialMode.SELECTION)
addTypeModeInIntent(intent, TypeMode.PASSKEY)
addSearchInfoInIntent(intent, searchInfo)
activityResultLauncher?.launch(intent)
} }
fun startActivityForRegistrationModeResult( fun startActivityForRegistrationModeResult(
context: Context?, context: Context,
activityResultLauncher: ActivityResultLauncher<Intent>?, activityResultLauncher: ActivityResultLauncher<Intent>?,
intent: Intent, intent: Intent,
registerInfo: RegisterInfo?, registerInfo: RegisterInfo?,
@@ -165,8 +148,7 @@ object EntrySelectionHelper {
if (activityResultLauncher == null) { if (activityResultLauncher == null) {
intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK
} }
activityResultLauncher?.launch(intent) ?: context?.startActivity(intent) ?: activityResultLauncher?.launch(intent) ?: context.startActivity(intent)
throw IllegalStateException("At least Context or ActivityResultLauncher must not be null")
} }
fun addSearchInfoInIntent(intent: Intent, searchInfo: SearchInfo?) { fun addSearchInfoInIntent(intent: Intent, searchInfo: SearchInfo?) {
@@ -293,7 +275,11 @@ object EntrySelectionHelper {
defaultAction.invoke() defaultAction.invoke()
} }
TypeMode.MAGIKEYBOARD -> keyboardSelectionAction.invoke(searchInfo) TypeMode.MAGIKEYBOARD -> keyboardSelectionAction.invoke(searchInfo)
TypeMode.PASSKEY -> passkeySelectionAction.invoke(searchInfo) TypeMode.PASSKEY ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
passkeySelectionAction.invoke(searchInfo)
} else
defaultAction.invoke()
else -> { else -> {
// In this case, error // In this case, error
removeModesFromIntent(intent) removeModesFromIntent(intent)

View File

@@ -145,22 +145,24 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
}, },
onItemNotFound = { openedDatabase -> onItemNotFound = { openedDatabase ->
// Show the database UI to select the entry // Show the database UI to select the entry
GroupActivity.launchForAutofillSelectionResult( GroupActivity.launchForSelection(
this, context = this,
openedDatabase, database = openedDatabase,
mCredentialActivityResultLauncher, typeMode = TypeMode.AUTOFILL,
autofillComponent, searchInfo = searchInfo,
searchInfo, autoSearch = false,
false autofillComponent = autofillComponent,
activityResultLauncher = mCredentialActivityResultLauncher,
) )
}, },
onDatabaseClosed = { onDatabaseClosed = {
// If database not open // If database not open
FileDatabaseSelectActivity.launchForAutofillResult( FileDatabaseSelectActivity.launchForSelection(
this, activity = this,
mCredentialActivityResultLauncher, typeMode = TypeMode.AUTOFILL,
autofillComponent, searchInfo = searchInfo,
searchInfo autofillComponent = autofillComponent,
activityResultLauncher = mCredentialActivityResultLauncher
) )
} }
) )

View File

@@ -152,11 +152,12 @@ class EntrySelectionLauncherActivity : DatabaseModeActivity() {
) )
}, },
{ autoSearch -> { autoSearch ->
GroupActivity.launchForKeyboardSelectionResult( GroupActivity.launchForSelection(
this, context = this,
openedDatabase, database = openedDatabase,
searchInfo, typeMode = TypeMode.MAGIKEYBOARD,
autoSearch searchInfo = searchInfo,
autoSearch = autoSearch
) )
} }
) )
@@ -184,11 +185,12 @@ class EntrySelectionLauncherActivity : DatabaseModeActivity() {
toastError(RegisterInReadOnlyDatabaseException()) toastError(RegisterInReadOnlyDatabaseException())
} }
} else if (searchShareForMagikeyboard) { } else if (searchShareForMagikeyboard) {
GroupActivity.launchForKeyboardSelectionResult( GroupActivity.launchForSelection(
this, context = this,
openedDatabase, database = openedDatabase,
searchInfo, typeMode = TypeMode.MAGIKEYBOARD,
false searchInfo = searchInfo,
autoSearch = false
) )
} else { } else {
GroupActivity.launchForSearchResult( GroupActivity.launchForSearchResult(
@@ -209,9 +211,10 @@ class EntrySelectionLauncherActivity : DatabaseModeActivity() {
typeMode = TypeMode.DEFAULT typeMode = TypeMode.DEFAULT
) )
} else if (searchShareForMagikeyboard) { } else if (searchShareForMagikeyboard) {
FileDatabaseSelectActivity.launchForKeyboardSelectionResult( FileDatabaseSelectActivity.launchForSelection(
this, activity = this,
searchInfo typeMode = TypeMode.MAGIKEYBOARD,
searchInfo = searchInfo
) )
} else { } else {
FileDatabaseSelectActivity.launchForSearchResult( FileDatabaseSelectActivity.launchForSearchResult(

View File

@@ -118,9 +118,10 @@ class PasskeyLauncherActivity : DatabaseLockActivity() {
passkeyLauncherViewModel.cancelResult() passkeyLauncherViewModel.cancelResult()
} }
is PasskeyLauncherViewModel.UIState.LaunchGroupActivityForSelection -> { is PasskeyLauncherViewModel.UIState.LaunchGroupActivityForSelection -> {
GroupActivity.launchForPasskeySelectionResult( GroupActivity.launchForSelection(
context = this@PasskeyLauncherActivity, context = this@PasskeyLauncherActivity,
database = uiState.database, database = uiState.database,
typeMode = TypeMode.PASSKEY,
activityResultLauncher = mPasskeySelectionActivityResultLauncher, activityResultLauncher = mPasskeySelectionActivityResultLauncher,
searchInfo = null, searchInfo = null,
autoSearch = false autoSearch = false
@@ -136,8 +137,9 @@ class PasskeyLauncherActivity : DatabaseLockActivity() {
) )
} }
is PasskeyLauncherViewModel.UIState.LaunchFileDatabaseSelectActivityForSelection -> { is PasskeyLauncherViewModel.UIState.LaunchFileDatabaseSelectActivityForSelection -> {
FileDatabaseSelectActivity.launchForPasskeySelectionResult( FileDatabaseSelectActivity.launchForSelection(
activity = this@PasskeyLauncherActivity, activity = this@PasskeyLauncherActivity,
typeMode = TypeMode.PASSKEY,
activityResultLauncher = mPasskeySelectionActivityResultLauncher, activityResultLauncher = mPasskeySelectionActivityResultLauncher,
searchInfo = uiState.searchInfo, searchInfo = uiState.searchInfo,
) )