Skip to content

fix(android): bound JNI references and runtime workers#1370

Open
maybeknott wants to merge 2 commits into
therealaleph:mainfrom
maybeknott:fix/android-jni-local-frames
Open

fix(android): bound JNI references and runtime workers#1370
maybeknott wants to merge 2 commits into
therealaleph:mainfrom
maybeknott:fix/android-jni-local-frames

Conversation

@maybeknott
Copy link
Copy Markdown

@maybeknott maybeknott commented May 23, 2026

Android JNI and runtime setup now keep resource ownership bounded on mobile devices.

This PR has two focused changes in src/android_jni.rs:

  • string-returning JNI entry points route through a shared conversion helper that uses an explicit local frame, preserving only the returned jstring for the JVM caller and releasing temporary handles before native methods exit;
  • the long-lived proxy Tokio runtime sizes its worker pool from available device parallelism, clamped between two and four workers, instead of always starting four workers on every Android target.

The JNI change protects repeated version, log, stats, update, SNI probe, and diagnostics calls from accumulating unmanaged local references as those paths evolve. Allocation or frame setup failures still return a null string, preserving the existing failure contract.

The runtime sizing change keeps at least two workers for accept, tunnel, stats, and shutdown work while avoiding unnecessary scheduler width on low-core phones, tablets in power-saving mode, and embedded Android targets. One-shot JNI runtimes used for probes and certificate operations remain current-thread runtimes.

No Kotlin method signatures, config fields, proxy routing behavior, payload contents, or Android lifecycle contracts change.

Android JNI entry points return string payloads for version checks, log drains, update checks, SNI probes, live stats, and pipeline diagnostics. Several of those methods are invoked repeatedly by the Kotlin UI while the proxy is running, so each path should keep JNI local-reference ownership explicit and bounded even when future payload construction adds intermediate Java objects.

Add a shared string_to_jstring helper that builds returned Java strings inside an explicit local frame with with_local_frame_returning_local. The frame preserves only the returned jstring for the JVM caller and releases temporary local handles before the native method exits. Allocation or frame setup failures continue to return a null jstring, preserving the existing failure contract.

Route every Android string-returning native entry point through the helper without changing payload contents, method names, signatures, threading behavior, or Kotlin call sites. This keeps repeated telemetry and diagnostics polling from relying on the implicit native-method frame and gives the JNI boundary a single audited conversion path.
@github-actions github-actions Bot added the type: fix fix: PR — auto-applied by release-drafter label May 23, 2026
Android startup built the long-lived proxy Tokio runtime with a fixed four-worker pool on every device. That is unnecessarily large on low-core phones, tablets in power-saving mode, and embedded Android targets, while still being capped enough that larger devices do not need more than a small bounded pool for this local proxy workload.

Add a dedicated worker-count helper for the Android proxy runtime. It reads the platform's available parallelism when the runtime starts, falls back to the minimum proxy-safe worker count when the value is unavailable, and clamps the result between two and four workers. The lower bound keeps accept, tunnel, stats, and shutdown work from competing on a single worker; the upper bound preserves the previous maximum and avoids creating a wider scheduler on constrained mobile CPUs.

Use the computed value when constructing the runtime and log the selected worker count once during startup. One-shot JNI runtimes used for probes and certificate operations remain current-thread runtimes, and no Kotlin method signatures, config fields, proxy routing behavior, or Android lifecycle contracts change.
@maybeknott maybeknott changed the title fix(android): bound JNI string local references fix(android): bound JNI references and runtime workers May 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix fix: PR — auto-applied by release-drafter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant