summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-10 16:20:55 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-10 16:20:55 -0700
commit7d814fb9f0fd40667bb0338b7ca2cebfcc331dcd (patch)
treefaaf82d874052bec80908cd093b8efd06786d1d6
downloademoji-7d814fb9f0fd40667bb0338b7ca2cebfcc331dcd.tar.gz
auto import from //branches/cupcake/...@137197
-rw-r--r--Android.mk42
-rw-r--r--EmojiFactory.cpp183
-rw-r--r--EmojiFactory.h100
3 files changed, 325 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..c5a4658
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := EmojiFactory.cpp
+
+LOCAL_MODULE := libemoji
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libutils
+
+ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
+LOCAL_LDLIBS += -ldl
+endif
+ifneq ($(TARGET_SIMULATOR),true)
+LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+LOCAL_CFLAGS += -Wall -Werror
+
+LOCAL_LDLIBS += -lpthread
+
+LOCAL_C_INCLUDES += \
+ $(base)/include/utils
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/EmojiFactory.cpp b/EmojiFactory.cpp
new file mode 100644
index 0000000..b52a02b
--- /dev/null
+++ b/EmojiFactory.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EmojiFactory.h"
+
+#define LOG_TAG "EmojiFactory"
+#include <utils/Log.h>
+#include <utils/Vector.h>
+
+#include <cutils/properties.h>
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+
+namespace android {
+
+static pthread_once_t g_once = PTHREAD_ONCE_INIT;
+static Vector<EmojiFactory *> *g_factories = NULL;
+static Vector<void *> *g_handles = NULL;
+
+class EmojiFactoryManager {
+ public:
+ void init();
+ virtual ~EmojiFactoryManager();
+ private:
+ void TryRegisterEmojiFactory(const char *library_name);
+};
+
+// Note: I previously did this procedure in the construcor. However,
+// property_get() didn't return a correct value in that context. I guess
+// property_get() does not return correct values before AndroidRuntime
+// instance (or exactly, AppRuntime in instance app_main.cpp) is
+// fully ready (see AndroidRunitem.cpp and app_main.cpp).
+// So, instead of doing this in constructor, I decided this shoud be done
+// when a user requires to EmojiFactory, which makes better sense to me.
+void EmojiFactoryManager::init() {
+ g_handles = new Vector<void *>();
+ g_factories = new Vector<EmojiFactory *>();
+
+ char *emoji_libraries = new char[PROPERTY_VALUE_MAX];
+ int len = property_get("ro.config.libemoji", emoji_libraries, "");
+ // LOGD("ro.config.libemoji: %s", emoji_libraries);
+ if (len > 0) {
+ char *saveptr, *ptr;
+ ptr = emoji_libraries;
+ while (true) {
+ ptr = strtok_r(ptr, ":", &saveptr);
+ if (NULL == ptr) {
+ break;
+ }
+ TryRegisterEmojiFactory(ptr);
+ ptr = NULL;
+ }
+ }
+
+ delete [] emoji_libraries;
+}
+
+void EmojiFactoryManager::TryRegisterEmojiFactory(const char *library_name) {
+ void *handle = dlopen(library_name, RTLD_LAZY | RTLD_LOCAL);
+ const char* error_str = dlerror();
+ if (error_str) {
+ LOGE("Failed to load shared library %s: %s", library_name, error_str);
+ return;
+ }
+ EmojiFactory *(*get_emoji_factory)() =
+ reinterpret_cast<EmojiFactory *(*)()>(dlsym(handle,
+ "GetEmojiFactory"));
+ error_str = dlerror();
+ if (error_str) {
+ LOGE("Failed to call GetEmojiFactory: %s", error_str);
+ dlclose(handle);
+ return;
+ }
+
+ EmojiFactory *factory = (*get_emoji_factory)();
+ if (NULL == factory) {
+ LOGE("Returned factory is NULL");
+ dlclose(handle);
+ return;
+ }
+
+ const char *name = factory->Name();
+
+ size_t size = g_factories->size();
+ for (size_t i = 0; i < size; ++i) {
+ EmojiFactory *f = g_factories->itemAt(i);
+ if (!strcmp(name, f->Name())) {
+ LOGE("Same EmojiFactory was found: %s", name);
+ delete factory;
+ dlclose(handle);
+ return;
+ }
+ }
+ g_factories->push(factory);
+ // dlclose() must not be called here, since returned factory may point to
+ // static data in the shared library (like "static const char* = "emoji";")
+ g_handles->push(handle);
+ // LOGD("successufl: %s", library_name); // to delete
+}
+
+EmojiFactoryManager::~EmojiFactoryManager() {
+ if (g_factories != NULL) {
+ size_t size = g_factories->size();
+ for (size_t i = 0; i < size; ++i) {
+ delete g_factories->itemAt(i);
+ }
+ delete g_factories;
+ }
+
+ if (g_handles != NULL) {
+ size_t size = g_handles->size();
+ for (size_t i = 0; i < size; ++i) {
+ dlclose(g_handles->itemAt(i));
+ }
+ delete g_handles;
+ }
+}
+
+static EmojiFactoryManager g_registrar;
+
+static void InitializeEmojiFactory() {
+ g_registrar.init();
+}
+
+/* static */
+EmojiFactory *EmojiFactory::GetImplementation(const char *name) {
+ pthread_once(&g_once, InitializeEmojiFactory);
+ if (NULL == name) {
+ return NULL;
+ }
+ size_t size = g_factories->size();
+ for (size_t i = 0; i < size; ++i) {
+ EmojiFactory *factory = g_factories->itemAt(i);
+ if (!strcmp(name, factory->Name())) {
+ return factory;
+ }
+ }
+ return NULL;
+}
+
+/* static */
+EmojiFactory *EmojiFactory::GetAvailableImplementation() {
+ pthread_once(&g_once, InitializeEmojiFactory);
+ size_t size = g_factories->size();
+ // LOGD("size: %d", size); // to delete
+ for (size_t i = 0; i < size; ++i) {
+ EmojiFactory *factory = g_factories->itemAt(i);
+ return factory;
+ }
+ return NULL;
+}
+
+} // namespace android
+
+/*
+// These ware for dlopen(). However, bionic libc does not allow dlopen() in
+// dlopen() context. That means this library cannot be dlopen()-ed.
+extern "C" android::EmojiFactory *GetImplementation(
+ const char *name) {
+ return android::EmojiFactory::GetImplementation(name);
+}
+
+extern "C" android::EmojiFactory *GetAvailableImplementation() {
+ return android::EmojiFactory::GetAvailableImplementation();
+}
+*/
diff --git a/EmojiFactory.h b/EmojiFactory.h
new file mode 100644
index 0000000..1d3fa06
--- /dev/null
+++ b/EmojiFactory.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EMOJI_FACTORY_H
+#define ANDROID_EMOJI_FACTORY_H
+
+namespace android {
+
+// Abstract class for EmojiFactory.
+//
+// Here, PUA (or Android PUA) means Unicode PUA defined for various emoji. The
+// PUA supports emoji of DoCoMo, KDDI, Softbank and Goomoji. Each PUA defined
+// by the other vendors (careers) are called Vendor Specific PUA (vsp).
+// For more information, go
+// http://unicode.org/~mdavis/08080r-emoji-proposal/ (tentative)
+class EmojiFactory {
+ public:
+ virtual ~EmojiFactory() {}
+ // Returns binary image data corresponding to "pua". The size of binary is
+ // stored to "size". Returns NULL if there's no mapping from the "pua" to a
+ // specific image. Currently, image format is all (animated) gif.
+ //
+ // TODO(dmiyakawa): there should be a way to tell users the format of the
+ // binary.
+ virtual const char *GetImageBinaryFromAndroidPua(int pua, int *size) = 0;
+
+ // Returns binary image data corresponding to "sjis", which is defined by
+ // each career. Returns NULL when there's no mapping for "sjis".
+ virtual const char *GetImageBinaryFromVendorSpecificSjis(unsigned short sjis,
+ int *size) {
+ return GetImageBinaryFromAndroidPua(
+ GetAndroidPuaFromVendorSpecificSjis(sjis), size);
+ }
+
+ // Returns binary image data corresponding to Vendor-specific PUA "vsp".
+ // Returns NULL when there's no mapping for "vsp".
+ virtual const char *GetImageBinaryFromVendorSpecificPua(int vsp,
+ int *size) {
+ return GetImageBinaryFromAndroidPua(
+ GetAndroidPuaFromVendorSpecificPua(vsp), size);
+ }
+
+ // Returns Android PUA corresponding to "sjis". Returns -1 when there's no
+ // mapping from "sjis" to a Android PUA.
+ virtual int GetAndroidPuaFromVendorSpecificSjis(unsigned short sjis) = 0;
+
+ // Returns Vendor-specific Shift jis code corresponding to "pua". Returns -1
+ // when ther's no mapping from "pua" to a specific sjis.
+ virtual int GetVendorSpecificSjisFromAndroidPua(int pua) = 0;
+
+ // Returns maximum Vendor-Specific PUA. This is the last valid value.
+ virtual int GetMaximumVendorSpecificPua() = 0;
+
+ // Returns minimum Vendor-Specific PUA.
+ virtual int GetMinimumVendorSpecificPua() = 0;
+
+ // Returns maximum Android PUA. This the last valid value.
+ virtual int GetMaximumAndroidPua() = 0;
+
+ // Returns minimum Android PUA.
+ virtual int GetMinimumAndroidPua() = 0;
+
+ // Returns Android PUA corresponding to Vendor-Specific Unicode "vsp". Returns
+ // -1 when there's no mapping from "vsp" to a Android PUA.
+ virtual int GetAndroidPuaFromVendorSpecificPua(int vsp) = 0;
+
+ // Returns Vendor-specific PUA corresponding to "pua". Returns -1 when
+ // there's no mapping from "pua" to a specific unicode.
+ virtual int GetVendorSpecificPuaFromAndroidPua(int pua) = 0;
+
+ // Returns non NULL string which defines the name of this factory.
+ // e.g. "docomo", "goomoji"
+ virtual const char *Name() const = 0;
+
+ // Get a specific implementation of EmojiFactory. If there's no implementation
+ // for "name", returns NULL.
+ static EmojiFactory *GetImplementation(const char *name);
+
+ // Get an implementation of EmojiFactory. This assumes that, usually, there
+ // should be only one possible EmojiFactory implementation. If there are more
+ // than one implementations, most prefered one is returned.
+ static EmojiFactory *GetAvailableImplementation();
+};
+
+} // namespace android
+
+#endif // ANDROID_EMOJI_FACTORY_H