Loading core/java/android/credentials/CredentialManager.java +16 −25 Original line number Diff line number Diff line Loading @@ -222,7 +222,7 @@ public final class CredentialManager { * @param callback the callback invoked when the request succeeds or fails * @hide */ @RequiresPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS) @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void listEnabledProviders( @Nullable CancellationSignal cancellationSignal, @CallbackExecutor @NonNull Executor executor, Loading Loading @@ -298,8 +298,7 @@ public final class CredentialManager { private boolean isServiceEnabled() { return DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER, true); DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER, true); } /** Loading @@ -313,22 +312,19 @@ public final class CredentialManager { } /** * Registers a {@link CredentialDescription} for an actively provisioned {@link Credential} * a CredentialProvider has. This registry will then be used to determine where to * fetch the requested {@link Credential} from. Not all credential types will be supported. * The distinction will be made by the JetPack layer. For the types that are supported, * JetPack will add a new key-value pair into {@link GetCredentialRequest}. These will not * be persistent on the device. The Credential Providers will need to call this API again * upon device reboot. * Registers a {@link CredentialDescription} for an actively provisioned {@link Credential} a * CredentialProvider has. This registry will then be used to determine where to fetch the * requested {@link Credential} from. Not all credential types will be supported. The * distinction will be made by the JetPack layer. For the types that are supported, JetPack will * add a new key-value pair into {@link GetCredentialRequest}. These will not be persistent on * the device. The Credential Providers will need to call this API again upon device reboot. * * @param request the request data * * @throws {@link UnsupportedOperationException} if the feature has not been enabled. * @throws {@link com.android.server.credentials.NonCredentialProviderCallerException} * if the calling package name is not also listed as a Credential Provider. * @throws {@link com.android.server.credentials.NonCredentialProviderCallerException} if the * calling package name is not also listed as a Credential Provider. * @throws {@link IllegalArgumentException} if the calling Credential Provider can not handle * one or more of the Credential Types that are sent for registration. * */ public void registerCredentialDescription( @NonNull RegisterCredentialDescriptionRequest request) { Loading @@ -346,16 +342,12 @@ public final class CredentialManager { } } /** * Unregisters a {@link CredentialDescription} for an actively provisioned {@link Credential} * that has been registered previously. * * * @param request the request data * * @throws {@link UnsupportedOperationException} if the feature has not been enabled. * */ public void unregisterCredentialDescription( @NonNull UnregisterCredentialDescriptionRequest request) { Loading @@ -371,7 +363,6 @@ public final class CredentialManager { } catch (RemoteException e) { e.rethrowFromSystemServer(); } } private static class GetCredentialTransport extends IGetCredentialCallback.Stub { Loading services/credentials/java/com/android/server/credentials/CredentialManagerService.java +147 −82 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.credentials; import static android.content.Context.CREDENTIAL_SERVICE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.annotation.NonNull; import android.annotation.UserIdInt; Loading Loading @@ -81,17 +82,17 @@ public final class CredentialManagerService private static final String TAG = "CredManSysService"; private static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API = "enable_credential_description_api"; private static final String PERMISSION_DENIED_ERROR = "permission_denied"; private static final String PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR = "Caller is missing WRITE_SECURE_SETTINGS permission"; private final Context mContext; /** * Cache of system service list per user id. */ /** Cache of system service list per user id. */ @GuardedBy("mLock") private final SparseArray<List<CredentialManagerServiceImpl>> mSystemServicesCacheList = new SparseArray<>(); public CredentialManagerService(@NonNull Context context) { super( context, Loading @@ -109,8 +110,10 @@ public final class CredentialManagerService List<CredentialManagerServiceImpl> services = new ArrayList<>(); List<CredentialProviderInfo> credentialProviderInfos = CredentialProviderInfo.getAvailableSystemServices(mContext, resolvedUserId); credentialProviderInfos.forEach(info -> { services.add(new CredentialManagerServiceImpl(this, mLock, resolvedUserId, info)); credentialProviderInfos.forEach( info -> { services.add( new CredentialManagerServiceImpl(this, mLock, resolvedUserId, info)); }); return services; } Loading Loading @@ -174,10 +177,9 @@ public final class CredentialManagerService CredentialManagerServiceImpl serviceToBeRemoved = null; for (CredentialManagerServiceImpl service : services) { if (service != null) { CredentialProviderInfo credentialProviderInfo = service.getCredentialProviderInfo(); ComponentName componentName = credentialProviderInfo.getServiceInfo() .getComponentName(); CredentialProviderInfo credentialProviderInfo = service.getCredentialProviderInfo(); ComponentName componentName = credentialProviderInfo.getServiceInfo().getComponentName(); if (packageName.equals(componentName.getPackageName())) { serviceToBeRemoved = service; removeServiceFromMultiModeSettings(componentName.flattenToString(), userId); Loading @@ -193,7 +195,6 @@ public final class CredentialManagerService // TODO("Iterate over system services and remove if needed") } @GuardedBy("mLock") private List<CredentialManagerServiceImpl> getOrConstructSystemServiceListLock( int resolvedUserId) { Loading @@ -205,6 +206,16 @@ public final class CredentialManagerService return services; } private boolean hasWriteSecureSettingsPermission() { final String permission = android.Manifest.permission.WRITE_SECURE_SETTINGS; final boolean result = mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED; if (!result) { Slog.e(TAG, "Caller does not have WRITE_SECURE_SETTINGS permission."); } return result; } private void runForUser(@NonNull final Consumer<CredentialManagerServiceImpl> c) { final int userId = UserHandle.getCallingUserId(); final long origId = Binder.clearCallingIdentity(); Loading @@ -222,8 +233,7 @@ public final class CredentialManagerService } @GuardedBy("mLock") private List<CredentialManagerServiceImpl> getAllCredentialProviderServicesLocked( int userId) { private List<CredentialManagerServiceImpl> getAllCredentialProviderServicesLocked(int userId) { List<CredentialManagerServiceImpl> concatenatedServices = new ArrayList<>(); List<CredentialManagerServiceImpl> userConfigurableServices = getServiceListForUserLocked(userId); Loading @@ -243,11 +253,13 @@ 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) { List<String> requestOptions, Set<String> activeCredentialContainers) { List<ProviderSession> providerSessions = new ArrayList<>(); // Invoke all services of a user to initiate a provider session for (String packageName : activeCredentialContainers) { providerSessions.add(ProviderRegistryGetSession.createNewSession( providerSessions.add( ProviderRegistryGetSession.createNewSession( mContext, UserHandle.getCallingUserId(), session, Loading @@ -260,16 +272,17 @@ public final class CredentialManagerService @NonNull private Set<String> getFilteredResultFromRegistry(List<CredentialOption> options) { // Session for active/provisioned credential descriptions; CredentialDescriptionRegistry registry = CredentialDescriptionRegistry .forUser(UserHandle.getCallingUserId()); CredentialDescriptionRegistry registry = CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId()); // All requested credential descriptions based on the given request. Set<String> requestedCredentialDescriptions = options.stream().map( getCredentialOption -> getCredentialOption options.stream() .map( getCredentialOption -> getCredentialOption .getCredentialRetrievalData() .getString(CredentialOption .FLATTENED_REQUEST)) .getString(CredentialOption.FLATTENED_REQUEST)) .collect(Collectors.toSet()); // All requested credential descriptions based on the given request. Loading Loading @@ -306,9 +319,13 @@ public final class CredentialManagerService private CallingAppInfo constructCallingAppInfo(String packageName, int userId) { final PackageInfo packageInfo; try { packageInfo = getContext().getPackageManager().getPackageInfoAsUser( packageInfo = getContext() .getPackageManager() .getPackageInfoAsUser( packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES), PackageManager.PackageInfoFlags.of( PackageManager.GET_SIGNING_CERTIFICATES), userId); } catch (PackageManager.NameNotFoundException e) { Log.i(TAG, "Issue while retrieving signatureInfo : " + e.getMessage()); Loading Loading @@ -345,33 +362,46 @@ public final class CredentialManagerService if (isCredentialDescriptionApiEnabled()) { List<CredentialOption> optionsThatRequireActiveCredentials = request.getCredentialOptions().stream() .filter(getCredentialOption -> !TextUtils.isEmpty(getCredentialOption .getCredentialRetrievalData().getString( .filter( getCredentialOption -> !TextUtils.isEmpty( getCredentialOption .getCredentialRetrievalData() .getString( CredentialOption .FLATTENED_REQUEST, null))) .FLATTENED_REQUEST, null))) .toList(); List<CredentialOption> optionsThatDoNotRequireActiveCredentials = request.getCredentialOptions().stream() .filter(getCredentialOption -> TextUtils.isEmpty(getCredentialOption .getCredentialRetrievalData().getString( .filter( getCredentialOption -> TextUtils.isEmpty( getCredentialOption .getCredentialRetrievalData() .getString( CredentialOption .FLATTENED_REQUEST, null))) .FLATTENED_REQUEST, null))) .toList(); List<ProviderSession> sessionsWithoutRemoteService = initiateProviderSessionsWithActiveContainers(session, optionsThatRequireActiveCredentials .stream().map(getCredentialOption -> getCredentialOption.getCredentialRetrievalData() .getString(CredentialOption initiateProviderSessionsWithActiveContainers( session, optionsThatRequireActiveCredentials.stream() .map( getCredentialOption -> getCredentialOption .getCredentialRetrievalData() .getString( CredentialOption .FLATTENED_REQUEST)) .collect(Collectors.toList()), getFilteredResultFromRegistry(optionsThatRequireActiveCredentials)); List<ProviderSession> sessionsWithRemoteService = initiateProviderSessions( List<ProviderSession> sessionsWithRemoteService = initiateProviderSessions( session, optionsThatDoNotRequireActiveCredentials.stream() .map(CredentialOption::getType) Loading @@ -394,7 +424,8 @@ public final class CredentialManagerService if (providerSessions.isEmpty()) { try { callback.onError(GetCredentialException.TYPE_NO_CREDENTIAL, callback.onError( GetCredentialException.TYPE_NO_CREDENTIAL, "No credentials available on this device."); } catch (RemoteException e) { Log.i( Loading Loading @@ -437,7 +468,8 @@ public final class CredentialManagerService if (providerSessions.isEmpty()) { try { callback.onError(CreateCredentialException.TYPE_NO_CREDENTIAL, callback.onError( CreateCredentialException.TYPE_NO_CREDENTIAL, "No credentials available on this device."); } catch (RemoteException e) { Log.i( Loading @@ -460,6 +492,16 @@ public final class CredentialManagerService 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) -> { Loading @@ -482,6 +524,16 @@ public final class CredentialManagerService List<String> providers, int userId, ISetEnabledProvidersCallback callback) { Log.i(TAG, "setEnabledProviders"); 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; } userId = ActivityManager.handleIncomingUser( Binder.getCallingPid(), Loading Loading @@ -550,8 +602,7 @@ public final class CredentialManagerService if (providerSessions.isEmpty()) { try { // TODO("Replace with properly defined error type") callback.onError("UNKNOWN", "No crdentials available on this " + "device"); callback.onError("UNKNOWN", "No crdentials available on this " + "device"); } catch (RemoteException e) { Log.i( TAG, Loading @@ -573,35 +624,46 @@ public final class CredentialManagerService Log.i(TAG, "registerCredentialDescription"); List<CredentialProviderInfo> services = CredentialProviderInfo.getAvailableServices(mContext, UserHandle.getCallingUserId()); CredentialProviderInfo.getAvailableServices( mContext, UserHandle.getCallingUserId()); List<String> providers = services.stream() .map(credentialProviderInfo -> credentialProviderInfo.getServiceInfo().packageName).toList(); List<String> providers = services.stream() .map( credentialProviderInfo -> credentialProviderInfo.getServiceInfo().packageName) .toList(); if (!providers.contains(callingPackage)) { throw new NonCredentialProviderCallerException(callingPackage); } List<CredentialProviderInfo> matchingService = services.stream().filter( List<CredentialProviderInfo> matchingService = services.stream() .filter( credentialProviderInfo -> credentialProviderInfo.getServiceInfo() .packageName.equals(callingPackage)).toList(); credentialProviderInfo .getServiceInfo() .packageName .equals(callingPackage)) .toList(); CredentialProviderInfo credentialProviderInfo = matchingService.get(0); Set<String> supportedTypes = request.getCredentialDescriptions() .stream().map(CredentialDescription::getType).filter( credentialProviderInfo::hasCapability).collect(Collectors.toSet()); Set<String> supportedTypes = request.getCredentialDescriptions().stream() .map(CredentialDescription::getType) .filter(credentialProviderInfo::hasCapability) .collect(Collectors.toSet()); if (supportedTypes.size() != request.getCredentialDescriptions().size()) { throw new IllegalArgumentException("CredentialProvider does not support one or more" throw new IllegalArgumentException( "CredentialProvider does not support one or more" + "of the registered types. Check your XML entry."); } CredentialDescriptionRegistry session = CredentialDescriptionRegistry .forUser(UserHandle.getCallingUserId()); CredentialDescriptionRegistry session = CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId()); session.executeRegisterRequest(request, callingPackage); } Loading @@ -614,19 +676,22 @@ public final class CredentialManagerService ICancellationSignal cancelTransport = CancellationSignal.createTransport(); List<CredentialProviderInfo> services = CredentialProviderInfo.getAvailableServices(mContext, UserHandle.getCallingUserId()); CredentialProviderInfo.getAvailableServices( mContext, UserHandle.getCallingUserId()); List<String> providers = services.stream() .map(credentialProviderInfo -> credentialProviderInfo.getServiceInfo().packageName).toList(); List<String> providers = services.stream() .map( credentialProviderInfo -> credentialProviderInfo.getServiceInfo().packageName) .toList(); if (!providers.contains(callingPackage)) { throw new NonCredentialProviderCallerException(callingPackage); } CredentialDescriptionRegistry session = CredentialDescriptionRegistry .forUser(UserHandle.getCallingUserId()); CredentialDescriptionRegistry session = CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId()); session.executeUnregisterRequest(request, callingPackage); } Loading Loading
core/java/android/credentials/CredentialManager.java +16 −25 Original line number Diff line number Diff line Loading @@ -222,7 +222,7 @@ public final class CredentialManager { * @param callback the callback invoked when the request succeeds or fails * @hide */ @RequiresPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS) @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void listEnabledProviders( @Nullable CancellationSignal cancellationSignal, @CallbackExecutor @NonNull Executor executor, Loading Loading @@ -298,8 +298,7 @@ public final class CredentialManager { private boolean isServiceEnabled() { return DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER, true); DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER, true); } /** Loading @@ -313,22 +312,19 @@ public final class CredentialManager { } /** * Registers a {@link CredentialDescription} for an actively provisioned {@link Credential} * a CredentialProvider has. This registry will then be used to determine where to * fetch the requested {@link Credential} from. Not all credential types will be supported. * The distinction will be made by the JetPack layer. For the types that are supported, * JetPack will add a new key-value pair into {@link GetCredentialRequest}. These will not * be persistent on the device. The Credential Providers will need to call this API again * upon device reboot. * Registers a {@link CredentialDescription} for an actively provisioned {@link Credential} a * CredentialProvider has. This registry will then be used to determine where to fetch the * requested {@link Credential} from. Not all credential types will be supported. The * distinction will be made by the JetPack layer. For the types that are supported, JetPack will * add a new key-value pair into {@link GetCredentialRequest}. These will not be persistent on * the device. The Credential Providers will need to call this API again upon device reboot. * * @param request the request data * * @throws {@link UnsupportedOperationException} if the feature has not been enabled. * @throws {@link com.android.server.credentials.NonCredentialProviderCallerException} * if the calling package name is not also listed as a Credential Provider. * @throws {@link com.android.server.credentials.NonCredentialProviderCallerException} if the * calling package name is not also listed as a Credential Provider. * @throws {@link IllegalArgumentException} if the calling Credential Provider can not handle * one or more of the Credential Types that are sent for registration. * */ public void registerCredentialDescription( @NonNull RegisterCredentialDescriptionRequest request) { Loading @@ -346,16 +342,12 @@ public final class CredentialManager { } } /** * Unregisters a {@link CredentialDescription} for an actively provisioned {@link Credential} * that has been registered previously. * * * @param request the request data * * @throws {@link UnsupportedOperationException} if the feature has not been enabled. * */ public void unregisterCredentialDescription( @NonNull UnregisterCredentialDescriptionRequest request) { Loading @@ -371,7 +363,6 @@ public final class CredentialManager { } catch (RemoteException e) { e.rethrowFromSystemServer(); } } private static class GetCredentialTransport extends IGetCredentialCallback.Stub { Loading
services/credentials/java/com/android/server/credentials/CredentialManagerService.java +147 −82 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.credentials; import static android.content.Context.CREDENTIAL_SERVICE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.annotation.NonNull; import android.annotation.UserIdInt; Loading Loading @@ -81,17 +82,17 @@ public final class CredentialManagerService private static final String TAG = "CredManSysService"; private static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API = "enable_credential_description_api"; private static final String PERMISSION_DENIED_ERROR = "permission_denied"; private static final String PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR = "Caller is missing WRITE_SECURE_SETTINGS permission"; private final Context mContext; /** * Cache of system service list per user id. */ /** Cache of system service list per user id. */ @GuardedBy("mLock") private final SparseArray<List<CredentialManagerServiceImpl>> mSystemServicesCacheList = new SparseArray<>(); public CredentialManagerService(@NonNull Context context) { super( context, Loading @@ -109,8 +110,10 @@ public final class CredentialManagerService List<CredentialManagerServiceImpl> services = new ArrayList<>(); List<CredentialProviderInfo> credentialProviderInfos = CredentialProviderInfo.getAvailableSystemServices(mContext, resolvedUserId); credentialProviderInfos.forEach(info -> { services.add(new CredentialManagerServiceImpl(this, mLock, resolvedUserId, info)); credentialProviderInfos.forEach( info -> { services.add( new CredentialManagerServiceImpl(this, mLock, resolvedUserId, info)); }); return services; } Loading Loading @@ -174,10 +177,9 @@ public final class CredentialManagerService CredentialManagerServiceImpl serviceToBeRemoved = null; for (CredentialManagerServiceImpl service : services) { if (service != null) { CredentialProviderInfo credentialProviderInfo = service.getCredentialProviderInfo(); ComponentName componentName = credentialProviderInfo.getServiceInfo() .getComponentName(); CredentialProviderInfo credentialProviderInfo = service.getCredentialProviderInfo(); ComponentName componentName = credentialProviderInfo.getServiceInfo().getComponentName(); if (packageName.equals(componentName.getPackageName())) { serviceToBeRemoved = service; removeServiceFromMultiModeSettings(componentName.flattenToString(), userId); Loading @@ -193,7 +195,6 @@ public final class CredentialManagerService // TODO("Iterate over system services and remove if needed") } @GuardedBy("mLock") private List<CredentialManagerServiceImpl> getOrConstructSystemServiceListLock( int resolvedUserId) { Loading @@ -205,6 +206,16 @@ public final class CredentialManagerService return services; } private boolean hasWriteSecureSettingsPermission() { final String permission = android.Manifest.permission.WRITE_SECURE_SETTINGS; final boolean result = mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED; if (!result) { Slog.e(TAG, "Caller does not have WRITE_SECURE_SETTINGS permission."); } return result; } private void runForUser(@NonNull final Consumer<CredentialManagerServiceImpl> c) { final int userId = UserHandle.getCallingUserId(); final long origId = Binder.clearCallingIdentity(); Loading @@ -222,8 +233,7 @@ public final class CredentialManagerService } @GuardedBy("mLock") private List<CredentialManagerServiceImpl> getAllCredentialProviderServicesLocked( int userId) { private List<CredentialManagerServiceImpl> getAllCredentialProviderServicesLocked(int userId) { List<CredentialManagerServiceImpl> concatenatedServices = new ArrayList<>(); List<CredentialManagerServiceImpl> userConfigurableServices = getServiceListForUserLocked(userId); Loading @@ -243,11 +253,13 @@ 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) { List<String> requestOptions, Set<String> activeCredentialContainers) { List<ProviderSession> providerSessions = new ArrayList<>(); // Invoke all services of a user to initiate a provider session for (String packageName : activeCredentialContainers) { providerSessions.add(ProviderRegistryGetSession.createNewSession( providerSessions.add( ProviderRegistryGetSession.createNewSession( mContext, UserHandle.getCallingUserId(), session, Loading @@ -260,16 +272,17 @@ public final class CredentialManagerService @NonNull private Set<String> getFilteredResultFromRegistry(List<CredentialOption> options) { // Session for active/provisioned credential descriptions; CredentialDescriptionRegistry registry = CredentialDescriptionRegistry .forUser(UserHandle.getCallingUserId()); CredentialDescriptionRegistry registry = CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId()); // All requested credential descriptions based on the given request. Set<String> requestedCredentialDescriptions = options.stream().map( getCredentialOption -> getCredentialOption options.stream() .map( getCredentialOption -> getCredentialOption .getCredentialRetrievalData() .getString(CredentialOption .FLATTENED_REQUEST)) .getString(CredentialOption.FLATTENED_REQUEST)) .collect(Collectors.toSet()); // All requested credential descriptions based on the given request. Loading Loading @@ -306,9 +319,13 @@ public final class CredentialManagerService private CallingAppInfo constructCallingAppInfo(String packageName, int userId) { final PackageInfo packageInfo; try { packageInfo = getContext().getPackageManager().getPackageInfoAsUser( packageInfo = getContext() .getPackageManager() .getPackageInfoAsUser( packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES), PackageManager.PackageInfoFlags.of( PackageManager.GET_SIGNING_CERTIFICATES), userId); } catch (PackageManager.NameNotFoundException e) { Log.i(TAG, "Issue while retrieving signatureInfo : " + e.getMessage()); Loading Loading @@ -345,33 +362,46 @@ public final class CredentialManagerService if (isCredentialDescriptionApiEnabled()) { List<CredentialOption> optionsThatRequireActiveCredentials = request.getCredentialOptions().stream() .filter(getCredentialOption -> !TextUtils.isEmpty(getCredentialOption .getCredentialRetrievalData().getString( .filter( getCredentialOption -> !TextUtils.isEmpty( getCredentialOption .getCredentialRetrievalData() .getString( CredentialOption .FLATTENED_REQUEST, null))) .FLATTENED_REQUEST, null))) .toList(); List<CredentialOption> optionsThatDoNotRequireActiveCredentials = request.getCredentialOptions().stream() .filter(getCredentialOption -> TextUtils.isEmpty(getCredentialOption .getCredentialRetrievalData().getString( .filter( getCredentialOption -> TextUtils.isEmpty( getCredentialOption .getCredentialRetrievalData() .getString( CredentialOption .FLATTENED_REQUEST, null))) .FLATTENED_REQUEST, null))) .toList(); List<ProviderSession> sessionsWithoutRemoteService = initiateProviderSessionsWithActiveContainers(session, optionsThatRequireActiveCredentials .stream().map(getCredentialOption -> getCredentialOption.getCredentialRetrievalData() .getString(CredentialOption initiateProviderSessionsWithActiveContainers( session, optionsThatRequireActiveCredentials.stream() .map( getCredentialOption -> getCredentialOption .getCredentialRetrievalData() .getString( CredentialOption .FLATTENED_REQUEST)) .collect(Collectors.toList()), getFilteredResultFromRegistry(optionsThatRequireActiveCredentials)); List<ProviderSession> sessionsWithRemoteService = initiateProviderSessions( List<ProviderSession> sessionsWithRemoteService = initiateProviderSessions( session, optionsThatDoNotRequireActiveCredentials.stream() .map(CredentialOption::getType) Loading @@ -394,7 +424,8 @@ public final class CredentialManagerService if (providerSessions.isEmpty()) { try { callback.onError(GetCredentialException.TYPE_NO_CREDENTIAL, callback.onError( GetCredentialException.TYPE_NO_CREDENTIAL, "No credentials available on this device."); } catch (RemoteException e) { Log.i( Loading Loading @@ -437,7 +468,8 @@ public final class CredentialManagerService if (providerSessions.isEmpty()) { try { callback.onError(CreateCredentialException.TYPE_NO_CREDENTIAL, callback.onError( CreateCredentialException.TYPE_NO_CREDENTIAL, "No credentials available on this device."); } catch (RemoteException e) { Log.i( Loading @@ -460,6 +492,16 @@ public final class CredentialManagerService 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) -> { Loading @@ -482,6 +524,16 @@ public final class CredentialManagerService List<String> providers, int userId, ISetEnabledProvidersCallback callback) { Log.i(TAG, "setEnabledProviders"); 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; } userId = ActivityManager.handleIncomingUser( Binder.getCallingPid(), Loading Loading @@ -550,8 +602,7 @@ public final class CredentialManagerService if (providerSessions.isEmpty()) { try { // TODO("Replace with properly defined error type") callback.onError("UNKNOWN", "No crdentials available on this " + "device"); callback.onError("UNKNOWN", "No crdentials available on this " + "device"); } catch (RemoteException e) { Log.i( TAG, Loading @@ -573,35 +624,46 @@ public final class CredentialManagerService Log.i(TAG, "registerCredentialDescription"); List<CredentialProviderInfo> services = CredentialProviderInfo.getAvailableServices(mContext, UserHandle.getCallingUserId()); CredentialProviderInfo.getAvailableServices( mContext, UserHandle.getCallingUserId()); List<String> providers = services.stream() .map(credentialProviderInfo -> credentialProviderInfo.getServiceInfo().packageName).toList(); List<String> providers = services.stream() .map( credentialProviderInfo -> credentialProviderInfo.getServiceInfo().packageName) .toList(); if (!providers.contains(callingPackage)) { throw new NonCredentialProviderCallerException(callingPackage); } List<CredentialProviderInfo> matchingService = services.stream().filter( List<CredentialProviderInfo> matchingService = services.stream() .filter( credentialProviderInfo -> credentialProviderInfo.getServiceInfo() .packageName.equals(callingPackage)).toList(); credentialProviderInfo .getServiceInfo() .packageName .equals(callingPackage)) .toList(); CredentialProviderInfo credentialProviderInfo = matchingService.get(0); Set<String> supportedTypes = request.getCredentialDescriptions() .stream().map(CredentialDescription::getType).filter( credentialProviderInfo::hasCapability).collect(Collectors.toSet()); Set<String> supportedTypes = request.getCredentialDescriptions().stream() .map(CredentialDescription::getType) .filter(credentialProviderInfo::hasCapability) .collect(Collectors.toSet()); if (supportedTypes.size() != request.getCredentialDescriptions().size()) { throw new IllegalArgumentException("CredentialProvider does not support one or more" throw new IllegalArgumentException( "CredentialProvider does not support one or more" + "of the registered types. Check your XML entry."); } CredentialDescriptionRegistry session = CredentialDescriptionRegistry .forUser(UserHandle.getCallingUserId()); CredentialDescriptionRegistry session = CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId()); session.executeRegisterRequest(request, callingPackage); } Loading @@ -614,19 +676,22 @@ public final class CredentialManagerService ICancellationSignal cancelTransport = CancellationSignal.createTransport(); List<CredentialProviderInfo> services = CredentialProviderInfo.getAvailableServices(mContext, UserHandle.getCallingUserId()); CredentialProviderInfo.getAvailableServices( mContext, UserHandle.getCallingUserId()); List<String> providers = services.stream() .map(credentialProviderInfo -> credentialProviderInfo.getServiceInfo().packageName).toList(); List<String> providers = services.stream() .map( credentialProviderInfo -> credentialProviderInfo.getServiceInfo().packageName) .toList(); if (!providers.contains(callingPackage)) { throw new NonCredentialProviderCallerException(callingPackage); } CredentialDescriptionRegistry session = CredentialDescriptionRegistry .forUser(UserHandle.getCallingUserId()); CredentialDescriptionRegistry session = CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId()); session.executeUnregisterRequest(request, callingPackage); } Loading