Fixed build failure if PJ_JNI_HAS_JNI_ONLOAD is disabled (#3496)

This commit is contained in:
sauwming 2023-04-13 11:14:48 +08:00 committed by GitHub
parent 79b4a3d83d
commit f5fab2619e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 83 deletions

View File

@ -1158,6 +1158,19 @@
#endif
/* Specify if JNI_OnLoad() will be defined in the library. If enabled,
* PJSIP will set the Java Virtual Machine (JVM) inside JNI_OnLoad().
*
* Since there can only be one JNI_OnLoad() in a library loaded from Java,
* you can disable this if the implementation is already defined somewhere
* else. Then you can set the JVM using the API pj_jni_set_jvm() instead.
*
* Default: enabled for Android
*/
#ifndef PJ_JNI_HAS_JNI_ONLOAD
# define PJ_JNI_HAS_JNI_ONLOAD PJ_ANDROID
#endif
/** @} */

View File

@ -381,6 +381,49 @@ PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
# define pj_thread_get_stack_info(thread,f,l) (*(f)="",*(l)=0)
#endif /* PJ_OS_HAS_CHECK_STACK */
/**
* @}
*/
/* **************************************************************************/
/**
* @defgroup PJ_JNI Java Native Interface specific
* @ingroup PJ_OS
* @{
* Functionalities specific to JNI.
* Currently only implemented on Android OS, but may be extended to other
* platforms in the future.
*
*/
/**
* Set the Java Virtual Machine environment variable.
* Note that applications typically do not need to call this function unless
* PJ_JNI_HAS_JNI_ONLOAD is disabled.
*
* @param jvm The Java Virtual Machine environment.
*/
PJ_DECL(void) pj_jni_set_jvm(void *jvm);
/**
* Attach the current thread to a Java Virtual Machine.
*
* @param jni_env Output parameter to store the JNI interface pointer.
*
* @return PJ_TRUE if the attachment is successful,
* PJ_FALSE if otherwise.
*/
PJ_DECL(pj_bool_t) pj_jni_attach_jvm(void **jni_env);
/**
* Detach the current thread from a Java Virtual Machine.
*
* @param attached Specify whether the current thread is attached
* to a JVM.
*/
PJ_DECL(void) pj_jni_detach_jvm(pj_bool_t attached);
/**
* @}
*/

View File

@ -19,33 +19,11 @@
*/
#include <pj/guid.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/string.h>
#include <jni.h>
extern JavaVM *pj_jni_jvm;
static pj_bool_t attach_jvm(JNIEnv **jni_env)
{
if ((*pj_jni_jvm)->GetEnv(pj_jni_jvm, (void **)jni_env,
JNI_VERSION_1_4) < 0)
{
if ((*pj_jni_jvm)->AttachCurrentThread(pj_jni_jvm, jni_env, NULL) < 0)
{
jni_env = NULL;
return PJ_FALSE;
}
return PJ_TRUE;
}
return PJ_FALSE;
}
#define detach_jvm(attached) \
if (attached) \
(*pj_jni_jvm)->DetachCurrentThread(pj_jni_jvm);
PJ_DEF_DATA(const unsigned) PJ_GUID_STRING_LENGTH=36;
PJ_DEF(unsigned) pj_GUID_STRING_LENGTH()
@ -64,7 +42,7 @@ PJ_DEF(pj_str_t*) pj_generate_unique_string(pj_str_t *str)
const char *native_string;
pj_str_t native_str;
pj_bool_t attached = attach_jvm(&jni_env);
pj_bool_t attached = pj_jni_attach_jvm((void **)&jni_env);
if (!jni_env)
goto on_error;
@ -108,12 +86,12 @@ PJ_DEF(pj_str_t*) pj_generate_unique_string(pj_str_t *str)
(*jni_env)->DeleteLocalRef(jni_env, javaUuid);
(*jni_env)->DeleteLocalRef(jni_env, uuid_class);
(*jni_env)->DeleteLocalRef(jni_env, uuid_string);
detach_jvm(attached);
pj_jni_detach_jvm(attached);
return str;
on_error:
PJ_LOG(2, ("guid_android.c", ("Error generating UUID")));
detach_jvm(attached);
pj_jni_detach_jvm(attached);
return NULL;
}

View File

@ -56,16 +56,14 @@
#define SIGNATURE1 0xDEAFBEEF
#define SIGNATURE2 0xDEADC0DE
#ifndef PJ_JNI_HAS_JNI_ONLOAD
# define PJ_JNI_HAS_JNI_ONLOAD PJ_ANDROID
#endif
#if defined(PJ_JNI_HAS_JNI_ONLOAD) && PJ_JNI_HAS_JNI_ONLOAD != 0
#if defined(PJ_ANDROID) && PJ_ANDROID != 0
#include <jni.h>
JavaVM *pj_jni_jvm = NULL;
#if defined(PJ_JNI_HAS_JNI_ONLOAD) && PJ_JNI_HAS_JNI_ONLOAD != 0
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
pj_jni_jvm = vm;
@ -73,8 +71,9 @@ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
return JNI_VERSION_1_4;
}
#endif
#endif /* PJ_JNI_HAS_JNI_ONLOAD */
#endif /* PJ_ANDROID */
struct pj_thread_t
{
@ -315,18 +314,26 @@ PJ_DEF(pj_bool_t) pj_thread_is_registered(void)
* A cool solution would be to port (if possible) the code from the
* android os regarding set_sched groups.
*/
#if PJ_ANDROID
#if defined(PJ_ANDROID) && PJ_ANDROID != 0
#include <jni.h>
#include <sys/resource.h>
#include <sys/system_properties.h>
PJ_DEF(pj_bool_t) pj_jni_attach_jvm(JNIEnv **jni_env)
/* If you disable PJ_JNI_HAS_JNI_ONLOAD, set the JVM using this function. */
PJ_DEF(void) pj_jni_set_jvm(void *jvm)
{
if ((*pj_jni_jvm)->GetEnv(pj_jni_jvm, (void **)jni_env,
JNI_VERSION_1_4) < 0)
{
if ((*pj_jni_jvm)->AttachCurrentThread(pj_jni_jvm, jni_env, NULL) < 0)
pj_jni_jvm = (JavaVM *)jvm;
}
PJ_DEF(pj_bool_t) pj_jni_attach_jvm(void **jni_env)
{
if (!pj_jni_jvm)
return PJ_FALSE;
if ((*pj_jni_jvm)->GetEnv(pj_jni_jvm, jni_env, JNI_VERSION_1_4) < 0) {
if ((*pj_jni_jvm)->AttachCurrentThread(pj_jni_jvm,
(JNIEnv **)jni_env, NULL) < 0)
{
jni_env = NULL;
return PJ_FALSE;
@ -337,8 +344,10 @@ PJ_DEF(pj_bool_t) pj_jni_attach_jvm(JNIEnv **jni_env)
return PJ_FALSE;
}
PJ_DEF(void) pj_jni_dettach_jvm(pj_bool_t attached)
PJ_DEF(void) pj_jni_detach_jvm(pj_bool_t attached)
{
if (!pj_jni_jvm) return;
if (attached)
(*pj_jni_jvm)->DetachCurrentThread(pj_jni_jvm);
}
@ -351,9 +360,9 @@ static pj_status_t set_android_thread_priority(int priority)
jthrowable exc;
pj_status_t result = PJ_SUCCESS;
JNIEnv *jni_env = 0;
pj_bool_t attached = pj_jni_attach_jvm(&jni_env);
pj_bool_t attached = pj_jni_attach_jvm((void **)&jni_env);
PJ_ASSERT_RETURN(jni_env, PJ_FALSE);
if (!jni_env) return PJ_EINVALIDOP;
/* Get pointer to the java class */
process_class = (jclass)(*jni_env)->NewGlobalRef(jni_env,
@ -390,7 +399,7 @@ static pj_status_t set_android_thread_priority(int priority)
}
on_return:
pj_jni_dettach_jvm(attached);
pj_jni_detach_jvm(attached);
return result;
}
@ -426,9 +435,11 @@ PJ_DEF(pj_status_t) pj_thread_set_prio(pj_thread_t *thread, int prio)
{
#if PJ_HAS_THREADS
# if PJ_ANDROID
#if defined(PJ_ANDROID) && PJ_ANDROID != 0
PJ_ASSERT_RETURN(thread==NULL || thread==pj_thread_this(), PJ_EINVAL);
return set_android_thread_priority(prio);
# else
struct sched_param param;

View File

@ -140,10 +140,8 @@ static pjmedia_aud_stream_op android_strm_op =
&strm_destroy
};
PJ_DECL(pj_bool_t) pj_jni_attach_jvm(JNIEnv **jni_env);
PJ_DECL(void) pj_jni_dettach_jvm(pj_bool_t attached);
#define attach_jvm(jni_env) pj_jni_attach_jvm(jni_env)
#define detach_jvm(attached) pj_jni_dettach_jvm(attached)
#define attach_jvm(jni_env) pj_jni_attach_jvm((void **)jni_env)
#define detach_jvm(attached) pj_jni_detach_jvm(attached)
#define THREAD_PRIORITY_AUDIO -16
#define THREAD_PRIORITY_URGENT_AUDIO -19

View File

@ -199,12 +199,6 @@ static struct jni_objs_t
} jobjs;
/* Declare JNI JVM helper from PJLIB OS */
extern "C" {
pj_bool_t pj_jni_attach_jvm(JNIEnv **jni_env);
void pj_jni_dettach_jvm(pj_bool_t attached);
}
#define GET_CLASS(class_path, class_name, cls) \
cls = jni_env->FindClass(class_path); \
if (cls == NULL || jni_env->ExceptionCheck()) { \
@ -258,7 +252,7 @@ static pj_status_t jni_init_ids()
{
JNIEnv *jni_env;
pj_status_t status = PJ_SUCCESS;
pj_bool_t with_attach = pj_jni_attach_jvm(&jni_env);
pj_bool_t with_attach = pj_jni_attach_jvm((void **)&jni_env);
/* PjAudioDevInfo class info */
GET_CLASS(PJ_AUDDEV_INFO_CLASS_PATH, "PjAudioDevInfo", jobjs.dev_info.cls);
@ -292,7 +286,7 @@ static pj_status_t jni_init_ids()
jobjs.activity_thread.m_get_app);
on_return:
pj_jni_dettach_jvm(with_attach);
pj_jni_detach_jvm(with_attach);
return status;
}
@ -304,7 +298,7 @@ on_return:
static void jni_deinit_ids()
{
JNIEnv *jni_env;
pj_bool_t with_attach = pj_jni_attach_jvm(&jni_env);
pj_bool_t with_attach = pj_jni_attach_jvm((void **)&jni_env);
if (jobjs.dev_info.cls) {
jni_env->DeleteGlobalRef(jobjs.dev_info.cls);
@ -316,7 +310,7 @@ static void jni_deinit_ids()
jobjs.activity_thread.cls = NULL;
}
pj_jni_dettach_jvm(with_attach);
pj_jni_detach_jvm(with_attach);
}
static jobject get_global_context(JNIEnv *jni_env)
@ -364,7 +358,7 @@ static pj_status_t oboe_refresh(pjmedia_aud_dev_factory *ff)
f->dev_count = 0;
pj_pool_reset(f->dev_pool);
with_attach = pj_jni_attach_jvm(&jni_env);
with_attach = pj_jni_attach_jvm((void **)&jni_env);
jobject context = get_global_context(jni_env);
if (context == NULL) {
@ -445,7 +439,7 @@ on_return:
if (context)
jni_env->DeleteLocalRef(context);
pj_jni_dettach_jvm(with_attach);
pj_jni_detach_jvm(with_attach);
return status;
}

View File

@ -248,30 +248,8 @@ static void JNICALL OnGetFrame(JNIEnv *env, jobject obj,
jlong user_data);
#endif
static pj_bool_t jni_get_env(JNIEnv **jni_env)
{
pj_bool_t with_attach = PJ_FALSE;
if ((*pj_jni_jvm)->GetEnv(pj_jni_jvm, (void **)jni_env,
JNI_VERSION_1_4) < 0)
{
if ((*pj_jni_jvm)->AttachCurrentThread(pj_jni_jvm, jni_env, NULL) < 0)
{
*jni_env = NULL;
} else {
with_attach = PJ_TRUE;
}
}
return with_attach;
}
static void jni_detach_env(pj_bool_t need_detach)
{
if (need_detach)
(*pj_jni_jvm)->DetachCurrentThread(pj_jni_jvm);
}
#define jni_get_env(jni_env) pj_jni_attach_jvm((void **)jni_env)
#define jni_detach_env(attached) pj_jni_detach_jvm(attached)
/* Get Java object IDs (via FindClass, GetMethodID, GetFieldID, etc).