2 #include "SkImageDecoder.h"
4 #define LOG_TAG "EmojiFactory_jni"
6 #include <ScopedUtfChars.h>
8 #include "EmojiFactory.h"
9 #include "GraphicsJNI.h"
10 #include <nativehelper/JNIHelp.h>
13 // #include <pthread.h>
17 class EmojiFactoryCaller {
19 EmojiFactoryCaller() {}
20 virtual ~EmojiFactoryCaller();
22 EmojiFactory *TryCallGetImplementation(const char* name);
23 EmojiFactory *TryCallGetAvailableImplementation();
26 EmojiFactory *(*m_get_implementation)(const char*);
27 EmojiFactory *(*m_get_available_implementation)();
30 bool EmojiFactoryCaller::Init() {
31 const char* error_msg;
32 m_handle = dlopen("libemoji.so", RTLD_LAZY | RTLD_LOCAL);
34 if (m_handle == NULL) {
35 error_msg = "Failed to load libemoji.so";
39 m_get_implementation =
40 reinterpret_cast<EmojiFactory *(*)(const char*)>(
41 dlsym(m_handle, "GetImplementation"));
42 if (m_get_implementation == NULL) {
43 error_msg = "Failed to get symbol of GetImplementation";
47 m_get_available_implementation =
48 reinterpret_cast<EmojiFactory *(*)()>(
49 dlsym(m_handle,"GetAvailableImplementation"));
50 if (m_get_available_implementation == NULL) {
51 error_msg = "Failed to get symbol of GetAvailableImplementation";
58 const char* error_str = dlerror();
59 if (error_str == NULL) {
60 error_str = "unknown reason";
63 ALOGE("%s: %s", error_msg, error_str);
64 if (m_handle != NULL) {
71 EmojiFactoryCaller::~EmojiFactoryCaller() {
77 EmojiFactory *EmojiFactoryCaller::TryCallGetImplementation(
79 if (NULL == m_handle) {
82 return m_get_implementation(name);
85 EmojiFactory *EmojiFactoryCaller::TryCallGetAvailableImplementation() {
86 if (NULL == m_handle) {
89 return m_get_available_implementation();
92 static EmojiFactoryCaller* gCaller;
93 static pthread_once_t g_once = PTHREAD_ONCE_INIT;
94 static bool lib_emoji_factory_is_ready;
96 static jclass gEmojiFactory_class;
97 static jmethodID gEmojiFactory_constructorMethodID;
99 static void InitializeCaller() {
100 gCaller = new EmojiFactoryCaller();
101 lib_emoji_factory_is_ready = gCaller->Init();
104 static jobject create_java_EmojiFactory(
105 JNIEnv* env, EmojiFactory* factory, jstring name) {
106 jobject obj = env->NewObject(gEmojiFactory_class, gEmojiFactory_constructorMethodID,
107 reinterpret_cast<jlong>(factory), name);
108 if (env->ExceptionCheck() != 0) {
109 ALOGE("*** Uncaught exception returned from Java call!\n");
110 env->ExceptionDescribe();
115 static jobject android_emoji_EmojiFactory_newInstance(
116 JNIEnv* env, jobject clazz, jstring name) {
120 pthread_once(&g_once, InitializeCaller);
121 if (!lib_emoji_factory_is_ready) {
125 ScopedUtfChars nameUtf(env, name);
127 EmojiFactory *factory = gCaller->TryCallGetImplementation(nameUtf.c_str());
128 // EmojiFactory *factory = EmojiFactory::GetImplementation(str.string());
129 if (NULL == factory) {
133 return create_java_EmojiFactory(env, factory, name);
136 static jobject android_emoji_EmojiFactory_newAvailableInstance(
137 JNIEnv* env, jobject clazz) {
138 pthread_once(&g_once, InitializeCaller);
139 if (!lib_emoji_factory_is_ready) {
143 EmojiFactory *factory = gCaller->TryCallGetAvailableImplementation();
144 // EmojiFactory *factory = EmojiFactory::GetAvailableImplementation();
145 if (NULL == factory) {
149 jstring jname = env->NewStringUTF(factory->Name());
154 return create_java_EmojiFactory(env, factory, jname);
157 static jobject android_emoji_EmojiFactory_getBitmapFromAndroidPua(
158 JNIEnv* env, jobject clazz, jlong nativeEmojiFactory, jint pua) {
159 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
162 const char *bytes = factory->GetImageBinaryFromAndroidPua(pua, &size);
167 SkBitmap *bitmap = new SkBitmap;
168 if (!SkImageDecoder::DecodeMemory(bytes, size, bitmap)) {
169 ALOGE("SkImageDecoder::DecodeMemory() failed.");
173 return GraphicsJNI::createBitmap(env, bitmap,
174 GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL);
177 static void android_emoji_EmojiFactory_destructor(
178 JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
180 // Must not delete this object!!
181 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
186 static jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis(
187 JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jchar sjis) {
188 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
189 return factory->GetAndroidPuaFromVendorSpecificSjis(sjis);
192 static jint android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua(
193 JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jint pua) {
194 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
195 return factory->GetVendorSpecificSjisFromAndroidPua(pua);
198 static jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua(
199 JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jint vsu) {
200 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
201 return factory->GetAndroidPuaFromVendorSpecificPua(vsu);
204 static jint android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua(
205 JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jint pua) {
206 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
207 return factory->GetVendorSpecificPuaFromAndroidPua(pua);
210 static jint android_emoji_EmojiFactory_getMaximumVendorSpecificPua(
211 JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
212 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
213 return factory->GetMaximumVendorSpecificPua();
216 static jint android_emoji_EmojiFactory_getMinimumVendorSpecificPua(
217 JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
218 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
219 return factory->GetMinimumVendorSpecificPua();
222 static jint android_emoji_EmojiFactory_getMaximumAndroidPua(
223 JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
224 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
225 return factory->GetMaximumAndroidPua();
228 static jint android_emoji_EmojiFactory_getMinimumAndroidPua(
229 JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
230 EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
231 return factory->GetMinimumAndroidPua();
234 static JNINativeMethod gMethods[] = {
235 { "newInstance", "(Ljava/lang/String;)Landroid/emoji/EmojiFactory;",
236 (void*)android_emoji_EmojiFactory_newInstance},
237 { "newAvailableInstance", "()Landroid/emoji/EmojiFactory;",
238 (void*)android_emoji_EmojiFactory_newAvailableInstance},
239 { "nativeDestructor", "(J)V",
240 (void*)android_emoji_EmojiFactory_destructor},
241 { "nativeGetBitmapFromAndroidPua", "(JI)Landroid/graphics/Bitmap;",
242 (void*)android_emoji_EmojiFactory_getBitmapFromAndroidPua},
243 { "nativeGetAndroidPuaFromVendorSpecificSjis", "(JC)I",
244 (void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis},
245 { "nativeGetVendorSpecificSjisFromAndroidPua", "(JI)I",
246 (void*)android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua},
247 { "nativeGetAndroidPuaFromVendorSpecificPua", "(JI)I",
248 (void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua},
249 { "nativeGetVendorSpecificPuaFromAndroidPua", "(JI)I",
250 (void*)android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua},
251 { "nativeGetMaximumVendorSpecificPua", "(J)I",
252 (void*)android_emoji_EmojiFactory_getMaximumVendorSpecificPua},
253 { "nativeGetMinimumVendorSpecificPua", "(J)I",
254 (void*)android_emoji_EmojiFactory_getMinimumVendorSpecificPua},
255 { "nativeGetMaximumAndroidPua", "(J)I",
256 (void*)android_emoji_EmojiFactory_getMaximumAndroidPua},
257 { "nativeGetMinimumAndroidPua", "(J)I",
258 (void*)android_emoji_EmojiFactory_getMinimumAndroidPua}
261 static jclass make_globalref(JNIEnv* env, const char classname[])
263 jclass c = env->FindClass(classname);
265 return (jclass)env->NewGlobalRef(c);
268 static jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz,
269 const char fieldname[], const char type[])
271 jfieldID id = env->GetFieldID(clazz, fieldname, type);
276 int register_android_emoji_EmojiFactory(JNIEnv* env) {
277 gEmojiFactory_class = make_globalref(env, "android/emoji/EmojiFactory");
278 gEmojiFactory_constructorMethodID = env->GetMethodID(
279 gEmojiFactory_class, "<init>", "(JLjava/lang/String;)V");
280 return jniRegisterNativeMethods(env, "android/emoji/EmojiFactory",
281 gMethods, NELEM(gMethods));
284 } // namespace android