summaryrefslogtreecommitdiff
path: root/src/com/android/inputmethod/pinyin/PinyinDecoderService.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/inputmethod/pinyin/PinyinDecoderService.java')
-rw-r--r--src/com/android/inputmethod/pinyin/PinyinDecoderService.java326
1 files changed, 326 insertions, 0 deletions
diff --git a/src/com/android/inputmethod/pinyin/PinyinDecoderService.java b/src/com/android/inputmethod/pinyin/PinyinDecoderService.java
new file mode 100644
index 0000000..a4a3ac4
--- /dev/null
+++ b/src/com/android/inputmethod/pinyin/PinyinDecoderService.java
@@ -0,0 +1,326 @@
+/*
+ * 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 com.android.inputmethod.pinyin;
+
+import com.android.inputmethod.pinyin.IPinyinDecoderService;
+
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+import java.util.Vector;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.AssetFileDescriptor;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * This class is used to separate the input method kernel in an individual
+ * service so that both IME and IME-syncer can use it.
+ */
+public class PinyinDecoderService extends Service {
+ native static boolean nativeImOpenDecoder(byte fn_sys_dict[],
+ byte fn_usr_dict[]);
+
+ native static boolean nativeImOpenDecoderFd(FileDescriptor fd,
+ long startOffset, long length, byte fn_usr_dict[]);
+
+ native static void nativeImSetMaxLens(int maxSpsLen, int maxHzsLen);
+
+ native static boolean nativeImCloseDecoder();
+
+ native static int nativeImSearch(byte pyBuf[], int pyLen);
+
+ native static int nativeImDelSearch(int pos, boolean is_pos_in_splid,
+ boolean clear_fixed_this_step);
+
+ native static void nativeImResetSearch();
+
+ native static int nativeImAddLetter(byte ch);
+
+ native static String nativeImGetPyStr(boolean decoded);
+
+ native static int nativeImGetPyStrLen(boolean decoded);
+
+ native static int[] nativeImGetSplStart();
+
+ native static String nativeImGetChoice(int choiceId);
+
+ native static int nativeImChoose(int choiceId);
+
+ native static int nativeImCancelLastChoice();
+
+ native static int nativeImGetFixedLen();
+
+ native static boolean nativeImCancelInput();
+
+ native static boolean nativeImFlushCache();
+
+ native static int nativeImGetPredictsNum(String fixedStr);
+
+ native static String nativeImGetPredictItem(int predictNo);
+
+ // Sync related
+ native static String nativeSyncUserDict(byte[] user_dict, String tomerge);
+
+ native static boolean nativeSyncBegin(byte[] user_dict);
+
+ native static boolean nativeSyncFinish();
+
+ native static String nativeSyncGetLemmas();
+
+ native static int nativeSyncPutLemmas(String tomerge);
+
+ native static int nativeSyncGetLastCount();
+
+ native static int nativeSyncGetTotalCount();
+
+ native static boolean nativeSyncClearLastGot();
+
+ native static int nativeSyncGetCapacity();
+
+ private final static int MAX_PATH_FILE_LENGTH = 100;
+ private static boolean inited = false;
+
+ private String mUsr_dict_file;
+
+ static {
+ try {
+ System.loadLibrary("jni_pinyinime");
+ } catch (UnsatisfiedLinkError ule) {
+ Log.e("PinyinDecoderService",
+ "WARNING: Could not load jni_pinyinime natives");
+ }
+ }
+
+ // Get file name of the specified dictionary
+ private boolean getUsrDictFileName(byte usr_dict[]) {
+ if (null == usr_dict) {
+ return false;
+ }
+
+ for (int i = 0; i < mUsr_dict_file.length(); i++)
+ usr_dict[i] = (byte) mUsr_dict_file.charAt(i);
+ usr_dict[mUsr_dict_file.length()] = 0;
+
+ return true;
+ }
+
+ private void initPinyinEngine() {
+ byte usr_dict[];
+ usr_dict = new byte[MAX_PATH_FILE_LENGTH];
+
+ // Here is how we open a built-in dictionary for access through
+ // a file descriptor...
+ AssetFileDescriptor afd = getResources().openRawResourceFd(
+ R.raw.dict_pinyin);
+ if (Environment.getInstance().needDebug()) {
+ Log
+ .i("foo", "Dict: start=" + afd.getStartOffset()
+ + ", length=" + afd.getLength() + ", fd="
+ + afd.getParcelFileDescriptor());
+ }
+ if (getUsrDictFileName(usr_dict)) {
+ inited = nativeImOpenDecoderFd(afd.getFileDescriptor(), afd
+ .getStartOffset(), afd.getLength(), usr_dict);
+ }
+ try {
+ afd.close();
+ } catch (IOException e) {
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mUsr_dict_file = getFileStreamPath("usr_dict.dat").getPath();
+ // This is a hack to make sure our "files" directory has been
+ // created.
+ try {
+ openFileOutput("dummy", 0).close();
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ }
+
+ initPinyinEngine();
+ }
+
+ @Override
+ public void onDestroy() {
+ nativeImCloseDecoder();
+ inited = false;
+ super.onDestroy();
+ }
+
+ private final IPinyinDecoderService.Stub mBinder = new IPinyinDecoderService.Stub() {
+ public int getInt() {
+ return 12345;
+ }
+
+ public void setMaxLens(int maxSpsLen, int maxHzsLen) {
+ nativeImSetMaxLens(maxSpsLen, maxHzsLen);
+ }
+
+ public int imSearch(byte[] pyBuf, int pyLen) {
+ return nativeImSearch(pyBuf, pyLen);
+ }
+
+ public int imDelSearch(int pos, boolean is_pos_in_splid,
+ boolean clear_fixed_this_step) {
+ return nativeImDelSearch(pos, is_pos_in_splid,
+ clear_fixed_this_step);
+ }
+
+ public void imResetSearch() {
+ nativeImResetSearch();
+ }
+
+ public int imAddLetter(byte ch) {
+ return nativeImAddLetter(ch);
+ }
+
+ public String imGetPyStr(boolean decoded) {
+ return nativeImGetPyStr(decoded);
+ }
+
+ public int imGetPyStrLen(boolean decoded) {
+ return nativeImGetPyStrLen(decoded);
+ }
+
+ public int[] imGetSplStart() {
+ return nativeImGetSplStart();
+ }
+
+ public String imGetChoice(int choiceId) {
+ return nativeImGetChoice(choiceId);
+ }
+
+ public String imGetChoices(int choicesNum) {
+ String retStr = null;
+ for (int i = 0; i < choicesNum; i++) {
+ if (null == retStr)
+ retStr = nativeImGetChoice(i);
+ else
+ retStr += " " + nativeImGetChoice(i);
+ }
+ return retStr;
+ }
+
+ public List<String> imGetChoiceList(int choicesStart, int choicesNum,
+ int sentFixedLen) {
+ Vector<String> choiceList = new Vector<String>();
+ for (int i = choicesStart; i < choicesStart + choicesNum; i++) {
+ String retStr = nativeImGetChoice(i);
+ if (0 == i) retStr = retStr.substring(sentFixedLen);
+ choiceList.add(retStr);
+ }
+ return choiceList;
+ }
+
+ public int imChoose(int choiceId) {
+ return nativeImChoose(choiceId);
+ }
+
+ public int imCancelLastChoice() {
+ return nativeImCancelLastChoice();
+ }
+
+ public int imGetFixedLen() {
+ return nativeImGetFixedLen();
+ }
+
+ public boolean imCancelInput() {
+ return nativeImCancelInput();
+ }
+
+ public void imFlushCache() {
+ nativeImFlushCache();
+ }
+
+ public int imGetPredictsNum(String fixedStr) {
+ return nativeImGetPredictsNum(fixedStr);
+ }
+
+ public String imGetPredictItem(int predictNo) {
+ return nativeImGetPredictItem(predictNo);
+ }
+
+ public List<String> imGetPredictList(int predictsStart, int predictsNum) {
+ Vector<String> predictList = new Vector<String>();
+ for (int i = predictsStart; i < predictsStart + predictsNum; i++) {
+ predictList.add(nativeImGetPredictItem(i));
+ }
+ return predictList;
+ }
+
+ public String syncUserDict(String tomerge) {
+ byte usr_dict[];
+ usr_dict = new byte[MAX_PATH_FILE_LENGTH];
+
+ if (getUsrDictFileName(usr_dict)) {
+ return nativeSyncUserDict(usr_dict, tomerge);
+ }
+ return null;
+ }
+
+ public boolean syncBegin() {
+ byte usr_dict[];
+ usr_dict = new byte[MAX_PATH_FILE_LENGTH];
+
+ if (getUsrDictFileName(usr_dict)) {
+ return nativeSyncBegin(usr_dict);
+ }
+ return false;
+ }
+
+ public void syncFinish() {
+ nativeSyncFinish();
+ }
+
+ public int syncPutLemmas(String tomerge) {
+ return nativeSyncPutLemmas(tomerge);
+ }
+
+ public String syncGetLemmas() {
+ return nativeSyncGetLemmas();
+ }
+
+ public int syncGetLastCount() {
+ return nativeSyncGetLastCount();
+ }
+
+ public int syncGetTotalCount() {
+ return nativeSyncGetTotalCount();
+ }
+
+ public void syncClearLastGot() {
+ nativeSyncClearLastGot();
+ }
+
+ public int imSyncGetCapacity() {
+ return nativeSyncGetCapacity();
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+}