in AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/MultiStepsService.java [68:136]
public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal,
FillCallback callback) {
int saveType = SaveInfo.SAVE_DATA_TYPE_GENERIC;
Bundle clientState = request.getClientState();
if (clientState != null) {
saveType = clientState.getInt(SAVE_TYPE_KEY, saveType);
}
Log.d(TAG, "onFillRequest(): saveType=" + saveType);
// Find autofillable fields
AssistStructure structure = getLatestAssistStructure(request);
ArrayMap<String, AutofillId> fields = getAutofillableFields(structure);
Log.d(TAG, "autofillable fields:" + fields);
if (fields.isEmpty()) {
toast("No autofill hints found");
callback.onSuccess(null);
return;
}
Collection<AutofillId> ids = fields.values();
AutofillId[] requiredIds = new AutofillId[ids.size()];
ids.toArray(requiredIds);
for (int i = 0; i < fields.size(); i++) {
String hint = fields.keyAt(i);
switch (hint) {
case View.AUTOFILL_HINT_USERNAME:
saveType |= SaveInfo.SAVE_DATA_TYPE_USERNAME;
break;
case View.AUTOFILL_HINT_EMAIL_ADDRESS:
saveType |= SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS;
break;
case View.AUTOFILL_HINT_PASSWORD:
saveType |= SaveInfo.SAVE_DATA_TYPE_PASSWORD;
break;
case View.AUTOFILL_HINT_CREDIT_CARD_NUMBER:
case View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE:
case View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY:
case View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH:
case View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR:
case View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE:
saveType |= SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD;
break;
case View.AUTOFILL_HINT_POSTAL_ADDRESS:
case View.AUTOFILL_HINT_POSTAL_CODE:
saveType |= SaveInfo.SAVE_DATA_TYPE_ADDRESS;
break;
default:
Log.d(TAG, "Ignoring hint '" + hint + "'");
}
}
Log.d(TAG, "new saveType=" + saveType);
if (clientState == null) {
// Initial request
clientState = new Bundle();
}
// NOTE: to simplify, we're saving just the saveType, but a real service implementation
// would have to save the previous values as well, so they can be used later (for example,
// it would have to save the username in the first request so it's used to save the
// username + password combo in the second request.
clientState.putInt(SAVE_TYPE_KEY, saveType);
// Create response...
callback.onSuccess(new FillResponse.Builder()
.setClientState(clientState)
.setSaveInfo(new SaveInfo.Builder(saveType, requiredIds).build())
.build());
}