OSDN Git Service

DO NOT MERGE fix build breakage on k am: 4e33c4f8b1 am: 07c994012c
[android-x86/frameworks-base.git] / core / jni / android_emoji_EmojiFactory.cpp
1 #include "SkTypes.h"
2 #include "SkImageDecoder.h"
3
4 #define LOG_TAG "EmojiFactory_jni"
5 #include <utils/Log.h>
6 #include <ScopedUtfChars.h>
7
8 #include "EmojiFactory.h"
9 #include "GraphicsJNI.h"
10 #include <nativehelper/JNIHelp.h>
11
12 #include <dlfcn.h>
13 // #include <pthread.h>
14
15 namespace android {
16
17 class EmojiFactoryCaller {
18  public:
19   EmojiFactoryCaller() {}
20   virtual ~EmojiFactoryCaller();
21   bool Init();
22   EmojiFactory *TryCallGetImplementation(const char* name);
23   EmojiFactory *TryCallGetAvailableImplementation();
24  private:
25   void *m_handle;
26   EmojiFactory *(*m_get_implementation)(const char*);
27   EmojiFactory *(*m_get_available_implementation)();
28 };
29
30 bool EmojiFactoryCaller::Init() {
31   const char* error_msg;
32   m_handle = dlopen("libemoji.so", RTLD_LAZY | RTLD_LOCAL);
33
34   if (m_handle == NULL) {
35     error_msg = "Failed to load libemoji.so";
36     goto FAIL;
37   }
38
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";
44     goto FAIL;
45   }
46
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";
52     goto FAIL;
53   }
54
55   return true;
56
57 FAIL:
58   const char* error_str = dlerror();
59   if (error_str == NULL) {
60     error_str = "unknown reason";
61   }
62
63   ALOGE("%s: %s", error_msg, error_str);
64   if (m_handle != NULL) {
65     dlclose(m_handle);
66     m_handle = NULL;
67   }
68   return false;
69 }
70
71 EmojiFactoryCaller::~EmojiFactoryCaller() {
72   if (m_handle) {
73     dlclose(m_handle);
74   }
75 }
76
77 EmojiFactory *EmojiFactoryCaller::TryCallGetImplementation(
78     const char* name) {
79   if (NULL == m_handle) {
80     return NULL;
81   }
82   return m_get_implementation(name);
83 }
84
85 EmojiFactory *EmojiFactoryCaller::TryCallGetAvailableImplementation() {
86   if (NULL == m_handle) {
87     return NULL;
88   }
89   return m_get_available_implementation();
90 }
91
92 static EmojiFactoryCaller* gCaller;
93 static pthread_once_t g_once = PTHREAD_ONCE_INIT;
94 static bool lib_emoji_factory_is_ready;
95
96 static jclass    gEmojiFactory_class;
97 static jmethodID gEmojiFactory_constructorMethodID;
98
99 static void InitializeCaller() {
100   gCaller = new EmojiFactoryCaller();
101   lib_emoji_factory_is_ready = gCaller->Init();
102 }
103
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();
111   }
112   return obj;
113 }
114
115 static jobject android_emoji_EmojiFactory_newInstance(
116     JNIEnv* env, jobject clazz, jstring name) {
117   if (NULL == name) {
118     return NULL;
119   }
120   pthread_once(&g_once, InitializeCaller);
121   if (!lib_emoji_factory_is_ready) {
122     return NULL;
123   }
124
125   ScopedUtfChars nameUtf(env, name);
126
127   EmojiFactory *factory = gCaller->TryCallGetImplementation(nameUtf.c_str());
128   // EmojiFactory *factory = EmojiFactory::GetImplementation(str.string());
129   if (NULL == factory) {
130     return NULL;
131   }
132
133   return create_java_EmojiFactory(env, factory, name);
134 }
135
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) {
140     return NULL;
141   }
142
143   EmojiFactory *factory = gCaller->TryCallGetAvailableImplementation();
144   // EmojiFactory *factory = EmojiFactory::GetAvailableImplementation();
145   if (NULL == factory) {
146     return NULL;
147   }
148
149   jstring jname = env->NewStringUTF(factory->Name());
150   if (NULL == jname) {
151     return NULL;
152   }
153
154   return create_java_EmojiFactory(env, factory, jname);
155 }
156
157 static jobject android_emoji_EmojiFactory_getBitmapFromAndroidPua(
158     JNIEnv* env, jobject clazz, jlong nativeEmojiFactory, jint pua) {
159   EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
160
161   int size;
162   const char *bytes = factory->GetImageBinaryFromAndroidPua(pua, &size);
163   if (bytes == NULL) {
164     return NULL;
165   }
166
167   SkBitmap *bitmap = new SkBitmap;
168   if (!SkImageDecoder::DecodeMemory(bytes, size, bitmap)) {
169     ALOGE("SkImageDecoder::DecodeMemory() failed.");
170     return NULL;
171   }
172
173   return GraphicsJNI::createBitmap(env, bitmap,
174       GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL);
175 }
176
177 static void android_emoji_EmojiFactory_destructor(
178     JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
179   /*
180   // Must not delete this object!!
181   EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
182   delete factory;
183   */
184 }
185
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);
190 }
191
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);
196 }
197
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);
202 }
203
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);
208 }
209
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();
214 }
215
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();
220 }
221
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();
226 }
227
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();
232 }
233
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}
259 };
260
261 static jclass make_globalref(JNIEnv* env, const char classname[])
262 {
263     jclass c = env->FindClass(classname);
264     SkASSERT(c);
265     return (jclass)env->NewGlobalRef(c);
266 }
267
268 static jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz,
269                                 const char fieldname[], const char type[])
270 {
271     jfieldID id = env->GetFieldID(clazz, fieldname, type);
272     SkASSERT(id);
273     return id;
274 }
275
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));
282 }
283
284 }  // namespace android