2 #include "SkImageDecoder.h"
4 #define LOG_TAG "EmojiFactory_jni"
6 #include <ScopedUtfChars.h>
8 #include "EmojiFactory.h"
9 #include <nativehelper/JNIHelp.h>
12 // #include <pthread.h>
16 class EmojiFactoryCaller {
18 EmojiFactoryCaller() {}
19 virtual ~EmojiFactoryCaller();
21 EmojiFactory *TryCallGetImplementation(const char* name);
22 EmojiFactory *TryCallGetAvailableImplementation();
25 EmojiFactory *(*m_get_implementation)(const char*);
26 EmojiFactory *(*m_get_available_implementation)();
29 bool EmojiFactoryCaller::Init() {
30 const char* error_msg;
31 m_handle = dlopen("libemoji.so", RTLD_LAZY | RTLD_LOCAL);
33 if (m_handle == NULL) {
34 error_msg = "Failed to load libemoji.so";
38 m_get_implementation =
39 reinterpret_cast<EmojiFactory *(*)(const char*)>(
40 dlsym(m_handle, "GetImplementation"));
41 if (m_get_implementation == NULL) {
42 error_msg = "Failed to get symbol of GetImplementation";
46 m_get_available_implementation =
47 reinterpret_cast<EmojiFactory *(*)()>(
48 dlsym(m_handle,"GetAvailableImplementation"));
49 if (m_get_available_implementation == NULL) {
50 error_msg = "Failed to get symbol of GetAvailableImplementation";
57 const char* error_str = dlerror();
58 if (error_str == NULL) {
59 error_str = "unknown reason";
62 ALOGE("%s: %s", error_msg, error_str);
63 if (m_handle != NULL) {
70 EmojiFactoryCaller::~EmojiFactoryCaller() {
76 EmojiFactory *EmojiFactoryCaller::TryCallGetImplementation(
78 if (NULL == m_handle) {
81 return m_get_implementation(name);
84 EmojiFactory *EmojiFactoryCaller::TryCallGetAvailableImplementation() {
85 if (NULL == m_handle) {
88 return m_get_available_implementation();
91 static EmojiFactoryCaller* gCaller;
92 static pthread_once_t g_once = PTHREAD_ONCE_INIT;
93 static bool lib_emoji_factory_is_ready;
95 static jclass gBitmap_class;
96 static jmethodID gBitmap_constructorMethodID;
98 static jclass gEmojiFactory_class;
99 static jmethodID gEmojiFactory_constructorMethodID;
101 static void InitializeCaller() {
102 gCaller = new EmojiFactoryCaller();
103 lib_emoji_factory_is_ready = gCaller->Init();
106 static jobject create_java_EmojiFactory(
107 JNIEnv* env, EmojiFactory* factory, jstring name) {
108 jobject obj = env->NewObject(gEmojiFactory_class, gEmojiFactory_constructorMethodID,
109 static_cast<jint>(reinterpret_cast<uintptr_t>(factory)), name);
110 if (env->ExceptionCheck() != 0) {
111 ALOGE("*** Uncaught exception returned from Java call!\n");
112 env->ExceptionDescribe();
117 static jobject android_emoji_EmojiFactory_newInstance(
118 JNIEnv* env, jobject clazz, jstring name) {
122 pthread_once(&g_once, InitializeCaller);
123 if (!lib_emoji_factory_is_ready) {
127 ScopedUtfChars nameUtf(env, name);
129 EmojiFactory *factory = gCaller->TryCallGetImplementation(nameUtf.c_str());
130 // EmojiFactory *factory = EmojiFactory::GetImplementation(str.string());
131 if (NULL == factory) {
135 return create_java_EmojiFactory(env, factory, name);
138 static jobject android_emoji_EmojiFactory_newAvailableInstance(
139 JNIEnv* env, jobject clazz) {
140 pthread_once(&g_once, InitializeCaller);
141 if (!lib_emoji_factory_is_ready) {
145 EmojiFactory *factory = gCaller->TryCallGetAvailableImplementation();
146 // EmojiFactory *factory = EmojiFactory::GetAvailableImplementation();
147 if (NULL == factory) {
151 jstring jname = env->NewStringUTF(factory->Name());
156 return create_java_EmojiFactory(env, factory, jname);
159 static jobject android_emoji_EmojiFactory_getBitmapFromAndroidPua(
160 JNIEnv* env, jobject clazz, jint nativeEmojiFactory, jint pua) {
161 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
164 const char *bytes = factory->GetImageBinaryFromAndroidPua(pua, &size);
169 SkBitmap *bitmap = new SkBitmap;
170 if (!SkImageDecoder::DecodeMemory(bytes, size, bitmap)) {
171 ALOGE("SkImageDecoder::DecodeMemory() failed.");
175 jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
176 static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)), NULL, false, NULL, -1);
177 if (env->ExceptionCheck() != 0) {
178 ALOGE("*** Uncaught exception returned from Java call!\n");
179 env->ExceptionDescribe();
184 static void android_emoji_EmojiFactory_destructor(
185 JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
187 // Must not delete this object!!
188 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
193 static jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis(
194 JNIEnv* env, jobject obj, jint nativeEmojiFactory, jchar sjis) {
195 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
196 return factory->GetAndroidPuaFromVendorSpecificSjis(sjis);
199 static jint android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua(
200 JNIEnv* env, jobject obj, jint nativeEmojiFactory, jint pua) {
201 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
202 return factory->GetVendorSpecificSjisFromAndroidPua(pua);
205 static jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua(
206 JNIEnv* env, jobject obj, jint nativeEmojiFactory, jint vsu) {
207 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
208 return factory->GetAndroidPuaFromVendorSpecificPua(vsu);
211 static jint android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua(
212 JNIEnv* env, jobject obj, jint nativeEmojiFactory, jint pua) {
213 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
214 return factory->GetVendorSpecificPuaFromAndroidPua(pua);
217 static jint android_emoji_EmojiFactory_getMaximumVendorSpecificPua(
218 JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
219 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
220 return factory->GetMaximumVendorSpecificPua();
223 static jint android_emoji_EmojiFactory_getMinimumVendorSpecificPua(
224 JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
225 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
226 return factory->GetMinimumVendorSpecificPua();
229 static jint android_emoji_EmojiFactory_getMaximumAndroidPua(
230 JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
231 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
232 return factory->GetMaximumAndroidPua();
235 static jint android_emoji_EmojiFactory_getMinimumAndroidPua(
236 JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
237 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
238 return factory->GetMinimumAndroidPua();
241 static JNINativeMethod gMethods[] = {
242 { "newInstance", "(Ljava/lang/String;)Landroid/emoji/EmojiFactory;",
243 (void*)android_emoji_EmojiFactory_newInstance},
244 { "newAvailableInstance", "()Landroid/emoji/EmojiFactory;",
245 (void*)android_emoji_EmojiFactory_newAvailableInstance},
246 { "nativeDestructor", "(I)V",
247 (void*)android_emoji_EmojiFactory_destructor},
248 { "nativeGetBitmapFromAndroidPua", "(II)Landroid/graphics/Bitmap;",
249 (void*)android_emoji_EmojiFactory_getBitmapFromAndroidPua},
250 { "nativeGetAndroidPuaFromVendorSpecificSjis", "(IC)I",
251 (void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis},
252 { "nativeGetVendorSpecificSjisFromAndroidPua", "(II)I",
253 (void*)android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua},
254 { "nativeGetAndroidPuaFromVendorSpecificPua", "(II)I",
255 (void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua},
256 { "nativeGetVendorSpecificPuaFromAndroidPua", "(II)I",
257 (void*)android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua},
258 { "nativeGetMaximumVendorSpecificPua", "(I)I",
259 (void*)android_emoji_EmojiFactory_getMaximumVendorSpecificPua},
260 { "nativeGetMinimumVendorSpecificPua", "(I)I",
261 (void*)android_emoji_EmojiFactory_getMinimumVendorSpecificPua},
262 { "nativeGetMaximumAndroidPua", "(I)I",
263 (void*)android_emoji_EmojiFactory_getMaximumAndroidPua},
264 { "nativeGetMinimumAndroidPua", "(I)I",
265 (void*)android_emoji_EmojiFactory_getMinimumAndroidPua}
268 static jclass make_globalref(JNIEnv* env, const char classname[])
270 jclass c = env->FindClass(classname);
272 return (jclass)env->NewGlobalRef(c);
275 static jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz,
276 const char fieldname[], const char type[])
278 jfieldID id = env->GetFieldID(clazz, fieldname, type);
283 int register_android_emoji_EmojiFactory(JNIEnv* env) {
284 gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
285 gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
287 gEmojiFactory_class = make_globalref(env, "android/emoji/EmojiFactory");
288 gEmojiFactory_constructorMethodID = env->GetMethodID(
289 gEmojiFactory_class, "<init>", "(ILjava/lang/String;)V");
290 return jniRegisterNativeMethods(env, "android/emoji/EmojiFactory",
291 gMethods, NELEM(gMethods));
294 } // namespace android