feat(bridge,android): BridgeEvent::PermissionState + JNI publish hook + c++_shared link

Per SDD-106 §5 add BridgeEvent::PermissionState{permission, state}
with the PermissionStateKind enum (Granted, Denied, PermanentlyDenied,
Unknown). The Kotlin side publishes mid-session permission changes
through a new JNI entry point Java_app_chanora_chanora_1flutter
_MainActivity_publishPermissionState routed by the new
permission_jni.rs module; the Rust audio engine subscribes and
authoritatively clamps the transmit gate (see SDD-106 §6).

Adds crates/chanora_bridge/build.rs to emit
cargo:rustc-link-lib=dylib=c++_shared on Android so libchanora_bridge
.so carries DT_NEEDED libc++_shared.so; this is required by Android
API 24+ per-library linker namespaces to resolve __cxa_pure_virtual
and friends at System.loadLibrary time.

Includes the FRB-regenerated Dart counterparts so each commit is
independently buildable.

Trace: SDD-105, SDD-106 §5, SDD-118 item 6 (extended).
This commit is contained in:
EdisonJwa
2026-05-18 12:32:01 +08:00
parent 56222d190e
commit 7966a7c8c6
12 changed files with 594 additions and 33 deletions
+12 -3
View File
@@ -20,9 +20,15 @@
//!
//! ## Boundary discipline
//!
//! Every type in this module is `Serialize + Deserialize` over owned
//! primitives or `String`s. No `tsclientlib`, `cpal`, or backend
//! types may appear in the public surface (SAD-067, SDD-079).
//! Every type in this module is built from owned primitives or
//! `String`s — no `tsclientlib`, `cpal`, or backend types may
//! appear in the public surface (SAD-067, SDD-079). Cross-language
//! serialisation is handled by `flutter_rust_bridge`'s generated
//! glue, so most public DTOs and the `BridgeEvent` enum intentionally
//! do *not* carry `serde::{Serialize, Deserialize}` derives — FRB
//! emits its own SSE encoders/decoders. `BridgeError` carries serde
//! derives historically; new bridge types should follow the
//! FRB-only convention unless an explicit non-FRB consumer is added.
//!
//! Note: this crate cannot use `#![forbid(unsafe_code)]` because the
//! FRB-generated glue (in `frb_generated`) legitimately uses unsafe
@@ -37,6 +43,9 @@ mod frb_generated;
#[cfg(target_os = "android")]
mod android_init;
#[cfg(target_os = "android")]
mod permission_jni;
use thiserror::Error;
/// Errors raised at the bridge boundary. Production code must keep