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

Commit 6c7150e1 authored by Daniel's avatar Daniel
Browse files

Display provider icon to inline suggestion

Display provider icon to inline suggestion if the credman provider has
one. If not, use the default drawable that credman bottomsheet uses.

With this change, the inline icon uses the same icon, but doesn't share
the icon color with the bottomsheet. The credman bottomsheet uses color
from Composable, which CredmanAutofillService had trouble importing.
Will look into this.

Bug: 299321128
Test: Build, deployed locally
Change-Id: I3d159ae1ced7d88b7f21eacd5a4a3fb72486178e
parent 23a4c182
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -336,7 +336,10 @@ class GetFlowUtils {
            return result
            return result
        }
        }


        private fun parseCredentialEntryFromSlice(slice: Slice): CredentialEntry? {
        /**
         * @hide
         */
        fun parseCredentialEntryFromSlice(slice: Slice): CredentialEntry? {
            try {
            try {
                when (slice.spec?.type) {
                when (slice.spec?.type) {
                    TYPE_PASSWORD_CREDENTIAL -> return PasswordCredentialEntry.fromSlice(slice)!!
                    TYPE_PASSWORD_CREDENTIAL -> return PasswordCredentialEntry.fromSlice(slice)!!
+39 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,8 @@ import android.credentials.CredentialOption
import android.credentials.GetCandidateCredentialsException
import android.credentials.GetCandidateCredentialsException
import android.credentials.GetCandidateCredentialsResponse
import android.credentials.GetCandidateCredentialsResponse
import android.credentials.GetCredentialRequest
import android.credentials.GetCredentialRequest
import android.credentials.ui.GetCredentialProviderData
import android.graphics.drawable.Icon
import android.os.Bundle
import android.os.Bundle
import android.os.CancellationSignal
import android.os.CancellationSignal
import android.os.OutcomeReceiver
import android.os.OutcomeReceiver
@@ -42,6 +44,9 @@ import android.view.autofill.AutofillId
import org.json.JSONException
import org.json.JSONException
import android.widget.inline.InlinePresentationSpec
import android.widget.inline.InlinePresentationSpec
import androidx.autofill.inline.v1.InlineSuggestionUi
import androidx.autofill.inline.v1.InlineSuggestionUi
import androidx.credentials.provider.CustomCredentialEntry
import androidx.credentials.provider.PasswordCredentialEntry
import androidx.credentials.provider.PublicKeyCredentialEntry
import com.android.credentialmanager.GetFlowUtils
import com.android.credentialmanager.GetFlowUtils
import com.android.credentialmanager.getflow.CredentialEntryInfo
import com.android.credentialmanager.getflow.CredentialEntryInfo
import com.android.credentialmanager.getflow.ProviderDisplayInfo
import com.android.credentialmanager.getflow.ProviderDisplayInfo
@@ -110,6 +115,34 @@ class CredentialAutofillService : AutofillService() {
        )
        )
    }
    }


    private fun getEntryToIconMap(
            candidateProviderDataList: MutableList<GetCredentialProviderData>
    ): Map<String, Icon> {
        val entryIconMap: MutableMap<String, Icon> = mutableMapOf()
        candidateProviderDataList.forEach { provider ->
            provider.credentialEntries.forEach { entry ->
                val credentialEntry = GetFlowUtils.parseCredentialEntryFromSlice(entry.slice)
                when (credentialEntry) {
                    is PasswordCredentialEntry -> {
                        entryIconMap[entry.key + entry.subkey] = credentialEntry.icon
                    }
                    is PublicKeyCredentialEntry -> {
                        entryIconMap[entry.key + entry.subkey] = credentialEntry.icon
                    }
                    is CustomCredentialEntry -> {
                        entryIconMap[entry.key + entry.subkey] = credentialEntry.icon
                    }
                }
            }
        }
        return entryIconMap
    }

    private fun getDefaultIcon(): Icon {
        return Icon.createWithResource(
                this, com.android.credentialmanager.R.drawable.ic_other_sign_in_24)
    }

    private fun convertToFillResponse(
    private fun convertToFillResponse(
            getCredResponse: GetCandidateCredentialsResponse,
            getCredResponse: GetCandidateCredentialsResponse,
            filLRequest: FillRequest
            filLRequest: FillRequest
@@ -120,6 +153,8 @@ class CredentialAutofillService : AutofillService() {
        if (providerList.isEmpty()) {
        if (providerList.isEmpty()) {
            return null
            return null
        }
        }
        val entryIconMap: Map<String, Icon> =
                getEntryToIconMap(getCredResponse.candidateProviderDataList)
        var totalEntryCount = 0
        var totalEntryCount = 0
        providerList.forEach { provider ->
        providerList.forEach { provider ->
            totalEntryCount += provider.credentialEntryList.size
            totalEntryCount += provider.credentialEntryList.size
@@ -174,6 +209,10 @@ class CredentialAutofillService : AutofillService() {
                    val sliceBuilder = InlineSuggestionUi
                    val sliceBuilder = InlineSuggestionUi
                            .newContentBuilder(pendingIntent)
                            .newContentBuilder(pendingIntent)
                            .setTitle(credentialEntry.userName)
                            .setTitle(credentialEntry.userName)
                    val icon: Icon =
                            entryIconMap[credentialEntry.entryKey + credentialEntry.entrySubkey]
                                    ?: getDefaultIcon()
                    sliceBuilder.setStartIcon(icon)
                    inlinePresentation = InlinePresentation(
                    inlinePresentation = InlinePresentation(
                            sliceBuilder.build().slice, spec, /* pinned= */ false)
                            sliceBuilder.build().slice, spec, /* pinned= */ false)
                }
                }