Compare commits

...

2 Commits

Author SHA1 Message Date
9f32185b78 Merge branch 'fix/recents-wipe-jni-null-view'
Guard against Gio's null-view detach event (recents-wipe SIGABRT).
2026-08-20 23:35:08 -04:00
d70bbfed13 Guard against Gio's null-view detach event (recents-wipe SIGABRT)
Gio's GioView.onDestroyView sends ViewEvent{View: 0} as its detach
signal when the view is destroyed — i.e. the activity going away on a
recents-wipe. An app that forwards the event to Enable() passes a zero
view through to registerFragment, whose GetObjectClass(null) aborts the
process (JNI DETECTED ERROR: java_object == null in call to
GetObjectClass).

Enable() now returns early on a zero view so all callers are covered
even if they forward the event unfiltered, and registerFragment
null-checks as defense in depth. Same fix as pad (fdbffc9); verified
there on a Pixel 9 Pro / Android 17 where the recents swipe used to
crash the app.
2026-08-20 22:16:23 -04:00
2 changed files with 17 additions and 0 deletions

View File

@ -225,6 +225,15 @@ func NewBLE() *BLE {
//Enable
func (b *BLE) Enable(view uintptr) {
log.Printf("ble.Enable()")
// view == 0 is Gio's detach signal (GioView.onDestroyView sends
// ViewEvent{View: 0} when the view is destroyed, e.g. the activity
// going away on a recents-wipe). Nothing to register; passing the null
// ref on would abort in JNI (GetObjectClass on null). A re-attach
// arrives as a fresh event with a live view. Callers that forward the
// event unfiltered are protected by this guard.
if view == 0 {
return
}
setJVM(app.JavaVM())
runInJVM(func(env *JNIEnv) {
log.Printf("ble.Enable(): inside runInJVM()")

View File

@ -5,6 +5,14 @@
void
registerFragment(JNIEnv *env, jobject view) {
if (view == NULL) {
// Detach signal (Gio sends ViewEvent{View: 0} when the view is
// destroyed, e.g. the activity going away on a recents-wipe).
// The Go side already filters these; this guard keeps the JNI
// calls safe if one ever slips through (GetObjectClass on null
// aborts the process).
return;
}
jclass cls = (*env)->GetObjectClass(env, view);
jmethodID mid = (*env)->GetMethodID(env, cls, "getContext", "()Landroid/content/Context;");
jobject ctx = (*env)->CallObjectMethod(env, view, mid);