Commit 2351ab40 authored by Thomas Guillem's avatar Thomas Guillem Committed by Jean-Baptiste Kempf

jni: factorize attach/detach thread and get_env

add jni_attach_thread, jni_detach_thread, jni_get_env in libvlcjni.c.

A name should be specified when a thread is attached to Java. Art (on
android-L) was warning us about. jni_attach_thread call AttachCurrentThread
with a JavaVMAttachArgs containing JNI_VERSION and THREAD_NAME.
Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent 35fa44b7
......@@ -42,8 +42,9 @@ typedef struct
jbyteArray buffer; /// Raw audio data to be played
} aout_sys_t;
/** Unique Java VM instance, as defined in libvlcjni.c */
extern JavaVM *myVm;
#define THREAD_NAME "jni_aout"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
int aout_open(void **opaque, char *format, unsigned *rate, unsigned *nb_channels)
{
......@@ -60,7 +61,7 @@ int aout_open(void **opaque, char *format, unsigned *rate, unsigned *nb_channels
*nb_channels, format, *rate);
JNIEnv *p_env;
if ((*myVm)->AttachCurrentThread (myVm, &p_env, NULL) != 0)
if (jni_attach_thread (&p_env, THREAD_NAME) != 0)
{
LOGE("Could not attach the display thread to the JVM !");
goto eattach;
......@@ -141,11 +142,11 @@ int aout_open(void **opaque, char *format, unsigned *rate, unsigned *nb_channels
// Get the play methodId
p_sys->play = (*p_env)->GetMethodID (p_env, cls, "playAudio", "([BI)V");
assert (p_sys->play != NULL);
(*myVm)->DetachCurrentThread (myVm);
jni_detach_thread ();
return 0;
error:
(*myVm)->DetachCurrentThread (myVm);
jni_detach_thread ();
eattach:
*opaque = NULL;
free (p_sys);
......@@ -165,7 +166,7 @@ void aout_play(void *opaque, const void *samples, unsigned count, int64_t pts)
* because it will be killed before aout_close is called.
* aout_close will actually be called in an different thread!
*/
(*myVm)->AttachCurrentThread (myVm, &p_env, NULL);
jni_attach_thread (&p_env, THREAD_NAME);
(*p_env)->SetByteArrayRegion (p_env, p_sys->buffer, 0,
2 /*nb_channels*/ * count * sizeof (uint16_t),
......@@ -186,7 +187,7 @@ void aout_play(void *opaque, const void *samples, unsigned count, int64_t pts)
FRAME_SIZE);
// FIXME: check for errors
(*myVm)->DetachCurrentThread (myVm);
jni_detach_thread ();
}
void aout_pause(void *opaque, int64_t pts)
......@@ -196,7 +197,7 @@ void aout_pause(void *opaque, int64_t pts)
assert(p_sys);
JNIEnv *p_env;
(*myVm)->AttachCurrentThread (myVm, &p_env, NULL);
jni_attach_thread (&p_env, THREAD_NAME);
// Call the pause function.
jclass cls = (*p_env)->GetObjectClass (p_env, p_sys->j_libVlc);
......@@ -213,7 +214,7 @@ void aout_pause(void *opaque, int64_t pts)
(*p_env)->ExceptionClear (p_env);
}
(*myVm)->DetachCurrentThread (myVm);
jni_detach_thread ();
}
void aout_close(void *opaque)
......@@ -224,7 +225,7 @@ void aout_close(void *opaque)
assert(p_sys->buffer);
JNIEnv *p_env;
(*myVm)->AttachCurrentThread (myVm, &p_env, NULL);
jni_attach_thread (&p_env, THREAD_NAME);
// Call the close function.
jclass cls = (*p_env)->GetObjectClass (p_env, p_sys->j_libVlc);
......@@ -242,17 +243,17 @@ void aout_close(void *opaque)
}
(*p_env)->DeleteGlobalRef (p_env, p_sys->buffer);
(*myVm)->DetachCurrentThread (myVm);
jni_detach_thread ();
free (p_sys);
}
int aout_get_native_sample_rate(void)
{
JNIEnv *p_env;
(*myVm)->AttachCurrentThread (myVm, &p_env, NULL);
jni_attach_thread (&p_env, THREAD_NAME);
jclass cls = (*p_env)->FindClass (p_env, "android/media/AudioTrack");
jmethodID method = (*p_env)->GetStaticMethodID (p_env, cls, "getNativeOutputSampleRate", "(I)I");
int sample_rate = (*p_env)->CallStaticIntMethod (p_env, cls, method, 3); // AudioManager.STREAM_MUSIC
(*myVm)->DetachCurrentThread (myVm);
jni_detach_thread ();
return sample_rate;
}
......@@ -36,8 +36,10 @@ static jobject debugBufferInstance = NULL;
// FIXME: use atomics
static bool buffer_logging;
/** Unique Java VM instance, as defined in libvlcjni.c */
extern JavaVM *myVm;
#define THREAD_NAME "libvlcjni-util"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
extern int jni_get_env(JNIEnv **env);
jint getInt(JNIEnv *env, jobject thiz, const char* field) {
jclass clazz = (*env)->GetObjectClass(env, thiz);
......@@ -151,8 +153,8 @@ static void debug_buffer_log(void *data, int level, const char *fmt, va_list ap)
bool isAttached = false;
JNIEnv *env = NULL;
if ((*myVm)->GetEnv(myVm, (void**) &env, JNI_VERSION_1_2) < 0) {
if ((*myVm)->AttachCurrentThread(myVm, &env, NULL) < 0)
if (jni_get_env(&env) < 0) {
if (jni_attach_thread(&env, THREAD_NAME) < 0)
return;
isAttached = true;
}
......@@ -179,7 +181,7 @@ static void debug_buffer_log(void *data, int level, const char *fmt, va_list ap)
free(psz_msg);
if (isAttached)
(*myVm)->DetachCurrentThread(myVm);
jni_detach_thread();
}
void debug_log(void *data, int level, const libvlc_log_t *ctx, const char *fmt, va_list ap)
......
......@@ -54,6 +54,11 @@
#define VLC_JNI_VERSION JNI_VERSION_1_2
#define THREAD_NAME "libvlcjni"
int jni_attach_thread(JNIEnv **env, const char *thread_name);
void jni_detach_thread();
int jni_get_env(JNIEnv **env);
static void add_media_options(libvlc_media_t *p_md, JNIEnv *env, jobjectArray mediaOptions)
{
int stringCount = (*env)->GetArrayLength(env, mediaOptions);
......@@ -123,8 +128,8 @@ static void vlc_event_callback(const libvlc_event_t *ev, void *data)
if (eventHandlerInstance == NULL)
return;
if ((*myVm)->GetEnv(myVm, (void**) &env, VLC_JNI_VERSION) < 0) {
if ((*myVm)->AttachCurrentThread(myVm, &env, NULL) < 0)
if (jni_get_env(&env) < 0) {
if (jni_attach_thread(&env, THREAD_NAME) < 0)
return;
isAttached = true;
}
......@@ -199,7 +204,7 @@ static void vlc_event_callback(const libvlc_event_t *ev, void *data)
end:
(*env)->DeleteLocalRef(env, bundle);
if (isAttached)
(*myVm)->DetachCurrentThread(myVm);
jni_detach_thread();
}
jint JNI_OnLoad(JavaVM *vm, void *reserved)
......@@ -219,6 +224,29 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
pthread_cond_destroy(&vout_android_surf_attached);
}
int jni_attach_thread(JNIEnv **env, const char *thread_name)
{
JavaVMAttachArgs args;
jint result;
args.version = VLC_JNI_VERSION;
args.name = thread_name;
args.group = NULL;
result = (*myVm)->AttachCurrentThread(myVm, env, &args);
return result == JNI_OK ? 0 : -1;
}
void jni_detach_thread()
{
(*myVm)->DetachCurrentThread(myVm);
}
int jni_get_env(JNIEnv **env)
{
return (*myVm)->GetEnv(myVm, (void **)&env, VLC_JNI_VERSION) == JNI_OK ? 0 : -1;
}
// FIXME: use atomics
static bool verbosity;
......
......@@ -25,8 +25,9 @@
static struct sigaction old_actions[NSIG];
static jobject j_libVLC;
/** Unique Java VM instance, as defined in libvlcjni.c */
extern JavaVM *myVm;
#define THREAD_NAME "native_crash_handler"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
// Monitored signals.
static const int monitored_signals[] = {
......@@ -51,14 +52,14 @@ void sigaction_callback(int signal, siginfo_t *info, void *reserved)
{
// Call the Java LibVLC method that handle the crash.
JNIEnv *env;
(*myVm)->AttachCurrentThread(myVm, &env, NULL);
jni_attach_thread(&env, THREAD_NAME);
jclass cls = (*env)->GetObjectClass(env, j_libVLC);
jmethodID methodId = (*env)->GetMethodID(env, cls, "onNativeCrash", "()V");
(*env)->CallVoidMethod(env, j_libVLC, methodId);
(*env)->DeleteLocalRef(env, cls);
(*myVm)->DetachCurrentThread(myVm);
jni_detach_thread();
// Call the old signal handler.
old_actions[signal].sa_handler(signal);
......
......@@ -23,8 +23,9 @@
#include <jni.h>
/** Unique Java VM instance, as defined in libvlcjni.c */
extern JavaVM *myVm;
#define THREAD_NAME "jni_vout"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
pthread_mutex_t vout_android_lock;
pthread_cond_t vout_android_surf_attached;
......@@ -65,14 +66,14 @@ void jni_EventHardwareAccelerationError()
return;
JNIEnv *env;
(*myVm)->AttachCurrentThread(myVm, &env, NULL);
jni_attach_thread(&env, THREAD_NAME);
jclass cls = (*env)->GetObjectClass(env, vout_android_gui);
jmethodID methodId = (*env)->GetMethodID(env, cls, "eventHardwareAccelerationError", "()V");
(*env)->CallVoidMethod(env, vout_android_gui, methodId);
(*env)->DeleteLocalRef(env, cls);
(*myVm)->DetachCurrentThread(myVm);
jni_detach_thread();
}
void jni_SetAndroidSurfaceSizeEnv(JNIEnv *p_env, int width, int height, int visible_width, int visible_height, int sar_num, int sar_den)
......@@ -92,10 +93,10 @@ void jni_SetAndroidSurfaceSize(int width, int height, int visible_width, int vis
{
JNIEnv *p_env;
(*myVm)->AttachCurrentThread (myVm, &p_env, NULL);
jni_attach_thread(&p_env, THREAD_NAME);
jni_SetAndroidSurfaceSizeEnv(p_env, width, height, visible_width, visible_height, sar_num, sar_den);
(*myVm)->DetachCurrentThread (myVm);
jni_detach_thread();
}
bool jni_IsVideoPlayerActivityCreated() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment