Skip to content

feat: C2PA-verified video import via share sheet#2878

Closed
rabble wants to merge 16 commits into
mainfrom
feat/c2pa-share-target
Closed

feat: C2PA-verified video import via share sheet#2878
rabble wants to merge 16 commits into
mainfrom
feat/c2pa-share-target

Conversation

@rabble
Copy link
Copy Markdown
Member

@rabble rabble commented Apr 8, 2026

Closes #2879

Summary

  • Add C2PA Content Credentials validation for imported videos, gating imports to only verified human-made content
  • Register diVine as an iOS/Android share target so users can share videos from Adobe Fresco, Premiere Pro, etc.
  • iOS Share Extension (native Swift) receives files via App Group, deep-links into Flutter app for C2PA validation
  • Android receives shared videos via intent filter
  • Full import-to-library flow: validate C2PA → show verification status → create clip + draft → navigate to publish

What's included

New files:

  • C2paImportResult model with source type classification (human/AI/composite)
  • C2paImportValidationService reads C2PA manifests and classifies content origin
  • VideoImportBloc manages the import state machine
  • VideoImportService copies file, extracts thumbnail/metadata, creates clip + draft
  • ImportVerificationPage/View shows verification result or education screen
  • iOS ShareExtension/ with ShareViewController.swift
  • Android intent filter for video/*

Modified files:

  • C2paSigningService.signVideo() now accepts DigitalSourceType parameter
  • app_router.dart - new route for import verification
  • main.dart - service registration
  • pubspec.yaml - added share_handler package

Remaining work (follow-up PRs)

  1. Xcode target setup: Share Extension source files exist but the Xcode target must be added via File > New > Target > Share Extension
  2. VideoMetadataScreen draft loading: Needs an alternative entry point to load a draft by ID (currently relies on recording flow providers)
  3. Codemagic CI: Provisioning profile needed for co.openvine.app.ShareExtension

Test plan

  • 37 new tests passing (model: 13, validation: 9, BLoC: 7, service: 3, widget: 5)
  • flutter analyze clean on all new files
  • Manual: Share a video from Photos to diVine on iOS simulator
  • Manual: Share a C2PA-signed video (from Adobe Fresco or created with c2patool) and verify "Verified" screen
  • Manual: Share a video without C2PA and verify education screen

🤖 Generated with Claude Code

@github-actions

This comment has been minimized.

@rabble rabble requested a review from n8fr8 April 8, 2026 03:32
Copy link
Copy Markdown
Member Author

@rabble rabble left a comment

Choose a reason for hiding this comment

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

Solid foundational work — good architecture (UI→BLoC→Service), proper BLoC patterns (droppable, addError, status enum), 37 tests, feature-flagged rollout. A few items to address:

Should fix:

  1. Hardcoded route pathcontext.go('/video-metadata?draftId=...') in ImportVerificationView should use context.goNamed(...) per routing rules ("Prefer Name Over Path")
  2. File paths in URL query params — filesystem paths can contain chars that break URL encoding. Use Uri.encodeComponent or pass via a different mechanism
  3. RepositoryProvider wrapping servicesC2paImportValidationService and VideoImportService are services, not repositories. Semantic mismatch with the architecture rules
  4. Confirm codemagic.yaml change — removing NotificationServiceExtension bundle ID could break notification push provisioning

Notes:

  • No share_handler listener wiring in this PR (feature is inert until follow-up) — expected per PR description
  • The 2,443-line plan document adds review noise — consider keeping planning docs out of feature PRs

Nice C2PA verification flow and source classification logic. Looking forward to Part 2 with the share handler wiring.

🤖 Generated with Claude Code

@rabble rabble marked this pull request as draft April 10, 2026 00:53
rabble and others added 16 commits May 7, 2026 02:30
Comprehensive plan for allowing users to import externally-created
videos (from Adobe Fresco, Premiere Pro, etc.) via OS share sheet,
gated by C2PA Content Credentials verification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix mock class name typos (underscore prefix)
- Use real constructors for registerFallbackValue (no .empty())
- Add registerFallbackValue for C2paImportResult in BLoC test
- Add missing import failure error test
- Standardize on import_verification_page.dart filename
- Fix exhaustive switch (handle error/imported states)
- Replace context.pop() with context.go('/') for reliability
- Resolve share_handler vs custom extension decision
- Document Codemagic wildcard provisioning approach
- Use specific git add paths instead of broad mobile/lib/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…brary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add share_handler package for receiving shared files from other apps.
Register ImportVerificationPage route in GoRouter as a full-screen
standalone route. Provide C2paImportValidationService and
VideoImportService via MultiRepositoryProvider so the import
verification page can access them through context.read<>().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add c2paVerifiedImport feature flag (FF_C2PA_VERIFIED_IMPORT).
Route redirects to home when flag is disabled. Default: off.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… UI)

Add tests for importing/error UI states, BlocListener navigation,
close button, event Equatable props, state copyWith, file copy
verification, and missing source file error handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rabble rabble force-pushed the feat/c2pa-share-target branch from 0962c4f to 7b53e61 Compare May 6, 2026 14:39
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Codex seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Mobile PR Preview

Preview refreshed for 7b53e61

Last refresh: 7b53e61 at 2026-05-06 14:45:16 UTC (preview run)

Property Value
Preview URL https://4980254e.openvine-app.pages.dev
Pages project openvine-app
Preview branch pr-2878
PR branch feat/c2pa-share-target
Commit 7b53e61

@rabble
Copy link
Copy Markdown
Member Author

rabble commented May 11, 2026

Draft review notes

The C2PA import architecture is plausible, but the current draft does not look end-to-end complete yet. The main platform entrypoints and success path still need wiring/verification.

Top findings

  • High: Share entrypoints do not appear wired into Flutter.

    • share_handler is added, but I did not see actual usage. Android adds an ACTION_SEND video/* intent filter, but nothing appears to consume the shared URI and navigate to import verification. iOS opens divine://import?path=..., while the Flutter route added is /import-verification?path=... unless existing deep-link resolution maps that.
  • High: Successful import likely dead-ends.

    • The UI navigates to /video-metadata?draftId=..., while the PR body lists “VideoMetadataScreen draft loading” as remaining work. That means the main success path is not complete.
  • High: C2PA policy may accept unknown source types.

    • C2paSourceClassification.unknown is accepted because only AI-generated/composite-with-AI types are rejected. If the product promise is verified human-made content, unknown source types should fail closed.
  • Medium: iOS Share Extension is source-only, not build-integrated.

    • The PR body says the Xcode target still must be added. Until target/entitlements/bundle/provisioning are in the project, iOS sharing is not shippable or CI-verifiable.
  • Medium: Android shared videos are often content:// URIs.

    • The import service expects filesystem paths and uses File(sourcePath).copy(...), which will not work for raw content:// URIs unless a layer first materializes them to a file.

Security/privacy notes

Avoid logging full local file paths where possible. Also validate route path input carefully: non-empty, expected scheme/location, file exists/type/size before processing. proofManifestJson: validationResult.claimGenerator also sounds semantically wrong; a claim-generator string is not proof/manifest JSON.

Readiness

Keep draft until Android/iOS share handling is wired end-to-end, unknown C2PA source types fail closed, metadata draft loading works, and at least one manual/integration path validates the full import journey.

@NotThatKindOfDrLiz
Copy link
Copy Markdown
Member

Closing this draft PR as stale and not currently shippable.

Reason for closing:

  • The branch is out of date and GitHub reports it as dirty.
  • The last CI run failed, and the CLA check is still pending.
  • The PR description itself calls out core remaining work: Xcode Share Extension target setup, VideoMetadata draft-loading support, and Codemagic provisioning.
  • Prior review also identified functional blockers in the end-to-end import path, including incomplete share-entry wiring and other readiness gaps.

This should come back as a fresh PR from current main if we still want the feature. At that point it should be narrowed to a reviewable, end-to-end shippable slice with green CI and complete platform wiring.

Closing rather than leaving a large incomplete draft open avoids confusion about implementation status.

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.

feat: C2PA-verified video import via share sheet

3 participants