diff --git a/core/api/current.txt b/core/api/current.txt index 19002d3cff70f..1b5e020c02ce6 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -13509,6 +13509,7 @@ package android.credentials { method public void clearCredentialState(@NonNull android.credentials.ClearCredentialStateRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver); method public void createCredential(@NonNull android.credentials.CreateCredentialRequest, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver); method public void getCredential(@NonNull android.credentials.GetCredentialRequest, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver); + method public boolean isEnabledCredentialProviderService(@NonNull android.content.ComponentName); method public void registerCredentialDescription(@NonNull android.credentials.RegisterCredentialDescriptionRequest); method public void unregisterCredentialDescription(@NonNull android.credentials.UnregisterCredentialDescriptionRequest); } diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java index b4109db2032a5..8b43a21c2fb72 100644 --- a/core/java/android/credentials/CredentialManager.java +++ b/core/java/android/credentials/CredentialManager.java @@ -25,6 +25,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.app.Activity; import android.app.PendingIntent; +import android.content.ComponentName; import android.content.Context; import android.content.IntentSender; import android.os.CancellationSignal; @@ -279,6 +280,25 @@ public final class CredentialManager { } } + /** + * Returns {@code true} if the calling application provides a CredentialProviderService that is + * enabled for the current user, or {@code false} otherwise. CredentialProviderServices are + * enabled on a per-service basis so the individual component name of the service should be + * passed in here. + * + * @param componentName the component name to check is enabled + */ + public boolean isEnabledCredentialProviderService(@NonNull ComponentName componentName) { + requireNonNull(componentName, "componentName must not be null"); + + try { + return mService.isEnabledCredentialProviderService( + componentName, mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Returns whether the service is enabled. * diff --git a/core/java/android/credentials/ICredentialManager.aidl b/core/java/android/credentials/ICredentialManager.aidl index 4ca3124f5c810..885acd4f712b3 100644 --- a/core/java/android/credentials/ICredentialManager.aidl +++ b/core/java/android/credentials/ICredentialManager.aidl @@ -28,6 +28,7 @@ import android.credentials.ICreateCredentialCallback; import android.credentials.IGetCredentialCallback; import android.credentials.IListEnabledProvidersCallback; import android.credentials.ISetEnabledProvidersCallback; +import android.content.ComponentName; import android.os.ICancellationSignal; /** @@ -50,5 +51,7 @@ interface ICredentialManager { void registerCredentialDescription(in RegisterCredentialDescriptionRequest request, String callingPackage); void unregisterCredentialDescription(in UnregisterCredentialDescriptionRequest request, String callingPackage); + + boolean isEnabledCredentialProviderService(in ComponentName componentName, String callingPackage); } diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java index 6cfb26b94caa5..aa5881d68df92 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java @@ -573,6 +573,37 @@ public final class CredentialManagerService getContext().sendBroadcast(IntentFactory.createProviderUpdateIntent()); } + @Override + public boolean isEnabledCredentialProviderService( + ComponentName componentName, String callingPackage) { + Log.i(TAG, "isEnabledCredentialProviderService"); + + // TODO(253157366): Check additional set of services. + final int userId = UserHandle.getCallingUserId(); + synchronized (mLock) { + final List services = + getServiceListForUserLocked(userId); + for (CredentialManagerServiceImpl s : services) { + final ComponentName serviceComponentName = s.getServiceComponentName(); + + if (serviceComponentName.equals(componentName)) { + if (!s.getServicePackageName().equals(callingPackage)) { + // The component name and the package name do not match. + Log.w( + TAG, + "isEnabledCredentialProviderService: Component name does not" + + " match package name."); + return false; + } + + return true; + } + } + } + + return false; + } + @Override public ICancellationSignal clearCredentialState( ClearCredentialStateRequest request,