FreeRDP
Loading...
Searching...
No Matches
android_jni_callback.c
1
12#include <freerdp/config.h>
13
14#include <stdio.h>
15
16#include "android_jni_callback.h"
17#include "android_freerdp_jni.h"
18
19#include <freerdp/log.h>
20#define TAG CLIENT_TAG("android.callback")
21
22static JavaVM* jVM;
23static jobject jLibFreeRDPObject;
24
25static const char* jLibFreeRDPPath = JAVA_LIBFREERDP_CLASS;
26
27static void jni_load_class(JNIEnv* env, const char* path, jobject* objptr)
28{
29 jclass class;
30 jmethodID method;
31 jobject object;
32 WLog_DBG(TAG, "jni_load_class: %s", path);
33 class = (*env)->FindClass(env, path);
34
35 if (!class)
36 {
37 WLog_ERR(TAG, "jni_load_class: failed to find class %s", path);
38 goto finish;
39 }
40
41 method = (*env)->GetMethodID(env, class, "<init>", "()V");
42
43 if (!method)
44 {
45 WLog_ERR(TAG, "jni_load_class: failed to find class constructor of %s", path);
46 goto finish;
47 }
48
49 object = (*env)->NewObject(env, class, method);
50
51 if (!object)
52 {
53 WLog_ERR(TAG, "jni_load_class: failed create new object of %s", path);
54 goto finish;
55 }
56
57 (*objptr) = (*env)->NewGlobalRef(env, object);
58finish:
59
60 while (0)
61 ;
62}
63
64jint init_callback_environment(JavaVM* vm, JNIEnv* env)
65{
66 jVM = vm;
67 jni_load_class(env, jLibFreeRDPPath, &jLibFreeRDPObject);
68 return JNI_VERSION_1_6;
69}
70
71/* attach current thread to jvm */
72jboolean jni_attach_thread(JNIEnv** env)
73{
74 if ((*jVM)->GetEnv(jVM, (void**)env, JNI_VERSION_1_4) != JNI_OK)
75 {
76 WLog_DBG(TAG, "android_java_callback: attaching current thread");
77 (*jVM)->AttachCurrentThread(jVM, env, NULL);
78
79 if ((*jVM)->GetEnv(jVM, (void**)env, JNI_VERSION_1_4) != JNI_OK)
80 {
81 WLog_ERR(TAG, "android_java_callback: failed to obtain current JNI environment");
82 }
83
84 return JNI_TRUE;
85 }
86
87 return JNI_FALSE;
88}
89
90/* attach current thread to JVM */
91void jni_detach_thread()
92{
93 (*jVM)->DetachCurrentThread(jVM);
94}
95
96/* callback with void result */
97static void java_callback_void(jobject obj, const char* callback, const char* signature,
98 va_list args)
99{
100 jclass jObjClass;
101 jmethodID jCallback;
102 jboolean attached;
103 JNIEnv* env;
104 WLog_DBG(TAG, "java_callback: %s (%s)", callback, signature);
105 attached = jni_attach_thread(&env);
106 jObjClass = (*env)->GetObjectClass(env, obj);
107
108 if (!jObjClass)
109 {
110 WLog_ERR(TAG, "android_java_callback: failed to get class reference");
111 goto finish;
112 }
113
114 jCallback = (*env)->GetStaticMethodID(env, jObjClass, callback, signature);
115
116 if (!jCallback)
117 {
118 WLog_ERR(TAG, "android_java_callback: failed to get method id");
119 goto finish;
120 }
121
122 (*env)->CallStaticVoidMethodV(env, jObjClass, jCallback, args);
123finish:
124
125 if (attached == JNI_TRUE)
126 jni_detach_thread();
127}
128
129/* callback with bool result */
130static jboolean java_callback_bool(jobject obj, const char* callback, const char* signature,
131 va_list args)
132{
133 jclass jObjClass;
134 jmethodID jCallback;
135 jboolean attached;
136 jboolean res = JNI_FALSE;
137 JNIEnv* env;
138 WLog_DBG(TAG, "java_callback: %s (%s)", callback, signature);
139 attached = jni_attach_thread(&env);
140 jObjClass = (*env)->GetObjectClass(env, obj);
141
142 if (!jObjClass)
143 {
144 WLog_ERR(TAG, "android_java_callback: failed to get class reference");
145 goto finish;
146 }
147
148 jCallback = (*env)->GetStaticMethodID(env, jObjClass, callback, signature);
149
150 if (!jCallback)
151 {
152 WLog_ERR(TAG, "android_java_callback: failed to get method id");
153 goto finish;
154 }
155
156 res = (*env)->CallStaticBooleanMethodV(env, jObjClass, jCallback, args);
157finish:
158
159 if (attached == JNI_TRUE)
160 jni_detach_thread();
161
162 return res;
163}
164
165/* callback with int result */
166static jint java_callback_int(jobject obj, const char* callback, const char* signature,
167 va_list args)
168{
169 jclass jObjClass;
170 jmethodID jCallback;
171 jboolean attached;
172 jint res = -1;
173 JNIEnv* env;
174 WLog_DBG(TAG, "java_callback: %s (%s)", callback, signature);
175 attached = jni_attach_thread(&env);
176 jObjClass = (*env)->GetObjectClass(env, obj);
177
178 if (!jObjClass)
179 {
180 WLog_ERR(TAG, "android_java_callback: failed to get class reference");
181 goto finish;
182 }
183
184 jCallback = (*env)->GetStaticMethodID(env, jObjClass, callback, signature);
185
186 if (!jCallback)
187 {
188 WLog_ERR(TAG, "android_java_callback: failed to get method id");
189 goto finish;
190 }
191
192 res = (*env)->CallStaticIntMethodV(env, jObjClass, jCallback, args);
193finish:
194
195 if (attached == JNI_TRUE)
196 jni_detach_thread();
197
198 return res;
199}
200
201/* callback to freerdp class */
202void freerdp_callback(const char* callback, const char* signature, ...)
203{
204 va_list vl;
205 va_start(vl, signature);
206 java_callback_void(jLibFreeRDPObject, callback, signature, vl);
207 va_end(vl);
208}
209
210jboolean freerdp_callback_bool_result(const char* callback, const char* signature, ...)
211{
212 va_list vl;
213 va_start(vl, signature);
214 jboolean res = java_callback_bool(jLibFreeRDPObject, callback, signature, vl);
215 va_end(vl);
216 return res;
217}
218
219jint freerdp_callback_int_result(const char* callback, const char* signature, ...)
220{
221 va_list vl;
222 va_start(vl, signature);
223 jint res = java_callback_int(jLibFreeRDPObject, callback, signature, vl);
224 va_end(vl);
225 return res;
226}