diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java index ee63bda8bdc22..3245c914b2b83 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java @@ -19,6 +19,7 @@ package com.android.server.credentials; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.credentials.CreateCredentialException; @@ -56,14 +57,11 @@ public final class ProviderCreateSession extends ProviderSession< // Key to be used as an entry key for a remote entry private static final String REMOTE_ENTRY_KEY = "remote_entry_key"; - @NonNull - private final Map mUiSaveEntries = new HashMap<>(); - /** The complete request to be used in the second round. */ private final CreateCredentialRequest mCompleteRequest; private CreateCredentialException mProviderException; - @Nullable protected Pair mUiRemoteEntry; + private final ProviderResponseDataHandler mProviderResponseDataHandler; /** Creates a new provider session to be used by the request session. */ @Nullable public static ProviderCreateSession createNewSession( @@ -88,7 +86,8 @@ public final class ProviderCreateSession extends ProviderSession< createRequestSession.mClientAppInfo, createRequestSession .mClientRequest.alwaysSendAppInfoToProvider()), - providerCreateRequest + providerCreateRequest, + createRequestSession.mHybridService ); } Log.i(TAG, "Unable to create provider session"); @@ -131,23 +130,20 @@ public final class ProviderCreateSession extends ProviderSession< @UserIdInt int userId, @NonNull RemoteCredentialService remoteCredentialService, @NonNull BeginCreateCredentialRequest beginCreateRequest, - @NonNull CreateCredentialRequest completeCreateRequest) { + @NonNull CreateCredentialRequest completeCreateRequest, + String hybridService) { super(context, info, beginCreateRequest, callbacks, userId, remoteCredentialService); mCompleteRequest = completeCreateRequest; setStatus(Status.PENDING); - } - - /** Returns the save entry maintained in state by this provider session. */ - public CreateEntry getUiSaveEntry(String entryId) { - return mUiSaveEntries.get(entryId); + mProviderResponseDataHandler = new ProviderResponseDataHandler(hybridService); } @Override public void onProviderResponseSuccess( @Nullable BeginCreateCredentialResponse response) { Log.i(TAG, "in onProviderResponseSuccess"); - onUpdateResponse(response); + onSetInitialRemoteResponse(response); } /** Called when the provider response resulted in a failure. */ @@ -171,21 +167,18 @@ public final class ProviderCreateSession extends ProviderSession< } } - private void onUpdateResponse(BeginCreateCredentialResponse response) { - Log.i(TAG, "updateResponse with save entries"); + private void onSetInitialRemoteResponse(BeginCreateCredentialResponse response) { + Log.i(TAG, "onSetInitialRemoteResponse with save entries"); mProviderResponse = response; - if (isEmptyResponse(response)) { + mProviderResponseDataHandler.addResponseContent(response.getCreateEntries(), + response.getRemoteCreateEntry()); + if (mProviderResponseDataHandler.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 @Nullable protected CreateCredentialProviderData prepareUiData() throws IllegalArgumentException { @@ -194,53 +187,37 @@ public final class ProviderCreateSession extends ProviderSession< Log.i(TAG, "In prepareUiData not in uiInvokingStatus"); return null; } - final BeginCreateCredentialResponse response = getProviderResponse(); - if (response == null) { - Log.i(TAG, "In prepareUiData response null"); - throw new IllegalStateException("Response must be in completion mode"); - } - if (response.getCreateEntries() != null) { + + if (mProviderResponse != null && !mProviderResponseDataHandler.isEmptyResponse()) { Log.i(TAG, "In prepareUiData save entries not null"); - return prepareUiProviderData( - prepareUiSaveEntries(response.getCreateEntries()), - prepareUiRemoteEntry(response.getRemoteCreateEntry())); + return mProviderResponseDataHandler.toCreateCredentialProviderData(); } return null; } - private Entry prepareUiRemoteEntry(CreateEntry remoteCreateEntry) { - if (remoteCreateEntry == null) { - return null; - } - String entryId = generateUniqueId(); - Entry remoteEntry = new Entry(REMOTE_ENTRY_KEY, entryId, remoteCreateEntry.getSlice(), - setUpFillInIntent()); - mUiRemoteEntry = new Pair<>(entryId, remoteCreateEntry); - return remoteEntry; - } - @Override public void onUiEntrySelected(String entryType, String entryKey, ProviderPendingIntentResponse providerPendingIntentResponse) { switch (entryType) { case SAVE_ENTRY_KEY: - if (mUiSaveEntries.containsKey(entryKey)) { - onSaveEntrySelected(providerPendingIntentResponse); - } else { + if (mProviderResponseDataHandler.getCreateEntry(entryKey) == null) { Log.i(TAG, "Unexpected save entry key"); invokeCallbackOnInternalInvalidState(); + return; } + onCreateEntrySelected(providerPendingIntentResponse); break; case REMOTE_ENTRY_KEY: - if (mUiRemoteEntry.first.equals(entryKey)) { - onRemoteEntrySelected(providerPendingIntentResponse); - } else { + if (mProviderResponseDataHandler.getRemoteEntry(entryKey) == null) { Log.i(TAG, "Unexpected remote entry key"); invokeCallbackOnInternalInvalidState(); + return; } + onRemoteEntrySelected(providerPendingIntentResponse); break; default: Log.i(TAG, "Unsupported entry type selected"); + invokeCallbackOnInternalInvalidState(); } } @@ -252,21 +229,6 @@ public final class ProviderCreateSession extends ProviderSession< } } - private List prepareUiSaveEntries(@NonNull List saveEntries) { - Log.i(TAG, "in populateUiSaveEntries"); - List uiSaveEntries = new ArrayList<>(); - - // Populate the save entries - for (CreateEntry createEntry : saveEntries) { - 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(), - setUpFillInIntent())); - } - return uiSaveEntries; - } - private Intent setUpFillInIntent() { Intent intent = new Intent(); intent.putExtra(CredentialProviderService.EXTRA_CREATE_CREDENTIAL_REQUEST, @@ -274,16 +236,7 @@ public final class ProviderCreateSession extends ProviderSession< return intent; } - private CreateCredentialProviderData prepareUiProviderData(List saveEntries, - Entry remoteEntry) { - return new CreateCredentialProviderData.Builder( - mComponentName.flattenToString()) - .setSaveEntries(saveEntries) - .setRemoteEntry(remoteEntry) - .build(); - } - - private void onSaveEntrySelected(ProviderPendingIntentResponse pendingIntentResponse) { + private void onCreateEntrySelected(ProviderPendingIntentResponse pendingIntentResponse) { CreateCredentialException exception = maybeGetPendingIntentException( pendingIntentResponse); if (exception != null) { @@ -297,7 +250,6 @@ public final class ProviderCreateSession extends ProviderSession< pendingIntentResponse.getResultData()); if (credentialResponse != null) { mCallbacks.onFinalResponseReceived(mComponentName, credentialResponse); - return; } else { Log.i(TAG, "onSaveEntrySelected - no response or error found in pending " + "intent response"); @@ -305,6 +257,12 @@ public final class ProviderCreateSession extends ProviderSession< } } + private void onRemoteEntrySelected(ProviderPendingIntentResponse pendingIntentResponse) { + // Response from remote entry should be dealt with similar to a response from a + // create entry + onCreateEntrySelected(pendingIntentResponse); + } + @Nullable private CreateCredentialException maybeGetPendingIntentException( ProviderPendingIntentResponse pendingIntentResponse) { @@ -336,4 +294,91 @@ public final class ProviderCreateSession extends ProviderSession< CreateCredentialException.TYPE_UNKNOWN, null); } + + private class ProviderResponseDataHandler { + private final ComponentName mExpectedRemoteEntryProviderService; + + @NonNull + private final Map> mUiCreateEntries = new HashMap<>(); + + @Nullable private Pair> mUiRemoteEntry = null; + + ProviderResponseDataHandler(String hybridService) { + mExpectedRemoteEntryProviderService = ComponentName.unflattenFromString(hybridService); + } + + public void addResponseContent(List createEntries, + CreateEntry remoteEntry) { + createEntries.forEach(this::addCreateEntry); + setRemoteEntry(remoteEntry); + } + public void addCreateEntry(CreateEntry createEntry) { + String id = generateUniqueId(); + Entry entry = new Entry(SAVE_ENTRY_KEY, + id, createEntry.getSlice(), setUpFillInIntent()); + mUiCreateEntries.put(id, new Pair<>(createEntry, entry)); + } + + public void setRemoteEntry(@Nullable CreateEntry remoteEntry) { + if (remoteEntry == null) { + mUiRemoteEntry = null; + return; + } + if (!mComponentName.equals(mExpectedRemoteEntryProviderService)) { + Log.i(TAG, "Remote entry being dropped as it is not from the service " + + "configured by the OEM."); + return; + } + String id = generateUniqueId(); + Entry entry = new Entry(REMOTE_ENTRY_KEY, + id, remoteEntry.getSlice(), setUpFillInIntent()); + mUiRemoteEntry = new Pair<>(id, new Pair<>(remoteEntry, entry)); + } + + public CreateCredentialProviderData toCreateCredentialProviderData() { + return new CreateCredentialProviderData.Builder( + mComponentName.flattenToString()) + .setSaveEntries(prepareUiCreateEntries()) + .setRemoteEntry(prepareRemoteEntry()) + .build(); + } + + private List prepareUiCreateEntries() { + List createEntries = new ArrayList<>(); + for (String key : mUiCreateEntries.keySet()) { + createEntries.add(mUiCreateEntries.get(key).second); + } + return createEntries; + } + + private Entry prepareRemoteEntry() { + if (mUiRemoteEntry == null || mUiRemoteEntry.first == null + || mUiRemoteEntry.second == null) { + return null; + } + return mUiRemoteEntry.second.second; + } + + private boolean isEmptyResponse() { + return mUiCreateEntries.isEmpty() && mUiRemoteEntry == null; + } + @Nullable + public CreateEntry getRemoteEntry(String entryKey) { + return mUiRemoteEntry == null || mUiRemoteEntry + .first == null || !mUiRemoteEntry.first.equals(entryKey) + || mUiRemoteEntry.second == null + ? null : mUiRemoteEntry.second.first; + } + + @Nullable + public CreateEntry getCreateEntry(String entryKey) { + return mUiCreateEntries.get(entryKey) == null + ? null : mUiCreateEntries.get(entryKey).first; + } + + public boolean isEmptyResponse(BeginCreateCredentialResponse response) { + return (response.getCreateEntries() == null || response.getCreateEntries().isEmpty()) + && response.getRemoteCreateEntry() == null; + } + } } diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java index 187d516ef1fc7..12074c7494bf9 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java @@ -19,6 +19,7 @@ package com.android.server.credentials; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.credentials.CredentialOption; @@ -45,7 +46,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; +import java.util.Optional; /** * Central provider session that listens for provider callbacks, and maintains provider state. @@ -69,14 +70,7 @@ public final class ProviderGetSession extends ProviderSession mBeginGetOptionToCredentialOptionMap; - @NonNull - private final Map mUiCredentialEntries = new HashMap<>(); - @NonNull - private final Map mUiActionsEntries = new HashMap<>(); - @Nullable - private final Map mUiAuthenticationEntries = new HashMap<>(); - @Nullable protected Pair mUiRemoteEntry; /** The complete request to be used in the second round. */ private final android.credentials.GetCredentialRequest mCompleteRequest; @@ -84,6 +78,8 @@ public final class ProviderGetSession extends ProviderSession providerCapabilities, android.credentials.GetCredentialRequest clientRequest ) { @@ -169,19 +166,22 @@ public final class ProviderGetSession extends ProviderSession beginGetOptionToCredentialOptionMap) { + Map beginGetOptionToCredentialOptionMap, + String hybridService) { super(context, info, beginGetRequest, callbacks, userId, remoteCredentialService); mCompleteRequest = completeGetRequest; mCallingAppInfo = callingAppInfo; setStatus(Status.PENDING); mBeginGetOptionToCredentialOptionMap = new HashMap<>(beginGetOptionToCredentialOptionMap); + mProviderResponseDataHandler = new ProviderResponseDataHandler( + ComponentName.unflattenFromString(hybridService)); } /** Called when the provider response has been updated by an external source. */ @Override // Callback from the remote provider public void onProviderResponseSuccess(@Nullable BeginGetCredentialResponse response) { Log.i(TAG, "in onProviderResponseSuccess"); - onUpdateResponse(response); + onSetInitialRemoteResponse(response); } /** Called when the provider response resulted in a failure. */ @@ -207,18 +207,20 @@ public final class ProviderGetSession extends ProviderSession(entryId, remoteCredentialEntry); - return remoteEntry; - } - - private List prepareUiAuthenticationEntries( - @NonNull List authenticationEntries) { - List authenticationUiEntries = new ArrayList<>(); - - // TODO: properly construct entries when they should have the unlocked status. - for (Action authenticationAction : authenticationEntries) { - String entryId = generateUniqueId(); - mUiAuthenticationEntries.put(entryId, authenticationAction); - authenticationUiEntries.add(new AuthenticationEntry( - AUTHENTICATION_ACTION_ENTRY_KEY, entryId, - authenticationAction.getSlice(), - AuthenticationEntry.STATUS_LOCKED, - setUpFillInIntentForAuthentication())); - } - return authenticationUiEntries; - } - - private List prepareUiCredentialEntries(@NonNull - List credentialEntries) { - Log.i(TAG, "in prepareUiProviderDataWithCredentials"); - List credentialUiEntries = new ArrayList<>(); - - // Populate the credential entries - for (CredentialEntry credentialEntry : credentialEntries) { - 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, - credentialEntry.getSlice(), - /*fillInIntent=*/setUpFillInIntent(credentialEntry - .getBeginGetCredentialOption().getId()))); - } - return credentialUiEntries; + Log.i(TAG, "In prepareUiData response null"); + return null; } private Intent setUpFillInIntent(@NonNull String id) { @@ -335,68 +301,47 @@ public final class ProviderGetSession extends ProviderSession prepareUiActionEntries(@Nullable List actions) { - List actionEntries = new ArrayList<>(); - for (Action action : actions) { - String entryId = UUID.randomUUID().toString(); - mUiActionsEntries.put(entryId, action); - // TODO : Remove conversion of string to int after change in Entry class - actionEntries.add(new Entry(ACTION_ENTRY_KEY, entryId, action.getSlice())); - } - return actionEntries; - } - - private GetCredentialProviderData prepareUiProviderData(List actionEntries, - List credentialEntries, List authenticationActionEntries, - Entry remoteEntry) { - return new GetCredentialProviderData.Builder( - mComponentName.flattenToString()).setActionChips(actionEntries) - .setCredentialEntries(credentialEntries) - .setAuthenticationEntries(authenticationActionEntries) - .setRemoteEntry(remoteEntry) - .build(); - } - - private void onCredentialEntrySelected(CredentialEntry credentialEntry, + private void onRemoteEntrySelected( ProviderPendingIntentResponse providerPendingIntentResponse) { - if (providerPendingIntentResponse != null) { - // Check if pending intent has an error - GetCredentialException exception = maybeGetPendingIntentException( - providerPendingIntentResponse); - if (exception != null) { - invokeCallbackWithError(exception.getType(), - exception.getMessage()); - return; - } + onCredentialEntrySelected(providerPendingIntentResponse); + } - // Check if pending intent has a credential - GetCredentialResponse getCredentialResponse = PendingIntentResultHandler - .extractGetCredentialResponse( - providerPendingIntentResponse.getResultData()); - if (getCredentialResponse != null) { - mCallbacks.onFinalResponseReceived(mComponentName, - getCredentialResponse); - return; - } - - Log.i(TAG, "Pending intent response contains no credential, or error"); + private void onCredentialEntrySelected( + ProviderPendingIntentResponse providerPendingIntentResponse) { + if (providerPendingIntentResponse == null) { invokeCallbackOnInternalInvalidState(); + return; } - Log.i(TAG, "CredentialEntry does not have a credential or a pending intent result"); + // Check if pending intent has an error + GetCredentialException exception = maybeGetPendingIntentException( + providerPendingIntentResponse); + if (exception != null) { + invokeCallbackWithError(exception.getType(), exception.getMessage()); + return; + } + + // Check if pending intent has a credential response + GetCredentialResponse getCredentialResponse = PendingIntentResultHandler + .extractGetCredentialResponse( + providerPendingIntentResponse.getResultData()); + if (getCredentialResponse != null) { + mCallbacks.onFinalResponseReceived(mComponentName, + getCredentialResponse); + return; + } + Log.i(TAG, "Pending intent response contains no credential, or error"); invokeCallbackOnInternalInvalidState(); } @Nullable - protected GetCredentialException maybeGetPendingIntentException( + private GetCredentialException maybeGetPendingIntentException( ProviderPendingIntentResponse pendingIntentResponse) { if (pendingIntentResponse == null) { Log.i(TAG, "pendingIntentResponse is null"); @@ -417,13 +362,19 @@ public final class ProviderGetSession extends ProviderSession> mUiCredentialEntries = + new HashMap<>(); + @NonNull + private final Map> mUiActionsEntries = new HashMap<>(); + @Nullable + private final Map> mUiAuthenticationEntries = + new HashMap<>(); + + @Nullable private Pair> mUiRemoteEntry = null; + + ProviderResponseDataHandler(ComponentName expectedRemoteEntryProviderService) { + mExpectedRemoteEntryProviderService = expectedRemoteEntryProviderService; + } + + public void addResponseContent(List credentialEntries, + List actions, List authenticationActions, + CredentialEntry remoteEntry) { + credentialEntries.forEach(this::addCredentialEntry); + actions.forEach(this::addAction); + authenticationActions.forEach( + authenticationAction -> addAuthenticationAction(authenticationAction, + AuthenticationEntry.STATUS_LOCKED)); + setRemoteEntry(remoteEntry); + } + public void addCredentialEntry(CredentialEntry credentialEntry) { + String id = generateUniqueId(); + Entry entry = new Entry(CREDENTIAL_ENTRY_KEY, + id, credentialEntry.getSlice(), + setUpFillInIntent(credentialEntry + .getBeginGetCredentialOption().getId())); + mUiCredentialEntries.put(id, new Pair<>(credentialEntry, entry)); + } + + public void addAction(Action action) { + String id = generateUniqueId(); + Entry entry = new Entry(ACTION_ENTRY_KEY, + id, action.getSlice(), + setUpFillInIntentWithQueryRequest()); + mUiActionsEntries.put(id, new Pair<>(action, entry)); + } + + public void addAuthenticationAction(Action authenticationAction, + @AuthenticationEntry.Status int status) { + Log.i(TAG, "In addAuthenticationAction"); + String id = generateUniqueId(); + Log.i(TAG, "In addAuthenticationAction, id : " + id); + AuthenticationEntry entry = new AuthenticationEntry( + AUTHENTICATION_ACTION_ENTRY_KEY, + id, authenticationAction.getSlice(), + status, + setUpFillInIntentWithQueryRequest()); + mUiAuthenticationEntries.put(id, new Pair<>(authenticationAction, entry)); + } + + public void removeAuthenticationAction(String id) { + mUiAuthenticationEntries.remove(id); + } + + public void setRemoteEntry(@Nullable CredentialEntry remoteEntry) { + if (remoteEntry == null) { + return; + } + if (!mComponentName.equals(mExpectedRemoteEntryProviderService)) { + Log.i(TAG, "Remote entry being dropped as it is not from the service " + + "configured by the OEM."); + return; + } + String id = generateUniqueId(); + Entry entry = new Entry(REMOTE_ENTRY_KEY, + id, remoteEntry.getSlice(), setUpFillInIntent( + remoteEntry.getBeginGetCredentialOption().getId())); + mUiRemoteEntry = new Pair<>(generateUniqueId(), new Pair<>(remoteEntry, entry)); + } + + public GetCredentialProviderData toGetCredentialProviderData() { + return new GetCredentialProviderData.Builder( + mComponentName.flattenToString()).setActionChips(prepareActionEntries()) + .setCredentialEntries(prepareCredentialEntries()) + .setAuthenticationEntries(prepareAuthenticationEntries()) + .setRemoteEntry(prepareRemoteEntry()) + .build(); + } + + private List prepareActionEntries() { + List actionEntries = new ArrayList<>(); + for (String key : mUiActionsEntries.keySet()) { + actionEntries.add(mUiActionsEntries.get(key).second); + } + return actionEntries; + } + + private List prepareAuthenticationEntries() { + List authEntries = new ArrayList<>(); + for (String key : mUiAuthenticationEntries.keySet()) { + authEntries.add(mUiAuthenticationEntries.get(key).second); + } + return authEntries; + } + + private List prepareCredentialEntries() { + List credEntries = new ArrayList<>(); + for (String key : mUiCredentialEntries.keySet()) { + credEntries.add(mUiCredentialEntries.get(key).second); + } + return credEntries; + } + + + private Entry prepareRemoteEntry() { + if (mUiRemoteEntry == null || mUiRemoteEntry.first == null + || mUiRemoteEntry.second == null) { + return null; + } + return mUiRemoteEntry.second.second; + } + + private boolean isEmptyResponse() { + return mUiCredentialEntries.isEmpty() && mUiActionsEntries.isEmpty() + && mUiAuthenticationEntries.isEmpty() && mUiRemoteEntry == null; + } + + private boolean isEmptyResponse(BeginGetCredentialResponse response) { + return response.getCredentialEntries().isEmpty() && response.getActions().isEmpty() + && response.getAuthenticationActions().isEmpty() + && response.getRemoteCredentialEntry() == null; + } + + @Nullable + public Action getAuthenticationAction(String entryKey) { + return mUiAuthenticationEntries.get(entryKey) == null ? null : + mUiAuthenticationEntries.get(entryKey).first; + } + + @Nullable + public Action getActionEntry(String entryKey) { + return mUiActionsEntries.get(entryKey) == null + ? null : mUiActionsEntries.get(entryKey).first; + } + + @Nullable + public CredentialEntry getRemoteEntry(String entryKey) { + return mUiRemoteEntry.first.equals(entryKey) && mUiRemoteEntry.second != null + ? mUiRemoteEntry.second.first : null; + } + + @Nullable + public CredentialEntry getCredentialEntry(String entryKey) { + return mUiCredentialEntries.get(entryKey) == null + ? null : mUiCredentialEntries.get(entryKey).first; + } + + public void updateAuthEntryWithNoCredentialsReceived(String entryKey) { + updatePreviousMostRecentAuthEntry(); + updateMostRecentAuthEntry(entryKey); + } + + private void updateMostRecentAuthEntry(String entryKey) { + AuthenticationEntry previousAuthenticationEntry = + mUiAuthenticationEntries.get(entryKey).second; + Action previousAuthenticationAction = mUiAuthenticationEntries.get(entryKey).first; + mUiAuthenticationEntries.put(entryKey, new Pair<>( + previousAuthenticationAction, + copyAuthEntryAndChangeStatus( + previousAuthenticationEntry, + AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT))); + } + + private void updatePreviousMostRecentAuthEntry() { + Optional>> + previousMostRecentAuthEntry = mUiAuthenticationEntries + .entrySet().stream().filter(e -> e.getValue().second.getStatus() + == AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT) + .findFirst(); + if (previousMostRecentAuthEntry.isEmpty()) { + Log.i(TAG, "In updatePreviousMostRecentAuthEntry - previous entry not found"); + return; + } + String id = previousMostRecentAuthEntry.get().getKey(); + mUiAuthenticationEntries.remove(id); + mUiAuthenticationEntries.put(id, new Pair<>( + previousMostRecentAuthEntry.get().getValue().first, + copyAuthEntryAndChangeStatus( + previousMostRecentAuthEntry.get().getValue().second, + AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_LESS_RECENT))); + } + + private AuthenticationEntry copyAuthEntryAndChangeStatus( + AuthenticationEntry from, Integer toStatus) { + return new AuthenticationEntry(AUTHENTICATION_ACTION_ENTRY_KEY, from.getSubkey(), + from.getSlice(), toStatus, + from.getFrameworkExtrasIntent()); + } + } } diff --git a/services/credentials/java/com/android/server/credentials/ProviderSession.java b/services/credentials/java/com/android/server/credentials/ProviderSession.java index 4f49a3b5678e7..2f9d57872c3c0 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderSession.java @@ -66,8 +66,7 @@ public abstract class ProviderSession * on the credMan UI. */ public static boolean isUiInvokingStatus(Status status) { - return status == Status.CREDENTIALS_RECEIVED || status == Status.SAVE_ENTRIES_RECEIVED - || status == Status.REQUIRES_AUTHENTICATION; + return status == Status.CREDENTIALS_RECEIVED || status == Status.SAVE_ENTRIES_RECEIVED; } /** @@ -208,11 +207,6 @@ public abstract class ProviderSession } } - protected void onRemoteEntrySelected( - ProviderPendingIntentResponse providerPendingIntentResponse) { - //TODO: Implement - } - /** Get the request to be sent to the provider. */ protected T getProviderRequest() { return mProviderRequest; diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java index e3572848cf1c7..862266564c001 100644 --- a/services/credentials/java/com/android/server/credentials/RequestSession.java +++ b/services/credentials/java/com/android/server/credentials/RequestSession.java @@ -38,6 +38,7 @@ import android.service.credentials.CallingAppInfo; import android.service.credentials.CredentialProviderInfo; import android.util.Log; +import com.android.internal.R; import com.android.internal.util.FrameworkStatsLog; import com.android.server.credentials.metrics.CandidateProviderMetric; import com.android.server.credentials.metrics.ChosenProviderMetric; @@ -79,6 +80,7 @@ abstract class RequestSession implements CredentialManagerUi.CredentialMan protected final Map mProviders = new HashMap<>(); protected ChosenProviderMetric mChosenProviderMetric = new ChosenProviderMetric(); //TODO improve design to allow grouped metrics per request + protected final String mHybridService; protected RequestSession(@NonNull Context context, @UserIdInt int userId, int callingUid, @NonNull T clientRequest, U clientCallback, @@ -97,6 +99,8 @@ abstract class RequestSession implements CredentialManagerUi.CredentialMan mRequestId = new Binder(); mCredentialManagerUi = new CredentialManagerUi(mContext, mUserId, this); + mHybridService = context.getResources().getString( + R.string.config_defaultCredentialManagerHybridService); } public abstract ProviderSession initiateProviderSession(CredentialProviderInfo providerInfo,