diff options
author | 2023-03-06 18:58:28 +0000 | |
---|---|---|
committer | 2023-03-07 17:14:03 +0000 | |
commit | 8d08ee778ab03d2ed6adea98f3e1661b19a5c99c (patch) | |
tree | 120c90c8f2033a29929af52308d83b6eb957a75e | |
parent | 9397e3117efb413ef274b56d72d1f8dcb4b0cc3b (diff) |
Move CredentialProviderInfo for test/settings (framework)
This is a precusor CL to adding a subtitle for settings
to use so we need to move CPI where it can be used
by settings, atest and CTS.
Test: ondevice & atest & cts
Bug: 253157366
Change-Id: I2ffb1f89caf3f2c5bbf7d4dd693ad9a1bbc93fbb
(cherry picked from commit on googleplex-android-review.googlesource.com host: 496d3a3aae0f83f2456f92f09e0800276f1a0dc0)
Merged-In: I2ffb1f89caf3f2c5bbf7d4dd693ad9a1bbc93fbb
18 files changed, 535 insertions, 383 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 85163eda04b0..17c3d3399235 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1072,6 +1072,40 @@ package android.content.rollback { } +package android.credentials { + + public final class CredentialManager { + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.QUERY_ALL_PACKAGES, "android.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS"}) public java.util.List<android.credentials.CredentialProviderInfo> getCredentialProviderServicesForTesting(int); + method public static boolean isServiceEnabled(@NonNull android.content.Context); + field public static final int PROVIDER_FILTER_ALL_PROVIDERS = 0; // 0x0 + field public static final int PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY = 1; // 0x1 + field public static final int PROVIDER_FILTER_USER_PROVIDERS_ONLY = 2; // 0x2 + } + + public final class CredentialProviderInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public java.util.List<java.lang.String> getCapabilities(); + method @NonNull public android.content.ComponentName getComponentName(); + method @Nullable public CharSequence getLabel(@NonNull android.content.Context); + method @Nullable public android.graphics.drawable.Drawable getServiceIcon(@NonNull android.content.Context); + method @NonNull public android.content.pm.ServiceInfo getServiceInfo(); + method @NonNull public boolean hasCapability(@NonNull String); + method public boolean isEnabled(); + method public boolean isSystemProvider(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.credentials.CredentialProviderInfo> CREATOR; + } + + public static final class CredentialProviderInfo.Builder { + ctor public CredentialProviderInfo.Builder(@NonNull android.content.pm.ServiceInfo); + method @NonNull public android.credentials.CredentialProviderInfo.Builder addCapabilities(@NonNull java.util.List<java.lang.String>); + method @NonNull public android.credentials.CredentialProviderInfo build(); + method @NonNull public android.credentials.CredentialProviderInfo.Builder setEnabled(boolean); + method @NonNull public android.credentials.CredentialProviderInfo.Builder setSystemProvider(boolean); + } + +} + package android.credentials.ui { public final class AuthenticationEntry implements android.os.Parcelable { diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java index f0230e7f4593..0806f1db2bb7 100644 --- a/core/java/android/credentials/CredentialManager.java +++ b/core/java/android/credentials/CredentialManager.java @@ -26,12 +26,12 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemService; +import android.annotation.TestApi; import android.app.Activity; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.IntentSender; -import android.content.pm.ServiceInfo; import android.os.CancellationSignal; import android.os.ICancellationSignal; import android.os.OutcomeReceiver; @@ -75,21 +75,21 @@ public final class CredentialManager { * * @hide */ - public static final int PROVIDER_FILTER_ALL_PROVIDERS = 0; + @TestApi public static final int PROVIDER_FILTER_ALL_PROVIDERS = 0; /** * Returns system credential providers only. * * @hide */ - public static final int PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY = 1; + @TestApi public static final int PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY = 1; /** * Returns user credential providers only. * * @hide */ - public static final int PROVIDER_FILTER_USER_PROVIDERS_ONLY = 2; + @TestApi public static final int PROVIDER_FILTER_USER_PROVIDERS_ONLY = 2; private final Context mContext; private final ICredentialManager mService; @@ -263,44 +263,6 @@ public final class CredentialManager { } /** - * Gets a list of all user configurable credential providers registered on the system. This API - * is intended for browsers and settings apps. - * - * @param cancellationSignal an optional signal that allows for cancelling this call - * @param executor the callback will take place on this {@link Executor} - * @param callback the callback invoked when the request succeeds or fails - * @hide - */ - @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) - public void listEnabledProviders( - @Nullable CancellationSignal cancellationSignal, - @CallbackExecutor @NonNull Executor executor, - @NonNull - OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException> - callback) { - requireNonNull(executor, "executor must not be null"); - requireNonNull(callback, "callback must not be null"); - - if (cancellationSignal != null && cancellationSignal.isCanceled()) { - Log.w(TAG, "listEnabledProviders already canceled"); - return; - } - - ICancellationSignal cancelRemote = null; - try { - cancelRemote = - mService.listEnabledProviders( - new ListEnabledProvidersTransport(executor, callback)); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - - if (cancellationSignal != null && cancelRemote != null) { - cancellationSignal.setRemote(cancelRemote); - } - } - - /** * Sets a list of all user configurable credential providers registered on the system. This API * is intended for settings apps. * @@ -348,36 +310,43 @@ public final class CredentialManager { } /** - * Returns the list of ServiceInfo for all discovered credential providers on this device. + * Returns the list of CredentialProviderInfo for all discovered credential providers on this + * device but will include test system providers as well. * * @hide */ @NonNull - @RequiresPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS) - public List<ServiceInfo> getCredentialProviderServicesForTesting( - @ProviderFilter int providerFilter) { + @TestApi + @RequiresPermission( + anyOf = { + android.Manifest.permission.QUERY_ALL_PACKAGES, + android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS + }) + public List<CredentialProviderInfo> getCredentialProviderServicesForTesting( + @ProviderFilter int providerFilter) { try { - return mService.getCredentialProviderServices( - mContext.getUserId(), - /* disableSystemAppVerificationForTests= */ true, - providerFilter); + return mService.getCredentialProviderServicesForTesting(providerFilter); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Returns the list of ServiceInfo for all discovered credential providers on this device. + * Returns the list of CredentialProviderInfo for all discovered credential providers on this + * device. * * @hide */ @NonNull - @RequiresPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS) - public List<ServiceInfo> getCredentialProviderServices( + @RequiresPermission( + anyOf = { + android.Manifest.permission.QUERY_ALL_PACKAGES, + android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS + }) + public List<CredentialProviderInfo> getCredentialProviderServices( int userId, @ProviderFilter int providerFilter) { try { - return mService.getCredentialProviderServices( - userId, /* disableSystemAppVerificationForTests= */ false, providerFilter); + return mService.getCredentialProviderServices(userId, providerFilter); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -388,7 +357,9 @@ public final class CredentialManager { * * @hide */ - public static boolean isServiceEnabled(Context context) { + @TestApi + public static boolean isServiceEnabled(@NonNull Context context) { + requireNonNull(context, "context must not be null"); if (context == null) { return false; } @@ -578,33 +549,6 @@ public final class CredentialManager { } } - private static class ListEnabledProvidersTransport extends IListEnabledProvidersCallback.Stub { - // TODO: listen for cancellation to release callback. - - private final Executor mExecutor; - private final OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException> - mCallback; - - private ListEnabledProvidersTransport( - Executor executor, - OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException> - callback) { - mExecutor = executor; - mCallback = callback; - } - - @Override - public void onResponse(ListEnabledProvidersResponse response) { - mExecutor.execute(() -> mCallback.onResult(response)); - } - - @Override - public void onError(String errorType, String message) { - mExecutor.execute( - () -> mCallback.onError(new ListEnabledProvidersException(errorType, message))); - } - } - private static class SetEnabledProvidersTransport extends ISetEnabledProvidersCallback.Stub { // TODO: listen for cancellation to release callback. diff --git a/core/java/android/credentials/IListEnabledProvidersCallback.aidl b/core/java/android/credentials/CredentialProviderInfo.aidl index 3a8e25ed954a..30b7742d17f8 100644 --- a/core/java/android/credentials/IListEnabledProvidersCallback.aidl +++ b/core/java/android/credentials/CredentialProviderInfo.aidl @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,4 @@ package android.credentials; -import android.credentials.ListEnabledProvidersResponse; - -/** - * Listener for an listEnabledProviders request. - * - * @hide - */ -interface IListEnabledProvidersCallback { - oneway void onResponse(in ListEnabledProvidersResponse response); - oneway void onError(String errorType, String message); -}
\ No newline at end of file +parcelable CredentialProviderInfo;
\ No newline at end of file diff --git a/core/java/android/credentials/CredentialProviderInfo.java b/core/java/android/credentials/CredentialProviderInfo.java new file mode 100644 index 000000000000..7276770d281e --- /dev/null +++ b/core/java/android/credentials/CredentialProviderInfo.java @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.credentials; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.TestApi; +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.ServiceInfo; +import android.graphics.drawable.Drawable; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * {@link ServiceInfo} and meta-data about a credential provider. + * + * @hide + */ +@TestApi +public final class CredentialProviderInfo implements Parcelable { + @NonNull private final ServiceInfo mServiceInfo; + @NonNull private final List<String> mCapabilities = new ArrayList<>(); + @Nullable private final CharSequence mOverrideLabel; + private final boolean mIsSystemProvider; + private final boolean mIsEnabled; + + /** + * Constructs an information instance of the credential provider. + * + * @param builder the builder object. + */ + private CredentialProviderInfo(@NonNull Builder builder) { + mServiceInfo = builder.mServiceInfo; + mCapabilities.addAll(builder.mCapabilities); + mIsSystemProvider = builder.mIsSystemProvider; + mIsEnabled = builder.mIsEnabled; + mOverrideLabel = builder.mOverrideLabel; + } + + /** Returns true if the service supports the given {@code credentialType}, false otherwise. */ + @NonNull + public boolean hasCapability(@NonNull String credentialType) { + return mCapabilities.contains(credentialType); + } + + /** Returns the service info. */ + @NonNull + public ServiceInfo getServiceInfo() { + return mServiceInfo; + } + + /** Returns whether it is a system provider. */ + public boolean isSystemProvider() { + return mIsSystemProvider; + } + + /** Returns the service icon. */ + @Nullable + public Drawable getServiceIcon(@NonNull Context context) { + return mServiceInfo.loadIcon(context.getPackageManager()); + } + + /** Returns the service label. */ + @Nullable + public CharSequence getLabel(@NonNull Context context) { + if (mOverrideLabel != null) { + return mOverrideLabel; + } + return mServiceInfo.loadSafeLabel(context.getPackageManager()); + } + + /** Returns a list of capabilities this provider service can support. */ + @NonNull + public List<String> getCapabilities() { + return Collections.unmodifiableList(mCapabilities); + } + + /** Returns whether the provider is enabled by the user. */ + public boolean isEnabled() { + return mIsEnabled; + } + + /** Returns the component name for the service. */ + @NonNull + public ComponentName getComponentName() { + return mServiceInfo.getComponentName(); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeTypedObject(mServiceInfo, flags); + dest.writeBoolean(mIsSystemProvider); + dest.writeStringList(mCapabilities); + dest.writeBoolean(mIsEnabled); + TextUtils.writeToParcel(mOverrideLabel, dest, flags); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public String toString() { + return "CredentialProviderInfo {" + + "serviceInfo=" + + mServiceInfo + + ", " + + "isSystemProvider=" + + mIsSystemProvider + + ", " + + "isEnabled=" + + mIsEnabled + + ", " + + "overrideLabel=" + + mOverrideLabel + + ", " + + "capabilities=" + + String.join(",", mCapabilities) + + "}"; + } + + private CredentialProviderInfo(@NonNull Parcel in) { + mServiceInfo = in.readTypedObject(ServiceInfo.CREATOR); + mIsSystemProvider = in.readBoolean(); + in.readStringList(mCapabilities); + mIsEnabled = in.readBoolean(); + mOverrideLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); + } + + public static final @NonNull Parcelable.Creator<CredentialProviderInfo> CREATOR = + new Parcelable.Creator<CredentialProviderInfo>() { + @Override + public CredentialProviderInfo[] newArray(int size) { + return new CredentialProviderInfo[size]; + } + + @Override + public CredentialProviderInfo createFromParcel(@NonNull Parcel in) { + return new CredentialProviderInfo(in); + } + }; + + /** A builder for {@link CredentialProviderInfo} objects. */ + public static final class Builder { + + @NonNull private ServiceInfo mServiceInfo; + @NonNull private List<String> mCapabilities = new ArrayList<>(); + private boolean mIsSystemProvider = false; + private boolean mIsEnabled = false; + @Nullable private CharSequence mOverrideLabel = null; + + /** + * Creates a new builder. + * + * @param serviceInfo the service info of the credential provider service. + */ + public Builder(@NonNull ServiceInfo serviceInfo) { + mServiceInfo = serviceInfo; + } + + /** Sets whether it is a system provider. */ + public @NonNull Builder setSystemProvider(boolean isSystemProvider) { + mIsSystemProvider = isSystemProvider; + return this; + } + + /** + * Sets the label to be used instead of getting from the system (for unit tests). + * + * @hide + */ + public @NonNull Builder setOverrideLabel(@NonNull CharSequence overrideLabel) { + mOverrideLabel = overrideLabel; + return this; + } + + /** Sets a list of capabilities this provider service can support. */ + public @NonNull Builder addCapabilities(@NonNull List<String> capabilities) { + mCapabilities.addAll(capabilities); + return this; + } + + /** Sets whether it is enabled by the user. */ + public @NonNull Builder setEnabled(boolean isEnabled) { + mIsEnabled = isEnabled; + return this; + } + + /** Builds a new {@link CredentialProviderInfo} instance. */ + public @NonNull CredentialProviderInfo build() { + return new CredentialProviderInfo(this); + } + } +} diff --git a/core/java/android/credentials/ICredentialManager.aidl b/core/java/android/credentials/ICredentialManager.aidl index 625fc8ab5dad..8c2cb5aa0d77 100644 --- a/core/java/android/credentials/ICredentialManager.aidl +++ b/core/java/android/credentials/ICredentialManager.aidl @@ -18,7 +18,7 @@ package android.credentials; import java.util.List; -import android.content.pm.ServiceInfo; +import android.credentials.CredentialProviderInfo; import android.credentials.ClearCredentialStateRequest; import android.credentials.CreateCredentialRequest; import android.credentials.GetCredentialRequest; @@ -27,7 +27,6 @@ import android.credentials.UnregisterCredentialDescriptionRequest; import android.credentials.IClearCredentialStateCallback; import android.credentials.ICreateCredentialCallback; import android.credentials.IGetCredentialCallback; -import android.credentials.IListEnabledProvidersCallback; import android.credentials.ISetEnabledProvidersCallback; import android.content.ComponentName; import android.os.ICancellationSignal; @@ -45,8 +44,6 @@ interface ICredentialManager { @nullable ICancellationSignal clearCredentialState(in ClearCredentialStateRequest request, in IClearCredentialStateCallback callback, String callingPackage); - @nullable ICancellationSignal listEnabledProviders(in IListEnabledProvidersCallback callback); - void setEnabledProviders(in List<String> providers, in int userId, in ISetEnabledProvidersCallback callback); void registerCredentialDescription(in RegisterCredentialDescriptionRequest request, String callingPackage); @@ -55,6 +52,8 @@ interface ICredentialManager { boolean isEnabledCredentialProviderService(in ComponentName componentName, String callingPackage); - List<ServiceInfo> getCredentialProviderServices(in int userId, in boolean disableSystemAppVerificationForTests, in int providerFilter); + List<CredentialProviderInfo> getCredentialProviderServices(in int userId, in int providerFilter); + + List<CredentialProviderInfo> getCredentialProviderServicesForTesting(in int providerFilter); } diff --git a/core/java/android/service/credentials/CredentialProviderInfo.java b/core/java/android/service/credentials/CredentialProviderInfoFactory.java index b5464db98d0e..fd9360f00d4a 100644 --- a/core/java/android/service/credentials/CredentialProviderInfo.java +++ b/core/java/android/service/credentials/CredentialProviderInfoFactory.java @@ -34,40 +34,27 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.credentials.CredentialManager; -import android.graphics.drawable.Drawable; +import android.credentials.CredentialProviderInfo; import android.os.Bundle; import android.os.RemoteException; -import android.text.TextUtils; +import android.os.UserHandle; import android.util.Log; import android.util.Slog; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** - * {@link ServiceInfo} and meta-data about a credential provider. + * {@link CredentialProviderInfo} generator. * * @hide */ -public final class CredentialProviderInfo { - private static final String TAG = "CredentialProviderInfo"; - - @NonNull - private final ServiceInfo mServiceInfo; - @NonNull - private final List<String> mCapabilities; - - @NonNull - private final Context mContext; - @Nullable - private final Drawable mIcon; - @Nullable - private final CharSequence mLabel; - private final boolean mIsSystemProvider; +public final class CredentialProviderInfoFactory { + private static final String TAG = "CredentialProviderInfoFactory"; /** * Constructs an information instance of the credential provider. @@ -79,14 +66,18 @@ public final class CredentialProviderInfo { * @throws PackageManager.NameNotFoundException If provider service is not found * @throws SecurityException If provider does not require the relevant permission */ - public CredentialProviderInfo(@NonNull Context context, - @NonNull ComponentName serviceComponent, int userId, boolean isSystemProvider) + public static CredentialProviderInfo create( + @NonNull Context context, + @NonNull ComponentName serviceComponent, + int userId, + boolean isSystemProvider) throws PackageManager.NameNotFoundException { - this( + return create( context, getServiceInfoOrThrow(serviceComponent, userId), isSystemProvider, - /* disableSystemAppVerificationForTests= */ false); + /* disableSystemAppVerificationForTests= */ false, + /* isEnabled= */ false); } /** @@ -98,13 +89,16 @@ public final class CredentialProviderInfo { * @param isSystemProvider whether the provider app is a system provider * @param disableSystemAppVerificationForTests whether to disable system app permission * verification so that tests can install system providers + * @param isEnabled whether the user enabled this provider * @throws SecurityException If provider does not require the relevant permission */ - public CredentialProviderInfo( + public static CredentialProviderInfo create( @NonNull Context context, @NonNull ServiceInfo serviceInfo, boolean isSystemProvider, - boolean disableSystemAppVerificationForTests) { + boolean disableSystemAppVerificationForTests, + boolean isEnabled) + throws SecurityException { verifyProviderPermission(serviceInfo); if (isSystemProvider) { if (!isValidSystemProvider( @@ -114,23 +108,11 @@ public final class CredentialProviderInfo { "Provider is not a valid system provider: " + serviceInfo); } } - mIsSystemProvider = isSystemProvider; - mContext = requireNonNull(context, "context must not be null"); - mServiceInfo = requireNonNull(serviceInfo, "serviceInfo must not be null"); - mCapabilities = new ArrayList<>(); - mIcon = mServiceInfo.loadIcon(mContext.getPackageManager()); - mLabel = - mServiceInfo.loadSafeLabel( - mContext.getPackageManager(), - 0 /* do not ellipsize */, - TextUtils.SAFE_STRING_FLAG_FIRST_LINE | TextUtils.SAFE_STRING_FLAG_TRIM); - Log.i( - TAG, - "mLabel is : " - + mLabel - + ", for: " - + mServiceInfo.getComponentName().flattenToString()); - populateProviderCapabilities(context, serviceInfo); + + return populateMetadata(context, serviceInfo) + .setSystemProvider(isSystemProvider) + .setEnabled(isEnabled) + .build(); } private static void verifyProviderPermission(ServiceInfo serviceInfo) throws SecurityException { @@ -138,19 +120,14 @@ public final class CredentialProviderInfo { if (permission.equals(serviceInfo.permission)) { return; } - - Slog.e( - TAG, - "Credential Provider Service from : " - + serviceInfo.packageName - + "does not require permission" - + permission); throw new SecurityException( "Service does not require the expected permission : " + permission); } private static boolean isSystemProviderWithValidPermission( ServiceInfo serviceInfo, Context context) { + requireNonNull(context, "context must not be null"); + final String permission = Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE; try { ApplicationInfo appInfo = @@ -177,67 +154,88 @@ public final class CredentialProviderInfo { Context context, ServiceInfo serviceInfo, boolean disableSystemAppVerificationForTests) { - boolean isValidSystemTestProvider = - isTestSystemProvider(serviceInfo, disableSystemAppVerificationForTests); - if (isValidSystemTestProvider) { - return true; + requireNonNull(context, "context must not be null"); + + if (disableSystemAppVerificationForTests) { + Bundle metadata = serviceInfo.metaData; + if (metadata == null) { + Slog.e(TAG, "isValidSystemProvider - metadata is null: " + serviceInfo); + return false; + } + return metadata.getBoolean( + CredentialProviderService.TEST_SYSTEM_PROVIDER_META_DATA_KEY); } + return isSystemProviderWithValidPermission(serviceInfo, context); } - private static boolean isTestSystemProvider( - ServiceInfo serviceInfo, boolean disableSystemAppVerificationForTests) { - if (!disableSystemAppVerificationForTests) { - return false; - } + private static CredentialProviderInfo.Builder populateMetadata( + @NonNull Context context, ServiceInfo serviceInfo) { + requireNonNull(context, "context must not be null"); - Bundle metadata = serviceInfo.metaData; + final CredentialProviderInfo.Builder builder = + new CredentialProviderInfo.Builder(serviceInfo); + final PackageManager pm = context.getPackageManager(); + + // 1. Get the metadata for the service. + final Bundle metadata = serviceInfo.metaData; if (metadata == null) { - Slog.e(TAG, "metadata is null: " + serviceInfo); - return false; + Log.i(TAG, "populateMetadata - metadata is null"); + return builder; } - return metadata.getBoolean(CredentialProviderService.TEST_SYSTEM_PROVIDER_META_DATA_KEY); - } - private void populateProviderCapabilities(@NonNull Context context, ServiceInfo serviceInfo) { - final PackageManager pm = context.getPackageManager(); + // 2. Extract the capabilities from the bundle. try { - Bundle metadata = serviceInfo.metaData; Resources resources = pm.getResourcesForApplication(serviceInfo.applicationInfo); if (metadata == null || resources == null) { - Log.i(TAG, "populateProviderCapabilities - metadata or resources is null"); - return; - } - - String[] capabilities = resources.getStringArray(metadata.getInt( - CredentialProviderService.CAPABILITY_META_DATA_KEY)); - if (capabilities == null || capabilities.length == 0) { - Slog.i(TAG, "No capabilities found for provider:" + serviceInfo.packageName); - return; + Log.i(TAG, "populateMetadata - resources is null"); + return builder; } - for (String capability : capabilities) { - if (capability.isEmpty()) { - Slog.i(TAG, "Skipping empty capability"); - continue; - } - Slog.i(TAG, "Capabilities found for provider: " + capability); - mCapabilities.add(capability); - } + builder.addCapabilities(populateProviderCapabilities(resources, metadata, serviceInfo)); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, e.getMessage()); + } + + return builder; + } + + private static List<String> populateProviderCapabilities( + Resources resources, Bundle metadata, ServiceInfo serviceInfo) { + List<String> output = new ArrayList<>(); + String[] capabilities = new String[0]; + + try { + capabilities = + resources.getStringArray( + metadata.getInt(CredentialProviderService.CAPABILITY_META_DATA_KEY)); } catch (Resources.NotFoundException e) { - Slog.e(TAG, e.getMessage()); + Slog.e(TAG, "Failed to get capabilities: " + e.getMessage()); + } + + if (capabilities == null || capabilities.length == 0) { + Slog.e(TAG, "No capabilities found for provider:" + serviceInfo.packageName); + return output; } + + for (String capability : capabilities) { + if (capability.isEmpty()) { + Slog.e(TAG, "Skipping empty capability"); + continue; + } + Slog.e(TAG, "Capabilities found for provider: " + capability); + output.add(capability); + } + return output; } - private static ServiceInfo getServiceInfoOrThrow(@NonNull ComponentName serviceComponent, - int userId) throws PackageManager.NameNotFoundException { + private static ServiceInfo getServiceInfoOrThrow( + @NonNull ComponentName serviceComponent, int userId) + throws PackageManager.NameNotFoundException { try { - ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo( - serviceComponent, - PackageManager.GET_META_DATA, - userId); + ServiceInfo si = + AppGlobals.getPackageManager() + .getServiceInfo(serviceComponent, PackageManager.GET_META_DATA, userId); if (si != null) { return si; } @@ -256,6 +254,8 @@ public final class CredentialProviderInfo { @NonNull Context context, @UserIdInt int userId, boolean disableSystemAppVerificationForTests) { + requireNonNull(context, "context must not be null"); + final List<ServiceInfo> services = new ArrayList<>(); final List<ResolveInfo> resolveInfos = new ArrayList<>(); @@ -268,15 +268,20 @@ public final class CredentialProviderInfo { for (ResolveInfo resolveInfo : resolveInfos) { final ServiceInfo serviceInfo = resolveInfo.serviceInfo; + if (disableSystemAppVerificationForTests) { + if (serviceInfo != null) { + services.add(serviceInfo); + } + continue; + } + try { - PackageManager.ApplicationInfoFlags appInfoFlags = - disableSystemAppVerificationForTests - ? PackageManager.ApplicationInfoFlags.of(0) - : PackageManager.ApplicationInfoFlags.of( - PackageManager.MATCH_SYSTEM_ONLY); ApplicationInfo appInfo = context.getPackageManager() - .getApplicationInfo(serviceInfo.packageName, appInfoFlags); + .getApplicationInfo( + serviceInfo.packageName, + PackageManager.ApplicationInfoFlags.of( + PackageManager.MATCH_SYSTEM_ONLY)); if (appInfo == null || serviceInfo == null) { continue; @@ -300,19 +305,22 @@ public final class CredentialProviderInfo { public static List<CredentialProviderInfo> getAvailableSystemServices( @NonNull Context context, @UserIdInt int userId, - boolean disableSystemAppVerificationForTests) { + boolean disableSystemAppVerificationForTests, + Set<ServiceInfo> enabledServices) { requireNonNull(context, "context must not be null"); + final List<CredentialProviderInfo> providerInfos = new ArrayList<>(); for (ServiceInfo si : getAvailableSystemServiceInfos( context, userId, disableSystemAppVerificationForTests)) { try { CredentialProviderInfo cpi = - new CredentialProviderInfo( + CredentialProviderInfoFactory.create( context, si, /* isSystemProvider= */ true, - disableSystemAppVerificationForTests); + disableSystemAppVerificationForTests, + enabledServices.contains(si)); if (cpi.isSystemProvider()) { providerInfos.add(cpi); } else { @@ -325,45 +333,12 @@ public final class CredentialProviderInfo { return providerInfos; } - /** - * Returns true if the service supports the given {@code credentialType}, false otherwise. - */ - @NonNull - public boolean hasCapability(@NonNull String credentialType) { - return mCapabilities.contains(credentialType); - } - - /** Returns the service info. */ - @NonNull - public ServiceInfo getServiceInfo() { - return mServiceInfo; - } - - public boolean isSystemProvider() { - return mIsSystemProvider; - } - - /** Returns the service icon. */ - @Nullable - public Drawable getServiceIcon() { - return mIcon; - } - - /** Returns the service label. */ - @Nullable - public CharSequence getServiceLabel() { - return mLabel; - } - - /** Returns an immutable list of capabilities this provider service can support. */ - @NonNull - public List<String> getCapabilities() { - return Collections.unmodifiableList(mCapabilities); - } + private static @Nullable PackagePolicy getDeviceManagerPolicy( + @NonNull Context context, int userId) { + Context newContext = context.createContextAsUser(UserHandle.of(userId), 0); - private static @Nullable PackagePolicy getDeviceManagerPolicy(@NonNull Context context) { try { - DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class); + DevicePolicyManager dpm = newContext.getSystemService(DevicePolicyManager.class); return dpm.getCredentialManagerPolicy(); } catch (SecurityException e) { // If the current user is not enrolled in DPM then this can throw a security error. @@ -381,21 +356,53 @@ public final class CredentialProviderInfo { public static List<CredentialProviderInfo> getCredentialProviderServices( @NonNull Context context, int userId, - boolean disableSystemAppVerificationForTests, - int providerFilter) { + int providerFilter, + Set<ServiceInfo> enabledServices) { + requireNonNull(context, "context must not be null"); + + // Get the device policy. + PackagePolicy pp = getDeviceManagerPolicy(context, userId); + + // Generate the provider list. + final boolean disableSystemAppVerificationForTests = false; + ProviderGenerator generator = + new ProviderGenerator( + context, pp, disableSystemAppVerificationForTests, providerFilter); + generator.addUserProviders( + getUserProviders( + context, userId, disableSystemAppVerificationForTests, enabledServices)); + generator.addSystemProviders( + getAvailableSystemServices( + context, userId, disableSystemAppVerificationForTests, enabledServices)); + return generator.getProviders(); + } + + /** + * Returns the valid credential provider services available for the user with the given {@code + * userId}. Includes test providers. + */ + @NonNull + public static List<CredentialProviderInfo> getCredentialProviderServicesForTesting( + @NonNull Context context, + int userId, + int providerFilter, + Set<ServiceInfo> enabledServices) { requireNonNull(context, "context must not be null"); // Get the device policy. - PackagePolicy pp = getDeviceManagerPolicy(context); + PackagePolicy pp = getDeviceManagerPolicy(context, userId); // Generate the provider list. + final boolean disableSystemAppVerificationForTests = true; ProviderGenerator generator = new ProviderGenerator( context, pp, disableSystemAppVerificationForTests, providerFilter); generator.addUserProviders( - getUserProviders(context, userId, disableSystemAppVerificationForTests)); + getUserProviders( + context, userId, disableSystemAppVerificationForTests, enabledServices)); generator.addSystemProviders( - getAvailableSystemServices(context, userId, disableSystemAppVerificationForTests)); + getAvailableSystemServices( + context, userId, disableSystemAppVerificationForTests, enabledServices)); return generator.getProviders(); } @@ -484,7 +491,8 @@ public final class CredentialProviderInfo { private static List<CredentialProviderInfo> getUserProviders( @NonNull Context context, @UserIdInt int userId, - boolean disableSystemAppVerificationForTests) { + boolean disableSystemAppVerificationForTests, + Set<ServiceInfo> enabledServices) { final List<CredentialProviderInfo> services = new ArrayList<>(); final List<ResolveInfo> resolveInfos = context.getPackageManager() @@ -496,11 +504,12 @@ public final class CredentialProviderInfo { final ServiceInfo serviceInfo = resolveInfo.serviceInfo; try { CredentialProviderInfo cpi = - new CredentialProviderInfo( + CredentialProviderInfoFactory.create( context, serviceInfo, /* isSystemProvider= */ false, - disableSystemAppVerificationForTests); + disableSystemAppVerificationForTests, + enabledServices.contains(serviceInfo)); if (!cpi.isSystemProvider()) { services.add(cpi); } diff --git a/core/tests/coretests/src/android/credentials/CredentialManagerTest.java b/core/tests/coretests/src/android/credentials/CredentialManagerTest.java index 43334ab08b2f..e31d5aef9b69 100644 --- a/core/tests/coretests/src/android/credentials/CredentialManagerTest.java +++ b/core/tests/coretests/src/android/credentials/CredentialManagerTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.when; import android.app.Activity; import android.app.slice.Slice; import android.content.Context; +import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.Bundle; import android.os.CancellationSignal; @@ -47,6 +48,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; @@ -59,6 +61,17 @@ public class CredentialManagerTest { @Mock private Activity mMockActivity; + private static final int TEST_USER_ID = 1; + private static final CredentialProviderInfo TEST_CREDENTIAL_PROVIDER_INFO = + new CredentialProviderInfo.Builder(new ServiceInfo()) + .setSystemProvider(true) + .setOverrideLabel("test") + .addCapabilities(Arrays.asList("passkey")) + .setEnabled(true) + .build(); + private static final List<CredentialProviderInfo> TEST_CREDENTIAL_PROVIDER_INFO_LIST = + Arrays.asList(TEST_CREDENTIAL_PROVIDER_INFO); + private GetCredentialRequest mGetRequest; private CreateCredentialRequest mCreateRequest; @@ -438,95 +451,53 @@ public class CredentialManagerTest { } @Test - public void testListEnabledProviders_nullExecutor() { - assertThrows(NullPointerException.class, - () -> mCredentialManager.listEnabledProviders(null, null, result -> { - })); - + public void testGetCredentialProviderServices_allProviders() throws RemoteException { + verifyGetCredentialProviderServices(CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS); } @Test - public void testListEnabledProviders_nullCallback() { - assertThrows(NullPointerException.class, - () -> mCredentialManager.listEnabledProviders(null, mExecutor, null)); - + public void testGetCredentialProviderServices_userProviders() throws RemoteException { + verifyGetCredentialProviderServices(CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY); } @Test - public void testListEnabledProviders_alreadyCancelled() throws RemoteException { - final CancellationSignal cancellation = new CancellationSignal(); - cancellation.cancel(); - - mCredentialManager.listEnabledProviders(cancellation, mExecutor, result -> { - }); - - verify(mMockCredentialManagerService, never()).listEnabledProviders(any()); + public void testGetCredentialProviderServices_systemProviders() throws RemoteException { + verifyGetCredentialProviderServices(CredentialManager.PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY); } @Test - public void testListEnabledProviders_cancel() throws RemoteException { - final ICancellationSignal serviceSignal = mock(ICancellationSignal.class); - final CancellationSignal cancellation = new CancellationSignal(); - - OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException> callback = - mock(OutcomeReceiver.class); - - when(mMockCredentialManagerService.listEnabledProviders(any())).thenReturn(serviceSignal); - - mCredentialManager.listEnabledProviders(cancellation, mExecutor, callback); - - verify(mMockCredentialManagerService).listEnabledProviders(any()); - - cancellation.cancel(); - verify(serviceSignal).cancel(); + public void testGetCredentialProviderServicesForTesting_allProviders() throws RemoteException { + verifyGetCredentialProviderServicesForTesting(CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS); } @Test - public void testListEnabledProviders_failed() throws RemoteException { - ArgumentCaptor<IListEnabledProvidersCallback> callbackCaptor = ArgumentCaptor.forClass( - IListEnabledProvidersCallback.class); - ArgumentCaptor<ListEnabledProvidersException> errorCaptor = ArgumentCaptor.forClass( - ListEnabledProvidersException.class); - - OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException> callback = - mock(OutcomeReceiver.class); - - when(mMockCredentialManagerService.listEnabledProviders( - callbackCaptor.capture())).thenReturn(mock(ICancellationSignal.class)); - mCredentialManager.listEnabledProviders(null, mExecutor, callback); - verify(mMockCredentialManagerService).listEnabledProviders(any()); - - final String errorType = "type"; - callbackCaptor.getValue().onError("type", "unknown error"); - verify(callback).onError(errorCaptor.capture()); - - assertThat(errorCaptor.getValue().getType()).isEqualTo(errorType); + public void testGetCredentialProviderServicesForTesting_userProviders() throws RemoteException { + verifyGetCredentialProviderServicesForTesting(CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY); } @Test - public void testListEnabledProviders_success() throws RemoteException { - ListEnabledProvidersResponse response = ListEnabledProvidersResponse.create( - List.of("foo", "bar", "baz")); + public void testGetCredentialProviderServicesForTesting_systemProviders() throws RemoteException { + verifyGetCredentialProviderServicesForTesting(CredentialManager.PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY); + } - OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException> callback = - mock(OutcomeReceiver.class); + private void verifyGetCredentialProviderServices(int testFilter) throws RemoteException { + when(mMockCredentialManagerService.getCredentialProviderServices( + TEST_USER_ID, testFilter)).thenReturn(TEST_CREDENTIAL_PROVIDER_INFO_LIST); - ArgumentCaptor<IListEnabledProvidersCallback> callbackCaptor = ArgumentCaptor.forClass( - IListEnabledProvidersCallback.class); - ArgumentCaptor<ListEnabledProvidersResponse> responseCaptor = ArgumentCaptor.forClass( - ListEnabledProvidersResponse.class); + List<CredentialProviderInfo> output = + mCredentialManager.getCredentialProviderServices(TEST_USER_ID, testFilter); - when(mMockCredentialManagerService.listEnabledProviders( - callbackCaptor.capture())).thenReturn(mock(ICancellationSignal.class)); - mCredentialManager.listEnabledProviders(null, mExecutor, callback); + assertThat(output).containsExactlyElementsIn(TEST_CREDENTIAL_PROVIDER_INFO_LIST); + } - verify(mMockCredentialManagerService).listEnabledProviders(any()); + private void verifyGetCredentialProviderServicesForTesting(int testFilter) throws RemoteException { + when(mMockCredentialManagerService.getCredentialProviderServicesForTesting( + testFilter)).thenReturn(TEST_CREDENTIAL_PROVIDER_INFO_LIST); - callbackCaptor.getValue().onResponse(response); + List<CredentialProviderInfo> output = + mCredentialManager.getCredentialProviderServicesForTesting(testFilter); - verify(callback).onResult(responseCaptor.capture()); - assertThat(responseCaptor.getValue().getProviderComponentNames()).containsExactlyElementsIn( - response.getProviderComponentNames()); + assertThat(output).containsExactlyElementsIn(TEST_CREDENTIAL_PROVIDER_INFO_LIST); } @Test diff --git a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java index c8ec7c20650b..49db5f710004 100644 --- a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java +++ b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java @@ -20,13 +20,13 @@ import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.credentials.ClearCredentialStateRequest; +import android.credentials.CredentialProviderInfo; import android.credentials.IClearCredentialStateCallback; import android.credentials.ui.ProviderData; import android.credentials.ui.RequestInfo; import android.os.CancellationSignal; import android.os.RemoteException; import android.service.credentials.CallingAppInfo; -import android.service.credentials.CredentialProviderInfo; import android.util.Log; import com.android.server.credentials.metrics.ApiName; diff --git a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java index 0c1133ce8793..90e10679abcd 100644 --- a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java +++ b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java @@ -27,13 +27,13 @@ import android.credentials.CreateCredentialException; import android.credentials.CreateCredentialRequest; import android.credentials.CreateCredentialResponse; import android.credentials.CredentialManager; +import android.credentials.CredentialProviderInfo; import android.credentials.ICreateCredentialCallback; import android.credentials.ui.ProviderData; import android.credentials.ui.RequestInfo; import android.os.CancellationSignal; import android.os.RemoteException; import android.service.credentials.CallingAppInfo; -import android.service.credentials.CredentialProviderInfo; import android.util.Log; import com.android.server.credentials.metrics.ApiName; diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java index 41ae9118d965..8170dc30d09d 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java @@ -36,15 +36,14 @@ import android.credentials.CreateCredentialRequest; import android.credentials.CredentialDescription; import android.credentials.CredentialManager; import android.credentials.CredentialOption; +import android.credentials.CredentialProviderInfo; import android.credentials.GetCredentialException; import android.credentials.GetCredentialRequest; import android.credentials.IClearCredentialStateCallback; import android.credentials.ICreateCredentialCallback; import android.credentials.ICredentialManager; import android.credentials.IGetCredentialCallback; -import android.credentials.IListEnabledProvidersCallback; import android.credentials.ISetEnabledProvidersCallback; -import android.credentials.ListEnabledProvidersResponse; import android.credentials.RegisterCredentialDescriptionRequest; import android.credentials.UnregisterCredentialDescriptionRequest; import android.credentials.ui.IntentFactory; @@ -56,7 +55,7 @@ import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings; import android.service.credentials.CallingAppInfo; -import android.service.credentials.CredentialProviderInfo; +import android.service.credentials.CredentialProviderInfoFactory; import android.text.TextUtils; import android.util.Log; import android.util.Pair; @@ -118,10 +117,11 @@ public final class CredentialManagerService int resolvedUserId) { List<CredentialManagerServiceImpl> services = new ArrayList<>(); List<CredentialProviderInfo> serviceInfos = - CredentialProviderInfo.getAvailableSystemServices( + CredentialProviderInfoFactory.getAvailableSystemServices( mContext, resolvedUserId, - /* disableSystemAppVerificationForTests= */ false); + /* disableSystemAppVerificationForTests= */ false, + new HashSet<>()); serviceInfos.forEach( info -> { services.add( @@ -222,10 +222,16 @@ public final class CredentialManagerService return hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS); } - private void verifyPermission(String permission) throws SecurityException { - if (!hasPermission(permission)) { - throw new SecurityException("Caller is missing permission: " + permission); + private void verifyGetProvidersPermission() throws SecurityException { + if (hasPermission(android.Manifest.permission.QUERY_ALL_PACKAGES)) { + return; } + + if (hasPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS)) { + return; + } + + throw new SecurityException("Caller is missing permission: QUERY_ALL_PACKAGES or LIST_ENABLED_CREDENTIAL_PROVIDERS"); } private boolean hasPermission(String permission) { @@ -550,40 +556,6 @@ public final class CredentialManagerService providerSessions.forEach(ProviderSession::invokeSession); } - @SuppressWarnings("GuardedBy") // ErrorProne requires listEnabledProviders - // to be guarded by 'service.mLock', which is the same as mLock. - @Override - public ICancellationSignal listEnabledProviders(IListEnabledProvidersCallback callback) { - Log.i(TAG, "listEnabledProviders"); - ICancellationSignal cancelTransport = CancellationSignal.createTransport(); - - if (!hasWriteSecureSettingsPermission()) { - try { - callback.onError( - PERMISSION_DENIED_ERROR, PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR); - } catch (RemoteException e) { - Log.e(TAG, "Issue with invoking response: " + e.getMessage()); - } - return cancelTransport; - } - - List<String> enabledProviders = new ArrayList<>(); - runForUser( - (service) -> { - enabledProviders.add(service.getComponentName().flattenToString()); - }); - - // Call the callback. - try { - callback.onResponse(ListEnabledProvidersResponse.create(enabledProviders)); - } catch (RemoteException e) { - Log.i(TAG, "Issue with invoking response: " + e.getMessage()); - // TODO: Propagate failure - } - - return cancelTransport; - } - @Override public void setEnabledProviders( List<String> providers, int userId, ISetEnabledProvidersCallback callback) { @@ -677,20 +649,35 @@ public final class CredentialManagerService } @Override - public List<ServiceInfo> getCredentialProviderServices( - int userId, boolean disableSystemAppVerificationForTests, int providerFilter) { + public List<CredentialProviderInfo> getCredentialProviderServices( + int userId, int providerFilter) { Log.i(TAG, "getCredentialProviderServices"); - verifyPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS); - - List<ServiceInfo> services = new ArrayList<>(); - List<CredentialProviderInfo> providers = - CredentialProviderInfo.getCredentialProviderServices( - mContext, userId, disableSystemAppVerificationForTests, providerFilter); - for (CredentialProviderInfo p : providers) { - services.add(p.getServiceInfo()); - } + verifyGetProvidersPermission(); - return services; + return CredentialProviderInfoFactory.getCredentialProviderServices( + mContext, userId, providerFilter, getEnabledProviders()); + } + + @Override + public List<CredentialProviderInfo> getCredentialProviderServicesForTesting( + int providerFilter) { + Log.i(TAG, "getCredentialProviderServicesForTesting"); + verifyGetProvidersPermission(); + + final int userId = UserHandle.getCallingUserId(); + return CredentialProviderInfoFactory.getCredentialProviderServicesForTesting( + mContext, userId, providerFilter, getEnabledProviders()); + } + + private Set<ServiceInfo> getEnabledProviders() { + Set<ServiceInfo> enabledProviders = new HashSet<>(); + synchronized (mLock) { + runForUser( + (service) -> { + enabledProviders.add(service.getCredentialProviderInfo().getServiceInfo()); + }); + } + return enabledProviders; } @Override @@ -828,11 +815,11 @@ public final class CredentialManagerService } private List<CredentialProviderInfo> getServicesForCredentialDescription(int userId) { - return CredentialProviderInfo.getCredentialProviderServices( + return CredentialProviderInfoFactory.getCredentialProviderServices( mContext, userId, - /* disableSystemAppVerificationForTests= */ false, - CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS); + CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS, + new HashSet<>()); } } diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java index 546c48fe05f4..ee55a1ccc357 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java @@ -21,7 +21,8 @@ import android.annotation.Nullable; import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; -import android.service.credentials.CredentialProviderInfo; +import android.credentials.CredentialProviderInfo; +import android.service.credentials.CredentialProviderInfoFactory; import android.util.Log; import android.util.Slog; @@ -82,7 +83,7 @@ public final class CredentialManagerServiceImpl extends Log.i(TAG, "newServiceInfoLocked with null mInfo , " + serviceComponent.getPackageName()); } - mInfo = new CredentialProviderInfo( + mInfo = CredentialProviderInfoFactory.create( getContext(), serviceComponent, mUserId, /*isSystemProvider=*/false); return mInfo.getServiceInfo(); diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java index 2c6c0d8b4018..546c37ff95af 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ServiceInfo; import android.credentials.CredentialManager; +import android.credentials.CredentialProviderInfo; import android.credentials.ui.DisabledProviderData; import android.credentials.ui.IntentFactory; import android.credentials.ui.ProviderData; @@ -31,11 +32,12 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.ResultReceiver; -import android.service.credentials.CredentialProviderInfo; +import android.service.credentials.CredentialProviderInfoFactory; import android.util.Log; import android.util.Slog; import java.util.ArrayList; +import java.util.HashSet; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -118,11 +120,11 @@ public class CredentialManagerUi { .map(ProviderData::getProviderFlattenedComponentName) .collect(Collectors.toUnmodifiableSet()); Set<String> allProviders = - CredentialProviderInfo.getCredentialProviderServices( + CredentialProviderInfoFactory.getCredentialProviderServices( mContext, mUserId, - /* disableSystemAppVerificationForTests= */ false, - CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY) + CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY, + new HashSet<>()) .stream() .map(CredentialProviderInfo::getServiceInfo) .map(ServiceInfo::getComponentName) diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java index 13f4b542a83e..4af2713a5cf8 100644 --- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java +++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java @@ -22,6 +22,7 @@ import static com.android.server.credentials.MetricUtilities.METRICS_PROVIDER_ST import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; +import android.credentials.CredentialProviderInfo; import android.credentials.GetCredentialException; import android.credentials.GetCredentialRequest; import android.credentials.GetCredentialResponse; @@ -31,7 +32,6 @@ import android.credentials.ui.RequestInfo; import android.os.CancellationSignal; import android.os.RemoteException; import android.service.credentials.CallingAppInfo; -import android.service.credentials.CredentialProviderInfo; import android.util.Log; import com.android.server.credentials.metrics.ApiName; diff --git a/services/credentials/java/com/android/server/credentials/ProviderClearSession.java b/services/credentials/java/com/android/server/credentials/ProviderClearSession.java index 941d9ad26dca..b7a4cd581a1a 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderClearSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderClearSession.java @@ -20,11 +20,11 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; import android.credentials.ClearCredentialStateException; +import android.credentials.CredentialProviderInfo; import android.credentials.ui.ProviderData; import android.credentials.ui.ProviderPendingIntentResponse; import android.service.credentials.CallingAppInfo; import android.service.credentials.ClearCredentialStateRequest; -import android.service.credentials.CredentialProviderInfo; import android.util.Log; import android.util.Slog; diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java index 17caba5831e8..640cc3331b1a 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java @@ -24,6 +24,7 @@ import android.content.Context; import android.content.Intent; import android.credentials.CreateCredentialException; import android.credentials.CreateCredentialResponse; +import android.credentials.CredentialProviderInfo; import android.credentials.ui.CreateCredentialProviderData; import android.credentials.ui.Entry; import android.credentials.ui.ProviderPendingIntentResponse; @@ -33,7 +34,6 @@ import android.service.credentials.BeginCreateCredentialResponse; import android.service.credentials.CallingAppInfo; import android.service.credentials.CreateCredentialRequest; import android.service.credentials.CreateEntry; -import android.service.credentials.CredentialProviderInfo; import android.service.credentials.CredentialProviderService; import android.service.credentials.RemoteEntry; import android.util.Log; diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java index b8b11ebd13f0..07e2f877bfc0 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java @@ -23,6 +23,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.credentials.CredentialOption; +import android.credentials.CredentialProviderInfo; import android.credentials.GetCredentialException; import android.credentials.GetCredentialResponse; import android.credentials.ui.AuthenticationEntry; @@ -35,7 +36,6 @@ import android.service.credentials.BeginGetCredentialRequest; import android.service.credentials.BeginGetCredentialResponse; import android.service.credentials.CallingAppInfo; import android.service.credentials.CredentialEntry; -import android.service.credentials.CredentialProviderInfo; import android.service.credentials.CredentialProviderService; import android.service.credentials.GetCredentialRequest; import android.service.credentials.RemoteEntry; diff --git a/services/credentials/java/com/android/server/credentials/ProviderSession.java b/services/credentials/java/com/android/server/credentials/ProviderSession.java index 53ed070e3e49..fc179e4526f5 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderSession.java @@ -27,11 +27,11 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.credentials.Credential; +import android.credentials.CredentialProviderInfo; import android.credentials.ui.ProviderData; import android.credentials.ui.ProviderPendingIntentResponse; import android.os.ICancellationSignal; import android.os.RemoteException; -import android.service.credentials.CredentialProviderInfo; import android.util.Log; import com.android.server.credentials.metrics.CandidateProviderMetric; diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java index abfb2107c4a3..c1f35d0f8195 100644 --- a/services/credentials/java/com/android/server/credentials/RequestSession.java +++ b/services/credentials/java/com/android/server/credentials/RequestSession.java @@ -22,6 +22,7 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ComponentName; import android.content.Context; +import android.credentials.CredentialProviderInfo; import android.credentials.ui.ProviderData; import android.credentials.ui.UserSelectionDialogResult; import android.os.Binder; @@ -30,7 +31,6 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.service.credentials.CallingAppInfo; -import android.service.credentials.CredentialProviderInfo; import android.util.Log; import com.android.internal.R; |