Loading core/api/current.txt +3 −2 Original line number Diff line number Diff line Loading @@ -40258,7 +40258,7 @@ package android.service.credentials { } public class BeginGetCredentialOption implements android.os.Parcelable { ctor public BeginGetCredentialOption(@NonNull String, @NonNull android.os.Bundle); ctor public BeginGetCredentialOption(@NonNull String, @NonNull String, @NonNull android.os.Bundle); method public int describeContents(); method @NonNull public android.os.Bundle getCandidateQueryData(); method @NonNull public String getType(); Loading Loading @@ -40341,8 +40341,9 @@ package android.service.credentials { } public class CredentialEntry implements android.os.Parcelable { ctor public CredentialEntry(@NonNull String, @NonNull android.app.slice.Slice); ctor public CredentialEntry(@NonNull android.service.credentials.BeginGetCredentialOption, @NonNull android.app.slice.Slice); method public int describeContents(); method @NonNull public android.service.credentials.BeginGetCredentialOption getBeginGetCredentialOption(); method @NonNull public android.app.slice.Slice getSlice(); method @NonNull public String getType(); method public void writeToParcel(@NonNull android.os.Parcel, int); core/java/android/service/credentials/BeginGetCredentialOption.java +25 −3 Original line number Diff line number Diff line Loading @@ -39,6 +39,11 @@ import com.android.internal.util.Preconditions; */ @SuppressLint("ParcelNotFinal") public class BeginGetCredentialOption implements Parcelable { /** * A unique id associated with this request option. */ @NonNull private final String mId; /** * The requested credential type. Loading @@ -52,6 +57,18 @@ public class BeginGetCredentialOption implements Parcelable { @NonNull private final Bundle mCandidateQueryData; /** * Returns the unique id associated with this request. Providers must pass this id * to the constructor of {@link CredentialEntry} while creating a candidate credential * entry for this request option. * * @hide */ @NonNull public String getId() { return mId; } /** * Returns the requested credential type. */ Loading Loading @@ -80,6 +97,7 @@ public class BeginGetCredentialOption implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString8(mType); dest.writeBundle(mCandidateQueryData); dest.writeString8(mId); } @Override Loading @@ -92,20 +110,22 @@ public class BeginGetCredentialOption implements Parcelable { return "GetCredentialOption {" + "type=" + mType + ", candidateQueryData=" + mCandidateQueryData + ", id=" + mId + "}"; } /** * Constructs a {@link BeginGetCredentialOption}. * * @param id the unique id associated with this option * @param type the requested credential type * @param candidateQueryData the request candidateQueryData * * @throws IllegalArgumentException If type is empty. */ public BeginGetCredentialOption( @NonNull String type, @NonNull String id, @NonNull String type, @NonNull Bundle candidateQueryData) { mId = id; mType = Preconditions.checkStringNotEmpty(type, "type must not be empty"); mCandidateQueryData = requireNonNull( candidateQueryData, "candidateQueryData must not be null"); Loading @@ -114,11 +134,13 @@ public class BeginGetCredentialOption implements Parcelable { private BeginGetCredentialOption(@NonNull Parcel in) { String type = in.readString8(); Bundle candidateQueryData = in.readBundle(); String id = in.readString8(); mType = type; AnnotationValidations.validate(NonNull.class, null, mType); mCandidateQueryData = candidateQueryData; AnnotationValidations.validate(NonNull.class, null, mCandidateQueryData); mId = id; } public static final @NonNull Creator<BeginGetCredentialOption> CREATOR = Loading core/java/android/service/credentials/CredentialEntry.java +64 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package android.service.credentials; import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.PendingIntent; import android.app.slice.Slice; Loading @@ -29,9 +32,11 @@ import android.os.Parcelable; * user. * * <p>If user selects this entry, the corresponding {@link PendingIntent}, * set on the {@code slice} as a {@link androidx.slice.core.SliceAction} will be * invoked to launch activities that require some user engagement before getting * the credential corresponding to this entry, e.g. authentication, confirmation etc. * set on the {@code slice} will be invoked to launch activities that require some user engagement * before getting the credential corresponding to this entry, e.g. authentication, * confirmation etc. The extras associated with the resulting {@link android.app.Activity} will * also contain the complete credential request containing all required parameters. This request * can be retrieved against {@link CredentialProviderService#EXTRA_GET_CREDENTIAL_REQUEST}. * * Once the activity fulfills the required user engagement, the {@link android.app.Activity} * result should be set to {@link android.app.Activity#RESULT_OK}, and the Loading @@ -42,24 +47,69 @@ import android.os.Parcelable; * object passed into the constructor. Any other field will not be parceled through. If the * derived class has custom parceling implementation, this class will not be able to unpack * the parcel without having access to that implementation. * * <p>While creating this entry, providers must set a {@code requestId} to be retrieved * from {@link BeginGetCredentialOption#getId()}, to determine for which request this entry is * being presented to the user. This will ensure that when user selects the entry, the correct * complete request is added to the {@link PendingIntent} mentioned above. */ @SuppressLint("ParcelNotFinal") public class CredentialEntry implements Parcelable { /** The request option that corresponds to this entry. **/ private final @Nullable BeginGetCredentialOption mBeginGetCredentialOption; /** The type of the credential entry to be shown on the UI. */ private final @NonNull String mType; /** The object containing display content to be shown along with this credential entry * on the UI. */ private final @NonNull Slice mSlice; /** * Creates an entry that is associated with a {@link BeginGetCredentialOption} request. * Providers must use this constructor when they extend from {@link CredentialProviderService} * to respond to query phase {@link CredentialProviderService#onBeginGetCredential} * credential retrieval requests. * * @param beginGetCredentialOption the request option for which this credential entry is * being constructed This helps maintain an association, * such that when the user selects this entry, providers * can receive the conmplete corresponding request. * @param slice the slice containing the metadata to be shown on the UI. Must be * constructed through the androidx.credentials jetpack library. */ public CredentialEntry(@NonNull BeginGetCredentialOption beginGetCredentialOption, @NonNull Slice slice) { mBeginGetCredentialOption = requireNonNull(beginGetCredentialOption, "beginGetCredentialOption must not be null"); mType = requireNonNull(mBeginGetCredentialOption.getType(), "type must not be null"); mSlice = requireNonNull(slice, "slice must not be null"); } /** * Creates an entry that is independent of an incoming {@link BeginGetCredentialOption} * request. Providers must use this constructor for constructing entries to be registered * with the framework outside of the span of an API call. * * @param type the type of the credential * @param slice the slice containing the metadata to be shown on the UI. Must be * constructed through the androidx.credentials jetpack library. * * @hide */ // TODO: Unhide this constructor when the registry APIs are stable public CredentialEntry(@NonNull String type, @NonNull Slice slice) { mType = type; mSlice = slice; mBeginGetCredentialOption = null; mType = requireNonNull(type, "type must not be null"); mSlice = requireNonNull(slice, "slice must not be null"); } private CredentialEntry(@NonNull Parcel in) { mType = in.readString8(); mSlice = in.readTypedObject(Slice.CREATOR); mBeginGetCredentialOption = in.readTypedObject(BeginGetCredentialOption.CREATOR); } @NonNull Loading @@ -85,6 +135,15 @@ public class CredentialEntry implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString8(mType); dest.writeTypedObject(mSlice, flags); dest.writeTypedObject(mBeginGetCredentialOption, flags); } /** * Returns the request option for which this credential entry has been constructed. */ @NonNull public BeginGetCredentialOption getBeginGetCredentialOption() { return mBeginGetCredentialOption; } /** Loading services/credentials/java/com/android/server/credentials/ProviderCreateSession.java +1 −1 Original line number Diff line number Diff line Loading @@ -229,7 +229,7 @@ public final class ProviderCreateSession extends ProviderSession< // Populate the save entries for (CreateEntry createEntry : saveEntries) { String entryId = generateEntryId(); String entryId = generateUniqueId(); mUiSaveEntries.put(entryId, createEntry); Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId); uiSaveEntries.add(new Entry(SAVE_ENTRY_KEY, entryId, createEntry.getSlice(), Loading services/credentials/java/com/android/server/credentials/ProviderGetSession.java +35 −26 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; /** * Central provider session that listens for provider callbacks, and maintains provider state. Loading @@ -67,6 +66,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential // Key to be used as an entry key for a credential entry private static final String CREDENTIAL_ENTRY_KEY = "credential_key"; @NonNull private final Map<String, CredentialOption> mBeginGetOptionToCredentialOptionMap; @NonNull private final Map<String, CredentialEntry> mUiCredentialEntries = new HashMap<>(); @NonNull Loading @@ -91,12 +92,16 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential filterOptions(providerInfo.getCapabilities(), getRequestSession.mClientRequest); if (filteredRequest != null) { Map<String, CredentialOption> beginGetOptionToCredentialOptionMap = new HashMap<>(); BeginGetCredentialRequest beginGetCredentialRequest = constructQueryPhaseRequest( filteredRequest, getRequestSession.mClientAppInfo, getRequestSession.mClientRequest.alwaysSendAppInfoToProvider()); getRequestSession.mClientRequest.alwaysSendAppInfoToProvider(), beginGetOptionToCredentialOptionMap); return new ProviderGetSession(context, providerInfo, getRequestSession, userId, remoteCredentialService, beginGetCredentialRequest, filteredRequest, getRequestSession.mClientAppInfo); getRequestSession.mClientAppInfo, beginGetOptionToCredentialOptionMap); } Log.i(TAG, "Unable to create provider session"); return null; Loading @@ -105,15 +110,18 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential private static BeginGetCredentialRequest constructQueryPhaseRequest( android.credentials.GetCredentialRequest filteredRequest, CallingAppInfo callingAppInfo, boolean propagateToProvider) { boolean propagateToProvider, Map<String, CredentialOption> beginGetOptionToCredentialOptionMap ) { BeginGetCredentialRequest.Builder builder = new BeginGetCredentialRequest.Builder(); builder.setBeginGetCredentialOptions( filteredRequest.getCredentialOptions().stream().map( option -> { return new BeginGetCredentialOption( option.getType(), option.getCandidateQueryData()); }).collect(Collectors.toList())); filteredRequest.getCredentialOptions().forEach(option -> { String id = generateUniqueId(); builder.addBeginGetCredentialOption( new BeginGetCredentialOption( id, option.getType(), option.getCandidateQueryData()) ); beginGetOptionToCredentialOptionMap.put(id, option); }); if (propagateToProvider) { builder.setCallingAppInfo(callingAppInfo); } Loading Loading @@ -152,11 +160,13 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential int userId, RemoteCredentialService remoteCredentialService, BeginGetCredentialRequest beginGetRequest, android.credentials.GetCredentialRequest completeGetRequest, CallingAppInfo callingAppInfo) { CallingAppInfo callingAppInfo, Map<String, CredentialOption> beginGetOptionToCredentialOptionMap) { super(context, info, beginGetRequest, callbacks, userId, remoteCredentialService); mCompleteRequest = completeGetRequest; mCallingAppInfo = callingAppInfo; setStatus(Status.PENDING); mBeginGetOptionToCredentialOptionMap = beginGetOptionToCredentialOptionMap; } /** Called when the provider response has been updated by an external source. */ Loading Loading @@ -260,7 +270,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential if (remoteCredentialEntry == null) { return null; } String entryId = generateEntryId(); String entryId = generateUniqueId(); Entry remoteEntry = new Entry(REMOTE_ENTRY_KEY, entryId, remoteCredentialEntry.getSlice()); mUiRemoteEntry = new Pair<>(entryId, remoteCredentialEntry); return remoteEntry; Loading @@ -271,7 +281,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential List<Entry> authenticationUiEntries = new ArrayList<>(); for (Action authenticationAction : authenticationEntries) { String entryId = generateEntryId(); String entryId = generateUniqueId(); mUiAuthenticationEntries.put(entryId, authenticationAction); authenticationUiEntries.add(new Entry( AUTHENTICATION_ACTION_ENTRY_KEY, entryId, Loading @@ -288,7 +298,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential // Populate the credential entries for (CredentialEntry credentialEntry : credentialEntries) { String entryId = generateEntryId(); String entryId = generateUniqueId(); mUiCredentialEntries.put(entryId, credentialEntry); Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId); credentialUiEntries.add(new Entry(CREDENTIAL_ENTRY_KEY, entryId, Loading @@ -298,18 +308,17 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential return credentialUiEntries; } private Intent setUpFillInIntent(String type) { Intent intent = new Intent(); for (CredentialOption option : mCompleteRequest.getCredentialOptions()) { if (option.getType().equals(type)) { intent.putExtra( CredentialProviderService .EXTRA_GET_CREDENTIAL_REQUEST, new GetCredentialRequest(mCallingAppInfo, option)); return intent; private Intent setUpFillInIntent(@Nullable String id) { // TODO: Determine if we should skip this entry if entry id is not set, or is set // but does not resolve to a valid option. For now, not skipping it because // it may be possible that the provider adds their own extras and expects to receive // those and complete the flow. if (id == null || mBeginGetOptionToCredentialOptionMap.get(id) == null) { Log.i(TAG, "Id from Credential Entry does not resolve to a valid option"); } } return intent; return new Intent().putExtra(CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST, new GetCredentialRequest( mCallingAppInfo, mBeginGetOptionToCredentialOptionMap.get(id))); } private Intent setUpFillInIntentForAuthentication() { Loading Loading
core/api/current.txt +3 −2 Original line number Diff line number Diff line Loading @@ -40258,7 +40258,7 @@ package android.service.credentials { } public class BeginGetCredentialOption implements android.os.Parcelable { ctor public BeginGetCredentialOption(@NonNull String, @NonNull android.os.Bundle); ctor public BeginGetCredentialOption(@NonNull String, @NonNull String, @NonNull android.os.Bundle); method public int describeContents(); method @NonNull public android.os.Bundle getCandidateQueryData(); method @NonNull public String getType(); Loading Loading @@ -40341,8 +40341,9 @@ package android.service.credentials { } public class CredentialEntry implements android.os.Parcelable { ctor public CredentialEntry(@NonNull String, @NonNull android.app.slice.Slice); ctor public CredentialEntry(@NonNull android.service.credentials.BeginGetCredentialOption, @NonNull android.app.slice.Slice); method public int describeContents(); method @NonNull public android.service.credentials.BeginGetCredentialOption getBeginGetCredentialOption(); method @NonNull public android.app.slice.Slice getSlice(); method @NonNull public String getType(); method public void writeToParcel(@NonNull android.os.Parcel, int);
core/java/android/service/credentials/BeginGetCredentialOption.java +25 −3 Original line number Diff line number Diff line Loading @@ -39,6 +39,11 @@ import com.android.internal.util.Preconditions; */ @SuppressLint("ParcelNotFinal") public class BeginGetCredentialOption implements Parcelable { /** * A unique id associated with this request option. */ @NonNull private final String mId; /** * The requested credential type. Loading @@ -52,6 +57,18 @@ public class BeginGetCredentialOption implements Parcelable { @NonNull private final Bundle mCandidateQueryData; /** * Returns the unique id associated with this request. Providers must pass this id * to the constructor of {@link CredentialEntry} while creating a candidate credential * entry for this request option. * * @hide */ @NonNull public String getId() { return mId; } /** * Returns the requested credential type. */ Loading Loading @@ -80,6 +97,7 @@ public class BeginGetCredentialOption implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString8(mType); dest.writeBundle(mCandidateQueryData); dest.writeString8(mId); } @Override Loading @@ -92,20 +110,22 @@ public class BeginGetCredentialOption implements Parcelable { return "GetCredentialOption {" + "type=" + mType + ", candidateQueryData=" + mCandidateQueryData + ", id=" + mId + "}"; } /** * Constructs a {@link BeginGetCredentialOption}. * * @param id the unique id associated with this option * @param type the requested credential type * @param candidateQueryData the request candidateQueryData * * @throws IllegalArgumentException If type is empty. */ public BeginGetCredentialOption( @NonNull String type, @NonNull String id, @NonNull String type, @NonNull Bundle candidateQueryData) { mId = id; mType = Preconditions.checkStringNotEmpty(type, "type must not be empty"); mCandidateQueryData = requireNonNull( candidateQueryData, "candidateQueryData must not be null"); Loading @@ -114,11 +134,13 @@ public class BeginGetCredentialOption implements Parcelable { private BeginGetCredentialOption(@NonNull Parcel in) { String type = in.readString8(); Bundle candidateQueryData = in.readBundle(); String id = in.readString8(); mType = type; AnnotationValidations.validate(NonNull.class, null, mType); mCandidateQueryData = candidateQueryData; AnnotationValidations.validate(NonNull.class, null, mCandidateQueryData); mId = id; } public static final @NonNull Creator<BeginGetCredentialOption> CREATOR = Loading
core/java/android/service/credentials/CredentialEntry.java +64 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package android.service.credentials; import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.PendingIntent; import android.app.slice.Slice; Loading @@ -29,9 +32,11 @@ import android.os.Parcelable; * user. * * <p>If user selects this entry, the corresponding {@link PendingIntent}, * set on the {@code slice} as a {@link androidx.slice.core.SliceAction} will be * invoked to launch activities that require some user engagement before getting * the credential corresponding to this entry, e.g. authentication, confirmation etc. * set on the {@code slice} will be invoked to launch activities that require some user engagement * before getting the credential corresponding to this entry, e.g. authentication, * confirmation etc. The extras associated with the resulting {@link android.app.Activity} will * also contain the complete credential request containing all required parameters. This request * can be retrieved against {@link CredentialProviderService#EXTRA_GET_CREDENTIAL_REQUEST}. * * Once the activity fulfills the required user engagement, the {@link android.app.Activity} * result should be set to {@link android.app.Activity#RESULT_OK}, and the Loading @@ -42,24 +47,69 @@ import android.os.Parcelable; * object passed into the constructor. Any other field will not be parceled through. If the * derived class has custom parceling implementation, this class will not be able to unpack * the parcel without having access to that implementation. * * <p>While creating this entry, providers must set a {@code requestId} to be retrieved * from {@link BeginGetCredentialOption#getId()}, to determine for which request this entry is * being presented to the user. This will ensure that when user selects the entry, the correct * complete request is added to the {@link PendingIntent} mentioned above. */ @SuppressLint("ParcelNotFinal") public class CredentialEntry implements Parcelable { /** The request option that corresponds to this entry. **/ private final @Nullable BeginGetCredentialOption mBeginGetCredentialOption; /** The type of the credential entry to be shown on the UI. */ private final @NonNull String mType; /** The object containing display content to be shown along with this credential entry * on the UI. */ private final @NonNull Slice mSlice; /** * Creates an entry that is associated with a {@link BeginGetCredentialOption} request. * Providers must use this constructor when they extend from {@link CredentialProviderService} * to respond to query phase {@link CredentialProviderService#onBeginGetCredential} * credential retrieval requests. * * @param beginGetCredentialOption the request option for which this credential entry is * being constructed This helps maintain an association, * such that when the user selects this entry, providers * can receive the conmplete corresponding request. * @param slice the slice containing the metadata to be shown on the UI. Must be * constructed through the androidx.credentials jetpack library. */ public CredentialEntry(@NonNull BeginGetCredentialOption beginGetCredentialOption, @NonNull Slice slice) { mBeginGetCredentialOption = requireNonNull(beginGetCredentialOption, "beginGetCredentialOption must not be null"); mType = requireNonNull(mBeginGetCredentialOption.getType(), "type must not be null"); mSlice = requireNonNull(slice, "slice must not be null"); } /** * Creates an entry that is independent of an incoming {@link BeginGetCredentialOption} * request. Providers must use this constructor for constructing entries to be registered * with the framework outside of the span of an API call. * * @param type the type of the credential * @param slice the slice containing the metadata to be shown on the UI. Must be * constructed through the androidx.credentials jetpack library. * * @hide */ // TODO: Unhide this constructor when the registry APIs are stable public CredentialEntry(@NonNull String type, @NonNull Slice slice) { mType = type; mSlice = slice; mBeginGetCredentialOption = null; mType = requireNonNull(type, "type must not be null"); mSlice = requireNonNull(slice, "slice must not be null"); } private CredentialEntry(@NonNull Parcel in) { mType = in.readString8(); mSlice = in.readTypedObject(Slice.CREATOR); mBeginGetCredentialOption = in.readTypedObject(BeginGetCredentialOption.CREATOR); } @NonNull Loading @@ -85,6 +135,15 @@ public class CredentialEntry implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString8(mType); dest.writeTypedObject(mSlice, flags); dest.writeTypedObject(mBeginGetCredentialOption, flags); } /** * Returns the request option for which this credential entry has been constructed. */ @NonNull public BeginGetCredentialOption getBeginGetCredentialOption() { return mBeginGetCredentialOption; } /** Loading
services/credentials/java/com/android/server/credentials/ProviderCreateSession.java +1 −1 Original line number Diff line number Diff line Loading @@ -229,7 +229,7 @@ public final class ProviderCreateSession extends ProviderSession< // Populate the save entries for (CreateEntry createEntry : saveEntries) { String entryId = generateEntryId(); String entryId = generateUniqueId(); mUiSaveEntries.put(entryId, createEntry); Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId); uiSaveEntries.add(new Entry(SAVE_ENTRY_KEY, entryId, createEntry.getSlice(), Loading
services/credentials/java/com/android/server/credentials/ProviderGetSession.java +35 −26 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; /** * Central provider session that listens for provider callbacks, and maintains provider state. Loading @@ -67,6 +66,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential // Key to be used as an entry key for a credential entry private static final String CREDENTIAL_ENTRY_KEY = "credential_key"; @NonNull private final Map<String, CredentialOption> mBeginGetOptionToCredentialOptionMap; @NonNull private final Map<String, CredentialEntry> mUiCredentialEntries = new HashMap<>(); @NonNull Loading @@ -91,12 +92,16 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential filterOptions(providerInfo.getCapabilities(), getRequestSession.mClientRequest); if (filteredRequest != null) { Map<String, CredentialOption> beginGetOptionToCredentialOptionMap = new HashMap<>(); BeginGetCredentialRequest beginGetCredentialRequest = constructQueryPhaseRequest( filteredRequest, getRequestSession.mClientAppInfo, getRequestSession.mClientRequest.alwaysSendAppInfoToProvider()); getRequestSession.mClientRequest.alwaysSendAppInfoToProvider(), beginGetOptionToCredentialOptionMap); return new ProviderGetSession(context, providerInfo, getRequestSession, userId, remoteCredentialService, beginGetCredentialRequest, filteredRequest, getRequestSession.mClientAppInfo); getRequestSession.mClientAppInfo, beginGetOptionToCredentialOptionMap); } Log.i(TAG, "Unable to create provider session"); return null; Loading @@ -105,15 +110,18 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential private static BeginGetCredentialRequest constructQueryPhaseRequest( android.credentials.GetCredentialRequest filteredRequest, CallingAppInfo callingAppInfo, boolean propagateToProvider) { boolean propagateToProvider, Map<String, CredentialOption> beginGetOptionToCredentialOptionMap ) { BeginGetCredentialRequest.Builder builder = new BeginGetCredentialRequest.Builder(); builder.setBeginGetCredentialOptions( filteredRequest.getCredentialOptions().stream().map( option -> { return new BeginGetCredentialOption( option.getType(), option.getCandidateQueryData()); }).collect(Collectors.toList())); filteredRequest.getCredentialOptions().forEach(option -> { String id = generateUniqueId(); builder.addBeginGetCredentialOption( new BeginGetCredentialOption( id, option.getType(), option.getCandidateQueryData()) ); beginGetOptionToCredentialOptionMap.put(id, option); }); if (propagateToProvider) { builder.setCallingAppInfo(callingAppInfo); } Loading Loading @@ -152,11 +160,13 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential int userId, RemoteCredentialService remoteCredentialService, BeginGetCredentialRequest beginGetRequest, android.credentials.GetCredentialRequest completeGetRequest, CallingAppInfo callingAppInfo) { CallingAppInfo callingAppInfo, Map<String, CredentialOption> beginGetOptionToCredentialOptionMap) { super(context, info, beginGetRequest, callbacks, userId, remoteCredentialService); mCompleteRequest = completeGetRequest; mCallingAppInfo = callingAppInfo; setStatus(Status.PENDING); mBeginGetOptionToCredentialOptionMap = beginGetOptionToCredentialOptionMap; } /** Called when the provider response has been updated by an external source. */ Loading Loading @@ -260,7 +270,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential if (remoteCredentialEntry == null) { return null; } String entryId = generateEntryId(); String entryId = generateUniqueId(); Entry remoteEntry = new Entry(REMOTE_ENTRY_KEY, entryId, remoteCredentialEntry.getSlice()); mUiRemoteEntry = new Pair<>(entryId, remoteCredentialEntry); return remoteEntry; Loading @@ -271,7 +281,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential List<Entry> authenticationUiEntries = new ArrayList<>(); for (Action authenticationAction : authenticationEntries) { String entryId = generateEntryId(); String entryId = generateUniqueId(); mUiAuthenticationEntries.put(entryId, authenticationAction); authenticationUiEntries.add(new Entry( AUTHENTICATION_ACTION_ENTRY_KEY, entryId, Loading @@ -288,7 +298,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential // Populate the credential entries for (CredentialEntry credentialEntry : credentialEntries) { String entryId = generateEntryId(); String entryId = generateUniqueId(); mUiCredentialEntries.put(entryId, credentialEntry); Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId); credentialUiEntries.add(new Entry(CREDENTIAL_ENTRY_KEY, entryId, Loading @@ -298,18 +308,17 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential return credentialUiEntries; } private Intent setUpFillInIntent(String type) { Intent intent = new Intent(); for (CredentialOption option : mCompleteRequest.getCredentialOptions()) { if (option.getType().equals(type)) { intent.putExtra( CredentialProviderService .EXTRA_GET_CREDENTIAL_REQUEST, new GetCredentialRequest(mCallingAppInfo, option)); return intent; private Intent setUpFillInIntent(@Nullable String id) { // TODO: Determine if we should skip this entry if entry id is not set, or is set // but does not resolve to a valid option. For now, not skipping it because // it may be possible that the provider adds their own extras and expects to receive // those and complete the flow. if (id == null || mBeginGetOptionToCredentialOptionMap.get(id) == null) { Log.i(TAG, "Id from Credential Entry does not resolve to a valid option"); } } return intent; return new Intent().putExtra(CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST, new GetCredentialRequest( mCallingAppInfo, mBeginGetOptionToCredentialOptionMap.get(id))); } private Intent setUpFillInIntentForAuthentication() { Loading