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

Commit 4c598542 authored by Qinmei Du's avatar Qinmei Du
Browse files

Update get flow about the icons and chip UI

1. Update the sorting of crendentialEntry to sort passkey first
2. Update the padding of the entry
3. Make the icons apply dynamatic color
4. Make the credentialEntry icons fall back to unknown sign-in icons
5. Make the icons of action chip use provider icon
6. Add the lock icon inside the authentication chip
7. Make password type display 12 dots

screencast: https://drive.google.com/file/d/1hM2M0yNMGKjpipvoIZg0oeCRBDN9UQ5d/view?usp=sharing&resourcekey=0-AVdG9BISCHteQqtv6a-NYw

Test: deployed locally

Bug: 253157237
Change-Id: Ibe5556076cae3b64ab1cc1514cf14986e84182b0
parent 24a4e3fd
Loading
Loading
Loading
Loading
+0 −30
Original line number Original line Diff line number Diff line
<!--
  ~ 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.
  -->

<!--TODO: Testing only icon. Remove later. -->

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:ignore="VectorPath"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24"
        android:viewportHeight="24"
        android:tint="?attr/colorControlNormal">
    <path
        android:fillColor="#808080"
        android:pathData="M9.025,14.275Q8.5,14.275 8.125,13.9Q7.75,13.525 7.75,13Q7.75,12.475 8.125,12.1Q8.5,11.725 9.025,11.725Q9.575,11.725 9.938,12.1Q10.3,12.475 10.3,13Q10.3,13.525 9.938,13.9Q9.575,14.275 9.025,14.275ZM14.975,14.275Q14.425,14.275 14.062,13.9Q13.7,13.525 13.7,13Q13.7,12.475 14.062,12.1Q14.425,11.725 14.975,11.725Q15.5,11.725 15.875,12.1Q16.25,12.475 16.25,13Q16.25,13.525 15.875,13.9Q15.5,14.275 14.975,14.275ZM12,19.925Q15.325,19.925 17.625,17.625Q19.925,15.325 19.925,12Q19.925,11.4 19.85,10.85Q19.775,10.3 19.575,9.775Q19.05,9.9 18.538,9.962Q18.025,10.025 17.45,10.025Q15.2,10.025 13.188,9.062Q11.175,8.1 9.775,6.375Q8.975,8.3 7.5,9.712Q6.025,11.125 4.075,11.85Q4.075,11.9 4.075,11.925Q4.075,11.95 4.075,12Q4.075,15.325 6.375,17.625Q8.675,19.925 12,19.925ZM12,22.2Q9.9,22.2 8.038,21.4Q6.175,20.6 4.788,19.225Q3.4,17.85 2.6,15.988Q1.8,14.125 1.8,12Q1.8,9.875 2.6,8.012Q3.4,6.15 4.788,4.775Q6.175,3.4 8.038,2.6Q9.9,1.8 12,1.8Q14.125,1.8 15.988,2.6Q17.85,3.4 19.225,4.775Q20.6,6.15 21.4,8.012Q22.2,9.875 22.2,12Q22.2,14.125 21.4,15.988Q20.6,17.85 19.225,19.225Q17.85,20.6 15.988,21.4Q14.125,22.2 12,22.2Z"/>
</vector>
 No newline at end of file
+0 −30
Original line number Original line Diff line number Diff line
<!--
  ~ 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.
  -->

<!--TODO: Testing only icon. Remove later. -->

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:ignore="VectorPath"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24"
        android:viewportHeight="24"
        android:tint="?attr/colorControlNormal">
    <path
        android:fillColor="#808080"
        android:pathData="M16.1,21.2 L15.775,19.675Q15.5,19.55 15.25,19.425Q15,19.3 14.75,19.1L13.275,19.575L12.2,17.75L13.375,16.725Q13.325,16.4 13.325,16.112Q13.325,15.825 13.375,15.5L12.2,14.475L13.275,12.65L14.75,13.1Q15,12.925 15.25,12.787Q15.5,12.65 15.775,12.55L16.1,11.025H18.25L18.55,12.55Q18.825,12.65 19.075,12.8Q19.325,12.95 19.575,13.15L21.05,12.65L22.125,14.525L20.95,15.55Q21.025,15.825 21.013,16.137Q21,16.45 20.95,16.725L22.125,17.75L21.05,19.575L19.575,19.1Q19.325,19.3 19.075,19.425Q18.825,19.55 18.55,19.675L18.25,21.2ZM1.8,20.3V17.3Q1.8,16.375 2.275,15.613Q2.75,14.85 3.5,14.475Q4.775,13.825 6.425,13.362Q8.075,12.9 10,12.9Q10.2,12.9 10.4,12.9Q10.6,12.9 10.775,12.95Q9.925,14.85 10.062,16.738Q10.2,18.625 11.4,20.3ZM17.175,18.075Q17.975,18.075 18.55,17.487Q19.125,16.9 19.125,16.1Q19.125,15.3 18.55,14.725Q17.975,14.15 17.175,14.15Q16.375,14.15 15.788,14.725Q15.2,15.3 15.2,16.1Q15.2,16.9 15.788,17.487Q16.375,18.075 17.175,18.075ZM10,11.9Q8.25,11.9 7.025,10.662Q5.8,9.425 5.8,7.7Q5.8,5.95 7.025,4.725Q8.25,3.5 10,3.5Q11.75,3.5 12.975,4.725Q14.2,5.95 14.2,7.7Q14.2,9.425 12.975,10.662Q11.75,11.9 10,11.9Z"/>
</vector>
 No newline at end of file
+2 −6
Original line number Original line Diff line number Diff line
@@ -63,7 +63,7 @@ class CredentialManagerRepo(
    requestInfo = intent.extras?.getParcelable(
    requestInfo = intent.extras?.getParcelable(
      RequestInfo.EXTRA_REQUEST_INFO,
      RequestInfo.EXTRA_REQUEST_INFO,
      RequestInfo::class.java
      RequestInfo::class.java
    ) ?: testCreatePasskeyRequestInfo()
    ) ?: testGetRequestInfo()


    providerEnabledList = when (requestInfo.type) {
    providerEnabledList = when (requestInfo.type) {
      RequestInfo.TYPE_CREATE ->
      RequestInfo.TYPE_CREATE ->
@@ -245,12 +245,10 @@ class CredentialManagerRepo(
          listOf(
          listOf(
            newActionEntry(
            newActionEntry(
              "key3", "subkey-1", TYPE_PASSWORD_CREDENTIAL,
              "key3", "subkey-1", TYPE_PASSWORD_CREDENTIAL,
              Icon.createWithResource(context, R.drawable.ic_manage_accounts),
              "Open Google Password Manager", "elisa.beckett@gmail.com"
              "Open Google Password Manager", "elisa.beckett@gmail.com"
            ),
            ),
            newActionEntry(
            newActionEntry(
              "key3", "subkey-2", TYPE_PASSWORD_CREDENTIAL,
              "key3", "subkey-2", TYPE_PASSWORD_CREDENTIAL,
              Icon.createWithResource(context, R.drawable.ic_manage_accounts),
              "Open Google Password Manager", "beckett-family@gmail.com"
              "Open Google Password Manager", "beckett-family@gmail.com"
            ),
            ),
          )
          )
@@ -275,7 +273,6 @@ class CredentialManagerRepo(
          listOf(
          listOf(
            newActionEntry(
            newActionEntry(
              "key3", "subkey-1", TYPE_PASSWORD_CREDENTIAL,
              "key3", "subkey-1", TYPE_PASSWORD_CREDENTIAL,
              Icon.createWithResource(context, R.drawable.ic_face),
              "Open Enpass"
              "Open Enpass"
            ),
            ),
          )
          )
@@ -287,7 +284,6 @@ class CredentialManagerRepo(
    key: String,
    key: String,
    subkey: String,
    subkey: String,
    credentialType: String,
    credentialType: String,
    icon: Icon,
    text: String,
    text: String,
    subtext: String? = null,
    subtext: String? = null,
  ): Entry {
  ): Entry {
@@ -295,7 +291,7 @@ class CredentialManagerRepo(
      Entry.CREDENTIAL_MANAGER_ENTRY_URI, SliceSpec(credentialType, 1)
      Entry.CREDENTIAL_MANAGER_ENTRY_URI, SliceSpec(credentialType, 1)
    ).addText(
    ).addText(
      text, null, listOf(Entry.HINT_ACTION_TITLE)
      text, null, listOf(Entry.HINT_ACTION_TITLE)
    ).addIcon(icon, null, listOf(Entry.HINT_ACTION_ICON))
    )
    if (subtext != null) {
    if (subtext != null) {
      slice.addText(subtext, null, listOf(Entry.HINT_ACTION_SUBTEXT))
      slice.addText(subtext, null, listOf(Entry.HINT_ACTION_SUBTEXT))
    }
    }
+6 −5
Original line number Original line Diff line number Diff line
@@ -67,7 +67,8 @@ class GetFlowUtils {
          .getPackageInfo(packageName!!,
          .getPackageInfo(packageName!!,
            PackageManager.PackageInfoFlags.of(0))
            PackageManager.PackageInfoFlags.of(0))
        val providerDisplayName = pkgInfo.applicationInfo.loadLabel(packageManager).toString()
        val providerDisplayName = pkgInfo.applicationInfo.loadLabel(packageManager).toString()
        // TODO: decide what to do when failed to load a provider icon
        // TODO: get the provider icon from the service
        //  and decide what to do when failed to load a provider icon
        val providerIcon = pkgInfo.applicationInfo.loadIcon(packageManager)!!
        val providerIcon = pkgInfo.applicationInfo.loadIcon(packageManager)!!
        ProviderInfo(
        ProviderInfo(
          id = it.providerFlattenedComponentName,
          id = it.providerFlattenedComponentName,
@@ -83,7 +84,7 @@ class GetFlowUtils {
            it.authenticationEntry),
            it.authenticationEntry),
          remoteEntry = getRemoteEntry(it.providerFlattenedComponentName, it.remoteEntry),
          remoteEntry = getRemoteEntry(it.providerFlattenedComponentName, it.remoteEntry),
          actionEntryList = getActionEntryList(
          actionEntryList = getActionEntryList(
            it.providerFlattenedComponentName, it.actionChips, context),
            it.providerFlattenedComponentName, it.actionChips, providerIcon),
        )
        )
      }
      }
    }
    }
@@ -119,7 +120,7 @@ class GetFlowUtils {
          displayName = credentialEntryUi.userDisplayName?.toString(),
          displayName = credentialEntryUi.userDisplayName?.toString(),
          // TODO: proper fallback
          // TODO: proper fallback
          icon = credentialEntryUi.entryIcon?.loadDrawable(context)
          icon = credentialEntryUi.entryIcon?.loadDrawable(context)
            ?: context.getDrawable(R.drawable.ic_passkey)!!,
            ?: context.getDrawable(R.drawable.ic_other_sign_in)!!,
          lastUsedTimeMillis = credentialEntryUi.lastUsedTimeMillis,
          lastUsedTimeMillis = credentialEntryUi.lastUsedTimeMillis,
        )
        )
      }
      }
@@ -164,7 +165,7 @@ class GetFlowUtils {
    private fun getActionEntryList(
    private fun getActionEntryList(
      providerId: String,
      providerId: String,
      actionEntries: List<Entry>,
      actionEntries: List<Entry>,
      context: Context,
      providerIcon: Drawable,
    ): List<ActionEntryInfo> {
    ): List<ActionEntryInfo> {
      return actionEntries.map {
      return actionEntries.map {
        val actionEntryUi = ActionUi.fromSlice(it.slice)
        val actionEntryUi = ActionUi.fromSlice(it.slice)
@@ -177,7 +178,7 @@ class GetFlowUtils {
          fillInIntent = it.frameworkExtrasIntent,
          fillInIntent = it.frameworkExtrasIntent,
          title = actionEntryUi.text.toString(),
          title = actionEntryUi.text.toString(),
          // TODO: gracefully fail
          // TODO: gracefully fail
          icon = actionEntryUi.icon.loadDrawable(context)!!,
          icon = providerIcon,
          subTitle = actionEntryUi.subtext?.toString(),
          subTitle = actionEntryUi.subtext?.toString(),
        )
        )
      }
      }
+44 −24
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.credentialmanager.getflow
package com.android.credentialmanager.getflow


import android.credentials.Credential
import android.text.TextUtils
import android.text.TextUtils
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResult
@@ -35,6 +36,7 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.outlined.Lock
import androidx.compose.material3.Divider
import androidx.compose.material3.Divider
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Icon
@@ -189,7 +191,7 @@ fun PrimarySelectionCard(
                color = Color.Transparent
                color = Color.Transparent
            )
            )
            Row(
            Row(
                horizontalArrangement = Arrangement.Start,
                horizontalArrangement = Arrangement.SpaceBetween,
                modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp)
                modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp)
            ) {
            ) {
                CancelButton(stringResource(R.string.get_dialog_button_label_no_thanks), onCancel)
                CancelButton(stringResource(R.string.get_dialog_button_label_no_thanks), onCancel)
@@ -423,11 +425,12 @@ fun CredentialEntryRow(
    Entry(
    Entry(
        onClick = { onEntrySelected(credentialEntryInfo) },
        onClick = { onEntrySelected(credentialEntryInfo) },
        icon = {
        icon = {
            Image(
            Icon(
                modifier = Modifier.padding(start = 10.dp).size(32.dp),
                modifier = Modifier.padding(start = 10.dp).size(32.dp),
                bitmap = credentialEntryInfo.icon.toBitmap().asImageBitmap(),
                bitmap = credentialEntryInfo.icon.toBitmap().asImageBitmap(),
                // TODO: add description.
                // TODO: add description.
                contentDescription = ""
                contentDescription = "",
                tint = LocalAndroidColorScheme.current.colorAccentPrimaryVariant,
            )
            )
        },
        },
        label = {
        label = {
@@ -436,19 +439,24 @@ fun CredentialEntryRow(
                TextOnSurfaceVariant(
                TextOnSurfaceVariant(
                    text = credentialEntryInfo.userName,
                    text = credentialEntryInfo.userName,
                    style = MaterialTheme.typography.titleLarge,
                    style = MaterialTheme.typography.titleLarge,
                    modifier = Modifier.padding(top = 16.dp)
                    modifier = Modifier.padding(top = 16.dp, start = 5.dp)
                )
                )
                TextSecondary(
                TextSecondary(
                    text =
                    text = if (
                        credentialEntryInfo.credentialType == Credential.TYPE_PASSWORD_CREDENTIAL) {
                        "••••••••••••"
                    } else {
                        if (TextUtils.isEmpty(credentialEntryInfo.displayName))
                        if (TextUtils.isEmpty(credentialEntryInfo.displayName))
                            credentialEntryInfo.credentialTypeDisplayName
                            credentialEntryInfo.credentialTypeDisplayName
                        else
                        else
                            credentialEntryInfo.credentialTypeDisplayName +
                            credentialEntryInfo.credentialTypeDisplayName +
                                    stringResource(
                                    stringResource(
                                    R.string.get_dialog_sign_in_type_username_separator) +
                                        R.string.get_dialog_sign_in_type_username_separator
                                credentialEntryInfo.displayName,
                                    ) +
                                    credentialEntryInfo.displayName
                    },
                    style = MaterialTheme.typography.bodyMedium,
                    style = MaterialTheme.typography.bodyMedium,
                    modifier = Modifier.padding(bottom = 16.dp)
                    modifier = Modifier.padding(bottom = 16.dp, start = 5.dp)
                )
                )
            }
            }
        }
        }
@@ -472,6 +480,10 @@ fun AuthenticationEntryRow(
            )
            )
        },
        },
        label = {
        label = {
            Row(
                horizontalArrangement = Arrangement.SpaceBetween,
                modifier = Modifier.fillMaxWidth().padding(horizontal = 5.dp),
                ) {
                Column() {
                Column() {
                    // TODO: fix the text values.
                    // TODO: fix the text values.
                    TextOnSurfaceVariant(
                    TextOnSurfaceVariant(
@@ -485,6 +497,12 @@ fun AuthenticationEntryRow(
                        modifier = Modifier.padding(bottom = 16.dp)
                        modifier = Modifier.padding(bottom = 16.dp)
                    )
                    )
                }
                }
                Icon(
                    Icons.Outlined.Lock,
                    null,
                    Modifier.align(alignment = Alignment.CenterVertically).padding(end = 10.dp),
                )
            }
        }
        }
    )
    )
}
}
@@ -509,11 +527,13 @@ fun ActionEntryRow(
                TextOnSurfaceVariant(
                TextOnSurfaceVariant(
                    text = actionEntryInfo.title,
                    text = actionEntryInfo.title,
                    style = MaterialTheme.typography.titleLarge,
                    style = MaterialTheme.typography.titleLarge,
                    modifier = Modifier.padding(start = 5.dp),
                )
                )
                if (actionEntryInfo.subTitle != null) {
                if (actionEntryInfo.subTitle != null) {
                    TextSecondary(
                    TextSecondary(
                        text = actionEntryInfo.subTitle,
                        text = actionEntryInfo.subTitle,
                        style = MaterialTheme.typography.bodyMedium,
                        style = MaterialTheme.typography.bodyMedium,
                        modifier = Modifier.padding(start = 5.dp),
                    )
                    )
                }
                }
            }
            }
Loading