Remove EmojiFactory and its mentions from frameworks.

Bug: 18134313
Bug: 20158206
Change-Id: If46cdbd9d558e6592280b2b95f00b87d04de70a2
This commit is contained in:
Roozbeh Pournader
2015-08-07 12:44:41 -07:00
parent 456c7a766c
commit 112d9c7f11
8 changed files with 23 additions and 658 deletions

View File

@@ -1,289 +0,0 @@
/*
* 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.
*/
package android.emoji;
import android.graphics.Bitmap;
import java.lang.ref.WeakReference;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* A class for the factories which produce Emoji (pictgram) images.
* This is intended to be used by IME, Email app, etc.
* There's no plan to make this public for now.
* @hide
*/
public final class EmojiFactory {
// private static final String LOG_TAG = "EmojiFactory";
private int sCacheSize = 100;
// HashMap for caching Bitmap object. In order not to make a cache object
// blow up, we use LinkedHashMap with size limit.
private class CustomLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
public CustomLinkedHashMap() {
// These magic numbers are gotten from the source code of
// LinkedHashMap.java and HashMap.java.
super(16, 0.75f, true);
}
/*
* If size() becomes more than sCacheSize, least recently used cache
* is erased.
* @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry)
*/
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > sCacheSize;
}
}
// A pointer to native EmojiFactory object.
private long mNativeEmojiFactory;
private String mName;
// Cache.
private Map<Integer, WeakReference<Bitmap>> mCache;
/**
* @noinspection UnusedDeclaration
*/
/*
* Private constructor that must received an already allocated native
* EmojiFactory int (pointer).
*
* This can be called from JNI code.
*/
private EmojiFactory(long nativeEmojiFactory, String name) {
mNativeEmojiFactory = nativeEmojiFactory;
mName = name;
mCache = new CustomLinkedHashMap<Integer, WeakReference<Bitmap>>();
}
@Override
protected void finalize() throws Throwable {
try {
nativeDestructor(mNativeEmojiFactory);
} finally {
super.finalize();
}
}
public String name() {
return mName;
}
/**
* Returns Bitmap object corresponding to the AndroidPua.
*
* Note that each Bitmap is cached by this class, which means that, if you modify a
* Bitmap object (using setPos() method), all same emoji Bitmap will be modified.
* If it is unacceptable, please copy the object before modifying it.
*
* @param pua A unicode codepoint.
* @return Bitmap object when this factory knows the Bitmap relevant to the codepoint.
* Otherwise null is returned.
*/
public synchronized Bitmap getBitmapFromAndroidPua(int pua) {
WeakReference<Bitmap> cache = mCache.get(pua);
if (cache == null) {
Bitmap ret = nativeGetBitmapFromAndroidPua(mNativeEmojiFactory, pua);
// There is no need to cache returned null, since in most cases it means there
// is no map from the AndroidPua to a specific image. In other words, it usually does
// not include the cost of creating Bitmap object.
if (ret != null) {
mCache.put(pua, new WeakReference<Bitmap>(ret));
}
return ret;
} else {
Bitmap tmp = cache.get();
if (tmp == null) {
Bitmap ret = nativeGetBitmapFromAndroidPua(mNativeEmojiFactory, pua);
mCache.put(pua, new WeakReference<Bitmap>(ret));
return ret;
} else {
return tmp;
}
}
}
/**
* Returns Bitmap object corresponding to the vendor specified sjis.
*
* See comments in getBitmapFromAndroidPua().
*
* @param sjis sjis code specific to each career(vendor)
* @return Bitmap object when this factory knows the Bitmap relevant to the code. Otherwise
* null is returned.
*/
public synchronized Bitmap getBitmapFromVendorSpecificSjis(char sjis) {
return getBitmapFromAndroidPua(getAndroidPuaFromVendorSpecificSjis(sjis));
}
/**
* Returns Bitmap object corresponding to the vendor specific Unicode.
*
* See comments in getBitmapFromAndroidPua().
*
* @param vsp vendor specific PUA.
* @return Bitmap object when this factory knows the Bitmap relevant to the code. Otherwise
* null is returned.
*/
public synchronized Bitmap getBitmapFromVendorSpecificPua(int vsp) {
return getBitmapFromAndroidPua(getAndroidPuaFromVendorSpecificPua(vsp));
}
/**
* Returns Unicode PUA for Android corresponding to the vendor specific sjis.
*
* @param sjis vendor specific sjis
* @return Unicode PUA for Android, or -1 if there's no map for the sjis.
*/
public int getAndroidPuaFromVendorSpecificSjis(char sjis) {
return nativeGetAndroidPuaFromVendorSpecificSjis(mNativeEmojiFactory, sjis);
}
/**
* Returns vendor specific sjis corresponding to the Unicode AndroidPua.
*
* @param pua Unicode PUA for Android,
* @return vendor specific sjis, or -1 if there's no map for the AndroidPua.
*/
public int getVendorSpecificSjisFromAndroidPua(int pua) {
return nativeGetVendorSpecificSjisFromAndroidPua(mNativeEmojiFactory, pua);
}
/**
* Returns Unicode PUA for Android corresponding to the vendor specific Unicode.
*
* @param vsp vendor specific PUA.
* @return Unicode PUA for Android, or -1 if there's no map for the
* Unicode.
*/
public int getAndroidPuaFromVendorSpecificPua(int vsp) {
return nativeGetAndroidPuaFromVendorSpecificPua(mNativeEmojiFactory, vsp);
}
public String getAndroidPuaFromVendorSpecificPua(String vspString) {
if (vspString == null) {
return null;
}
int minVsp = nativeGetMinimumVendorSpecificPua(mNativeEmojiFactory);
int maxVsp = nativeGetMaximumVendorSpecificPua(mNativeEmojiFactory);
int len = vspString.length();
int[] codePoints = new int[vspString.codePointCount(0, len)];
int new_len = 0;
for (int i = 0; i < len; i = vspString.offsetByCodePoints(i, 1), new_len++) {
int codePoint = vspString.codePointAt(i);
if (minVsp <= codePoint && codePoint <= maxVsp) {
int newCodePoint = getAndroidPuaFromVendorSpecificPua(codePoint);
if (newCodePoint > 0) {
codePoints[new_len] = newCodePoint;
continue;
}
}
codePoints[new_len] = codePoint;
}
return new String(codePoints, 0, new_len);
}
/**
* Returns vendor specific Unicode corresponding to the Unicode AndroidPua.
*
* @param pua Unicode PUA for Android,
* @return vendor specific sjis, or -1 if there's no map for the AndroidPua.
*/
public int getVendorSpecificPuaFromAndroidPua(int pua) {
return nativeGetVendorSpecificPuaFromAndroidPua(mNativeEmojiFactory, pua);
}
public String getVendorSpecificPuaFromAndroidPua(String puaString) {
if (puaString == null) {
return null;
}
int minVsp = nativeGetMinimumAndroidPua(mNativeEmojiFactory);
int maxVsp = nativeGetMaximumAndroidPua(mNativeEmojiFactory);
int len = puaString.length();
int[] codePoints = new int[puaString.codePointCount(0, len)];
int new_len = 0;
for (int i = 0; i < len; i = puaString.offsetByCodePoints(i, 1), new_len++) {
int codePoint = puaString.codePointAt(i);
if (minVsp <= codePoint && codePoint <= maxVsp) {
int newCodePoint = getVendorSpecificPuaFromAndroidPua(codePoint);
if (newCodePoint > 0) {
codePoints[new_len] = newCodePoint;
continue;
}
}
codePoints[new_len] = codePoint;
}
return new String(codePoints, 0, new_len);
}
/**
* Constructs an instance of EmojiFactory corresponding to the name.
*
* @param class_name Name of the factory. This must include complete package name.
* @return A concrete EmojiFactory instance corresponding to factory_name.
* If factory_name is invalid, null is returned.
*/
public static native EmojiFactory newInstance(String class_name);
/**
* Constructs an instance of available EmojiFactory.
*
* @return A concrete EmojiFactory instance. If there are several available
* EmojiFactory class, preferred one is chosen by the system. If there isn't, null
* is returned.
*/
public static native EmojiFactory newAvailableInstance();
/**
* Returns the lowest code point corresponding to an Android
* emoji character.
*/
public int getMinimumAndroidPua() {
return nativeGetMinimumAndroidPua(mNativeEmojiFactory);
}
/**
* Returns the highest code point corresponding to an Android
* emoji character.
*/
public int getMaximumAndroidPua() {
return nativeGetMaximumAndroidPua(mNativeEmojiFactory);
}
// native methods
private native void nativeDestructor(long nativeEmojiFactory);
private native Bitmap nativeGetBitmapFromAndroidPua(long nativeEmojiFactory, int AndroidPua);
private native int nativeGetAndroidPuaFromVendorSpecificSjis(long nativeEmojiFactory,
char sjis);
private native int nativeGetVendorSpecificSjisFromAndroidPua(long nativeEmojiFactory,
int pua);
private native int nativeGetAndroidPuaFromVendorSpecificPua(long nativeEmojiFactory,
int vsp);
private native int nativeGetVendorSpecificPuaFromAndroidPua(long nativeEmojiFactory,
int pua);
private native int nativeGetMaximumVendorSpecificPua(long nativeEmojiFactory);
private native int nativeGetMinimumVendorSpecificPua(long nativeEmojiFactory);
private native int nativeGetMaximumAndroidPua(long nativeEmojiFactory);
private native int nativeGetMinimumAndroidPua(long nativeEmojiFactory);
}

View File

@@ -17,7 +17,6 @@
package android.text;
import android.annotation.IntDef;
import android.emoji.EmojiFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
@@ -103,19 +102,6 @@ public abstract class Layout {
private static final ParagraphStyle[] NO_PARA_SPANS =
ArrayUtils.emptyArray(ParagraphStyle.class);
/* package */ static final EmojiFactory EMOJI_FACTORY = EmojiFactory.newAvailableInstance();
/* package */ static final int MIN_EMOJI, MAX_EMOJI;
static {
if (EMOJI_FACTORY != null) {
MIN_EMOJI = EMOJI_FACTORY.getMinimumAndroidPua();
MAX_EMOJI = EMOJI_FACTORY.getMaximumAndroidPua();
} else {
MIN_EMOJI = -1;
MAX_EMOJI = -1;
}
}
/**
* Return how wide a layout must be in order to display the
* specified text with one line per paragraph.
@@ -360,9 +346,9 @@ public abstract class Layout {
}
}
boolean hasTabOrEmoji = getLineContainsTab(lineNum);
boolean hasTab = getLineContainsTab(lineNum);
// Can't tell if we have tabs for sure, currently
if (hasTabOrEmoji && !tabStopsIsInitialized) {
if (hasTab && !tabStopsIsInitialized) {
if (tabStops == null) {
tabStops = new TabStops(TAB_INCREMENT, spans);
} else {
@@ -405,11 +391,11 @@ public abstract class Layout {
paint.setHyphenEdit(getHyphen(lineNum));
Directions directions = getLineDirections(lineNum);
if (directions == DIRS_ALL_LEFT_TO_RIGHT && !mSpannedText && !hasTabOrEmoji) {
if (directions == DIRS_ALL_LEFT_TO_RIGHT && !mSpannedText && !hasTab) {
// XXX: assumes there's nothing additional to be done
canvas.drawText(buf, start, end, x, lbaseline, paint);
} else {
tl.set(paint, buf, start, end, dir, directions, hasTabOrEmoji, tabStops);
tl.set(paint, buf, start, end, dir, directions, hasTab, tabStops);
tl.draw(canvas, x, ltop, lbaseline, lbottom);
}
paint.setHyphenEdit(0);
@@ -710,8 +696,7 @@ public abstract class Layout {
/**
* Returns whether the specified line contains one or more
* characters that need to be handled specially, like tabs
* or emoji.
* characters that need to be handled specially, like tabs.
*/
public abstract boolean getLineContainsTab(int line);
@@ -911,11 +896,11 @@ public abstract class Layout {
int start = getLineStart(line);
int end = getLineEnd(line);
int dir = getParagraphDirection(line);
boolean hasTabOrEmoji = getLineContainsTab(line);
boolean hasTab = getLineContainsTab(line);
Directions directions = getLineDirections(line);
TabStops tabStops = null;
if (hasTabOrEmoji && mText instanceof Spanned) {
if (hasTab && mText instanceof Spanned) {
// Just checking this line should be good enough, tabs should be
// consistent across all lines in a paragraph.
TabStopSpan[] tabs = getParagraphSpans((Spanned) mText, start, end, TabStopSpan.class);
@@ -925,7 +910,7 @@ public abstract class Layout {
}
TextLine tl = TextLine.obtain();
tl.set(mPaint, mText, start, end, dir, directions, hasTabOrEmoji, tabStops);
tl.set(mPaint, mText, start, end, dir, directions, hasTab, tabStops);
float wid = tl.measure(offset - start, trailing, null);
TextLine.recycle(tl);
@@ -1031,9 +1016,9 @@ public abstract class Layout {
int start = getLineStart(line);
int end = full ? getLineEnd(line) : getLineVisibleEnd(line);
boolean hasTabsOrEmoji = getLineContainsTab(line);
boolean hasTabs = getLineContainsTab(line);
TabStops tabStops = null;
if (hasTabsOrEmoji && mText instanceof Spanned) {
if (hasTabs && mText instanceof Spanned) {
// Just checking this line should be good enough, tabs should be
// consistent across all lines in a paragraph.
TabStopSpan[] tabs = getParagraphSpans((Spanned) mText, start, end, TabStopSpan.class);
@@ -1049,7 +1034,7 @@ public abstract class Layout {
int dir = getParagraphDirection(line);
TextLine tl = TextLine.obtain();
tl.set(mPaint, mText, start, end, dir, directions, hasTabsOrEmoji, tabStops);
tl.set(mPaint, mText, start, end, dir, directions, hasTabs, tabStops);
float width = tl.metrics(null);
TextLine.recycle(tl);
return width;
@@ -1066,12 +1051,12 @@ public abstract class Layout {
private float getLineExtent(int line, TabStops tabStops, boolean full) {
int start = getLineStart(line);
int end = full ? getLineEnd(line) : getLineVisibleEnd(line);
boolean hasTabsOrEmoji = getLineContainsTab(line);
boolean hasTabs = getLineContainsTab(line);
Directions directions = getLineDirections(line);
int dir = getParagraphDirection(line);
TextLine tl = TextLine.obtain();
tl.set(mPaint, mText, start, end, dir, directions, hasTabsOrEmoji, tabStops);
tl.set(mPaint, mText, start, end, dir, directions, hasTabs, tabStops);
float width = tl.metrics(null);
TextLine.recycle(tl);
return width;

View File

@@ -1308,7 +1308,7 @@ public class StaticLayout extends Layout {
private static final int INITIAL_SIZE = 16;
public int[] breaks = new int[INITIAL_SIZE];
public float[] widths = new float[INITIAL_SIZE];
public int[] flags = new int[INITIAL_SIZE]; // hasTabOrEmoji
public int[] flags = new int[INITIAL_SIZE]; // hasTab
// breaks, widths, and flags should all have the same length
}

View File

@@ -128,7 +128,7 @@ class TextLine {
* @param limit the limit of the line relative to the text
* @param dir the paragraph direction of this line
* @param directions the directions information of this line
* @param hasTabs true if the line might contain tabs or emoji
* @param hasTabs true if the line might contain tabs
* @param tabStops the tabStops. Can be null.
*/
void set(TextPaint paint, CharSequence text, int start, int limit, int dir,
@@ -204,7 +204,6 @@ class TextLine {
float h = 0;
int[] runs = mDirections.mDirections;
RectF emojiRect = null;
int lastRunIndex = runs.length - 2;
for (int i = 0; i < runs.length; i += 2) {
@@ -218,41 +217,23 @@ class TextLine {
int segstart = runStart;
for (int j = mHasTabs ? runStart : runLimit; j <= runLimit; j++) {
int codept = 0;
Bitmap bm = null;
if (mHasTabs && j < runLimit) {
codept = mChars[j];
if (codept >= 0xd800 && codept < 0xdc00 && j + 1 < runLimit) {
if (codept >= 0xD800 && codept < 0xDC00 && j + 1 < runLimit) {
codept = Character.codePointAt(mChars, j);
if (codept >= Layout.MIN_EMOJI && codept <= Layout.MAX_EMOJI) {
bm = Layout.EMOJI_FACTORY.getBitmapFromAndroidPua(codept);
} else if (codept > 0xffff) {
if (codept > 0xFFFF) {
++j;
continue;
}
}
}
if (j == runLimit || codept == '\t' || bm != null) {
if (j == runLimit || codept == '\t') {
h += drawRun(c, segstart, j, runIsRtl, x+h, top, y, bottom,
i != lastRunIndex || j != mLen);
if (codept == '\t') {
h = mDir * nextTab(h * mDir);
} else if (bm != null) {
float bmAscent = ascent(j);
float bitmapHeight = bm.getHeight();
float scale = -bmAscent / bitmapHeight;
float width = bm.getWidth() * scale;
if (emojiRect == null) {
emojiRect = new RectF();
}
emojiRect.set(x + h, y + bmAscent,
x + h + width, y);
c.drawBitmap(bm, null, emojiRect, mPaint);
h += width;
j++;
}
segstart = j + 1;
}
@@ -313,22 +294,18 @@ class TextLine {
int segstart = runStart;
for (int j = mHasTabs ? runStart : runLimit; j <= runLimit; j++) {
int codept = 0;
Bitmap bm = null;
if (mHasTabs && j < runLimit) {
codept = chars[j];
if (codept >= 0xd800 && codept < 0xdc00 && j + 1 < runLimit) {
if (codept >= 0xD800 && codept < 0xDC00 && j + 1 < runLimit) {
codept = Character.codePointAt(chars, j);
if (codept >= Layout.MIN_EMOJI && codept <= Layout.MAX_EMOJI) {
bm = Layout.EMOJI_FACTORY.getBitmapFromAndroidPua(codept);
} else if (codept > 0xffff) {
if (codept > 0xFFFF) {
++j;
continue;
}
}
}
if (j == runLimit || codept == '\t' || bm != null) {
if (j == runLimit || codept == '\t') {
boolean inSegment = target >= segstart && target < j;
boolean advance = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
@@ -353,13 +330,6 @@ class TextLine {
}
}
if (bm != null) {
float bmAscent = ascent(j);
float wid = bm.getWidth() * -bmAscent / bm.getHeight();
h += mDir * wid;
j++;
}
segstart = j + 1;
}
}
@@ -705,7 +675,7 @@ class TextLine {
/**
* Utility function for measuring and rendering text. The text must
* not include a tab or emoji.
* not include a tab.
*
* @param wp the working paint
* @param start the start of the text
@@ -860,7 +830,7 @@ class TextLine {
/**
* Utility function for handling a unidirectional run. The run must not
* contain tabs or emoji but can contain styles.
* contain tabs but can contain styles.
*
*
* @param start the line-relative start of the run
@@ -993,32 +963,6 @@ class TextLine {
}
}
/**
* Returns the ascent of the text at start. This is used for scaling
* emoji.
*
* @param pos the line-relative position
* @return the ascent of the text at start
*/
float ascent(int pos) {
if (mSpanned == null) {
return mPaint.ascent();
}
pos += mStart;
MetricAffectingSpan[] spans = mSpanned.getSpans(pos, pos + 1, MetricAffectingSpan.class);
if (spans.length == 0) {
return mPaint.ascent();
}
TextPaint wp = mWorkPaint;
wp.set(mPaint);
for (MetricAffectingSpan span : spans) {
span.updateMeasureState(wp);
}
return wp.ascent();
}
/**
* Returns the next tab position.
*

View File

@@ -49,7 +49,6 @@ LOCAL_SRC_FILES:= \
android_database_SQLiteConnection.cpp \
android_database_SQLiteGlobal.cpp \
android_database_SQLiteDebug.cpp \
android_emoji_EmojiFactory.cpp \
android_view_DisplayEventReceiver.cpp \
android_view_DisplayListCanvas.cpp \
android_view_GraphicBuffer.cpp \
@@ -201,7 +200,6 @@ LOCAL_C_INCLUDES += \
external/tremor/Tremor \
external/jpeg \
external/harfbuzz_ng/src \
frameworks/opt/emoji \
libcore/include \
$(call include-path-for, audio-utils) \
frameworks/minikin/include \

View File

@@ -107,7 +107,6 @@ extern int register_android_util_EventLog(JNIEnv* env);
extern int register_android_util_Log(JNIEnv* env);
extern int register_android_content_StringBlock(JNIEnv* env);
extern int register_android_content_XmlBlock(JNIEnv* env);
extern int register_android_emoji_EmojiFactory(JNIEnv* env);
extern int register_android_graphics_Canvas(JNIEnv* env);
extern int register_android_graphics_CanvasProperty(JNIEnv* env);
extern int register_android_graphics_ColorFilter(JNIEnv* env);
@@ -1265,7 +1264,6 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
REG_JNI(register_android_content_XmlBlock),
REG_JNI(register_android_emoji_EmojiFactory),
REG_JNI(register_android_text_AndroidCharacter),
REG_JNI(register_android_text_StaticLayout),
REG_JNI(register_android_text_AndroidBidi),

View File

@@ -1,270 +0,0 @@
#include "SkTypes.h"
#include "SkImageDecoder.h"
#define LOG_TAG "EmojiFactory_jni"
#include <utils/Log.h>
#include <ScopedUtfChars.h>
#include "BitmapFactory.h"
#include "EmojiFactory.h"
#include "GraphicsJNI.h"
#include <nativehelper/JNIHelp.h>
#include <dlfcn.h>
// #include <pthread.h>
namespace android {
class EmojiFactoryCaller {
public:
EmojiFactoryCaller() {}
virtual ~EmojiFactoryCaller();
bool Init();
EmojiFactory *TryCallGetImplementation(const char* name);
EmojiFactory *TryCallGetAvailableImplementation();
private:
void *m_handle;
EmojiFactory *(*m_get_implementation)(const char*);
EmojiFactory *(*m_get_available_implementation)();
};
bool EmojiFactoryCaller::Init() {
const char* error_msg;
m_handle = dlopen("libemoji.so", RTLD_LAZY | RTLD_LOCAL);
if (m_handle == NULL) {
error_msg = "Failed to load libemoji.so";
goto FAIL;
}
m_get_implementation =
reinterpret_cast<EmojiFactory *(*)(const char*)>(
dlsym(m_handle, "GetImplementation"));
if (m_get_implementation == NULL) {
error_msg = "Failed to get symbol of GetImplementation";
goto FAIL;
}
m_get_available_implementation =
reinterpret_cast<EmojiFactory *(*)()>(
dlsym(m_handle,"GetAvailableImplementation"));
if (m_get_available_implementation == NULL) {
error_msg = "Failed to get symbol of GetAvailableImplementation";
goto FAIL;
}
return true;
FAIL:
const char* error_str = dlerror();
if (error_str == NULL) {
error_str = "unknown reason";
}
ALOGE("%s: %s", error_msg, error_str);
if (m_handle != NULL) {
dlclose(m_handle);
m_handle = NULL;
}
return false;
}
EmojiFactoryCaller::~EmojiFactoryCaller() {
if (m_handle) {
dlclose(m_handle);
}
}
EmojiFactory *EmojiFactoryCaller::TryCallGetImplementation(
const char* name) {
if (NULL == m_handle) {
return NULL;
}
return m_get_implementation(name);
}
EmojiFactory *EmojiFactoryCaller::TryCallGetAvailableImplementation() {
if (NULL == m_handle) {
return NULL;
}
return m_get_available_implementation();
}
static EmojiFactoryCaller* gCaller;
static pthread_once_t g_once = PTHREAD_ONCE_INIT;
static bool lib_emoji_factory_is_ready;
static jclass gEmojiFactory_class;
static jmethodID gEmojiFactory_constructorMethodID;
static void InitializeCaller() {
gCaller = new EmojiFactoryCaller();
lib_emoji_factory_is_ready = gCaller->Init();
}
static jobject create_java_EmojiFactory(
JNIEnv* env, EmojiFactory* factory, jstring name) {
jobject obj = env->NewObject(gEmojiFactory_class, gEmojiFactory_constructorMethodID,
reinterpret_cast<jlong>(factory), name);
if (env->ExceptionCheck() != 0) {
ALOGE("*** Uncaught exception returned from Java call!\n");
env->ExceptionDescribe();
}
return obj;
}
static jobject android_emoji_EmojiFactory_newInstance(
JNIEnv* env, jobject clazz, jstring name) {
if (NULL == name) {
return NULL;
}
pthread_once(&g_once, InitializeCaller);
if (!lib_emoji_factory_is_ready) {
return NULL;
}
ScopedUtfChars nameUtf(env, name);
EmojiFactory *factory = gCaller->TryCallGetImplementation(nameUtf.c_str());
// EmojiFactory *factory = EmojiFactory::GetImplementation(str.string());
if (NULL == factory) {
return NULL;
}
return create_java_EmojiFactory(env, factory, name);
}
static jobject android_emoji_EmojiFactory_newAvailableInstance(
JNIEnv* env, jobject clazz) {
pthread_once(&g_once, InitializeCaller);
if (!lib_emoji_factory_is_ready) {
return NULL;
}
EmojiFactory *factory = gCaller->TryCallGetAvailableImplementation();
// EmojiFactory *factory = EmojiFactory::GetAvailableImplementation();
if (NULL == factory) {
return NULL;
}
jstring jname = env->NewStringUTF(factory->Name());
if (NULL == jname) {
return NULL;
}
return create_java_EmojiFactory(env, factory, jname);
}
static jobject android_emoji_EmojiFactory_getBitmapFromAndroidPua(
JNIEnv* env, jobject clazz, jlong nativeEmojiFactory, jint pua) {
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
int size;
const char *bytes = factory->GetImageBinaryFromAndroidPua(pua, &size);
if (bytes == NULL) {
return NULL;
}
return decodeBitmap(env, (void*)bytes, size);
}
static void android_emoji_EmojiFactory_destructor(
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
/*
// Must not delete this object!!
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
delete factory;
*/
}
static jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis(
JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jchar sjis) {
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
return factory->GetAndroidPuaFromVendorSpecificSjis(sjis);
}
static jint android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua(
JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jint pua) {
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
return factory->GetVendorSpecificSjisFromAndroidPua(pua);
}
static jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua(
JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jint vsu) {
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
return factory->GetAndroidPuaFromVendorSpecificPua(vsu);
}
static jint android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua(
JNIEnv* env, jobject obj, jlong nativeEmojiFactory, jint pua) {
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
return factory->GetVendorSpecificPuaFromAndroidPua(pua);
}
static jint android_emoji_EmojiFactory_getMaximumVendorSpecificPua(
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
return factory->GetMaximumVendorSpecificPua();
}
static jint android_emoji_EmojiFactory_getMinimumVendorSpecificPua(
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
return factory->GetMinimumVendorSpecificPua();
}
static jint android_emoji_EmojiFactory_getMaximumAndroidPua(
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
return factory->GetMaximumAndroidPua();
}
static jint android_emoji_EmojiFactory_getMinimumAndroidPua(
JNIEnv* env, jobject obj, jlong nativeEmojiFactory) {
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
return factory->GetMinimumAndroidPua();
}
static JNINativeMethod gMethods[] = {
{ "newInstance", "(Ljava/lang/String;)Landroid/emoji/EmojiFactory;",
(void*)android_emoji_EmojiFactory_newInstance},
{ "newAvailableInstance", "()Landroid/emoji/EmojiFactory;",
(void*)android_emoji_EmojiFactory_newAvailableInstance},
{ "nativeDestructor", "(J)V",
(void*)android_emoji_EmojiFactory_destructor},
{ "nativeGetBitmapFromAndroidPua", "(JI)Landroid/graphics/Bitmap;",
(void*)android_emoji_EmojiFactory_getBitmapFromAndroidPua},
{ "nativeGetAndroidPuaFromVendorSpecificSjis", "(JC)I",
(void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis},
{ "nativeGetVendorSpecificSjisFromAndroidPua", "(JI)I",
(void*)android_emoji_EmojiFactory_getVendorSpecificSjisFromAndroidPua},
{ "nativeGetAndroidPuaFromVendorSpecificPua", "(JI)I",
(void*)android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificPua},
{ "nativeGetVendorSpecificPuaFromAndroidPua", "(JI)I",
(void*)android_emoji_EmojiFactory_getVendorSpecificPuaFromAndroidPua},
{ "nativeGetMaximumVendorSpecificPua", "(J)I",
(void*)android_emoji_EmojiFactory_getMaximumVendorSpecificPua},
{ "nativeGetMinimumVendorSpecificPua", "(J)I",
(void*)android_emoji_EmojiFactory_getMinimumVendorSpecificPua},
{ "nativeGetMaximumAndroidPua", "(J)I",
(void*)android_emoji_EmojiFactory_getMaximumAndroidPua},
{ "nativeGetMinimumAndroidPua", "(J)I",
(void*)android_emoji_EmojiFactory_getMinimumAndroidPua}
};
static jclass make_globalref(JNIEnv* env, const char classname[])
{
jclass c = env->FindClass(classname);
SkASSERT(c);
return (jclass)env->NewGlobalRef(c);
}
int register_android_emoji_EmojiFactory(JNIEnv* env) {
gEmojiFactory_class = make_globalref(env, "android/emoji/EmojiFactory");
gEmojiFactory_constructorMethodID = env->GetMethodID(
gEmojiFactory_class, "<init>", "(JLjava/lang/String;)V");
return jniRegisterNativeMethods(env, "android/emoji/EmojiFactory",
gMethods, NELEM(gMethods));
}
} // namespace android

View File

@@ -742,7 +742,6 @@ android.ddm.DdmHandleProfiling
android.ddm.DdmHandleThread
android.ddm.DdmHandleViewDebug
android.ddm.DdmRegister
android.emoji.EmojiFactory
android.graphics.AvoidXfermode
android.graphics.Bitmap
android.graphics.Bitmap$1