Skip to content

Fix Android HTTP JNI leaks and honor SQLite storage selection - #1555

Merged
bmehta001 merged 3 commits into
microsoft:mainfrom
bmehta001:fix/android-jni-storage
Nov 5, 2026
Merged

bmehta001 merged 3 commits into
microsoft:mainfrom
bmehta001:fix/android-jni-storage

Conversation

@bmehta001

Copy link
Copy Markdown
Contributor

Summary

Fixes #1551.
Fixes #1550.

  • Scope every Android HTTP send's JNI local frame through execution and all error returns; do not promote the FutureShim into a caller frame on a persistently attached thread.
  • Release the task's global reference before completion/cancellation callbacks, including create/execute/cancel failures. Retained native requests no longer retain completed futures. Remove failed requests before invoking callbacks and keep a stable request-ID copy when a callback deletes its request.
  • Delete temporary class references used for cancellation and client setup.
  • Preserve the AAR's Room default without forcing it over an explicit MATSDK_ANDROID_USE_ROOM=OFF. Restore the deprecated USE_ROOM alias; an explicit canonical option takes precedence.
  • Add an ART/CheckJNI emulator regression job and validate actual AAR storage sources/definitions in the existing all-ABI, Room/SQLite no-exceptions build matrix.

Validation

Check Result
Windows-hosted Android API 30 x86_64 emulator, -Xcheck:jni All 13 lifecycle cases passed: success, network failure, individual/bulk/early/preparing cancellation, create/execute/cancel exceptions, null task, synchronous callback deletion, asynchronous completion, and completion/cancellation races.
Persistent-thread stress 60,000 successful sends on one attached native thread; zero retained FutureShim objects after GC, while both the thread and native request objects remain alive.
Regression against original client The callback-deletes-request case fails with 1,024 retained FutureShim objects, isolating the local-reference leak even when native destructors release globals.
AAR storage configuration All 7 combinations passed: default, canonical ON/OFF, legacy ON/OFF, and both conflicting combinations. The original wrapper reproduces OFF becoming ON in CMakeCache.
Actual AAR JNI libraries Room and SQLite x86_64 builds passed; native symbols confirm the selected storage implementation. ARM64 SQLite JNI build without C++ exceptions also passed.
Windows and WSL Storage option compatibility/precedence tests passed on both.
Lint Changed-line C++ formatting, regression C++ formatting, Java -Xlint:all -Werror, Ruff, and git diff --check passed.

The ART tests link the production C++ HTTP client to a deterministic Java FutureTask peer, without network or AndroidX dependencies. They verify reference lifetime and callback behavior, not a Teams end-to-end session or physical-device reproduction. No cases are skipped or excluded.

Keep local JNI references scoped to every send, including failures, and release task globals before terminal callbacks so retained native requests do not keep completed futures alive. Honor explicit AAR storage options and translate the legacy USE_ROOM flag.

Add ART/CheckJNI GC regressions and AAR storage configuration checks to prevent recurrence.

Files changed:
.github/workflows/build-android.yml
cmake/MatsdkOptions.cmake
lib/android_build/maesdk/src/main/cpp/CMakeLists.txt
lib/http/HttpClient_Android.cpp
lib/http/HttpClient_Android.hpp
tests/android-http-client/CMakeLists.txt
tests/android-http-client/HttpClient.java
tests/android-http-client/android-http-client-tests.cpp
tests/android-http-client/run-tests.py
tests/android-storage/CMakeLists.txt
tests/android-storage/options-tests.cmake

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 01fc96f0-9072-4225-903a-5402ae46b7ae
@bmehta001
bmehta001 requested a review from a team as a code owner November 5, 2026 06:03
@bmehta001
bmehta001 enabled auto-merge (squash) November 5, 2026 07:07
@bmehta001 bmehta001 self-assigned this Nov 5, 2026
@bmehta001
bmehta001 merged commit cac13ad into microsoft:main Nov 5, 2026
95 checks passed
@bmehta001
bmehta001 deleted the fix/android-jni-storage branch November 5, 2026 07:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants