SDL: android: register all methods using JNI_OnLoad

From 4676d1d31e7927be8c7e5cfca17f0eff70717acc Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Thu, 22 Dec 2022 02:27:38 +0100
Subject: [PATCH] android: register all methods using JNI_OnLoad

---
 src/core/android/SDL_android.c |  2 +
 src/dynapi/SDL_dynapi.sym      | 56 +---------------------
 src/dynapi/gendynapi.py        | 85 ----------------------------------
 src/hidapi/android/hid.cpp     | 15 +++++-
 src/hidapi/android/hid.h       | 41 ++++++++++++++++
 5 files changed, 58 insertions(+), 141 deletions(-)
 create mode 100644 src/hidapi/android/hid.h

diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index 6ee77947d5b8..02406a7e9545 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -32,6 +32,7 @@
 #include "../../video/android/SDL_androidwindow.h"
 #include "../../joystick/android/SDL_sysjoystick_c.h"
 #include "../../haptic/android/SDL_syshaptic_c.h"
+#include "../../hidapi/android/hid.h"
 
 #include <android/log.h>
 #include <android/configuration.h>
@@ -520,6 +521,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
     register_methods(env, "org/libsdl/app/SDLInputConnection", SDLInputConnection_tab, SDL_arraysize(SDLInputConnection_tab));
     register_methods(env, "org/libsdl/app/SDLAudioManager", SDLAudioManager_tab, SDL_arraysize(SDLAudioManager_tab));
     register_methods(env, "org/libsdl/app/SDLControllerManager", SDLControllerManager_tab, SDL_arraysize(SDLControllerManager_tab));
+    register_methods(env, "org/libsdl/app/HIDDeviceManager", HIDDeviceManager_tab, SDL_arraysize(HIDDeviceManager_tab));
 
     return JNI_VERSION_1_4;
 }
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 5ded7ee6ecfc..061ab91ec5e8 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -1,5 +1,6 @@
 SDL3_0.0.0 {
   global:
+    JNI_OnLoad;
     SDL_OpenURL;
     SDL_LoadObject;
     SDL_LoadFunction;
@@ -860,60 +861,5 @@ SDL3_0.0.0 {
     SDL_GetRenderDriver;
     SDL_RunApp;
     # extra symbols go here (don't modify this line)
-    # Android symbols start here (don't modify this line)
-    JNI_OnLoad;
-    Java_org_libsdl_app_HIDDeviceManager_HIDDeviceConnected;
-    Java_org_libsdl_app_HIDDeviceManager_HIDDeviceDisconnected;
-    Java_org_libsdl_app_HIDDeviceManager_HIDDeviceFeatureReport;
-    Java_org_libsdl_app_HIDDeviceManager_HIDDeviceInputReport;
-    Java_org_libsdl_app_HIDDeviceManager_HIDDeviceOpenPending;
-    Java_org_libsdl_app_HIDDeviceManager_HIDDeviceOpenResult;
-    Java_org_libsdl_app_HIDDeviceManager_HIDDeviceRegisterCallback;
-    Java_org_libsdl_app_HIDDeviceManager_HIDDeviceReleaseCallback;
-    Java_org_libsdl_app_SDLActivity_nativeAddTouch;
-    Java_org_libsdl_app_SDLActivity_nativeFocusChanged;
-    Java_org_libsdl_app_SDLActivity_nativeGetHint;
-    Java_org_libsdl_app_SDLActivity_nativeGetHintBoolean;
-    Java_org_libsdl_app_SDLActivity_nativeGetVersion;
-    Java_org_libsdl_app_SDLActivity_nativeLowMemory;
-    Java_org_libsdl_app_SDLActivity_nativePause;
-    Java_org_libsdl_app_SDLActivity_nativePermissionResult;
-    Java_org_libsdl_app_SDLActivity_nativeQuit;
-    Java_org_libsdl_app_SDLActivity_nativeResume;
-    Java_org_libsdl_app_SDLActivity_nativeRunMain;
-    Java_org_libsdl_app_SDLActivity_nativeSendQuit;
-    Java_org_libsdl_app_SDLActivity_nativeSetScreenResolution;
-    Java_org_libsdl_app_SDLActivity_nativeSetenv;
-    Java_org_libsdl_app_SDLActivity_nativeSetupJNI;
-    Java_org_libsdl_app_SDLActivity_onNativeAccel;
-    Java_org_libsdl_app_SDLActivity_onNativeClipboardChanged;
-    Java_org_libsdl_app_SDLActivity_onNativeDropFile;
-    Java_org_libsdl_app_SDLActivity_onNativeKeyDown;
-    Java_org_libsdl_app_SDLActivity_onNativeKeyUp;
-    Java_org_libsdl_app_SDLActivity_onNativeKeyboardFocusLost;
-    Java_org_libsdl_app_SDLActivity_onNativeLocaleChanged;
-    Java_org_libsdl_app_SDLActivity_onNativeMouse;
-    Java_org_libsdl_app_SDLActivity_onNativeOrientationChanged;
-    Java_org_libsdl_app_SDLActivity_onNativeResize;
-    Java_org_libsdl_app_SDLActivity_onNativeSoftReturnKey;
-    Java_org_libsdl_app_SDLActivity_onNativeSurfaceChanged;
-    Java_org_libsdl_app_SDLActivity_onNativeSurfaceCreated;
-    Java_org_libsdl_app_SDLActivity_onNativeSurfaceDestroyed;
-    Java_org_libsdl_app_SDLActivity_onNativeTouch;
-    Java_org_libsdl_app_SDLAudioManager_addAudioDevice;
-    Java_org_libsdl_app_SDLAudioManager_nativeSetupJNI;
-    Java_org_libsdl_app_SDLAudioManager_removeAudioDevice;
-    Java_org_libsdl_app_SDLControllerManager_nativeAddHaptic;
-    Java_org_libsdl_app_SDLControllerManager_nativeAddJoystick;
-    Java_org_libsdl_app_SDLControllerManager_nativeRemoveHaptic;
-    Java_org_libsdl_app_SDLControllerManager_nativeRemoveJoystick;
-    Java_org_libsdl_app_SDLControllerManager_nativeSetupJNI;
-    Java_org_libsdl_app_SDLControllerManager_onNativeHat;
-    Java_org_libsdl_app_SDLControllerManager_onNativeJoy;
-    Java_org_libsdl_app_SDLControllerManager_onNativePadDown;
-    Java_org_libsdl_app_SDLControllerManager_onNativePadUp;
-    Java_org_libsdl_app_SDLInputConnection_nativeCommitText;
-    Java_org_libsdl_app_SDLInputConnection_nativeGenerateScancodeForUnichar;
-    # Android symbols end here (don't modify this line)
   local: *;
 };
diff --git a/src/dynapi/gendynapi.py b/src/dynapi/gendynapi.py
index b99010897413..b9e4ba1993e4 100755
--- a/src/dynapi/gendynapi.py
+++ b/src/dynapi/gendynapi.py
@@ -43,8 +43,6 @@
 SDL_DYNAPI_PROCS_H = SDL_ROOT / "src/dynapi/SDL_dynapi_procs.h"
 SDL_DYNAPI_OVERRIDES_H = SDL_ROOT / "src/dynapi/SDL_dynapi_overrides.h"
 SDL_DYNAPI_SYM = SDL_ROOT / "src/dynapi/SDL_dynapi.sym"
-SDL_ANDROID_C = SDL_ROOT / "src/core/android/SDL_android.c"
-SDL_ANDROID_HID_CPP = SDL_ROOT / "src/hidapi/android/hid.cpp"
 
 full_API = []
 
@@ -322,9 +320,6 @@ def main():
     # Dump API into a json file
     full_API_json()
 
-    # Add all native Android functions to SDL_dynapi.sym
-    write_android_symbols_to_sym()
-
 # Dump API into a json file
 def full_API_json():
     if args.dump:
@@ -460,86 +455,6 @@ def add_dyn_api(proc):
     f.close()
 
 
-def extract_symbols_sdl_android_c():
-    sdl_android_c_source = SDL_ANDROID_C.read_text()
-
-    prefix_match = re.search(r"#define SDL_JAVA_PREFIX\s+(?P<prefix>\S+)", sdl_android_c_source)
-    prefix = prefix_match["prefix"]
-
-    wrapper_names = []
-    wrappers = set()
-    for m in re.finditer(r"JNIEXPORT[\s]+(?P<ret>[a-z_]+)[\s]+JNICALL[\s]+(?P<wrapper>SDL_JAVA[A-Z_]+)\((?P<name>[a-zA-Z0-9_]+)\)", sdl_android_c_source, flags=re.M):
-        wrappers.add(m["wrapper"])
-        wrapper_names.append({"wrapper": m["wrapper"], "name": m["name"]})
-
-    wrapper2prefix = {}
-    for wrapper in wrappers:
-        s = re.search(r"#define\s+"+wrapper+r"\([a-z]+\)\s+CONCAT1\(SDL_JAVA_PREFIX,\s*(?P<prefix>[a-zA-Z0-9_]+),\s*function\)", sdl_android_c_source)
-        wrapper2prefix[wrapper] = s["prefix"]
-
-    symbols = set()
-    for wrapper_name in wrapper_names:
-        symbols.add("Java_" + prefix + "_" + wrapper2prefix[wrapper_name["wrapper"]] + "_" + wrapper_name["name"])
-
-    symbols.add("JNI_OnLoad")
-    symbols = list(symbols)
-
-    return symbols
-
-
-def extract_symbols_andoid_sdl_hid_cpp():
-    hid_cpp_source = SDL_ANDROID_HID_CPP.read_text()
-
-    prefix_match = re.search(r"#define SDL_JAVA_PREFIX\s+(?P<prefix>\S+)", hid_cpp_source)
-    prefix = prefix_match["prefix"]
-
-    wrapper_names = []
-    wrappers = set()
-    for m in re.finditer(r"JNIEXPORT[\s]+(?P<ret>[a-z_]+)[\s]+JNICALL[\s]+(?P<wrapper>HID_[A-Z_]+)\((?P<name>[a-zA-Z0-9_]+)\)", hid_cpp_source, flags=re.M):
-        wrappers.add(m["wrapper"])
-        wrapper_names.append({"wrapper": m["wrapper"], "name": m["name"]})
-
-    wrapper2prefix = {}
-    for wrapper in wrappers:
-        s = re.search(r"#define\s+"+wrapper+r"\([a-z]+\)\s+CONCAT1\(SDL_JAVA_PREFIX,\s*(?P<prefix>[a-zA-Z0-9_]+),\s*function\)", hid_cpp_source)
-        wrapper2prefix[wrapper] = s["prefix"]
-
-    symbols = set()
-    for wrapper_name in wrapper_names:
-        symbols.add("Java_" + prefix + "_" + wrapper2prefix[wrapper_name["wrapper"]] + "_" + wrapper_name["name"])
-
-    symbols = list(symbols)
-    symbols.sort()
-
-    return symbols
-
-
-def extract_android_symbols():
-    symbols = extract_symbols_sdl_android_c() + extract_symbols_andoid_sdl_hid_cpp()
-    symbols.sort()
-
-    return symbols
-
-
-def write_android_symbols_to_sym():
-    android_symbols = extract_android_symbols()
-    new_input = []
-    ignore_current = False
-    for line in SDL_DYNAPI_SYM.open():
-        if "Android symbols end here" in line:
-            ignore_current = False
-            for android_symbol in android_symbols:
-                new_input.append("    " + android_symbol + ";\n")
-        if ignore_current:
-            continue
-        if "Android symbols start here" in line:
-            ignore_current = True
-        new_input.append(line)
-    with SDL_DYNAPI_SYM.open("w") as f:
-        for line in new_input:
-            f.write(line)
-
-
 if __name__ == '__main__':
 
     parser = argparse.ArgumentParser()
diff --git a/src/hidapi/android/hid.cpp b/src/hidapi/android/hid.cpp
index d43958058ae0..888586b52ae7 100644
--- a/src/hidapi/android/hid.cpp
+++ b/src/hidapi/android/hid.cpp
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 2021 Valve Corporation
+  Copyright (C) 2022 Valve Corporation
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -24,6 +24,7 @@
 //
 //          This layer glues the hidapi API to Android's USB and BLE stack.
 
+#include "hid.h"
 
 // Common to stub version and non-stub version of functions
 #include <jni.h>
@@ -1428,3 +1429,15 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)
 }
 
 #endif /* SDL_HIDAPI_DISABLED */
+
+extern "C"
+JNINativeMethod HIDDeviceManager_tab[8] = {
+        { "HIDDeviceRegisterCallback", "()V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback) },
+        { "HIDDeviceReleaseCallback", "()V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback) },
+        { "HIDDeviceConnected", "(ILjava/lang/String;IILjava/lang/String;ILjava/lang/String;Ljava/lang/String;IIII)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected) },
+        { "HIDDeviceOpenPending", "(I)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending) },
+        { "HIDDeviceOpenResult", "(IZ)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult) },
+        { "HIDDeviceDisconnected", "(I)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected) },
+        { "HIDDeviceInputReport", "(I[B)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport) },
+        { "HIDDeviceFeatureReport", "(I[B)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport) }
+};
diff --git a/src/hidapi/android/hid.h b/src/hidapi/android/hid.h
new file mode 100644
index 000000000000..bf5d058cfe1b
--- /dev/null
+++ b/src/hidapi/android/hid.h
@@ -0,0 +1,41 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 2022 Valve Corporation
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+// Purpose: Exporting table containing HIDDeviceManager native methods
+
+#ifndef SDL_android_hid_h_
+#define SDL_android_hid_h_
+
+#include <jni.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern JNINativeMethod HIDDeviceManager_tab[8];
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */