summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Helen Qin <helenqin@google.com> 2023-03-06 05:02:01 +0000
committer Helen Qin <helenqin@google.com> 2023-03-06 05:03:45 +0000
commit79886a8928a755c64db45707097861cdcae54c25 (patch)
tree29e15ab64189374d3335dbfa5af6120c22c95b36
parent1ee1185baa60d0303085a55c8f522a5437248ae4 (diff)
[CredManUi] Support auto select.
Bug: 265209303 Test: manual Change-Id: Ie1b46eccec4116be1c0833f9399d19f23876defe
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt20
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt24
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt6
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt20
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt17
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt18
6 files changed, 83 insertions, 22 deletions
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index a2d1e4de8e35..b32fe3fef00d 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -42,11 +42,13 @@ import com.android.credentialmanager.createflow.DisabledProviderInfo
import com.android.credentialmanager.createflow.EnabledProviderInfo
import com.android.credentialmanager.createflow.RequestDisplayInfo
import com.android.credentialmanager.getflow.GetCredentialUiState
+import com.android.credentialmanager.getflow.findAutoSelectEntry
import androidx.credentials.CreateCredentialRequest.DisplayInfo
import androidx.credentials.CreatePublicKeyCredentialRequest
import androidx.credentials.CreatePasswordRequest
import androidx.credentials.GetPasswordOption
import androidx.credentials.GetPublicKeyCredentialOption
+import com.android.credentialmanager.common.ProviderActivityState
import java.time.Instant
@@ -128,10 +130,20 @@ class CredentialManagerRepo(
getCredentialUiState = null,
)
}
- RequestInfo.TYPE_GET -> UiState(
- createCredentialUiState = null,
- getCredentialUiState = getCredentialInitialUiState(originName)!!,
- )
+ RequestInfo.TYPE_GET -> {
+ val getCredentialInitialUiState = getCredentialInitialUiState(originName)!!
+ val autoSelectEntry =
+ findAutoSelectEntry(getCredentialInitialUiState.providerDisplayInfo)
+ UiState(
+ createCredentialUiState = null,
+ getCredentialUiState = getCredentialInitialUiState,
+ selectedEntry = autoSelectEntry,
+ providerActivityState =
+ if (autoSelectEntry == null) ProviderActivityState.NOT_APPLICABLE
+ else ProviderActivityState.READY_TO_LAUNCH,
+ isAutoSelectFlow = autoSelectEntry != null,
+ )
+ }
else -> throw IllegalStateException("Unrecognized request type: ${requestInfo.type}")
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index a5c749432753..ca30c53a6d83 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -44,6 +44,9 @@ data class UiState(
val selectedEntry: BaseEntry? = null,
val providerActivityState: ProviderActivityState = ProviderActivityState.NOT_APPLICABLE,
val dialogState: DialogState = DialogState.ACTIVE,
+ // True if the UI has one and onely one auto selectable entry. Its provider activiey will be
+ // launched immediately, and canceling it will cancel the whole UI flow.
+ val isAutoSelectFlow: Boolean = false,
)
class CredentialSelectorViewModel(
@@ -96,13 +99,20 @@ class CredentialSelectorViewModel(
val resultCode = providerActivityResult.resultCode
val resultData = providerActivityResult.data
if (resultCode == Activity.RESULT_CANCELED) {
- // Re-display the CredMan UI if the user canceled from the provider UI.
- Log.d(Constants.LOG_TAG, "The provider activity was cancelled," +
- " re-displaying our UI.")
- uiState = uiState.copy(
- selectedEntry = null,
- providerActivityState = ProviderActivityState.NOT_APPLICABLE,
- )
+ // Re-display the CredMan UI if the user canceled from the provider UI, or cancel
+ // the UI if this is the auto select flow.
+ if (uiState.isAutoSelectFlow) {
+ Log.d(Constants.LOG_TAG, "The auto selected provider activity was cancelled," +
+ " ending the credential manager activity.")
+ onUserCancel()
+ } else {
+ Log.d(Constants.LOG_TAG, "The provider activity was cancelled," +
+ " re-displaying our UI.")
+ uiState = uiState.copy(
+ selectedEntry = null,
+ providerActivityState = ProviderActivityState.NOT_APPLICABLE,
+ )
+ }
} else {
if (entry != null) {
Log.d(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index 43912c26f3c8..223806cdba3a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -222,6 +222,8 @@ class GetFlowUtils {
displayName = credentialEntry.displayName?.toString(),
icon = credentialEntry.icon.loadDrawable(context),
lastUsedTimeMillis = credentialEntry.lastUsedTime,
+ isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
+ credentialEntry.autoSelectAllowedFromOption,
))
}
is PublicKeyCredentialEntry -> {
@@ -237,6 +239,8 @@ class GetFlowUtils {
displayName = credentialEntry.displayName?.toString(),
icon = credentialEntry.icon.loadDrawable(context),
lastUsedTimeMillis = credentialEntry.lastUsedTime,
+ isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
+ credentialEntry.autoSelectAllowedFromOption,
))
}
is CustomCredentialEntry -> {
@@ -252,6 +256,8 @@ class GetFlowUtils {
displayName = credentialEntry.subtitle?.toString(),
icon = credentialEntry.icon.loadDrawable(context),
lastUsedTimeMillis = credentialEntry.lastUsedTime,
+ isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
+ credentialEntry.autoSelectAllowedFromOption,
))
}
else -> Log.d(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
index 75b12ff756ad..82d6952bf826 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
@@ -155,21 +155,23 @@ class GetTestUtils {
userName: String,
userDisplayName: String?,
lastUsedTime: Instant?,
+ isAutoSelectAllowed: Boolean = false,
): Entry {
- val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD")
- .setPackage("com.androidauth.androidvault")
- intent.putExtra("provider_extra_sample", "testprovider")
- val pendingIntent = PendingIntent.getActivity(
- context, 1,
- intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
- or PendingIntent.FLAG_ONE_SHOT)
+ val intent = Intent(Settings.ACTION_SYNC_SETTINGS)
+ val pendingIntent =
+ PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+ val candidateQueryData = Bundle()
+ candidateQueryData.putBoolean(
+ "androidx.credentials.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED",
+ isAutoSelectAllowed
)
val passkeyEntry = PublicKeyCredentialEntry.Builder(
context,
userName,
pendingIntent,
- BeginGetPublicKeyCredentialOption(Bundle(), "id", "requestjson")
- ).setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build()
+ BeginGetPublicKeyCredentialOption(candidateQueryData, "id", "requestjson")
+ ).setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime)
+ .setAutoSelectAllowed(isAutoSelectAllowed).build()
return Entry(key, subkey, passkeyEntry.slice, Intent())
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index b83c593fdffc..652cf0180b53 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -1,4 +1,18 @@
-@file:OptIn(ExperimentalMaterial3Api::class)
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.android.credentialmanager.createflow
@@ -15,7 +29,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material3.Divider
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.NewReleases
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index 9727d3f39c4a..dbf199768bbf 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -41,6 +41,23 @@ internal fun hasContentToDisplay(state: GetCredentialUiState): Boolean {
!state.requestDisplayInfo.preferImmediatelyAvailableCredentials)
}
+internal fun findAutoSelectEntry(providerDisplayInfo: ProviderDisplayInfo): CredentialEntryInfo? {
+ if (providerDisplayInfo.authenticationEntryList.isNotEmpty()) {
+ return null
+ }
+ if (providerDisplayInfo.sortedUserNameToCredentialEntryList.size == 1) {
+ val entryList = providerDisplayInfo.sortedUserNameToCredentialEntryList.firstOrNull()
+ ?: return null
+ if (entryList.sortedCredentialEntryList.size == 1) {
+ val entry = entryList.sortedCredentialEntryList.firstOrNull() ?: return null
+ if (entry.isAutoSelectable) {
+ return entry
+ }
+ }
+ }
+ return null
+}
+
data class ProviderInfo(
/**
* Unique id (component name) of this provider.
@@ -81,6 +98,7 @@ class CredentialEntryInfo(
val displayName: String?,
val icon: Drawable?,
val lastUsedTimeMillis: Instant?,
+ val isAutoSelectable: Boolean,
) : BaseEntry(
providerId,
entryKey,