Skip to content

SDKS-5267 Build the ping_davinci bridge package - #144

Open
rodrigoareis wants to merge 2 commits into
flutterfrom
SDKS-5267
Open

rodrigoareis wants to merge 2 commits into
flutterfrom
SDKS-5267

Conversation

@rodrigoareis

Copy link
Copy Markdown
Contributor

Summary

Adds ping_davinci, a new Flutter bridge plugin package exposing the native Ping DaVinci SDK (Android/iOS, pinned to 2.2.0) to Dart, on the same Pigeon-generated, handle-registry architecture as ping_journey (#124) and ping_oidc (#131). The flutter-davinci sample app follows in SDKS-5268.

  • flutter/flutter-sdk-bridge/ping_davinci/ — the new package:
    • Pigeon schema (pigeons/messages.dart) and generated Dart/Kotlin/Swift bindings, including the package's first @EventChannelApi stream
    • configureDaVinci builds the native workflow, configuring OIDC from either hoisted fields or an existing ping_oidc client handle (oidcClientId); both-or-neither is a typed argument error
    • start / next over a sealed Dart DaVinciNode (ContinueNode / SuccessNode / ErrorNode / FailureNode). Values go back by {type, index} and are re-resolved natively against the cached node, with strict type checks
    • All 17 core collector keys as a sealed Collector hierarchy, plus an AddOnCollector branch so Plan 3 modules (IdP, FIDO, Protect, mobile pairing) can register their own types. Form fields the native factory drops arrive as ContinueNode.unsupportedFields, each with a reason
    • validate runs the native local validation and returns a structured ValidationError per failure (not iOS's hardcoded English strings). ErrorNode carries status, typed errorDetails, a flat per-field fieldErrors map, and the continueNode to retry from
    • getSession (the authorization code, not tokens), getToken, getUserInfo({cache}), signOff, dispose. Tokens stay in native secure storage, and no host method takes a token
    • poll(PollingCollector) streams a sealed PollingStatus over one shared event channel, tagged per poll. next / start / signOff / dispose end running polls. QRCodeCollector carries its data URI plus imageBytes; device collectors take selectDevice; MetadataCollector takes setResult / setError
    • Typed error mapper (DaVinciErrorMapper / DaVinciErrorCodes) kept 1:1 between Kotlin and Swift
  • flutter/flutter-sdk-bridge/ping_core/ — adds CoreRuntime.davinciRegistry (Kotlin/Swift)
  • ping_journey / ping_oidc — the iOS ping_core SPM path is now ../ping_core, the path Flutter's generated package uses; it was a "Conflicting identity" warning or a resolution error. The example hosts reference their plugin the same way. No behaviour change.
  • flutter/pubspec.yaml — adds ping_davinci and its example to the workspace

Platform differences the bridge handles

Android iOS Bridge
Collector registration eager (AndroidX Startup) detached Task {} in createDaVinci, racing start() iOS factory awaits its own registration of the 23 keys before returning the handle
ErrorNode.details() on the tenant's wrong-password body throws (SDKS-5536) decodes Android decodes each detail leniently, like iOS
user() after signOff() null (needs the session cookie) returns the cached user, and can redeem an unused code iOS drops the cached user before signing off
Challenge-polling status order Continue after an attempt comes back incomplete .continue before the attempt's request iOS statuses reordered to Android's
Cancelling a poll stops the network polling can't: the SDK's polling task is uncancellable delivery stops on both; iOS limitation documented and pinned by a test
Polling timedOut response recoverable ErrorNode FailureNode passed through as-is, documented, pinned by a test (SDKS-5461)
Validation edge cases (regex full match vs firstMatch, required checkbox, length units) passed through, pinned by native tests (SDKS-5537/5538/5539)

Test plan

  • flutter analyze clean (workspace root)
  • Dart unit tests: 89 passing (ping_davinci)
  • Android native unit tests: 70 passing (:ping_davinci:testDebugUnitTest)
  • iOS native XCTests: 68 passing (RunnerTests in the example host)
  • Hermetic integration suite (in-process mock DaVinci server, fixtures captured from the live test tenant): 23/23 on Android (Pixel 5 API 33) and 23/23 on iOS (iPhone 17 simulator, one file per run)
  • Live against the PingOne DaVinci test tenant on both platforms: sign-on, session/token/userinfo, sign-off, challenge polling (approved through the magic link), simple polling, QR code, metadata, device registration
  • flutter build apk --debug and flutter build ios --debug --no-codesign from ping_davinci/example
  • DEVICE_AUTHENTICATION is verified hermetically only: the tenant offers it only to a signed-in user with an enrolled device

@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@rodrigoareis rodrigoareis mentioned this pull request Oct 28, 2026
5 of 7 tasks

@spetrov spetrov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍🏻

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants