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?