Skip to content

[devragrin] [GmsCore] Implement guardWithRequest service path (#2851)#3524

Open
kwanter wants to merge 2 commits into
microg:masterfrom
kwanter:fix/guardWithRequest-2851
Open

[devragrin] [GmsCore] Implement guardWithRequest service path (#2851)#3524
kwanter wants to merge 2 commits into
microg:masterfrom
kwanter:fix/guardWithRequest-2851

Conversation

@kwanter
Copy link
Copy Markdown

@kwanter kwanter commented Jun 2, 2026

/claim #2851

Summary

  • Implement the previously stubbed IDroidGuardService.guardWithRequest so request-backed DroidGuard flows can execute instead of throwing NotImplementedError.
  • Wire it to the existing handle lifecycle: getHandle()initWithRequest(flow, request)snapshot(map)callbacks.onResult(bytes)close().
  • Preserve a narrow diff: no AIDL/API surface changes, no new session lifecycle assumptions, no dependency changes.
  • Add a brief remote DroidGuard setup guide for client config, endpoint expectations, and validation notes.

Why

guardWithRequest was a literal TODO("Not yet implemented"). Apps using Play Integrity / Firebase AppCheck-backed flows can hit this request-backed path, which breaks attestation on microG-only devices before the configured remote DroidGuard server can be used.

Error handling

  • If initWithRequest returns null, fall back to the existing init(flow) path.
  • Always close the handle in finally.
  • On runtime errors, return an empty byte array through callbacks.onResult(...) instead of throwing through Binder.

Test Plan

Local environment note: my current runner has no Java runtime installed (java -version returns “Unable to locate a Java Runtime”), so I could not run Gradle locally in this session.

Recommended maintainer validation:

  • Build: ./gradlew :play-services-droidguard:core:compileDebugKotlin
  • Unit tests if configured: ./gradlew :play-services-droidguard:core:testDebugUnitTest
  • Manual: enable remote DroidGuard mode, trigger a Play Integrity / Firebase AppCheck flow (e.g. Dott sign-in), confirm the flow no longer fails at guardWithRequest with NotImplementedError.
  • Regression: existing single-step flows still enter through guard() and continue to use the same handle implementation.

Metadata note

Public issue/repo context only. No private prompts, memory, credentials, or hidden runtime context are disclosed. PR is intended to be evaluated on its own merits against issue #2851.

Bounty: claimed via BountyHub for the $100 total listed on this issue.

The IDroidGuardService.guardWithRequest method was previously stubbed with
TODO, which caused request-backed DroidGuard flows (e.g. Play Integrity
multi-step attestation) to throw NotImplementedError.

This wires the missing entry point to the existing handle lifecycle:
- call getHandle() to obtain the active handle (embedded or remote)
- try initWithRequest(flow, request) with fallback to init(flow)
- deliver the snapshot result through IDroidGuardCallbacks.onResult
- always close the handle in a finally block
- on error, deliver an empty byte array (matching the existing
  KeyRetrievalService error convention) to avoid binder exceptions

This is the minimal change to unblock the request-backed flow while
keeping behavior aligned with the existing one-shot guard() entry point.
@kwanter
Copy link
Copy Markdown
Author

kwanter commented Jun 3, 2026

Update / implementation note:

This PR intentionally keeps #2851 narrow: it only replaces the missing guardWithRequest runtime path with the existing DroidGuard handle lifecycle.

Runtime flow implemented:

getHandle() -> initWithRequest(flow, request) -> snapshot(map) -> callbacks.onResult(bytes) -> close()

If initWithRequest returns null, it falls back to the existing init(flow) path before snapshotting. Errors return an empty byte array via the callback instead of throwing through binder, matching the existing error-tolerant service pattern.

Reason for the small diff:

  • no AIDL/API surface changes
  • no new session lifecycle assumptions
  • no docs-only change
  • uses existing DroidGuardHandleImpl / RemoteHandleImpl behavior already present in the codebase

Happy to expand this if maintainers want explicit multi-step session APIs, but this should address the immediate TODO("Not yet implemented") failure path hit by request-backed Play Integrity / remote DroidGuard callers.

Brief setup doc for the remote DroidGuard path, covering client
configuration, server endpoint expectations, and quick validation.
Addresses the documentation gap noted in the bounty discussion.
@kwanter
Copy link
Copy Markdown
Author

kwanter commented Jun 5, 2026

Update: added a brief setup doc for the remote DroidGuard path. No AIDL or API surface changes — the doc only covers client config, server endpoint expectations, and quick validation notes.

PR diff is now 2 files, +55/-1 total (service impl + setup doc).

Happy to rebase or address review feedback.

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.

1 participant