android_emoji_EmojiFactory.cpp revision b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54
1b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project#include "SkTypes.h"
2b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project#include "SkImageDecoder.h"
3b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
4b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project#define LOG_TAG "DoCoMoEmojiFactory_jni"
5b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project#include <utils/Log.h>
6b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project#include <utils/String8.h>
7b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
8b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project#include "EmojiFactory.h"
9b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project#include <nativehelper/JNIHelp.h>
10b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
11b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project#include <dlfcn.h>
12b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// #include <pthread.h>
13b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
14b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectnamespace android {
15b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
16b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// Note: This class is originally developed so that libandroid_runtime does
17b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// not have to depend on libemoji which is optional library. However, we
18b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// cannot use this class, since current (2009-02-16) bionic libc does not allow
19b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// dlopen()-ing inside dlopen(), while not only this class but also libemoji
20b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// uses dlopen().
21b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectclass EmojiFactoryCaller {
22b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project public:
23b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactoryCaller();
24b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  virtual ~EmojiFactoryCaller();
25b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *TryCallGetImplementation(const char* name);
26b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *TryCallGetAvailableImplementation();
27b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project private:
28b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  void *m_handle;
29b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *(*m_get_implementation)(const char*);
30b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *(*m_get_available_implementation)();
31b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project};
32b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
33b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source ProjectEmojiFactoryCaller::EmojiFactoryCaller() {
34b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  m_handle = dlopen("libemoji.so", RTLD_LAZY | RTLD_LOCAL);
35b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  const char* error_str = dlerror();
36b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (error_str) {
37b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    LOGI("Failed to load libemoji.so: %s", error_str);
38b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return;
39b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
40b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
41b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  m_get_implementation =
42b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project      reinterpret_cast<EmojiFactory *(*)(const char*)>(
43b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project          dlsym(m_handle, "GetImplementation"));
44b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  error_str = dlerror();
45b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (error_str) {
46b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    LOGE("Failed to get symbol of GetImplementation: %s", error_str);
47b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    dlclose(m_handle);
48b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    m_handle = NULL;
49b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return;
50b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
51b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
52b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  m_get_available_implementation =
53b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project      reinterpret_cast<EmojiFactory *(*)()>(
54b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project          dlsym(m_handle,"GetAvailableImplementation"));
55b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  error_str = dlerror();
56b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (error_str) {
57b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    LOGE("Failed to get symbol of GetAvailableImplementation: %s", error_str);
58b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    dlclose(m_handle);
59b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    m_handle = NULL;
60b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return;
61b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
62b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
63b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
64b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source ProjectEmojiFactoryCaller::~EmojiFactoryCaller() {
65b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (m_handle) {
66b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    dlclose(m_handle);
67b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
68b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
69b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
70b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source ProjectEmojiFactory *EmojiFactoryCaller::TryCallGetImplementation(
71b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    const char* name) {
72b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (NULL == m_handle) {
73b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return NULL;
74b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
75b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return m_get_implementation(name);
76b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
77b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
78b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source ProjectEmojiFactory *EmojiFactoryCaller::TryCallGetAvailableImplementation() {
79b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (NULL == m_handle) {
80b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return NULL;
81b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
82b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return m_get_available_implementation();
83b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
84b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
85b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// Note: bionic libc's dlopen() does not allow recursive dlopen(). So currently
86b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// we cannot use EmojiFactoryCaller here.
87b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// static EmojiFactoryCaller* gCaller;
88b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// static pthread_once_t g_once = PTHREAD_ONCE_INIT;
89b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
90b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jclass    gString_class;
91b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
92b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jclass    gBitmap_class;
93b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jmethodID gBitmap_constructorMethodID;
94b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
95b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jclass    gEmojiFactory_class;
96b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jmethodID gEmojiFactory_constructorMethodID;
97b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
98b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// static void InitializeCaller() {
99b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project//   gCaller = new EmojiFactoryCaller();
100b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project// }
101b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
102b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jobject create_java_EmojiFactory(
103b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, EmojiFactory* factory, jstring name) {
104b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  jobject obj = env->AllocObject(gEmojiFactory_class);
105b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (obj) {
106b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    env->CallVoidMethod(obj, gEmojiFactory_constructorMethodID,
107b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                        (jint)factory, name);
108b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    if (env->ExceptionCheck() != 0) {
109b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project      LOGE("*** Uncaught exception returned from Java call!\n");
110b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project      env->ExceptionDescribe();
111b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project      obj = NULL;
112b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    }
113b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
114b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return obj;
115b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
116b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
117b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jobject android_emoji_EmojiFactory_newInstance(
118b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject clazz, jstring name) {
119b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  // pthread_once(&g_once, InitializeCaller);
120b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
121b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (NULL == name) {
122b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return NULL;
123b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
124b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
125b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  const jchar* jchars = env->GetStringChars(name, NULL);
126b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  jsize len = env->GetStringLength(name);
127b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  String8 str(String16(jchars, len));
128b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
129b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  // EmojiFactory *factory = gCaller->TryCallGetImplementation(str.string());
130b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = EmojiFactory::GetImplementation(str.string());
131b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
132b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  env->ReleaseStringChars(name, jchars);
133b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
134b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return create_java_EmojiFactory(env, factory, name);
135b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
136b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
137b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jobject android_emoji_EmojiFactory_newAvailableInstance(
138b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject clazz) {
139b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  // pthread_once(&g_once, InitializeCaller);
140b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
141b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  // EmojiFactory *factory = gCaller->TryCallGetAvailableImplementation();
142b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = EmojiFactory::GetAvailableImplementation();
143b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (NULL == factory) {
144b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return NULL;
145b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
146b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  String16 name_16(String8(factory->Name()));
147b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  jstring jname = env->NewString(name_16.string(), name_16.size());
148b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (NULL == jname) {
149b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return NULL;
150b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
151b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
152b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return create_java_EmojiFactory(env, factory, jname);
153b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
154b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
155b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jobject android_emoji_EmojiFactory_getBitmapFromAndroidPua(
156b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject clazz, jint nativeEmojiFactory, jint pua) {
157b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
158b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
159b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  int size;
160b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  const char *bytes = factory->GetImageBinaryFromAndroidPua(pua, &size);
161b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (bytes == NULL) {
162b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return NULL;
163b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
164b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
165b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  SkBitmap *bitmap = new SkBitmap;
166b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (!SkImageDecoder::DecodeMemory(bytes, size, bitmap)) {
167b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    LOGE("SkImageDecoder::DecodeMemory() failed.");
168b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return NULL;
169b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
170b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
171b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  jobject obj = env->AllocObject(gBitmap_class);
172b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  if (obj) {
173b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    env->CallVoidMethod(obj, gBitmap_constructorMethodID,
174b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                        reinterpret_cast<jint>(bitmap), false, NULL);
175b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    if (env->ExceptionCheck() != 0) {
176b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project      LOGE("*** Uncaught exception returned from Java call!\n");
177b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project      env->ExceptionDescribe();
178b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project      return NULL;
179b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    }
180b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  }
181b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
182b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return obj;
183b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
184b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
185b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic void android_emoji_EmojiFactory_destructor(
186b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
187b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
188b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  delete factory;
189b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
190b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
191b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis(
192b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject obj, jint nativeEmojiFactory, jchar sjis) {
193b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
194b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return factory->GetAndroidPuaFromVendorSpecificSjis(sjis);
195b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
196b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
197b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jint android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua(
198b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject obj, jint nativeEmojiFactory, jint pua) {
199b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
200b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return factory->GetVendorSpecificSjisFromAndroidPua(pua);
201b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
202b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
203b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua(
204b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject obj, jint nativeEmojiFactory, jint vsu) {
205b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
206b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return factory->GetAndroidPuaFromVendorSpecificPua(vsu);
207b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
208b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
209b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jint android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua(
210b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject obj, jint nativeEmojiFactory, jint pua) {
211b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
212b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return factory->GetVendorSpecificPuaFromAndroidPua(pua);
213b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
214b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
215b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jint android_emoji_EmojiFactory_getMaximumVendorSpecificPua(
216b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
217b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
218b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return factory->GetMaximumVendorSpecificPua();
219b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
220b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
221b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jint android_emoji_EmojiFactory_getMinimumVendorSpecificPua(
222b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
223b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
224b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return factory->GetMinimumVendorSpecificPua();
225b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
226b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
227b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jint android_emoji_EmojiFactory_getMaximumAndroidPua(
228b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
229b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
230b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return factory->GetMaximumAndroidPua();
231b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
232b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
233b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jint android_emoji_EmojiFactory_getMinimumAndroidPua(
234b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
235b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
236b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return factory->GetMinimumAndroidPua();
237b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
238b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
239b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic JNINativeMethod gMethods[] = {
240b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "newInstance", "(Ljava/lang/String;)Landroid/emoji/EmojiFactory;",
241b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_newInstance},
242b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "newAvailableInstance", "()Landroid/emoji/EmojiFactory;",
243b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_newAvailableInstance},
244b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeDestructor", "(I)V",
245b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_destructor},
246b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeGetBitmapFromAndroidPua", "(II)Landroid/graphics/Bitmap;",
247b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_getBitmapFromAndroidPua},
248b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeGetAndroidPuaFromVendorSpecificSjis", "(IC)I",
249b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis},
250b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeGetVendorSpecificSjisFromAndroidPua", "(II)I",
251b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua},
252b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeGetAndroidPuaFromVendorSpecificPua", "(II)I",
253b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua},
254b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeGetVendorSpecificPuaFromAndroidPua", "(II)I",
255b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua},
256b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeGetMaximumVendorSpecificPua", "(I)I",
257b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_getMaximumVendorSpecificPua},
258b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeGetMinimumVendorSpecificPua", "(I)I",
259b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_getMinimumVendorSpecificPua},
260b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeGetMaximumAndroidPua", "(I)I",
261b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_getMaximumAndroidPua},
262b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  { "nativeGetMinimumAndroidPua", "(I)I",
263b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    (void*)android_emoji_EmojiFactory_getMinimumAndroidPua}
264b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project};
265b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
266b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jclass make_globalref(JNIEnv* env, const char classname[])
267b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project{
268b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    jclass c = env->FindClass(classname);
269b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    SkASSERT(c);
270b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return (jclass)env->NewGlobalRef(c);
271b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
272b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
273b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectstatic jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz,
274b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                                const char fieldname[], const char type[])
275b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project{
276b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    jfieldID id = env->GetFieldID(clazz, fieldname, type);
277b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    SkASSERT(id);
278b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    return id;
279b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
280b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
281b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Projectint register_android_emoji_EmojiFactory(JNIEnv* env) {
282b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
283b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
284b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                                                 "(IZ[B)V");
285b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  gEmojiFactory_class = make_globalref(env, "android/emoji/EmojiFactory");
286b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  gEmojiFactory_constructorMethodID = env->GetMethodID(
287b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project      gEmojiFactory_class, "<init>", "(ILjava/lang/String;)V");
288b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project  return jniRegisterNativeMethods(env, "android/emoji/EmojiFactory",
289b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                                  gMethods, NELEM(gMethods));
290b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}
291b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
292b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project}  // namespace android
293