mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Let user select entry for autofill
This commit is contained in:
@@ -65,6 +65,7 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
applicationId = intent.getStringExtra(KEY_SEARCH_APPLICATION_ID)
|
||||
webDomain = intent.getStringExtra(KEY_SEARCH_DOMAIN)
|
||||
webScheme = intent.getStringExtra(KEY_SEARCH_SCHEME)
|
||||
manualSelection = intent.getBooleanExtra(KEY_MANUAL_SELECTION, false)
|
||||
}
|
||||
SearchInfo.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
|
||||
searchInfo.webDomain = concreteWebDomain
|
||||
@@ -198,6 +199,7 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val KEY_MANUAL_SELECTION = "KEY_MANUAL_SELECTION"
|
||||
private const val KEY_SEARCH_APPLICATION_ID = "KEY_SEARCH_APPLICATION_ID"
|
||||
private const val KEY_SEARCH_DOMAIN = "KEY_SEARCH_DOMAIN"
|
||||
private const val KEY_SEARCH_SCHEME = "KEY_SEARCH_SCHEME"
|
||||
@@ -214,6 +216,7 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
putExtra(KEY_SEARCH_APPLICATION_ID, it.applicationId)
|
||||
putExtra(KEY_SEARCH_DOMAIN, it.webDomain)
|
||||
putExtra(KEY_SEARCH_SCHEME, it.webScheme)
|
||||
putExtra(KEY_MANUAL_SELECTION, it.manualSelection)
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
inlineSuggestionsRequest?.let {
|
||||
|
||||
@@ -42,6 +42,7 @@ import androidx.autofill.inline.UiVersions
|
||||
import androidx.autofill.inline.v1.InlineSuggestionUi
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.AutofillLauncherActivity
|
||||
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
|
||||
import com.kunzisoft.keepass.activities.helpers.SpecialMode
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
@@ -309,6 +310,26 @@ object AutofillHelper {
|
||||
}
|
||||
}
|
||||
|
||||
if (PreferencesUtil.isAutofillManualSelectionEnable(context)) {
|
||||
val searchInfo = SearchInfo().apply {
|
||||
applicationId = parseResult.applicationId
|
||||
webDomain = parseResult.webDomain
|
||||
webScheme = parseResult.webScheme
|
||||
manualSelection = true
|
||||
}
|
||||
|
||||
val manualSelectionView = newRemoteViews(context, database, context.getString(R.string.autofill_manual_selection_prompt), null)
|
||||
val intentSender = AutofillLauncherActivity.getAuthIntentSenderForSelection(context,
|
||||
searchInfo, null)
|
||||
val builder = Dataset.Builder(manualSelectionView)
|
||||
// enable manual selection only for the form field that has focus
|
||||
parseResult.focusedId?.let { autofillId ->
|
||||
builder.setValue(autofillId, AutofillValue.forText("dummy"))
|
||||
builder.setAuthentication(intentSender)
|
||||
responseBuilder.addDataset(builder.build())
|
||||
}
|
||||
}
|
||||
|
||||
return try {
|
||||
responseBuilder.build()
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -44,6 +44,7 @@ class StructureParser(private val structure: AssistStructure) {
|
||||
fun parse(saveValue: Boolean = false): Result? {
|
||||
try {
|
||||
result = Result()
|
||||
result?.focusedId = getFocusedID()
|
||||
result?.apply {
|
||||
allowSaveValues = saveValue
|
||||
usernameIdCandidate = null
|
||||
@@ -74,6 +75,35 @@ class StructureParser(private val structure: AssistStructure) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: SDK >= Q provides this method...
|
||||
* fillContext.getFocusedId()
|
||||
*/
|
||||
private fun getFocusedID(): AutofillId? {
|
||||
for (i in 0 until structure.windowNodeCount) {
|
||||
val windowNode = structure.getWindowNodeAt(i)
|
||||
val autofillId = traverse(windowNode.rootViewNode)
|
||||
if (autofillId != null) {
|
||||
return autofillId
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun traverse(node: AssistStructure.ViewNode): AutofillId? {
|
||||
if (node.visibility == View.VISIBLE && node.autofillHints != null) {
|
||||
return node.autofillId
|
||||
} else {
|
||||
for (i in 0 until node.childCount) {
|
||||
val autoFillId = traverse(node.getChildAt(i))
|
||||
if (autoFillId != null) {
|
||||
return autoFillId
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun parseViewNode(node: AssistStructure.ViewNode): Boolean {
|
||||
// remember this
|
||||
if (node.className == "android.webkit.WebView") {
|
||||
@@ -399,7 +429,6 @@ class StructureParser(private val structure: AssistStructure) {
|
||||
class Result {
|
||||
var isWebView: Boolean = false
|
||||
var applicationId: String? = null
|
||||
|
||||
var webDomain: String? = null
|
||||
set(value) {
|
||||
if (field == null)
|
||||
@@ -418,6 +447,9 @@ class StructureParser(private val structure: AssistStructure) {
|
||||
var creditCardExpirationMonthOptions: Array<CharSequence>? = null
|
||||
var creditCardExpirationDayOptions: Array<CharSequence>? = null
|
||||
|
||||
// the AutofillId of the view that triggered autofill.
|
||||
var focusedId: AutofillId? = null
|
||||
|
||||
var usernameId: AutofillId? = null
|
||||
set(value) {
|
||||
if (field == null)
|
||||
|
||||
@@ -106,7 +106,7 @@ class SearchHelper {
|
||||
} else if (TimeoutHelper.checkTime(context)) {
|
||||
var searchWithoutUI = false
|
||||
if (PreferencesUtil.isAutofillAutoSearchEnable(context)
|
||||
&& searchInfo != null
|
||||
&& searchInfo != null && !searchInfo.manualSelection
|
||||
&& !searchInfo.containsOnlyNullValues()) {
|
||||
// If search provide results
|
||||
database.createVirtualGroupFromSearchInfo(
|
||||
|
||||
@@ -14,7 +14,7 @@ import kotlinx.coroutines.launch
|
||||
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
|
||||
|
||||
class SearchInfo : ObjectNameResource, Parcelable {
|
||||
|
||||
var manualSelection: Boolean = false
|
||||
var applicationId: String? = null
|
||||
set(value) {
|
||||
field = when {
|
||||
|
||||
@@ -487,6 +487,12 @@ object PreferencesUtil {
|
||||
context.resources.getBoolean(R.bool.autofill_inline_suggestions_default))
|
||||
}
|
||||
|
||||
fun isAutofillManualSelectionEnable(context: Context): Boolean {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
return prefs.getBoolean(context.getString(R.string.autofill_manual_selection_key),
|
||||
context.resources.getBoolean(R.bool.autofill_manual_selection_default))
|
||||
}
|
||||
|
||||
fun isAutofillSaveSearchInfoEnable(context: Context): Boolean {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
return prefs.getBoolean(context.getString(R.string.autofill_save_search_info_key),
|
||||
@@ -624,6 +630,7 @@ object PreferencesUtil {
|
||||
context.getString(R.string.autofill_close_database_key) -> editor.putBoolean(name, value.toBoolean())
|
||||
context.getString(R.string.autofill_auto_search_key) -> editor.putBoolean(name, value.toBoolean())
|
||||
context.getString(R.string.autofill_inline_suggestions_key) -> editor.putBoolean(name, value.toBoolean())
|
||||
context.getString(R.string.autofill_manual_selection_key) -> editor.putBoolean(name, value.toBoolean())
|
||||
context.getString(R.string.autofill_save_search_info_key) -> editor.putBoolean(name, value.toBoolean())
|
||||
context.getString(R.string.autofill_ask_to_save_data_key) -> editor.putBoolean(name, value.toBoolean())
|
||||
context.getString(R.string.autofill_application_id_blocklist_key) -> editor.putStringSet(name, getStringSetFromProperties(value))
|
||||
|
||||
@@ -448,6 +448,9 @@
|
||||
<string name="validate">Validieren</string>
|
||||
<string name="autofill_auto_search_summary">Suchergebnisse automatisch nach Web-Domain oder Anwendungs-ID vorschlagen</string>
|
||||
<string name="autofill_auto_search_title">Automatische Suche</string>
|
||||
<string name="autofill_manual_selection_prompt">Eintrag auswählen...</string>
|
||||
<string name="autofill_manual_selection_title">Manuelle Auswahl</string>
|
||||
<string name="autofill_manual_selection_summary">Manuelle Auswahl des Datenbank-Eintrags ermöglichen</string>
|
||||
<string name="lock_database_show_button_summary">Zeigt die Sperrtaste in der Benutzeroberfläche an</string>
|
||||
<string name="lock_database_show_button_title">Sperrtaste anzeigen</string>
|
||||
<string name="autofill_preference_title">Einstellungen für automatisches Ausfüllen</string>
|
||||
|
||||
@@ -159,6 +159,8 @@
|
||||
<bool name="autofill_auto_search_default" translatable="false">true</bool>
|
||||
<string name="autofill_inline_suggestions_key" translatable="false">autofill_inline_suggestions_key</string>
|
||||
<bool name="autofill_inline_suggestions_default" translatable="false">false</bool>
|
||||
<string name="autofill_manual_selection_key" translatable="false">autofill_manual_selection_key</string>
|
||||
<bool name="autofill_manual_selection_default" translatable="false">false</bool>
|
||||
<string name="autofill_save_search_info_key" translatable="false">autofill_save_search_info_key</string>
|
||||
<bool name="autofill_save_search_info_default" translatable="false">true</bool>
|
||||
<string name="autofill_ask_to_save_data_key" translatable="false">autofill_ask_to_save_data_key</string>
|
||||
|
||||
@@ -487,6 +487,9 @@
|
||||
<string name="autofill_auto_search_summary">Automatically suggest search results from the web domain or application ID</string>
|
||||
<string name="autofill_inline_suggestions_title">Inline suggestions</string>
|
||||
<string name="autofill_inline_suggestions_summary">Attempt to display autofill suggestions directly from a compatible keyboard</string>
|
||||
<string name="autofill_manual_selection_prompt">Choose entry...</string>
|
||||
<string name="autofill_manual_selection_title">Manual selection</string>
|
||||
<string name="autofill_manual_selection_summary">Display option to let the user select database entry</string>
|
||||
<string name="autofill_save_search_info_title">Save search info</string>
|
||||
<string name="autofill_save_search_info_summary">Try to save search information when making a manual entry selection</string>
|
||||
<string name="autofill_ask_to_save_data_title">Ask to save data</string>
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
android:title="@string/autofill_inline_suggestions_title"
|
||||
android:summary="@string/autofill_inline_suggestions_summary"
|
||||
android:defaultValue="@bool/autofill_inline_suggestions_default"/>
|
||||
<SwitchPreference
|
||||
android:key="@string/autofill_manual_selection_key"
|
||||
android:title="@string/autofill_manual_selection_title"
|
||||
android:summary="@string/autofill_manual_selection_summary"
|
||||
android:defaultValue="@bool/autofill_manual_selection_default"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:title="@string/save">
|
||||
|
||||
Reference in New Issue
Block a user