summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author harinirajan <harinirajan@google.com> 2024-01-29 07:12:30 +0000
committer harinirajan <harinirajan@google.com> 2024-02-06 01:09:44 +0000
commit3e352e4ebf69801ac03f05eadaf08aacfe8cf1f2 (patch)
tree90b6db7b3a0bafc913987e5fbee66a0d41fdd95f
parent6892184b02d5f7a5b6f320731e37bd6b83da4fb9 (diff)
Single provider password screen changes
Test: Manual. See go/credential-selector-ui Bug: 322797031 Change-Id: I3a955f8e5d86bdb4c316daee8009db55fa28cc23
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt6
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/UiState.kt (renamed from packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt)18
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt72
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt43
4 files changed, 69 insertions, 70 deletions
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
index 790f5b1f27f3..f8e22eed90f0 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -58,9 +58,9 @@ fun WearApp(
scrollable(Screen.SinglePasswordScreen.route) {
SinglePasswordScreen(
- state = viewModel.uiState.value as SingleEntry,
+ credentialSelectorUiState = viewModel.uiState.value as SingleEntry,
+ screenIcon = null,
columnState = it.columnState,
- onCloseApp = onCloseApp,
)
}
}
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/UiState.kt
index 52bbfaa818ed..42a88e2ea303 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/UiState.kt
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2024 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.0N
+ * 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,
@@ -14,6 +14,16 @@
* limitations under the License.
*/
-package com.android.credentialmanager.ui.model
+package com.android.credentialmanager.ui.screens.single
-data class PasswordUiModel(val email: String)
+import androidx.activity.result.IntentSenderRequest
+
+sealed class UiState {
+ data object CredentialScreen : UiState()
+
+ data class CredentialSelected(
+ val intentSenderRequest: IntentSenderRequest?
+ ) : UiState()
+
+ data object Cancel : UiState()
+} \ No newline at end of file
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
index 95ef7dbfef30..a8be94466a2e 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
@@ -18,8 +18,9 @@
package com.android.credentialmanager.ui.screens.single.password
-import android.util.Log
+import android.graphics.drawable.Drawable
import androidx.activity.compose.rememberLauncherForActivityResult
+import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
@@ -29,47 +30,52 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.android.credentialmanager.CredentialSelectorUiState.Get.SingleEntry
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.rememberNavController
+import com.android.credentialmanager.CredentialSelectorUiState
import com.android.credentialmanager.R
-import com.android.credentialmanager.TAG
import com.android.credentialmanager.activity.StartBalIntentSenderForResultContract
import com.android.credentialmanager.ui.components.PasswordRow
+import com.android.credentialmanager.ui.components.ContinueChip
+import com.android.credentialmanager.ui.components.DismissChip
import com.android.credentialmanager.ui.components.SignInHeader
-import com.android.credentialmanager.ui.model.PasswordUiModel
+import com.android.credentialmanager.ui.components.SignInOptionsChip
import com.android.credentialmanager.ui.screens.single.SingleAccountScreen
+import com.android.credentialmanager.model.get.CredentialEntryInfo
+import com.android.credentialmanager.ui.screens.single.UiState
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.compose.layout.ScalingLazyColumnState
+@OptIn(ExperimentalHorologistApi::class)
@Composable
fun SinglePasswordScreen(
- state: SingleEntry,
+ credentialSelectorUiState: CredentialSelectorUiState.Get.SingleEntry,
+ screenIcon: Drawable?,
columnState: ScalingLazyColumnState,
- onCloseApp: () -> Unit,
modifier: Modifier = Modifier,
viewModel: SinglePasswordScreenViewModel = hiltViewModel(),
+ navController: NavHostController = rememberNavController(),
) {
- viewModel.initialize(state.entry)
+ viewModel.initialize(credentialSelectorUiState.entry)
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
when (val state = uiState) {
- SinglePasswordScreenUiState.Idle -> {
- // TODO: b/301206470 implement latency version of the screen
- }
-
- is SinglePasswordScreenUiState.Loaded -> {
+ UiState.CredentialScreen -> {
SinglePasswordScreen(
- passwordUiModel = state.passwordUiModel,
- columnState = columnState,
- modifier = modifier
+ credentialSelectorUiState.entry,
+ screenIcon,
+ columnState,
+ modifier,
+ viewModel
)
}
- is SinglePasswordScreenUiState.PasswordSelected -> {
+ is UiState.CredentialSelected -> {
val launcher = rememberLauncherForActivityResult(
StartBalIntentSenderForResultContract()
) {
- viewModel.onPasswordInfoRetrieved(it.resultCode, it.data)
+ viewModel.onPasswordInfoRetrieved(it.resultCode, null)
}
SideEffect {
@@ -79,37 +85,32 @@ fun SinglePasswordScreen(
}
}
- SinglePasswordScreenUiState.Cancel -> {
- // TODO: b/301206470 implement navigation for when user taps cancel
- }
-
- SinglePasswordScreenUiState.Error -> {
- // TODO: b/301206470 implement navigation for when there is an error to load screen
- }
-
- SinglePasswordScreenUiState.Completed -> {
- Log.d(TAG, "Received signal to finish the activity.")
- onCloseApp()
+ UiState.Cancel -> {
+ // TODO(b/322797032) add valid navigation path here for going back
+ navController.popBackStack()
}
}
}
+@OptIn(ExperimentalHorologistApi::class)
@Composable
-fun SinglePasswordScreen(
- passwordUiModel: PasswordUiModel,
+private fun SinglePasswordScreen(
+ entry: CredentialEntryInfo,
+ screenIcon: Drawable?,
columnState: ScalingLazyColumnState,
modifier: Modifier = Modifier,
+ viewModel: SinglePasswordScreenViewModel,
) {
SingleAccountScreen(
headerContent = {
SignInHeader(
- icon = null,
+ icon = screenIcon,
title = stringResource(R.string.use_password_title),
)
},
accountContent = {
PasswordRow(
- email = passwordUiModel.email,
+ email = entry.userName,
modifier = Modifier.padding(top = 10.dp),
)
},
@@ -117,6 +118,13 @@ fun SinglePasswordScreen(
modifier = modifier.padding(horizontal = 10.dp)
) {
item {
+ Column {
+ ContinueChip(viewModel::onContinueClick)
+ SignInOptionsChip(viewModel::onSignInOptionsClick)
+ DismissChip(viewModel::onDismissClick)
+ }
}
}
}
+
+
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt
index c9c66b4a7271..3f841b8af146 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt
@@ -17,16 +17,15 @@
package com.android.credentialmanager.ui.screens.single.password
import android.content.Intent
-import android.credentials.selection.ProviderPendingIntentResponse
import android.credentials.selection.UserSelectionDialogResult
-import androidx.activity.result.IntentSenderRequest
+import android.credentials.selection.ProviderPendingIntentResponse
import androidx.annotation.MainThread
import androidx.lifecycle.ViewModel
import com.android.credentialmanager.ktx.getIntentSenderRequest
import com.android.credentialmanager.model.Request
import com.android.credentialmanager.client.CredentialManagerClient
import com.android.credentialmanager.model.get.CredentialEntryInfo
-import com.android.credentialmanager.ui.model.PasswordUiModel
+import com.android.credentialmanager.ui.screens.single.UiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -37,36 +36,31 @@ class SinglePasswordScreenViewModel @Inject constructor(
private val credentialManagerClient: CredentialManagerClient,
) : ViewModel() {
- private var initializeCalled = false
-
private lateinit var requestGet: Request.Get
private lateinit var entryInfo: CredentialEntryInfo
private val _uiState =
- MutableStateFlow<SinglePasswordScreenUiState>(SinglePasswordScreenUiState.Idle)
- val uiState: StateFlow<SinglePasswordScreenUiState> = _uiState
+ MutableStateFlow<UiState>(UiState.CredentialScreen)
+ val uiState: StateFlow<UiState> = _uiState
@MainThread
fun initialize(entryInfo: CredentialEntryInfo) {
- if (initializeCalled) return
- initializeCalled = true
- _uiState.value = SinglePasswordScreenUiState.Loaded(
- PasswordUiModel(
- email = entryInfo.userName,
- )
- )
+ this.entryInfo = entryInfo
}
- fun onCancelClick() {
- _uiState.value = SinglePasswordScreenUiState.Cancel
+ fun onDismissClick() {
+ _uiState.value = UiState.Cancel
}
- fun onOKClick() {
- _uiState.value = SinglePasswordScreenUiState.PasswordSelected(
+ fun onContinueClick() {
+ _uiState.value = UiState.CredentialSelected(
intentSenderRequest = entryInfo.getIntentSenderRequest()
)
}
+ fun onSignInOptionsClick() {
+ }
+
fun onPasswordInfoRetrieved(
resultCode: Int? = null,
resultData: Intent? = null,
@@ -79,18 +73,5 @@ class SinglePasswordScreenViewModel @Inject constructor(
if (resultCode != null) ProviderPendingIntentResponse(resultCode, resultData) else null
)
credentialManagerClient.sendResult(userSelectionDialogResult)
- _uiState.value = SinglePasswordScreenUiState.Completed
}
}
-
-sealed class SinglePasswordScreenUiState {
- data object Idle : SinglePasswordScreenUiState()
- data class Loaded(val passwordUiModel: PasswordUiModel) : SinglePasswordScreenUiState()
- data class PasswordSelected(
- val intentSenderRequest: IntentSenderRequest?
- ) : SinglePasswordScreenUiState()
-
- data object Cancel : SinglePasswordScreenUiState()
- data object Error : SinglePasswordScreenUiState()
- data object Completed : SinglePasswordScreenUiState()
-}