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

Commit 2a401d42 authored by Omer Ozer's avatar Omer Ozer
Browse files

Make ProviderRegistryGetSesh per option.

Make sure that ProviderRegistryGetSessions are
created for each CredentialOption sent with
the GetCredentialRequest.

Bug: 269800380
Test: manual
Change-Id: I9701ac6b971789751d2d63804c19258b22f4f35b
parent e1295fff
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -49,11 +49,14 @@ public final class CredentialDescriptionRegistry {
    /** Represents the results of a given query into the registry. */
    public static final class FilterResult {
        final String mPackageName;
        final String mFlattenedRequest;
        final List<CredentialEntry> mCredentialEntries;

        private FilterResult(String packageName,
                String flattenedRequest,
                List<CredentialEntry> credentialEntries) {
            mPackageName = packageName;
            mFlattenedRequest = flattenedRequest;
            mCredentialEntries = credentialEntries;
        }
    }
@@ -133,12 +136,13 @@ public final class CredentialDescriptionRegistry {
    /** Returns package names and entries of a CredentialProviders that can satisfy a given
     * {@link CredentialDescription}. */
    public Set<FilterResult> getFilteredResultForProvider(String packageName,
            List<String> flatRequestStrings) {
            String flatRequestStrings) {
        Set<FilterResult> result = new HashSet<>();
        Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName);
        for (CredentialDescription containedDescription: currentSet) {
            if (flatRequestStrings.contains(containedDescription.getFlattenedRequestString())) {
                result.add(new FilterResult(packageName, containedDescription
            if (flatRequestStrings.equals(containedDescription.getFlattenedRequestString())) {
                result.add(new FilterResult(packageName,
                        containedDescription.getFlattenedRequestString(), containedDescription
                        .getCredentialEntries()));
            }
        }
@@ -147,13 +151,15 @@ public final class CredentialDescriptionRegistry {

    /** Returns package names of CredentialProviders that can satisfy a given
     * {@link CredentialDescription}. */
    public Set<String> getMatchingProviders(Set<String> flatRequestString) {
        Set<String> result = new HashSet<>();
    public Set<FilterResult> getMatchingProviders(Set<String> flatRequestString) {
        Set<FilterResult> result = new HashSet<>();
        for (String packageName: mCredentialDescriptions.keySet()) {
            Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName);
            for (CredentialDescription containedDescription : currentSet) {
                if (flatRequestString.contains(containedDescription.getFlattenedRequestString())) {
                    result.add(packageName);
                    result.add(new FilterResult(packageName,
                            containedDescription.getFlattenedRequestString(), containedDescription
                            .getCredentialEntries()));
                }
            }
        }
+26 −17
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import android.service.credentials.CallingAppInfo;
import android.service.credentials.CredentialProviderInfo;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;

@@ -66,6 +67,7 @@ import com.android.server.infra.AbstractMasterSystemService;
import com.android.server.infra.SecureSettingsServiceNameResolver;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -274,24 +276,25 @@ public final class CredentialManagerService
    // to be guarded by 'service.mLock', which is the same as mLock.
    private List<ProviderSession> initiateProviderSessionsWithActiveContainers(
            GetRequestSession session,
            List<String> requestOptions,
            Set<String> activeCredentialContainers) {
            Set<Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult>>
                    activeCredentialContainers) {
        List<ProviderSession> providerSessions = new ArrayList<>();
        // Invoke all services of a user to initiate a provider session
        for (String packageName : activeCredentialContainers) {
        for (Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult> result :
                activeCredentialContainers) {
            providerSessions.add(
                    ProviderRegistryGetSession.createNewSession(
                            mContext,
                            UserHandle.getCallingUserId(),
                            session,
                            packageName,
                            requestOptions));
                            result.second.mPackageName,
                            result.first));
        }
        return providerSessions;
    }

    @NonNull
    private Set<String> getFilteredResultFromRegistry(List<CredentialOption> options) {
    private Set<Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult>>
            getFilteredResultFromRegistry(List<CredentialOption> options) {
        // Session for active/provisioned credential descriptions;
        CredentialDescriptionRegistry registry =
                CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId());
@@ -307,7 +310,22 @@ public final class CredentialManagerService
                        .collect(Collectors.toSet());

        // All requested credential descriptions based on the given request.
        return registry.getMatchingProviders(requestedCredentialDescriptions);
        Set<CredentialDescriptionRegistry.FilterResult> filterResults =
                registry.getMatchingProviders(requestedCredentialDescriptions);

        Set<Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult>> result =
                new HashSet<>();

        for (CredentialDescriptionRegistry.FilterResult filterResult: filterResults) {
            for (CredentialOption credentialOption: options) {
                if (filterResult.mFlattenedRequest.equals(credentialOption
                        .getCredentialRetrievalData()
                        .getString(CredentialOption.FLATTENED_REQUEST))) {
                    result.add(new Pair<>(credentialOption, filterResult));
                }
            }
        }
        return result;
    }

    @SuppressWarnings("GuardedBy") // ErrorProne requires initiateProviderSessionForRequestLocked
@@ -452,15 +470,6 @@ public final class CredentialManagerService
                List<ProviderSession> sessionsWithoutRemoteService =
                        initiateProviderSessionsWithActiveContainers(
                        session,
                        optionsThatRequireActiveCredentials.stream()
                            .map(
                                getCredentialOption ->
                                    getCredentialOption
                                        .getCredentialRetrievalData()
                                        .getString(
                                            CredentialOption
                                                .FLATTENED_REQUEST))
                            .collect(Collectors.toList()),
                        getFilteredResultFromRegistry(optionsThatRequireActiveCredentials));

                List<ProviderSession> sessionsWithRemoteService =
+18 −32
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.content.Context;
import android.content.Intent;
import android.credentials.CredentialOption;
import android.credentials.GetCredentialException;
import android.credentials.GetCredentialRequest;
import android.credentials.GetCredentialResponse;
import android.credentials.ui.Entry;
import android.credentials.ui.GetCredentialProviderData;
@@ -49,7 +48,7 @@ import java.util.stream.Stream;
 *
 * @hide
 */
public class ProviderRegistryGetSession extends ProviderSession<GetCredentialRequest,
public class ProviderRegistryGetSession extends ProviderSession<CredentialOption,
        Set<CredentialDescriptionRegistry.FilterResult>> {

    private static final String TAG = "ProviderRegistryGetSession";
@@ -62,15 +61,14 @@ public class ProviderRegistryGetSession extends ProviderSession<GetCredentialReq
            @UserIdInt int userId,
            @NonNull GetRequestSession getRequestSession,
            @NonNull String credentialProviderPackageName,
            @NonNull List<String> requestOptions) {
            @NonNull CredentialOption requestOption) {
        return new ProviderRegistryGetSession(
                context,
                userId,
                getRequestSession,
                getRequestSession.mClientRequest,
                getRequestSession.mClientAppInfo,
                credentialProviderPackageName,
                requestOptions);
                requestOption);
    }

    @NonNull
@@ -82,24 +80,22 @@ public class ProviderRegistryGetSession extends ProviderSession<GetCredentialReq
    @NonNull
    private final String mCredentialProviderPackageName;
    @NonNull
    private final GetRequestSession mGetRequestSession;
    @NonNull
    private final List<String> mRequestOptions;
    private final String mFlattenedRequestOptionString;
    private List<CredentialEntry> mCredentialEntries;

    protected ProviderRegistryGetSession(@NonNull Context context,
            @NonNull int userId,
            @NonNull GetRequestSession session,
            @NonNull GetCredentialRequest request,
            @NonNull CallingAppInfo callingAppInfo,
            @NonNull String servicePackageName,
            @NonNull List<String> requestOptions) {
        super(context, null, request, session, userId, null);
        mGetRequestSession = session;
            @NonNull CredentialOption requestOption) {
        super(context, null, requestOption, session, userId, null);
        mCredentialDescriptionRegistry = CredentialDescriptionRegistry.forUser(userId);
        mCallingAppInfo = callingAppInfo;
        mCredentialProviderPackageName = servicePackageName;
        mRequestOptions = requestOptions;
        mFlattenedRequestOptionString = requestOption
                .getCredentialRetrievalData()
                .getString(CredentialOption.FLATTENED_REQUEST);
    }

    private List<Entry> prepareUiCredentialEntries(
@@ -114,23 +110,18 @@ public class ProviderRegistryGetSession extends ProviderSession<GetCredentialReq
            Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId);
            credentialUiEntries.add(new Entry(CREDENTIAL_ENTRY_KEY, entryId,
                    credentialEntry.getSlice(),
                    setUpFillInIntent(credentialEntry.getType())));
                    setUpFillInIntent()));
        }
        return credentialUiEntries;
    }

    private Intent setUpFillInIntent(String type) {
    private Intent setUpFillInIntent() {
        Intent intent = new Intent();
        for (CredentialOption option : mProviderRequest.getCredentialOptions()) {
            if (option.getType().equals(type)) {
        intent.putExtra(
                CredentialProviderService
                        .EXTRA_GET_CREDENTIAL_REQUEST,
                new android.service.credentials.GetCredentialRequest(
                                mCallingAppInfo, option));
                return intent;
            }
        }
                        mCallingAppInfo, mProviderRequest));
        return intent;
    }

@@ -176,11 +167,6 @@ public class ProviderRegistryGetSession extends ProviderSession<GetCredentialReq

    private void onCredentialEntrySelected(CredentialEntry credentialEntry,
            ProviderPendingIntentResponse providerPendingIntentResponse) {
        if (!mCredentialEntries.contains(credentialEntry)) {
            invokeCallbackWithError("",
                    "");
        }

        if (providerPendingIntentResponse != null) {
            // Check if pending intent has an error
            GetCredentialException exception = maybeGetPendingIntentException(
@@ -228,13 +214,13 @@ public class ProviderRegistryGetSession extends ProviderSession<GetCredentialReq
    protected void invokeSession() {
        mProviderResponse = mCredentialDescriptionRegistry
                .getFilteredResultForProvider(mCredentialProviderPackageName,
                        mRequestOptions);
                        mFlattenedRequestOptionString);
        mCredentialEntries = mProviderResponse.stream().flatMap(
                        (Function<CredentialDescriptionRegistry.FilterResult,
                                Stream<CredentialEntry>>) filterResult
                        -> filterResult.mCredentialEntries.stream())
                .collect(Collectors.toList());
        setStatus(Status.CREDENTIALS_RECEIVED);
        updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
        // TODO(use metric later)
    }