Home | History | Annotate | Download | only in pinyin
      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 {
     39     native static boolean nativeImOpenDecoder(byte fn_sys_dict[],
     40             byte fn_usr_dict[]);
     41 
     42     native static boolean nativeImOpenDecoderFd(FileDescriptor fd,
     43             long startOffset, long length, byte fn_usr_dict[]);
     44 
     45     native static void nativeImSetMaxLens(int maxSpsLen, int maxHzsLen);
     46 
     47     native static boolean nativeImCloseDecoder();
     48 
     49     native static int nativeImSearch(byte pyBuf[], int pyLen);
     50 
     51     native static int nativeImDelSearch(int pos, boolean is_pos_in_splid,
     52             boolean clear_fixed_this_step);
     53 
     54     native static void nativeImResetSearch();
     55 
     56     native static int nativeImAddLetter(byte ch);
     57 
     58     native static String nativeImGetPyStr(boolean decoded);
     59 
     60     native static int nativeImGetPyStrLen(boolean decoded);
     61 
     62     native static int[] nativeImGetSplStart();
     63 
     64     native static String nativeImGetChoice(int choiceId);
     65 
     66     native static int nativeImChoose(int choiceId);
     67 
     68     native static int nativeImCancelLastChoice();
     69 
     70     native static int nativeImGetFixedLen();
     71 
     72     native static boolean nativeImCancelInput();
     73 
     74     native static boolean nativeImFlushCache();
     75 
     76     native static int nativeImGetPredictsNum(String fixedStr);
     77 
     78     native static String nativeImGetPredictItem(int predictNo);
     79 
     80     // Sync related
     81     native static String nativeSyncUserDict(byte[] user_dict, String tomerge);
     82 
     83     native static boolean nativeSyncBegin(byte[] user_dict);
     84 
     85     native static boolean nativeSyncFinish();
     86 
     87     native static String nativeSyncGetLemmas();
     88 
     89     native static int nativeSyncPutLemmas(String tomerge);
     90 
     91     native static int nativeSyncGetLastCount();
     92 
     93     native static int nativeSyncGetTotalCount();
     94 
     95     native static boolean nativeSyncClearLastGot();
     96 
     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
    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 
    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
    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
    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
    323     public IBinder onBind(Intent intent) {
    324         return mBinder;
    325     }
    326 }
    327