Loading services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java +33 −5 Original line number Diff line number Diff line Loading @@ -25,17 +25,19 @@ import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; /** Contains information on what CredentialProvider has what provisioned Credential. */ public class CredentialDescriptionRegistry { private static final String FLAT_STRING_SPLIT_REGEX = ";"; private static final int MAX_ALLOWED_CREDENTIAL_DESCRIPTIONS = 128; private static final int MAX_ALLOWED_ENTRIES_PER_PROVIDER = 16; @GuardedBy("sLock") Loading Loading @@ -164,14 +166,16 @@ public class CredentialDescriptionRegistry { /** Returns package names and entries of a CredentialProviders that can satisfy a given * {@link CredentialDescription}. */ public Set<FilterResult> getFilteredResultForProvider(String packageName, String flatRequestStrings) { String flatRequestString) { Set<FilterResult> result = new HashSet<>(); if (!mCredentialDescriptions.containsKey(packageName)) { return result; } Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName); Set<String> unflattenedRequestString = flatStringToSet(flatRequestString); for (CredentialDescription containedDescription: currentSet) { if (flatRequestStrings.equals(containedDescription.getFlattenedRequestString())) { if (checkForMatch(flatStringToSet(containedDescription.getFlattenedRequestString()), unflattenedRequestString)) { result.add(new FilterResult(packageName, containedDescription.getFlattenedRequestString(), containedDescription .getCredentialEntries())); Loading @@ -182,12 +186,16 @@ public class CredentialDescriptionRegistry { /** Returns package names of CredentialProviders that can satisfy a given * {@link CredentialDescription}. */ public Set<FilterResult> getMatchingProviders(Set<String> flatRequestString) { public Set<FilterResult> getMatchingProviders(Set<String> flatRequestStrings) { Set<FilterResult> result = new HashSet<>(); Set<Set<String>> unflattenedRequestStrings = flatRequestStrings.stream().map( CredentialDescriptionRegistry::flatStringToSet).collect(Collectors.toSet()); for (String packageName: mCredentialDescriptions.keySet()) { Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName); for (CredentialDescription containedDescription : currentSet) { if (flatRequestString.contains(containedDescription.getFlattenedRequestString())) { if (canProviderSatisfyAny(flatStringToSet(containedDescription .getFlattenedRequestString()), unflattenedRequestStrings)) { result.add(new FilterResult(packageName, containedDescription.getFlattenedRequestString(), containedDescription .getCredentialEntries())); Loading @@ -203,4 +211,24 @@ public class CredentialDescriptionRegistry { } } private static boolean canProviderSatisfyAny(Set<String> registeredUnflattenedStrings, Set<Set<String>> requestedUnflattenedStrings) { for (Set<String> requestedUnflattenedString : requestedUnflattenedStrings) { if (registeredUnflattenedStrings.containsAll(requestedUnflattenedString)) { return true; } } return false; } private static boolean checkForMatch(Set<String> registeredUnflattenedStrings, Set<String> requestedUnflattenedString) { return registeredUnflattenedStrings.containsAll(requestedUnflattenedString); } private static Set<String> flatStringToSet(String flatString) { return new HashSet<>(Arrays .asList(flatString.split(FLAT_STRING_SPLIT_REGEX))); } } services/tests/servicestests/src/com/android/server/credentials/CredentialDescriptionRegistryTest.java +10 −8 Original line number Diff line number Diff line Loading @@ -52,8 +52,10 @@ public class CredentialDescriptionRegistryTest { private static final String CALLING_PACKAGE_NAME_2 = "com.credman.app2"; private static final String MDOC_CREDENTIAL_TYPE = "MDOC"; private static final String PASSKEY_CREDENTIAL_TYPE = "PASSKEY"; private static final String FLATTENED_REQUEST = "FLATTENED_REQ"; private static final String FLATTENED_REQUEST_2 = "FLATTENED_REQ_2"; private static final String FLATTENED_REGISTRY = "FLATTENED_REQ;FLATTENED_REQ123;FLATTENED_REQa"; private static final String FLATTENED_REGISTRY_2 = "FLATTENED_REQ_2"; private static final String FLATTENED_REQUEST = "FLATTENED_REQ;FLATTENED_REQ123"; private CredentialDescriptionRegistry mCredentialDescriptionRegistry; private CredentialEntry mEntry; Loading Loading @@ -104,12 +106,12 @@ public class CredentialDescriptionRegistryTest { @Test public void testEvictProvider_existingProviders_succeeds() { final CredentialDescription credentialDescription = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST, new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY, Collections.emptyList()); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest = new RegisterCredentialDescriptionRequest(credentialDescription); final CredentialDescription credentialDescription2 = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST_2, new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY_2, Collections.emptyList()); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest2 = new RegisterCredentialDescriptionRequest(credentialDescription2); Loading @@ -130,12 +132,12 @@ public class CredentialDescriptionRegistryTest { @Test public void testGetMatchingProviders_existingProviders_succeeds() { final CredentialDescription credentialDescription = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST, new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY, Collections.emptyList()); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest = new RegisterCredentialDescriptionRequest(credentialDescription); final CredentialDescription credentialDescription2 = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST, new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY, Collections.emptyList()); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest2 = new RegisterCredentialDescriptionRequest(credentialDescription2); Loading Loading @@ -171,11 +173,11 @@ public class CredentialDescriptionRegistryTest { public void testExecuteRegisterRequest_existingProviders_filterSucceeds() { final CredentialDescription credentialDescription = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST, FLATTENED_REGISTRY, List.of(mEntry, mEntry2)); final CredentialDescription credentialDescription2 = new CredentialDescription(PASSKEY_CREDENTIAL_TYPE, FLATTENED_REQUEST_2, FLATTENED_REGISTRY_2, List.of(mEntry3)); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest = new RegisterCredentialDescriptionRequest(Set.of(credentialDescription, Loading Loading
services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java +33 −5 Original line number Diff line number Diff line Loading @@ -25,17 +25,19 @@ import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; /** Contains information on what CredentialProvider has what provisioned Credential. */ public class CredentialDescriptionRegistry { private static final String FLAT_STRING_SPLIT_REGEX = ";"; private static final int MAX_ALLOWED_CREDENTIAL_DESCRIPTIONS = 128; private static final int MAX_ALLOWED_ENTRIES_PER_PROVIDER = 16; @GuardedBy("sLock") Loading Loading @@ -164,14 +166,16 @@ public class CredentialDescriptionRegistry { /** Returns package names and entries of a CredentialProviders that can satisfy a given * {@link CredentialDescription}. */ public Set<FilterResult> getFilteredResultForProvider(String packageName, String flatRequestStrings) { String flatRequestString) { Set<FilterResult> result = new HashSet<>(); if (!mCredentialDescriptions.containsKey(packageName)) { return result; } Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName); Set<String> unflattenedRequestString = flatStringToSet(flatRequestString); for (CredentialDescription containedDescription: currentSet) { if (flatRequestStrings.equals(containedDescription.getFlattenedRequestString())) { if (checkForMatch(flatStringToSet(containedDescription.getFlattenedRequestString()), unflattenedRequestString)) { result.add(new FilterResult(packageName, containedDescription.getFlattenedRequestString(), containedDescription .getCredentialEntries())); Loading @@ -182,12 +186,16 @@ public class CredentialDescriptionRegistry { /** Returns package names of CredentialProviders that can satisfy a given * {@link CredentialDescription}. */ public Set<FilterResult> getMatchingProviders(Set<String> flatRequestString) { public Set<FilterResult> getMatchingProviders(Set<String> flatRequestStrings) { Set<FilterResult> result = new HashSet<>(); Set<Set<String>> unflattenedRequestStrings = flatRequestStrings.stream().map( CredentialDescriptionRegistry::flatStringToSet).collect(Collectors.toSet()); for (String packageName: mCredentialDescriptions.keySet()) { Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName); for (CredentialDescription containedDescription : currentSet) { if (flatRequestString.contains(containedDescription.getFlattenedRequestString())) { if (canProviderSatisfyAny(flatStringToSet(containedDescription .getFlattenedRequestString()), unflattenedRequestStrings)) { result.add(new FilterResult(packageName, containedDescription.getFlattenedRequestString(), containedDescription .getCredentialEntries())); Loading @@ -203,4 +211,24 @@ public class CredentialDescriptionRegistry { } } private static boolean canProviderSatisfyAny(Set<String> registeredUnflattenedStrings, Set<Set<String>> requestedUnflattenedStrings) { for (Set<String> requestedUnflattenedString : requestedUnflattenedStrings) { if (registeredUnflattenedStrings.containsAll(requestedUnflattenedString)) { return true; } } return false; } private static boolean checkForMatch(Set<String> registeredUnflattenedStrings, Set<String> requestedUnflattenedString) { return registeredUnflattenedStrings.containsAll(requestedUnflattenedString); } private static Set<String> flatStringToSet(String flatString) { return new HashSet<>(Arrays .asList(flatString.split(FLAT_STRING_SPLIT_REGEX))); } }
services/tests/servicestests/src/com/android/server/credentials/CredentialDescriptionRegistryTest.java +10 −8 Original line number Diff line number Diff line Loading @@ -52,8 +52,10 @@ public class CredentialDescriptionRegistryTest { private static final String CALLING_PACKAGE_NAME_2 = "com.credman.app2"; private static final String MDOC_CREDENTIAL_TYPE = "MDOC"; private static final String PASSKEY_CREDENTIAL_TYPE = "PASSKEY"; private static final String FLATTENED_REQUEST = "FLATTENED_REQ"; private static final String FLATTENED_REQUEST_2 = "FLATTENED_REQ_2"; private static final String FLATTENED_REGISTRY = "FLATTENED_REQ;FLATTENED_REQ123;FLATTENED_REQa"; private static final String FLATTENED_REGISTRY_2 = "FLATTENED_REQ_2"; private static final String FLATTENED_REQUEST = "FLATTENED_REQ;FLATTENED_REQ123"; private CredentialDescriptionRegistry mCredentialDescriptionRegistry; private CredentialEntry mEntry; Loading Loading @@ -104,12 +106,12 @@ public class CredentialDescriptionRegistryTest { @Test public void testEvictProvider_existingProviders_succeeds() { final CredentialDescription credentialDescription = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST, new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY, Collections.emptyList()); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest = new RegisterCredentialDescriptionRequest(credentialDescription); final CredentialDescription credentialDescription2 = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST_2, new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY_2, Collections.emptyList()); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest2 = new RegisterCredentialDescriptionRequest(credentialDescription2); Loading @@ -130,12 +132,12 @@ public class CredentialDescriptionRegistryTest { @Test public void testGetMatchingProviders_existingProviders_succeeds() { final CredentialDescription credentialDescription = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST, new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY, Collections.emptyList()); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest = new RegisterCredentialDescriptionRequest(credentialDescription); final CredentialDescription credentialDescription2 = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST, new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY, Collections.emptyList()); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest2 = new RegisterCredentialDescriptionRequest(credentialDescription2); Loading Loading @@ -171,11 +173,11 @@ public class CredentialDescriptionRegistryTest { public void testExecuteRegisterRequest_existingProviders_filterSucceeds() { final CredentialDescription credentialDescription = new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST, FLATTENED_REGISTRY, List.of(mEntry, mEntry2)); final CredentialDescription credentialDescription2 = new CredentialDescription(PASSKEY_CREDENTIAL_TYPE, FLATTENED_REQUEST_2, FLATTENED_REGISTRY_2, List.of(mEntry3)); final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest = new RegisterCredentialDescriptionRequest(Set.of(credentialDescription, Loading