@@ -29,10 +29,10 @@ import androidx.lifecycle.MutableLiveData
2929import androidx.lifecycle.compose.collectAsStateWithLifecycle
3030import androidx.lifecycle.viewModelScope
3131import at.bitfire.cert4android.Cert4Android
32- import at.bitfire.cert4android.TrustCertificateDialog
3332import at.bitfire.cert4android.CertificateDetails
3433import at.bitfire.cert4android.CustomCertManager
3534import at.bitfire.cert4android.CustomCertStore
35+ import at.bitfire.cert4android.TrustCertificateDialog
3636import kotlinx.coroutines.CompletableDeferred
3737import kotlinx.coroutines.Dispatchers
3838import kotlinx.coroutines.flow.MutableStateFlow
@@ -54,7 +54,7 @@ class MainActivity : ComponentActivity() {
5454 super .onCreate(savedInstanceState)
5555 setContent {
5656 val snackBarHostState = remember { SnackbarHostState () }
57- val certificateDetails = model.certificateDetailsFlow .collectAsStateWithLifecycle().value
57+ val pendingDecision = model.pendingDecisionFlow .collectAsStateWithLifecycle().value
5858
5959 Box (Modifier .fillMaxSize()) {
6060 Column (
@@ -117,8 +117,13 @@ class MainActivity : ComponentActivity() {
117117 }
118118 }
119119
120- if (certificateDetails != null )
121- TrustCertificateDialog (certificateDetails, model::registerUserDecision)
120+ if (pendingDecision != null )
121+ TrustCertificateDialog (
122+ certificateDetails = pendingDecision.certificateDetails,
123+ onSetTrustDecision = { actualDecision ->
124+ model.registerUserDecision(pendingDecision, actualDecision)
125+ }
126+ )
122127
123128 SnackbarHost (
124129 snackBarHostState,
@@ -133,24 +138,27 @@ class MainActivity : ComponentActivity() {
133138
134139 val resultMessage = MutableLiveData <String >()
135140
136- private val _certificateDetailsFlow = MutableStateFlow <CertificateDetails ?>(null )
137- val certificateDetailsFlow: StateFlow <CertificateDetails ?> = _certificateDetailsFlow
138-
139- @Volatile
140- private var userDecision: CompletableDeferred <Boolean > = CompletableDeferred ()
141-
142- fun registerUserDecision (decision : Boolean ) {
143- userDecision.complete(decision)
144- _certificateDetailsFlow .value = null
145- }
146-
141+ class PendingDecision (
142+ val certificateDetails : CertificateDetails ,
143+ val userDecision : CompletableDeferred <Boolean >
144+ )
145+ private val _pendingDecisionFlow = MutableStateFlow <PendingDecision ?>(null )
146+ val pendingDecisionFlow: StateFlow <PendingDecision ?> = _pendingDecisionFlow
147147
148148 init {
149149 // The default HostnameVerifier is called before our per-connection HostnameVerifier.
150150 @SuppressLint(" AllowAllHostnameVerifier" )
151151 HttpsURLConnection .setDefaultHostnameVerifier(AllowAllHostnameVerifier ())
152152 }
153153
154+ fun registerUserDecision (
155+ pendingDecision : PendingDecision ,
156+ actualDecision : Boolean
157+ ) {
158+ pendingDecision.userDecision.complete(actualDecision)
159+ _pendingDecisionFlow .value = null
160+ }
161+
154162 fun reset () = viewModelScope.launch(Dispatchers .IO ) {
155163 CustomCertStore .getInstance(getApplication()).clearUserDecisions()
156164 }
@@ -167,10 +175,13 @@ class MainActivity : ComponentActivity() {
167175 viewModelScope,
168176 getUserDecision = { cert ->
169177 // Reset user decision
170- userDecision = CompletableDeferred ()
178+ val userDecision = CompletableDeferred < Boolean > ()
171179
172180 // Show TrustDecisionDialog with certificate details to user
173- _certificateDetailsFlow .value = CertificateDetails .fromX509(cert)
181+ _pendingDecisionFlow .value = PendingDecision (
182+ certificateDetails = CertificateDetails .fromX509(cert),
183+ userDecision = userDecision
184+ )
174185
175186 // Wait for user decision and return it
176187 userDecision.await()
0 commit comments