1 /*
2 mediastreamer2 library - modular sound and video processing and streaming
3 Copyright (C) 2010  Belledonne Communications SARL
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 */
19 
20 #include "mediastreamer2/msjava.h"
21 #include "mediastreamer2/mscommon.h"
22 
23 static JavaVM *ms2_vm=NULL;
24 
25 #ifndef _WIN32
26 #include <pthread.h>
27 
28 static pthread_key_t jnienv_key;
29 
30 /*
31  * Do not forget that any log within this routine may cause re-attach of the thread to the jvm because the logs can callback the java application
32  * (see LinphoneCoreFactory.setLogHandler() ).
33 **/
_android_key_cleanup(void * data)34 void _android_key_cleanup(void *data){
35 	JNIEnv *env = (JNIEnv*) data;
36 
37 	if (env != NULL) {
38 		ms_message("Thread end, detaching jvm from current thread");
39 		(*ms2_vm)->DetachCurrentThread(ms2_vm);
40 		pthread_setspecific(jnienv_key,NULL);
41 	}
42 }
43 #endif
44 
ms_set_jvm_from_env(JNIEnv * env)45 void ms_set_jvm_from_env(JNIEnv *env){
46     (*env)->GetJavaVM(env, &ms2_vm);
47 #ifndef _WIN32
48 	pthread_key_create(&jnienv_key,_android_key_cleanup);
49 #endif
50 }
51 
ms_set_jvm(JavaVM * vm)52 void ms_set_jvm(JavaVM *vm){
53 	ms2_vm=vm;
54 #ifndef _WIN32
55 	pthread_key_create(&jnienv_key,_android_key_cleanup);
56 #endif
57 }
58 
ms_get_jvm(void)59 JavaVM *ms_get_jvm(void){
60 	return ms2_vm;
61 }
62 
ms_get_jni_env(void)63 JNIEnv *ms_get_jni_env(void){
64 	JNIEnv *env=NULL;
65 	if (ms2_vm==NULL){
66 		ms_fatal("Calling ms_get_jni_env() while no jvm has been set using ms_set_jvm().");
67 	}else{
68 #ifndef _WIN32
69 		env=(JNIEnv*)pthread_getspecific(jnienv_key);
70 		if (env==NULL){
71 			if ((*ms2_vm)->AttachCurrentThread(ms2_vm,&env,NULL)!=0){
72 				ms_fatal("AttachCurrentThread() failed !");
73 				return NULL;
74 			}
75 			pthread_setspecific(jnienv_key,env);
76 		}
77 #else
78 		ms_fatal("ms_get_jni_env() not implemented on windows.");
79 #endif
80 	}
81 	return env;
82 }
83 
84 #ifdef __ANDROID__
85 
ms_get_android_sdk_version(void)86 int ms_get_android_sdk_version(void) {
87 	static int sdk_version = 0;
88 	if (sdk_version==0){
89 		/* Get Android SDK version. */
90 		JNIEnv *env = ms_get_jni_env();
91 		jclass version_class = (*env)->FindClass(env, "android/os/Build$VERSION");
92 		jfieldID fid = (*env)->GetStaticFieldID(env, version_class, "SDK_INT", "I");
93 		sdk_version = (*env)->GetStaticIntField(env, version_class, fid);
94 		ms_message("SDK version [%i] detected", sdk_version);
95 		(*env)->DeleteLocalRef(env, version_class);
96 	}
97 	return sdk_version;
98 }
99 
Java_org_linphone_mediastream_Log_d(JNIEnv * env,jobject thiz,jstring jmsg)100 JNIEXPORT void JNICALL Java_org_linphone_mediastream_Log_d(JNIEnv* env, jobject thiz, jstring jmsg) {
101 	const char* msg = jmsg ? (*env)->GetStringUTFChars(env, jmsg, NULL) : NULL;
102 	ms_debug("%s", msg);
103 	if (msg) (*env)->ReleaseStringUTFChars(env, jmsg, msg);
104 }
105 
Java_org_linphone_mediastream_Log_i(JNIEnv * env,jobject thiz,jstring jmsg)106 JNIEXPORT void JNICALL Java_org_linphone_mediastream_Log_i(JNIEnv* env, jobject thiz, jstring jmsg) {
107 	const char* msg = jmsg ? (*env)->GetStringUTFChars(env, jmsg, NULL) : NULL;
108 	ms_message("%s", msg);
109 	if (msg) (*env)->ReleaseStringUTFChars(env, jmsg, msg);
110 }
111 
Java_org_linphone_mediastream_Log_w(JNIEnv * env,jobject thiz,jstring jmsg)112 JNIEXPORT void JNICALL Java_org_linphone_mediastream_Log_w(JNIEnv* env, jobject thiz, jstring jmsg) {
113 	const char* msg = jmsg ? (*env)->GetStringUTFChars(env, jmsg, NULL) : NULL;
114 	ms_warning("%s", msg);
115 	if (msg) (*env)->ReleaseStringUTFChars(env, jmsg, msg);
116 }
117 
Java_org_linphone_mediastream_Log_e(JNIEnv * env,jobject thiz,jstring jmsg)118 JNIEXPORT void JNICALL Java_org_linphone_mediastream_Log_e(JNIEnv* env, jobject thiz, jstring jmsg) {
119 	const char* msg = jmsg ? (*env)->GetStringUTFChars(env, jmsg, NULL) : NULL;
120 	ms_error("%s", msg);
121 	if (msg) (*env)->ReleaseStringUTFChars(env, jmsg, msg);
122 }
123 
124 #endif
125