Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: deviceplug/btleplug
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: deviceplug/btleplug
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: dev
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 19 commits
  • 23 files changed
  • 2 contributors

Commits on May 25, 2026

  1. build: Upgrade jni from 0.19 to 0.20

    Breaking changes addressed:
    - call_method_unchecked takes &[jni::sys::jvalue] instead of &[JValue];
      added JValue::to_jni() at all ~40 call sites
    - JavaType replaced by ReturnType in call_method_unchecked return type
      parameter (Object/Array/Primitive instead of carrying class strings)
    - JMethodID no longer has a lifetime parameter
    - JObject::into_inner() renamed to into_raw()
    - set_rust_field/get_rust_field/take_rust_field marked unsafe; wrapped
      all 9 call sites in unsafe blocks
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    fdcaedb View commit details
    Browse the repository at this point in the history
  2. build: Upgrade jni from 0.20 to 0.21

    Major restructure of the Android JNI backend for jni-rs 0.21 breaking
    changes. JNIEnv now requires &mut self for all operations and JObject
    types are no longer Copy/Clone.
    
    Key changes:
    - Remove env field from all JNI wrapper structs, pass &mut JNIEnv
      per-method-call instead
    - JSendFuture/JSendStream store JavaVM and obtain env via get_env()
      on each poll, solving the Future::poll env-passing problem
    - Replace JList/JMap wrapper usage with direct env.call_method()
      iteration to avoid &mut borrow conflicts
    - Extract throw_panic from throw_unwind to enable catch_unwind in
      ops.rs without double &mut env borrows
    - Use typed arrays (JByteArray, JObjectArray) per 0.21 API
    - Wrap call_method_unchecked in unsafe blocks with raw jvalue args
    - Update test infrastructure for RefCell<JNIEnv> invariance: explicit
      RefMut guards, scoped setup before block_on, block-scoped borrows
      between await points
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    38e4804 View commit details
    Browse the repository at this point in the history
  3. fix: Update droidplug and test crate for jni 0.21 lifetime requirements

    jni 0.21 tightened lifetime variance on JNIEnv, requiring explicit shared
    lifetimes wherever JObject and JNIEnv are used together.
    
    Changes:
    - `with_obj` closure: use HRTB `for<'env>` so JNIEnv and JPeripheral share
      the same lifetime, fixing the invariant mutable reference errors
    - `Peripheral::new`, `report_scan_result`, `adapter_report_scan_result_internal`,
      `adapter_report_scan_result` JNI callback: add explicit `'a` lifetime
      annotations tying env and JObject parameters together
    - `adapter_on_connection_state_changed_internal`: get address string before
      acquiring the MutexGuard from `get_rust_field` to avoid double-mutable
      borrow of env
    - `JUuid::as_obj().as_raw()` → `uuid.as_raw()` via Deref: `JObject::as_obj()`
      was removed in jni 0.21; JUuid already Derefs to JObject
    - Test crate `lib.rs`: update `run_test`, `initBtleplug`, and `jni_test!`
      macro to use `&mut JNIEnv` as required by the updated API
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    f59c47e View commit details
    Browse the repository at this point in the history
  4. build: Bump jni from 0.21 to 0.22

    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    3f8cef1 View commit details
    Browse the repository at this point in the history
  5. refactor: Rename JNIEnv to Env and GlobalRef to Global<T> across droi…

    …dplug
    
    Phase 2 of jni 0.22 migration. Non-FFI function signatures now use
    Env<'a> instead of JNIEnv<'a>. GlobalRef fields in Clone structs are
    wrapped in Arc<Global<JObject<'static>>>. Classcache stores
    Arc<Global<JObject<'static>>>.
    
    extern "C" FFI functions and test_utils are left as-is for later phases.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    0b81626 View commit details
    Browse the repository at this point in the history
  6. refactor: Wrap JNI strings with jni_str! and signatures with jni_sig!

    Phase 3 of jni 0.22 migration. All string literals passed to JNI API
    methods (find_class, get_method_id, call_method, new_object,
    is_instance_of, set/get/take_rust_field, call_static_method) are now
    wrapped with jni_str!() for names and jni_sig!() for type signatures.
    
    classcache::find_add_class uses JNIString for runtime &str conversion.
    register_native_methods calls wrapped in unsafe blocks (required by 0.22).
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    b2f0528 View commit details
    Browse the repository at this point in the history
  7. refactor: Migrate to callback-based attach_current_thread

    Replace all deprecated get_env() and attach_current_thread_permanently()
    calls with jni 0.22's callback-based attach_current_thread(|env| {...}).
    
    Production code: adapter.rs (4 sites), peripheral.rs with_obj + notifications
    closure (2 sites), future.rs poll_internal (1 site), stream.rs
    poll_next_internal (1 site).
    
    Test infrastructure: Replace RefCell<JNIEnv<'static>> thread-local with
    with_env(f) helper that wraps attach_current_thread. This is a fundamental
    rethink — 0.22's callback model means Env can't escape the closure, so the
    old pattern of storing env in a RefCell is dead. All 25 test call sites
    migrated from JVM_ENV.with(|cell|) to with_env(|env|). Block_on/join tests
    use nested with_env calls for independent env access.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    6a19506 View commit details
    Browse the repository at this point in the history
  8. refactor: Migrate extern C functions to EnvUnowned + with_env pattern

    Completes the jni 0.22 FFI migration:
    - ops.rs: JNIEnv → Env for non-FFI code, EnvUnowned + with_env() for
      extern "C" fn_adapter_call_internal and fn_adapter_close_internal
    - jni/mod.rs: extern "C" callbacks migrated to EnvUnowned + with_env()
    - classcache: Store Global<JClass<'static>> instead of Global<JObject<'static>>
      so &Global<JClass> satisfies Desc<JClass> for new_object/get_method_id
    - Fix <&JClass>::from(class.as_obj()) → class.as_ref() across all files
    - arrays.rs: new_byte_array now takes usize, remove jint cast
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    7905053 View commit details
    Browse the repository at this point in the history
  9. fix: Update exception handling and NativeMethod for jni 0.22

    - exception_check() now returns bool (was Result<bool>), remove ?
    - exception_occurred() now returns Option<JThrowable> (was Result), use .unwrap()
    - exception_clear() now returns () (was Result<()>), remove ?/.unwrap()
    - throw() now returns Err(JavaException) on success; use match or let _ =
      instead of .unwrap()/.? to preserve original control flow semantics
    - JObject → JThrowable/JString: use env.cast_local::<T>() (From impls removed)
    - NativeMethod struct fields replaced by unsafe from_raw_parts constructor
    - JObjectArray::from_raw now requires env param and element type param
    - JavaStr → MUTF8Chars in test string assertions (String::from(chars))
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    a2f5816 View commit details
    Browse the repository at this point in the history
  10. fix: Modernize deprecated jni 0.22 APIs and fix Android-only build er…

    …rors
    
    Migrate deprecated array methods to type methods (JByteArray::set_region,
    JPrimitiveArray::len, JObjectArray::get_element), replace removed
    From<JObject> for JString with cast_local, update from_raw calls to pass
    env, fix jboolean (now bool) comparisons, resolve JObject Send lifetime
    issue in async connect by scoping Global references, and replace
    env.get_string with JString::mutf8_chars throughout.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    16aaa20 View commit details
    Browse the repository at this point in the history
  11. fix: Migrate Android test crate to jni 0.22 EnvUnowned + with_env pat…

    …tern
    
    Replace deprecated JNIEnv with EnvUnowned in extern "system" FFI entry
    points, use with_env/into_outcome for env access, and update throw_new
    to use jni_str! and JNIString for 0.22 string type requirements.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    0d7a9f0 View commit details
    Browse the repository at this point in the history
  12. refactor: Replace JNI boilerplate with bind_java_type! macros and Jav…

    …aVM::singleton()
    
    Convert all hand-rolled JNI wrapper types (struct + from_env + Deref + From impls)
    to jni 0.22's bind_java_type! macro. Replace GLOBAL_JVM OnceCell with
    JavaVM::singleton(). Simplify JSendFuture/JSendStream by dropping cached
    JMethodID fields in favour of cast_local per poll call.
    
    Net reduction of ~780 lines of boilerplate.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    dfdcf34 View commit details
    Browse the repository at this point in the history
  13. refactor: Replace adapter extern C callbacks with native_method! macro

    The macro generates extern "system" trampolines with automatic catch_unwind
    and error-to-Java-exception propagation, replacing the manual EnvUnowned
    pattern that silently swallowed errors.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    93a3e34 View commit details
    Browse the repository at this point in the history
  14. refactor: Eliminate classcache module, use bind_java_type! class caching

    Replace the hand-rolled DashMap-based class cache with bind_java_type!'s
    built-in global class caching via Reference::lookup_class(). Add bare
    bind_java_type! declarations for exception types, FnAdapter, and other
    utility classes previously only tracked in classcache. Delete
    classcache.rs entirely.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    3c1b3a0 View commit details
    Browse the repository at this point in the history
  15. fix: Fix Android cross-compilation issues with bind_java_type! macros

    - Use string literal syntax for Java class paths containing "impl"
      keyword (bind_java_type! parses dot-separated idents, and "impl" is
      reserved in Rust)
    - Use block syntax for methods with name overrides (inline sig + block
      is not supported, must use { name = "...", sig = (...) -> T } form)
    - Fix borrow checker issues in JPeripheral wrapper methods by splitting
      raw call and cast_local into separate statements
    - Fix error type mismatches in with_obj and notification stream by
      unifying on crate::Result
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    70b0ca4 View commit details
    Browse the repository at this point in the history
  16. fix: Fix JNI signature mismatches caused by bind_java_type! JObject m…

    …apping
    
    bind_java_type! maps JObject to Ljava/lang/Object; in JNI signatures, but
    Java methods using domain-specific types (UUID, Future, Stream, ScanResult,
    byte[], List, Map, etc.) require exact signature matches. This caused runtime
    "Method not found" errors and a SIGSEGV in the scan callback.
    
    Changes:
    - objects.rs: Move all methods with domain-typed params/returns out of
      bind_java_type! into manual env.call_method() with correct JNI signatures.
      Keep bind_java_type! for class definitions and primitive-only methods.
    - future.rs: Move JFuture::poll to manual impl with correct Waker/PollResult sigs
    - stream.rs: Move JStream::poll_next to manual impl with correct Waker/PollResult sigs
    - mod.rs: Fix reportScanResult to use extern "C" + EnvUnowned + with_env for
      raw JNI ABI compatibility (from_raw_parts requires raw C calling convention).
      Add env.get_java_vm() to seed JavaVM singleton during init.
    - peripheral_finder.rs: Add catch_unwind and logging to adapter background thread
      for Android debugging (silent thread death caused confusing RecvError)
    
    Verified: 28/29 Android integration tests pass on Pixel 9a. The single failure
    (testPropertiesContainPeripheralInfo TX power) is a test-peripheral issue.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    1194685 View commit details
    Browse the repository at this point in the history
  17. fix: Propagate JNI callback failures instead of silently discarding them

    Replace the deprecated `into_outcome()` pattern with jni-rs 0.22's
    `resolve::<ThrowRuntimeExAndDefault>()` for scan result reporting,
    FnAdapter call/close callbacks, and test initialization.
    
    In `adapter_on_connection_state_changed`, errors were previously
    swallowed with `let _ =`. Now Rust-side errors are thrown as Java
    RuntimeExceptions when no JNI exception is already pending.
    qdot committed May 25, 2026
    Configuration menu
    Copy the full SHA
    9e8a10d View commit details
    Browse the repository at this point in the history
  18. chore: run rustfmt

    qdot committed May 25, 2026
    Configuration menu
    Copy the full SHA
    7dd9823 View commit details
    Browse the repository at this point in the history
  19. fix: resolve clippy warnings breaking CI

    - bluez/peripheral: fix never_loop, use map entry API, use .values()
    - bluez/adapter: collapse nested match into outer pattern
    - droidplug/exceptions: remove redundant closure call, collapse nested ifs
    - droidplug/ops: suppress unused_unit and type_complexity from macro-generated code
    - lib.rs: allow dead_code on jni-host-tests module (callers are Android-only)
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    qdot and claude committed May 25, 2026
    Configuration menu
    Copy the full SHA
    1e129e2 View commit details
    Browse the repository at this point in the history
Loading