Merge "[Rlog68] Logger; make filenames more unique to prevent filesys conflicts"
diff --git a/java/res/xml/spellchecker.xml b/java/res/xml/spellchecker.xml
index 66cd662..813319c 100644
--- a/java/res/xml/spellchecker.xml
+++ b/java/res/xml/spellchecker.xml
@@ -57,18 +57,6 @@
/>
<subtype
android:label="@string/subtype_generic"
- android:subtypeLocale="cs"
- />
- <subtype
- android:label="@string/subtype_generic"
- android:subtypeLocale="nl"
- />
- <subtype
- android:label="@string/subtype_generic"
- android:subtypeLocale="hr"
- />
- <subtype
- android:label="@string/subtype_generic"
android:subtypeLocale="pt_BR"
/>
</spell-checker>
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 448d25c..878633e 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -42,17 +42,13 @@
* really long words.
*/
private static final int MAX_WORD_LENGTH = Constants.Dictionary.MAX_WORD_LENGTH;
- private static final int MAX_WORDS = 18;
- private static final int MAX_SPACES = 16;
-
- private static final int MAX_PREDICTIONS = 60;
- private static final int MAX_RESULTS = Math.max(MAX_PREDICTIONS, MAX_WORDS);
+ private static final int MAX_RESULTS = 18; /* Must be identical to MAX_RESULTS in defines.h */
private long mNativeDict;
private final Locale mLocale;
private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH];
private final int[] mOutputCodePoints = new int[MAX_WORD_LENGTH * MAX_RESULTS];
- private final int[] mSpaceIndices = new int[MAX_SPACES];
+ private final int[] mSpaceIndices = new int[MAX_RESULTS];
private final int[] mOutputScores = new int[MAX_RESULTS];
private final int[] mOutputTypes = new int[MAX_RESULTS];
@@ -80,16 +76,14 @@
/**
* Constructor for the binary dictionary. This is supposed to be called from the
* dictionary factory.
- * @param context the context to access the environment from.
* @param filename the name of the file to read through native code.
* @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 dictType the dictionary type, as a human-readable string
*/
- public BinaryDictionary(final Context context, final String filename, final long offset,
- final long length, final boolean useFullEditDistance, final Locale locale,
- final String dictType) {
+ public BinaryDictionary(final String filename, final long offset, final long length,
+ final boolean useFullEditDistance, final Locale locale, final String dictType) {
super(dictType);
mLocale = locale;
mUseFullEditDistance = useFullEditDistance;
@@ -101,7 +95,7 @@
}
private native long openNative(String sourceDir, long dictOffset, long dictSize,
- int maxWordLength, int maxWords, int maxPredictions);
+ int maxWordLength);
private native void closeNative(long dict);
private native int getFrequencyNative(long dict, int[] word);
private native boolean isValidBigramNative(long dict, int[] word1, int[] word2);
@@ -116,8 +110,7 @@
// TODO: Move native dict into session
private final void loadDictionary(final String path, final long startOffset,
final long length) {
- mNativeDict = openNative(path, startOffset, length, MAX_WORD_LENGTH, MAX_WORDS,
- MAX_PREDICTIONS);
+ mNativeDict = openNative(path, startOffset, length, MAX_WORD_LENGTH);
}
@Override
@@ -148,14 +141,12 @@
final InputPointers ips = composer.getInputPointers();
final int codesSize = isGesture ? ips.getPointerSize() : composerSize;
// proximityInfo and/or prevWordForBigrams may not be null.
- final int tmpCount = getSuggestionsNative(mNativeDict,
- proximityInfo.getNativeProximityInfo(), getTraverseSession(sessionId).getSession(),
- ips.getXCoordinates(), ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(),
- mInputCodePoints, codesSize, 0 /* commitPoint */, isGesture, prevWordCodePointArray,
+ final int count = getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
+ getTraverseSession(sessionId).getSession(), ips.getXCoordinates(),
+ ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), mInputCodePoints,
+ codesSize, 0 /* commitPoint */, isGesture, prevWordCodePointArray,
mUseFullEditDistance, mOutputCodePoints, mOutputScores, mSpaceIndices,
mOutputTypes);
- final int count = Math.min(tmpCount, MAX_PREDICTIONS);
-
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
for (int j = 0; j < count; ++j) {
if (composerSize > 0 && mOutputScores[j] < 1) break;
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index f381973..22cf5b3 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -58,9 +58,8 @@
BinaryDictionaryGetter.getDictionaryFiles(locale, context);
if (null != assetFileList) {
for (final AssetFileAddress f : assetFileList) {
- final BinaryDictionary binaryDictionary =
- new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength,
- useFullEditDistance, locale, Dictionary.TYPE_MAIN);
+ final BinaryDictionary binaryDictionary = new BinaryDictionary(f.mFilename,
+ f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN);
if (binaryDictionary.isValidDictionary()) {
dictList.add(binaryDictionary);
}
@@ -112,7 +111,7 @@
Log.e(TAG, "sourceDir is not a file: " + sourceDir);
return null;
}
- return new BinaryDictionary(context, sourceDir, afd.getStartOffset(), afd.getLength(),
+ return new BinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(),
false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN);
} catch (android.content.res.Resources.NotFoundException e) {
Log.e(TAG, "Could not find the resource");
@@ -130,17 +129,16 @@
/**
* Create a dictionary from passed data. This is intended for unit tests only.
- * @param context the test context to create this data from.
* @param dictionary the file to read
* @param startOffset the offset in the file where the data starts
* @param length the length of the data
* @param useFullEditDistance whether to use the full edit distance in suggestions
* @return the created dictionary, or null.
*/
- public static Dictionary createDictionaryForTest(Context context, File dictionary,
- long startOffset, long length, final boolean useFullEditDistance, Locale locale) {
+ public static Dictionary createDictionaryForTest(File dictionary, long startOffset, long length,
+ final boolean useFullEditDistance, Locale locale) {
if (dictionary.isFile()) {
- return new BinaryDictionary(context, dictionary.getAbsolutePath(), startOffset, length,
+ return new BinaryDictionary(dictionary.getAbsolutePath(), startOffset, length,
useFullEditDistance, locale, Dictionary.TYPE_MAIN);
} else {
Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath());
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 47adaa8..2c7fdcc 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -279,9 +279,8 @@
final long length = file.length();
// Build the new binary dictionary
- final BinaryDictionary newBinaryDictionary =
- new BinaryDictionary(mContext, filename, 0, length, true /* useFullEditDistance */,
- null, mDictType);
+ final BinaryDictionary newBinaryDictionary = new BinaryDictionary(filename, 0, length,
+ true /* useFullEditDistance */, null, mDictType);
if (mBinaryDictionary != null) {
// Ensure all threads accessing the current dictionary have finished before swapping in
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index df733c5..4a35114 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1301,13 +1301,13 @@
}
private void sendKeyCodePoint(final int code) {
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_sendKeyCodePoint(code);
+ }
// TODO: Remove this special handling of digit letters.
// For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
if (code >= '0' && code <= '9') {
sendDownUpKeyEventForBackwardCompatibility(code - '0' + KeyEvent.KEYCODE_0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_sendKeyCodePoint(code);
- }
return;
}
@@ -1327,6 +1327,9 @@
// Implementation of {@link KeyboardActionListener}.
@Override
public void onCodeInput(final int primaryCode, final int x, final int y) {
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
+ }
final long when = SystemClock.uptimeMillis();
if (primaryCode != Constants.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
mDeleteCount = 0;
@@ -1420,9 +1423,6 @@
mEnteredText = null;
}
mConnection.endBatchEdit();
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
- }
}
// Called from PointerTracker through the KeyboardActionListener interface
@@ -1667,7 +1667,7 @@
if (mWordComposer.isBatchMode()) {
if (ProductionFlag.IS_EXPERIMENTAL) {
final String word = mWordComposer.getTypedWord();
- ResearchLogger.latinIME_handleBackspace_batch(word);
+ ResearchLogger.latinIME_handleBackspace_batch(word, 1);
ResearchLogger.getInstance().uncommitCurrentLogUnit(
word, false /* dumpCurrentLogUnit */);
}
@@ -1718,14 +1718,17 @@
// We should backspace one char and restart suggestion if at the end of a word.
if (mLastSelectionStart != mLastSelectionEnd) {
// If there is a selection, remove it.
- final int lengthToDelete = mLastSelectionEnd - mLastSelectionStart;
+ final int numCharsDeleted = mLastSelectionEnd - mLastSelectionStart;
mConnection.setSelection(mLastSelectionEnd, mLastSelectionEnd);
// Reset mLastSelectionEnd to mLastSelectionStart. This is what is supposed to
// happen, and if it's wrong, the next call to onUpdateSelection will correct it,
// but we want to set it right away to avoid it being used with the wrong values
// later (typically, in a subsequent press on backspace).
mLastSelectionEnd = mLastSelectionStart;
- mConnection.deleteSurroundingText(lengthToDelete, 0);
+ mConnection.deleteSurroundingText(numCharsDeleted, 0);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_handleBackspace(numCharsDeleted);
+ }
} else {
// There is no selection, just delete one character.
if (NOT_A_CURSOR_POSITION == mLastSelectionEnd) {
@@ -1742,8 +1745,14 @@
} else {
mConnection.deleteSurroundingText(1, 0);
}
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_handleBackspace(1);
+ }
if (mDeleteCount > DELETE_ACCELERATE_AT) {
mConnection.deleteSurroundingText(1, 0);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_handleBackspace(1);
+ }
}
}
if (mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation)) {
@@ -1843,6 +1852,9 @@
// Returns true if we did an autocorrection, false otherwise.
private boolean handleSeparator(final int primaryCode, final int x, final int y,
final int spaceState) {
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_handleSeparator();
+ }
boolean didAutoCorrect = false;
// Handle separator
if (mWordComposer.isComposingWord()) {
@@ -2122,7 +2134,7 @@
Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_punctuationSuggestion(index, suggestion,
- false /* isBatchMode */);
+ false /* isBatchMode */, suggestedWords.mIsPrediction);
}
return;
}
@@ -2309,7 +2321,9 @@
}
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_revertCommit(committedWord, originallyTypedWord,
- mWordComposer.isBatchMode());
+ mWordComposer.isBatchMode(), mLastComposedWord.mSeparatorString);
+ ResearchLogger.getInstance().uncommitCurrentLogUnit(committedWord,
+ true /* dumpCurrentLogUnit */);
}
// Don't restart suggestion yet. We'll restart if the user deletes the
// separator.
@@ -2322,6 +2336,9 @@
public void promotePhantomSpace() {
if (mSettings.getCurrent().shouldInsertSpacesAutomatically()) {
sendKeyCodePoint(Constants.CODE_SPACE);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_promotePhantomSpace();
+ }
}
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 3dc2ba9..2abf75d 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -72,9 +72,8 @@
}
@UsedForTesting
- Suggest(final Context context, final File dictionary,
- final long startOffset, final long length, final Locale locale) {
- final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary,
+ Suggest(final File dictionary, final long startOffset, final long length, final Locale locale) {
+ final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(dictionary,
startOffset, length /* useFullEditDistance */, false, locale);
mLocale = locale;
mMainDictionary = mainDict;
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 89d6c90..907c0cd 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -81,6 +81,7 @@
public static final int SCRIPT_LATIN = 0;
public static final int SCRIPT_CYRILLIC = 1;
+ public static final int SCRIPT_GREEK = 2;
public static final String SINGLE_QUOTE = "\u0027";
public static final String APOSTROPHE = "\u2019";
private static final TreeMap<String, Integer> mLanguageToScript;
@@ -94,18 +95,23 @@
// IMPORTANT: this only contains languages - do not write countries in there.
// Only the language is searched from the map.
mLanguageToScript = CollectionUtils.newTreeMap();
- mLanguageToScript.put("en", SCRIPT_LATIN);
- mLanguageToScript.put("fr", SCRIPT_LATIN);
- mLanguageToScript.put("de", SCRIPT_LATIN);
- mLanguageToScript.put("nl", SCRIPT_LATIN);
mLanguageToScript.put("cs", SCRIPT_LATIN);
+ mLanguageToScript.put("da", SCRIPT_LATIN);
+ mLanguageToScript.put("de", SCRIPT_LATIN);
+ mLanguageToScript.put("el", SCRIPT_GREEK);
+ mLanguageToScript.put("en", SCRIPT_LATIN);
mLanguageToScript.put("es", SCRIPT_LATIN);
- mLanguageToScript.put("it", SCRIPT_LATIN);
+ mLanguageToScript.put("fi", SCRIPT_LATIN);
+ mLanguageToScript.put("fr", SCRIPT_LATIN);
mLanguageToScript.put("hr", SCRIPT_LATIN);
+ mLanguageToScript.put("it", SCRIPT_LATIN);
+ mLanguageToScript.put("lt", SCRIPT_LATIN);
+ mLanguageToScript.put("lv", SCRIPT_LATIN);
+ mLanguageToScript.put("nb", SCRIPT_LATIN);
+ mLanguageToScript.put("nl", SCRIPT_LATIN);
mLanguageToScript.put("pt", SCRIPT_LATIN);
+ mLanguageToScript.put("sl", SCRIPT_LATIN);
mLanguageToScript.put("ru", SCRIPT_CYRILLIC);
- // TODO: Make a persian proximity, and activate the Farsi subtype.
- // mLanguageToScript.put("fa", SCRIPT_PERSIAN);
}
@Override public void onCreate() {
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 470943b..6581978 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -143,8 +143,17 @@
case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
// All Cyrillic characters are in the 400~52F block. There are some in the upper
// Unicode range, but they are archaic characters that are not used in modern
- // russian and are not used by our dictionary.
+ // Russian and are not used by our dictionary.
return codePoint >= 0x400 && codePoint <= 0x52F && Character.isLetter(codePoint);
+ case AndroidSpellCheckerService.SCRIPT_GREEK:
+ // Greek letters are either in the 370~3FF range (Greek & Coptic), or in the
+ // 1F00~1FFF range (Greek extended). Our dictionary contains both sort of characters.
+ // Our dictionary also contains a few words with 0xF2; it would be best to check
+ // if that's correct, but a Google search does return results for these words so
+ // they are probably okay.
+ return (codePoint >= 0x370 && codePoint <= 0x3FF)
+ || (codePoint >= 0x1F00 && codePoint <= 0x1FFF)
+ || codePoint == 0xF2;
default:
// Should never come here
throw new RuntimeException("Impossible value of script: " + script);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
index 6c0d79c..572a826 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
@@ -73,6 +73,12 @@
// to spell check has been entered with one of the keyboards above. Also, specifically
// to English, many spelling errors consist of the last vowel of the word being wrong
// because in English vowels tend to merge with each other in pronunciation.
+ /*
+ The Qwerty layout this represents looks like the following:
+ q w e r t y u i o p
+ a s d f g h j k l
+ z x c v b n m
+ */
final static int[] PROXIMITY = {
// Proximity for row 1. This must have exactly ROW_SIZE entries for each letter,
// and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's.
@@ -127,10 +133,13 @@
final private static TreeMap<Integer, Integer> INDICES = CollectionUtils.newTreeMap();
// TODO: The following table is solely based on the keyboard layout. Consult with Russian
// speakers on commonly misspelled words/letters.
- final static int[] PROXIMITY = {
- // Proximity for row 1. This must have exactly ROW_SIZE entries for each letter,
- // and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's.
- // The number of rows must be exactly PROXIMITY_GRID_HEIGHT.
+ /*
+ The Russian layout this represents looks like the following:
+ й ц у к е н г ш щ з х
+ ф ы в а п р о л д ж э
+ я ч с м и т ь б ю
+
+ This gives us the following table:
'й', 'ц', 'ф', 'ы', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'ц', 'й', 'ф', 'ы', 'в', 'у', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'у', 'ц', 'ы', 'в', 'а', 'к', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -143,7 +152,6 @@
'з', 'щ', 'д', 'ж', 'э', 'х', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'х', 'з', 'ж', 'э', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- // Proximity for row 2. See comment above about size.
'ф', 'й', 'ц', 'ы', 'я', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'ы', 'й', 'ц', 'у', 'ф', 'в', 'я', 'ч', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'в', 'ц', 'у', 'к', 'ы', 'а', 'я', 'ч', 'с', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -156,7 +164,6 @@
'ж', 'щ', 'з', 'х', 'д', 'э', 'б', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'э', 'з', 'х', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- // Proximity for row 3. See comment above about size.
'я', 'ф', 'ы', 'в', 'ч', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'ч', 'ы', 'в', 'а', 'я', 'с', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'с', 'в', 'а', 'п', 'ч', 'м', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -166,6 +173,249 @@
'ь', 'о', 'л', 'д', 'т', 'б', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'б', 'л', 'д', 'ж', 'ь', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'ю', 'д', 'ж', 'э', 'б', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ Using the following characters:
+ */
+ private static final int CY_SHORT_I = '\u0439'; // й
+ private static final int CY_TSE = '\u0446'; // ц
+ private static final int CY_U = '\u0443'; // у
+ private static final int CY_KA = '\u043A'; // к
+ private static final int CY_IE = '\u0435'; // е
+ private static final int CY_EN = '\u043D'; // н
+ private static final int CY_GHE = '\u0433'; // г
+ private static final int CY_SHA = '\u0448'; // ш
+ private static final int CY_SHCHA = '\u0449'; // щ
+ private static final int CY_ZE = '\u0437'; // з
+ private static final int CY_HA = '\u0445'; // х
+ private static final int CY_EF = '\u0444'; // ф
+ private static final int CY_YERU = '\u044B'; // ы
+ private static final int CY_VE = '\u0432'; // в
+ private static final int CY_A = '\u0430'; // а
+ private static final int CY_PE = '\u043F'; // п
+ private static final int CY_ER = '\u0440'; // р
+ private static final int CY_O = '\u043E'; // о
+ private static final int CY_EL = '\u043B'; // л
+ private static final int CY_DE = '\u0434'; // д
+ private static final int CY_ZHE = '\u0436'; // ж
+ private static final int CY_E = '\u044D'; // э
+ private static final int CY_YA = '\u044F'; // я
+ private static final int CY_CHE = '\u0447'; // ч
+ private static final int CY_ES = '\u0441'; // с
+ private static final int CY_EM = '\u043C'; // м
+ private static final int CY_I = '\u0438'; // и
+ private static final int CY_TE = '\u0442'; // т
+ private static final int CY_SOFT_SIGN = '\u044C'; // ь
+ private static final int CY_BE = '\u0431'; // б
+ private static final int CY_YU = '\u044E'; // ю
+ final static int[] PROXIMITY = {
+ // Proximity for row 1. This must have exactly ROW_SIZE entries for each letter,
+ // and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's.
+ // The number of rows must be exactly PROXIMITY_GRID_HEIGHT.
+ CY_SHORT_I, CY_TSE, CY_EF, CY_YERU, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_TSE, CY_SHORT_I, CY_EF, CY_YERU, CY_VE, CY_U, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_U, CY_TSE, CY_YERU, CY_VE, CY_A, CY_KA, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_KA, CY_U, CY_VE, CY_A, CY_PE, CY_IE, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_IE, CY_KA, CY_A, CY_PE, CY_ER, CY_EN, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_EN, CY_IE, CY_PE, CY_ER, CY_O, CY_GHE, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_GHE, CY_EN, CY_ER, CY_O, CY_EL, CY_SHA, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_SHA, CY_GHE, CY_O, CY_EL, CY_DE, CY_SHCHA, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_SHCHA, CY_SHA, CY_EL, CY_DE, CY_ZHE, CY_ZE, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_ZE, CY_SHCHA, CY_DE, CY_ZHE, CY_E, CY_HA, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_HA, CY_ZE, CY_ZHE, CY_E, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ // Proximity for row 2. See comment above about size.
+ CY_EF, CY_SHORT_I, CY_TSE, CY_YERU, CY_YA, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_YERU, CY_SHORT_I, CY_TSE, CY_U, CY_EF, CY_VE, CY_YA, CY_CHE,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_VE, CY_TSE, CY_U, CY_KA, CY_YERU, CY_A, CY_YA, CY_CHE,
+ CY_ES, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_A, CY_U, CY_KA, CY_IE, CY_VE, CY_PE, CY_CHE, CY_ES,
+ CY_EM, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_PE, CY_KA, CY_IE, CY_EN, CY_A, CY_ER, CY_ES, CY_EM,
+ CY_I, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_ER, CY_IE, CY_EN, CY_GHE, CY_PE, CY_O, CY_EM, CY_I,
+ CY_TE, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_O, CY_EN, CY_GHE, CY_SHA, CY_ER, CY_EL, CY_I, CY_TE,
+ CY_SOFT_SIGN, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_EL, CY_GHE, CY_SHA, CY_SHCHA, CY_O, CY_DE, CY_TE, CY_SOFT_SIGN,
+ CY_BE, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_DE, CY_SHA, CY_SHCHA, CY_ZE, CY_EL, CY_ZHE, CY_SOFT_SIGN, CY_BE,
+ CY_YU, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_ZHE, CY_SHCHA, CY_ZE, CY_HA, CY_DE, CY_E, CY_BE, CY_YU,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_E, CY_ZE, CY_HA, CY_YU, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ // Proximity for row 3. See comment above about size.
+ CY_YA, CY_EF, CY_YERU, CY_VE, CY_CHE, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_CHE, CY_YERU, CY_VE, CY_A, CY_YA, CY_ES, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_ES, CY_VE, CY_A, CY_PE, CY_CHE, CY_EM, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_EM, CY_A, CY_PE, CY_ER, CY_ES, CY_I, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_I, CY_PE, CY_ER, CY_O, CY_EM, CY_TE, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_TE, CY_ER, CY_O, CY_EL, CY_I, CY_SOFT_SIGN, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_SOFT_SIGN, CY_O, CY_EL, CY_DE, CY_TE, CY_BE, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_BE, CY_EL, CY_DE, CY_ZHE, CY_SOFT_SIGN, CY_YU, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ CY_YU, CY_DE, CY_ZHE, CY_E, CY_BE, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ };
+ static {
+ buildProximityIndices(PROXIMITY, INDICES);
+ }
+ static int getIndexOf(int characterCode) {
+ return computeIndex(characterCode, INDICES);
+ }
+ }
+
+ private static final class Greek {
+ final private static TreeMap<Integer, Integer> INDICES = CollectionUtils.newTreeMap();
+ // TODO: The following table is solely based on the keyboard layout. Consult with Greek
+ // speakers on commonly misspelled words/letters.
+ /*
+ The Greek layout this represents looks like the following:
+ ; ς ε ρ τ υ θ ι ο π
+ α σ δ φ γ η ξ κ λ
+ ζ χ ψ ω β ν μ
+
+ This gives us the following table:
+ 'ς', 'ε', 'α', 'σ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ε', 'ς', 'ρ', 'σ', 'δ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ρ', 'ε', 'τ', 'δ', 'φ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'τ', 'ρ', 'υ', 'φ', 'γ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'υ', 'τ', 'θ', 'γ', 'η', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'θ', 'υ', 'ι', 'η', 'ξ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ι', 'θ', 'ο', 'ξ', 'κ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ο', 'ι', 'π', 'κ', 'λ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'π', 'ο', 'λ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ 'α', 'ς', 'σ', 'ζ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'σ', 'ς', 'ε', 'α', 'δ', 'ζ', 'χ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'δ', 'ε', 'ρ', 'σ', 'φ', 'ζ', 'χ', 'ψ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'φ', 'ρ', 'τ', 'δ', 'γ', 'χ', 'ψ', 'ω', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'γ', 'τ', 'υ', 'φ', 'η', 'ψ', 'ω', 'β', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'η', 'υ', 'θ', 'γ', 'ξ', 'ω', 'β', 'ν', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ξ', 'θ', 'ι', 'η', 'κ', 'β', 'ν', 'μ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'κ', 'ι', 'ο', 'ξ', 'λ', 'ν', 'μ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'λ', 'ο', 'π', 'κ', 'μ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ 'ζ', 'α', 'σ', 'δ', 'χ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'χ', 'σ', 'δ', 'φ', 'ζ', 'ψ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ψ', 'δ', 'φ', 'γ', 'χ', 'ω', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ω', 'φ', 'γ', 'η', 'ψ', 'β', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'β', 'γ', 'η', 'ξ', 'ω', 'ν', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ν', 'η', 'ξ', 'κ', 'β', 'μ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'μ', 'ξ', 'κ', 'λ', 'ν', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ Using the following characters:
+ */
+ private static final int GR_FINAL_SIGMA = '\u03C2'; // ς
+ private static final int GR_EPSILON = '\u03B5'; // ε
+ private static final int GR_RHO = '\u03C1'; // ρ
+ private static final int GR_TAU = '\u03C4'; // τ
+ private static final int GR_UPSILON = '\u03C5'; // υ
+ private static final int GR_THETA = '\u03B8'; // θ
+ private static final int GR_IOTA = '\u03B9'; // ι
+ private static final int GR_OMICRON = '\u03BF'; // ο
+ private static final int GR_PI = '\u03C0'; // π
+ private static final int GR_ALPHA = '\u03B1'; // α
+ private static final int GR_SIGMA = '\u03C3'; // σ
+ private static final int GR_DELTA = '\u03B4'; // δ
+ private static final int GR_PHI = '\u03C6'; // φ
+ private static final int GR_GAMMA = '\u03B3'; // γ
+ private static final int GR_ETA = '\u03B7'; // η
+ private static final int GR_XI = '\u03BE'; // ξ
+ private static final int GR_KAPPA = '\u03BA'; // κ
+ private static final int GR_LAMDA = '\u03BB'; // λ
+ private static final int GR_ZETA = '\u03B6'; // ζ
+ private static final int GR_CHI = '\u03C7'; // χ
+ private static final int GR_PSI = '\u03C8'; // ψ
+ private static final int GR_OMEGA = '\u03C9'; // ω
+ private static final int GR_BETA = '\u03B2'; // β
+ private static final int GR_NU = '\u03BD'; // ν
+ private static final int GR_MU = '\u03BC'; // μ
+ final static int[] PROXIMITY = {
+ // Proximity for row 1. This must have exactly ROW_SIZE entries for each letter,
+ // and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's.
+ // The number of rows must be exactly PROXIMITY_GRID_HEIGHT.
+ GR_FINAL_SIGMA, GR_EPSILON, GR_ALPHA, GR_SIGMA, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_EPSILON, GR_FINAL_SIGMA, GR_RHO, GR_SIGMA, GR_DELTA, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_RHO, GR_EPSILON, GR_TAU, GR_DELTA, GR_PHI, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_TAU, GR_RHO, GR_UPSILON, GR_PHI, GR_GAMMA, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_UPSILON, GR_TAU, GR_THETA, GR_GAMMA, GR_ETA, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_THETA, GR_UPSILON, GR_IOTA, GR_ETA, GR_XI, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_IOTA, GR_THETA, GR_OMICRON, GR_XI, GR_KAPPA, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_OMICRON, GR_IOTA, GR_PI, GR_KAPPA, GR_LAMDA, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_PI, GR_OMICRON, GR_LAMDA, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ GR_ALPHA, GR_FINAL_SIGMA, GR_SIGMA, GR_ZETA, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_SIGMA, GR_FINAL_SIGMA, GR_EPSILON, GR_ALPHA, GR_DELTA, GR_ZETA, GR_CHI, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_DELTA, GR_EPSILON, GR_RHO, GR_SIGMA, GR_PHI, GR_ZETA, GR_CHI, GR_PSI,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_PHI, GR_RHO, GR_TAU, GR_DELTA, GR_GAMMA, GR_CHI, GR_PSI, GR_OMEGA,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_GAMMA, GR_TAU, GR_UPSILON, GR_PHI, GR_ETA, GR_PSI, GR_OMEGA, GR_BETA,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_ETA, GR_UPSILON, GR_THETA, GR_GAMMA, GR_XI, GR_OMEGA, GR_BETA, GR_NU,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_XI, GR_THETA, GR_IOTA, GR_ETA, GR_KAPPA, GR_BETA, GR_NU, GR_MU,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_KAPPA, GR_IOTA, GR_OMICRON, GR_XI, GR_LAMDA, GR_NU, GR_MU, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_LAMDA, GR_OMICRON, GR_PI, GR_KAPPA, GR_MU, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ GR_ZETA, GR_ALPHA, GR_SIGMA, GR_DELTA, GR_CHI, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_CHI, GR_SIGMA, GR_DELTA, GR_PHI, GR_ZETA, GR_PSI, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_PSI, GR_DELTA, GR_PHI, GR_GAMMA, GR_CHI, GR_OMEGA, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_OMEGA, GR_PHI, GR_GAMMA, GR_ETA, GR_PSI, GR_BETA, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_BETA, GR_GAMMA, GR_ETA, GR_XI, GR_OMEGA, GR_NU, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_NU, GR_ETA, GR_XI, GR_KAPPA, GR_BETA, GR_MU, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ GR_MU, GR_XI, GR_KAPPA, GR_LAMDA, GR_NU, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
};
@@ -183,6 +433,8 @@
return Latin.PROXIMITY;
case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
return Cyrillic.PROXIMITY;
+ case AndroidSpellCheckerService.SCRIPT_GREEK:
+ return Greek.PROXIMITY;
default:
throw new RuntimeException("Wrong script supplied: " + script);
}
@@ -194,6 +446,8 @@
return Latin.getIndexOf(codePoint);
case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
return Cyrillic.getIndexOf(codePoint);
+ case AndroidSpellCheckerService.SCRIPT_GREEK:
+ return Greek.getIndexOf(codePoint);
default:
throw new RuntimeException("Wrong script supplied: " + script);
}
diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java
index 7b45ff1..cfba289 100644
--- a/java/src/com/android/inputmethod/research/LogUnit.java
+++ b/java/src/com/android/inputmethod/research/LogUnit.java
@@ -133,7 +133,7 @@
// will not have been opened for writing.
if (jsonWriter == null) {
jsonWriter = researchLog.getValidJsonWriterLocked();
- outputLogUnitStart(jsonWriter);
+ outputLogUnitStart(jsonWriter, isIncludingPrivateData);
}
outputLogStatementToLocked(jsonWriter, mLogStatementList.get(i), mValuesList.get(i),
mTimeList.get(i));
@@ -169,11 +169,14 @@
private static final String LOG_UNIT_BEGIN_KEY = "logUnitStart";
private static final String LOG_UNIT_END_KEY = "logUnitEnd";
- private void outputLogUnitStart(final JsonWriter jsonWriter) {
+ private void outputLogUnitStart(final JsonWriter jsonWriter,
+ final boolean isIncludingPrivateData) {
try {
jsonWriter.beginObject();
jsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis());
- jsonWriter.name(WORD_KEY).value(getWord());
+ if (isIncludingPrivateData) {
+ jsonWriter.name(WORD_KEY).value(getWord());
+ }
jsonWriter.name(EVENT_TYPE_KEY).value(LOG_UNIT_BEGIN_KEY);
jsonWriter.endObject();
} catch (IOException e) {
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index f609a27..8b6bff4 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -741,6 +741,8 @@
}
}
+ private static final LogStatement LOGSTATEMENT_UNCOMMIT_CURRENT_LOGUNIT =
+ new LogStatement("UncommitCurrentLogUnit", false, false);
public void uncommitCurrentLogUnit(final String expectedWord,
final boolean dumpCurrentLogUnit) {
// The user has deleted this word and returned to the previous. Check that the word in the
@@ -779,6 +781,7 @@
if (mFeedbackLogBuffer != null) {
mFeedbackLogBuffer.unshiftIn();
}
+ enqueueEvent(LOGSTATEMENT_UNCOMMIT_CURRENT_LOGUNIT);
if (DEBUG) {
Log.d(TAG, "uncommitCurrentLogUnit (dump=" + dumpCurrentLogUnit + ") back to "
+ (mCurrentLogUnit.hasWord() ? ": '" + mCurrentLogUnit.getWord() + "'" : ""));
@@ -849,6 +852,10 @@
mCurrentLogUnit = newLogUnit;
}
+ private void setSavedDownEventTime(final long time) {
+ mSavedDownEventTime = time;
+ }
+
public void onWordFinished(final String word, final boolean isBatchMode) {
commitCurrentLogUnitAsWord(word, mSavedDownEventTime, isBatchMode);
mSavedDownEventTime = Long.MAX_VALUE;
@@ -998,7 +1005,7 @@
if (action == MotionEvent.ACTION_DOWN) {
// Subtract 1 from eventTime so the down event is included in the later
// LogUnit, not the earlier (the test is for inequality).
- researchLogger.mSavedDownEventTime = eventTime - 1;
+ researchLogger.setSavedDownEventTime(eventTime - 1);
}
}
}
@@ -1164,7 +1171,7 @@
suggestion == null ? null : scrubbedWord, Constants.SUGGESTION_STRIP_COORDINATE,
Constants.SUGGESTION_STRIP_COORDINATE);
researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, Long.MAX_VALUE, isBatchMode);
- researchLogger.mStatistics.recordManualSuggestion();
+ researchLogger.mStatistics.recordManualSuggestion(SystemClock.uptimeMillis());
}
/**
@@ -1174,21 +1181,21 @@
*/
private static final LogStatement LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION =
new LogStatement("LatinIMEPunctuationSuggestion", false, false, "index", "suggestion",
- "x", "y");
+ "x", "y", "isPrediction");
public static void latinIME_punctuationSuggestion(final int index, final String suggestion,
- final boolean isBatchMode) {
+ final boolean isBatchMode, final boolean isPrediction) {
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION, index, suggestion,
- Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE);
+ Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE,
+ isPrediction);
researchLogger.commitCurrentLogUnitAsWord(suggestion, Long.MAX_VALUE, isBatchMode);
}
/**
* Log a call to LatinIME.sendKeyCodePoint().
*
- * SystemResponse: The IME is simulating a hardware keypress. This happens for numbers; other
- * input typically goes through RichInputConnection.setComposingText() and
- * RichInputConnection.commitText().
+ * SystemResponse: The IME is inserting text into the TextView for numbers, fixed strings, or
+ * some other unusual mechanism.
*/
private static final LogStatement LOGSTATEMENT_LATINIME_SENDKEYCODEPOINT =
new LogStatement("LatinIMESendKeyCodePoint", true, false, "code");
@@ -1202,6 +1209,24 @@
}
/**
+ * Log a call to LatinIME.promotePhantomSpace().
+ *
+ * SystemResponse: The IME is inserting a real space in place of a phantom space.
+ */
+ private static final LogStatement LOGSTATEMENT_LATINIME_PROMOTEPHANTOMSPACE =
+ new LogStatement("LatinIMEPromotPhantomSpace", false, false);
+ public static void latinIME_promotePhantomSpace() {
+ final ResearchLogger researchLogger = getInstance();
+ final LogUnit logUnit;
+ if (researchLogger.mMainLogBuffer == null) {
+ logUnit = researchLogger.mCurrentLogUnit;
+ } else {
+ logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit();
+ }
+ researchLogger.enqueueEvent(logUnit, LOGSTATEMENT_LATINIME_PROMOTEPHANTOMSPACE);
+ }
+
+ /**
* Log a call to LatinIME.swapSwapperAndSpace().
*
* SystemResponse: A symbol has been swapped with a space character. E.g. punctuation may swap
@@ -1213,7 +1238,12 @@
public static void latinIME_swapSwapperAndSpace(final CharSequence originalCharacters,
final String charactersAfterSwap) {
final ResearchLogger researchLogger = getInstance();
- final LogUnit logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit();
+ final LogUnit logUnit;
+ if (researchLogger.mMainLogBuffer == null) {
+ logUnit = null;
+ } else {
+ logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit();
+ }
if (logUnit != null) {
researchLogger.enqueueEvent(logUnit, LOGSTATEMENT_LATINIME_SWAPSWAPPERANDSPACE,
originalCharacters, charactersAfterSwap);
@@ -1258,8 +1288,9 @@
public static void mainKeyboardView_setKeyboard(final Keyboard keyboard) {
final KeyboardId kid = keyboard.mId;
final boolean isPasswordView = kid.passwordInput();
- getInstance().setIsPasswordView(isPasswordView);
- getInstance().enqueueEvent(LOGSTATEMENT_MAINKEYBOARDVIEW_SETKEYBOARD,
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.setIsPasswordView(isPasswordView);
+ researchLogger.enqueueEvent(LOGSTATEMENT_MAINKEYBOARDVIEW_SETKEYBOARD,
KeyboardId.elementIdToName(kid.mElementId),
kid.mLocale + ":" + kid.mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
kid.mOrientation, kid.mWidth, KeyboardId.modeName(kid.mMode), kid.imeAction(),
@@ -1278,22 +1309,27 @@
*/
private static final LogStatement LOGSTATEMENT_LATINIME_REVERTCOMMIT =
new LogStatement("LatinIMERevertCommit", true, false, "committedWord",
- "originallyTypedWord");
+ "originallyTypedWord", "separatorString");
public static void latinIME_revertCommit(final String committedWord,
- final String originallyTypedWord, final boolean isBatchMode) {
+ final String originallyTypedWord, final boolean isBatchMode,
+ final String separatorString) {
final ResearchLogger researchLogger = getInstance();
- // Assume that mCurrentLogUnit has been restored to contain the reverted word.
- final LogUnit logUnit = researchLogger.mCurrentLogUnit;
+ // TODO: Verify that mCurrentLogUnit has been restored and contains the reverted word.
+ final LogUnit logUnit;
+ if (researchLogger.mMainLogBuffer == null) {
+ logUnit = null;
+ } else {
+ logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit();
+ }
if (originallyTypedWord.length() > 0 && hasLetters(originallyTypedWord)) {
if (logUnit != null) {
- // Probably not necessary, but setting as a precaution in case the word isn't
- // committed later.
logUnit.setWord(originallyTypedWord);
}
}
researchLogger.enqueueEvent(logUnit != null ? logUnit : researchLogger.mCurrentLogUnit,
- LOGSTATEMENT_LATINIME_REVERTCOMMIT, committedWord, originallyTypedWord);
- researchLogger.mStatistics.recordRevertCommit();
+ LOGSTATEMENT_LATINIME_REVERTCOMMIT, committedWord, originallyTypedWord,
+ separatorString);
+ researchLogger.mStatistics.recordRevertCommit(SystemClock.uptimeMillis());
researchLogger.commitCurrentLogUnitAsWord(originallyTypedWord, Long.MAX_VALUE, isBatchMode);
}
@@ -1424,10 +1460,17 @@
final String scrubbedTypedWord = scrubDigitsFromString(typedWord);
final String scrubbedAutoCorrection = scrubDigitsFromString(autoCorrection);
final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_COMMITCURRENTAUTOCORRECTION,
- scrubbedTypedWord, scrubbedAutoCorrection, separatorString);
researchLogger.commitCurrentLogUnitAsWord(scrubbedAutoCorrection, Long.MAX_VALUE,
isBatchMode);
+
+ // Add the autocorrection logStatement at the end of the logUnit for the committed word.
+ // We have to do this after calling commitCurrentLogUnitAsWord, because it may split the
+ // current logUnit, and then we have to peek to get the logUnit reference back.
+ final LogUnit logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit();
+ // TODO: Add test to confirm that the commitCurrentAutoCorrection log statement should
+ // always be added to logUnit (if non-null) and not mCurrentLogUnit.
+ researchLogger.enqueueEvent(logUnit, LOGSTATEMENT_LATINIME_COMMITCURRENTAUTOCORRECTION,
+ scrubbedTypedWord, scrubbedAutoCorrection, separatorString);
}
private boolean isExpectingCommitText = false;
@@ -1616,20 +1659,58 @@
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_ONENDBATCHINPUT, enteredText,
enteredWordPos);
- researchLogger.mStatistics.recordGestureInput(enteredText.length());
+ researchLogger.mStatistics.recordGestureInput(enteredText.length(),
+ SystemClock.uptimeMillis());
}
/**
- * Log a call to LatinIME.handleBackspace().
+ * Log a call to LatinIME.handleBackspace() that is not a batch delete.
+ *
+ * UserInput: The user is deleting one or more characters by hitting the backspace key once.
+ * The covers single character deletes as well as deleting selections.
+ */
+ private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE =
+ new LogStatement("LatinIMEHandleBackspace", true, false, "numCharacters");
+ public static void latinIME_handleBackspace(final int numCharacters) {
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE, numCharacters);
+ }
+
+ /**
+ * Log a call to LatinIME.handleBackspace() that is a batch delete.
*
* UserInput: The user is deleting a gestured word by hitting the backspace key once.
*/
private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE_BATCH =
- new LogStatement("LatinIMEHandleBackspaceBatch", true, false, "deletedText");
- public static void latinIME_handleBackspace_batch(final CharSequence deletedText) {
+ new LogStatement("LatinIMEHandleBackspaceBatch", true, false, "deletedText",
+ "numCharacters");
+ public static void latinIME_handleBackspace_batch(final CharSequence deletedText,
+ final int numCharacters) {
final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE_BATCH, deletedText);
- researchLogger.mStatistics.recordGestureDelete();
+ researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE_BATCH, deletedText,
+ numCharacters);
+ researchLogger.mStatistics.recordGestureDelete(deletedText.length(),
+ SystemClock.uptimeMillis());
+ }
+
+ /**
+ * Log a long interval between user operation.
+ *
+ * UserInput: The user has not done anything for a while.
+ */
+ private static final LogStatement LOGSTATEMENT_ONUSERPAUSE = new LogStatement("OnUserPause",
+ false, false, "intervalInMs");
+ public static void onUserPause(final long interval) {
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.enqueueEvent(LOGSTATEMENT_ONUSERPAUSE, interval);
+ }
+
+ public static void latinIME_handleSeparator() {
+ // Reset the saved down event time. For tapping, motion events, etc. before the separator
+ // are assigned to the previous LogUnit, and events after the separator are assigned to the
+ // next LogUnit. In the case of multitap, this might capture down events corresponding to
+ // the next word, however it should not be more than a character or two.
+ getInstance().setSavedDownEventTime(SystemClock.uptimeMillis());
}
/**
diff --git a/java/src/com/android/inputmethod/research/Statistics.java b/java/src/com/android/inputmethod/research/Statistics.java
index e9c02c9..a920265 100644
--- a/java/src/com/android/inputmethod/research/Statistics.java
+++ b/java/src/com/android/inputmethod/research/Statistics.java
@@ -134,17 +134,9 @@
if (DEBUG) {
Log.d(TAG, "recordChar() called");
}
- final long delta = time - mLastTapTime;
if (codePoint == Constants.CODE_DELETE) {
mDeleteKeyCount++;
- if (delta < MIN_DELETION_INTERMISSION) {
- if (mIsLastKeyDeleteKey) {
- mDuringRepeatedDeleteKeysCounter.add(delta);
- } else {
- mBeforeDeleteKeyCounter.add(delta);
- }
- }
- mIsLastKeyDeleteKey = true;
+ recordUserAction(time, true /* isDeletion */);
} else {
mCharCount++;
if (Character.isDigit(codePoint)) {
@@ -156,14 +148,8 @@
if (Character.isSpaceChar(codePoint)) {
mSpaceCount++;
}
- if (mIsLastKeyDeleteKey && delta < MIN_DELETION_INTERMISSION) {
- mAfterDeleteKeyCounter.add(delta);
- } else if (!mIsLastKeyDeleteKey && delta < MIN_TYPING_INTERMISSION) {
- mKeyCounter.add(delta);
- }
- mIsLastKeyDeleteKey = false;
+ recordUserAction(time, false /* isDeletion */);
}
- mLastTapTime = time;
}
public void recordWordEntered(final boolean isDictionaryWord) {
@@ -177,9 +163,10 @@
mSplitWordsCount++;
}
- public void recordGestureInput(final int numCharsEntered) {
+ public void recordGestureInput(final int numCharsEntered, final long time) {
mGesturesInputCount++;
mGesturesCharsCount += numCharsEntered;
+ recordUserAction(time, false /* isDeletion */);
}
public void setIsEmptyUponStarting(final boolean isEmpty) {
@@ -187,14 +174,43 @@
mIsEmptinessStateKnown = true;
}
- public void recordGestureDelete() {
+ public void recordGestureDelete(final int length, final long time) {
mGesturesDeletedCount++;
- }
- public void recordManualSuggestion() {
- mManualSuggestionsCount++;
+ recordUserAction(time, true /* isDeletion */);
}
- public void recordRevertCommit() {
+ public void recordManualSuggestion(final long time) {
+ mManualSuggestionsCount++;
+ recordUserAction(time, false /* isDeletion */);
+ }
+
+ public void recordRevertCommit(final long time) {
mRevertCommitsCount++;
+ recordUserAction(time, true /* isDeletion */);
+ }
+
+ private void recordUserAction(final long time, final boolean isDeletion) {
+ final long delta = time - mLastTapTime;
+ if (isDeletion) {
+ if (delta < MIN_DELETION_INTERMISSION) {
+ if (mIsLastKeyDeleteKey) {
+ mDuringRepeatedDeleteKeysCounter.add(delta);
+ } else {
+ mBeforeDeleteKeyCounter.add(delta);
+ }
+ } else {
+ ResearchLogger.onUserPause(delta);
+ }
+ } else {
+ if (mIsLastKeyDeleteKey && delta < MIN_DELETION_INTERMISSION) {
+ mAfterDeleteKeyCounter.add(delta);
+ } else if (!mIsLastKeyDeleteKey && delta < MIN_TYPING_INTERMISSION) {
+ mKeyCounter.add(delta);
+ } else {
+ ResearchLogger.onUserPause(delta);
+ }
+ }
+ mIsLastKeyDeleteKey = isDeletion;
+ mLastTapTime = time;
}
}
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 4e34f98..d787327 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -43,7 +43,7 @@
static void releaseDictBuf(const void *dictBuf, const size_t length, const int fd);
static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object, jstring sourceDir,
- jlong dictOffset, jlong dictSize, jint maxWordLength, jint maxWords, jint maxPredictions) {
+ jlong dictOffset, jlong dictSize, jint maxWordLength) {
PROF_OPEN;
PROF_START(66);
const jsize sourceDirUtf8Length = env->GetStringUTFLength(sourceDir);
@@ -117,8 +117,7 @@
releaseDictBuf(dictBuf, 0, 0);
#endif // USE_MMAP_FOR_DICTIONARY
} else {
- dictionary = new Dictionary(dictBuf, static_cast<int>(dictSize), fd, adjust, maxWordLength,
- maxWords, maxPredictions);
+ dictionary = new Dictionary(dictBuf, static_cast<int>(dictSize), fd, adjust, maxWordLength);
}
PROF_END(66);
PROF_CLOSE;
@@ -163,6 +162,14 @@
const jsize outputCodePointsLength = env->GetArrayLength(outputCodePointsArray);
int outputCodePoints[outputCodePointsLength];
const jsize scoresLength = env->GetArrayLength(scoresArray);
+
+ /* By the way, let's check the output array length here to make sure */
+ if (scoresLength < MAX_RESULTS) {
+ ASSERT(false);
+ return 0;
+ }
+
+ // Cont'd: Output values
int scores[scoresLength];
const jsize spaceIndicesLength = env->GetArrayLength(spaceIndicesArray);
int spaceIndices[spaceIndicesLength];
@@ -270,7 +277,7 @@
}
static JNINativeMethod sMethods[] = {
- {"openNative", "(Ljava/lang/String;JJIII)J",
+ {"openNative", "(Ljava/lang/String;JJI)J",
reinterpret_cast<void *>(latinime_BinaryDictionary_open)},
{"closeNative", "(J)V", reinterpret_cast<void *>(latinime_BinaryDictionary_close)},
{"getSuggestionsNative", "(JJJ[I[I[I[I[IIIZ[IZ[I[I[I[I)I",
diff --git a/native/jni/src/bigram_dictionary.cpp b/native/jni/src/bigram_dictionary.cpp
index e62ae6f..733e861 100644
--- a/native/jni/src/bigram_dictionary.cpp
+++ b/native/jni/src/bigram_dictionary.cpp
@@ -26,8 +26,8 @@
namespace latinime {
-BigramDictionary::BigramDictionary(const unsigned char *dict, int maxWordLength, int maxPredictions)
- : DICT(dict), MAX_WORD_LENGTH(maxWordLength), MAX_PREDICTIONS(maxPredictions) {
+BigramDictionary::BigramDictionary(const unsigned char *dict, int maxWordLength)
+ : DICT(dict), MAX_WORD_LENGTH(maxWordLength) {
if (DEBUG_DICT) {
AKLOGI("BigramDictionary - constructor");
}
@@ -36,7 +36,7 @@
BigramDictionary::~BigramDictionary() {
}
-bool BigramDictionary::addWordBigram(int *word, int length, int frequency, int *bigramFreq,
+void BigramDictionary::addWordBigram(int *word, int length, int frequency, int *bigramFreq,
int *bigramCodePoints, int *outputTypes) const {
word[length] = 0;
if (DEBUG_DICT) {
@@ -49,7 +49,7 @@
// Find the right insertion point
int insertAt = 0;
- while (insertAt < MAX_PREDICTIONS) {
+ while (insertAt < MAX_RESULTS) {
if (frequency > bigramFreq[insertAt] || (bigramFreq[insertAt] == frequency
&& length < Dictionary::wideStrLen(
bigramCodePoints + insertAt * MAX_WORD_LENGTH))) {
@@ -58,28 +58,27 @@
insertAt++;
}
if (DEBUG_DICT) {
- AKLOGI("Bigram: InsertAt -> %d MAX_PREDICTIONS: %d", insertAt, MAX_PREDICTIONS);
+ AKLOGI("Bigram: InsertAt -> %d MAX_RESULTS: %d", insertAt, MAX_RESULTS);
}
- if (insertAt < MAX_PREDICTIONS) {
- memmove(bigramFreq + (insertAt + 1),
- bigramFreq + insertAt,
- (MAX_PREDICTIONS - insertAt - 1) * sizeof(bigramFreq[0]));
- bigramFreq[insertAt] = frequency;
- outputTypes[insertAt] = Dictionary::KIND_PREDICTION;
- memmove(bigramCodePoints + (insertAt + 1) * MAX_WORD_LENGTH,
- bigramCodePoints + insertAt * MAX_WORD_LENGTH,
- (MAX_PREDICTIONS - insertAt - 1) * sizeof(bigramCodePoints[0]) * MAX_WORD_LENGTH);
- int *dest = bigramCodePoints + insertAt * MAX_WORD_LENGTH;
- while (length--) {
- *dest++ = *word++;
- }
- *dest = 0; // NULL terminate
- if (DEBUG_DICT) {
- AKLOGI("Bigram: Added word at %d", insertAt);
- }
- return true;
+ if (insertAt >= MAX_RESULTS) {
+ return;
}
- return false;
+ memmove(bigramFreq + (insertAt + 1),
+ bigramFreq + insertAt,
+ (MAX_RESULTS - insertAt - 1) * sizeof(bigramFreq[0]));
+ bigramFreq[insertAt] = frequency;
+ outputTypes[insertAt] = Dictionary::KIND_PREDICTION;
+ memmove(bigramCodePoints + (insertAt + 1) * MAX_WORD_LENGTH,
+ bigramCodePoints + insertAt * MAX_WORD_LENGTH,
+ (MAX_RESULTS - insertAt - 1) * sizeof(bigramCodePoints[0]) * MAX_WORD_LENGTH);
+ int *dest = bigramCodePoints + insertAt * MAX_WORD_LENGTH;
+ while (length--) {
+ *dest++ = *word++;
+ }
+ *dest = 0; // NULL terminate
+ if (DEBUG_DICT) {
+ AKLOGI("Bigram: Added word at %d", insertAt);
+ }
}
/* Parameters :
@@ -135,13 +134,12 @@
// here, but it can't get too bad.
const int frequency =
BinaryFormat::computeFrequencyForBigram(unigramFreq, bigramFreqTemp);
- if (addWordBigram(bigramBuffer, length, frequency, bigramFreq, bigramCodePoints,
- outputTypes)) {
- ++bigramCount;
- }
+ addWordBigram(bigramBuffer, length, frequency, bigramFreq, bigramCodePoints,
+ outputTypes);
+ ++bigramCount;
}
} while (BinaryFormat::FLAG_ATTRIBUTE_HAS_NEXT & bigramFlags);
- return bigramCount;
+ return min(bigramCount, MAX_RESULTS);
}
// Returns a pointer to the start of the bigram list.
diff --git a/native/jni/src/bigram_dictionary.h b/native/jni/src/bigram_dictionary.h
index 150192d..c2535c7 100644
--- a/native/jni/src/bigram_dictionary.h
+++ b/native/jni/src/bigram_dictionary.h
@@ -26,7 +26,7 @@
class BigramDictionary {
public:
- BigramDictionary(const unsigned char *dict, int maxWordLength, int maxPredictions);
+ BigramDictionary(const unsigned char *dict, int maxWordLength);
int getBigrams(const int *word, int length, int *inputCodes, int codesSize, int *outWords,
int *frequencies, int *outputTypes) const;
void fillBigramAddressToFrequencyMapAndFilter(const int *prevWord, const int prevWordLength,
@@ -35,7 +35,7 @@
~BigramDictionary();
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(BigramDictionary);
- bool addWordBigram(int *word, int length, int frequency, int *bigramFreq, int *bigramCodePoints,
+ void addWordBigram(int *word, int length, int frequency, int *bigramFreq, int *bigramCodePoints,
int *outputTypes) const;
int getBigramAddress(int *pos, bool advance);
int getBigramFreq(int *pos);
@@ -48,7 +48,6 @@
const unsigned char *DICT;
const int MAX_WORD_LENGTH;
- const int MAX_PREDICTIONS;
// TODO: Re-implement proximity correction for bigram correction
static const int MAX_ALTERNATIVES = 1;
};
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 96abfe8..e39d0e5 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -347,13 +347,8 @@
#define SUPPRESS_SHORT_MULTIPLE_WORDS_THRESHOLD_FREQ (MAX_FREQ * 58 / 100)
#define MAX_DEPTH_MULTIPLIER 3
-
#define FIRST_WORD_INDEX 0
-
-#define MAX_SPACES_INTERNAL 16
-
-// TODO: Change this to MAX_WORDS, remove MAX_WORDS in Java, and stop getting it from Java
-#define MAX_WORDS_INTERNAL 18
+#define MAX_RESULTS 18 /* Must be identical to BinaryDictionary.MAX_RESULTS in Java */
// Max Distance between point to key
#define MAX_POINT_TO_KEY_LENGTH 10000000
diff --git a/native/jni/src/dictionary.cpp b/native/jni/src/dictionary.cpp
index 167b36f..f99f826 100644
--- a/native/jni/src/dictionary.cpp
+++ b/native/jni/src/dictionary.cpp
@@ -28,15 +28,14 @@
namespace latinime {
-Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int maxWordLength,
- int maxWords, int maxPredictions)
+Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int maxWordLength)
: mDict(static_cast<unsigned char *>(dict)),
mOffsetDict((static_cast<unsigned char *>(dict)) + BinaryFormat::getHeaderSize(mDict)),
mDictSize(dictSize), mMmapFd(mmapFd), mDictBufAdjust(dictBufAdjust),
- mUnigramDictionary(new UnigramDictionary(mOffsetDict, maxWordLength, maxWords,
+ mUnigramDictionary(new UnigramDictionary(mOffsetDict, maxWordLength,
BinaryFormat::getFlags(mDict))),
- mBigramDictionary(new BigramDictionary(mOffsetDict, maxWordLength, maxPredictions)),
- mGestureSuggest(new GestureSuggest(maxWordLength, maxWords)) {
+ mBigramDictionary(new BigramDictionary(mOffsetDict, maxWordLength)),
+ mGestureSuggest(new GestureSuggest(maxWordLength)) {
if (DEBUG_DICT) {
if (MAX_WORD_LENGTH_INTERNAL < maxWordLength) {
AKLOGI("Max word length (%d) is greater than %d",
diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h
index 26edc4f..5674803 100644
--- a/native/jni/src/dictionary.h
+++ b/native/jni/src/dictionary.h
@@ -41,8 +41,7 @@
const static int KIND_SHORTCUT = 7; // A shortcut
const static int KIND_PREDICTION = 8; // A prediction (== a suggestion with no input)
- Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int maxWordLength,
- int maxWords, int maxPredictions);
+ Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int maxWordLength);
int getSuggestions(ProximityInfo *proximityInfo, void *traverseSession, int *xcoordinates,
int *ycoordinates, int *times, int *pointerIds, int *codes, int codesSize,
diff --git a/native/jni/src/suggest/gesture_suggest.cpp b/native/jni/src/suggest/gesture_suggest.cpp
index 2a604b8..f138dae 100644
--- a/native/jni/src/suggest/gesture_suggest.cpp
+++ b/native/jni/src/suggest/gesture_suggest.cpp
@@ -17,7 +17,7 @@
#include "gesture_suggest.h"
namespace latinime {
- SuggestInterface *(*GestureSuggest::sGestureSuggestFactoryMethod)(int, int) = 0;
+ SuggestInterface *(*GestureSuggest::sGestureSuggestFactoryMethod)(int) = 0;
GestureSuggest::~GestureSuggest() {
delete mSuggestInterface;
diff --git a/native/jni/src/suggest/gesture_suggest.h b/native/jni/src/suggest/gesture_suggest.h
index e4af03f..41297cc 100644
--- a/native/jni/src/suggest/gesture_suggest.h
+++ b/native/jni/src/suggest/gesture_suggest.h
@@ -26,8 +26,8 @@
class GestureSuggest : public SuggestInterface {
public:
- GestureSuggest(const int maxWordLength, const int maxWords)
- : mSuggestInterface(getGestureSuggestInstance(maxWordLength, maxWords)) {
+ GestureSuggest(const int maxWordLength)
+ : mSuggestInterface(getGestureSuggestInstance(maxWordLength)) {
}
virtual ~GestureSuggest();
@@ -43,20 +43,20 @@
outputTypes);
}
- static void setGestureSuggestFactoryMethod(SuggestInterface *(*factoryMethod)(int, int)) {
+ static void setGestureSuggestFactoryMethod(SuggestInterface *(*factoryMethod)(int)) {
sGestureSuggestFactoryMethod = factoryMethod;
}
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(GestureSuggest);
- static SuggestInterface *getGestureSuggestInstance(int maxWordLength, int maxWords) {
+ static SuggestInterface *getGestureSuggestInstance(int maxWordLength) {
if (!sGestureSuggestFactoryMethod) {
return 0;
}
- return sGestureSuggestFactoryMethod(maxWordLength, maxWords);
+ return sGestureSuggestFactoryMethod(maxWordLength);
}
- static SuggestInterface *(*sGestureSuggestFactoryMethod)(int, int);
+ static SuggestInterface *(*sGestureSuggestFactoryMethod)(int);
SuggestInterface *mSuggestInterface;
};
} // namespace latinime
diff --git a/native/jni/src/suggest/typing_suggest.cpp b/native/jni/src/suggest/typing_suggest.cpp
index 40d4a98..320feef 100644
--- a/native/jni/src/suggest/typing_suggest.cpp
+++ b/native/jni/src/suggest/typing_suggest.cpp
@@ -17,7 +17,7 @@
#include "typing_suggest.h"
namespace latinime {
- SuggestInterface *(*TypingSuggest::sTypingSuggestFactoryMethod)(int, int) = 0;
+ SuggestInterface *(*TypingSuggest::sTypingSuggestFactoryMethod)(int) = 0;
TypingSuggest::~TypingSuggest() {
delete mSuggestInterface;
diff --git a/native/jni/src/suggest/typing_suggest.h b/native/jni/src/suggest/typing_suggest.h
index 9de4158..99d0c50 100644
--- a/native/jni/src/suggest/typing_suggest.h
+++ b/native/jni/src/suggest/typing_suggest.h
@@ -26,8 +26,8 @@
class TypingSuggest : public SuggestInterface {
public:
- TypingSuggest(const int maxWordLength, const int maxWords)
- : mSuggestInterface(getTypingSuggestInstance(maxWordLength, maxWords)) {
+ TypingSuggest(const int maxWordLength)
+ : mSuggestInterface(getTypingSuggestInstance(maxWordLength)) {
}
virtual ~TypingSuggest();
@@ -43,20 +43,20 @@
outputTypes);
}
- static void setTypingSuggestFactoryMethod(SuggestInterface *(*factoryMethod)(int, int)) {
+ static void setTypingSuggestFactoryMethod(SuggestInterface *(*factoryMethod)(int)) {
sTypingSuggestFactoryMethod = factoryMethod;
}
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(TypingSuggest);
- static SuggestInterface *getTypingSuggestInstance(int maxWordLength, int maxWords) {
+ static SuggestInterface *getTypingSuggestInstance(int maxWordLength) {
if (!sTypingSuggestFactoryMethod) {
return 0;
}
- return sTypingSuggestFactoryMethod(maxWordLength, maxWords);
+ return sTypingSuggestFactoryMethod(maxWordLength);
}
- static SuggestInterface *(*sTypingSuggestFactoryMethod)(int, int);
+ static SuggestInterface *(*sTypingSuggestFactoryMethod)(int);
SuggestInterface *mSuggestInterface;
};
} // namespace latinime
diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp
index 0a14425..52a9b27 100644
--- a/native/jni/src/unigram_dictionary.cpp
+++ b/native/jni/src/unigram_dictionary.cpp
@@ -41,9 +41,9 @@
// TODO: check the header
UnigramDictionary::UnigramDictionary(const uint8_t *const streamStart, int maxWordLength,
- int maxWords, const unsigned int flags)
- : DICT_ROOT(streamStart), MAX_WORD_LENGTH(maxWordLength), MAX_WORDS(maxWords),
- ROOT_POS(0), MAX_DIGRAPH_SEARCH_DEPTH(DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH), FLAGS(flags) {
+ const unsigned int flags)
+ : DICT_ROOT(streamStart), MAX_WORD_LENGTH(maxWordLength), ROOT_POS(0),
+ MAX_DIGRAPH_SEARCH_DEPTH(DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH), FLAGS(flags) {
if (DEBUG_DICT) {
AKLOGI("UnigramDictionary - constructor");
}
@@ -170,7 +170,7 @@
const int *ycoordinates, const int *codes, const int codesSize,
const std::map<int, int> *bigramMap, const uint8_t *bigramFilter,
const bool useFullEditDistance, int *outWords, int *frequencies, int *outputTypes) const {
- WordsPriorityQueuePool queuePool(MAX_WORDS, SUB_QUEUE_MAX_WORDS, MAX_WORD_LENGTH);
+ WordsPriorityQueuePool queuePool(MAX_RESULTS, SUB_QUEUE_MAX_WORDS, MAX_WORD_LENGTH);
queuePool.clearAll();
Correction masterCorrection;
masterCorrection.resetCorrection();
diff --git a/native/jni/src/unigram_dictionary.h b/native/jni/src/unigram_dictionary.h
index f5850b4..2301d63 100644
--- a/native/jni/src/unigram_dictionary.h
+++ b/native/jni/src/unigram_dictionary.h
@@ -39,7 +39,7 @@
static const int FLAG_MULTIPLE_SUGGEST_ABORT = 0;
static const int FLAG_MULTIPLE_SUGGEST_SKIP = 1;
static const int FLAG_MULTIPLE_SUGGEST_CONTINUE = 2;
- UnigramDictionary(const uint8_t *const streamStart, int maxWordLength, int maxWords,
+ UnigramDictionary(const uint8_t *const streamStart, int maxWordLength,
const unsigned int flags);
int getFrequency(const int *const inWord, const int length) const;
int getBigramPosition(int pos, int *word, int offset, int length) const;
@@ -110,7 +110,6 @@
const uint8_t *const DICT_ROOT;
const int MAX_WORD_LENGTH;
- const int MAX_WORDS;
const int ROOT_POS;
const int MAX_DIGRAPH_SEARCH_DEPTH;
const int FLAGS;