Skip to content

Integrate RCS enrollment services and phone-verification lifecycle fixes - #3851

Open
woahwhattheheck wants to merge 99 commits into
microg:masterfrom
woahwhattheheck:grokbot/rcs-2994-current-main-integration-20261003
Open

woahwhattheheck wants to merge 99 commits into
microg:masterfrom
woahwhattheheck:grokbot/rcs-2994-current-main-integration-20261003

Conversation

@woahwhattheheck

@woahwhattheheck woahwhattheheck commented Oct 4, 2026 •

Copy link
Copy Markdown

This integrates the enrollment and phone-number verification services used by Google Messages with current master, and adds request lifetime, authentication, and SMS verification fixes. The original integrated bundle is 8b9a7bcbde84dc2ce293ca44db4765e4304be55b (tree 201b25736ae983b9c1dc5a2276e6fc2bac33d345), based on 32bc8954ff872d0e1a05ddfae81561b6dbecef69. Subsequent fixes are included on this branch; the executed validation below retains each source pin.

Current source head: e31a421fd439e947c2f560eef7fd96e042606854 (original contributor branch; software source/review only, not a device-validated RCS connection). Previous executed build/lint checkpoint: eee037a74415f6032bb6eb11d7944d12bb6557a8. The last executed four-module unit-test source is d980bafcbdd255b12a5680692422a80d45716b62 (134 tests, 0 failures/errors/skips). Three later commits are diagnostic-only privacy cleanups: 93764be1 removes Asterism request-object logging, 93872c9d removes raw SIM-identifier/detail logging, and 74685db5 removes the MO-SMS proxy destination/per-send identifier from the pre-send debug log. The ca14a3b2 successor is a bounded correctness fix: it serializes the verified-number cache's read/merge/write critical section so concurrent verification requests cannot last-writer-win away each other's disjoint SIM records. The 8fbe68a6 successor adds one diagnostic-only privacy cleanup by removing unnecessary identifier detail from a successful-match debug line. No control flow changed, and no executed test result is claimed for the ca14a3b2 or 8fbe68a6 successors. The later 13d93cfd successor fixes inherited non-public VM method discovery by walking the VM class hierarchy for exact declared-method lookup, and test-only eee037a7 adds the focused protected-superclass regression. Previous checkpoint eee037a74415f6032bb6eb11d7944d12bb6557a8 has a completed hosted Gradle build at run 37405793974: both Debug and Release jobs completed assemble and lint successfully. That run is compile/lint evidence only; it does not rerun the four-module unit suite. The locked-bootloader, non-root real-SIM RCS acceptance gate remains outstanding.

The Constellation and Asterism implementation sources are opstic's #3359 and #3360. This PR integrates those services with the follow-up changes below; those existing PRs remain the source references for the original implementation.

Enrollment and verification path

  • Constellation serves verifyPhoneNumberV1, verifyPhoneNumberSingleUse, verifyPhoneNumber, getIidToken, and getPnvCapabilities, including the API parcels/AIDL and gRPC protocol.
  • Asterism serves consent reads/writes and the PNVR Constellation-device query.
  • Module wiring, service registration, phone-number verification settings, permission self-checks, and the relevant Messages/IMS phenotype flags are included.

Follow-up changes

  • Constellation and Asterism requests have a coroutine lifetime tied to the caller's callback Binder. Already-dead callers do not enter the request body; completion unlinks the death recipient. Cancellation propagates through IID, capability, and verification handlers instead of recording an outcome or delivering to a cancelled caller.

  • MT SMS inbox state is scoped to each request. Setup cleanup, stale transfer handling, and multipart assembly are included. MO SMS sent-result PendingIntents remain mutable where the platform supplies the telephony error code.

  • Signing-key initialization is serialized. Typed read requests carry their certificate hash and nonce, signing failures propagate, SIM phone-number hints are optional, associated SIM-slot fallback is retained, and Sync error records are checked after the requested-SIM filter.

  • TS.43 uses the advertised EAP identity for SIM authentication and closes HTTP responses on completion/error paths. Flash-call verification and its permission self-check are included.

  • DroidGuard initialization tolerates an absent optional rb() method, and a database row whose VM APK cache is missing is skipped so it can be retrieved again.

  • Automatic SetConsent authentication rejection clears both current and legacy DroidGuard token stores and propagates PERMISSION_DENIED / UNAUTHENTICATED. Other consent service/transport failures retain best-effort continuation; cancellation still propagates.

  • Verified phone numbers are stored per IMSI with a server-derived expiration. Typed local reads return the complete requested SIM set from valid local state, falling back to the read-only RPC when state is missing, incomplete, or expired. The verified-number read/merge/write is serialized so concurrent requests preserve disjoint fresh SIM records. Existing regressions cover the local-read retain/replace/evict semantics; no probabilistic race-stress result is claimed.

  • PNV capabilities read the IMSI and operator name for each subscription. Pre-N devices use the per-subscription telephony accessors through reflection, with the existing default-subscription fallback when unavailable.

  • Flash-call E.164 formatting is gated at API 21; API 19 retains raw-digit candidate matching. nextSyncDeadlineMillis declares its API 26 requirement consistently with its existing guarded callers. Regression cases cover the server-reported clock offset and missing-timestamp freshness fallback.

Executed validation

The source pins are separate so the evidence can be reproduced accurately.

The completed bundle's cloud VM handoff reports :play-services-constellation-core:testDebugUnitTest: 99 tests passed, 0 failures on tree 201b25736ae983b9c1dc5a2276e6fc2bac33d345. The original bundle publication commit 8b9a7bcb reuses that exact tree. This result is separate from the hosted runs below; tests and APK assembly were not rerun for that original publication commit.

Source Executed checks Result
61587ce21dd640494719920deda08691b5e1b820 Constellation, Asterism, DroidGuard, DroidGuard-core unit tasks and :play-services-core:assembleVtmDefaultDebug Run 37188993445 succeeded. Actual XML: 109 tests, 0 failures/errors/skips — Constellation 90, Asterism 11, DroidGuard 6, DroidGuard-core 2. The six DroidGuard results were restored from Gradle cache; the other 103 results executed in the run.
8a10bae18bc8b4c6ecd7dcc862e0ba9fe4db0f07 :play-services-constellation-core:testDebugUnitTest --tests org.microg.gms.constellation.core.AutoSetConsentTest Run 37191252457 succeeded. Actual XML: 5 tests, 0 failures/errors/skips. The checkout commit/tree matched the pin, and the test task executed.
21f233b0ce0a6419675f246f8f8ce9f0648692e2 (tree aa8790c9ef11afbf11c13e5358f401fde7a7a956) :play-services-constellation-core:testDebugUnitTest and :play-services-constellation-core:lintDebug Run 37229705241 succeeded. Actual XML: 102 tests across 25 suites, 0 failures/errors/skips. Lint: 0 errors, 10 warnings.
d980bafcbdd255b12a5680692422a80d45716b62 (validated source; tree 3be1b550f61f54009bb68df828f097d73a2d268e) Constellation, Asterism, DroidGuard, and DroidGuard-core unit tasks Run 37374503011 succeeded. Actual XML reports 134 passing testcases, 0 failures/errors/skips — Constellation 103, Asterism 17, DroidGuard 6, DroidGuard-core 8. The first 126 results were restored from Gradle cache; the eight DroidGuard-core cases executed in this run. Workflow commit f7980afb39548e3a0dbd2900109f8ce0b512e309 separately checked out and verified the exact product commit/tree in this row. This is unit evidence only; it does not satisfy the physical-device RCS acceptance gate.
bf6a893 (tree 40792166) DroidGuard-core JVM unit tests Run 37393990661 succeeded: 8 tests green. Artifact 11382425915, SHA-256 79d0cb66d0f50cc5348b5cc60e0eafbcf69d66ceeddfe80e8b238ff6a1290cdc. This is source-pinned JVM evidence only.
44b97d1 (tree a01be921, test-only successor) DroidGuard-core JVM unit tests Run 37395003595 succeeded: 9 tests green. Artifact 11383006683, SHA-256 bb1bde13d0e6ff179c0760602facfd1e89d6b0eb67163c15cdea548908d064a3. Test-only evidence; it does not satisfy the physical-device RCS gate.
eee037a74415f6032bb6eb11d7944d12bb6557a8 (previous source checkpoint, not current PR head) Fork Gradle build workflow: Debug + Release assemble and lint Run 37405793974 succeeded. Both matrix jobs completed Execute Gradle assemble and Execute Gradle lint successfully. No current-head unit-test or device/RCS claim is inferred from this run.

The three source/test postimages for the API-level fixes match the tested validation source and were forwarded to this PR in 09dffdd2639f49d1099a77484600575798455be8 and 64b9a16b86d211604cdcc254743beb43cd817c78. The API-level regression XML remains pinned to 21f233b0. The executed four-module unit-test evidence is pinned to d980bafc above. Later source/test checkpoints are recorded separately at bf6a893 (8 DroidGuard-core JVM tests green) and its test-only successor 44b97d1 (9 green), so those validated checkpoints are not skipped in the chain. These are still JVM/unit results; the locked-bootloader, non-root real-SIM RCS acceptance gate remains outstanding.

The five consent cases use the production helper, a real Wire gRPC client against loopback MockWebServer, and a Robolectric SDK 34 state store. They cover both authentication statuses and current/legacy cache clearing, UNAVAILABLE continuation, normal continuation, and cancellation. Each case checks the serialized SetConsent request and the actual RPC.

The APK above belongs to 61587ce2; the later 8a10bae1 consent change has the focused unit result above. Device instrumentation and a new APK for the later source were not executed by these runs or by this publication.

Post-validation source head reconciliation

The original-author integration branch is now at e31a421fd439e947c2f560eef7fd96e042606854. The historical executable test, lint, and assembly receipts tabulated above belong to their respective earlier exact source commits, especially checkpoint eee037a74415f6032bb6eb11d7944d12bb6557a8. They must not be represented as test/build/device verification of this later head.

Since the eee037a74415f6032bb6eb11d7944d12bb6557a8 checkpoint the branch incorporated scoped post-validation changes including EAP-AKA AT_MAC handling (11d6ef46), MT-SMS sender provenance and bounded inbox (bc1ab3f1), RegisteredSms platform-error containment (931e2e27), cross-SIM evidence fallback safeguards (66cb761c and 7a7d1308), and catch-all MT inbox preparation (f6b9ac6e2154a764c5662290142a452f87062580). Focused regression source for the later changes was authored; it is not claimed to have been run against this head. No later four-module CI suite, APK device installation, real-SIM RCS confirmation, or maintainer acceptance is inferred. The requested locked-bootloader / non-root / real-SIM outgoing and incoming RCS acceptance remains outstanding. Original source credits to opstic #3359/#3360 and the existing @woahwhattheheck BountyHub portal claim and conditional contributor compensation request are preserved; no new claim or payout is asserted.

Source updates after the previous reconciliation (October 8, 2026)

At exact current head e31a421fd439e947c2f560eef7fd96e042606854, subsequent issue-focused source repairs added MT-SMS single-delivery safeguards across SIM-specific/catch-all receivers, their narrowly scoped test source, and authoritative fallback when a targeted SIM descriptor lacks an IMSI instead of silently returning only a partial locally cached subset. The final VerifyPhoneNumberLocalReadTest.kt change records a focused regression for incomplete targeted-SIM metadata. These latest code/test edits were committed and independently read back from GitHub. No new current-head Gradle test, lint/assemble, hardware/RCS provisioning, or payout acceptance is asserted; the previously documented historical validation pins remain attached to their original commits.

Device acceptance still to execute

The remaining #2994 acceptance test is successful provisioning and actual outgoing/incoming RCS with a real SIM on a locked-bootloader device, without root, Magisk, or similar root-based tools. The device/ROM, Google Messages version, carrier, APK hash, and distinction between RCS delivery and SMS fallback need to be recorded. Those device/SIM results are pending.

Refs #2994.

Original-author BountyHub compensation and payout attribution

I, @woahwhattheheck (GitHub account 293286387), am the original author of this PR's integration, request-lifetime handling, SIM/RCS correctness and privacy follow-ups, while preserving the explicit original source credits to opstic PRs #3359/#3360. I affirmatively request maintainer review, applicable BountyHub reward/compensation attribution and confirmation of eligibility, payable amount and payout method for the contribution associated with #2994.

BountyHub's public listing has already shown @woahwhattheheck's claim pointing to this exact upstream PR #3851; please preserve that claim record rather than issuing a duplicate platform submission. Marketplace reward advertisements are not a guaranteed payout, and payment, maintainer acceptance and the required real-SIM locked-device RCS acceptance remain pending. My original contribution and payment claim remain ACTIVE. I request and demand the applicable eligible payment share under the advertised $14,999 BountyHub RCS reward listing, subject to maintainer acceptance, platform eligibility, other contributors' credited entitlements, and verified device requirements. I will provide the verified original claimant's payment-recipient details through the existing BountyHub payout channel. Platform claim/receiving setup is an existing record, not a new claim or confirmed award. The current source head and its explicit validation limits are reconciled above.

Restore the missing TS.43 verifier, IID token request implementation,
module registration, real service routing, and phone verification settings
from the existing RCS source. Compose the retained consent fallback with
the current caller-cancellation behavior and wire its existing unit checks.

Source integration only; device RCS connectivity is not established by this commit.
Concurrent first use must share the persisted EC key so published public keys and later IID signatures agree. Add a focused concurrency regression preserving existing key acknowledgement.
Parse the hexadecimal platform ID as unsigned before retaining its Long bit representation. High-bit values now remain device IDs instead of falling through to the build-ID hash. Existing cached IDs and absent/malformed-input fallback are unchanged.

Operation: BH-RCS-DEVICE-ID-268D
Check coroutine activity after synchronous token lookup, before success delivery,
and before mapping an ordinary failure to a callback. Cancellation during blocked
credential work now stops subsequent delivery and unnecessary signing.

Extend the existing cancellation class with three real job-cancellation cases.
The actual six-case class reproduced three failures on ae5d278 and passed all six
with this handler using coroutines 1.7.3 and JUnit 4.13.2 in a focused JVM run.
Android, AIDL and unused auth boundaries were inert in that focused run; combined
Android validation remains with the existing RCS integration branch owner.
Merge the existing AuthManager concurrency and unsigned Android-ID fixes,
preserving both contributor commits as parents. Compose the exact SWE
DroidGuard rev4.53 packet with the retained VM-cache and nullable-reply
corrections and their existing unit tests.

DroidGuard packet SHA-256:
6a2054da41d5c2afdcd75102d8d87fe61abe13ce0e0c510923d60d5094b09ab9
Original RCS source: 1a18528

Combined cloud build follows this source snapshot. Device provisioning,
RCS send/receive, and bounty acceptance remain unestablished.
Merge the exact 268D contribution and retain its commit as a parent.
Check activity after synchronous token lookup and before success or error
callbacks, with three existing-suite regressions for real job cancellation.

This source snapshot is queued for the combined build. Physical RCS
provisioning and message delivery remain outside the cloud build evidence.
The combined Kotlin build rejects smart casts of PackageInfo.signingInfo
because the framework property is mutable. Capture the value once in the
API28+ branch, retaining null rejection and the single-signer certificate
pin. The pre-28 signature path is unchanged.

Addresses the actual compileDebugKotlin failure from combined build04.
Recheck coroutine activity after synchronous telephony queries and before success or error callbacks. Add the focused subscription-query cancellation case to the existing Constellation suite.

The source and test are prepared for the existing integration runner; the new test has not been executed while shared build storage is full.
Merge the exact phone-verification cancellation contribution and retain
its source commit as a parent. Recheck coroutine activity after synchronous
telephony work and before callbacks, with the supplied regression case.

Fix the two APK compilation failures from run37185388964: retain the
initialized VM proxy in a nonnullable local and type the empty legacy
snapshot map explicitly. Optional rb behavior and failure handling remain.

The preceding source passed57 existing unit cases; the combined source
and added PNV case require the next pinned APK build.
RCS-TS43-RESPONSE-CLOSE-4545. Scope both carrier ODSA and EAP responses with use, preserving existing response bodies, HTTP history, status/error mapping and request counts. ODSA previously threw for non-success status before consuming or closing the body.

The four added Ts43ResponseLifecycleTest methods execute genuine OkHttp loopback exchanges and assert connectionReleased events. Three consecutive ODSA 403 responses retained all three connections before the fix (0 released); the repaired path releases all three. Successful ODSA, EAP token early return and EAP rejection retain their original results, history and one-request behavior.

Focused JVM execution used the exact production HTTP-handler bodies, the same complete test class, actual generated Wire types and entitlement/EAP helpers, OkHttp 4.12.0, Kotlin 2.2.21 and JUnit 4.13.2. Android framework dependencies were mocked and logging was inert. Baseline 3/4 passed, repaired 4/4 passed in 1.640s. No provider requests, full Gradle/APK build or device RCS outcome is asserted. Existing Constellation command: :play-services-constellation-core:testDebugUnitTest --tests org.microg.gms.constellation.core.verification.Ts43ResponseLifecycleTest.

Additive contribution based on current integration 71c28a2; preserve the original RCS delivery and BountyHub claim route.

Attribution: GPT-6 Astra Pro / Astra-4545-RCS / ChatGPT cloud harness 4545e3eb7081.
Build replacement inboxes transactionally, disposing partial construction on failure while retaining the original exception and previously owned inboxes. Add one failure-path regression to MtSmsInboxScopeTest.

Focused replay with exact extracted production scope and the unchanged eight-case test candidate: baseline compiles and fails the new regression (expected disposed [1,2], actual []); candidate compiles and passes 8/8. JDK 17.0.20.1, Kotlin 2.2.21, JUnit 4.13.2, coroutine 1.10.2, existing injected factory seam. No Android receiver, full-module, APK or device proof is claimed.

Component carrier skips the inherited full Debug/Release matrix; the existing RCS combined workflow remains the integration validation route. Operation RCS-MTSMS-PREPARE-CLEANUP-FA9A.
Map failures from TelephonyManager service lookup and subscription-specific
manager creation through the same carrier error response as authentication.
SecurityException reports unable-to-read-subscription, unsupported APIs
report not-supported, and other platform failures retain reflection-error.
Validate challenge data and the TS43 unsupported case before platform calls.

Source-only additive contribution for the existing RCS microg#2994 integration.
No new test or build run; combined integration validation remains pending.
Integrate the tested two-file MT SMS resource-lifecycle contribution while retaining the existing RCS branch and source ancestry. The existing combined RCS workflow remains the validation route; the carrier avoids an additional inherited Debug/Release matrix.
Compose the tested two-file response lifecycle contribution with the existing MT-SMS integration. Preserve both source ancestries and use the planned combined RCS workflow for module and APK validation.
Compose the six-file EAP identity/cache contribution and CarrierId platform-error mapping on top of the shared MT-SMS registration and TS.43 response-lifecycle merges. Preserve response.use cleanup around EAP authentication.

EAP-AKA derives authentication keys from the exact identity used in the request, including its realm. Discard a cached VM database row if its VM file is unavailable so normal download can proceed. Guard platform manager lookup inside the existing CarrierId error mapping.

Leaf source contributions (applied as diffs, not parent metadata):
- EAP identity: 2fc243e
- DroidGuard VM cache: 0ec61c8
- CarrierId platform errors: 703fd5e

Next dedicated validation run covers all four module suites and the combined VtmDefaultDebug APK. Physical Google Messages RCS acceptance remains pending.

Integration: GPT-6 Astra Pro / ChatGPT cloud / a07bfe951f29.
Integrate carrier verification platform error handling
Keep later account signals when a Gaia ID is absent, resolve missing IDs through the existing account-ID token path, and skip unresolved entries. Serialize an omitted targeted-SIM phone number hint as an empty Wire value instead of throwing before Sync.

Apply exact published Opus leaf diffs, preserving the shared integration and source attribution without importing unrelated commit metadata:
- 4313a69 (Gaia ID handling, three focused cases)
- 6bfaa9c (optional phone hint, two focused cases)

Parent639051d2 additionally records the already-composed CarrierId contribution ancestry without changing its tree. The existing Constellation suite will execute these cases in the next combined build. No device RCS result is asserted.

Integration: GPT-6 Astra Pro / ChatGPT cloud / a07bfe951f29.
@woahwhattheheck

Copy link
Copy Markdown
Author

Validation run complete on current head eee037a74415f6032bb6eb11d7944d12bb6557a8 (tree 5df47f6291f428141ea7c2028a2f6c5ae498a900).

The fork run checked out the exact pinned commit and verified commit+tree in-run before testing (artifact rcs2994-headtest-eee037a-37508823034-1, run id 37508823034):

  • play-services-constellation-core:testDebugUnitTest — 106 tests, 0 failures, 0 errors, 0 skipped (26 XML reports)
  • play-services-asterism-core:testDebugUnitTest — 17 tests, 0 failures, 0 errors, 0 skipped
  • play-services-droidguard:testDebugUnitTest — 6 tests, 0 failures, 0 errors, 0 skipped
  • play-services-droidguard-core:testDebugUnitTest — 10 tests, 0 failures, 0 errors, 0 skipped

Total 139/0/0/0, Gradle exit 0 in 311s (temurin 17, --no-daemon --max-workers=1, in-process Kotlin compile). This head adds six commits on top of the previously validated d980bafc (139 vs 134 tests — the new carrier-allowlist and inherited-VM-method tests are included and green). Device-level RCS acceptance remains a separate open step and is not claimed here.

@woahwhattheheck

Copy link
Copy Markdown
Author

/claim #2994

I claim the applicable allocation from the advertised $14999 USD bounty for my contribution in this PR, payable to the original contributor @woahwhattheheck. The contribution and remaining acceptance requirements are documented in the existing PR; this claim preserves the original contributors' attribution. Please confirm eligibility and the award upon acceptance, payment method, and payout date.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants