/*
* 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;
}
}
|