ffi 1.29: retire the C sx_android_query_safe_insets body
Closes the Phase 1D migration for the safe-insets JNI chain. The C function and its `#foreign` declaration in `android.sx` are gone; all dispatch now goes through the sx-side `#jni_call` machinery plus the JavaVM helpers landed in 1.26. What's gone from `library/vendors/sx_android_jni/sx_android_jni.c`: - `#include <android/native_activity.h>` and `<jni.h>` (no longer needed without the JNI body). - `sx_android_query_safe_insets` — 55 lines of `(*env)->Foo` chain with manual `goto done` early-exit. Migrated to `library/modules/platform/android.sx::sx_query_safe_insets_jni` in 1.25 (15 lines of `#jni_call`). What stays: - `sx_android_install_input_handler` — non-JNI; struct-field assignment against `struct android_app`'s `onInputEvent` slot. No sx equivalent yet (would need to either land a `#android_app`- style intrinsic or hand-roll the offset, neither of which is Phase 1 scope). - `<android/input.h>` and the `struct sx_android_app_min` mirror needed by the input-handler installer. Net diff: -55 lines in the .c file, -1 line `#foreign` decl in android.sx. Phase 2 (declarative JNI imports) will revisit whether the .c file can be deleted entirely (the input-handler hop may move into a different shape). Verification: - zig build + zig test + run_examples + cross_compile all green. Notable: the previously-failing `ffi-objc-call-12-rect-u64-returns` also passes now — looks like the working-tree `#import c` work was tidied up alongside. - chess Android APK rebuilt + reinstalled + launched on Pixel device; safe-insets behavior unchanged (board top edge sits below the status bar correctly, all pieces in starting positions, no status-bar overlap).
This commit is contained in:
@@ -51,8 +51,11 @@ AMotionEvent_getAction :: (event: *void) -> s32 #foreign;
|
||||
AMotionEvent_getX :: (event: *void, pointer_index: u64) -> f32 #foreign;
|
||||
AMotionEvent_getY :: (event: *void, pointer_index: u64) -> f32 #foreign;
|
||||
|
||||
// JNI/glue bridges from vendors/sx_android_jni/sx_android_jni.c.
|
||||
sx_android_query_safe_insets :: (activity: *void, top: *s32, left: *s32, bottom: *s32, right: *s32) -> void #foreign;
|
||||
// Glue bridge from vendors/sx_android_jni/sx_android_jni.c. The
|
||||
// safe-insets JNI chain that used to live in that file was migrated
|
||||
// to sx (see `sx_query_safe_insets_jni` below) — what remains is the
|
||||
// input-handler installer, which is plain struct-field plumbing
|
||||
// rather than JNI dispatch.
|
||||
sx_android_install_input_handler :: (app: *void, handler: (*void, *void) -> s32) -> void #foreign;
|
||||
|
||||
// JavaVM vtable indirection — used to attach the calling thread to
|
||||
|
||||
74
library/vendors/sx_android_jni/sx_android_jni.c
vendored
74
library/vendors/sx_android_jni/sx_android_jni.c
vendored
@@ -2,11 +2,16 @@
|
||||
// so consumers don't need to vendor an identically-named copy. The sx
|
||||
// compiler resolves `#source "vendors/..."` against the stdlib search
|
||||
// paths in addition to the consumer's project root.
|
||||
//
|
||||
// The safe-insets JNI chain that used to live here was migrated to
|
||||
// sx in Phase 1D of the FFI plan (see `library/modules/platform/
|
||||
// android.sx::sx_query_safe_insets_jni` and the JavaVM helpers
|
||||
// alongside it). What remains is the input-handler installer, which
|
||||
// is a plain C struct-field assignment rather than JNI dispatch and
|
||||
// has no sx equivalent yet.
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/native_activity.h>
|
||||
#include <android/input.h>
|
||||
#include <jni.h>
|
||||
|
||||
// Mirror of struct android_app (NDK 29 / arm64) up to the fields we touch.
|
||||
// Avoids depending on the glue header in the sx library compile path.
|
||||
@@ -26,69 +31,4 @@ void sx_android_install_input_handler(void* app,
|
||||
struct sx_android_app_min* a = (struct sx_android_app_min*)app;
|
||||
a->onInputEvent = (int (*)(struct sx_android_app_min*, AInputEvent*))handler;
|
||||
}
|
||||
|
||||
// Query system-bar insets (status bar, nav bar) via JNI:
|
||||
// activity → getWindow() → getDecorView()
|
||||
// → getRootWindowInsets()
|
||||
// → getSystemWindowInset[Top|Left|Bottom|Right]()
|
||||
// Out params receive physical-pixel insets; the sx caller divides by
|
||||
// dpi_scale to convert to logical units. Falls back to zeros if the
|
||||
// view isn't attached yet (e.g. called before the first frame).
|
||||
void sx_android_query_safe_insets(void* activity_ptr,
|
||||
int* out_top, int* out_left,
|
||||
int* out_bottom, int* out_right) {
|
||||
*out_top = 0; *out_left = 0; *out_bottom = 0; *out_right = 0;
|
||||
if (activity_ptr == 0) return;
|
||||
|
||||
ANativeActivity* act = (ANativeActivity*)activity_ptr;
|
||||
JavaVM* vm = act->vm;
|
||||
if (vm == 0) return;
|
||||
|
||||
JNIEnv* env = 0;
|
||||
int already_attached = 1;
|
||||
if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) {
|
||||
already_attached = 0;
|
||||
if ((*vm)->AttachCurrentThread(vm, &env, 0) != 0) return;
|
||||
}
|
||||
|
||||
jobject activity_obj = act->clazz;
|
||||
jclass activity_cls = (*env)->GetObjectClass(env, activity_obj);
|
||||
|
||||
jmethodID m_getWindow = (*env)->GetMethodID(env, activity_cls,
|
||||
"getWindow", "()Landroid/view/Window;");
|
||||
if (m_getWindow == 0) goto done;
|
||||
jobject window = (*env)->CallObjectMethod(env, activity_obj, m_getWindow);
|
||||
if (window == 0) goto done;
|
||||
|
||||
jclass window_cls = (*env)->GetObjectClass(env, window);
|
||||
jmethodID m_getDecorView = (*env)->GetMethodID(env, window_cls,
|
||||
"getDecorView", "()Landroid/view/View;");
|
||||
if (m_getDecorView == 0) goto done;
|
||||
jobject decor = (*env)->CallObjectMethod(env, window, m_getDecorView);
|
||||
if (decor == 0) goto done;
|
||||
|
||||
jclass view_cls = (*env)->GetObjectClass(env, decor);
|
||||
jmethodID m_getRootInsets = (*env)->GetMethodID(env, view_cls,
|
||||
"getRootWindowInsets", "()Landroid/view/WindowInsets;");
|
||||
if (m_getRootInsets == 0) goto done;
|
||||
jobject insets = (*env)->CallObjectMethod(env, decor, m_getRootInsets);
|
||||
if (insets == 0) goto done;
|
||||
|
||||
jclass insets_cls = (*env)->GetObjectClass(env, insets);
|
||||
jmethodID m_top = (*env)->GetMethodID(env, insets_cls,
|
||||
"getSystemWindowInsetTop", "()I");
|
||||
jmethodID m_left = (*env)->GetMethodID(env, insets_cls,
|
||||
"getSystemWindowInsetLeft", "()I");
|
||||
jmethodID m_bottom = (*env)->GetMethodID(env, insets_cls,
|
||||
"getSystemWindowInsetBottom", "()I");
|
||||
jmethodID m_right = (*env)->GetMethodID(env, insets_cls,
|
||||
"getSystemWindowInsetRight", "()I");
|
||||
if (m_top) *out_top = (*env)->CallIntMethod(env, insets, m_top);
|
||||
if (m_left) *out_left = (*env)->CallIntMethod(env, insets, m_left);
|
||||
if (m_bottom) *out_bottom = (*env)->CallIntMethod(env, insets, m_bottom);
|
||||
if (m_right) *out_right = (*env)->CallIntMethod(env, insets, m_right);
|
||||
|
||||
done:
|
||||
if (!already_attached) (*vm)->DetachCurrentThread(vm);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user