From 5291e5cb7649e0128b9d7274090e8b0b6cd6a745 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 3 Oct 2022 17:36:17 -0700
Subject: [PATCH] Added version checking to SDLActivity.java
Make sure the SDL java and C code match when updating SDL in a game.
Right now we're assuming that we only have to make sure release versions match. We can extend the version string with an interface version if we need more fine grained sanity checking.
Fixes https://github.com/libsdl-org/SDL/issues/1540
---
.../main/java/org/libsdl/app/SDLActivity.java | 18 ++++++++++++++++--
build-scripts/test-versioning.sh | 11 +++++++++++
build-scripts/update-version.sh | 4 ++++
src/core/android/SDL_android.c | 15 +++++++++++++++
4 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
index f65e93c06e43..6cf7611cc479 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -59,6 +59,9 @@
*/
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
private static final String TAG = "SDL";
+ private static final int SDL_MAJOR_VERSION = 2;
+ private static final int SDL_MINOR_VERSION = 25;
+ private static final int SDL_MICRO_VERSION = 0;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
@@ -342,8 +345,18 @@ protected void onCreate(Bundle savedInstanceState) {
errorMsgBrokenLib = e.getMessage();
}
- if (mBrokenLibraries)
- {
+ if (!mBrokenLibraries) {
+ String expected_version = String.valueOf(SDL_MAJOR_VERSION) + "." +
+ String.valueOf(SDL_MINOR_VERSION) + "." +
+ String.valueOf(SDL_MICRO_VERSION);
+ String version = nativeGetVersion();
+ if (!version.equals(expected_version)) {
+ mBrokenLibraries = true;
+ errorMsgBrokenLib = "SDL C/Java version mismatch (expected " + expected_version + ", got " + version + ")";
+ }
+ }
+
+ if (mBrokenLibraries) {
mSingleton = this;
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
dlgAlert.setMessage("An error occurred while trying to start the application. Please try again and/or reinstall."
@@ -884,6 +897,7 @@ boolean sendCommand(int command, Object data) {
}
// C functions we call
+ public static native String nativeGetVersion();
public static native int nativeSetupJNI();
public static native int nativeRunMain(String library, String function, Object arguments);
public static native void nativeLowMemory();
diff --git a/build-scripts/test-versioning.sh b/build-scripts/test-versioning.sh
index c1b6c3084b4b..7d71c9e1511d 100755
--- a/build-scripts/test-versioning.sh
+++ b/build-scripts/test-versioning.sh
@@ -56,6 +56,17 @@ else
not_ok "CMakeLists.txt $version disagrees with SDL_version.h $ref_version"
fi
+major=$(sed -ne 's/.*SDL_MAJOR_VERSION = \([0-9]*\);/\1/p' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java)
+minor=$(sed -ne 's/.*SDL_MINOR_VERSION = \([0-9]*\);/\1/p' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java)
+micro=$(sed -ne 's/.*SDL_MICRO_VERSION = \([0-9]*\);/\1/p' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java)
+version="${major}.${minor}.${micro}"
+
+if [ "$ref_version" = "$version" ]; then
+ ok "SDLActivity.java $version"
+else
+ not_ok "android-project/app/src/main/java/org/libsdl/app/SDLActivity.java $version disagrees with SDL_version.h $ref_version"
+fi
+
major=$(sed -ne 's/^MAJOR_VERSION *= *//p' Makefile.os2)
minor=$(sed -ne 's/^MINOR_VERSION *= *//p' Makefile.os2)
micro=$(sed -ne 's/^MICRO_VERSION *= *//p' Makefile.os2)
diff --git a/build-scripts/update-version.sh b/build-scripts/update-version.sh
index fc247fd9d33e..82174becf5fd 100755
--- a/build-scripts/update-version.sh
+++ b/build-scripts/update-version.sh
@@ -58,6 +58,10 @@ perl -w -pi -e 's/\A(set\(SDL_MAJOR_VERSION\s+)\d+/${1}'$MAJOR'/;' CMakeLists.tx
perl -w -pi -e 's/\A(set\(SDL_MINOR_VERSION\s+)\d+/${1}'$MINOR'/;' CMakeLists.txt
perl -w -pi -e 's/\A(set\(SDL_MICRO_VERSION\s+)\d+/${1}'$PATCH'/;' CMakeLists.txt
+perl -w -pi -e 's/\A(.* SDL_MAJOR_VERSION = )\d+/${1}'$MAJOR'/;' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+perl -w -pi -e 's/\A(.* SDL_MINOR_VERSION = )\d+/${1}'$MINOR'/;' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+perl -w -pi -e 's/\A(.* SDL_MICRO_VERSION = )\d+/${1}'$PATCH'/;' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+
perl -w -pi -e 's/\A(MAJOR_VERSION\s*=\s*)\d+/${1}'$MAJOR'/;' Makefile.os2
perl -w -pi -e 's/\A(MINOR_VERSION\s*=\s*)\d+/${1}'$MINOR'/;' Makefile.os2
perl -w -pi -e 's/\A(MICRO_VERSION\s*=\s*)\d+/${1}'$PATCH'/;' Makefile.os2
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index b0884eda8682..83e631199765 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -25,6 +25,7 @@
#include "SDL_hints.h"
#include "SDL_main.h"
#include "SDL_timer.h"
+#include "SDL_version.h"
#ifdef __ANDROID__
@@ -63,6 +64,9 @@
#define ENCODING_PCM_FLOAT 4
/* Java class SDLActivity */
+JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetVersion)(
+ JNIEnv *env, jclass cls);
+
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(
JNIEnv *env, jclass cls);
@@ -167,6 +171,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(
jint requestCode, jboolean result);
static JNINativeMethod SDLActivity_tab[] = {
+ { "nativeGetVersion", "()Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetVersion) },
{ "nativeSetupJNI", "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) },
{ "nativeRunMain", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I", SDL_JAVA_INTERFACE(nativeRunMain) },
{ "onNativeDropFile", "(Ljava/lang/String;)V", SDL_JAVA_INTERFACE(onNativeDropFile) },
@@ -536,6 +541,16 @@ void checkJNIReady(void)
SDL_SetMainReady();
}
+/* Get SDL version -- called before SDL_main() to verify JNI bindings */
+JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetVersion)(JNIEnv *env, jclass cls)
+{
+ char version[128];
+
+ SDL_snprintf(version, sizeof(version), "%d.%d.%d", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL);
+
+ return (*env)->NewStringUTF(env, version);
+}
+
/* Activity initialization -- called before SDL_main() to initialize JNI bindings */
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)
{