summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Qinmei Du <duqinmei@google.com> 2022-11-30 22:45:59 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-11-30 22:45:59 +0000
commit3708b3783021e708ea1a328e9c5078c55d7cede6 (patch)
tree5c38b4c1ee28e04808c0b23728518e7df2446362
parent8dadc7e871a6908b84c8d924f07b0f0e60fee529 (diff)
parent3b7090ae7417f10188db3d3413611e579425c870 (diff)
Merge "Add the screen when there's no create option for the default provider but there's remoteEntry"
-rw-r--r--packages/CredentialManager/res/values/strings.xml2
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt57
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt86
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt2
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt1
5 files changed, 130 insertions, 18 deletions
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index 252ecf4a6005..8c9023c55eff 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -49,6 +49,8 @@
<string name="save_password_to_title">Save password to</string>
<!-- This appears as the title of the modal bottom sheet for users to choose other available places the created other credential types can be saved to. [CHAR LIMIT=200] -->
<string name="save_sign_in_to_title">Save sign-in to</string>
+ <!-- This appears as the title of the modal bottom sheet for users to choose to create a passkey on another device. [CHAR LIMIT=200] -->
+ <string name="create_passkey_in_other_device_title">Create a passkey in another device?</string>
<!-- This appears as the title of the modal bottom sheet for users to confirm whether they should use the selected provider as default or not. [CHAR LIMIT=200] -->
<string name="use_provider_for_all_title">Use <xliff:g id="providerInfoDisplayName" example="Google Password Manager">%1$s</xliff:g> for all your sign-ins?</string>
<!-- TODO: Check the wording here. -->
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index 530f1c467a76..0cc11946ca85 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -44,6 +44,8 @@ import com.android.credentialmanager.createflow.ActiveEntry
import com.android.credentialmanager.createflow.CreateCredentialUiState
import com.android.credentialmanager.createflow.CreateScreenState
import com.android.credentialmanager.createflow.EnabledProviderInfo
+import com.android.credentialmanager.createflow.RemoteInfo
+import com.android.credentialmanager.createflow.RequestDisplayInfo
import com.android.credentialmanager.getflow.GetCredentialUiState
import com.android.credentialmanager.getflow.GetScreenState
import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest.Companion.toBundle
@@ -142,25 +144,22 @@ class CredentialManagerRepo(
val providerDisabledList = CreateFlowUtils.toDisabledProviderList(
// Handle runtime cast error
providerDisabledList as List<DisabledProviderData>, context)
- var hasDefault = false
- var defaultProvider: EnabledProviderInfo = providerEnabledList.first()
+ var defaultProvider: EnabledProviderInfo? = null
+ var remoteEntry: RemoteInfo? = null
providerEnabledList.forEach{providerInfo -> providerInfo.createOptions =
providerInfo.createOptions.sortedWith(compareBy { it.lastUsedTimeMillis }).reversed()
- if (providerInfo.isDefault) {hasDefault = true; defaultProvider = providerInfo} }
+ if (providerInfo.isDefault) {defaultProvider = providerInfo}
+ if (providerInfo.remoteEntry != null) {
+ remoteEntry = providerInfo.remoteEntry!!
+ }
+ }
return CreateCredentialUiState(
enabledProviders = providerEnabledList,
disabledProviders = providerDisabledList,
- // TODO: Add the screen when defaultProvider has no createOption but
- // there's remoteInfo under other providers
- if (!hasDefault || defaultProvider.createOptions.isEmpty()) {
- if (requestDisplayInfo.type == TYPE_PUBLIC_KEY_CREDENTIAL)
- {CreateScreenState.PASSKEY_INTRO} else {CreateScreenState.PROVIDER_SELECTION}
- } else {CreateScreenState.CREATION_OPTION_SELECTION},
+ toCreateScreenState(requestDisplayInfo, defaultProvider, remoteEntry),
requestDisplayInfo,
false,
- if (hasDefault) {
- ActiveEntry(defaultProvider, defaultProvider.createOptions.first())
- } else null
+ toActiveEntry(defaultProvider, remoteEntry),
)
}
@@ -509,4 +508,38 @@ class CredentialManagerRepo(
"tribank.us"
)
}
+
+ private fun toCreateScreenState(
+ requestDisplayInfo: RequestDisplayInfo,
+ defaultProvider: EnabledProviderInfo?,
+ remoteEntry: RemoteInfo?,
+ ): CreateScreenState {
+ return if (
+ defaultProvider != null && defaultProvider.createOptions.isEmpty() && remoteEntry != null
+ ){
+ CreateScreenState.EXTERNAL_ONLY_SELECTION
+ } else if (defaultProvider == null || defaultProvider.createOptions.isEmpty()) {
+ if (requestDisplayInfo.type == TYPE_PUBLIC_KEY_CREDENTIAL) {
+ CreateScreenState.PASSKEY_INTRO
+ } else {
+ CreateScreenState.PROVIDER_SELECTION
+ }
+ } else {
+ CreateScreenState.CREATION_OPTION_SELECTION
+ }
+ }
+
+ private fun toActiveEntry(
+ defaultProvider: EnabledProviderInfo?,
+ remoteEntry: RemoteInfo?,
+ ): ActiveEntry? {
+ return if (
+ defaultProvider != null && defaultProvider.createOptions.isNotEmpty()
+ ) {
+ ActiveEntry(defaultProvider, defaultProvider.createOptions.first())
+ } else if (
+ defaultProvider != null && defaultProvider.createOptions.isEmpty() && remoteEntry != null) {
+ ActiveEntry(defaultProvider, remoteEntry)
+ } else null
+ }
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index fde32792e8f8..20b3d81c8b3c 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -60,7 +60,7 @@ fun CreateCredentialScreen(
viewModel.onEntrySelected(it, providerActivityLauncher)
}
val confirmEntryCallback: () -> Unit = {
- viewModel.onConfirmCreationSelected(providerActivityLauncher)
+ viewModel.onConfirmEntrySelected(providerActivityLauncher)
}
val state = rememberModalBottomSheetState(
initialValue = ModalBottomSheetValue.Expanded,
@@ -108,6 +108,13 @@ fun CreateCredentialScreen(
providerInfo = uiState.activeEntry?.activeProvider!!,
onDefaultOrNotSelected = viewModel::onDefaultOrNotSelected
)
+ CreateScreenState.EXTERNAL_ONLY_SELECTION -> ExternalOnlySelectionCard(
+ requestDisplayInfo = uiState.requestDisplayInfo,
+ activeRemoteEntry = uiState.activeEntry?.activeEntryInfo!!,
+ onOptionSelected = selectEntryCallback,
+ onConfirm = confirmEntryCallback,
+ onCancel = viewModel::onCancel,
+ )
}
},
scrimColor = MaterialTheme.colorScheme.scrim,
@@ -489,7 +496,7 @@ fun CreationSelectionCard(
) {
PrimaryCreateOptionRow(
requestDisplayInfo = requestDisplayInfo,
- createOptionInfo = createOptionInfo,
+ entryInfo = createOptionInfo,
onOptionSelected = onOptionSelected
)
}
@@ -562,16 +569,85 @@ fun CreationSelectionCard(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
+fun ExternalOnlySelectionCard(
+ requestDisplayInfo: RequestDisplayInfo,
+ activeRemoteEntry: EntryInfo,
+ onOptionSelected: (EntryInfo) -> Unit,
+ onConfirm: () -> Unit,
+ onCancel: () -> Unit,
+) {
+ Card() {
+ Column() {
+ Icon(
+ painter = painterResource(R.drawable.ic_other_devices),
+ contentDescription = null,
+ tint = Color.Unspecified,
+ modifier = Modifier.align(alignment = Alignment.CenterHorizontally)
+ .padding(all = 24.dp).size(32.dp)
+ )
+ Text(
+ text = stringResource(R.string.create_passkey_in_other_device_title),
+ style = MaterialTheme.typography.titleMedium,
+ modifier = Modifier.padding(horizontal = 24.dp)
+ .align(alignment = Alignment.CenterHorizontally),
+ textAlign = TextAlign.Center,
+ )
+ Divider(
+ thickness = 24.dp,
+ color = Color.Transparent
+ )
+ Card(
+ shape = MaterialTheme.shapes.medium,
+ modifier = Modifier
+ .padding(horizontal = 24.dp)
+ .align(alignment = Alignment.CenterHorizontally),
+ ) {
+ PrimaryCreateOptionRow(
+ requestDisplayInfo = requestDisplayInfo,
+ entryInfo = activeRemoteEntry,
+ onOptionSelected = onOptionSelected
+ )
+ }
+ Divider(
+ thickness = 24.dp,
+ color = Color.Transparent
+ )
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp)
+ ) {
+ CancelButton(
+ stringResource(R.string.string_cancel),
+ onClick = onCancel
+ )
+ ConfirmButton(
+ stringResource(R.string.string_continue),
+ onClick = onConfirm
+ )
+ }
+ Divider(
+ thickness = 18.dp,
+ color = Color.Transparent,
+ modifier = Modifier.padding(bottom = 16.dp)
+ )
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
fun PrimaryCreateOptionRow(
requestDisplayInfo: RequestDisplayInfo,
- createOptionInfo: CreateOptionInfo,
+ entryInfo: EntryInfo,
onOptionSelected: (EntryInfo) -> Unit
) {
Entry(
- onClick = {onOptionSelected(createOptionInfo)},
+ onClick = {onOptionSelected(entryInfo)},
icon = {
Icon(
- bitmap = createOptionInfo.profileIcon.toBitmap().asImageBitmap(),
+ bitmap = if (entryInfo is CreateOptionInfo) {
+ entryInfo.profileIcon.toBitmap().asImageBitmap()
+ } else {requestDisplayInfo.typeIcon.toBitmap().asImageBitmap()},
contentDescription = null,
tint = LocalAndroidColorScheme.current.colorAccentPrimaryVariant,
modifier = Modifier.padding(start = 18.dp).size(32.dp)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
index 0f685a104329..393cf7d9ae01 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
@@ -155,7 +155,7 @@ class CreateCredentialViewModel(
}
}
- fun onConfirmCreationSelected(
+ fun onConfirmEntrySelected(
launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
) {
val selectedEntry = uiState.activeEntry?.activeEntryInfo
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
index 31d0365a821f..9ac524a4e6d9 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
@@ -95,4 +95,5 @@ enum class CreateScreenState {
CREATION_OPTION_SELECTION,
MORE_OPTIONS_SELECTION,
MORE_OPTIONS_ROW_INTRO,
+ EXTERNAL_ONLY_SELECTION,
}