Repository navigation
Conversation
1. UnsatisfiedLinkError: libusb1.0.so / libsodium.so / libopus.so are
linked into libWfbngRtl8812.so and libVideoNative.so via absolute
paths in each module's CMakeLists.txt, but nothing placed them
under a jniLibs source set, so AGP never packaged them into the
APK and the dynamic linker couldn't find them at runtime. Only
surfaces on a genuinely fresh install/device with no cached APK
already carrying them (e.g. from a properly configured CI/release
build) to mask the gap. Fixed by adding the prebuilt libraries
(already present in each module's src/main/cpp/libs/<abi>/) to a
standard src/main/jniLibs/<abi>/ source set for both modules.
2. SIGABRT in Aggregator::Aggregator ("Unable to open gs.key") /
USB adapter lock false-refusal: WfbngLink.hpp/.cpp hardcoded both
the gs.key path and the USB advisory lock directory as
/data/user/0/com.openipc.pixelpilot/..., which is only correct for
the default applicationId running as Android's default user (id
0). Under a different applicationId (a fork/rebrand) or a
non-default user profile (secondary user, work profile, Samsung
Secure Folder, ...), that path doesn't exist, so opening gs.key
fails outright, and the USB lock (see UsbDeviceLock.h) either
silently degrades to no exclusivity or -- once the directory
happens to resolve to a stale lock from an earlier process -- falsely
reports "in use". Fixed by resolving both from
Context.getFilesDir() via JNI once in the constructor instead.
Verified on-device (Galaxy Tab S7 FE, RTL8812AU): a fresh install now
launches and opens the USB adapter successfully
("USB adapter <id> locked for exclusive access") instead of crashing
or falsely refusing the adapter.
PR Summary by QodoResolve native key and USB lock paths from the app context
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1. Library callers can hit a native crash
|
| jclass contextClass = env->GetObjectClass(context); | ||
| jmethodID getFilesDirMethod = env->GetMethodID(contextClass, "getFilesDir", "()Ljava/io/File;"); | ||
| jobject filesDir = env->CallObjectMethod(context, getFilesDirMethod); |
There was a problem hiding this comment.
1. Library callers can hit a native crash 🐞 Bug ☼ Reliability
resolveFilesDir passes context and each returned JNI object into subsequent calls without checking for null values or pending exceptions. A caller constructing WfbNgLink with a null context now reaches GetObjectClass and continues through invalid JNI results, potentially aborting initialization instead of reporting a controlled Java error.
Agent Prompt
## Issue description
The new files-directory resolver dereferences the constructor's `Context` without validating it and continues after JNI lookup or invocation failures. This can turn a null context or pending Java exception into an uncontrolled native failure.
## Issue Context
`WfbNgLink` exposes a public constructor that forwards its argument directly to `nativeInitialize`. Validate the context before native initialization and stop immediately after any JNI exception or null result, preferably by throwing a clear Java exception rather than continuing with invalid JNI values.
## Fix Focus Areas
- app/wfbngrtl8812/src/main/cpp/WfbngLink.cpp[55-66]
- app/wfbngrtl8812/src/main/java/com/openipc/wfbngrtl8812/WfbNgLink.java[53-55]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
Code review by qodo was updated up to the latest commit 06f85fe |
josephnef
left a comment
There was a problem hiding this comment.
Thanks, the two halves of this need different answers.
Part 2, resolving the files dir from Context: yes, please keep it. The hard-coded /data/user/0/com.openipc.pixelpilot/... for both gs.key and devourer's lock dir was a documented gotcha (it is in CLAUDE.md) and this is the right fix: AggregatorUDPv4 and TxArgs already take std::string paths, so the type change is clean. Two small asks there: check the JNI results for null and pending exceptions in resolveFilesDir (Qodo's note, and it keeps a library consumer from crashing with a bare Context), and the lock dir comment can drop the "resolved in the constructor" cross-reference now that the member name says it.
Part 1, the jniLibs copies: I cannot reproduce the problem and would rather not take 8 MB of duplicated binaries. Both APKs that CI produces today already contain libusb1.0.so, libsodium.so and libopus.so for both ABIs (checked with unzip -l on the debug artifact from the reopened run and on the latest release APK). AGP 8.5 packages shared libraries that a CMake target links by absolute path, which is why the existing src/main/cpp/libs/<abi>/ setup works. If your fresh-install UnsatisfiedLinkError came from an Android Studio build, can you say which AGP / Studio version and whether useLegacyPackaging was in effect? If there is a real configuration that drops them, the fix should be sourceSets.main.jniLibs.srcDirs pointing at the existing cpp/libs directories rather than a second copy of the files.
CI note: format, host test, debug APK and emulator smoke are all green on this branch.
So: drop the four jniLibs/ binaries (or replace with srcDirs plus the evidence), add the null checks, and this is good to merge.
UnsatisfiedLinkError: libusb1.0.so / libsodium.so / libopus.so are
linked into libWfbngRtl8812.so and libVideoNative.so via absolute
paths in each module's CMakeLists.txt, but nothing placed them
under a jniLibs source set, so AGP never packaged them into the
APK and the dynamic linker couldn't find them at runtime. Only
surfaces on a genuinely fresh install/device with no cached APK
already carrying them (e.g. from a properly configured CI/release
build) to mask the gap. Fixed by adding the prebuilt libraries
(already present in each module's src/main/cpp/libs//) to a
standard src/main/jniLibs// source set for both modules.
SIGABRT in Aggregator::Aggregator ("Unable to open gs.key") /
USB adapter lock false-refusal: WfbngLink.hpp/.cpp hardcoded both
the gs.key path and the USB advisory lock directory as
/data/user/0/com.openipc.pixelpilot/..., which is only correct for
the default applicationId running as Android's default user (id
0). Under a different applicationId (a fork/rebrand) or a
non-default user profile (secondary user, work profile, Samsung
Secure Folder, ...), that path doesn't exist, so opening gs.key
fails outright, and the USB lock (see UsbDeviceLock.h) either
silently degrades to no exclusivity or -- once the directory
happens to resolve to a stale lock from an earlier process -- falsely
reports "in use". Fixed by resolving both from
Context.getFilesDir() via JNI once in the constructor instead.
Verified on-device (Galaxy Tab S7 FE, RTL8812AU): a fresh install now
launches and opens the USB adapter successfully
("USB adapter locked for exclusive access") instead of crashing
or falsely refusing the adapter.
🤖 Generated with Claude Code