mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
fix: runtime exception #1649
This commit is contained in:
@@ -3,7 +3,7 @@ KeePassDX(4.0.3)
|
||||
* Fix username autofill #1665 #530 #1572 #1426 #1523 #1556 #1653 #1658 #1508 #1667
|
||||
* Fix regex OTP recognition #1596
|
||||
* Change password color dynamically #1490
|
||||
* Small fixes #1641 #1656
|
||||
* Small fixes #1641 #1656 #1649
|
||||
|
||||
KeePassDX(4.0.2)
|
||||
* Fix Autofill with API 33
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.annotation.RequiresApi
|
||||
@@ -44,6 +45,7 @@ import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.utils.getParcelableCompat
|
||||
import com.kunzisoft.keepass.utils.getParcelableExtraCompat
|
||||
import com.kunzisoft.keepass.utils.WebDomain
|
||||
import java.lang.RuntimeException
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
@@ -216,6 +218,8 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
private val TAG = AutofillLauncherActivity::class.java.name
|
||||
|
||||
private const val KEY_SELECTION_BUNDLE = "KEY_SELECTION_BUNDLE"
|
||||
private const val KEY_SEARCH_INFO = "KEY_SEARCH_INFO"
|
||||
private const val KEY_INLINE_SUGGESTION = "KEY_INLINE_SUGGESTION"
|
||||
@@ -224,37 +228,51 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
|
||||
fun getPendingIntentForSelection(context: Context,
|
||||
searchInfo: SearchInfo? = null,
|
||||
compatInlineSuggestionsRequest: CompatInlineSuggestionsRequest? = null): PendingIntent {
|
||||
return PendingIntent.getActivity(context, 0,
|
||||
// Doesn't work with direct extra Parcelable (don't know why?)
|
||||
// Wrap into a bundle to bypass the problem
|
||||
Intent(context, AutofillLauncherActivity::class.java).apply {
|
||||
putExtra(KEY_SELECTION_BUNDLE, Bundle().apply {
|
||||
putParcelable(KEY_SEARCH_INFO, searchInfo)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
putParcelable(KEY_INLINE_SUGGESTION, compatInlineSuggestionsRequest)
|
||||
}
|
||||
})
|
||||
},
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
})
|
||||
compatInlineSuggestionsRequest: CompatInlineSuggestionsRequest? = null): PendingIntent? {
|
||||
try {
|
||||
return PendingIntent.getActivity(
|
||||
context, 0,
|
||||
// Doesn't work with direct extra Parcelable (don't know why?)
|
||||
// Wrap into a bundle to bypass the problem
|
||||
Intent(context, AutofillLauncherActivity::class.java).apply {
|
||||
putExtra(KEY_SELECTION_BUNDLE, Bundle().apply {
|
||||
putParcelable(KEY_SEARCH_INFO, searchInfo)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
putParcelable(KEY_INLINE_SUGGESTION, compatInlineSuggestionsRequest)
|
||||
}
|
||||
})
|
||||
},
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
)
|
||||
} catch (e: RuntimeException) {
|
||||
Log.e(TAG, "Unable to create pending intent for selection", e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
fun getPendingIntentForRegistration(context: Context,
|
||||
registerInfo: RegisterInfo): PendingIntent {
|
||||
return PendingIntent.getActivity(context, 0,
|
||||
Intent(context, AutofillLauncherActivity::class.java).apply {
|
||||
EntrySelectionHelper.addSpecialModeInIntent(this, SpecialMode.REGISTRATION)
|
||||
putExtra(KEY_REGISTER_INFO, registerInfo)
|
||||
},
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
})
|
||||
registerInfo: RegisterInfo): PendingIntent? {
|
||||
try {
|
||||
return PendingIntent.getActivity(
|
||||
context, 0,
|
||||
Intent(context, AutofillLauncherActivity::class.java).apply {
|
||||
EntrySelectionHelper.addSpecialModeInIntent(this, SpecialMode.REGISTRATION)
|
||||
putExtra(KEY_REGISTER_INFO, registerInfo)
|
||||
},
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
)
|
||||
} catch (e: RuntimeException) {
|
||||
Log.e(TAG, "Unable to create pending intent for registration", e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
fun launchForRegistration(context: Context,
|
||||
|
||||
@@ -452,46 +452,52 @@ object AutofillHelper {
|
||||
manualSelection = true
|
||||
}
|
||||
val manualSelectionView = RemoteViews(context.packageName, R.layout.item_autofill_select_entry)
|
||||
val pendingIntent = AutofillLauncherActivity.getPendingIntentForSelection(context,
|
||||
searchInfo, compatInlineSuggestionsRequest)
|
||||
AutofillLauncherActivity.getPendingIntentForSelection(context,
|
||||
searchInfo, compatInlineSuggestionsRequest)?.let { pendingIntent ->
|
||||
|
||||
var inlinePresentation: InlinePresentation? = null
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
compatInlineSuggestionsRequest?.inlineSuggestionsRequest?.let { inlineSuggestionsRequest ->
|
||||
val inlinePresentationSpec = inlineSuggestionsRequest.inlinePresentationSpecs[0]
|
||||
inlinePresentation = buildInlinePresentationForManualSelection(context, inlinePresentationSpec, pendingIntent)
|
||||
var inlinePresentation: InlinePresentation? = null
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
compatInlineSuggestionsRequest?.inlineSuggestionsRequest?.let { inlineSuggestionsRequest ->
|
||||
val inlinePresentationSpec =
|
||||
inlineSuggestionsRequest.inlinePresentationSpecs[0]
|
||||
inlinePresentation = buildInlinePresentationForManualSelection(
|
||||
context,
|
||||
inlinePresentationSpec,
|
||||
pendingIntent
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val datasetBuilder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
Dataset.Builder(Presentations.Builder()
|
||||
.apply {
|
||||
val datasetBuilder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
Dataset.Builder(Presentations.Builder()
|
||||
.apply {
|
||||
inlinePresentation?.let {
|
||||
setInlinePresentation(it)
|
||||
}
|
||||
}
|
||||
.setDialogPresentation(manualSelectionView)
|
||||
.setMenuPresentation(manualSelectionView)
|
||||
.build())
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
Dataset.Builder(manualSelectionView).apply {
|
||||
inlinePresentation?.let {
|
||||
setInlinePresentation(it)
|
||||
}
|
||||
}
|
||||
.setDialogPresentation(manualSelectionView)
|
||||
.setMenuPresentation(manualSelectionView)
|
||||
.build())
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
Dataset.Builder(manualSelectionView).apply {
|
||||
inlinePresentation?.let {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
setInlinePresentation(it)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
setInlinePresentation(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parseResult.allAutofillIds().let { autofillIds ->
|
||||
autofillIds.forEach { id ->
|
||||
datasetBuilder.addValueToDatasetBuilder(id, null)
|
||||
datasetBuilder.setAuthentication(pendingIntent.intentSender)
|
||||
parseResult.allAutofillIds().let { autofillIds ->
|
||||
autofillIds.forEach { id ->
|
||||
datasetBuilder.addValueToDatasetBuilder(id, null)
|
||||
datasetBuilder.setAuthentication(pendingIntent.intentSender)
|
||||
}
|
||||
val dataset = datasetBuilder.build()
|
||||
Log.d(TAG, "Autofill Dataset for manual selection $dataset created")
|
||||
responseBuilder.addDataset(dataset)
|
||||
}
|
||||
val dataset = datasetBuilder.build()
|
||||
Log.d(TAG, "Autofill Dataset for manual selection $dataset created")
|
||||
responseBuilder.addDataset(dataset)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -162,154 +162,184 @@ class KeeAutofillService : AutofillService() {
|
||||
if (autofillIds.isNotEmpty()) {
|
||||
// If the entire Autofill Response is authenticated, AuthActivity is used
|
||||
// to generate Response.
|
||||
val intentSender = AutofillLauncherActivity.getPendingIntentForSelection(this,
|
||||
searchInfo, inlineSuggestionsRequest).intentSender
|
||||
val responseBuilder = FillResponse.Builder()
|
||||
val remoteViewsUnlock: RemoteViews = if (database == null) {
|
||||
if (!parseResult.webDomain.isNullOrEmpty()) {
|
||||
RemoteViews(
|
||||
packageName,
|
||||
R.layout.item_autofill_unlock_web_domain
|
||||
).apply {
|
||||
setTextViewText(
|
||||
R.id.autofill_web_domain_text,
|
||||
parseResult.webDomain
|
||||
)
|
||||
}
|
||||
} else if (!parseResult.applicationId.isNullOrEmpty()) {
|
||||
RemoteViews(packageName, R.layout.item_autofill_unlock_app_id).apply {
|
||||
setTextViewText(
|
||||
R.id.autofill_app_id_text,
|
||||
parseResult.applicationId
|
||||
)
|
||||
AutofillLauncherActivity.getPendingIntentForSelection(this,
|
||||
searchInfo, inlineSuggestionsRequest)?.intentSender?.let { intentSender ->
|
||||
val responseBuilder = FillResponse.Builder()
|
||||
val remoteViewsUnlock: RemoteViews = if (database == null) {
|
||||
if (!parseResult.webDomain.isNullOrEmpty()) {
|
||||
RemoteViews(
|
||||
packageName,
|
||||
R.layout.item_autofill_unlock_web_domain
|
||||
).apply {
|
||||
setTextViewText(
|
||||
R.id.autofill_web_domain_text,
|
||||
parseResult.webDomain
|
||||
)
|
||||
}
|
||||
} else if (!parseResult.applicationId.isNullOrEmpty()) {
|
||||
RemoteViews(packageName, R.layout.item_autofill_unlock_app_id).apply {
|
||||
setTextViewText(
|
||||
R.id.autofill_app_id_text,
|
||||
parseResult.applicationId
|
||||
)
|
||||
}
|
||||
} else {
|
||||
RemoteViews(packageName, R.layout.item_autofill_unlock)
|
||||
}
|
||||
} else {
|
||||
RemoteViews(packageName, R.layout.item_autofill_unlock)
|
||||
}
|
||||
} else {
|
||||
if (!parseResult.webDomain.isNullOrEmpty()) {
|
||||
RemoteViews(
|
||||
packageName,
|
||||
R.layout.item_autofill_select_entry_web_domain
|
||||
).apply {
|
||||
setTextViewText(
|
||||
R.id.autofill_web_domain_text,
|
||||
parseResult.webDomain
|
||||
)
|
||||
if (!parseResult.webDomain.isNullOrEmpty()) {
|
||||
RemoteViews(
|
||||
packageName,
|
||||
R.layout.item_autofill_select_entry_web_domain
|
||||
).apply {
|
||||
setTextViewText(
|
||||
R.id.autofill_web_domain_text,
|
||||
parseResult.webDomain
|
||||
)
|
||||
}
|
||||
} else if (!parseResult.applicationId.isNullOrEmpty()) {
|
||||
RemoteViews(
|
||||
packageName,
|
||||
R.layout.item_autofill_select_entry_app_id
|
||||
).apply {
|
||||
setTextViewText(
|
||||
R.id.autofill_app_id_text,
|
||||
parseResult.applicationId
|
||||
)
|
||||
}
|
||||
} else {
|
||||
RemoteViews(packageName, R.layout.item_autofill_select_entry)
|
||||
}
|
||||
} else if (!parseResult.applicationId.isNullOrEmpty()) {
|
||||
RemoteViews(packageName, R.layout.item_autofill_select_entry_app_id).apply {
|
||||
setTextViewText(
|
||||
R.id.autofill_app_id_text,
|
||||
parseResult.applicationId
|
||||
)
|
||||
}
|
||||
} else {
|
||||
RemoteViews(packageName, R.layout.item_autofill_select_entry)
|
||||
}
|
||||
}
|
||||
|
||||
// Tell the autofill framework the interest to save credentials
|
||||
if (askToSaveData) {
|
||||
var types: Int = SaveInfo.SAVE_DATA_TYPE_GENERIC
|
||||
val requiredIds = ArrayList<AutofillId>()
|
||||
val optionalIds = ArrayList<AutofillId>()
|
||||
// Tell the autofill framework the interest to save credentials
|
||||
if (askToSaveData) {
|
||||
var types: Int = SaveInfo.SAVE_DATA_TYPE_GENERIC
|
||||
val requiredIds = ArrayList<AutofillId>()
|
||||
val optionalIds = ArrayList<AutofillId>()
|
||||
|
||||
// Only if at least a password
|
||||
parseResult.passwordId?.let { passwordInfo ->
|
||||
parseResult.usernameId?.let { usernameInfo ->
|
||||
types = types or SaveInfo.SAVE_DATA_TYPE_USERNAME
|
||||
requiredIds.add(usernameInfo)
|
||||
// Only if at least a password
|
||||
parseResult.passwordId?.let { passwordInfo ->
|
||||
parseResult.usernameId?.let { usernameInfo ->
|
||||
types = types or SaveInfo.SAVE_DATA_TYPE_USERNAME
|
||||
requiredIds.add(usernameInfo)
|
||||
}
|
||||
types = types or SaveInfo.SAVE_DATA_TYPE_PASSWORD
|
||||
requiredIds.add(passwordInfo)
|
||||
}
|
||||
types = types or SaveInfo.SAVE_DATA_TYPE_PASSWORD
|
||||
requiredIds.add(passwordInfo)
|
||||
}
|
||||
// or a credit card form
|
||||
if (requiredIds.isEmpty()) {
|
||||
parseResult.creditCardNumberId?.let { numberId ->
|
||||
types = types or SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD
|
||||
requiredIds.add(numberId)
|
||||
Log.d(TAG, "Asking to save credit card number")
|
||||
// or a credit card form
|
||||
if (requiredIds.isEmpty()) {
|
||||
parseResult.creditCardNumberId?.let { numberId ->
|
||||
types = types or SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD
|
||||
requiredIds.add(numberId)
|
||||
Log.d(TAG, "Asking to save credit card number")
|
||||
}
|
||||
parseResult.creditCardExpirationDateId?.let { id -> optionalIds.add(id) }
|
||||
parseResult.creditCardExpirationYearId?.let { id -> optionalIds.add(id) }
|
||||
parseResult.creditCardExpirationMonthId?.let { id -> optionalIds.add(id) }
|
||||
parseResult.creditCardHolderId?.let { id -> optionalIds.add(id) }
|
||||
parseResult.cardVerificationValueId?.let { id -> optionalIds.add(id) }
|
||||
}
|
||||
parseResult.creditCardExpirationDateId?.let { id -> optionalIds.add(id) }
|
||||
parseResult.creditCardExpirationYearId?.let { id -> optionalIds.add(id) }
|
||||
parseResult.creditCardExpirationMonthId?.let { id -> optionalIds.add(id) }
|
||||
parseResult.creditCardHolderId?.let { id -> optionalIds.add(id) }
|
||||
parseResult.cardVerificationValueId?.let { id -> optionalIds.add(id) }
|
||||
}
|
||||
if (requiredIds.isNotEmpty()) {
|
||||
val builder = SaveInfo.Builder(types, requiredIds.toTypedArray())
|
||||
if (optionalIds.isNotEmpty()) {
|
||||
builder.setOptionalIds(optionalIds.toTypedArray())
|
||||
if (requiredIds.isNotEmpty()) {
|
||||
val builder = SaveInfo.Builder(types, requiredIds.toTypedArray())
|
||||
if (optionalIds.isNotEmpty()) {
|
||||
builder.setOptionalIds(optionalIds.toTypedArray())
|
||||
}
|
||||
responseBuilder.setSaveInfo(builder.build())
|
||||
}
|
||||
responseBuilder.setSaveInfo(builder.build())
|
||||
}
|
||||
}
|
||||
|
||||
// Build inline presentation
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
||||
&& autofillInlineSuggestionsEnabled) {
|
||||
var inlinePresentation: InlinePresentation? = null
|
||||
inlineSuggestionsRequest?.inlineSuggestionsRequest?.let { inlineSuggestionsRequest ->
|
||||
val inlinePresentationSpecs = inlineSuggestionsRequest.inlinePresentationSpecs
|
||||
if (inlineSuggestionsRequest.maxSuggestionCount > 0
|
||||
&& inlinePresentationSpecs.size > 0) {
|
||||
val inlinePresentationSpec = inlinePresentationSpecs[0]
|
||||
// Build inline presentation
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
||||
&& autofillInlineSuggestionsEnabled
|
||||
) {
|
||||
var inlinePresentation: InlinePresentation? = null
|
||||
inlineSuggestionsRequest?.inlineSuggestionsRequest?.let { inlineSuggestionsRequest ->
|
||||
val inlinePresentationSpecs =
|
||||
inlineSuggestionsRequest.inlinePresentationSpecs
|
||||
if (inlineSuggestionsRequest.maxSuggestionCount > 0
|
||||
&& inlinePresentationSpecs.size > 0
|
||||
) {
|
||||
val inlinePresentationSpec = inlinePresentationSpecs[0]
|
||||
|
||||
// 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)) {
|
||||
// Build the content for IME UI
|
||||
inlinePresentation = 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)
|
||||
) {
|
||||
// Build the content for IME UI
|
||||
inlinePresentation = InlinePresentation(
|
||||
InlineSuggestionUi.newContentBuilder(
|
||||
PendingIntent.getActivity(this,
|
||||
0,
|
||||
Intent(this, AutofillSettingsActivity::class.java),
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
0
|
||||
})
|
||||
PendingIntent.getActivity(
|
||||
this,
|
||||
0,
|
||||
Intent(this, AutofillSettingsActivity::class.java),
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
0
|
||||
}
|
||||
)
|
||||
).apply {
|
||||
setContentDescription(getString(R.string.autofill_sign_in_prompt))
|
||||
setTitle(getString(R.string.autofill_sign_in_prompt))
|
||||
setStartIcon(Icon.createWithResource(this@KeeAutofillService, R.mipmap.ic_launcher_round).apply {
|
||||
setTintBlendMode(BlendMode.DST)
|
||||
})
|
||||
}.build().slice, inlinePresentationSpec, false)
|
||||
setStartIcon(
|
||||
Icon.createWithResource(
|
||||
this@KeeAutofillService,
|
||||
R.mipmap.ic_launcher_round
|
||||
).apply {
|
||||
setTintBlendMode(BlendMode.DST)
|
||||
})
|
||||
}.build().slice, inlinePresentationSpec, false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build response
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
try {
|
||||
// Buggy method on some API 33 devices
|
||||
// Build response
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
try {
|
||||
// Buggy method on some API 33 devices
|
||||
responseBuilder.setAuthentication(
|
||||
autofillIds,
|
||||
intentSender,
|
||||
Presentations.Builder().apply {
|
||||
inlinePresentation?.let {
|
||||
setInlinePresentation(it)
|
||||
}
|
||||
setDialogPresentation(remoteViewsUnlock)
|
||||
}.build()
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to use the new setAuthentication method.", e)
|
||||
@Suppress("DEPRECATION")
|
||||
responseBuilder.setAuthentication(
|
||||
autofillIds,
|
||||
intentSender,
|
||||
remoteViewsUnlock,
|
||||
inlinePresentation
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
responseBuilder.setAuthentication(
|
||||
autofillIds,
|
||||
intentSender,
|
||||
Presentations.Builder().apply {
|
||||
inlinePresentation?.let {
|
||||
setInlinePresentation(it)
|
||||
}
|
||||
setDialogPresentation(remoteViewsUnlock)
|
||||
}.build()
|
||||
remoteViewsUnlock,
|
||||
inlinePresentation
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to use the new setAuthentication method.", e)
|
||||
@Suppress("DEPRECATION")
|
||||
responseBuilder.setAuthentication(autofillIds, intentSender, remoteViewsUnlock, inlinePresentation)
|
||||
}
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
responseBuilder.setAuthentication(autofillIds, intentSender, remoteViewsUnlock, inlinePresentation)
|
||||
responseBuilder.setAuthentication(
|
||||
autofillIds,
|
||||
intentSender,
|
||||
remoteViewsUnlock
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
responseBuilder.setAuthentication(autofillIds, intentSender, remoteViewsUnlock)
|
||||
success = true
|
||||
callback.onSuccess(responseBuilder.build())
|
||||
}
|
||||
success = true
|
||||
callback.onSuccess(responseBuilder.build())
|
||||
}
|
||||
}
|
||||
if (!success)
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
* Fix username autofill #1665 #530 #1572 #1426 #1523 #1556 #1653 #1658 #1508 #1667
|
||||
* Fix regex OTP recognition #1596
|
||||
* Change password color dynamically #1490
|
||||
* Small fixes #1641 #1656
|
||||
* Small fixes #1641 #1656 #1649
|
||||
@@ -2,4 +2,4 @@
|
||||
* Correction du nom d'utilisateur dans la reconnaissance automatique #1665 #530 #1572 #1426 #1523 #1556 #1653 #1658 #1508 #1667
|
||||
* Correction de la regex de reconnaissance OTP #1596
|
||||
* Changement de couleur de mot passe dynamique #1490
|
||||
* Petites corrections #1641 #1656
|
||||
* Petites corrections #1641 #1656 #1649
|
||||
|
||||
Reference in New Issue
Block a user