Loading core/java/android/credentials/ui/Constants.java +6 −3 Original line number Diff line number Diff line Loading @@ -24,9 +24,12 @@ package android.credentials.ui; public class Constants { /** * The intent extra key for the {@code ResultReceiver} object when launching the UX * activities. * The intent extra key for the {@code ResultReceiver} object when launching the UX activities. */ public static final String EXTRA_RESULT_RECEIVER = "android.credentials.ui.extra.RESULT_RECEIVER"; /** The intent action for when the enabled Credential Manager providers has been updated. */ public static final String CREDMAN_ENABLED_PROVIDERS_UPDATED = "android.credentials.ui.action.CREDMAN_ENABLED_PROVIDERS_UPDATED"; } core/java/android/credentials/ui/IntentFactory.java +34 −11 Original line number Diff line number Diff line Loading @@ -39,14 +39,19 @@ public class IntentFactory { public static Intent createCredentialSelectorIntent( @NonNull RequestInfo requestInfo, @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling. @NonNull ArrayList<ProviderData> enabledProviderDataList, @NonNull ArrayList<ProviderData> enabledProviderDataList, @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling. @NonNull ArrayList<DisabledProviderData> disabledProviderDataList, @NonNull ArrayList<DisabledProviderData> disabledProviderDataList, @NonNull ResultReceiver resultReceiver) { Intent intent = new Intent(); ComponentName componentName = ComponentName.unflattenFromString( Resources.getSystem().getString( com.android.internal.R.string.config_credentialManagerDialogComponent)); ComponentName componentName = ComponentName.unflattenFromString( Resources.getSystem() .getString( com.android.internal.R.string .config_credentialManagerDialogComponent)); intent.setComponent(componentName); intent.putParcelableArrayListExtra( Loading @@ -54,16 +59,34 @@ public class IntentFactory { intent.putParcelableArrayListExtra( ProviderData.EXTRA_DISABLED_PROVIDER_DATA_LIST, disabledProviderDataList); intent.putExtra(RequestInfo.EXTRA_REQUEST_INFO, requestInfo); intent.putExtra(Constants.EXTRA_RESULT_RECEIVER, toIpcFriendlyResultReceiver(resultReceiver)); intent.putExtra( Constants.EXTRA_RESULT_RECEIVER, toIpcFriendlyResultReceiver(resultReceiver)); return intent; } /** * Notify the UI that providers have been enabled/disabled. * * @hide */ @NonNull public static Intent createProviderUpdateIntent() { Intent intent = new Intent(); ComponentName componentName = ComponentName.unflattenFromString( Resources.getSystem() .getString( com.android.internal.R.string .config_credentialManagerDialogComponent)); intent.setComponent(componentName); intent.setAction(Constants.CREDMAN_ENABLED_PROVIDERS_UPDATED); return intent; } /** * Convert an instance of a "locally-defined" ResultReceiver to an instance of * {@link android.os.ResultReceiver} itself, which the receiving process will be able to * unmarshall. * Convert an instance of a "locally-defined" ResultReceiver to an instance of {@link * android.os.ResultReceiver} itself, which the receiving process will be able to unmarshall. */ private static <T extends ResultReceiver> ResultReceiver toIpcFriendlyResultReceiver( T resultReceiver) { Loading services/credentials/java/com/android/server/credentials/CredentialManagerService.java +57 −40 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.credentials.IGetCredentialCallback; import android.credentials.IListEnabledProvidersCallback; import android.credentials.ISetEnabledProvidersCallback; import android.credentials.ListEnabledProvidersResponse; import android.credentials.ui.IntentFactory; import android.os.Binder; import android.os.CancellationSignal; import android.os.ICancellationSignal; Loading Loading @@ -115,9 +116,8 @@ public final class CredentialManagerService continue; } try { serviceList.add(new CredentialManagerServiceImpl(this, mLock, resolvedUserId, serviceName)); serviceList.add( new CredentialManagerServiceImpl(this, mLock, resolvedUserId, serviceName)); } catch (PackageManager.NameNotFoundException | SecurityException e) { Log.i(TAG, "Unable to add serviceInfo : " + e.getMessage()); } Loading Loading @@ -175,10 +175,12 @@ public final class CredentialManagerService RequestSession session, List<String> requestOptions) { List<ProviderSession> providerSessions = new ArrayList<>(); // Invoke all services of a user to initiate a provider session runForUser((service) -> { runForUser( (service) -> { synchronized (mLock) { ProviderSession providerSession = service .initiateProviderSessionForRequestLocked(session, requestOptions); ProviderSession providerSession = service.initiateProviderSessionForRequestLocked( session, requestOptions); if (providerSession != null) { providerSessions.add(providerSession); } Loading Loading @@ -208,25 +210,33 @@ public final class CredentialManagerService // Initiate all provider sessions List<ProviderSession> providerSessions = initiateProviderSessions(session, request.getGetCredentialOptions() .stream().map(GetCredentialOption::getType) initiateProviderSessions( session, request.getGetCredentialOptions().stream() .map(GetCredentialOption::getType) .collect(Collectors.toList())); if (providerSessions.isEmpty()) { try { // TODO("Replace with properly defined error type") callback.onError("unknown_type", "No providers available to fulfill request."); callback.onError("unknown_type", "No providers available to fulfill request."); } catch (RemoteException e) { Log.i(TAG, "Issue invoking onError on IGetCredentialCallback " + "callback: " + e.getMessage()); Log.i( TAG, "Issue invoking onError on IGetCredentialCallback " + "callback: " + e.getMessage()); } } // Iterate over all provider sessions and invoke the request providerSessions.forEach(providerGetSession -> { providerGetSession.getRemoteCredentialService().onBeginGetCredential( (BeginGetCredentialRequest) providerGetSession.getProviderRequest(), providerSessions.forEach( providerGetSession -> { providerGetSession .getRemoteCredentialService() .onBeginGetCredential( (BeginGetCredentialRequest) providerGetSession.getProviderRequest(), /* callback= */ providerGetSession); }); return cancelTransport; Loading Loading @@ -257,11 +267,13 @@ public final class CredentialManagerService if (providerSessions.isEmpty()) { try { // TODO("Replace with properly defined error type") callback.onError("unknown_type", "No providers available to fulfill request."); callback.onError("unknown_type", "No providers available to fulfill request."); } catch (RemoteException e) { Log.i(TAG, "Issue invoking onError on ICreateCredentialCallback " + "callback: " + e.getMessage()); Log.i( TAG, "Issue invoking onError on ICreateCredentialCallback " + "callback: " + e.getMessage()); } } Loading @@ -288,8 +300,7 @@ public final class CredentialManagerService List<String> enabledProviders = new ArrayList<>(); runForUser( (service) -> { enabledProviders.add( service.getComponentName().flattenToString()); enabledProviders.add(service.getComponentName().flattenToString()); }); // Call the callback. Loading Loading @@ -331,7 +342,7 @@ public final class CredentialManagerService "Failed to store setting containing enabled providers"); } catch (RemoteException e) { Log.i(TAG, "Issue with invoking error response: " + e.getMessage()); // TODO: Propagate failure return; } } Loading @@ -342,11 +353,16 @@ public final class CredentialManagerService Log.i(TAG, "Issue with invoking response: " + e.getMessage()); // TODO: Propagate failure } // Send an intent to the UI that we have new enabled providers. getContext().sendBroadcast(IntentFactory.createProviderUpdateIntent()); } @Override public ICancellationSignal clearCredentialState(ClearCredentialStateRequest request, IClearCredentialStateCallback callback, String callingPackage) { public ICancellationSignal clearCredentialState( ClearCredentialStateRequest request, IClearCredentialStateCallback callback, String callingPackage) { Log.i(TAG, "starting clearCredentialState with callingPackage: " + callingPackage); // TODO : Implement cancellation ICancellationSignal cancelTransport = CancellationSignal.createTransport(); Loading @@ -362,17 +378,18 @@ public final class CredentialManagerService // Initiate all provider sessions // TODO: Determine if provider needs to have clear capability in their manifest List<ProviderSession> providerSessions = initiateProviderSessions(session, List.of()); List<ProviderSession> providerSessions = initiateProviderSessions(session, List.of()); if (providerSessions.isEmpty()) { try { // TODO("Replace with properly defined error type") callback.onError("unknown_type", "No providers available to fulfill request."); callback.onError("unknown_type", "No providers available to fulfill request."); } catch (RemoteException e) { Log.i(TAG, "Issue invoking onError on IClearCredentialStateCallback " + "callback: " + e.getMessage()); Log.i( TAG, "Issue invoking onError on IClearCredentialStateCallback " + "callback: " + e.getMessage()); } } Loading Loading
core/java/android/credentials/ui/Constants.java +6 −3 Original line number Diff line number Diff line Loading @@ -24,9 +24,12 @@ package android.credentials.ui; public class Constants { /** * The intent extra key for the {@code ResultReceiver} object when launching the UX * activities. * The intent extra key for the {@code ResultReceiver} object when launching the UX activities. */ public static final String EXTRA_RESULT_RECEIVER = "android.credentials.ui.extra.RESULT_RECEIVER"; /** The intent action for when the enabled Credential Manager providers has been updated. */ public static final String CREDMAN_ENABLED_PROVIDERS_UPDATED = "android.credentials.ui.action.CREDMAN_ENABLED_PROVIDERS_UPDATED"; }
core/java/android/credentials/ui/IntentFactory.java +34 −11 Original line number Diff line number Diff line Loading @@ -39,14 +39,19 @@ public class IntentFactory { public static Intent createCredentialSelectorIntent( @NonNull RequestInfo requestInfo, @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling. @NonNull ArrayList<ProviderData> enabledProviderDataList, @NonNull ArrayList<ProviderData> enabledProviderDataList, @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling. @NonNull ArrayList<DisabledProviderData> disabledProviderDataList, @NonNull ArrayList<DisabledProviderData> disabledProviderDataList, @NonNull ResultReceiver resultReceiver) { Intent intent = new Intent(); ComponentName componentName = ComponentName.unflattenFromString( Resources.getSystem().getString( com.android.internal.R.string.config_credentialManagerDialogComponent)); ComponentName componentName = ComponentName.unflattenFromString( Resources.getSystem() .getString( com.android.internal.R.string .config_credentialManagerDialogComponent)); intent.setComponent(componentName); intent.putParcelableArrayListExtra( Loading @@ -54,16 +59,34 @@ public class IntentFactory { intent.putParcelableArrayListExtra( ProviderData.EXTRA_DISABLED_PROVIDER_DATA_LIST, disabledProviderDataList); intent.putExtra(RequestInfo.EXTRA_REQUEST_INFO, requestInfo); intent.putExtra(Constants.EXTRA_RESULT_RECEIVER, toIpcFriendlyResultReceiver(resultReceiver)); intent.putExtra( Constants.EXTRA_RESULT_RECEIVER, toIpcFriendlyResultReceiver(resultReceiver)); return intent; } /** * Notify the UI that providers have been enabled/disabled. * * @hide */ @NonNull public static Intent createProviderUpdateIntent() { Intent intent = new Intent(); ComponentName componentName = ComponentName.unflattenFromString( Resources.getSystem() .getString( com.android.internal.R.string .config_credentialManagerDialogComponent)); intent.setComponent(componentName); intent.setAction(Constants.CREDMAN_ENABLED_PROVIDERS_UPDATED); return intent; } /** * Convert an instance of a "locally-defined" ResultReceiver to an instance of * {@link android.os.ResultReceiver} itself, which the receiving process will be able to * unmarshall. * Convert an instance of a "locally-defined" ResultReceiver to an instance of {@link * android.os.ResultReceiver} itself, which the receiving process will be able to unmarshall. */ private static <T extends ResultReceiver> ResultReceiver toIpcFriendlyResultReceiver( T resultReceiver) { Loading
services/credentials/java/com/android/server/credentials/CredentialManagerService.java +57 −40 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.credentials.IGetCredentialCallback; import android.credentials.IListEnabledProvidersCallback; import android.credentials.ISetEnabledProvidersCallback; import android.credentials.ListEnabledProvidersResponse; import android.credentials.ui.IntentFactory; import android.os.Binder; import android.os.CancellationSignal; import android.os.ICancellationSignal; Loading Loading @@ -115,9 +116,8 @@ public final class CredentialManagerService continue; } try { serviceList.add(new CredentialManagerServiceImpl(this, mLock, resolvedUserId, serviceName)); serviceList.add( new CredentialManagerServiceImpl(this, mLock, resolvedUserId, serviceName)); } catch (PackageManager.NameNotFoundException | SecurityException e) { Log.i(TAG, "Unable to add serviceInfo : " + e.getMessage()); } Loading Loading @@ -175,10 +175,12 @@ public final class CredentialManagerService RequestSession session, List<String> requestOptions) { List<ProviderSession> providerSessions = new ArrayList<>(); // Invoke all services of a user to initiate a provider session runForUser((service) -> { runForUser( (service) -> { synchronized (mLock) { ProviderSession providerSession = service .initiateProviderSessionForRequestLocked(session, requestOptions); ProviderSession providerSession = service.initiateProviderSessionForRequestLocked( session, requestOptions); if (providerSession != null) { providerSessions.add(providerSession); } Loading Loading @@ -208,25 +210,33 @@ public final class CredentialManagerService // Initiate all provider sessions List<ProviderSession> providerSessions = initiateProviderSessions(session, request.getGetCredentialOptions() .stream().map(GetCredentialOption::getType) initiateProviderSessions( session, request.getGetCredentialOptions().stream() .map(GetCredentialOption::getType) .collect(Collectors.toList())); if (providerSessions.isEmpty()) { try { // TODO("Replace with properly defined error type") callback.onError("unknown_type", "No providers available to fulfill request."); callback.onError("unknown_type", "No providers available to fulfill request."); } catch (RemoteException e) { Log.i(TAG, "Issue invoking onError on IGetCredentialCallback " + "callback: " + e.getMessage()); Log.i( TAG, "Issue invoking onError on IGetCredentialCallback " + "callback: " + e.getMessage()); } } // Iterate over all provider sessions and invoke the request providerSessions.forEach(providerGetSession -> { providerGetSession.getRemoteCredentialService().onBeginGetCredential( (BeginGetCredentialRequest) providerGetSession.getProviderRequest(), providerSessions.forEach( providerGetSession -> { providerGetSession .getRemoteCredentialService() .onBeginGetCredential( (BeginGetCredentialRequest) providerGetSession.getProviderRequest(), /* callback= */ providerGetSession); }); return cancelTransport; Loading Loading @@ -257,11 +267,13 @@ public final class CredentialManagerService if (providerSessions.isEmpty()) { try { // TODO("Replace with properly defined error type") callback.onError("unknown_type", "No providers available to fulfill request."); callback.onError("unknown_type", "No providers available to fulfill request."); } catch (RemoteException e) { Log.i(TAG, "Issue invoking onError on ICreateCredentialCallback " + "callback: " + e.getMessage()); Log.i( TAG, "Issue invoking onError on ICreateCredentialCallback " + "callback: " + e.getMessage()); } } Loading @@ -288,8 +300,7 @@ public final class CredentialManagerService List<String> enabledProviders = new ArrayList<>(); runForUser( (service) -> { enabledProviders.add( service.getComponentName().flattenToString()); enabledProviders.add(service.getComponentName().flattenToString()); }); // Call the callback. Loading Loading @@ -331,7 +342,7 @@ public final class CredentialManagerService "Failed to store setting containing enabled providers"); } catch (RemoteException e) { Log.i(TAG, "Issue with invoking error response: " + e.getMessage()); // TODO: Propagate failure return; } } Loading @@ -342,11 +353,16 @@ public final class CredentialManagerService Log.i(TAG, "Issue with invoking response: " + e.getMessage()); // TODO: Propagate failure } // Send an intent to the UI that we have new enabled providers. getContext().sendBroadcast(IntentFactory.createProviderUpdateIntent()); } @Override public ICancellationSignal clearCredentialState(ClearCredentialStateRequest request, IClearCredentialStateCallback callback, String callingPackage) { public ICancellationSignal clearCredentialState( ClearCredentialStateRequest request, IClearCredentialStateCallback callback, String callingPackage) { Log.i(TAG, "starting clearCredentialState with callingPackage: " + callingPackage); // TODO : Implement cancellation ICancellationSignal cancelTransport = CancellationSignal.createTransport(); Loading @@ -362,17 +378,18 @@ public final class CredentialManagerService // Initiate all provider sessions // TODO: Determine if provider needs to have clear capability in their manifest List<ProviderSession> providerSessions = initiateProviderSessions(session, List.of()); List<ProviderSession> providerSessions = initiateProviderSessions(session, List.of()); if (providerSessions.isEmpty()) { try { // TODO("Replace with properly defined error type") callback.onError("unknown_type", "No providers available to fulfill request."); callback.onError("unknown_type", "No providers available to fulfill request."); } catch (RemoteException e) { Log.i(TAG, "Issue invoking onError on IClearCredentialStateCallback " + "callback: " + e.getMessage()); Log.i( TAG, "Issue invoking onError on IClearCredentialStateCallback " + "callback: " + e.getMessage()); } } Loading