From a1e992b110b9adf3305a5ebb5514f0e970f7911e Mon Sep 17 00:00:00 2001
From: Sylvain <[EMAIL REDACTED]>
Date: Tue, 21 Dec 2021 22:07:17 +0100
Subject: [PATCH] Fixed bug #5118 - [Android] PointerIcon leak in Cursor API
---
.../src/main/java/org/libsdl/app/SDLActivity.java | 13 +++++++++++++
src/core/android/SDL_android.c | 9 +++++++++
src/core/android/SDL_android.h | 1 +
src/video/android/SDL_androidmouse.c | 4 ++++
4 files changed, 27 insertions(+)
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 02c64b1bdff..8641ccf8073 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
@@ -1479,6 +1479,19 @@ public static int createCustomCursor(int[] colors, int width, int height, int ho
return mLastCursorID;
}
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static void destroyCustomCursor(int cursorID) {
+ if (Build.VERSION.SDK_INT >= 24) {
+ try {
+ mCursors.remove(cursorID);
+ } catch (Exception e) {
+ }
+ }
+ return;
+ }
+
/**
* This method is called by SDL using JNI.
*/
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index e2384141396..b731f3996b4 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -303,6 +303,7 @@ static jmethodID midClipboardGetText;
static jmethodID midClipboardHasText;
static jmethodID midClipboardSetText;
static jmethodID midCreateCustomCursor;
+static jmethodID midDestroyCustomCursor;
static jmethodID midGetContext;
static jmethodID midGetDisplayDPI;
static jmethodID midGetManifestEnvironmentVariables;
@@ -582,6 +583,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
midClipboardHasText = (*env)->GetStaticMethodID(env, mActivityClass, "clipboardHasText", "()Z");
midClipboardSetText = (*env)->GetStaticMethodID(env, mActivityClass, "clipboardSetText", "(Ljava/lang/String;)V");
midCreateCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "createCustomCursor", "([IIIII)I");
+ midDestroyCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "destroyCustomCursor", "(I)V");
midGetContext = (*env)->GetStaticMethodID(env, mActivityClass, "getContext","()Landroid/content/Context;");
midGetDisplayDPI = (*env)->GetStaticMethodID(env, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;");
midGetManifestEnvironmentVariables = (*env)->GetStaticMethodID(env, mActivityClass, "getManifestEnvironmentVariables", "()Z");
@@ -612,6 +614,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
!midClipboardHasText ||
!midClipboardSetText ||
!midCreateCustomCursor ||
+ !midDestroyCustomCursor ||
!midGetContext ||
!midGetDisplayDPI ||
!midGetManifestEnvironmentVariables ||
@@ -2503,6 +2506,12 @@ int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y)
return custom_cursor;
}
+void Android_JNI_DestroyCustomCursor(int cursorID)
+{
+ JNIEnv *env = Android_JNI_GetEnv();
+ (*env)->CallStaticVoidMethod(env, mActivityClass, midDestroyCustomCursor, cursorID);
+ return;
+}
SDL_bool Android_JNI_SetCustomCursor(int cursorID)
{
diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h
index 5db7458289a..9634fce0503 100644
--- a/src/core/android/SDL_android.h
+++ b/src/core/android/SDL_android.h
@@ -118,6 +118,7 @@ int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *bu
/* Cursor support */
int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y);
+void Android_JNI_DestroyCustomCursor(int cursorID);
SDL_bool Android_JNI_SetCustomCursor(int cursorID);
SDL_bool Android_JNI_SetSystemCursor(int cursorID);
diff --git a/src/video/android/SDL_androidmouse.c b/src/video/android/SDL_androidmouse.c
index bfb29e003b5..96b368c3066 100644
--- a/src/video/android/SDL_androidmouse.c
+++ b/src/video/android/SDL_androidmouse.c
@@ -113,6 +113,10 @@ Android_CreateSystemCursor(SDL_SystemCursor id)
static void
Android_FreeCursor(SDL_Cursor * cursor)
{
+ SDL_AndroidCursorData *data = (SDL_AndroidCursorData*) cursor->driverdata;
+ if (data->custom_cursor != 0) {
+ Android_JNI_DestroyCustomCursor(data->custom_cursor);
+ }
SDL_free(cursor->driverdata);
SDL_free(cursor);
}