diff options
| author | 2023-10-10 17:15:43 +0000 | |
|---|---|---|
| committer | 2023-10-10 21:40:44 +0000 | |
| commit | 9c2bd2eea8807a46ec9d3cf7b561bc11d74b9d81 (patch) | |
| tree | a2274706f50320744dc709cbc06db96994c31765 | |
| parent | 1ade2aac90619e3188fe77d134bbfc2d75da53ab (diff) | |
Return inline presentations of credential entries
Create inline presentations from the credential entries and return to
Autofill Session.
Test: Built locally
Bug: 299321128
Change-Id: I7641cc92a4e10a1bcce9c7652a039bdd6324f38b
| -rw-r--r-- | packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt | 85 |
1 files changed, 82 insertions, 3 deletions
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt index 2318bb95dabb..52038f8c1529 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt @@ -27,14 +27,21 @@ import android.os.Bundle import android.os.CancellationSignal import android.os.OutcomeReceiver import android.service.autofill.AutofillService +import android.service.autofill.Dataset +import android.service.autofill.Field import android.service.autofill.FillCallback import android.service.autofill.FillRequest import android.service.autofill.FillResponse +import android.service.autofill.InlinePresentation +import android.service.autofill.Presentations import android.service.autofill.SaveCallback import android.service.autofill.SaveRequest import android.service.credentials.CredentialProviderService import android.util.Log import android.view.autofill.AutofillId +import android.widget.inline.InlinePresentationSpec +import androidx.autofill.inline.v1.InlineSuggestionUi +import com.android.credentialmanager.GetFlowUtils import org.json.JSONObject import java.util.concurrent.Executors @@ -74,8 +81,13 @@ class CredentialAutofillService : AutofillService() { GetCandidateCredentialsException> { override fun onResult(result: GetCandidateCredentialsResponse) { Log.i(TAG, "getCandidateCredentials onResponse") - val fillResponse: FillResponse? = convertToFillResponse(result, request) - callback.onSuccess(fillResponse) + val fillResponse = convertToFillResponse(result, request) + if (fillResponse != null) { + callback.onSuccess(fillResponse) + } else { + Log.e(TAG, "Failed to create a FillResponse from the CredentialResponse.") + callback.onFailure("No dataset was created from the CredentialResponse") + } } override fun onError(error: GetCandidateCredentialsException) { @@ -97,7 +109,74 @@ class CredentialAutofillService : AutofillService() { getCredResponse: GetCandidateCredentialsResponse, filLRequest: FillRequest ): FillResponse? { - TODO("Not yet implemented") + val providerList = GetFlowUtils.toProviderList( + getCredResponse.candidateProviderDataList, + this@CredentialAutofillService) + var totalEntryCount = 0 + providerList.forEach { provider -> + totalEntryCount += provider.credentialEntryList.size + } + val inlineSuggestionsRequest = filLRequest.inlineSuggestionsRequest + val inlineMaxSuggestedCount = inlineSuggestionsRequest?.maxSuggestionCount ?: 0 + val inlinePresentationSpecs = inlineSuggestionsRequest?.inlinePresentationSpecs + val inlinePresentationSpecsCount = inlinePresentationSpecs?.size ?: 0 + var maxItemCount = totalEntryCount + if (inlineMaxSuggestedCount > 0) { + maxItemCount = maxItemCount.coerceAtMost(inlineMaxSuggestedCount) + } + var i = 0 + val fillResponseBuilder = FillResponse.Builder() + var emptyFillResponse = true + providerList.forEach {provider -> + // TODO(b/299321128): Before iterating the list, sort the list so that + // the relevant entries don't get truncated + provider.credentialEntryList.forEach entryLoop@ {entry -> + val autofillId: AutofillId? = entry.fillInIntent?.getParcelableExtra( + CredentialProviderService.EXTRA_AUTOFILL_ID, + AutofillId::class.java) + val pendingIntent = entry.pendingIntent + if (autofillId == null || pendingIntent == null) { + return@entryLoop + } + var inlinePresentation: InlinePresentation? = null + // Create inline presentation + if (inlinePresentationSpecs != null && i < maxItemCount) { + val spec: InlinePresentationSpec + if (i < inlinePresentationSpecsCount) { + spec = inlinePresentationSpecs[i] + } else { + spec = inlinePresentationSpecs[inlinePresentationSpecsCount - 1] + } + val sliceBuilder = InlineSuggestionUi + .newContentBuilder(pendingIntent) + .setTitle(entry.userName) + inlinePresentation = InlinePresentation( + sliceBuilder.build().slice, spec, /* pinned= */ false) + } + i++ + + val dataSetBuilder = Dataset.Builder() + val presentationBuilder = Presentations.Builder() + if (inlinePresentation != null) { + presentationBuilder.setInlinePresentation(inlinePresentation) + } + fillResponseBuilder.addDataset( + dataSetBuilder + .setField( + autofillId, + Field.Builder().setPresentations( + presentationBuilder.build()) + .build()) + .setAuthentication(entry.pendingIntent.intentSender) + .setAuthenticationExtras(entry.fillInIntent.extras) + .build()) + emptyFillResponse = false + } + } + if (emptyFillResponse) { + return null + } + return fillResponseBuilder.build() } override fun onSaveRequest(request: SaveRequest, callback: SaveCallback) { |