Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d20b86f6 authored by Helen Qin's avatar Helen Qin Committed by Android (Google) Code Review
Browse files

Merge "Handle empty input gracefully."

parents 1ebf6969 7c9550ab
Loading
Loading
Loading
Loading
+22 −17
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ class CredentialManagerRepo(
        requestInfo = intent.extras?.getParcelable(
            RequestInfo.EXTRA_REQUEST_INFO,
            RequestInfo::class.java
        ) ?: testGetRequestInfo()
        ) ?: testCreatePasskeyRequestInfo()

        providerEnabledList = when (requestInfo.type) {
            RequestInfo.TYPE_CREATE ->
@@ -115,8 +115,10 @@ class CredentialManagerRepo(
                        providerDisableListUiState,
                        defaultProviderId,
                        requestDisplayInfoUiState,
                        /** isOnPasskeyIntroStateAlready = */ false,
                        isPasskeyFirstUse)!!,
                        /** isOnPasskeyIntroStateAlready = */
                        false,
                        isPasskeyFirstUse
                    )!!,
                    getCredentialUiState = null,
                )
            }
@@ -224,12 +226,14 @@ class CredentialManagerRepo(
                .Builder("io.enpass.app")
                .setSaveEntries(
                    listOf<Entry>(
                        CreateTestUtils.newCreateEntry(context,
                        CreateTestUtils.newCreateEntry(
                            context,
                            "key1", "subkey-1", "elisa.beckett@gmail.com",
                            20, 7, 27, Instant.ofEpochSecond(10L),
                            "Legal note"
                        ),
                        CreateTestUtils.newCreateEntry(context,
                        CreateTestUtils.newCreateEntry(
                            context,
                            "key1", "subkey-2", "elisa.work@google.com",
                            20, 7, 27, Instant.ofEpochSecond(12L),
                            null
@@ -244,12 +248,14 @@ class CredentialManagerRepo(
                .Builder("com.dashlane")
                .setSaveEntries(
                    listOf<Entry>(
                        CreateTestUtils.newCreateEntry(context,
                        CreateTestUtils.newCreateEntry(
                            context,
                            "key1", "subkey-3", "elisa.beckett@dashlane.com",
                            20, 7, 27, Instant.ofEpochSecond(11L),
                            null
                        ),
                        CreateTestUtils.newCreateEntry(context,
                        CreateTestUtils.newCreateEntry(
                            context,
                            "key1", "subkey-4", "elisa.work@dashlane.com",
                            20, 7, 27, Instant.ofEpochSecond(14L),
                            null
@@ -343,7 +349,6 @@ class CredentialManagerRepo(
    }



    private fun newRemoteEntry(
        key: String,
        subkey: String,
@@ -427,7 +432,8 @@ class CredentialManagerRepo(
        val displayInfo = DisplayInfo("my-username00", "Joe")
        data.putBundle(
            "androidx.credentials.BUNDLE_KEY_REQUEST_DISPLAY_INFO",
            displayInfo.toBundle())
            displayInfo.toBundle()
        )
        return RequestInfo.newCreateRequestInfo(
            Binder(),
            CreateCredentialRequest(
@@ -445,8 +451,7 @@ class CredentialManagerRepo(
            Binder(),
            GetCredentialRequest.Builder(
                Bundle()
            )
                .addCredentialOption(
            ).addCredentialOption(
                CredentialOption(
                    "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL",
                    Bundle(),
+5 −3
Original line number Diff line number Diff line
@@ -36,7 +36,9 @@ import com.android.credentialmanager.common.DialogState
import com.android.credentialmanager.common.ProviderActivityResult
import com.android.credentialmanager.common.StartBalIntentSenderForResultContract
import com.android.credentialmanager.createflow.CreateCredentialScreen
import com.android.credentialmanager.createflow.hasContentToDisplay
import com.android.credentialmanager.getflow.GetCredentialScreen
import com.android.credentialmanager.getflow.hasContentToDisplay
import com.android.credentialmanager.ui.theme.CredentialSelectorTheme

@ExperimentalMaterialApi
@@ -94,13 +96,13 @@ class CredentialSelectorActivity : ComponentActivity() {

        val createCredentialUiState = viewModel.uiState.createCredentialUiState
        val getCredentialUiState = viewModel.uiState.getCredentialUiState
        if (createCredentialUiState != null) {
        if (createCredentialUiState != null && hasContentToDisplay(createCredentialUiState)) {
            CreateCredentialScreen(
                viewModel = viewModel,
                createCredentialUiState = createCredentialUiState,
                providerActivityLauncher = launcher
            )
        } else if (getCredentialUiState != null) {
        } else if (getCredentialUiState != null && hasContentToDisplay(getCredentialUiState)) {
            GetCredentialScreen(
                viewModel = viewModel,
                getCredentialUiState = getCredentialUiState,
@@ -130,7 +132,7 @@ class CredentialSelectorActivity : ComponentActivity() {
    }

    private fun onInitializationError(e: Exception, intent: Intent) {
        Log.e(Constants.LOG_TAG, "Failed to show the credential selector", e)
        Log.e(Constants.LOG_TAG, "Failed to show the credential selector; closing the activity", e)
        val resultReceiver = intent.getParcelableExtra(
            android.credentials.ui.Constants.EXTRA_RESULT_RECEIVER,
            ResultReceiver::class.java
+9 −2
Original line number Diff line number Diff line
@@ -473,8 +473,14 @@ class CreateFlowUtils {
                        createOptionsPairs.add(Pair(it, enabledProvider))
                    }
                }
                if (enabledProvider.remoteEntry != null) {
                    remoteEntry = enabledProvider.remoteEntry!!
                val currRemoteEntry = enabledProvider.remoteEntry
                if (currRemoteEntry != null) {
                    if (remoteEntry != null) {
                        // There can only be at most one remote entry
                        Log.d(Constants.LOG_TAG, "Found more than one remote entry.")
                        return null
                    }
                    remoteEntry = currRemoteEntry
                }
            }
            val initialScreenState = toCreateScreenState(
@@ -500,6 +506,7 @@ class CreateFlowUtils {
                    lastSeenProviderWithNonEmptyCreateOptions,
                    /*remoteEntry=*/remoteEntry
                ),
                remoteEntry = remoteEntry,
            )
        }

+41 −37
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ import com.android.credentialmanager.common.ui.ContainerCard
import com.android.credentialmanager.common.ui.ToggleVisibilityButton
import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CreateCredentialScreen(
    viewModel: CredentialSelectorViewModel,
@@ -80,10 +79,10 @@ fun CreateCredentialScreen(
                        )
                        CreateScreenState.PROVIDER_SELECTION -> ProviderSelectionCard(
                            requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
                            enabledProviderList = createCredentialUiState.enabledProviders,
                            disabledProviderList = createCredentialUiState.disabledProviders,
                            sortedCreateOptionsPairs =
                            createCredentialUiState.sortedCreateOptionsPairs,
                            hasRemoteEntry = createCredentialUiState.remoteEntry != null,
                            onOptionSelected =
                            viewModel::createFlowOnEntrySelectedFromFirstUseScreen,
                            onDisabledProvidersSelected =
@@ -277,9 +276,9 @@ fun ConfirmationCard(
@Composable
fun ProviderSelectionCard(
    requestDisplayInfo: RequestDisplayInfo,
    enabledProviderList: List<EnabledProviderInfo>,
    disabledProviderList: List<DisabledProviderInfo>?,
    sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
    hasRemoteEntry: Boolean,
    onOptionSelected: (ActiveEntry) -> Unit,
    onDisabledProvidersSelected: () -> Unit,
    onMoreOptionsSelected: () -> Unit,
@@ -302,7 +301,8 @@ fun ProviderSelectionCard(
                        CredentialType.PASSWORD ->
                            stringResource(R.string.passwords)
                        CredentialType.UNKNOWN -> stringResource(R.string.sign_in_info)
                    }),
                    }
                ),
                style = MaterialTheme.typography.titleMedium,
                modifier = Modifier.padding(horizontal = 24.dp)
                    .align(alignment = Alignment.CenterHorizontally),
@@ -317,15 +317,14 @@ fun ProviderSelectionCard(
                style = MaterialTheme.typography.bodyLarge,
                modifier = Modifier.padding(horizontal = 28.dp),
            )
            Divider(
                thickness = 18.dp,
                color = Color.Transparent
            )
            ContainerCard(
                shape = MaterialTheme.shapes.medium,
                modifier = Modifier
                    .padding(horizontal = 24.dp)
                    .align(alignment = Alignment.CenterHorizontally),
                modifier = Modifier.padding(
                    start = 24.dp,
                    end = 24.dp,
                    top = 24.dp,
                    bottom = if (hasRemoteEntry) 24.dp else 16.dp
                ).align(alignment = Alignment.CenterHorizontally),
            ) {
                LazyColumn(
                    verticalArrangement = Arrangement.spacedBy(2.dp)
@@ -356,12 +355,11 @@ fun ProviderSelectionCard(
                    }
                }
            }
            if (hasRemoteEntry) {
                Divider(
                    thickness = 24.dp,
                    color = Color.Transparent
                )
            enabledProviderList.forEach { enabledProvider ->
                if (enabledProvider.remoteEntry != null) {
                Row(
                    horizontalArrangement = Arrangement.Start,
                    modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp)
@@ -371,13 +369,10 @@ fun ProviderSelectionCard(
                        onMoreOptionsSelected
                    )
                }
                    return@forEach
                }
            }
            Divider(
                thickness = 18.dp,
                thickness = 24.dp,
                color = Color.Transparent,
                modifier = Modifier.padding(bottom = 16.dp)
            )
        }
    }
@@ -412,7 +407,8 @@ fun MoreOptionsSelectionCard(
                                CredentialType.PASSWORD ->
                                    stringResource(R.string.password)
                                CredentialType.UNKNOWN -> stringResource(R.string.sign_in_info)
                            }),
                            }
                        ),
                        style = MaterialTheme.typography.titleMedium,
                    )
                },
@@ -653,7 +649,8 @@ fun CreationSelectionCard(
                    text = createOptionInfo.footerDescription,
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier.padding(
                        start = 29.dp, top = 8.dp, bottom = 18.dp, end = 28.dp)
                        start = 29.dp, top = 8.dp, bottom = 18.dp, end = 28.dp
                    )
                )
            }
            Divider(
@@ -739,7 +736,8 @@ fun MoreAboutPasskeysIntroCard(
                    TextOnSurface(
                        text =
                        stringResource(
                            R.string.more_about_passkeys_title),
                            R.string.more_about_passkeys_title
                        ),
                        style = MaterialTheme.typography.titleMedium,
                    )
                },
@@ -865,9 +863,13 @@ fun PrimaryCreateOptionRow(
                            style = MaterialTheme.typography.titleLarge,
                            modifier = Modifier.padding(top = 16.dp, start = 5.dp),
                        )
                        Row(modifier = Modifier.fillMaxWidth().padding(top = 4.dp, bottom = 16.dp,
                                                                       start = 5.dp),
                            verticalAlignment = Alignment.CenterVertically) {
                        Row(
                            modifier = Modifier.fillMaxWidth().padding(
                                top = 4.dp, bottom = 16.dp,
                                start = 5.dp
                            ),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            val visualTransformation = remember { PasswordVisualTransformation() }
                            // This subtitle would never be null for create password
                            val originalPassword by remember {
@@ -915,7 +917,8 @@ fun PrimaryCreateOptionRow(
                                text = requestDisplayInfo.title,
                                style = MaterialTheme.typography.titleLarge,
                                modifier = Modifier.padding(
                                    top = 16.dp, bottom = 16.dp, start = 5.dp),
                                    top = 16.dp, bottom = 16.dp, start = 5.dp
                                ),
                            )
                        }
                    }
@@ -957,7 +960,8 @@ fun MoreOptionsInfoRow(
                    )
                }
                if (requestDisplayInfo.type == CredentialType.PASSKEY ||
                    requestDisplayInfo.type == CredentialType.PASSWORD) {
                    requestDisplayInfo.type == CredentialType.PASSWORD
                ) {
                    if (createOptionInfo.passwordCount != null &&
                        createOptionInfo.passkeyCount != null
                    ) {
+5 −0
Original line number Diff line number Diff line
@@ -33,9 +33,14 @@ data class CreateCredentialUiState(
  // we're showing provider selection page at the beginning
  val hasDefaultProvider: Boolean,
  val activeEntry: ActiveEntry? = null,
  val remoteEntry: RemoteInfo? = null,
  val isFromProviderSelection: Boolean? = null,
)

internal fun hasContentToDisplay(state: CreateCredentialUiState): Boolean {
    return state.sortedCreateOptionsPairs.isNotEmpty()
}

open class ProviderInfo(
  val icon: Drawable,
  val id: String,
Loading