SDL: android: Fixed audio device detection.

https://github.com/libsdl-org/SDL/commit/1c074e8d9785d55fc720c06801a8010cf8a6cc6a

From 1c074e8d9785d55fc720c06801a8010cf8a6cc6a Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Sat, 29 Jul 2023 19:43:24 -0400
Subject: [PATCH] android: Fixed audio device detection.

---
 .../main/java/org/libsdl/app/SDLAudioManager.java    | 10 ++++++++++
 src/audio/android/SDL_androidaudio.c                 |  1 +
 src/core/android/SDL_android.c                       | 12 ++++++++----
 3 files changed, 19 insertions(+), 4 deletions(-)

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 e64a0790d457..8c84b1c29583 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
@@ -309,6 +309,16 @@ private static AudioDeviceInfo getOutputAudioDeviceInfo(int deviceId) {
     public static void registerAudioDeviceCallback() {
         if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
             AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+            // get an initial list now, before hotplug callbacks fire.
+            for (AudioDeviceInfo dev : audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)) {
+                if (dev.getType() == AudioDeviceInfo.TYPE_TELEPHONY) {
+                    continue;  // Device cannot be opened
+                }
+                addAudioDevice(dev.isSink(), dev.getProductName().toString(), dev.getId());
+            }
+            for (AudioDeviceInfo dev : audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)) {
+                addAudioDevice(dev.isSink(), dev.getProductName().toString(), dev.getId());
+            }
             audioManager.registerAudioDeviceCallback(mAudioDeviceCallback, null);
         }
     }
diff --git a/src/audio/android/SDL_androidaudio.c b/src/audio/android/SDL_androidaudio.c
index 7dbb8541af2f..c87f2b3f3252 100644
--- a/src/audio/android/SDL_androidaudio.c
+++ b/src/audio/android/SDL_androidaudio.c
@@ -128,6 +128,7 @@ static void ANDROIDAUDIO_CloseDevice(SDL_AudioDevice *device)
 
 static SDL_bool ANDROIDAUDIO_Init(SDL_AudioDriverImpl *impl)
 {
+    // !!! FIXME: if on Android API < 24, DetectDevices and Deinitialize should be NULL and OnlyHasDefaultOutputDevice and OnlyHasDefaultCaptureDevice should be SDL_TRUE, since audio device enum and hotplug appears to require Android 7.0+.
     impl->ThreadInit = Android_AudioThreadInit;
     impl->DetectDevices = Android_StartAudioHotplug;
     impl->Deinitialize = Android_StopAudioHotplug;
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index e00d99988f60..28a9b047357a 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -1006,10 +1006,14 @@ JNIEXPORT void JNICALL
 SDL_JAVA_AUDIO_INTERFACE(addAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture,
                                          jstring name, jint device_id)
 {
-    SDL_assert(SDL_GetCurrentAudioDriver() != NULL);  // should have been started by Android_StartAudioHotplug inside an audio driver.
-    const char *utf8name = (*env)->GetStringUTFChars(env, name, NULL);
-    SDL_AddAudioDevice(is_capture ? SDL_TRUE : SDL_FALSE, SDL_strdup(utf8name), NULL, (void *)((size_t)device_id));
-    (*env)->ReleaseStringUTFChars(env, name, utf8name);
+    if (SDL_GetCurrentAudioDriver() != NULL) {
+        void *handle = (void *)((size_t)device_id);
+        if (!SDL_FindPhysicalAudioDeviceByHandle(handle)) {
+            const char *utf8name = (*env)->GetStringUTFChars(env, name, NULL);
+            SDL_AddAudioDevice(is_capture ? SDL_TRUE : SDL_FALSE, SDL_strdup(utf8name), NULL, handle);
+            (*env)->ReleaseStringUTFChars(env, name, utf8name);
+        }
+    }
 }
 
 JNIEXPORT void JNICALL