Genymobile / Genymobile/scrcpy

Use a compile-only framework stub for `IContentProvider.call()`

Open
#7,010 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
150k
Forks
13.8k
Avg merge
4d 13h
Merged PRs (30d)
2

Description

Background

The scrcpy server uses reflection to access Android framework APIs that are hidden from the public SDK. Reflection is still necessary for private members and for APIs whose runtime compatibility cannot be trusted, but some framework APIs are callable at runtime and are only absent from the SDK android.jar.

I previously opened #6492 to discuss using local framework declarations for these cases. At the time, I did not have enough time to prepare a series of small, testable changes. I would now like to revisit the idea step by step, starting with one limited call site. If you think this approach is reasonable, I would consider separate, focused proposals and PRs for other suitable APIs later.

The first candidate is IContentProvider.call() in the settings provider wrapper. scrcpy already exposes the framework object as IContentProvider, but the wrapper stores it as Object and invokes call() through reflection.

Problem

For this call site, the current reflection layer:

  • discards an existing useful framework type;
  • performs reflective lookup and argument assembly for four historical signatures;
  • introduces reflection-specific exception handling around a Binder call;
  • packages the local IContentProvider declaration in the server DEX, even though the runtime definition must come from the Android framework.

The implementation must continue to support the historical signatures used from Android 9 and earlier through Android 12 and later. Compatibility with vendor-modified frameworks is also important, so older signatures should still be selected by runtime capability rather than only by SDK_INT.

Proposed direction

  • Move the local IContentProvider declaration to a small compile-only module.
  • Keep the provider strongly typed and call IContentProvider.call() directly.
  • Preserve the existing pre-Android 12 fallback order and cache the selected signature on the provider instance.
  • Keep the public SettingsException contract unchanged.
  • Ensure that the stub is available during compilation but is not defined in the final server DEX.

Direct calls produce Binder, runtime, and linkage failures instead of reflection-specific exceptions. The implementation should use only a missing intermediate method to select an older signature; other failures should retain their meaning and continue to be reported through SettingsException.

Scope

This proposal only covers IContentProvider.call() in the settings provider wrapper. It does not attempt to replace reflection used for private fields, private constructors, or unrelated framework wrappers.

Acceptance criteria

  • ContentProvider no longer uses reflection for IContentProvider.call().
  • All four existing framework signatures remain supported.
  • The pre-Android 12 runtime fallback and per-provider cache are preserved.
  • The final server DEX references IContentProvider but does not define it.
  • Both Gradle and non-Gradle server builds work.
  • Runtime behavior is verified on representative Android versions before merging.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the settings provider wrapper and its existing local IContentProvider declaration, then inspect the server's Gradle and non-Gradle build definitions. Trace the current reflective call, fallback order, and per-provider cache before designing the compile-only module. Done means all four signatures remain supported, the stub is absent from the server DEX, both builds work, and representative Android versions preserve the SettingsException contract.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
build-system, mobile-dev
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.