Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
...@@ -31,10 +31,7 @@ interface CredentialManagerClient { ...@@ -31,10 +31,7 @@ interface CredentialManagerClient {
fun updateRequest(intent: Intent) fun updateRequest(intent: Intent)
/** Sends an error encountered during the UI. */ /** Sends an error encountered during the UI. */
fun sendError( fun sendError(@BaseDialogResult.ResultCode resultCode: Int)
@BaseDialogResult.ResultCode resultCode: Int,
errorMessage: String? = null,
)
/** /**
* Sends a response to the system service. The response * Sends a response to the system service. The response
......
...@@ -48,9 +48,13 @@ class CredentialManagerClientImpl @Inject constructor( ...@@ -48,9 +48,13 @@ class CredentialManagerClientImpl @Inject constructor(
override fun updateRequest(intent: Intent) { override fun updateRequest(intent: Intent) {
val request = intent.parse( val request: Request
context = context, 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") Log.d(TAG, "Request parsed: $request, client instance: $this")
if (request is Request.Cancel || request is Request.Close) { if (request is Request.Cancel || request is Request.Close) {
if (request.token != null && request.token != _requests.value?.token) { if (request.token != null && request.token != _requests.value?.token) {
...@@ -61,8 +65,9 @@ class CredentialManagerClientImpl @Inject constructor( ...@@ -61,8 +65,9 @@ class CredentialManagerClientImpl @Inject constructor(
_requests.value = request _requests.value = request
} }
override fun sendError(resultCode: Int, errorMessage: String?) { override fun sendError(resultCode: Int) {
TODO("b/300422310 - [Wear] Implement UI for cancellation request with message") Log.w(TAG, "Error occurred, resultCode: $resultCode, current request: ${ requests.value }")
requests.value?.sendCancellationCode(resultCode)
} }
override fun sendResult(result: UserSelectionDialogResult) { override fun sendResult(result: UserSelectionDialogResult) {
...@@ -108,7 +113,7 @@ class CredentialManagerClientImpl @Inject constructor( ...@@ -108,7 +113,7 @@ class CredentialManagerClientImpl @Inject constructor(
return entryInfo.shouldTerminateUiUponSuccessfulProviderResult return entryInfo.shouldTerminateUiUponSuccessfulProviderResult
} }
private fun Request.Get.sendCancellationCode(cancelCode: Int) { private fun Request.sendCancellationCode(cancelCode: Int) {
sendCancellationCode( sendCancellationCode(
cancelCode = cancelCode, cancelCode = cancelCode,
requestToken = token, requestToken = token,
......
...@@ -25,6 +25,8 @@ import com.android.credentialmanager.model.get.ProviderInfo ...@@ -25,6 +25,8 @@ import com.android.credentialmanager.model.get.ProviderInfo
*/ */
sealed class Request private constructor( sealed class Request private constructor(
open val token: IBinder?, open val token: IBinder?,
open val resultReceiver: ResultReceiver? = null,
open val finalResponseReceiver: ResultReceiver? = null,
) { ) {
/** /**
...@@ -48,10 +50,10 @@ sealed class Request private constructor( ...@@ -48,10 +50,10 @@ sealed class Request private constructor(
*/ */
data class Get( data class Get(
override val token: IBinder?, override val token: IBinder?,
val resultReceiver: ResultReceiver?, override val resultReceiver: ResultReceiver?,
val finalResponseReceiver: ResultReceiver?, override val finalResponseReceiver: ResultReceiver?,
val providerInfos: List<ProviderInfo>, val providerInfos: List<ProviderInfo>,
) : Request(token) ) : Request(token, resultReceiver, finalResponseReceiver)
/** /**
* Request to start the create credentials flow. * Request to start the create credentials flow.
*/ */
......
...@@ -19,5 +19,6 @@ package com.android.credentialmanager ...@@ -19,5 +19,6 @@ package com.android.credentialmanager
import android.app.Application import android.app.Application
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
/** [Application] of credential selector. */
@HiltAndroidApp(Application::class) @HiltAndroidApp(Application::class)
class CredentialSelectorApp : Hilt_CredentialSelectorApp() class CredentialSelectorApp : Hilt_CredentialSelectorApp()
\ No newline at end of file
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
package com.android.credentialmanager package com.android.credentialmanager
import android.content.Intent import android.content.Intent
import android.credentials.selection.BaseDialogResult
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.android.credentialmanager.CredentialSelectorUiState.Get import com.android.credentialmanager.CredentialSelectorUiState.Get
...@@ -27,6 +28,10 @@ import com.android.credentialmanager.model.get.ActionEntryInfo ...@@ -27,6 +28,10 @@ import com.android.credentialmanager.model.get.ActionEntryInfo
import com.android.credentialmanager.model.get.CredentialEntryInfo import com.android.credentialmanager.model.get.CredentialEntryInfo
import com.android.credentialmanager.ui.mappers.toGet import com.android.credentialmanager.ui.mappers.toGet
import android.util.Log 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 dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
...@@ -49,21 +54,21 @@ class CredentialSelectorViewModel @Inject constructor( ...@@ -49,21 +54,21 @@ class CredentialSelectorViewModel @Inject constructor(
) { request, isPrimary, shouldClose -> ) { request, isPrimary, shouldClose ->
if (shouldClose) { if (shouldClose) {
Log.d(TAG, "Request finished, closing ") Log.d(TAG, "Request finished, closing ")
return@combine CredentialSelectorUiState.Close return@combine Close
} }
when (request) { when (request) {
null -> CredentialSelectorUiState.Idle null -> Idle
is Request.Cancel -> CredentialSelectorUiState.Cancel(request.appName) is Request.Cancel -> Cancel(request.appName)
is Request.Close -> CredentialSelectorUiState.Close is Request.Close -> Close
is Request.Create -> CredentialSelectorUiState.Create is Request.Create -> Create
is Request.Get -> request.toGet(isPrimary) is Request.Get -> request.toGet(isPrimary)
} }
} }
.stateIn( .stateIn(
viewModelScope, viewModelScope,
started = SharingStarted.WhileSubscribed(5000), started = SharingStarted.WhileSubscribed(5000),
initialValue = CredentialSelectorUiState.Idle, initialValue = Idle,
) )
fun updateRequest(intent: Intent) { fun updateRequest(intent: Intent) {
...@@ -74,16 +79,14 @@ class CredentialSelectorViewModel @Inject constructor( ...@@ -74,16 +79,14 @@ class CredentialSelectorViewModel @Inject constructor(
Log.d(TAG, "OnBackPressed") Log.d(TAG, "OnBackPressed")
when (uiState.value) { when (uiState.value) {
is Get.MultipleEntry -> isPrimaryScreen.value = true is Get.MultipleEntry -> isPrimaryScreen.value = true
else -> { is Create, Close, is Cancel, Idle -> shouldClose.value = true
shouldClose.value = true is Get.SingleEntry, is Get.SingleEntryPerAccount -> cancel()
// TODO("b/300422310 - [Wear] Implement UI for cancellation request with message")
}
} }
} }
override fun cancel() { override fun cancel() {
credentialManagerClient.sendError(BaseDialogResult.RESULT_CODE_DIALOG_USER_CANCELED)
shouldClose.value = true shouldClose.value = true
// TODO("b/300422310 - [Wear] Implement UI for cancellation request with message")
} }
override fun openSecondaryScreen() { override fun openSecondaryScreen() {
......
...@@ -120,7 +120,6 @@ fun WearApp( ...@@ -120,7 +120,6 @@ fun WearApp(
} }
is CredentialSelectorUiState.Cancel -> { is CredentialSelectorUiState.Cancel -> {
// TODO: b/300422310 - Implement cancel with message flow
onCloseApp() onCloseApp()
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment