Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44da7e6e authored by Daniel Kim's avatar Daniel Kim Committed by Android (Google) Code Review
Browse files

Merge "Sort inline suggestions" into main

parents 2bd65089 f86cf87a
Loading
Loading
Loading
Loading
+44 −11
Original line number Diff line number Diff line
@@ -43,6 +43,9 @@ import org.json.JSONException
import android.widget.inline.InlinePresentationSpec
import androidx.autofill.inline.v1.InlineSuggestionUi
import com.android.credentialmanager.GetFlowUtils
import com.android.credentialmanager.getflow.CredentialEntryInfo
import com.android.credentialmanager.getflow.ProviderDisplayInfo
import com.android.credentialmanager.getflow.toProviderDisplayInfo
import org.json.JSONObject
import java.util.concurrent.Executors

@@ -114,10 +117,14 @@ class CredentialAutofillService : AutofillService() {
        val providerList = GetFlowUtils.toProviderList(
                getCredResponse.candidateProviderDataList,
                this@CredentialAutofillService)
        if (providerList.isEmpty()) {
            return null
        }
        var totalEntryCount = 0
        providerList.forEach { provider ->
            totalEntryCount += provider.credentialEntryList.size
        }
        val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerList)
        val inlineSuggestionsRequest = filLRequest.inlineSuggestionsRequest
        val inlineMaxSuggestedCount = inlineSuggestionsRequest?.maxSuggestionCount ?: 0
        val inlinePresentationSpecs = inlineSuggestionsRequest?.inlinePresentationSpecs
@@ -129,15 +136,30 @@ class CredentialAutofillService : AutofillService() {
        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(

        providerDisplayInfo.sortedUserNameToCredentialEntryList.forEach usernameLoop@ {
            val primaryEntry = it.sortedCredentialEntryList.first()
            // In regular CredMan bottomsheet, only one primary entry per username is displayed.
            // But since the credential requests from different fields are allocated into a single
            // request for autofill, there will be duplicate primary entries, especially for
            // username/pw autofill fields. These primary entries will be the same entries except
            // their autofillIds will point to different autofill fields. Process all primary
            // fields.
            // TODO(b/307435163): Merge credential options
            it.sortedCredentialEntryList.forEach entryLoop@ { credentialEntry ->
                if (!isSameCredentialEntry(primaryEntry, credentialEntry)) {
                    // Encountering different credential entry means all the duplicate primary
                    // entries have been processed.
                    return@usernameLoop
                }
                val autofillId: AutofillId? = credentialEntry
                        .fillInIntent
                        ?.getParcelableExtra(
                                CredentialProviderService.EXTRA_AUTOFILL_ID,
                                AutofillId::class.java)
                val pendingIntent = entry.pendingIntent
                val pendingIntent = credentialEntry.pendingIntent
                if (autofillId == null || pendingIntent == null) {
                    Log.e(TAG, "AutofillId or pendingIntent was missing from the entry.")
                    return@entryLoop
                }
                var inlinePresentation: InlinePresentation? = null
@@ -151,7 +173,7 @@ class CredentialAutofillService : AutofillService() {
                    }
                    val sliceBuilder = InlineSuggestionUi
                            .newContentBuilder(pendingIntent)
                            .setTitle(entry.userName)
                            .setTitle(credentialEntry.userName)
                    inlinePresentation = InlinePresentation(
                            sliceBuilder.build().slice, spec, /* pinned= */ false)
                }
@@ -169,8 +191,8 @@ class CredentialAutofillService : AutofillService() {
                                        Field.Builder().setPresentations(
                                                presentationBuilder.build())
                                                .build())
                                .setAuthentication(entry.pendingIntent.intentSender)
                                .setAuthenticationExtras(entry.fillInIntent.extras)
                                .setAuthentication(pendingIntent.intentSender)
                                .setAuthenticationExtras(credentialEntry.fillInIntent.extras)
                                .build())
                emptyFillResponse = false
            }
@@ -292,4 +314,15 @@ class CredentialAutofillService : AutofillService() {
        }
        return result
    }

    private fun isSameCredentialEntry(
            info1: CredentialEntryInfo,
            info2: CredentialEntryInfo
    ): Boolean {
        return info1.providerId == info2.providerId &&
                info1.lastUsedTimeMillis == info2.lastUsedTimeMillis &&
                info1.credentialType == info2.credentialType &&
                info1.displayName == info2.displayName &&
                info1.userName == info2.userName
    }
}
 No newline at end of file
+8 −3
Original line number Diff line number Diff line
@@ -203,9 +203,14 @@ enum class GetScreenState {
    UNLOCKED_AUTH_ENTRIES_ONLY,
}

// IMPORTANT: new invocation should be mindful that this method will throw if more than 1 remote
// entry exists
private fun toProviderDisplayInfo(

/**
 * IMPORTANT: new invocation should be mindful that this method will throw if more than 1 remote
 * entry exists
 *
 * @hide
 */
fun toProviderDisplayInfo(
    providerInfoList: List<ProviderInfo>
): ProviderDisplayInfo {
    val userNameToCredentialEntryMap = mutableMapOf<String, MutableList<CredentialEntryInfo>>()