@@ -23,15 +23,20 @@ import kotlinx.coroutines.withContext
2323import org.microg.gms.common.Constants
2424import org.microg.gms.constellation.core.proto.AsterismClient
2525import org.microg.gms.constellation.core.proto.Consent
26+ import org.microg.gms.constellation.core.proto.ConsentVersion
2627import org.microg.gms.constellation.core.proto.DeviceID
2728import org.microg.gms.constellation.core.proto.GetConsentRequest
2829import org.microg.gms.constellation.core.proto.GetConsentResponse
30+ import org.microg.gms.constellation.core.proto.Param
31+ import org.microg.gms.constellation.core.proto.RcsConsent
2932import org.microg.gms.constellation.core.proto.RequestHeader
33+ import org.microg.gms.constellation.core.proto.SetConsentRequest
3034import org.microg.gms.constellation.core.proto.SyncRequest
3135import org.microg.gms.constellation.core.proto.Verification
3236import org.microg.gms.constellation.core.proto.builder.RequestBuildContext
3337import org.microg.gms.constellation.core.proto.builder.buildImsiToSubscriptionInfoMap
3438import org.microg.gms.constellation.core.proto.builder.buildRequestContext
39+ import org.microg.gms.constellation.core.proto.builder.getList
3540import org.microg.gms.constellation.core.proto.builder.invoke
3641import org.microg.gms.constellation.core.verification.ChallengeProcessor
3742import org.microg.gms.constellation.core.verification.MtSmsInboxRegistry
@@ -176,6 +181,10 @@ private suspend fun handleVerifyPhoneNumberRequest(
176181 var phoneNumbers = emptyList<PhoneNumberInfo >()
177182 var verifications = emptyArray<PhoneNumberVerification >()
178183 val status = try {
184+ if (! ConstellationStateStore .isPhoneNumberVerificationEnabled(context)) {
185+ throw PhoneNumberVerificationDisabledException ()
186+ }
187+
179188 when (readCallbackMode) {
180189 ReadCallbackMode .LEGACY -> {
181190 Log .d(TAG , " Using read-only mode" )
@@ -205,13 +214,25 @@ private suspend fun handleVerifyPhoneNumberRequest(
205214 } catch (e: Exception ) {
206215 Log .e(TAG , " verifyPhoneNumber failed" , e)
207216 when {
217+ e is PhoneNumberVerificationDisabledException -> Status (5000 )
208218 readCallbackMode != ReadCallbackMode .NONE -> Status .INTERNAL_ERROR
209219 e is GrpcException -> handleRpcError(e)
210- e is NoConsentException -> Status (5001 )
211220 else -> Status .INTERNAL_ERROR
212221 }
213222 }
214223
224+ val successful = status.isSuccess && when (readCallbackMode) {
225+ ReadCallbackMode .NONE -> verifications.isNotEmpty() &&
226+ (request.targetedSims.isEmpty() ||
227+ verifications.size == request.targetedSims.size) &&
228+ verifications.all {
229+ it.verificationStatus == Verification .Status .STATUS_VERIFIED .toClientStatus()
230+ }
231+
232+ else -> true
233+ }
234+ ConstellationStateStore .recordPhoneNumberVerification(context, callingPackage, successful)
235+
215236 if (readCallbackMode == ReadCallbackMode .LEGACY ||
216237 readCallbackMode == ReadCallbackMode .NONE && legacyCallbackOnFullFlow
217238 ) {
@@ -232,6 +253,8 @@ private suspend fun handleVerifyPhoneNumberRequest(
232253 )
233254}
234255
256+ private class PhoneNumberVerificationDisabledException : Exception (" Phone number verification is disabled" )
257+
235258private fun handleRpcError (error : GrpcException ): Status {
236259 val statusCode = when (error.grpcStatus) {
237260 GrpcStatus .RESOURCE_EXHAUSTED -> 5008
@@ -245,8 +268,6 @@ private fun handleRpcError(error: GrpcException): Status {
245268 return Status (statusCode, error.message)
246269}
247270
248- private class NoConsentException : Exception (" No consent" )
249-
250271private suspend fun runVerificationFlow (
251272 context : Context ,
252273 request : VerifyPhoneNumberRequest ,
@@ -278,8 +299,24 @@ private suspend fun runVerificationFlow(
278299 }
279300
280301 if (! consented) {
281- Log .e(TAG , " Consent has not been set. Not running verification." )
282- throw NoConsentException ()
302+ Log .e(TAG , " Consent has not been set. Auto-setting consent." )
303+ val consentType = parseConsentVersion(request.extras)
304+ val setRequest = SetConsentRequest (
305+ header_ = RequestHeader (context, sessionId, buildContext, " setConsent" ),
306+ asterism_client = asterismClient,
307+ rcs_consent = RcsConsent (
308+ consent = Consent .CONSENTED ,
309+ consent_version = consentType
310+ ),
311+ consent_version = consentType,
312+ api_params = Param .getList(request.extras)
313+ )
314+ try {
315+ RpcClient .phoneDeviceVerificationClient.SetConsent ().execute(setRequest)
316+ Log .i(TAG , " Auto-consented for $asterismClient " )
317+ } catch (e: Exception ) {
318+ Log .w(TAG , " Auto-consent failed" , e)
319+ }
283320 }
284321 }
285322
@@ -313,6 +350,14 @@ private suspend fun runVerificationFlow(
313350 return verifications
314351}
315352
353+ private fun parseConsentVersion (extras : Bundle ): ConsentVersion {
354+ val value = extras.getString(" consent_type" )
355+ val parsed = value?.toIntOrNull()?.let (ConsentVersion ::fromValue)
356+ ? : value?.let { runCatching { ConsentVersion .valueOf(it) }.getOrNull() }
357+ return parsed?.takeUnless { it == ConsentVersion .CONSENT_VERSION_UNSPECIFIED }
358+ ? : ConsentVersion .RCS_DEFAULT_ON_LEGAL_FYI
359+ }
360+
316361private fun PhoneNumberVerification.toLegacyPhoneNumberInfoOrNull (): PhoneNumberInfo ? {
317362 if (
318363 verificationStatus != Verification .Status .STATUS_VERIFIED .toClientStatus() ||
0 commit comments