From 4606367f98a30c97715e9b7f312d5f9b97d0a053 Mon Sep 17 00:00:00 2001 From: Ken Wakasa Date: Mon, 26 Apr 2010 19:10:14 +0900 Subject: [PATCH] Get rid of dependency on native AssetManager API. Confirmed the native code builds with the NDK r3. Change-Id: I6a9a5bb4129e9269d74348801436c9e5e0058da5 --- .../inputmethod/latin/BinaryDictionary.java | 41 +++++++++-- native/Android.mk | 7 -- ...oid_inputmethod_latin_BinaryDictionary.cpp | 68 ++----------------- native/src/dictionary.cpp | 10 +-- 4 files changed, 41 insertions(+), 85 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 6d0257b82..9fcd9e50c 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -16,6 +16,11 @@ package com.android.inputmethod.latin; +import java.io.InputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.Channels; import java.util.Arrays; import android.content.Context; @@ -27,6 +32,7 @@ import android.util.Log; */ public class BinaryDictionary extends Dictionary { + private static final String TAG = "BinaryDictionary"; public static final int MAX_WORD_LENGTH = 48; private static final int MAX_ALTERNATIVES = 16; private static final int MAX_WORDS = 16; @@ -35,16 +41,19 @@ public class BinaryDictionary extends Dictionary { private static final boolean ENABLE_MISSED_CHARACTERS = true; private int mNativeDict; - private int mDictLength; // This value is set from native code, don't change the name!!!! + private int mDictLength; private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES]; private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS]; private int[] mFrequencies = new int[MAX_WORDS]; + // Keep a reference to the native dict direct buffer in Java to avoid + // unexpected deallocation of the direct buffer. + private ByteBuffer mNativeDictDirectBuffer; static { try { System.loadLibrary("jni_latinime2"); } catch (UnsatisfiedLinkError ule) { - Log.e("BinaryDictionary", "Could not load native library jni_latinime"); + Log.e("BinaryDictionary", "Could not load native library jni_latinime2"); } } @@ -59,8 +68,7 @@ public class BinaryDictionary extends Dictionary { } } - private native int openNative(AssetManager am, String resourcePath, int typedLetterMultiplier, - int fullWordMultiplier); + private native int openNative(ByteBuffer bb, int typedLetterMultiplier, int fullWordMultiplier); private native void closeNative(int dict); private native boolean isValidWordNative(int nativeData, char[] word, int wordLength); private native int getSuggestionsNative(int dict, int[] inputCodes, int codesSize, @@ -69,9 +77,28 @@ public class BinaryDictionary extends Dictionary { int[] nextLettersFrequencies, int nextLettersSize); private final void loadDictionary(Context context, int resId) { - AssetManager am = context.getResources().getAssets(); - String assetName = context.getResources().getString(resId); - mNativeDict = openNative(am, assetName, TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER); + InputStream is = context.getResources().openRawResource(resId); + try { + int avail = is.available(); + ByteBuffer mNativeDictDirectBuffer = + ByteBuffer.allocateDirect(avail).order(ByteOrder.nativeOrder()); + int got = Channels.newChannel(is).read(mNativeDictDirectBuffer); + if (got != avail) { + Log.e(TAG, "Read " + got + " bytes, expected " + avail); + } else { + mNativeDict = openNative(mNativeDictDirectBuffer, + TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER); + mDictLength = avail; + } + } catch (IOException e) { + Log.w(TAG, "No available size for binary dictionary"); + } finally { + try { + is.close(); + } catch (IOException e) { + Log.w(TAG, "Failed to close input stream"); + } + } } @Override diff --git a/native/Android.mk b/native/Android.mk index 260ca3023..57551097b 100644 --- a/native/Android.mk +++ b/native/Android.mk @@ -11,15 +11,8 @@ LOCAL_SRC_FILES := \ LOCAL_C_INCLUDES += \ $(JNI_H_INCLUDE) -LOCAL_LDLIBS := -lm - LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES := \ - libandroid_runtime \ - libcutils \ - libutils - LOCAL_MODULE := libjni_latinime2 LOCAL_MODULE_TAGS := optional diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index d068f3faf..bb45cb538 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -15,31 +15,18 @@ ** limitations under the License. */ -#define LOG_TAG "BinaryDictionary" -#include "utils/Log.h" - #include #include #include #include -#include -#include "utils/AssetManager.h" -#include "utils/Asset.h" - +#include #include "dictionary.h" // ---------------------------------------------------------------------------- using namespace latinime; -using namespace android; - -static jfieldID sDescriptorField; -static jfieldID sAssetManagerNativeField; -static jmethodID sAddWordMethod; -static jfieldID sDictLength; - // // helper function to throw an exception // @@ -54,35 +41,15 @@ static void throwException(JNIEnv *env, const char* ex, const char* fmt, int dat } static jint latinime_BinaryDictionary_open - (JNIEnv *env, jobject object, jobject assetManager, jstring resourceString, + (JNIEnv *env, jobject object, jobject dictDirectBuffer, jint typedLetterMultiplier, jint fullWordMultiplier) { - // Get the native file descriptor from the FileDescriptor object - AssetManager *am = (AssetManager*) env->GetIntField(assetManager, sAssetManagerNativeField); - if (!am) { - LOGE("DICT: Couldn't get AssetManager native peer\n"); - return 0; - } - const char *resourcePath = env->GetStringUTFChars(resourceString, NULL); - - Asset *dictAsset = am->openNonAsset(resourcePath, Asset::ACCESS_BUFFER); - if (dictAsset == NULL) { - LOGE("DICT: Couldn't get asset %s\n", resourcePath); - env->ReleaseStringUTFChars(resourceString, resourcePath); - return 0; - } - - void *dict = (void*) dictAsset->getBuffer(false); + void *dict = env->GetDirectBufferAddress(dictDirectBuffer); if (dict == NULL) { - LOGE("DICT: Dictionary buffer is null\n"); - env->ReleaseStringUTFChars(resourceString, resourcePath); + fprintf(stderr, "DICT: Dictionary buffer is null\n"); return 0; } Dictionary *dictionary = new Dictionary(dict, typedLetterMultiplier, fullWordMultiplier); - dictionary->setAsset(dictAsset); - env->SetIntField(object, sDictLength, (jint) dictAsset->getLength()); - - env->ReleaseStringUTFChars(resourceString, resourcePath); return (jint) dictionary; } @@ -131,14 +98,13 @@ static void latinime_BinaryDictionary_close (JNIEnv *env, jobject object, jint dict) { Dictionary *dictionary = (Dictionary*) dict; - ((Asset*) dictionary->getAsset())->close(); delete (Dictionary*) dict; } // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { - {"openNative", "(Landroid/content/res/AssetManager;Ljava/lang/String;II)I", + {"openNative", "(Ljava/nio/ByteBuffer;II)I", (void*)latinime_BinaryDictionary_open}, {"closeNative", "(I)V", (void*)latinime_BinaryDictionary_close}, {"getSuggestionsNative", "(I[II[C[IIIII[II)I", (void*)latinime_BinaryDictionary_getSuggestions}, @@ -167,30 +133,6 @@ static int registerNativeMethods(JNIEnv* env, const char* className, static int registerNatives(JNIEnv *env) { const char* const kClassPathName = "com/android/inputmethod/latin/BinaryDictionary"; - jclass clazz; - - clazz = env->FindClass("java/io/FileDescriptor"); - if (clazz == NULL) { - LOGE("Can't find %s", "java/io/FileDescriptor"); - return -1; - } - sDescriptorField = env->GetFieldID(clazz, "descriptor", "I"); - - clazz = env->FindClass("android/content/res/AssetManager"); - if (clazz == NULL) { - LOGE("Can't find %s", "java/io/FileDescriptor"); - return -1; - } - sAssetManagerNativeField = env->GetFieldID(clazz, "mObject", "I"); - - // Get the field pointer for the dictionary length - clazz = env->FindClass(kClassPathName); - if (clazz == NULL) { - LOGE("Can't find %s", kClassPathName); - return -1; - } - sDictLength = env->GetFieldID(clazz, "mDictLength", "I"); - return registerNativeMethods(env, kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0])); } diff --git a/native/src/dictionary.cpp b/native/src/dictionary.cpp index 3f196a9ed..e75beb5b7 100644 --- a/native/src/dictionary.cpp +++ b/native/src/dictionary.cpp @@ -19,14 +19,8 @@ #include #include #include -#include - -//#define USE_ASSET_MANAGER - -#ifdef USE_ASSET_MANAGER -#include -#include -#endif +//#include +#define LOGI #include "dictionary.h" #include "basechars.h"