Fixed bug 3930 - Android, set thread priorities and names

SDLActivity thread priority is unchanged, by default -10 (THREAD_PRIORITY_VIDEO).

SDLAudio thread priority was -4 (SDL_SetThreadPriority was ignored) and is now -16 (THREAD_PRIORITY_AUDIO).

SDLThread thread priority was 0 (THREAD_PRIORITY_DEFAULT) and is -4 (THREAD_PRIORITY_DISPLAY).
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 44cee5a..d88cde9 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
@@ -193,6 +193,12 @@
         Log.v(TAG, "onCreate()");
         super.onCreate(savedInstanceState);
 
+        try {
+            Thread.currentThread().setName("SDLActivity");
+        } catch (Exception e) {
+            Log.v(TAG, "modify thread properties failed " + e.toString());
+        }
+
         // Load shared libraries
         String errorMsgBrokenLib = "";
         try {
@@ -1494,7 +1500,14 @@
         String function = SDLActivity.mSingleton.getMainFunction();
         String[] arguments = SDLActivity.mSingleton.getArguments();
 
+        try {
+            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DISPLAY);
+        } catch (Exception e) {
+            Log.v("SDL", "modify thread properties failed " + e.toString());
+        }
+
         Log.v("SDL", "Running main function " + function + " from library " + library);
+
         SDLActivity.nativeRunMain(library, function, arguments);
 
         Log.v("SDL", "Finished main function");
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java
index bed0eb5..0714419 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java
@@ -73,7 +73,7 @@
             sampleSize = 2;
             break;
         }
- 
+
         if (isCapture) {
             switch (desiredChannels) {
             case 1:
@@ -298,7 +298,7 @@
             Log.e(TAG, "Attempted to make audio call with uninitialized audio!");
             return;
         }
-        
+
         for (int i = 0; i < buffer.length; ) {
             int result = mAudioTrack.write(buffer, i, buffer.length - i);
             if (result > 0) {
@@ -364,5 +364,24 @@
         }
     }
 
+    /** This method is called by SDL using JNI. */
+    public static void audioSetThreadPriority(boolean iscapture, int device_id) {
+        try {
+
+            /* Set thread name */
+            if (iscapture) {
+                Thread.currentThread().setName("SDLAudioC" + device_id);
+            } else {
+                Thread.currentThread().setName("SDLAudioP" + device_id);
+            }
+
+            /* Set thread priority */
+            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
+
+        } catch (Exception e) {
+            Log.v(TAG, "modify thread properties failed " + e.toString());
+        }
+    }
+
     public static native int nativeSetupJNI();
 }
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index d8218fe..0343052 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -695,8 +695,16 @@
 
     SDL_assert(!device->iscapture);
 
+#if SDL_AUDIO_DRIVER_ANDROID
+    {
+        /* Set thread priority to THREAD_PRIORITY_AUDIO */
+        extern void Android_JNI_AudioSetThreadPriority(int, int);
+        Android_JNI_AudioSetThreadPriority(device->iscapture, device->id);
+    }
+#else
     /* The audio mixing is always a high priority thread */
     SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL);
+#endif
 
     /* Perform any thread setup */
     device->threadid = SDL_ThreadID();
@@ -792,8 +800,16 @@
 
     SDL_assert(device->iscapture);
 
+#if SDL_AUDIO_DRIVER_ANDROID
+    {
+        /* Set thread priority to THREAD_PRIORITY_AUDIO */
+        extern void Android_JNI_AudioSetThreadPriority(int, int);
+        Android_JNI_AudioSetThreadPriority(device->iscapture, device->id);
+    }
+#else
     /* The audio mixing is always a high priority thread */
     SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
+#endif
 
     /* Perform any thread setup */
     device->threadid = SDL_ThreadID();
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index 0a51f03..0afaa76 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -268,6 +268,7 @@
 static jmethodID midCaptureReadShortBuffer;
 static jmethodID midCaptureReadFloatBuffer;
 static jmethodID midCaptureClose;
+static jmethodID midAudioSetThreadPriority;
 
 /* controller manager */
 static jclass mControllerManagerClass;
@@ -442,9 +443,11 @@
                                 "captureReadFloatBuffer", "([FZ)I");
     midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
                                 "captureClose", "()V");
+    midAudioSetThreadPriority = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
+                                "audioSetThreadPriority", "(ZI)V");
 
     if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose ||
-       !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose) {
+       !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose || !midAudioSetThreadPriority) {
         __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?");
     }
 
@@ -1467,6 +1470,12 @@
     }
 }
 
+void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id)
+{
+    JNIEnv *env = Android_JNI_GetEnv();
+    (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioSetThreadPriority, iscapture, device_id);
+}
+
 /* Test for an exception and call SDL_SetError with its detail if one occurs */
 /* If the parameter silent is truthy then SDL_SetError() will not be called. */
 static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h
index ea35f59..f8830cc 100644
--- a/src/core/android/SDL_android.h
+++ b/src/core/android/SDL_android.h
@@ -55,6 +55,7 @@
 extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen);
 extern void Android_JNI_FlushCapturedAudio(void);
 extern void Android_JNI_CloseAudioDevice(const int iscapture);
+extern void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id);
 
 /* Detecting device type */
 extern SDL_bool Android_IsDeXMode();