Merge "Maintain auth entry status across providers" into udc-dev am: d77e0d9929
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21559288 Change-Id: I589a8033ad6ee5783af1c924efa893e65ebef52b Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -44,7 +44,6 @@ public final class GetRequestSession extends RequestSession<GetCredentialRequest
|
||||
IGetCredentialCallback>
|
||||
implements ProviderSession.ProviderInternalCallback<GetCredentialResponse> {
|
||||
private static final String TAG = "GetRequestSession";
|
||||
|
||||
public GetRequestSession(Context context, int userId, int callingUid,
|
||||
IGetCredentialCallback callback, GetCredentialRequest request,
|
||||
CallingAppInfo callingAppInfo, CancellationSignal cancellationSignal) {
|
||||
@@ -173,6 +172,12 @@ public final class GetRequestSession extends RequestSession<GetCredentialRequest
|
||||
public void onProviderStatusChanged(ProviderSession.Status status,
|
||||
ComponentName componentName) {
|
||||
Log.i(TAG, "in onStatusChanged with status: " + status);
|
||||
// Auth entry was selected, and it did not have any underlying credentials
|
||||
if (status == ProviderSession.Status.NO_CREDENTIALS_FROM_AUTH_ENTRY) {
|
||||
handleEmptyAuthenticationSelection(componentName);
|
||||
return;
|
||||
}
|
||||
// For any other status, we check if all providers are done and then invoke UI if needed
|
||||
if (!isAnyProviderPending()) {
|
||||
// If all provider responses have been received, we can either need the UI,
|
||||
// or we need to respond with error. The only other case is the entry being
|
||||
@@ -186,4 +191,34 @@ public final class GetRequestSession extends RequestSession<GetCredentialRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEmptyAuthenticationSelection(ComponentName componentName) {
|
||||
// Update auth entry statuses across different provider sessions
|
||||
mProviders.keySet().forEach(key -> {
|
||||
ProviderGetSession session = (ProviderGetSession) mProviders.get(key);
|
||||
if (!session.mComponentName.equals(componentName)) {
|
||||
session.updateAuthEntriesStatusFromAnotherSession();
|
||||
}
|
||||
});
|
||||
|
||||
// Invoke UI since it needs to show a snackbar if last auth entry, or a status on each
|
||||
// auth entries along with other valid entries
|
||||
getProviderDataAndInitiateUi();
|
||||
|
||||
// Respond to client if all auth entries are empty and nothing else to show on the UI
|
||||
if (providerDataContainsEmptyAuthEntriesOnly()) {
|
||||
respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
|
||||
"No credentials available");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean providerDataContainsEmptyAuthEntriesOnly() {
|
||||
for (String key : mProviders.keySet()) {
|
||||
ProviderGetSession session = (ProviderGetSession) mProviders.get(key);
|
||||
if (!session.containsEmptyAuthEntriesOnly()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,13 +241,14 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
if (additionalContentReceived) {
|
||||
Log.i(TAG, "Additional content received - removing authentication entry");
|
||||
mProviderResponseDataHandler.removeAuthenticationAction(entryKey);
|
||||
if (!mProviderResponseDataHandler.isEmptyResponse()) {
|
||||
updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "Additional content not received");
|
||||
mProviderResponseDataHandler
|
||||
.updateAuthEntryWithNoCredentialsReceived(entryKey);
|
||||
}
|
||||
if (!mProviderResponseDataHandler.isEmptyResponse()) {
|
||||
updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
|
||||
updateStatusAndInvokeCallback(Status.NO_CREDENTIALS_FROM_AUTH_ENTRY);
|
||||
}
|
||||
break;
|
||||
case REMOTE_ENTRY_KEY:
|
||||
@@ -456,6 +457,27 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
GetCredentialException.TYPE_UNKNOWN, null);
|
||||
}
|
||||
|
||||
/** Update auth entries status based on an auth entry selected from a different session. */
|
||||
public void updateAuthEntriesStatusFromAnotherSession() {
|
||||
// Pass null for entryKey if the auth entry selected belongs to a different session
|
||||
mProviderResponseDataHandler.updateAuthEntryWithNoCredentialsReceived(/*entryKey=*/null);
|
||||
}
|
||||
|
||||
/** Returns true if the provider response contains empty auth entries only, false otherwise. **/
|
||||
public boolean containsEmptyAuthEntriesOnly() {
|
||||
// We do not consider action entries here because if actions are the only entries,
|
||||
// we don't show the UI
|
||||
return mProviderResponseDataHandler.mUiCredentialEntries.isEmpty()
|
||||
&& mProviderResponseDataHandler.mUiRemoteEntry == null
|
||||
&& mProviderResponseDataHandler.mUiAuthenticationEntries
|
||||
.values().stream().allMatch(
|
||||
e -> e.second.getStatus() == AuthenticationEntry
|
||||
.STATUS_UNLOCKED_BUT_EMPTY_LESS_RECENT
|
||||
|| e.second.getStatus()
|
||||
== AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT
|
||||
);
|
||||
}
|
||||
|
||||
private class ProviderResponseDataHandler {
|
||||
private final ComponentName mExpectedRemoteEntryProviderService;
|
||||
@NonNull
|
||||
@@ -610,7 +632,12 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
? null : mUiCredentialEntries.get(entryKey).first;
|
||||
}
|
||||
|
||||
public void updateAuthEntryWithNoCredentialsReceived(String entryKey) {
|
||||
public void updateAuthEntryWithNoCredentialsReceived(@Nullable String entryKey) {
|
||||
if (entryKey == null) {
|
||||
// Auth entry from a different provider was selected by the user.
|
||||
updatePreviousMostRecentAuthEntry();
|
||||
return;
|
||||
}
|
||||
updatePreviousMostRecentAuthEntry();
|
||||
updateMostRecentAuthEntry(entryKey);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,8 @@ public abstract class ProviderSession<T, R>
|
||||
* on the credMan UI.
|
||||
*/
|
||||
public static boolean isUiInvokingStatus(Status status) {
|
||||
return status == Status.CREDENTIALS_RECEIVED || status == Status.SAVE_ENTRIES_RECEIVED;
|
||||
return status == Status.CREDENTIALS_RECEIVED || status == Status.SAVE_ENTRIES_RECEIVED
|
||||
|| status == Status.NO_CREDENTIALS_FROM_AUTH_ENTRY;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +141,7 @@ public abstract class ProviderSession<T, R>
|
||||
PENDING_INTENT_INVOKED,
|
||||
CREDENTIAL_RECEIVED_FROM_SELECTION,
|
||||
SAVE_ENTRIES_RECEIVED, CANCELED,
|
||||
NO_CREDENTIALS, EMPTY_RESPONSE, COMPLETE
|
||||
NO_CREDENTIALS, EMPTY_RESPONSE, NO_CREDENTIALS_FROM_AUTH_ENTRY, COMPLETE
|
||||
}
|
||||
|
||||
/** Converts exception to a provider session status. */
|
||||
|
||||
@@ -216,7 +216,7 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
* Returns true if at least one provider is ready for UI invocation, and no
|
||||
* provider is pending a response.
|
||||
*/
|
||||
boolean isUiInvocationNeeded() {
|
||||
protected boolean isUiInvocationNeeded() {
|
||||
for (ProviderSession session : mProviders.values()) {
|
||||
if (ProviderSession.isUiInvokingStatus(session.getStatus())) {
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user