diff options
7 files changed, 162 insertions, 56 deletions
diff --git a/packages/CredentialManager/res/values/themes.xml b/packages/CredentialManager/res/values/themes.xml index feec74608000..a58a0383b9b2 100644 --- a/packages/CredentialManager/res/values/themes.xml +++ b/packages/CredentialManager/res/values/themes.xml @@ -2,11 +2,12 @@ <resources> <style name="Theme.CredentialSelector" parent="@android:style/ThemeOverlay.Material"> - <item name="android:statusBarColor">@color/purple_700</item> + <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item> <item name="android:colorBackgroundCacheHint">@null</item> + <item name="fontFamily">google-sans</item> </style> </resources>
\ No newline at end of file diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt new file mode 100644 index 000000000000..51a1cbbbf942 --- /dev/null +++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt @@ -0,0 +1,68 @@ +/* + * 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.common.ui + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SuggestionChip +import androidx.compose.material3.SuggestionChipDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import com.android.credentialmanager.ui.theme.EntryShape +import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Entry( + onClick: () -> Unit, + label: @Composable () -> Unit, + modifier: Modifier = Modifier, + icon: @Composable (() -> Unit)? = null, +) { + SuggestionChip( + modifier = modifier.fillMaxWidth(), + onClick = onClick, + shape = EntryShape.FullSmallRoundedCorner, + label = label, + icon = icon, + border = null, + colors = SuggestionChipDefaults.suggestionChipColors( + containerColor = LocalAndroidColorScheme.current.colorSurface, + ), + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun TransparentBackgroundEntry( + onClick: () -> Unit, + label: @Composable () -> Unit, + modifier: Modifier = Modifier, + icon: @Composable (() -> Unit)? = null, +) { + SuggestionChip( + modifier = modifier.fillMaxWidth(), + onClick = onClick, + label = label, + icon = icon, + border = null, + colors = SuggestionChipDefaults.suggestionChipColors( + containerColor = Color.Transparent, + ), + ) +}
\ No newline at end of file diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt index dbb33c8233dd..27d366d55937 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt @@ -17,7 +17,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.SuggestionChip import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar @@ -43,6 +42,7 @@ import com.android.credentialmanager.common.material.ModalBottomSheetValue import com.android.credentialmanager.common.material.rememberModalBottomSheetState import com.android.credentialmanager.common.ui.CancelButton import com.android.credentialmanager.common.ui.ConfirmButton +import com.android.credentialmanager.common.ui.Entry import com.android.credentialmanager.ui.theme.EntryShape import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL @@ -184,7 +184,7 @@ fun ProviderSelectionCard( color = Color.Transparent ) Card( - shape = EntryShape.FullRoundedCorner, + shape = MaterialTheme.shapes.medium, modifier = Modifier .padding(horizontal = 24.dp) .align(alignment = Alignment.CenterHorizontally), @@ -257,7 +257,7 @@ fun MoreOptionsSelectionCard( color = Color.Transparent ) Card( - shape = EntryShape.FullRoundedCorner, + shape = MaterialTheme.shapes.medium, modifier = Modifier .padding(horizontal = 24.dp) .align(alignment = Alignment.CenterHorizontally) @@ -356,20 +356,17 @@ fun MoreOptionsRowIntroCard( } } -@OptIn(ExperimentalMaterial3Api::class) @Composable fun ProviderRow(providerInfo: ProviderInfo, onProviderSelected: (String) -> Unit) { - SuggestionChip( - modifier = Modifier.fillMaxWidth(), + Entry( onClick = {onProviderSelected(providerInfo.name)}, icon = { - Image(modifier = Modifier.size(24.dp, 24.dp).padding(start = 10.dp), + Image(modifier = Modifier.size(32.dp).padding(start = 10.dp), bitmap = providerInfo.icon.toBitmap().asImageBitmap(), // painter = painterResource(R.drawable.ic_passkey), // TODO: add description. contentDescription = "") }, - shape = EntryShape.FullRoundedCorner, label = { Text( text = providerInfo.displayName, @@ -433,7 +430,7 @@ fun CreationSelectionCard( ) } Card( - shape = EntryShape.FullRoundedCorner, + shape = MaterialTheme.shapes.medium, modifier = Modifier .padding(horizontal = 24.dp) .align(alignment = Alignment.CenterHorizontally), @@ -499,15 +496,13 @@ fun PrimaryCreateOptionRow( createOptionInfo: CreateOptionInfo, onOptionSelected: () -> Unit ) { - SuggestionChip( - modifier = Modifier.fillMaxWidth(), + Entry( onClick = onOptionSelected, icon = { - Image(modifier = Modifier.size(24.dp, 24.dp).padding(start = 10.dp), + Image(modifier = Modifier.size(32.dp).padding(start = 10.dp), bitmap = createOptionInfo.credentialTypeIcon.toBitmap().asImageBitmap(), contentDescription = null) }, - shape = EntryShape.FullRoundedCorner, label = { Column() { // TODO: Add the function to hide/view password when the type is create password @@ -542,15 +537,13 @@ fun MoreOptionsInfoRow( createOptionInfo: CreateOptionInfo, onOptionSelected: () -> Unit ) { - SuggestionChip( - modifier = Modifier.fillMaxWidth(), + Entry( onClick = onOptionSelected, icon = { - Image(modifier = Modifier.size(32.dp, 32.dp).padding(start = 16.dp), + Image(modifier = Modifier.size(32.dp).padding(start = 16.dp), bitmap = providerInfo.icon.toBitmap().asImageBitmap(), contentDescription = null) }, - shape = EntryShape.FullRoundedCorner, label = { Column() { Text( @@ -611,8 +604,7 @@ fun MoreOptionsDisabledProvidersRow( disabledProviders: List<ProviderInfo>, onDisabledPasswordManagerSelected: () -> Unit, ) { - SuggestionChip( - modifier = Modifier.fillMaxWidth(), + Entry( onClick = onDisabledPasswordManagerSelected, icon = { Icon( @@ -621,7 +613,6 @@ fun MoreOptionsDisabledProvidersRow( modifier = Modifier.padding(start = 16.dp) ) }, - shape = EntryShape.FullRoundedCorner, label = { Column() { Text( @@ -644,8 +635,7 @@ fun MoreOptionsDisabledProvidersRow( fun RemoteEntryRow( onRemoteEntrySelected: () -> Unit, ) { - SuggestionChip( - modifier = Modifier.fillMaxWidth(), + Entry( onClick = onRemoteEntrySelected, icon = { Icon( @@ -655,7 +645,6 @@ fun RemoteEntryRow( modifier = Modifier.padding(start = 18.dp) ) }, - shape = EntryShape.FullRoundedCorner, label = { Column() { Text( diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt index dcdd71a283a8..6fd51dd3b69a 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt @@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.Card @@ -33,7 +34,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.SuggestionChip import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -46,6 +46,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.core.graphics.drawable.toBitmap import com.android.credentialmanager.R @@ -53,6 +54,8 @@ import com.android.credentialmanager.common.material.ModalBottomSheetLayout import com.android.credentialmanager.common.material.ModalBottomSheetValue import com.android.credentialmanager.common.material.rememberModalBottomSheetState import com.android.credentialmanager.common.ui.CancelButton +import com.android.credentialmanager.common.ui.Entry +import com.android.credentialmanager.common.ui.TransparentBackgroundEntry import com.android.credentialmanager.jetpack.developer.PublicKeyCredential @Composable @@ -107,6 +110,9 @@ fun PrimarySelectionCard( Card() { Column() { Text( + modifier = Modifier.padding(all = 24.dp), + textAlign = TextAlign.Center, + style = MaterialTheme.typography.headlineSmall, text = stringResource( if (sortedUserNameToCredentialEntryList.size == 1) { if (sortedUserNameToCredentialEntryList.first().sortedCredentialEntryList @@ -117,12 +123,10 @@ fun PrimarySelectionCard( } else R.string.get_dialog_title_choose_sign_in_for, requestDisplayInfo.appDomainName ), - style = MaterialTheme.typography.titleMedium, - modifier = Modifier.padding(all = 24.dp).align(alignment = Alignment.CenterHorizontally) ) Card( - shape = MaterialTheme.shapes.large, + shape = MaterialTheme.shapes.medium, modifier = Modifier .padding(horizontal = 24.dp) .align(alignment = Alignment.CenterHorizontally) @@ -254,9 +258,14 @@ fun ActionChips( modifier = Modifier.padding(vertical = 8.dp) ) // TODO: tweak padding. - Column(verticalArrangement = Arrangement.spacedBy(2.dp)) { - actionChips.forEach { - ActionEntryRow(it, onEntrySelected) + Card( + modifier = Modifier.fillMaxWidth().wrapContentHeight(), + shape = MaterialTheme.shapes.medium, + ) { + Column(verticalArrangement = Arrangement.spacedBy(2.dp)) { + actionChips.forEach { + ActionEntryRow(it, onEntrySelected) + } } } } @@ -271,8 +280,18 @@ fun LockedCredentials( style = MaterialTheme.typography.labelLarge, modifier = Modifier.padding(vertical = 8.dp) ) - authenticationEntryList.forEach { - AuthenticationEntryRow(it, onEntrySelected) + Card( + modifier = Modifier.fillMaxWidth().wrapContentHeight(), + shape = MaterialTheme.shapes.medium, + ) { + Column( + modifier = Modifier.fillMaxWidth().wrapContentHeight(), + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + authenticationEntryList.forEach { + AuthenticationEntryRow(it, onEntrySelected) + } + } } } @@ -287,8 +306,18 @@ fun PerUserNameCredentials( style = MaterialTheme.typography.labelLarge, modifier = Modifier.padding(vertical = 8.dp) ) - perUserNameCredentialEntryList.sortedCredentialEntryList.forEach { - CredentialEntryRow(it, onEntrySelected) + Card( + modifier = Modifier.fillMaxWidth().wrapContentHeight(), + shape = MaterialTheme.shapes.medium, + ) { + Column( + modifier = Modifier.fillMaxWidth().wrapContentHeight(), + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + perUserNameCredentialEntryList.sortedCredentialEntryList.forEach { + CredentialEntryRow(it, onEntrySelected) + } + } } } @@ -298,16 +327,14 @@ fun CredentialEntryRow( credentialEntryInfo: CredentialEntryInfo, onEntrySelected: (EntryInfo) -> Unit, ) { - SuggestionChip( - modifier = Modifier.fillMaxWidth(), + Entry( onClick = {onEntrySelected(credentialEntryInfo)}, icon = { - Image(modifier = Modifier.size(24.dp, 24.dp).padding(start = 10.dp), + Image(modifier = Modifier.padding(start = 10.dp).size(32.dp), bitmap = credentialEntryInfo.icon.toBitmap().asImageBitmap(), // TODO: add description. contentDescription = "") }, - shape = MaterialTheme.shapes.large, label = { Column() { // TODO: fix the text values. @@ -338,16 +365,14 @@ fun AuthenticationEntryRow( authenticationEntryInfo: AuthenticationEntryInfo, onEntrySelected: (EntryInfo) -> Unit, ) { - SuggestionChip( - modifier = Modifier.fillMaxWidth(), + Entry( onClick = {onEntrySelected(authenticationEntryInfo)}, icon = { - Image(modifier = Modifier.size(24.dp, 24.dp).padding(start = 10.dp), + Image(modifier = Modifier.padding(start = 10.dp).size(32.dp), bitmap = authenticationEntryInfo.icon.toBitmap().asImageBitmap(), // TODO: add description. contentDescription = "") }, - shape = MaterialTheme.shapes.large, label = { Column() { // TODO: fix the text values. @@ -372,16 +397,13 @@ fun ActionEntryRow( actionEntryInfo: ActionEntryInfo, onEntrySelected: (EntryInfo) -> Unit, ) { - SuggestionChip( - modifier = Modifier.fillMaxWidth(), - onClick = { onEntrySelected(actionEntryInfo) }, + TransparentBackgroundEntry( icon = { - Image(modifier = Modifier.size(24.dp, 24.dp).padding(start = 10.dp), + Image(modifier = Modifier.padding(start = 10.dp).size(32.dp), bitmap = actionEntryInfo.icon.toBitmap().asImageBitmap(), // TODO: add description. contentDescription = "") }, - shape = MaterialTheme.shapes.large, label = { Column() { Text( @@ -395,17 +417,16 @@ fun ActionEntryRow( ) } } - } + }, + onClick = { onEntrySelected(actionEntryInfo) }, ) } @OptIn(ExperimentalMaterial3Api::class) @Composable fun SignInAnotherWayRow(onSelect: () -> Unit) { - SuggestionChip( - modifier = Modifier.fillMaxWidth(), + Entry( onClick = onSelect, - shape = MaterialTheme.shapes.large, label = { Text( text = stringResource(R.string.get_dialog_use_saved_passkey_for), diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt index c1d9ea9b9188..c541e08ffbb4 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt @@ -64,8 +64,6 @@ class CredentialEntryInfo( val lastUsedTimeMillis: Long?, ) : EntryInfo(providerId, entryKey, entrySubkey) -// TODO: handle sub credential type values like password obfuscation. - class AuthenticationEntryInfo( providerId: String, entryKey: String, diff --git a/packages/CredentialManager/src/com/android/credentialmanager/ui/theme/AndroidColorScheme.kt b/packages/CredentialManager/src/com/android/credentialmanager/ui/theme/AndroidColorScheme.kt index e0954ad13348..15ae3295416b 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/ui/theme/AndroidColorScheme.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/ui/theme/AndroidColorScheme.kt @@ -39,7 +39,32 @@ val LocalAndroidColorScheme = */ class AndroidColorScheme internal constructor(context: Context) { + val colorPrimary = getColor(context, R.attr.colorPrimary) + val colorPrimaryDark = getColor(context, R.attr.colorPrimaryDark) + val colorAccent = getColor(context, R.attr.colorAccent) + val colorAccentPrimary = getColor(context, R.attr.colorAccentPrimary) + val colorAccentSecondary = getColor(context, R.attr.colorAccentSecondary) + val colorAccentTertiary = getColor(context, R.attr.colorAccentTertiary) + val colorAccentPrimaryVariant = getColor(context, R.attr.colorAccentPrimaryVariant) + val colorAccentSecondaryVariant = getColor(context, R.attr.colorAccentSecondaryVariant) + val colorAccentTertiaryVariant = getColor(context, R.attr.colorAccentTertiaryVariant) + val colorSurface = getColor(context, R.attr.colorSurface) val colorSurfaceHighlight = getColor(context, R.attr.colorSurfaceHighlight) + val colorSurfaceVariant = getColor(context, R.attr.colorSurfaceVariant) + val colorSurfaceHeader = getColor(context, R.attr.colorSurfaceHeader) + val colorError = getColor(context, R.attr.colorError) + val colorBackground = getColor(context, R.attr.colorBackground) + val colorBackgroundFloating = getColor(context, R.attr.colorBackgroundFloating) + val panelColorBackground = getColor(context, R.attr.panelColorBackground) + val textColorPrimary = getColor(context, R.attr.textColorPrimary) + val textColorSecondary = getColor(context, R.attr.textColorSecondary) + val textColorTertiary = getColor(context, R.attr.textColorTertiary) + val textColorPrimaryInverse = getColor(context, R.attr.textColorPrimaryInverse) + val textColorSecondaryInverse = getColor(context, R.attr.textColorSecondaryInverse) + val textColorTertiaryInverse = getColor(context, R.attr.textColorTertiaryInverse) + val textColorOnAccent = getColor(context, R.attr.textColorOnAccent) + val colorForeground = getColor(context, R.attr.colorForeground) + val colorForegroundInverse = getColor(context, R.attr.colorForegroundInverse) private fun getColor(context: Context, attr: Int): Color { val ta = context.obtainStyledAttributes(intArrayOf(attr)) diff --git a/packages/CredentialManager/src/com/android/credentialmanager/ui/theme/Shape.kt b/packages/CredentialManager/src/com/android/credentialmanager/ui/theme/Shape.kt index 32def89be06a..d8a8f162ba40 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/ui/theme/Shape.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/ui/theme/Shape.kt @@ -6,11 +6,15 @@ import androidx.compose.ui.unit.dp val Shapes = Shapes( small = RoundedCornerShape(100.dp), - medium = RoundedCornerShape(20.dp), + medium = RoundedCornerShape(28.dp), large = RoundedCornerShape(0.dp) ) object EntryShape { val TopRoundedCorner = RoundedCornerShape(28.dp, 28.dp, 0.dp, 0.dp) - val FullRoundedCorner = RoundedCornerShape(28.dp, 28.dp, 28.dp, 28.dp) + val BottomRoundedCorner = RoundedCornerShape(0.dp, 0.dp, 28.dp, 28.dp) + // Used for middle entries. + val FullSmallRoundedCorner = RoundedCornerShape(4.dp, 4.dp, 4.dp, 4.dp) + // Used for when there's a single entry. + val FullMediumRoundedCorner = RoundedCornerShape(28.dp, 28.dp, 28.dp, 28.dp) } |