summaryrefslogtreecommitdiffstats
path: root/media/libcubeb/src/cubeb-jni.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libcubeb/src/cubeb-jni.cpp')
-rw-r--r--media/libcubeb/src/cubeb-jni.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/media/libcubeb/src/cubeb-jni.cpp b/media/libcubeb/src/cubeb-jni.cpp
new file mode 100644
index 0000000000..8e7345b8aa
--- /dev/null
+++ b/media/libcubeb/src/cubeb-jni.cpp
@@ -0,0 +1,82 @@
+/* clang-format off */
+#include "jni.h"
+#include <assert.h>
+#include "cubeb-jni-instances.h"
+/* clang-format on */
+
+#define AUDIO_STREAM_TYPE_MUSIC 3
+
+struct cubeb_jni {
+ jobject s_audio_manager_obj = nullptr;
+ jclass s_audio_manager_class = nullptr;
+ jmethodID s_get_output_latency_id = nullptr;
+};
+
+extern "C" cubeb_jni *
+cubeb_jni_init()
+{
+ jobject ctx_obj = cubeb_jni_get_context_instance();
+ JNIEnv * jni_env = cubeb_get_jni_env_for_thread();
+ if (!jni_env || !ctx_obj) {
+ return nullptr;
+ }
+
+ cubeb_jni * cubeb_jni_ptr = new cubeb_jni;
+ assert(cubeb_jni_ptr);
+
+ // Find the audio manager object and make it global to call it from another
+ // method
+ jclass context_class = jni_env->FindClass("android/content/Context");
+ jfieldID audio_service_field = jni_env->GetStaticFieldID(
+ context_class, "AUDIO_SERVICE", "Ljava/lang/String;");
+ jstring jstr = (jstring)jni_env->GetStaticObjectField(context_class,
+ audio_service_field);
+ jmethodID get_system_service_id =
+ jni_env->GetMethodID(context_class, "getSystemService",
+ "(Ljava/lang/String;)Ljava/lang/Object;");
+ jobject audio_manager_obj =
+ jni_env->CallObjectMethod(ctx_obj, get_system_service_id, jstr);
+ cubeb_jni_ptr->s_audio_manager_obj =
+ reinterpret_cast<jobject>(jni_env->NewGlobalRef(audio_manager_obj));
+
+ // Make the audio manager class a global reference in order to preserve method
+ // id
+ jclass audio_manager_class = jni_env->FindClass("android/media/AudioManager");
+ cubeb_jni_ptr->s_audio_manager_class =
+ reinterpret_cast<jclass>(jni_env->NewGlobalRef(audio_manager_class));
+ cubeb_jni_ptr->s_get_output_latency_id =
+ jni_env->GetMethodID(audio_manager_class, "getOutputLatency", "(I)I");
+
+ jni_env->DeleteLocalRef(ctx_obj);
+ jni_env->DeleteLocalRef(context_class);
+ jni_env->DeleteLocalRef(jstr);
+ jni_env->DeleteLocalRef(audio_manager_obj);
+ jni_env->DeleteLocalRef(audio_manager_class);
+
+ return cubeb_jni_ptr;
+}
+
+extern "C" int
+cubeb_get_output_latency_from_jni(cubeb_jni * cubeb_jni_ptr)
+{
+ assert(cubeb_jni_ptr);
+ JNIEnv * jni_env = cubeb_get_jni_env_for_thread();
+ return jni_env->CallIntMethod(
+ cubeb_jni_ptr->s_audio_manager_obj,
+ cubeb_jni_ptr->s_get_output_latency_id,
+ AUDIO_STREAM_TYPE_MUSIC); // param: AudioManager.STREAM_MUSIC
+}
+
+extern "C" void
+cubeb_jni_destroy(cubeb_jni * cubeb_jni_ptr)
+{
+ assert(cubeb_jni_ptr);
+
+ JNIEnv * jni_env = cubeb_get_jni_env_for_thread();
+ assert(jni_env);
+
+ jni_env->DeleteGlobalRef(cubeb_jni_ptr->s_audio_manager_obj);
+ jni_env->DeleteGlobalRef(cubeb_jni_ptr->s_audio_manager_class);
+
+ delete cubeb_jni_ptr;
+}