summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Daniel <danieljkim@google.com> 2023-10-10 17:15:43 +0000
committer Daniel <danieljkim@google.com> 2023-10-10 21:40:44 +0000
commit9c2bd2eea8807a46ec9d3cf7b561bc11d74b9d81 (patch)
treea2274706f50320744dc709cbc06db96994c31765
parent1ade2aac90619e3188fe77d134bbfc2d75da53ab (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.kt85
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) {