• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.pinyin;
18 
19 import com.android.inputmethod.pinyin.IPinyinDecoderService;
20 
21 import java.io.FileDescriptor;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.util.List;
25 import java.util.Vector;
26 
27 import android.app.Service;
28 import android.content.Intent;
29 import android.content.res.AssetFileDescriptor;
30 import android.os.IBinder;
31 import android.os.RemoteException;
32 import android.util.Log;
33 
34 /**
35  * This class is used to separate the input method kernel in an individual
36  * service so that both IME and IME-syncer can use it.
37  */
38 public class PinyinDecoderService extends Service {
nativeImOpenDecoder(byte fn_sys_dict[], byte fn_usr_dict[])39     native static boolean nativeImOpenDecoder(byte fn_sys_dict[],
40             byte fn_usr_dict[]);
41 
nativeImOpenDecoderFd(FileDescriptor fd, long startOffset, long length, byte fn_usr_dict[])42     native static boolean nativeImOpenDecoderFd(FileDescriptor fd,
43             long startOffset, long length, byte fn_usr_dict[]);
44 
nativeImSetMaxLens(int maxSpsLen, int maxHzsLen)45     native static void nativeImSetMaxLens(int maxSpsLen, int maxHzsLen);
46 
nativeImCloseDecoder()47     native static boolean nativeImCloseDecoder();
48 
nativeImSearch(byte pyBuf[], int pyLen)49     native static int nativeImSearch(byte pyBuf[], int pyLen);
50 
nativeImDelSearch(int pos, boolean is_pos_in_splid, boolean clear_fixed_this_step)51     native static int nativeImDelSearch(int pos, boolean is_pos_in_splid,
52             boolean clear_fixed_this_step);
53 
nativeImResetSearch()54     native static void nativeImResetSearch();
55 
nativeImAddLetter(byte ch)56     native static int nativeImAddLetter(byte ch);
57 
nativeImGetPyStr(boolean decoded)58     native static String nativeImGetPyStr(boolean decoded);
59 
nativeImGetPyStrLen(boolean decoded)60     native static int nativeImGetPyStrLen(boolean decoded);
61 
nativeImGetSplStart()62     native static int[] nativeImGetSplStart();
63 
nativeImGetChoice(int choiceId)64     native static String nativeImGetChoice(int choiceId);
65 
nativeImChoose(int choiceId)66     native static int nativeImChoose(int choiceId);
67 
nativeImCancelLastChoice()68     native static int nativeImCancelLastChoice();
69 
nativeImGetFixedLen()70     native static int nativeImGetFixedLen();
71 
nativeImCancelInput()72     native static boolean nativeImCancelInput();
73 
nativeImFlushCache()74     native static boolean nativeImFlushCache();
75 
nativeImGetPredictsNum(String fixedStr)76     native static int nativeImGetPredictsNum(String fixedStr);
77 
nativeImGetPredictItem(int predictNo)78     native static String nativeImGetPredictItem(int predictNo);
79 
80     // Sync related
nativeSyncUserDict(byte[] user_dict, String tomerge)81     native static String nativeSyncUserDict(byte[] user_dict, String tomerge);
82 
nativeSyncBegin(byte[] user_dict)83     native static boolean nativeSyncBegin(byte[] user_dict);
84 
nativeSyncFinish()85     native static boolean nativeSyncFinish();
86 
nativeSyncGetLemmas()87     native static String nativeSyncGetLemmas();
88 
nativeSyncPutLemmas(String tomerge)89     native static int nativeSyncPutLemmas(String tomerge);
90 
nativeSyncGetLastCount()91     native static int nativeSyncGetLastCount();
92 
nativeSyncGetTotalCount()93     native static int nativeSyncGetTotalCount();
94 
nativeSyncClearLastGot()95     native static boolean nativeSyncClearLastGot();
96 
nativeSyncGetCapacity()97     native static int nativeSyncGetCapacity();
98 
99     private final static int MAX_PATH_FILE_LENGTH = 100;
100     private static boolean inited = false;
101 
102     private String mUsr_dict_file;
103 
104     static {
105         try {
106             System.loadLibrary("jni_pinyinime");
107         } catch (UnsatisfiedLinkError ule) {
108             Log.e("PinyinDecoderService",
109                     "WARNING: Could not load jni_pinyinime natives");
110         }
111     }
112 
113     // Get file name of the specified dictionary
getUsrDictFileName(byte usr_dict[])114     private boolean getUsrDictFileName(byte usr_dict[]) {
115         if (null == usr_dict) {
116             return false;
117         }
118 
119         for (int i = 0; i < mUsr_dict_file.length(); i++)
120             usr_dict[i] = (byte) mUsr_dict_file.charAt(i);
121         usr_dict[mUsr_dict_file.length()] = 0;
122 
123         return true;
124     }
125 
initPinyinEngine()126     private void initPinyinEngine() {
127         byte usr_dict[];
128         usr_dict = new byte[MAX_PATH_FILE_LENGTH];
129 
130         // Here is how we open a built-in dictionary for access through
131         // a file descriptor...
132         AssetFileDescriptor afd = getResources().openRawResourceFd(
133                 R.raw.dict_pinyin);
134         if (Environment.getInstance().needDebug()) {
135             Log
136                     .i("foo", "Dict: start=" + afd.getStartOffset()
137                             + ", length=" + afd.getLength() + ", fd="
138                             + afd.getParcelFileDescriptor());
139         }
140         if (getUsrDictFileName(usr_dict)) {
141             inited = nativeImOpenDecoderFd(afd.getFileDescriptor(), afd
142                     .getStartOffset(), afd.getLength(), usr_dict);
143         }
144         try {
145             afd.close();
146         } catch (IOException e) {
147         }
148     }
149 
150     @Override
onCreate()151     public void onCreate() {
152         super.onCreate();
153         mUsr_dict_file = getFileStreamPath("usr_dict.dat").getPath();
154         // This is a hack to make sure our "files" directory has been
155         // created.
156         try {
157             openFileOutput("dummy", 0).close();
158         } catch (FileNotFoundException e) {
159         } catch (IOException e) {
160         }
161 
162         initPinyinEngine();
163     }
164 
165     @Override
onDestroy()166     public void onDestroy() {
167         nativeImCloseDecoder();
168         inited = false;
169         super.onDestroy();
170     }
171 
172     private final IPinyinDecoderService.Stub mBinder = new IPinyinDecoderService.Stub() {
173         public int getInt() {
174             return 12345;
175         }
176 
177         public void setMaxLens(int maxSpsLen, int maxHzsLen) {
178             nativeImSetMaxLens(maxSpsLen, maxHzsLen);
179         }
180 
181         public int imSearch(byte[] pyBuf, int pyLen) {
182             return nativeImSearch(pyBuf, pyLen);
183         }
184 
185         public int imDelSearch(int pos, boolean is_pos_in_splid,
186                 boolean clear_fixed_this_step) {
187             return nativeImDelSearch(pos, is_pos_in_splid,
188                     clear_fixed_this_step);
189         }
190 
191         public void imResetSearch() {
192             nativeImResetSearch();
193         }
194 
195         public int imAddLetter(byte ch) {
196             return nativeImAddLetter(ch);
197         }
198 
199         public String imGetPyStr(boolean decoded) {
200             return nativeImGetPyStr(decoded);
201         }
202 
203         public int imGetPyStrLen(boolean decoded) {
204             return nativeImGetPyStrLen(decoded);
205         }
206 
207         public int[] imGetSplStart() {
208             return nativeImGetSplStart();
209         }
210 
211         public String imGetChoice(int choiceId) {
212             return nativeImGetChoice(choiceId);
213         }
214 
215         public String imGetChoices(int choicesNum) {
216             String retStr = null;
217             for (int i = 0; i < choicesNum; i++) {
218                 if (null == retStr)
219                     retStr = nativeImGetChoice(i);
220                 else
221                     retStr += " " + nativeImGetChoice(i);
222             }
223             return retStr;
224         }
225 
226         public List<String> imGetChoiceList(int choicesStart, int choicesNum,
227                 int sentFixedLen) {
228             Vector<String> choiceList = new Vector<String>();
229             for (int i = choicesStart; i < choicesStart + choicesNum; i++) {
230                 String retStr = nativeImGetChoice(i);
231                 if (0 == i) retStr = retStr.substring(sentFixedLen);
232                 choiceList.add(retStr);
233             }
234             return choiceList;
235         }
236 
237         public int imChoose(int choiceId) {
238             return nativeImChoose(choiceId);
239         }
240 
241         public int imCancelLastChoice() {
242             return nativeImCancelLastChoice();
243         }
244 
245         public int imGetFixedLen() {
246             return nativeImGetFixedLen();
247         }
248 
249         public boolean imCancelInput() {
250             return nativeImCancelInput();
251         }
252 
253         public void imFlushCache() {
254             nativeImFlushCache();
255         }
256 
257         public int imGetPredictsNum(String fixedStr) {
258             return nativeImGetPredictsNum(fixedStr);
259         }
260 
261         public String imGetPredictItem(int predictNo) {
262             return nativeImGetPredictItem(predictNo);
263         }
264 
265         public List<String> imGetPredictList(int predictsStart, int predictsNum) {
266             Vector<String> predictList = new Vector<String>();
267             for (int i = predictsStart; i < predictsStart + predictsNum; i++) {
268                 predictList.add(nativeImGetPredictItem(i));
269             }
270             return predictList;
271         }
272 
273         public String syncUserDict(String tomerge) {
274             byte usr_dict[];
275             usr_dict = new byte[MAX_PATH_FILE_LENGTH];
276 
277             if (getUsrDictFileName(usr_dict)) {
278                 return nativeSyncUserDict(usr_dict, tomerge);
279             }
280             return null;
281         }
282 
283         public boolean syncBegin() {
284             byte usr_dict[];
285             usr_dict = new byte[MAX_PATH_FILE_LENGTH];
286 
287             if (getUsrDictFileName(usr_dict)) {
288                 return nativeSyncBegin(usr_dict);
289             }
290             return false;
291         }
292 
293         public void syncFinish() {
294             nativeSyncFinish();
295         }
296 
297         public int syncPutLemmas(String tomerge) {
298             return nativeSyncPutLemmas(tomerge);
299         }
300 
301         public String syncGetLemmas() {
302             return nativeSyncGetLemmas();
303         }
304 
305         public int syncGetLastCount() {
306             return nativeSyncGetLastCount();
307         }
308 
309         public int syncGetTotalCount() {
310             return nativeSyncGetTotalCount();
311         }
312 
313         public void syncClearLastGot() {
314             nativeSyncClearLastGot();
315         }
316 
317         public int imSyncGetCapacity() {
318             return nativeSyncGetCapacity();
319         }
320     };
321 
322     @Override
onBind(Intent intent)323     public IBinder onBind(Intent intent) {
324         return mBinder;
325     }
326 }
327