4

I have implemented an Android Autofill Service for my password manager app. Users have reported issues with the Paypal app, where the service does not seem to work.

I have investigated this and found that the following code (Xamarin) in onFillRequest does work: ("does work" means the fields are filled after clicking the autofill popup)

var responseBuilder = new FillResponse.Builder();
var autofillIds = FindAutoFillIds(); //gets the autofill ids for each EditText
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, "fill data from onFillRequest", AppNames.LauncherIcon);
var datasetBuilder = new Dataset.Builder(presentation);

foreach (AutofillId autofillId in autofillIds)
{
    datasetBuilder.SetValue(autofillId, AutofillValue.ForText("some data"));
}

responseBuilder.AddDataset(datasetBuilder.Build());

callback.OnSuccess(responseBuilder.Build());

It basically creates a fill response with a single dataset which has values set for each autofill field.

Now I need to add an authentication activity:

var responseBuilder = new FillResponse.Builder();
var autofillIds = FindAutoFillIds(); //gets the autofill ids for each EditText

Intent intent = new Intent(this, typeof(MyAuthActivity));   
var sender = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.CancelCurrent).IntentSender;
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, "fill data after auth", AppNames.LauncherIcon);

var datasetBuilder = new Dataset.Builder(presentation);
//Main difference here:
datasetBuilder.SetAuthentication(sender);

foreach (AutofillId autofillId in autofillIds)
{
    datasetBuilder.SetValue(autofillId, AutofillValue.ForText("some placeholder data"));
}

responseBuilder.AddDataset(datasetBuilder.Build());

callback.OnSuccess(responseBuilder.Build());

where MyAuthActivity.OnCreate is like this:

RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, "dataset from auth activity", AppNames.LauncherIcon);

var datasetBuilder = new Dataset.Builder(presentation);
var autofillIds = GetAutofillIds(...); //returns the same autofillIds as in the onFillRequest

foreach (AutofillId autofillId in autofillIds)
{
    datasetBuilder.SetValue(autofillId, AutofillValue.ForText("some other data"));
}
var ReplyIntent = new Intent();

bool returnDataset = true; //tried both true and false, neither works
if (returnDataset)
{
    ReplyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, datasetBuilder.Build());
}
else
{
    var responseBuilder = new FillResponse.Builder();
    responseBuilder.AddDataset(datasetBuilder.Build());
    ReplyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, responseBuilder.Build());
}

SetResult(Result.Ok, ReplyIntent);
Finish();

which basically creates another dataset using the same autofill ids, but neither returning them with a FillResponse nor a Dataset response works: The input fields on the target app remain empty.

I noticed that the same behavior appears in Bitwarden's implementation of their autofill service.

My questions are: Is there anything wrong with the code of the authentication activity? Or does this show an issue with Paypal's app? And is there anything I can do to debug this further?

Philipp
  • 11,549
  • 8
  • 66
  • 126

1 Answers1

0

This is a known WebView issue, which is fixed on Chrome M64.

You can verify it's fixed by installing a newer Chrome and changing the default WebView implementation through Settings -> Developer Options.

Felipe Leme
  • 181
  • 4
  • With Chrome beta (64.0.3282.29) I still see the same. Do I need to do anything else? – Philipp Jan 04 '18 at 23:29
  • No, it should just work. To be honest, I haven't tried the fix myself, so I added a comment to the Chromium issue. – Felipe Leme Jan 06 '18 at 00:48
  • Actually, I think it's only fixed on M65; I tried it with Chrome Beta (64.0.3282.85) and my service (https://github.com/the-felipeal/android-AutofillFramework) and it still failed. Then I switched to Canary (65.0.3322.0), and it worked. – Felipe Leme Jan 16 '18 at 21:28