BinaryDictionary.java revision 4250eb27f54f8fedc388fe4825b0646a88778744
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/*
2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project
3e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa *
4923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of
6923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License at
7e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa *
8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0
9e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa *
10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * License for the specific language governing permissions and limitations under
14923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License.
15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */
16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
17923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpackage com.android.inputmethod.latin;
18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
196f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard;
208fbd55229243cb66c03d5ea1f79dfb39f596590dsatokimport com.android.inputmethod.keyboard.KeyboardSwitcher;
218fbd55229243cb66c03d5ea1f79dfb39f596590dsatokimport com.android.inputmethod.keyboard.ProximityInfo;
228fbd55229243cb66c03d5ea1f79dfb39f596590dsatok
23fa086c90760bc2bedf0b74eacb0fed3bf7ebc2b7Tadashi G. Takaokaimport android.content.Context;
24fa086c90760bc2bedf0b74eacb0fed3bf7ebc2b7Tadashi G. Takaoka
25923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport java.util.Arrays;
26923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
27923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/**
28923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Implements a static, compacted, binary dictionary of standard words.
29923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */
30923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpublic class BinaryDictionary extends Dictionary {
31923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
32cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard    public static final String DICTIONARY_PACK_AUTHORITY =
33cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard            "com.android.inputmethod.latin.dictionarypack";
34cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard
35979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    /**
36cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard     * There is a difference between what java and native code can handle.
37979f8690967ff5409fe18f5085858ccdb8e0ccf1satok     * This value should only be used in BinaryDictionary.java
38979f8690967ff5409fe18f5085858ccdb8e0ccf1satok     * It is necessary to keep it at this value because some languages e.g. German have
39979f8690967ff5409fe18f5085858ccdb8e0ccf1satok     * really long words.
40979f8690967ff5409fe18f5085858ccdb8e0ccf1satok     */
418fbd55229243cb66c03d5ea1f79dfb39f596590dsatok    public static final int MAX_WORD_LENGTH = 48;
422e04770adfc16344f69d316efd3ed0a617ede330Tadashi G. Takaoka    public static final int MAX_WORDS = 18;
43979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
444250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard    @SuppressWarnings("unused")
45979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final String TAG = "BinaryDictionary";
468fbd55229243cb66c03d5ea1f79dfb39f596590dsatok    private static final int MAX_PROXIMITY_CHARS_SIZE = ProximityInfo.MAX_PROXIMITY_CHARS_SIZE;
47979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final int MAX_BIGRAMS = 60;
48923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
49923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final int TYPED_LETTER_MULTIPLIER = 2;
50923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
51979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private int mDicTypeId;
52923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mNativeDict;
538fbd55229243cb66c03d5ea1f79dfb39f596590dsatok    private final int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_PROXIMITY_CHARS_SIZE];
5430088259480130e5bac5c2028e2c7c3e6d4c51a2satok    private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
5530088259480130e5bac5c2028e2c7c3e6d4c51a2satok    private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS];
56e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka    private final int[] mScores = new int[MAX_WORDS];
57e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka    private final int[] mBigramScores = new int[MAX_BIGRAMS];
58923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
598fbd55229243cb66c03d5ea1f79dfb39f596590dsatok    private final KeyboardSwitcher mKeyboardSwitcher = KeyboardSwitcher.getInstance();
60071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka
61071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka    public static final Flag FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING =
62c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard            new Flag(R.bool.config_require_umlaut_processing, 0x1);
63c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard
64c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard    // Can create a new flag from extravalue :
65c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard    // public static final Flag FLAG_MYFLAG =
66c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard    //         new Flag("my_flag", 0x02);
67071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka
68071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka    private static final Flag[] ALL_FLAGS = {
69071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka        // Here should reside all flags that trigger some special processing
70071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka        // These *must* match the definition in UnigramDictionary enum in
71071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka        // unigram_dictionary.h so please update both at the same time.
72071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka        FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING,
73071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka    };
74071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka
75c2bbc6a4499a6da979381fa0e8e6e855a5ac6aa4Jean Chalard    private int mFlags = 0;
76923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
77923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
784250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard     * Constructor for the binary dictionary. This is supposed to be called from the
794250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard     * dictionary factory.
804250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard     * All implementations should pass null into flagArray, except for testing purposes.
814250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard     * @param context the context to access the environment from.
824250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard     * @param filename the name of the file to read through native code.
834250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard     * @param offset the offset of the dictionary data within the file.
844250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard     * @param length the length of the binary data.
854250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard     * @param flagArray the flags to limit the dictionary to, or null for default.
86923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
874250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard    public BinaryDictionary(final Context context,
884250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard            final String filename, final long offset, final long length, Flag[] flagArray) {
894250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard        // Note: at the moment a binary dictionary is always of the "main" type.
904250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard        // Initializing this here will help transitioning out of the scheme where
914250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard        // the Suggest class knows everything about every single dictionary.
924250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard        mDicTypeId = Suggest.DIC_MAIN;
934250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard        // TODO: Stop relying on the state of SubtypeSwitcher, get it as a parameter
944250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard        mFlags = Flag.initFlags(null == flagArray ? ALL_FLAGS : flagArray, context,
954250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard                SubtypeSwitcher.getInstance());
964250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard        loadDictionary(filename, offset, length);
97979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
98979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
99eaef1c500703b4ee378821884c7b108815ed2983Ken Wakasa    static {
100eaef1c500703b4ee378821884c7b108815ed2983Ken Wakasa        Utils.loadNativeLibrary();
101eaef1c500703b4ee378821884c7b108815ed2983Ken Wakasa    }
102c2bbc6a4499a6da979381fa0e8e6e855a5ac6aa4Jean Chalard
10390d96615bcb71af7ccbb2318b588aa78c4308e5aKen Wakasa    private native int openNative(String sourceDir, long dictOffset, long dictSize,
104e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa            int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength,
105e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa            int maxWords, int maxAlternatives);
106923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private native void closeNative(int dict);
107923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private native boolean isValidWordNative(int nativeData, char[] word, int wordLength);
1088fbd55229243cb66c03d5ea1f79dfb39f596590dsatok    private native int getSuggestionsNative(int dict, int proximityInfo, int[] xCoordinates,
109c2bbc6a4499a6da979381fa0e8e6e855a5ac6aa4Jean Chalard            int[] yCoordinates, int[] inputCodes, int codesSize, int flags, char[] outputChars,
110e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka            int[] scores);
111979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength,
112e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka            int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores,
113979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            int maxWordLength, int maxBigrams, int maxAlternatives);
114979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
11533e0b1e79e464ac48a09433bbfcbb17ded620452Tadashi G. Takaoka    private final void loadDictionary(String path, long startOffset, long length) {
11633e0b1e79e464ac48a09433bbfcbb17ded620452Tadashi G. Takaoka        mNativeDict = openNative(path, startOffset, length,
117e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka                    TYPED_LETTER_MULTIPLIER, FULL_WORD_SCORE_MULTIPLIER,
1188fbd55229243cb66c03d5ea1f79dfb39f596590dsatok                    MAX_WORD_LENGTH, MAX_WORDS, MAX_PROXIMITY_CHARS_SIZE);
119979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
120979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
121979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    @Override
122979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    public void getBigrams(final WordComposer codes, final CharSequence previousWord,
123887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaoka            final WordCallback callback) {
124da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa        if (mNativeDict == 0) return;
125da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa
126979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        char[] chars = previousWord.toString().toCharArray();
127979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        Arrays.fill(mOutputChars_bigrams, (char) 0);
128e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka        Arrays.fill(mBigramScores, 0);
129979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
130979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        int codesSize = codes.size();
13189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard        if (codesSize <= 0) {
13289bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard            // Do not return bigrams from BinaryDictionary when nothing was typed.
13389bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard            // Only use user-history bigrams (or whatever other bigram dictionaries decide).
13489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard            return;
13589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard        }
136979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        Arrays.fill(mInputCodes, -1);
137979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        int[] alternatives = codes.getCodesAt(0);
138979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        System.arraycopy(alternatives, 0, mInputCodes, 0,
1398fbd55229243cb66c03d5ea1f79dfb39f596590dsatok                Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE));
140979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
141979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        int count = getBigramsNative(mNativeDict, chars, chars.length, mInputCodes, codesSize,
142e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka                mOutputChars_bigrams, mBigramScores, MAX_WORD_LENGTH, MAX_BIGRAMS,
1438fbd55229243cb66c03d5ea1f79dfb39f596590dsatok                MAX_PROXIMITY_CHARS_SIZE);
144979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
145f5cded1c6cf0f39df13750d4f9f5ba66c1b32964satok        for (int j = 0; j < count; ++j) {
146e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka            if (mBigramScores[j] < 1) break;
147f5cded1c6cf0f39df13750d4f9f5ba66c1b32964satok            final int start = j * MAX_WORD_LENGTH;
148979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            int len = 0;
149f5cded1c6cf0f39df13750d4f9f5ba66c1b32964satok            while (len <  MAX_WORD_LENGTH && mOutputChars_bigrams[start + len] != 0) {
150f5cded1c6cf0f39df13750d4f9f5ba66c1b32964satok                ++len;
151979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            }
152979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            if (len > 0) {
153e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka                callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j],
154979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                        mDicTypeId, DataType.BIGRAM);
155979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            }
156979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        }
157923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
158923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
159923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    @Override
160887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaoka    public void getWords(final WordComposer codes, final WordCallback callback) {
1612e04770adfc16344f69d316efd3ed0a617ede330Tadashi G. Takaoka        final int count = getSuggestions(codes, mKeyboardSwitcher.getLatinKeyboard(),
162e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka                mOutputChars, mScores);
1636f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka
1646f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka        for (int j = 0; j < count; ++j) {
165e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka            if (mScores[j] < 1) break;
1666f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka            final int start = j * MAX_WORD_LENGTH;
1676f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka            int len = 0;
1686f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka            while (len < MAX_WORD_LENGTH && mOutputChars[start + len] != 0) {
1696f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka                ++len;
1706f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka            }
1716f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka            if (len > 0) {
172e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka                callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId,
1736f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka                        DataType.UNIGRAM);
1746f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka            }
1756f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka        }
1766f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka    }
1776f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka
1786f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka    /* package for test */ boolean isValidDictionary() {
1796f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka        return mNativeDict != 0;
1806f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka    }
1816f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka
1822e04770adfc16344f69d316efd3ed0a617ede330Tadashi G. Takaoka    /* package for test */ int getSuggestions(final WordComposer codes, final Keyboard keyboard,
183e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka            char[] outputChars, int[] scores) {
1846f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka        if (!isValidDictionary()) return -1;
185da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa
186923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final int codesSize = codes.size();
187979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        // Won't deal with really long words.
1886f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka        if (codesSize > MAX_WORD_LENGTH - 1) return -1;
18930088259480130e5bac5c2028e2c7c3e6d4c51a2satok
190887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaoka        Arrays.fill(mInputCodes, WordComposer.NOT_A_CODE);
191923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        for (int i = 0; i < codesSize; i++) {
192923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            int[] alternatives = codes.getCodesAt(i);
1938fbd55229243cb66c03d5ea1f79dfb39f596590dsatok            System.arraycopy(alternatives, 0, mInputCodes, i * MAX_PROXIMITY_CHARS_SIZE,
1948fbd55229243cb66c03d5ea1f79dfb39f596590dsatok                    Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE));
195923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
1962e04770adfc16344f69d316efd3ed0a617ede330Tadashi G. Takaoka        Arrays.fill(outputChars, (char) 0);
197e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka        Arrays.fill(scores, 0);
198c3df2d6fd27f3a5b84040b59aece3367769f0cb6Amith Yamasani
1996f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka        return getSuggestionsNative(
2006f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka                mNativeDict, keyboard.getProximityInfo(),
2018fbd55229243cb66c03d5ea1f79dfb39f596590dsatok                codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize,
202e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka                mFlags, outputChars, scores);
203923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
204923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
205923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    @Override
206923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public boolean isValidWord(CharSequence word) {
207923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (word == null) return false;
208f590a497393eb77875017010e9a36cf33b095e3cAmith Yamasani        char[] chars = word.toString().toCharArray();
209923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return isValidWordNative(mNativeDict, chars, chars.length);
210923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
211c3df2d6fd27f3a5b84040b59aece3367769f0cb6Amith Yamasani
21236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    @Override
213923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public synchronized void close() {
214da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa        closeInternal();
215da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa    }
216da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa
217da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa    private void closeInternal() {
218923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (mNativeDict != 0) {
219923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            closeNative(mNativeDict);
220923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mNativeDict = 0;
221923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
222923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
223923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
224923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    @Override
225923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    protected void finalize() throws Throwable {
226da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa        try {
227da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa            closeInternal();
228da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa        } finally {
229da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa            super.finalize();
230da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa        }
231923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
232923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project}
233