libhydra: Remove empty unused library
[strongswan.git] / src / frontends / android / app / src / main / jni / libandroidbridge / android_jni.c
1 /*
2 * Copyright (C) 2012-2015 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include <dlfcn.h>
19
20 #include "android_jni.h"
21
22 #include <library.h>
23 #include <threading/thread_value.h>
24
25 /**
26 * JVM
27 */
28 static JavaVM *android_jvm;
29
30 static struct {
31 char name[32];
32 void *handle;
33 } libs[] = {
34 { "libstrongswan.so", NULL },
35 #ifdef USE_BYOD
36 { "libtncif.so", NULL },
37 { "libtnccs.so", NULL },
38 { "libimcv.so", NULL },
39 #endif
40 { "libcharon.so", NULL },
41 { "libipsec.so", NULL },
42 };
43
44 jclass *android_charonvpnservice_class;
45 jclass *android_charonvpnservice_builder_class;
46 android_sdk_version_t android_sdk_version;
47
48 /**
49 * Thread-local variable. Only used because of the destructor
50 */
51 static thread_value_t *androidjni_threadlocal;
52
53 /**
54 * Thread-local destructor to ensure that a native thread is detached
55 * from the JVM even if androidjni_detach_thread() is not called.
56 */
57 static void attached_thread_cleanup(void *arg)
58 {
59 (*android_jvm)->DetachCurrentThread(android_jvm);
60 }
61
62 /*
63 * Described in header
64 */
65 void androidjni_attach_thread(JNIEnv **env)
66 {
67 if ((*android_jvm)->GetEnv(android_jvm, (void**)env,
68 JNI_VERSION_1_6) == JNI_OK)
69 { /* already attached or even a Java thread */
70 return;
71 }
72 (*android_jvm)->AttachCurrentThread(android_jvm, env, NULL);
73 /* use a thread-local value with a destructor that automatically detaches
74 * the thread from the JVM before it terminates, if not done manually */
75 androidjni_threadlocal->set(androidjni_threadlocal, (void*)*env);
76 }
77
78 /*
79 * Described in header
80 */
81 void androidjni_detach_thread()
82 {
83 if (androidjni_threadlocal->get(androidjni_threadlocal))
84 { /* only do this if we actually attached this thread */
85 androidjni_threadlocal->set(androidjni_threadlocal, NULL);
86 (*android_jvm)->DetachCurrentThread(android_jvm);
87 }
88 }
89
90 /**
91 * Called when this library is loaded by the JVM
92 */
93 jint JNI_OnLoad(JavaVM *vm, void *reserved)
94 {
95 JNIEnv *env;
96 jclass jversion;
97 jfieldID jsdk_int;
98 int i;
99
100 android_jvm = vm;
101
102 if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK)
103 {
104 return -1;
105 }
106
107 for (i = 0; i < countof(libs); i++)
108 {
109 libs[i].handle = dlopen(libs[i].name, RTLD_GLOBAL);
110 if (!libs[i].handle)
111 {
112 return -1;
113 }
114 }
115
116 androidjni_threadlocal = thread_value_create(attached_thread_cleanup);
117
118 android_charonvpnservice_class =
119 (*env)->NewGlobalRef(env, (*env)->FindClass(env,
120 JNI_PACKAGE_STRING "/CharonVpnService"));
121 android_charonvpnservice_builder_class =
122 (*env)->NewGlobalRef(env, (*env)->FindClass(env,
123 JNI_PACKAGE_STRING "/CharonVpnService$BuilderAdapter"));
124
125 jversion = (*env)->FindClass(env, "android/os/Build$VERSION");
126 jsdk_int = (*env)->GetStaticFieldID(env, jversion, "SDK_INT", "I");
127 android_sdk_version = (*env)->GetStaticIntField(env, jversion, jsdk_int);
128
129 return JNI_VERSION_1_6;
130 }
131
132 /**
133 * Called when this library is unloaded by the JVM (which never happens on
134 * Android)
135 */
136 void JNI_OnUnload(JavaVM *vm, void *reserved)
137 {
138 int i;
139
140 androidjni_threadlocal->destroy(androidjni_threadlocal);
141
142 for (i = countof(libs) - 1; i >= 0; i--)
143 {
144 if (libs[i].handle)
145 {
146 dlclose(libs[i].handle);
147 }
148 }
149 }
150