setAuthentication method doesn't work with autofill

411 Views Asked by At

I'm using Autofill service in my app. But there are two problems with that:

  1. Presentation view is blinking while clicking on the username/passwords fields. Sometimes it appears but sometimes no.
  2. When I'm using setAuthentication method and returning the data set from my activity it doesn't work. It works for auto-filling in regular apps but doesn't work for webbrowsers.

I've already seen a lot of issues reported for chrome etc. but autofilling seems working correctly for example for the Bitwarden or Lastpass app.

This is my code in onFillRequest:

creating presentation:

val manualPresentation = createPresentation("Select password")

Creating data set:

val dataSet = Dataset.Builder()
            .setValue(
                passwordParsedAssistStructure.id,
                AutofillValue.forText(null)
            )
            .setValue(
                usernameParsedAssistStructure.id,
                AutofillValue.forText(null)
            )
 val intent = Intent(applicationContext, AutofillActivity::class.java)
        
val sender = PendingIntent.getActivity(
            applicationContext, id, intent,
            PendingIntent.FLAG_CANCEL_CURRENT
        ).intentSender

val ids = arrayOf(passwordParsedAssistStructure.id, usernameParsedAssistStructure.id)

     
return FillResponse.Builder()
    .addDataset(
                dataSet.build()
            )
    .setAuthentication(ids, sender, manualPresentation)
    .build()

also, I'm passing those ids into my activity and then return it:

 val returnDataset = Dataset.Builder()

        returnDataset.setValue(
            passwordId,
            AutofillValue.forText(String(password))
        ).setValue(
            userId,
            AutofillValue.forText(username)
        )

        val responseBuilder = FillResponse.Builder()
        responseBuilder.addDataset(returnDataset.build())

val replyIntent = Intent().apply {
            putExtra(EXTRA_AUTHENTICATION_RESULT, responseBuilder.build())
}

setResult(Activity.RESULT_OK, replyIntent)
finish()

What am I doing wrong? setAuthentication method should be set on dataSet or fillResponse? Activity should return Dataset or FillResponse?

1

There are 1 best solutions below

0
On
  1. It requires the android.permission.BIND_AUTOFILL_SERVICE permission in its manifest.

  2. The user explicitly enables it using Android Settings (the Settings#ACTION_REQUEST_SET_AUTOFILL_SERVICE intent can be used to launch such Settings screen).

This is typically useful when user interaction is required to unlock their data vault if you encrypt the data set labels and data set data. It is recommended to encrypt only the sensitive data and not the data set labels which would allow auth on the data set level leading to a better user experience. Note that if you use sensitive data as a label, for example, an email address, then it should also be encrypted. The provided intent must be an Activity that implements your authentication flow. Also if you provide an auth intent you also need to specify the presentation view to be shown in the fill UI for the user to trigger your authentication flow.

When a user triggers autofill, the system launches the provided intent whose extras will have the screen content and your client state. Once you complete your authentication flow you should set the Activity result to Activity.RESULT_OK and set the AutofillManager.EXTRA_AUTHENTICATION_RESULT extra with the fully populated response (or null if the screen cannot be auto-filled).

For example, if you provided an empty response because the user's data was locked and marked that the response needs authentication then in the response returned if authentication succeeds you need to provide all available data sets some of which may need to be further authenticated, for example, a credit card whose CVV needs to be entered.

If you provide an authentication intent you must also provide a presentation that is used to visualize the response for triggering the authentication flow.

new FillResponse.Builder() .addDataset(new Dataset.Builder() .setValue(id1, AutofillValue.forText("homer"), createPresentation("homer")) .setValue(id2, AutofillValue.forText("D'OH!"), createPresentation("password for homer")) .build()) .build();

For reference please check

https://developer.android.com/reference/android/service/autofill/FillResponse.Builder#setAuthentication(android.view.autofill.AutofillId[],%20android.content.IntentSender,%20android.widget.RemoteViews)

https://developer.android.com/reference/android/service/autofill/FillResponse.Builder#addDataset(android.service.autofill.Dataset)