From 73680097996ea2ddbca3f84144a00ce3ba66b763 Mon Sep 17 00:00:00 2001
From: Satoshi Kataoka <satok@google.com>
Date: Mon, 25 Jun 2012 17:44:54 +0900
Subject: [PATCH] Change JNI for Gesture

Change-Id: I774a0052038d16677f60f7efa11fd266cb5f3088
---
 .../inputmethod/latin/BinaryDictionary.java   | 45 +++++++++++--------
 .../android/inputmethod/latin/Dictionary.java |  5 ++-
 .../inputmethod/latin/DictionaryFactory.java  |  6 +--
 .../latin/ExpandableBinaryDictionary.java     |  2 +-
 .../latin/ExpandableDictionary.java           |  5 ++-
 .../android/inputmethod/latin/Suggest.java    |  4 +-
 .../com/android/inputmethod/latin/Utils.java  |  2 +-
 .../AndroidSpellCheckerService.java           |  4 +-
 ...oid_inputmethod_latin_BinaryDictionary.cpp | 25 +++++++----
 native/jni/src/dictionary.h                   | 14 +++---
 10 files changed, 68 insertions(+), 44 deletions(-)

diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index d0613bd722..b7a5100210 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -40,6 +40,7 @@ public class BinaryDictionary extends Dictionary {
      */
     public static final int MAX_WORD_LENGTH = 48;
     public static final int MAX_WORDS = 18;
+    public static final int MAX_SPACES = 16;
 
     private static final String TAG = "BinaryDictionary";
     private static final int MAX_BIGRAMS = 60;
@@ -51,6 +52,7 @@ public class BinaryDictionary extends Dictionary {
     private final int[] mInputCodes = new int[MAX_WORD_LENGTH];
     private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
     private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS];
+    private final int[] mSpaceIndices = new int[MAX_SPACES];
     private final int[] mScores = new int[MAX_WORDS];
     private final int[] mBigramScores = new int[MAX_BIGRAMS];
 
@@ -65,14 +67,12 @@ public class BinaryDictionary extends Dictionary {
      * @param offset the offset of the dictionary data within the file.
      * @param length the length of the binary data.
      * @param useFullEditDistance whether to use the full edit distance in suggestions
+     * @param dicTypeId the dictionary type id of the dictionary
      */
     public BinaryDictionary(final Context context,
             final String filename, final long offset, final long length,
-            final boolean useFullEditDistance, final Locale locale) {
-        // Note: at the moment a binary dictionary is always of the "main" type.
-        // Initializing this here will help transitioning out of the scheme where
-        // the Suggest class knows everything about every single dictionary.
-        mDicTypeId = Suggest.DIC_MAIN;
+            final boolean useFullEditDistance, final Locale locale, final int dicTypeId) {
+        mDicTypeId = dicTypeId;
         mUseFullEditDistance = useFullEditDistance;
         loadDictionary(filename, offset, length);
     }
@@ -87,8 +87,10 @@ public class BinaryDictionary extends Dictionary {
     private native int getFrequencyNative(long dict, int[] word, int wordLength);
     private native boolean isValidBigramNative(long dict, int[] word1, int[] word2);
     private native int getSuggestionsNative(long dict, long proximityInfo, int[] xCoordinates,
-            int[] yCoordinates, int[] inputCodes, int codesSize, int[] prevWordForBigrams,
-            boolean useFullEditDistance, char[] outputChars, int[] scores);
+            int[] yCoordinates, int[] times, int[] pointerIds, int[] inputCodes, int codesSize,
+            int commitPoint, boolean isGesture, int dicTypeId,
+            int[] prevWordCodePointArray, boolean useFullEditDistance, char[] outputChars,
+            int[] scores, int[] outputIndices);
     private native int getBigramsNative(long dict, int[] prevWord, int prevWordLength,
             int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores,
             int maxWordLength, int maxBigrams);
@@ -131,7 +133,7 @@ public class BinaryDictionary extends Dictionary {
                 ++len;
             }
             if (len > 0) {
-                callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j],
+                callback.addWord(mOutputChars_bigrams, null, start, len, mBigramScores[j],
                         mDicTypeId, Dictionary.BIGRAM);
             }
         }
@@ -141,9 +143,9 @@ public class BinaryDictionary extends Dictionary {
     @Override
     public void getWords(final WordComposer codes, final CharSequence prevWordForBigrams,
             final WordCallback callback, final ProximityInfo proximityInfo) {
-        final int count = getSuggestions(codes, prevWordForBigrams, proximityInfo, mOutputChars,
-                mScores);
 
+        final int count = getSuggestions(codes, prevWordForBigrams, proximityInfo, mOutputChars,
+                mScores, mSpaceIndices);
         for (int j = 0; j < count; ++j) {
             if (mScores[j] < 1) break;
             final int start = j * MAX_WORD_LENGTH;
@@ -152,7 +154,7 @@ public class BinaryDictionary extends Dictionary {
                 ++len;
             }
             if (len > 0) {
-                callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId,
+                callback.addWord(mOutputChars, null, start, len, mScores[j], mDicTypeId,
                         Dictionary.UNIGRAM);
             }
         }
@@ -165,7 +167,7 @@ public class BinaryDictionary extends Dictionary {
     // proximityInfo may not be null.
     /* package for test */ int getSuggestions(final WordComposer codes,
             final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo,
-            char[] outputChars, int[] scores) {
+            char[] outputChars, int[] scores, int[] spaceIndices) {
         if (!isValidDictionary()) return -1;
 
         final int codesSize = codes.size();
@@ -179,14 +181,21 @@ public class BinaryDictionary extends Dictionary {
         Arrays.fill(outputChars, (char) 0);
         Arrays.fill(scores, 0);
 
-        final int[] prevWordCodePointArray = null == prevWordForBigrams
+        // TODO: toLowerCase in the native code
+        final int[] prevWordCodePointArray = (null == prevWordForBigrams)
                 ? null : StringUtils.toCodePointArray(prevWordForBigrams.toString());
 
-        // TODO: pass the previous word to native code
-        return getSuggestionsNative(
-                mNativeDict, proximityInfo.getNativeProximityInfo(),
-                codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize,
-                prevWordCodePointArray, mUseFullEditDistance, outputChars, scores);
+        int[] emptyArray = new int[codesSize];
+        Arrays.fill(emptyArray, 0);
+
+        //final int commitPoint = codes.getCommitPoint();
+        //codes.clearCommitPoint();
+
+        return getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
+            codes.getXCoordinates(), codes.getYCoordinates(), emptyArray, emptyArray, mInputCodes,
+            codesSize, 0 /* unused */, false, mDicTypeId,
+            prevWordCodePointArray, mUseFullEditDistance,
+            outputChars, scores, spaceIndices);
     }
 
     public static float calcNormalizedScore(String before, String after, int score) {
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 9c3d46e70e..c75e55d80f 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -41,6 +41,7 @@ public abstract class Dictionary {
          * Adds a word to a list of suggestions. The word is expected to be ordered based on
          * the provided score.
          * @param word the character array containing the word
+         * @param spaceIndices the indices of inserted spaces
          * @param wordOffset starting offset of the word in the character array
          * @param wordLength length of valid characters in the character array
          * @param score the score of occurrence. This is normalized between 1 and 255, but
@@ -49,8 +50,8 @@ public abstract class Dictionary {
          * @param dataType tells type of this data, either UNIGRAM or BIGRAM
          * @return true if the word was added, false if no more words are required
          */
-        boolean addWord(char[] word, int wordOffset, int wordLength, int score, int dicTypeId,
-                int dataType);
+        boolean addWord(char[] word, int[] spaceIndices, int wordOffset, int wordLength, int score,
+                int dicTypeId, int dataType);
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index a22d73af76..6d77c4dd2c 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -59,7 +59,7 @@ public class DictionaryFactory {
             for (final AssetFileAddress f : assetFileList) {
                 final BinaryDictionary binaryDictionary =
                         new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength,
-                                useFullEditDistance, locale);
+                                useFullEditDistance, locale, Suggest.DIC_MAIN);
                 if (binaryDictionary.isValidDictionary()) {
                     dictList.add(binaryDictionary);
                 }
@@ -112,7 +112,7 @@ public class DictionaryFactory {
                 return null;
             }
             return new BinaryDictionary(context, sourceDir, afd.getStartOffset(), afd.getLength(),
-                    false /* useFullEditDistance */, locale);
+                    false /* useFullEditDistance */, locale, Suggest.DIC_MAIN);
         } catch (android.content.res.Resources.NotFoundException e) {
             Log.e(TAG, "Could not find the resource");
             return null;
@@ -140,7 +140,7 @@ public class DictionaryFactory {
             long startOffset, long length, final boolean useFullEditDistance, Locale locale) {
         if (dictionary.isFile()) {
             return new BinaryDictionary(context, dictionary.getAbsolutePath(), startOffset, length,
-                    useFullEditDistance, locale);
+                    useFullEditDistance, locale, Suggest.DIC_MAIN);
         } else {
             Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath());
             return null;
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index c65404cbc2..41d4aa0617 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -306,7 +306,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
         // Build the new binary dictionary
         final BinaryDictionary newBinaryDictionary =
                 new BinaryDictionary(mContext, filename, 0, length, true /* useFullEditDistance */,
-                        null);
+                        null, mDicTypeId);
 
         if (mBinaryDictionary != null) {
             // Ensure all threads accessing the current dictionary have finished before swapping in
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index f5886aa128..c989614fb5 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -660,8 +660,9 @@ public class ExpandableDictionary extends Dictionary {
             } while (node != null);
 
             if (freq >= 0) {
-                callback.addWord(mLookedUpString, index, BinaryDictionary.MAX_WORD_LENGTH - index,
-                        freq, mDicTypeId, Dictionary.BIGRAM);
+                callback.addWord(mLookedUpString, null, index,
+                        BinaryDictionary.MAX_WORD_LENGTH - index, freq, mDicTypeId,
+                        Dictionary.BIGRAM);
             }
         }
     }
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 8922454021..0938bd1279 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -439,8 +439,8 @@ public class Suggest implements Dictionary.WordCallback {
 
     // TODO: Use codepoint instead of char
     @Override
-    public boolean addWord(final char[] word, final int offset, final int length, int score,
-            final int dicTypeId, final int dataType) {
+    public boolean addWord(final char[] word, int[] indices, final int offset, final int length,
+            int score, final int dicTypeId, final int dataType) {
         int dataTypeForLog = dataType;
         final ArrayList<SuggestedWordInfo> suggestions;
         final int prefMaxSuggestions;
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index a44b1f9ad7..19ac718764 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -537,7 +537,7 @@ public class Utils {
             final Dictionary.WordCallback callback) {
         for (SuggestedWordInfo suggestion : suggestions) {
             final String suggestionStr = suggestion.mWord.toString();
-            callback.addWord(suggestionStr.toCharArray(), 0, suggestionStr.length(),
+            callback.addWord(suggestionStr.toCharArray(), null, 0, suggestionStr.length(),
                     suggestion.mScore, dicTypeId, dataType);
         }
     }
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 7fffc31c0f..0bbf2acb1e 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -238,8 +238,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService
         }
 
         @Override
-        synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score,
-                int dicTypeId, int dataType) {
+        synchronized public boolean addWord(char[] word, int[] spaceIndices, int wordOffset,
+                int wordLength, int score, int dicTypeId, int dataType) {
             final int positionIndex = Arrays.binarySearch(mScores, 0, mLength, score);
             // binarySearch returns the index if the element exists, and -<insertion index> - 1
             // if it doesn't. See documentation for binarySearch.
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index d10dc962e5..3fa45da557 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -128,28 +128,37 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
 
 static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object, jlong dict,
         jlong proximityInfo, jintArray xCoordinatesArray, jintArray yCoordinatesArray,
-        jintArray inputArray, jint arraySize, jintArray prevWordForBigrams,
-        jboolean useFullEditDistance, jcharArray outputArray, jintArray frequencyArray) {
-    Dictionary *dictionary = (Dictionary*)dict;
+        jintArray timesArray, jintArray pointerIdArray, jintArray inputArray, jint arraySize,
+        jint commitPoint, jboolean isGesture, jint dicTypeId,
+        jintArray prevWordForBigrams, jboolean useFullEditDistance, jcharArray outputArray,
+        jintArray frequencyArray, jintArray spaceIndexArray) {
+    Dictionary *dictionary = (Dictionary*) dict;
     if (!dictionary) return 0;
     ProximityInfo *pInfo = (ProximityInfo*)proximityInfo;
     int *xCoordinates = env->GetIntArrayElements(xCoordinatesArray, 0);
     int *yCoordinates = env->GetIntArrayElements(yCoordinatesArray, 0);
+    int *times = env->GetIntArrayElements(timesArray, 0);
+    int *pointerIds = env->GetIntArrayElements(pointerIdArray, 0);
     int *frequencies = env->GetIntArrayElements(frequencyArray, 0);
     int *inputCodes = env->GetIntArrayElements(inputArray, 0);
     jchar *outputChars = env->GetCharArrayElements(outputArray, 0);
+    int *spaceIndices = env->GetIntArrayElements(spaceIndexArray, 0);
     jint *prevWordChars = prevWordForBigrams
             ? env->GetIntArrayElements(prevWordForBigrams, 0) : 0;
     jsize prevWordLength = prevWordChars ? env->GetArrayLength(prevWordForBigrams) : 0;
-    int count = dictionary->getSuggestions(pInfo, xCoordinates, yCoordinates, inputCodes,
-            arraySize, prevWordChars, prevWordLength, useFullEditDistance,
-            (unsigned short*) outputChars, frequencies);
+    int count = dictionary->getSuggestions(pInfo, xCoordinates, yCoordinates, times, pointerIds,
+            inputCodes, arraySize, prevWordChars, prevWordLength, commitPoint, isGesture,
+            dicTypeId, useFullEditDistance, (unsigned short*) outputChars,
+            frequencies, spaceIndices);
     if (prevWordChars) {
         env->ReleaseIntArrayElements(prevWordForBigrams, prevWordChars, JNI_ABORT);
     }
+    env->ReleaseIntArrayElements(spaceIndexArray, spaceIndices, 0);
     env->ReleaseCharArrayElements(outputArray, outputChars, 0);
     env->ReleaseIntArrayElements(inputArray, inputCodes, JNI_ABORT);
     env->ReleaseIntArrayElements(frequencyArray, frequencies, 0);
+    env->ReleaseIntArrayElements(pointerIdArray, pointerIds, 0);
+    env->ReleaseIntArrayElements(timesArray, times, 0);
     env->ReleaseIntArrayElements(yCoordinatesArray, yCoordinates, 0);
     env->ReleaseIntArrayElements(xCoordinatesArray, xCoordinates, 0);
     return count;
@@ -251,8 +260,8 @@ void releaseDictBuf(void* dictBuf, const size_t length, int fd) {
 static JNINativeMethod sMethods[] = {
     {"openNative", "(Ljava/lang/String;JJIIII)J", (void*)latinime_BinaryDictionary_open},
     {"closeNative", "(J)V", (void*)latinime_BinaryDictionary_close},
-    {"getSuggestionsNative", "(JJ[I[I[II[IZ[C[I)I",
-            (void*)latinime_BinaryDictionary_getSuggestions},
+    {"getSuggestionsNative", "(JJ[I[I[I[I[IIIZI[IZ[C[I[I)I",
+            (void*) latinime_BinaryDictionary_getSuggestions},
     {"getFrequencyNative", "(J[II)I", (void*)latinime_BinaryDictionary_getFrequency},
     {"isValidBigramNative", "(J[I[I)Z", (void*)latinime_BinaryDictionary_isValidBigram},
     {"getBigramsNative", "(J[II[II[C[III)I", (void*)latinime_BinaryDictionary_getBigrams},
diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h
index fd69f79e36..76b25e59a0 100644
--- a/native/jni/src/dictionary.h
+++ b/native/jni/src/dictionary.h
@@ -34,15 +34,19 @@ class Dictionary {
             int fullWordMultiplier, int maxWordLength, int maxWords);
 
     int getSuggestions(ProximityInfo *proximityInfo, int *xcoordinates, int *ycoordinates,
-            int *codes, int codesSize, const int32_t* prevWordChars, const int prevWordLength,
-            bool useFullEditDistance, unsigned short *outWords, int *frequencies) const {
+            int *times, int *pointerIds, int *codes, int codesSize, int *prevWordChars,
+            int prevWordLength, int commitPoint, bool isGesture, int dicTypeId,
+            bool useFullEditDistance, unsigned short *outWords,
+            int *frequencies, int *spaceIndices) {
+        int result = 0;
         std::map<int, int> bigramMap;
         uint8_t bigramFilter[BIGRAM_FILTER_BYTE_SIZE];
         mBigramDictionary->fillBigramAddressToFrequencyMapAndFilter(prevWordChars,
                 prevWordLength, &bigramMap, bigramFilter);
-        return mUnigramDictionary->getSuggestions(proximityInfo,
-                xcoordinates, ycoordinates, codes, codesSize, &bigramMap,
-                bigramFilter, useFullEditDistance, outWords, frequencies);
+        result = mUnigramDictionary->getSuggestions(proximityInfo, xcoordinates,
+                ycoordinates, codes, codesSize, &bigramMap, bigramFilter,
+                useFullEditDistance, outWords, frequencies);
+        return result;
     }
 
     int getBigrams(const int32_t *word, int length, int *codes, int codesSize,
-- 
GitLab