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

Commit 5d2542f6 authored by shuanghao's avatar shuanghao
Browse files

Handle cancellation flow.

Cancellation need to be report back to credential manager service so it can end ongoing request peacefully.

BUG: 300422310
Test: Manual.
Change-Id: I86fbf3149ab903e8d28f5ce827d44bee3d3e7bdd
parent e83bd36c
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -31,10 +31,7 @@ interface CredentialManagerClient {
    fun updateRequest(intent: Intent)

    /** Sends an error encountered during the UI. */
    fun sendError(
        @BaseDialogResult.ResultCode resultCode: Int,
        errorMessage: String? = null,
    )
    fun sendError(@BaseDialogResult.ResultCode resultCode: Int)

    /**
     * Sends a response to the system service. The response
+11 −6
Original line number Diff line number Diff line
@@ -48,9 +48,13 @@ class CredentialManagerClientImpl @Inject constructor(


    override fun updateRequest(intent: Intent) {
        val request = intent.parse(
            context = context,
        )
        val request: Request
        try {
            request = intent.parse(context)
        } catch (e: Exception) {
            sendError(BaseDialogResult.RESULT_CODE_DATA_PARSING_FAILURE)
            return
        }
        Log.d(TAG, "Request parsed: $request, client instance: $this")
        if (request is Request.Cancel || request is Request.Close) {
            if (request.token != null && request.token != _requests.value?.token) {
@@ -61,8 +65,9 @@ class CredentialManagerClientImpl @Inject constructor(
        _requests.value = request
    }

    override fun sendError(resultCode: Int, errorMessage: String?) {
        TODO("b/300422310 - [Wear] Implement UI for cancellation request with message")
    override fun sendError(resultCode: Int) {
        Log.w(TAG, "Error occurred, resultCode: $resultCode, current request: ${ requests.value }")
        requests.value?.sendCancellationCode(resultCode)
    }

    override fun sendResult(result: UserSelectionDialogResult) {
@@ -108,7 +113,7 @@ class CredentialManagerClientImpl @Inject constructor(
        return entryInfo.shouldTerminateUiUponSuccessfulProviderResult
    }

    private fun Request.Get.sendCancellationCode(cancelCode: Int) {
    private fun Request.sendCancellationCode(cancelCode: Int) {
        sendCancellationCode(
            cancelCode = cancelCode,
            requestToken = token,
+5 −3
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import com.android.credentialmanager.model.get.ProviderInfo
 */
sealed class Request private constructor(
    open val token: IBinder?,
    open val resultReceiver: ResultReceiver? = null,
    open val finalResponseReceiver: ResultReceiver? = null,
) {

    /**
@@ -48,10 +50,10 @@ sealed class Request private constructor(
     */
    data class Get(
        override val token: IBinder?,
        val resultReceiver: ResultReceiver?,
        val finalResponseReceiver: ResultReceiver?,
        override val resultReceiver: ResultReceiver?,
        override val finalResponseReceiver: ResultReceiver?,
        val providerInfos: List<ProviderInfo>,
    ) : Request(token)
    ) : Request(token, resultReceiver, finalResponseReceiver)
    /**
     * Request to start the create credentials flow.
     */
+1 −0
Original line number Diff line number Diff line
@@ -19,5 +19,6 @@ package com.android.credentialmanager
import android.app.Application
import dagger.hilt.android.HiltAndroidApp

/** [Application] of credential selector. */
@HiltAndroidApp(Application::class)
class CredentialSelectorApp : Hilt_CredentialSelectorApp()
 No newline at end of file
+14 −11
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.credentialmanager

import android.content.Intent
import android.credentials.selection.BaseDialogResult
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.android.credentialmanager.CredentialSelectorUiState.Get
@@ -27,6 +28,10 @@ import com.android.credentialmanager.model.get.ActionEntryInfo
import com.android.credentialmanager.model.get.CredentialEntryInfo
import com.android.credentialmanager.ui.mappers.toGet
import android.util.Log
import com.android.credentialmanager.CredentialSelectorUiState.Cancel
import com.android.credentialmanager.CredentialSelectorUiState.Close
import com.android.credentialmanager.CredentialSelectorUiState.Create
import com.android.credentialmanager.CredentialSelectorUiState.Idle
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -49,21 +54,21 @@ class CredentialSelectorViewModel @Inject constructor(
        ) { request, isPrimary, shouldClose ->
            if (shouldClose) {
                Log.d(TAG, "Request finished, closing ")
                return@combine CredentialSelectorUiState.Close
                return@combine Close
            }

            when (request) {
                null -> CredentialSelectorUiState.Idle
                is Request.Cancel -> CredentialSelectorUiState.Cancel(request.appName)
                is Request.Close -> CredentialSelectorUiState.Close
                is Request.Create -> CredentialSelectorUiState.Create
                null -> Idle
                is Request.Cancel -> Cancel(request.appName)
                is Request.Close -> Close
                is Request.Create -> Create
                is Request.Get -> request.toGet(isPrimary)
            }
        }
        .stateIn(
            viewModelScope,
            started = SharingStarted.WhileSubscribed(5000),
            initialValue = CredentialSelectorUiState.Idle,
            initialValue = Idle,
        )

    fun updateRequest(intent: Intent) {
@@ -74,16 +79,14 @@ class CredentialSelectorViewModel @Inject constructor(
        Log.d(TAG, "OnBackPressed")
        when (uiState.value) {
            is Get.MultipleEntry -> isPrimaryScreen.value = true
            else -> {
                shouldClose.value = true
                // TODO("b/300422310 - [Wear] Implement UI for cancellation request with message")
            }
            is Create, Close, is Cancel, Idle -> shouldClose.value = true
            is Get.SingleEntry, is Get.SingleEntryPerAccount -> cancel()
        }
    }

    override fun cancel() {
        credentialManagerClient.sendError(BaseDialogResult.RESULT_CODE_DIALOG_USER_CANCELED)
        shouldClose.value = true
        // TODO("b/300422310 - [Wear] Implement UI for cancellation request with message")
    }

    override fun openSecondaryScreen() {
Loading