Merge "Handling all UI event codes and exposing new type constant"
This commit is contained in:
@@ -13465,7 +13465,7 @@ package android.credentials {
|
||||
ctor public CreateCredentialException(@NonNull String);
|
||||
method @NonNull public String getType();
|
||||
field @NonNull public static final String TYPE_INTERRUPTED = "android.credentials.CreateCredentialException.TYPE_INTERRUPTED";
|
||||
field @NonNull public static final String TYPE_NO_CREDENTIAL = "android.credentials.CreateCredentialException.TYPE_NO_CREDENTIAL";
|
||||
field @NonNull public static final String TYPE_NO_CREATE_OPTIONS = "android.credentials.CreateCredentialException.TYPE_NO_CREATE_OPTIONS";
|
||||
field @NonNull public static final String TYPE_UNKNOWN = "android.credentials.CreateCredentialException.TYPE_UNKNOWN";
|
||||
field @NonNull public static final String TYPE_USER_CANCELED = "android.credentials.CreateCredentialException.TYPE_USER_CANCELED";
|
||||
}
|
||||
@@ -40242,6 +40242,7 @@ package android.service.credentials {
|
||||
}
|
||||
|
||||
public final class BeginCreateCredentialResponse implements android.os.Parcelable {
|
||||
ctor public BeginCreateCredentialResponse();
|
||||
method public int describeContents();
|
||||
method @NonNull public java.util.List<android.service.credentials.CreateEntry> getCreateEntries();
|
||||
method @Nullable public android.service.credentials.CreateEntry getRemoteCreateEntry();
|
||||
@@ -40283,6 +40284,7 @@ package android.service.credentials {
|
||||
}
|
||||
|
||||
public final class BeginGetCredentialResponse implements android.os.Parcelable {
|
||||
ctor public BeginGetCredentialResponse();
|
||||
method public int describeContents();
|
||||
method @NonNull public java.util.List<android.service.credentials.Action> getActions();
|
||||
method @NonNull public java.util.List<android.service.credentials.Action> getAuthenticationActions();
|
||||
|
||||
@@ -40,13 +40,13 @@ public class CreateCredentialException extends Exception {
|
||||
"android.credentials.CreateCredentialException.TYPE_UNKNOWN";
|
||||
|
||||
/**
|
||||
* The error type value for when no credential is available for the given {@link
|
||||
* CredentialManager#createCredential(CreateCredentialRequest, Activity,
|
||||
* The error type value for when no create options are available from any provider(s),
|
||||
* for the given {@link CredentialManager#createCredential(CreateCredentialRequest, Activity,
|
||||
* CancellationSignal, Executor, OutcomeReceiver)} request.
|
||||
*/
|
||||
@NonNull
|
||||
public static final String TYPE_NO_CREDENTIAL =
|
||||
"android.credentials.CreateCredentialException.TYPE_NO_CREDENTIAL";
|
||||
public static final String TYPE_NO_CREATE_OPTIONS =
|
||||
"android.credentials.CreateCredentialException.TYPE_NO_CREATE_OPTIONS";
|
||||
/**
|
||||
* The error type value for when the user intentionally cancelled the request.
|
||||
*
|
||||
|
||||
@@ -34,6 +34,14 @@ public final class BeginCreateCredentialResponse implements Parcelable {
|
||||
private final @NonNull List<CreateEntry> mCreateEntries;
|
||||
private final @Nullable CreateEntry mRemoteCreateEntry;
|
||||
|
||||
/**
|
||||
* Creates an empty response instance, to be used when there are no {@link CreateEntry}
|
||||
* to return.
|
||||
*/
|
||||
public BeginCreateCredentialResponse() {
|
||||
this(/*createEntries=*/new ArrayList<>(), /*remoteCreateEntry=*/null);
|
||||
}
|
||||
|
||||
private BeginCreateCredentialResponse(@NonNull Parcel in) {
|
||||
List<CreateEntry> createEntries = new ArrayList<>();
|
||||
in.readTypedList(createEntries, CreateEntry.CREATOR);
|
||||
@@ -137,13 +145,8 @@ public final class BeginCreateCredentialResponse implements Parcelable {
|
||||
|
||||
/**
|
||||
* Builds a new instance of {@link BeginCreateCredentialResponse}.
|
||||
*
|
||||
* @throws NullPointerException If {@code createEntries} is null.
|
||||
* @throws IllegalArgumentException If {@code createEntries} is empty.
|
||||
*/
|
||||
public @NonNull BeginCreateCredentialResponse build() {
|
||||
Preconditions.checkCollectionNotEmpty(mCreateEntries, "createEntries must "
|
||||
+ "not be null, or empty");
|
||||
return new BeginCreateCredentialResponse(mCreateEntries, mRemoteCreateEntry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,17 @@ public final class BeginGetCredentialResponse implements Parcelable {
|
||||
/** Remote credential entry to get the response from a different device. */
|
||||
private final @Nullable CredentialEntry mRemoteCredentialEntry;
|
||||
|
||||
/**
|
||||
* Creates an empty response instance, to be used when there are no {@link CredentialEntry},
|
||||
* or {@link Action} to return.
|
||||
*/
|
||||
public BeginGetCredentialResponse() {
|
||||
this(/*credentialEntries=*/new ArrayList<>(),
|
||||
/*authenticationActions=*/new ArrayList<>(),
|
||||
/*actions=*/new ArrayList<>(),
|
||||
/*remoteCredentialEntry=*/null);
|
||||
}
|
||||
|
||||
private BeginGetCredentialResponse(@NonNull List<CredentialEntry> credentialEntries,
|
||||
@NonNull List<Action> authenticationEntries, @NonNull List<Action> actions,
|
||||
@Nullable CredentialEntry remoteCredentialEntry) {
|
||||
@@ -243,16 +254,8 @@ public final class BeginGetCredentialResponse implements Parcelable {
|
||||
|
||||
/**
|
||||
* Builds a {@link BeginGetCredentialResponse} instance.
|
||||
*
|
||||
* @throws IllegalStateException if {@code credentialEntries}, {@code actions}
|
||||
* and {@code remoteCredentialEntry} are all null or empty.
|
||||
*/
|
||||
public @NonNull BeginGetCredentialResponse build() {
|
||||
if (mCredentialEntries.isEmpty() && mActions.isEmpty()
|
||||
&& mRemoteCredentialEntry == null && mAuthenticationEntries.isEmpty()) {
|
||||
throw new IllegalStateException("must set either an authentication, "
|
||||
+ "credential, action or remote entry");
|
||||
}
|
||||
return new BeginGetCredentialResponse(mCredentialEntries, mAuthenticationEntries,
|
||||
mActions, mRemoteCredentialEntry);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
|
||||
if (response != null) {
|
||||
respondToClientWithResponseAndFinish(response);
|
||||
} else {
|
||||
respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREDENTIAL,
|
||||
respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREATE_OPTIONS,
|
||||
"Invalid response");
|
||||
}
|
||||
}
|
||||
@@ -119,6 +119,12 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUiSelectorInvocationFailure() {
|
||||
respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREATE_OPTIONS,
|
||||
"No create options available.");
|
||||
}
|
||||
|
||||
private void respondToClientWithResponseAndFinish(CreateCredentialResponse response) {
|
||||
Log.i(TAG, "respondToClientWithResponseAndFinish");
|
||||
if (isSessionCancelled()) {
|
||||
@@ -166,8 +172,8 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
|
||||
Log.i(TAG, "in onProviderStatusChanged - isUiInvocationNeeded");
|
||||
getProviderDataAndInitiateUi();
|
||||
} else {
|
||||
respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREDENTIAL,
|
||||
"No credentials available");
|
||||
respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREATE_OPTIONS,
|
||||
"No create options available.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,8 +472,8 @@ public final class CredentialManagerService
|
||||
if (providerSessions.isEmpty()) {
|
||||
try {
|
||||
callback.onError(
|
||||
CreateCredentialException.TYPE_NO_CREDENTIAL,
|
||||
"No credentials available on this device.");
|
||||
CreateCredentialException.TYPE_NO_CREATE_OPTIONS,
|
||||
"No create options available.");
|
||||
} catch (RemoteException e) {
|
||||
Log.i(
|
||||
TAG,
|
||||
|
||||
@@ -56,19 +56,29 @@ public class CredentialManagerUi {
|
||||
};
|
||||
|
||||
private void handleUiResult(int resultCode, Bundle resultData) {
|
||||
if (resultCode == UserSelectionDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION) {
|
||||
UserSelectionDialogResult selection = UserSelectionDialogResult
|
||||
.fromResultData(resultData);
|
||||
if (selection != null) {
|
||||
mCallbacks.onUiSelection(selection);
|
||||
} else {
|
||||
Slog.i(TAG, "No selection found in UI result");
|
||||
}
|
||||
} else if (resultCode == UserSelectionDialogResult.RESULT_CODE_DIALOG_USER_CANCELED) {
|
||||
mCallbacks.onUiCancellation(/* isUserCancellation= */ true);
|
||||
} else if (resultCode
|
||||
== UserSelectionDialogResult.RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS) {
|
||||
mCallbacks.onUiCancellation(/* isUserCancellation= */ false);
|
||||
switch (resultCode) {
|
||||
case UserSelectionDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION:
|
||||
UserSelectionDialogResult selection = UserSelectionDialogResult
|
||||
.fromResultData(resultData);
|
||||
if (selection != null) {
|
||||
mCallbacks.onUiSelection(selection);
|
||||
} else {
|
||||
Slog.i(TAG, "No selection found in UI result");
|
||||
}
|
||||
break;
|
||||
case UserSelectionDialogResult.RESULT_CODE_DIALOG_USER_CANCELED:
|
||||
mCallbacks.onUiCancellation(/* isUserCancellation= */ true);
|
||||
break;
|
||||
case UserSelectionDialogResult.RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS:
|
||||
mCallbacks.onUiCancellation(/* isUserCancellation= */ false);
|
||||
break;
|
||||
case UserSelectionDialogResult.RESULT_CODE_DATA_PARSING_FAILURE:
|
||||
mCallbacks.onUiSelectorInvocationFailure();
|
||||
break;
|
||||
default:
|
||||
Slog.i(TAG, "Unknown error code returned from the UI");
|
||||
mCallbacks.onUiSelectorInvocationFailure();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +90,9 @@ public class CredentialManagerUi {
|
||||
void onUiSelection(UserSelectionDialogResult selection);
|
||||
/** Called when the UI is canceled without a successful provider result. */
|
||||
void onUiCancellation(boolean isUserCancellation);
|
||||
|
||||
/** Called when the selector UI fails to come up (mostly due to parsing issue today). */
|
||||
void onUiSelectorInvocationFailure();
|
||||
}
|
||||
public CredentialManagerUi(Context context, int userId,
|
||||
CredentialManagerUiCallback callbacks) {
|
||||
|
||||
@@ -146,6 +146,12 @@ public final class GetRequestSession extends RequestSession<GetCredentialRequest
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUiSelectorInvocationFailure() {
|
||||
respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
|
||||
"No credentials to show on the selector.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderStatusChanged(ProviderSession.Status status,
|
||||
ComponentName componentName) {
|
||||
|
||||
@@ -168,7 +168,16 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
private void onUpdateResponse(BeginCreateCredentialResponse response) {
|
||||
Log.i(TAG, "updateResponse with save entries");
|
||||
mProviderResponse = response;
|
||||
updateStatusAndInvokeCallback(Status.SAVE_ENTRIES_RECEIVED);
|
||||
if (isEmptyResponse(response)) {
|
||||
updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE);
|
||||
} else {
|
||||
updateStatusAndInvokeCallback(Status.SAVE_ENTRIES_RECEIVED);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEmptyResponse(BeginCreateCredentialResponse response) {
|
||||
return (response.getCreateEntries() == null || response.getCreateEntries().isEmpty())
|
||||
&& response.getRemoteCreateEntry() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -294,7 +303,7 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
ProviderPendingIntentResponse pendingIntentResponse) {
|
||||
if (pendingIntentResponse == null) {
|
||||
Log.i(TAG, "pendingIntentResponse is null");
|
||||
return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREDENTIAL);
|
||||
return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREATE_OPTIONS);
|
||||
}
|
||||
if (PendingIntentResultHandler.isValidResponse(pendingIntentResponse)) {
|
||||
CreateCredentialException exception = PendingIntentResultHandler
|
||||
@@ -306,7 +315,7 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
} else if (PendingIntentResultHandler.isCancelledResponse(pendingIntentResponse)) {
|
||||
return new CreateCredentialException(CreateCredentialException.TYPE_USER_CANCELED);
|
||||
} else {
|
||||
return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREDENTIAL);
|
||||
return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREATE_OPTIONS);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,6 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
Log.i(TAG, "Unable to create provider session");
|
||||
return null;
|
||||
}
|
||||
|
||||
private static BeginGetCredentialRequest constructQueryPhaseRequest(
|
||||
android.credentials.GetCredentialRequest filteredRequest,
|
||||
CallingAppInfo callingAppInfo,
|
||||
@@ -445,7 +444,22 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
/** Updates the response being maintained in state by this provider session. */
|
||||
private void onUpdateResponse(BeginGetCredentialResponse response) {
|
||||
mProviderResponse = response;
|
||||
updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
|
||||
if (isEmptyResponse(response)) {
|
||||
updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE);
|
||||
} else {
|
||||
updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEmptyResponse(BeginGetCredentialResponse response) {
|
||||
if ((response.getCredentialEntries() == null || response.getCredentialEntries().isEmpty())
|
||||
&& (response.getAuthenticationActions() == null || response
|
||||
.getAuthenticationActions().isEmpty())
|
||||
&& (response.getActions() == null || response.getActions().isEmpty())
|
||||
&& response.getRemoteCredentialEntry() == null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void onUpdateEmptyResponse() {
|
||||
|
||||
@@ -133,7 +133,7 @@ public abstract class ProviderSession<T, R>
|
||||
PENDING_INTENT_INVOKED,
|
||||
CREDENTIAL_RECEIVED_FROM_SELECTION,
|
||||
SAVE_ENTRIES_RECEIVED, CANCELED,
|
||||
NO_CREDENTIALS, COMPLETE
|
||||
NO_CREDENTIALS, EMPTY_RESPONSE, COMPLETE
|
||||
}
|
||||
|
||||
/** Converts exception to a provider session status. */
|
||||
|
||||
@@ -144,6 +144,11 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
finishSession(/*propagateCancellation=*/false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUiSelectorInvocationFailure() {
|
||||
Log.i(TAG, "onUiSelectorInvocationFailure");
|
||||
}
|
||||
|
||||
protected void finishSession(boolean propagateCancellation) {
|
||||
Log.i(TAG, "finishing session");
|
||||
if (propagateCancellation) {
|
||||
|
||||
Reference in New Issue
Block a user