aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/res/values/strings-talkback-descriptions.xml4
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java2
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java25
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java105
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java17
-rw-r--r--java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java8
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java15
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java12
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java69
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java4
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java12
-rw-r--r--java/src/com/android/inputmethod/latin/PrevWordsInfo.java6
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java6
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java7
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java16
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java10
-rw-r--r--java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java19
18 files changed, 197 insertions, 142 deletions
diff --git a/java/res/values/strings-talkback-descriptions.xml b/java/res/values/strings-talkback-descriptions.xml
index 14455d088..d7978b0c8 100644
--- a/java/res/values/strings-talkback-descriptions.xml
+++ b/java/res/values/strings-talkback-descriptions.xml
@@ -128,11 +128,13 @@
<string name="spoken_descrption_emoji_category_emoticons">Emoticons</string>
<!-- Description of an upper case letter of LOWER_LETTER. -->
- <string name="spoke_description_upper_case">Capital <xliff:g id="LOWER_LETTER" example="A, E, ligature">%s</xliff:g></string>
+ <string name="spoken_description_upper_case">Capital <xliff:g id="LOWER_LETTER" example="A, E, ligature">%s</xliff:g></string>
<!-- Spoken description for Unicode code point U+0049: "I" LATIN CAPITAL LETTER I
Note that depending on locale, the lower-case of this letter is U+0069 or U+0131. -->
<string name="spoken_letter_0049">Capital I</string>
<!-- Spoken description for Unicode code point U+0130: "İ" LATIN CAPITAL LETTER I WITH DOT ABOVE
Note that depending on locale, the lower-case of this letter is U+0069 or U+0131. -->
<string name="spoken_letter_0130">Capital I, dot above</string>
+ <!-- Spoken description for unknown emoji code point. -->
+ <string name="spoken_emoji_unknown">Unknown emoji</string>
</resources>
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
index d50dd3ee6..27896fd11 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -114,7 +114,7 @@ public final class AccessibilityUtils {
* @param event The event to check.
* @return {@true} is the event is a touch exploration event
*/
- public boolean isTouchExplorationEvent(final MotionEvent event) {
+ public static boolean isTouchExplorationEvent(final MotionEvent event) {
final int action = event.getAction();
return action == MotionEvent.ACTION_HOVER_ENTER
|| action == MotionEvent.ACTION_HOVER_EXIT
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index 2c87fc1e9..58672ace7 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -285,15 +285,14 @@ public final class KeyCodeDescriptionMapper {
if (index >= 0) {
return context.getString(mKeyCodeMap.valueAt(index));
}
- final String accentedLetter = getSpokenAccentedLetterDescriptionId(context, code);
+ final String accentedLetter = getSpokenAccentedLetterDescription(context, code);
if (accentedLetter != null) {
return accentedLetter;
}
- // Here, <code>code</code> may be a base letter.
- final int spokenEmojiId = getSpokenDescriptionId(
- context, code, SPOKEN_EMOJI_RESOURCE_NAME_FORMAT);
- if (spokenEmojiId != 0) {
- return context.getString(spokenEmojiId);
+ // Here, <code>code</code> may be a base (non-accented) letter.
+ final String emojiDescription = getSpokenEmojiDescription(context, code);
+ if (emojiDescription != null) {
+ return emojiDescription;
}
if (isDefinedNonCtrl) {
return Character.toString((char) code);
@@ -304,7 +303,7 @@ public final class KeyCodeDescriptionMapper {
return context.getString(R.string.spoken_description_unknown, code);
}
- private String getSpokenAccentedLetterDescriptionId(final Context context, final int code) {
+ private String getSpokenAccentedLetterDescription(final Context context, final int code) {
final boolean isUpperCase = Character.isUpperCase(code);
final int baseCode = isUpperCase ? Character.toLowerCase(code) : code;
final int baseIndex = mKeyCodeMap.indexOfKey(baseCode);
@@ -314,7 +313,17 @@ public final class KeyCodeDescriptionMapper {
return null;
}
final String spokenText = context.getString(resId);
- return isUpperCase ? context.getString(R.string.spoke_description_upper_case, spokenText)
+ return isUpperCase ? context.getString(R.string.spoken_description_upper_case, spokenText)
+ : spokenText;
+ }
+
+ private String getSpokenEmojiDescription(final Context context, final int code) {
+ final int resId = getSpokenDescriptionId(context, code, SPOKEN_EMOJI_RESOURCE_NAME_FORMAT);
+ if (resId == 0) {
+ return null;
+ }
+ final String spokenText = context.getString(resId);
+ return TextUtils.isEmpty(spokenText) ? context.getString(R.string.spoken_emoji_unknown)
: spokenText;
}
diff --git a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
index eed40f4a9..0ebad9774 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.accessibility;
+import android.content.Context;
import android.os.SystemClock;
import android.support.v4.view.AccessibilityDelegateCompat;
import android.support.v4.view.ViewCompat;
@@ -37,7 +38,7 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
protected final KeyDetector mKeyDetector;
private Keyboard mKeyboard;
private KeyboardAccessibilityNodeProvider mAccessibilityNodeProvider;
- private Key mLastHoverKey;
+ private Key mCurrentHoverKey;
public KeyboardAccessibilityDelegate(final KV keyboardView, final KeyDetector keyDetector) {
super();
@@ -70,6 +71,19 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
}
/**
+ * Sends a window state change event with the specified string resource id.
+ *
+ * @param resId The string resource id of the text to send with the event.
+ */
+ protected void sendWindowStateChanged(final int resId) {
+ if (resId == 0) {
+ return;
+ }
+ final Context context = mKeyboardView.getContext();
+ sendWindowStateChanged(context.getString(resId));
+ }
+
+ /**
* Sends a window state change event with the specified text.
*
* @param text The text to send with the event.
@@ -117,14 +131,14 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
* Receives hover events when touch exploration is turned on in SDK versions ICS and higher.
*
* @param event The hover event.
- * @return {@code true} if the event is handled
+ * @return {@code true} if the event is handled.
*/
- public boolean dispatchHoverEvent(final MotionEvent event) {
+ public boolean onHoverEvent(final MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
- final Key previousKey = mLastHoverKey;
+ final Key previousKey = mCurrentHoverKey;
final Key key = mKeyDetector.detectHitKey(x, y);
- mLastHoverKey = key;
+ mCurrentHoverKey = key;
switch (event.getAction()) {
case MotionEvent.ACTION_HOVER_EXIT:
@@ -133,17 +147,30 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
if (key != null) {
final long downTime = simulateKeyPress(key);
simulateKeyRelease(key, downTime);
+ onHoverExitKey(key);
}
- //$FALL-THROUGH$
+ mCurrentHoverKey = null;
+ break;
case MotionEvent.ACTION_HOVER_ENTER:
- return onHoverKey(key, event);
+ if (key != null) {
+ onHoverEnterKey(key);
+ }
+ break;
case MotionEvent.ACTION_HOVER_MOVE:
if (key != previousKey) {
- return onTransitionKey(key, previousKey, event);
+ if (previousKey != null) {
+ onHoverExitKey(previousKey);
+ }
+ if (key != null) {
+ onHoverEnterKey(key);
+ }
+ }
+ if (key != null) {
+ onHoverMoveKey(key);
}
- return onHoverKey(key, event);
+ break;
}
- return false;
+ return true;
}
/**
@@ -151,6 +178,7 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
* This avoids the complexity of trackers and listeners within the keyboard.
*
* @param key The key to press.
+ * @return the event time of the simulated key press.
*/
private long simulateKeyPress(final Key key) {
final int x = key.getHitBox().centerX();
@@ -168,6 +196,7 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
* This avoids the complexity of trackers and listeners within the keyboard.
*
* @param key The key to release.
+ * @param downTime the event time of the key press.
*/
private void simulateKeyRelease(final Key key, final long downTime) {
final int x = key.getHitBox().centerX();
@@ -179,54 +208,30 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
}
/**
- * Simulates a transition between two {@link Key}s by sending a HOVER_EXIT on the previous key,
- * a HOVER_ENTER on the current key, and a HOVER_MOVE on the current key.
+ * Handles a hover enter event on a key.
*
- * @param currentKey The currently hovered key.
- * @param previousKey The previously hovered key.
- * @param event The event that triggered the transition.
- * @return {@code true} if the event was handled.
+ * @param key The currently hovered key.
*/
- private boolean onTransitionKey(final Key currentKey, final Key previousKey,
- final MotionEvent event) {
- final int savedAction = event.getAction();
- event.setAction(MotionEvent.ACTION_HOVER_EXIT);
- onHoverKey(previousKey, event);
- event.setAction(MotionEvent.ACTION_HOVER_ENTER);
- onHoverKey(currentKey, event);
- event.setAction(MotionEvent.ACTION_HOVER_MOVE);
- final boolean handled = onHoverKey(currentKey, event);
- event.setAction(savedAction);
- return handled;
+ protected void onHoverEnterKey(final Key key) {
+ final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
+ provider.sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER);
+ provider.performActionForKey(key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS);
}
/**
- * Handles a hover event on a key. If {@link Key} extended View, this would be analogous to
- * calling View.onHoverEvent(MotionEvent).
+ * Handles a hover move event on a key.
*
* @param key The currently hovered key.
- * @param event The hover event.
- * @return {@code true} if the event was handled.
*/
- private boolean onHoverKey(final Key key, final MotionEvent event) {
- // Null keys can't receive events.
- if (key == null) {
- return false;
- }
- final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
+ protected void onHoverMoveKey(final Key key) { }
- switch (event.getAction()) {
- case MotionEvent.ACTION_HOVER_ENTER:
- provider.sendAccessibilityEventForKey(
- key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER);
- provider.performActionForKey(
- key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS, null);
- break;
- case MotionEvent.ACTION_HOVER_EXIT:
- provider.sendAccessibilityEventForKey(
- key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT);
- break;
- }
- return true;
+ /**
+ * Handles a hover exit event on a key.
+ *
+ * @param key The currently hovered key.
+ */
+ protected void onHoverExitKey(final Key key) {
+ final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
+ provider.sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT);
}
}
diff --git a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java
index cddd1c7ed..a6997e2f9 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java
@@ -134,7 +134,7 @@ public final class KeyboardAccessibilityNodeProvider extends AccessibilityNodePr
event.setClassName(key.getClass().getName());
event.setContentDescription(keyDescription);
event.setEnabled(true);
- final AccessibilityRecordCompat record = new AccessibilityRecordCompat(event);
+ final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
record.setSource(mKeyboardView, virtualViewId);
return event;
}
@@ -229,7 +229,7 @@ public final class KeyboardAccessibilityNodeProvider extends AccessibilityNodePr
if (key == null) {
return false;
}
- return performActionForKey(key, action, arguments);
+ return performActionForKey(key, action);
}
/**
@@ -237,25 +237,16 @@ public final class KeyboardAccessibilityNodeProvider extends AccessibilityNodePr
*
* @param key The on which to perform the action.
* @param action The action to perform.
- * @param arguments The action's arguments.
* @return The result of performing the action, or false if the action is not supported.
*/
- boolean performActionForKey(final Key key, final int action, final Bundle arguments) {
- final int virtualViewId = getVirtualViewIdOf(key);
-
+ boolean performActionForKey(final Key key, final int action) {
switch (action) {
case AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS:
- if (mAccessibilityFocusedView == virtualViewId) {
- return false;
- }
- mAccessibilityFocusedView = virtualViewId;
+ mAccessibilityFocusedView = getVirtualViewIdOf(key);
sendAccessibilityEventForKey(
key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
return true;
case AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
- if (mAccessibilityFocusedView != virtualViewId) {
- return false;
- }
mAccessibilityFocusedView = UNDEFINED;
sendAccessibilityEventForKey(
key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
diff --git a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
index 443f793a1..ec6bb0156 100644
--- a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
+++ b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
@@ -163,17 +163,13 @@ public final class MainKeyboardAccessibilityDelegate
default:
return;
}
- final String text = mKeyboardView.getContext().getString(resId);
- sendWindowStateChanged(text);
+ sendWindowStateChanged(resId);
}
/**
* Announces that the keyboard has been hidden.
*/
private void announceKeyboardHidden() {
- final Context context = mKeyboardView.getContext();
- final String text = context.getString(R.string.announce_keyboard_hidden);
-
- sendWindowStateChanged(text);
+ sendWindowStateChanged(R.string.announce_keyboard_hidden);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 22c6b6e0a..f291a7ed0 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -763,19 +763,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
/**
- * Receives hover events from the input framework.
- *
- * @param event The motion event to be dispatched.
- * @return {@code true} if the event was handled by the view, {@code false}
- * otherwise
+ * {@inheritDoc}
*/
@Override
- public boolean dispatchHoverEvent(final MotionEvent event) {
- if (!AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
- // Reflection doesn't support calling superclass methods.
- return false;
+ public boolean onHoverEvent(final MotionEvent event) {
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ return mAccessibilityDelegate.onHoverEvent(event);
}
- return mAccessibilityDelegate.dispatchHoverEvent(event);
+ return super.onHoverEvent(event);
}
public void updateShortcutKey(final boolean available) {
diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
index 4d74ea989..0166802a4 100644
--- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
@@ -83,13 +83,15 @@ final class EmojiPageKeyboardView extends KeyboardView implements
mKeyDetector.setKeyboard(keyboard, 0 /* correctionX */, 0 /* correctionY */);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public boolean dispatchHoverEvent(final MotionEvent event) {
- if (!AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
- // Reflection doesn't support calling superclass methods.
- return false;
+ public boolean onHoverEvent(final MotionEvent event) {
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ return mAccessibilityDelegate.onHoverEvent(event);
}
- return mAccessibilityDelegate.dispatchHoverEvent(event);
+ return super.onHoverEvent(event);
}
/**
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 97f262989..fd34b98f4 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -183,9 +183,9 @@ public final class BinaryDictionary extends Dictionary {
private static native void getHeaderInfoNative(long dict, int[] outHeaderSize,
int[] outFormatVersion, ArrayList<int[]> outAttributeKeys,
ArrayList<int[]> outAttributeValues);
- private static native void flushNative(long dict, String filePath);
+ private static native boolean flushNative(long dict, String filePath);
private static native boolean needsToRunGCNative(long dict, boolean mindsBlockByGC);
- private static native void flushWithGCNative(long dict, String filePath);
+ private static native boolean flushWithGCNative(long dict, String filePath);
private static native void closeNative(long dict);
private static native int getFormatVersionNative(long dict);
private static native int getProbabilityNative(long dict, int[] word);
@@ -203,12 +203,12 @@ public final class BinaryDictionary extends Dictionary {
int[] outputSuggestionCount, int[] outputCodePoints, int[] outputScores,
int[] outputIndices, int[] outputTypes, int[] outputAutoCommitFirstWordConfidence,
float[] inOutLanguageWeight);
- private static native void addUnigramWordNative(long dict, int[] word, int probability,
+ private static native boolean addUnigramWordNative(long dict, int[] word, int probability,
int[] shortcutTarget, int shortcutProbability, boolean isBeginningOfSentence,
boolean isNotAWord, boolean isBlacklisted, int timestamp);
- private static native void addBigramWordsNative(long dict, int[] word0,
+ private static native boolean addBigramWordsNative(long dict, int[] word0,
boolean isBeginningOfSentence, int[] word1, int probability, int timestamp);
- private static native void removeBigramWordsNative(long dict, int[] word0,
+ private static native boolean removeBigramWordsNative(long dict, int[] word0,
boolean isBeginningOfSentence, int[] word1);
private static native int addMultipleDictionaryEntriesNative(long dict,
LanguageModelParam[] languageModelParams, int startIndex);
@@ -417,45 +417,53 @@ public final class BinaryDictionary extends Dictionary {
}
// Add a unigram entry to binary dictionary with unigram attributes in native code.
- public void addUnigramEntry(final String word, final int probability,
+ public boolean addUnigramEntry(final String word, final int probability,
final String shortcutTarget, final int shortcutProbability,
final boolean isBeginningOfSentence, final boolean isNotAWord,
final boolean isBlacklisted, final int timestamp) {
if (word == null || (word.isEmpty() && !isBeginningOfSentence)) {
- return;
+ return false;
}
final int[] codePoints = StringUtils.toCodePointArray(word);
final int[] shortcutTargetCodePoints = (shortcutTarget != null) ?
StringUtils.toCodePointArray(shortcutTarget) : null;
- addUnigramWordNative(mNativeDict, codePoints, probability, shortcutTargetCodePoints,
- shortcutProbability, isBeginningOfSentence, isNotAWord, isBlacklisted, timestamp);
+ if (!addUnigramWordNative(mNativeDict, codePoints, probability, shortcutTargetCodePoints,
+ shortcutProbability, isBeginningOfSentence, isNotAWord, isBlacklisted, timestamp)) {
+ return false;
+ }
mHasUpdated = true;
+ return true;
}
// Add an n-gram entry to the binary dictionary with timestamp in native code.
- public void addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word,
- final int probability,
- final int timestamp) {
+ public boolean addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word,
+ final int probability, final int timestamp) {
if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) {
- return;
+ return false;
}
final int[] codePoints0 = StringUtils.toCodePointArray(prevWordsInfo.mPrevWord);
final int[] codePoints1 = StringUtils.toCodePointArray(word);
- addBigramWordsNative(mNativeDict, codePoints0, prevWordsInfo.mIsBeginningOfSentence,
- codePoints1, probability, timestamp);
+ if (!addBigramWordsNative(mNativeDict, codePoints0, prevWordsInfo.mIsBeginningOfSentence,
+ codePoints1, probability, timestamp)) {
+ return false;
+ }
mHasUpdated = true;
+ return true;
}
// Remove an n-gram entry from the binary dictionary in native code.
- public void removeNgramEntry(final PrevWordsInfo prevWordsInfo, final String word) {
+ public boolean removeNgramEntry(final PrevWordsInfo prevWordsInfo, final String word) {
if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) {
- return;
+ return false;
}
final int[] codePoints0 = StringUtils.toCodePointArray(prevWordsInfo.mPrevWord);
final int[] codePoints1 = StringUtils.toCodePointArray(word);
- removeBigramWordsNative(mNativeDict, codePoints0, prevWordsInfo.mIsBeginningOfSentence,
- codePoints1);
+ if (!removeBigramWordsNative(mNativeDict, codePoints0, prevWordsInfo.mIsBeginningOfSentence,
+ codePoints1)) {
+ return false;
+ }
mHasUpdated = true;
+ return true;
}
public void addMultipleDictionaryEntries(final LanguageModelParam[] languageModelParams) {
@@ -485,26 +493,33 @@ public final class BinaryDictionary extends Dictionary {
}
// Flush to dict file if the dictionary has been updated.
- public void flush() {
- if (!isValidDictionary()) return;
+ public boolean flush() {
+ if (!isValidDictionary()) return false;
if (mHasUpdated) {
- flushNative(mNativeDict, mDictFilePath);
+ if (!flushNative(mNativeDict, mDictFilePath)) {
+ return false;
+ }
reopen();
}
+ return true;
}
// Run GC and flush to dict file if the dictionary has been updated.
- public void flushWithGCIfHasUpdated() {
+ public boolean flushWithGCIfHasUpdated() {
if (mHasUpdated) {
- flushWithGC();
+ return flushWithGC();
}
+ return true;
}
// Run GC and flush to dict file.
- public void flushWithGC() {
- if (!isValidDictionary()) return;
- flushWithGCNative(mNativeDict, mDictFilePath);
+ public boolean flushWithGC() {
+ if (!isValidDictionary()) return false;
+ if (!flushWithGCNative(mNativeDict, mDictFilePath)) {
+ return false;
+ }
reopen();
+ return true;
}
/**
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 4cb920f37..7fa3d0479 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -408,7 +408,7 @@ public class DictionaryFacilitator {
if (userHistoryDictionary == null) {
return;
}
- final int maxFreq = getMaxFrequency(word);
+ final int maxFreq = getFrequency(word);
if (maxFreq == 0 && blockPotentiallyOffensive) {
return;
}
@@ -516,7 +516,7 @@ public class DictionaryFacilitator {
return false;
}
- private int getMaxFrequency(final String word) {
+ public int getFrequency(final String word) {
if (TextUtils.isEmpty(word)) {
return Dictionary.NOT_A_PROBABILITY;
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 95ff8c6e3..b10bae01a 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -298,8 +298,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
protected void addUnigramLocked(final String word, final int frequency,
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
final boolean isBlacklisted, final int timestamp) {
- mBinaryDictionary.addUnigramEntry(word, frequency, shortcutTarget, shortcutFreq,
- false /* isBeginningOfSentence */, isNotAWord, isBlacklisted, timestamp);
+ if (!mBinaryDictionary.addUnigramEntry(word, frequency, shortcutTarget, shortcutFreq,
+ false /* isBeginningOfSentence */, isNotAWord, isBlacklisted, timestamp)) {
+ Log.e(TAG, "Cannot add unigram entry. word: " + word);
+ }
}
/**
@@ -322,7 +324,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
protected void addNgramEntryLocked(final PrevWordsInfo prevWordsInfo, final String word,
final int frequency, final int timestamp) {
- mBinaryDictionary.addNgramEntry(prevWordsInfo, word, frequency, timestamp);
+ if (!mBinaryDictionary.addNgramEntry(prevWordsInfo, word, frequency, timestamp)) {
+ Log.e(TAG, "Cannot add n-gram entry.");
+ Log.e(TAG, " PrevWordsInfo: " + prevWordsInfo);
+ Log.e(TAG, " word: " + word);
+ }
}
/**
diff --git a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java
index e44239f1d..42b311c69 100644
--- a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java
+++ b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java
@@ -53,4 +53,10 @@ public class PrevWordsInfo {
public boolean isValid() {
return mPrevWord != null;
}
+
+ @Override
+ public String toString() {
+ return "PrevWord: " + mPrevWord + ", isBeginningOfSentence: "
+ + mIsBeginningOfSentence + ".";
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index e90b15ca5..346aea34a 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -23,23 +23,17 @@ import android.graphics.drawable.Drawable;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.keyboard.internal.KeyboardParams;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.TypefaceUtils;
public final class MoreSuggestions extends Keyboard {
public final SuggestedWords mSuggestedWords;
- public static abstract class MoreSuggestionsListener extends KeyboardActionListener.Adapter {
- public abstract void onSuggestionSelected(final int index, final SuggestedWordInfo info);
- }
-
MoreSuggestions(final MoreSuggestionsParam params, final SuggestedWords suggestedWords) {
super(params);
mSuggestedWords = suggestedWords;
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
index 7fd64c4bf..aa59db678 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
@@ -22,11 +22,12 @@ import android.util.Log;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.MoreKeysKeyboardView;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionKey;
-import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionsListener;
/**
* A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting
@@ -35,6 +36,10 @@ import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestions
public final class MoreSuggestionsView extends MoreKeysKeyboardView {
private static final String TAG = MoreSuggestionsView.class.getSimpleName();
+ public static abstract class MoreSuggestionsListener extends KeyboardActionListener.Adapter {
+ public abstract void onSuggestionSelected(final int index, final SuggestedWordInfo info);
+ }
+
public MoreSuggestionsView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.moreKeysKeyboardViewStyle);
}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 5af724fa6..c400f66c8 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -49,7 +49,7 @@ import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.settings.Settings;
-import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionsListener;
+import com.android.inputmethod.latin.suggestions.MoreSuggestionsView.MoreSuggestionsListener;
import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
import com.android.inputmethod.research.ResearchLogger;
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java
index 1c93a9105..ac0ab28bf 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java
@@ -33,6 +33,7 @@ import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardLayoutSet;
import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -98,10 +99,12 @@ public class DistracterFilterUsingSuggestion implements DistracterFilter {
}
}
- private static boolean isDistracter(
+ private boolean isDistracter(
final SuggestionResults suggestionResults, final String consideredWord) {
+ int perfectMatchProbability = Dictionary.NOT_A_PROBABILITY;
for (final SuggestedWordInfo suggestedWordInfo : suggestionResults) {
if (suggestedWordInfo.mWord.equals(consideredWord)) {
+ perfectMatchProbability = mDictionaryFacilitator.getFrequency(consideredWord);
continue;
}
// Exact match can include case errors, accent errors, digraph conversions.
@@ -121,6 +124,17 @@ public class DistracterFilterUsingSuggestion implements DistracterFilter {
Log.d(TAG, "isExactMatchWithIntentionalOmission: "
+ isExactMatchWithIntentionalOmission);
}
+ if (perfectMatchProbability != Dictionary.NOT_A_PROBABILITY) {
+ final int topNonPerfectProbability = mDictionaryFacilitator.getFrequency(
+ suggestedWordInfo.mWord);
+ if (DEBUG) {
+ Log.d(TAG, "perfectMatchProbability: " + perfectMatchProbability);
+ Log.d(TAG, "topNonPerfectProbability: " + topNonPerfectProbability);
+ }
+ if (perfectMatchProbability > topNonPerfectProbability) {
+ return false;
+ }
+ }
return isExactMatch || isExactMatchWithIntentionalOmission;
}
return false;
diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
index 7b678e175..c08697c4b 100644
--- a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
@@ -28,14 +28,14 @@ public class ExecutorUtils {
new ConcurrentHashMap<>();
/**
- * Gets the executor for the given dictionary name.
+ * Gets the executor for the given id.
*/
- public static PrioritizedSerialExecutor getExecutor(final String dictName) {
- PrioritizedSerialExecutor executor = sExecutorMap.get(dictName);
+ public static PrioritizedSerialExecutor getExecutor(final String id) {
+ PrioritizedSerialExecutor executor = sExecutorMap.get(id);
if (executor == null) {
synchronized(sExecutorMap) {
- executor = new PrioritizedSerialExecutor();
- sExecutorMap.put(dictName, executor);
+ executor = new PrioritizedSerialExecutor(id);
+ sExecutorMap.put(id, executor);
}
}
return executor;
diff --git a/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java b/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
index 148f3bce6..21949ffbd 100644
--- a/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
+++ b/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
@@ -21,6 +21,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -40,12 +41,26 @@ public class PrioritizedSerialExecutor {
// The task which is running now.
private Runnable mActive;
- public PrioritizedSerialExecutor() {
+ private static class ThreadFactoryWithId implements ThreadFactory {
+ private final String mId;
+
+ public ThreadFactoryWithId(final String id) {
+ mId = id;
+ }
+
+ @Override
+ public Thread newThread(final Runnable r) {
+ return new Thread(r, TAG + " - " + mId);
+ }
+ }
+
+ public PrioritizedSerialExecutor(final String id) {
mTasks = new ConcurrentLinkedQueue<>();
mPrioritizedTasks = new ConcurrentLinkedQueue<>();
mIsShutdown = false;
mThreadPoolExecutor = new ThreadPoolExecutor(1 /* corePoolSize */, 1 /* maximumPoolSize */,
- 0 /* keepAliveTime */, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
+ 0 /* keepAliveTime */, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1),
+ new ThreadFactoryWithId(id));
}
/**