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

Commit 54c14716 authored by Shuang Hao's avatar Shuang Hao Committed by Android (Google) Code Review
Browse files

Merge "Move UI state from ViewModel to FlowEngine. WearApp has then no...

Merge "Move UI state from ViewModel to FlowEngine. WearApp has then no directly dependency to activity ViewModel" into main
parents 04f59b8f a67783c8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ class CredentialSelectorActivity : Hilt_CredentialSelectorActivity() {
        setContent {
            MaterialTheme {
                WearApp(
                    viewModel = viewModel,
                    flowEngine = viewModel,
                    onCloseApp = { finish() },
                )
            }
+1 −30
Original line number Diff line number Diff line
@@ -24,9 +24,6 @@ import com.android.credentialmanager.CredentialSelectorUiState.Get
import com.android.credentialmanager.model.Request
import com.android.credentialmanager.client.CredentialManagerClient
import com.android.credentialmanager.model.EntryInfo
import com.android.credentialmanager.model.get.ActionEntryInfo
import com.android.credentialmanager.model.get.AuthenticationEntryInfo
import com.android.credentialmanager.model.get.CredentialEntryInfo
import com.android.credentialmanager.ui.mappers.toGet
import android.util.Log
import androidx.activity.compose.rememberLauncherForActivityResult
@@ -53,7 +50,7 @@ class CredentialSelectorViewModel @Inject constructor(
    private val shouldClose = MutableStateFlow(false)
    private lateinit var selectedEntry: EntryInfo
    private var isAutoSelected: Boolean = false
    val uiState: StateFlow<CredentialSelectorUiState> =
    override val uiState: StateFlow<CredentialSelectorUiState> =
        combine(
            credentialManagerClient.requests,
            isPrimaryScreen,
@@ -137,29 +134,3 @@ class CredentialSelectorViewModel @Inject constructor(
    }
}
sealed class CredentialSelectorUiState {
    data object Idle : CredentialSelectorUiState()
    sealed class Get : CredentialSelectorUiState() {
        data class SingleEntry(val entry: CredentialEntryInfo) : Get()
        data class SingleEntryPerAccount(
            val sortedEntries: List<CredentialEntryInfo>,
            val authenticationEntryList: List<AuthenticationEntryInfo>,
            ) : Get()
        data class MultipleEntry(
            val accounts: List<PerUserNameEntries>,
            val actionEntryList: List<ActionEntryInfo>,
            val authenticationEntryList: List<AuthenticationEntryInfo>,
        ) : Get() {
            data class PerUserNameEntries(
                val userName: String,
                val sortedCredentialEntryList: List<CredentialEntryInfo>,
            )
        }

        // TODO: b/301206470 add the remaining states
    }

    data object Create : CredentialSelectorUiState()
    data class Cancel(val appName: String) : CredentialSelectorUiState()
    data object Close : CredentialSelectorUiState()
}
+42 −0
Original line number Diff line number Diff line
@@ -20,9 +20,15 @@ import android.content.Intent
import androidx.activity.result.IntentSenderRequest
import androidx.compose.runtime.Composable
import com.android.credentialmanager.model.EntryInfo
import com.android.credentialmanager.model.get.ActionEntryInfo
import com.android.credentialmanager.model.get.AuthenticationEntryInfo
import com.android.credentialmanager.model.get.CredentialEntryInfo
import kotlinx.coroutines.flow.StateFlow

/** Engine of the credential selecting flow. */
interface FlowEngine {
    /** UI state of the selector app */
    val uiState: StateFlow<CredentialSelectorUiState>
    /** Back from previous stage. */
    fun back()
    /** Cancels the selection flow. */
@@ -55,3 +61,39 @@ interface FlowEngine {
    @Composable
    fun getEntrySelector(): (entry: EntryInfo, isAutoSelected: Boolean) -> Unit
}

/** UI state of the selector app */
sealed class CredentialSelectorUiState {
    /** Idle UI state, no request is going on. */
    data object Idle : CredentialSelectorUiState()
    /** Getting credential UI state. */
    sealed class Get : CredentialSelectorUiState() {
        /** Getting credential UI state when there is only one credential available. */
        data class SingleEntry(val entry: CredentialEntryInfo) : Get()
        /**
         * Getting credential UI state when there is only one account while with multiple
         * credentials, with different types(eg, passkey vs password) or providers.
         */
        data class SingleEntryPerAccount(
            val sortedEntries: List<CredentialEntryInfo>,
            val authenticationEntryList: List<AuthenticationEntryInfo>,
            ) : Get()
        /** Getting credential UI state when there are multiple accounts available. */
        data class MultipleEntry(
            val accounts: List<PerUserNameEntries>,
            val actionEntryList: List<ActionEntryInfo>,
            val authenticationEntryList: List<AuthenticationEntryInfo>,
        ) : Get() {
            data class PerUserNameEntries(
                val userName: String,
                val sortedCredentialEntryList: List<CredentialEntryInfo>,
            )
        }
    }
    /** Creating credential UI state. */
    data object Create : CredentialSelectorUiState()
    /** Request is cancelling by [appName]. */
    data class Cancel(val appName: String) : CredentialSelectorUiState()
    /** Request is closed peacefully. */
    data object Close : CredentialSelectorUiState()
}
 No newline at end of file
+3 −5
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import com.android.credentialmanager.CredentialSelectorUiState
import com.android.credentialmanager.CredentialSelectorUiState.Get.SingleEntryPerAccount
import com.android.credentialmanager.CredentialSelectorUiState.Get.SingleEntry
import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry
import com.android.credentialmanager.CredentialSelectorViewModel
import com.android.credentialmanager.FlowEngine
import com.android.credentialmanager.TAG
import com.android.credentialmanager.ui.screens.LoadingScreen
@@ -52,8 +51,7 @@ import com.android.credentialmanager.ui.screens.multiple.MultiCredentialsFlatten
@OptIn(ExperimentalHorologistApi::class)
@Composable
fun WearApp(
    viewModel: CredentialSelectorViewModel,
    flowEngine: FlowEngine = viewModel,
    flowEngine: FlowEngine,
    onCloseApp: () -> Unit,
) {
    val navController = rememberSwipeDismissableNavController()
@@ -62,7 +60,7 @@ fun WearApp(
        rememberSwipeDismissableNavHostState(swipeToDismissBoxState = swipeToDismissBoxState)
    val selectEntry = flowEngine.getEntrySelector()

    val uiState by viewModel.uiState.collectAsStateWithLifecycle()
    val uiState by flowEngine.uiState.collectAsStateWithLifecycle()
    WearNavScaffold(
        startDestination = Screen.Loading.route,
        navController = navController,
@@ -112,7 +110,7 @@ fun WearApp(
        }
    }
        BackHandler(true) {
            viewModel.back()
            flowEngine.back()
        }
        Log.d(TAG, "uiState change, state: $uiState")
        when (val state = uiState) {