mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Manual selection for inline suggestions
This commit is contained in:
@@ -206,9 +206,9 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
|
||||
private const val KEY_REGISTER_INFO = "KEY_REGISTER_INFO"
|
||||
|
||||
fun getAuthIntentSenderForSelection(context: Context,
|
||||
searchInfo: SearchInfo? = null,
|
||||
inlineSuggestionsRequest: InlineSuggestionsRequest? = null): IntentSender {
|
||||
fun getPendingIntentForSelection(context: Context,
|
||||
searchInfo: SearchInfo? = null,
|
||||
inlineSuggestionsRequest: InlineSuggestionsRequest? = null): PendingIntent {
|
||||
return PendingIntent.getActivity(context, 0,
|
||||
// Doesn't work with Parcelable (don't know why?)
|
||||
Intent(context, AutofillLauncherActivity::class.java).apply {
|
||||
@@ -224,7 +224,7 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
}
|
||||
}
|
||||
},
|
||||
PendingIntent.FLAG_CANCEL_CURRENT).intentSender
|
||||
PendingIntent.FLAG_CANCEL_CURRENT)
|
||||
}
|
||||
|
||||
fun getAuthIntentSenderForRegistration(context: Context,
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.app.PendingIntent
|
||||
import android.app.assist.AssistStructure
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentSender
|
||||
import android.graphics.BlendMode
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
@@ -37,6 +38,7 @@ import android.view.autofill.AutofillValue
|
||||
import android.view.inputmethod.InlineSuggestionsRequest
|
||||
import android.widget.RemoteViews
|
||||
import android.widget.Toast
|
||||
import android.widget.inline.InlinePresentationSpec
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.autofill.inline.UiVersions
|
||||
import androidx.autofill.inline.v1.InlineSuggestionUi
|
||||
@@ -52,7 +54,6 @@ import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateField
|
||||
import com.kunzisoft.keepass.settings.AutofillSettingsActivity
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
@@ -273,6 +274,27 @@ object AutofillHelper {
|
||||
return null
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.R)
|
||||
@SuppressLint("RestrictedApi")
|
||||
private fun buildInlinePresentationForManualSelection(context: Context,
|
||||
inlinePresentationSpec: InlinePresentationSpec,
|
||||
pendingIntent: PendingIntent): InlinePresentation? {
|
||||
// Make sure that the IME spec claims support for v1 UI template.
|
||||
val imeStyle = inlinePresentationSpec.style
|
||||
if (!UiVersions.getVersions(imeStyle).contains(UiVersions.INLINE_UI_VERSION_1))
|
||||
return null
|
||||
|
||||
// Build the content for IME UI
|
||||
return InlinePresentation(
|
||||
InlineSuggestionUi.newContentBuilder(pendingIntent).apply {
|
||||
setContentDescription(context.getString(R.string.autofill_sign_in_prompt))
|
||||
setTitle(context.getString(R.string.autofill_manual_selection_prompt))
|
||||
setStartIcon(Icon.createWithResource(context, R.drawable.ic_arrow_right_green_24dp).apply {
|
||||
setTintBlendMode(BlendMode.DST)
|
||||
})
|
||||
}.build().slice, inlinePresentationSpec, false)
|
||||
}
|
||||
|
||||
fun buildResponse(context: Context,
|
||||
database: Database,
|
||||
entriesInfo: List<EntryInfo>,
|
||||
@@ -296,18 +318,28 @@ object AutofillHelper {
|
||||
}
|
||||
|
||||
// Add inline suggestion for new IME and dataset
|
||||
entriesInfo.forEachIndexed { index, entryInfo ->
|
||||
val inlinePresentation = inlineSuggestionsRequest?.let {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
buildInlinePresentationForEntry(context, database, inlineSuggestionsRequest, index, entryInfo)
|
||||
} else {
|
||||
null
|
||||
var numberInlineSuggestions = 0
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
inlineSuggestionsRequest?.let {
|
||||
numberInlineSuggestions = minOf(inlineSuggestionsRequest.maxSuggestionCount, entriesInfo.size)
|
||||
if (PreferencesUtil.isAutofillManualSelectionEnable(context)) {
|
||||
if (entriesInfo.size >= inlineSuggestionsRequest.maxSuggestionCount) {
|
||||
--numberInlineSuggestions
|
||||
}
|
||||
}
|
||||
}
|
||||
val dataSet = buildDataset(context, database, entryInfo, parseResult, inlinePresentation)
|
||||
dataSet?.let {
|
||||
responseBuilder.addDataset(it)
|
||||
|
||||
}
|
||||
|
||||
entriesInfo.forEachIndexed { _, entry ->
|
||||
val inlinePresentation = if (numberInlineSuggestions > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
inlineSuggestionsRequest?.let {
|
||||
buildInlinePresentationForEntry(context, database, inlineSuggestionsRequest, numberInlineSuggestions--, entry)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
responseBuilder.addDataset(buildDataset(context, database, entry, parseResult, inlinePresentation))
|
||||
}
|
||||
|
||||
if (PreferencesUtil.isAutofillManualSelectionEnable(context)) {
|
||||
@@ -319,16 +351,26 @@ object AutofillHelper {
|
||||
}
|
||||
val manualSelectionView = RemoteViews(context.packageName, R.layout.item_autofill_entry)
|
||||
manualSelectionView.setTextViewText(R.id.autofill_entry_text, context.getString(R.string.autofill_manual_selection_prompt))
|
||||
manualSelectionView.setImageViewResource(R.id.autofill_entry_icon, R.mipmap.ic_launcher_round)
|
||||
val intentSender = AutofillLauncherActivity.getAuthIntentSenderForSelection(context,
|
||||
// manualSelectionView.setImageViewResource(R.id.autofill_entry_icon, R.mipmap.ic_launcher_round)
|
||||
val pendingIntent = AutofillLauncherActivity.getPendingIntentForSelection(context,
|
||||
searchInfo, inlineSuggestionsRequest)
|
||||
|
||||
val builder = Dataset.Builder(manualSelectionView)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
inlineSuggestionsRequest?.let {
|
||||
val inlinePresentationSpec = inlineSuggestionsRequest.inlinePresentationSpecs[0]
|
||||
val inlinePresentation = buildInlinePresentationForManualSelection(context, inlinePresentationSpec, pendingIntent)
|
||||
inlinePresentation?.let {
|
||||
builder.setInlinePresentation(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// enable manual selection only for the form field that has focus
|
||||
parseResult.focusedId?.let { autofillId ->
|
||||
builder.setValue(autofillId, AutofillValue.forText("dummy"))
|
||||
builder.setAuthentication(intentSender)
|
||||
builder.setAuthentication(pendingIntent.intentSender)
|
||||
responseBuilder.addDataset(builder.build())
|
||||
}
|
||||
}
|
||||
@@ -371,6 +413,7 @@ object AutofillHelper {
|
||||
} else {
|
||||
buildResponse(activity, database, entriesInfo, result, null)
|
||||
}
|
||||
response.apply { }
|
||||
val mReplyIntent = Intent()
|
||||
Log.d(activity.javaClass.name, "Successed Autofill auth.")
|
||||
mReplyIntent.putExtra(
|
||||
|
||||
@@ -160,8 +160,8 @@ class KeeAutofillService : AutofillService() {
|
||||
if (autofillIds.isNotEmpty()) {
|
||||
// If the entire Autofill Response is authenticated, AuthActivity is used
|
||||
// to generate Response.
|
||||
val intentSender = AutofillLauncherActivity.getAuthIntentSenderForSelection(this,
|
||||
searchInfo, inlineSuggestionsRequest)
|
||||
val intentSender = AutofillLauncherActivity.getPendingIntentForSelection(this,
|
||||
searchInfo, inlineSuggestionsRequest).intentSender
|
||||
val responseBuilder = FillResponse.Builder()
|
||||
val remoteViewsUnlock: RemoteViews = if (!parseResult.webDomain.isNullOrEmpty()) {
|
||||
RemoteViews(packageName, R.layout.item_autofill_unlock_web_domain).apply {
|
||||
|
||||
9
app/src/main/res/drawable/ic_arrow_right_green_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_arrow_right_green_24dp.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
<path
|
||||
android:fillColor="@color/green"
|
||||
android:pathData="M10,17l5,-5 -5,-5v10z"/>
|
||||
</vector>
|
||||
@@ -31,7 +31,7 @@
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:contentDescription="@string/content_description_entry_icon"
|
||||
android:src="@drawable/ic_key_white_24dp" />
|
||||
android:src="@drawable/ic_arrow_right_green_24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/autofill_entry_text"
|
||||
|
||||
@@ -487,7 +487,7 @@
|
||||
<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_prompt">Select 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>
|
||||
|
||||
Reference in New Issue
Block a user