aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java8
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java97
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java99
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/DrawingProxy.java33
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java5
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java3
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java46
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFactory.java55
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java2
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputMethodManager.java9
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java109
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java23
-rw-r--r--java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java2
-rw-r--r--java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java20
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java4
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java11
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java11
18 files changed, 293 insertions, 246 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
index 94a1ee6eb..e80982fc7 100644
--- a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
+++ b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
@@ -269,13 +269,9 @@ public final class MainKeyboardAccessibilityDelegate
eventTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0 /* metaState */);
// Inject a fake down event to {@link PointerTracker} to handle a long press correctly.
tracker.processMotionEvent(downEvent, mKeyDetector);
- // The above fake down event triggers an unnecessary long press timer that should be
- // canceled.
- tracker.cancelLongPressTimer();
downEvent.recycle();
- // Invoke {@link MainKeyboardView#onLongPress(PointerTracker)} as if a long press timeout
- // has passed.
- mKeyboardView.onLongPress(tracker);
+ // Invoke {@link PointerTracker#onLongPressed()} as if a long press timeout has passed.
+ tracker.onLongPressed();
// If {@link Key#hasNoPanelAutoMoreKeys()} is true (such as "0 +" key on the phone layout)
// or a key invokes IME switcher dialog, we should just ignore the next
// {@link #onRegisterHoverKey(Key,MotionEvent)}. It can be determined by whether
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 06b87bd9a..fc6d43919 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -461,12 +461,17 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
windowContentView.addView(mDrawingPreviewPlacerView);
}
+ // Implements {@link DrawingProxy#onKeyPressed(Key,boolean)}.
@Override
- public void showKeyPreview(@Nonnull final Key key) {
- // If the key is invalid or has no key preview, we must not show key preview.
- if (key.noKeyPreview()) {
- return;
+ public void onKeyPressed(@Nonnull final Key key, final boolean withPreview) {
+ key.onPressed();
+ invalidateKey(key);
+ if (withPreview && !key.noKeyPreview()) {
+ showKeyPreview(key);
}
+ }
+
+ private void showKeyPreview(@Nonnull final Key key) {
final Keyboard keyboard = getKeyboard();
if (keyboard == null) {
return;
@@ -483,15 +488,26 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
getWidth(), mOriginCoords, mDrawingPreviewPlacerView, isHardwareAccelerated());
}
- // Implements {@link DrawingProxy#dismissKeyPreviewWithoutDelay(Key)}.
- @Override
- public void dismissKeyPreviewWithoutDelay(@Nonnull final Key key) {
+ private void dismissKeyPreviewWithoutDelay(@Nonnull final Key key) {
mKeyPreviewChoreographer.dismissKeyPreview(key, false /* withAnimation */);
invalidateKey(key);
}
+ // Implements {@link DrawingProxy#onKeyReleased(Key,boolean)}.
@Override
- public void dismissKeyPreview(@Nonnull final Key key) {
+ public void onKeyReleased(@Nonnull final Key key, final boolean withAnimation) {
+ key.onReleased();
+ invalidateKey(key);
+ if (!key.noKeyPreview()) {
+ if (withAnimation) {
+ dismissKeyPreview(key);
+ } else {
+ dismissKeyPreviewWithoutDelay(key);
+ }
+ }
+ }
+
+ private void dismissKeyPreview(@Nonnull final Key key) {
if (isHardwareAccelerated()) {
mKeyPreviewChoreographer.dismissKeyPreview(key, true /* withAnimation */);
return;
@@ -574,7 +590,11 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
mDrawingPreviewPlacerView.removeAllViews();
}
- private MoreKeysPanel onCreateMoreKeysPanel(final Key key, final Context context) {
+ // Implements {@link DrawingProxy@showMoreKeysKeyboard(Key,PointerTracker)}.
+ @Override
+ @Nullable
+ public MoreKeysPanel showMoreKeysKeyboard(@Nonnull final Key key,
+ @Nonnull final PointerTracker tracker) {
final MoreKeySpec[] moreKeys = key.getMoreKeys();
if (moreKeys == null) {
return null;
@@ -590,7 +610,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
&& !key.noKeyPreview() && moreKeys.length == 1
&& mKeyPreviewDrawParams.getVisibleWidth() > 0;
final MoreKeysKeyboard.Builder builder = new MoreKeysKeyboard.Builder(
- context, key, getKeyboard(), isSingleMoreKeyWithPreview,
+ getContext(), key, getKeyboard(), isSingleMoreKeyWithPreview,
mKeyPreviewDrawParams.getVisibleWidth(),
mKeyPreviewDrawParams.getVisibleHeight(), newLabelPaint(key));
moreKeysKeyboard = builder.build();
@@ -603,50 +623,6 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
(MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view);
moreKeysKeyboardView.setKeyboard(moreKeysKeyboard);
container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- return moreKeysKeyboardView;
- }
-
- // Implements {@link DrawingProxy@onLongPress(PointerTracker)}.
- /**
- * Called when a key is long pressed.
- * @param tracker the pointer tracker which pressed the parent key
- */
- @Override
- public void onLongPress(@Nonnull final PointerTracker tracker) {
- if (isShowingMoreKeysPanel()) {
- return;
- }
- final Key key = tracker.getKey();
- if (key == null) {
- return;
- }
- final KeyboardActionListener listener = mKeyboardActionListener;
- if (key.hasNoPanelAutoMoreKey()) {
- final int moreKeyCode = key.getMoreKeys()[0].mCode;
- tracker.onLongPressed();
- listener.onPressKey(moreKeyCode, 0 /* repeatCount */, true /* isSinglePointer */);
- listener.onCodeInput(moreKeyCode, Constants.NOT_A_COORDINATE,
- Constants.NOT_A_COORDINATE, false /* isKeyRepeat */);
- listener.onReleaseKey(moreKeyCode, false /* withSliding */);
- return;
- }
- final int code = key.getCode();
- if (code == Constants.CODE_SPACE || code == Constants.CODE_LANGUAGE_SWITCH) {
- // Long pressing the space key invokes IME switcher dialog.
- if (listener.onCustomRequest(Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER)) {
- tracker.onLongPressed();
- listener.onReleaseKey(code, false /* withSliding */);
- return;
- }
- }
- openMoreKeysPanel(key, tracker);
- }
-
- private void openMoreKeysPanel(final Key key, final PointerTracker tracker) {
- final MoreKeysPanel moreKeysPanel = onCreateMoreKeysPanel(key, getContext());
- if (moreKeysPanel == null) {
- return;
- }
final int[] lastCoords = CoordinateUtils.newInstance();
tracker.getLastCoordinates(lastCoords);
@@ -664,10 +640,8 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
// {@code mPreviewVisibleOffset} has been set appropriately in
// {@link KeyboardView#showKeyPreview(PointerTracker)}.
final int pointY = key.getY() + mKeyPreviewDrawParams.getVisibleOffset();
- moreKeysPanel.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener);
- tracker.onShowMoreKeysPanel(moreKeysPanel);
- // TODO: Implement zoom in animation of more keys panel.
- mKeyPreviewChoreographer.dismissKeyPreview(key, false /* withAnimation */);
+ moreKeysKeyboardView.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener);
+ return moreKeysKeyboardView;
}
public boolean isInDraggingFinger() {
@@ -895,13 +869,16 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
}
private void drawLanguageOnSpacebar(final Key key, final Canvas canvas, final Paint paint) {
+ final Keyboard keyboard = getKeyboard();
+ if (keyboard == null) {
+ return;
+ }
final int width = key.getWidth();
final int height = key.getHeight();
paint.setTextAlign(Align.CENTER);
paint.setTypeface(Typeface.DEFAULT);
paint.setTextSize(mLanguageOnSpacebarTextSize);
- final RichInputMethodSubtype subtype = getKeyboard().mId.mSubtype;
- final String language = layoutLanguageOnSpacebar(paint, subtype, width);
+ final String language = layoutLanguageOnSpacebar(paint, keyboard.mId.mSubtype, width);
// Draw language text with shadow
final float descent = paint.descent();
final float textHeight = -paint.ascent() + descent;
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 7902ce852..9764cb389 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -222,7 +222,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
final int trackersSize = sTrackers.size();
for (int i = 0; i < trackersSize; ++i) {
final PointerTracker tracker = sTrackers.get(i);
- tracker.setReleasedKeyGraphics(tracker.getKey());
+ tracker.setReleasedKeyGraphics(tracker.getKey(), true /* withAnimation */);
}
}
@@ -382,19 +382,17 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
return mKeyDetector.detectHitKey(x, y);
}
- private void setReleasedKeyGraphics(@Nullable final Key key) {
+ private void setReleasedKeyGraphics(@Nullable final Key key, final boolean withAnimation) {
if (key == null) {
return;
}
- sDrawingProxy.dismissKeyPreview(key);
- // Even if the key is disabled, update the key release graphics just in case.
- updateReleaseKeyGraphics(key);
+ sDrawingProxy.onKeyReleased(key, withAnimation);
if (key.isShift()) {
for (final Key shiftKey : mKeyboard.mShiftKeys) {
if (shiftKey != key) {
- updateReleaseKeyGraphics(shiftKey);
+ sDrawingProxy.onKeyReleased(shiftKey, false /* withAnimation */);
}
}
}
@@ -403,11 +401,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
final int altCode = key.getAltCode();
final Key altKey = mKeyboard.getKey(altCode);
if (altKey != null) {
- updateReleaseKeyGraphics(altKey);
+ sDrawingProxy.onKeyReleased(altKey, false /* withAnimation */);
}
for (final Key k : mKeyboard.mAltCodeKeysWhileTyping) {
if (k != key && k.getAltCode() == altCode) {
- updateReleaseKeyGraphics(k);
+ sDrawingProxy.onKeyReleased(k, false /* withAnimation */);
}
}
}
@@ -418,7 +416,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
return sTypingTimeRecorder.needsToSuppressKeyPreviewPopup(eventTime);
}
- private void setPressedKeyGraphics(final Key key, final long eventTime) {
+ private void setPressedKeyGraphics(@Nullable final Key key, final long eventTime) {
if (key == null) {
return;
}
@@ -430,15 +428,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
return;
}
- if (!key.noKeyPreview() && !sInGesture && !needsToSuppressKeyPreviewPopup(eventTime)) {
- sDrawingProxy.showKeyPreview(key);
- }
- updatePressKeyGraphics(key);
+ final boolean noKeyPreview = sInGesture || needsToSuppressKeyPreviewPopup(eventTime);
+ sDrawingProxy.onKeyPressed(key, !noKeyPreview);
if (key.isShift()) {
for (final Key shiftKey : mKeyboard.mShiftKeys) {
if (shiftKey != key) {
- updatePressKeyGraphics(shiftKey);
+ sDrawingProxy.onKeyPressed(shiftKey, false /* withPreview */);
}
}
}
@@ -447,26 +443,16 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
final int altCode = key.getAltCode();
final Key altKey = mKeyboard.getKey(altCode);
if (altKey != null) {
- updatePressKeyGraphics(altKey);
+ sDrawingProxy.onKeyPressed(altKey, false /* withPreview */);
}
for (final Key k : mKeyboard.mAltCodeKeysWhileTyping) {
if (k != key && k.getAltCode() == altCode) {
- updatePressKeyGraphics(k);
+ sDrawingProxy.onKeyPressed(k, false /* withPreview */);
}
}
}
}
- private static void updateReleaseKeyGraphics(final Key key) {
- key.onReleased();
- sDrawingProxy.invalidateKey(key);
- }
-
- private static void updatePressKeyGraphics(final Key key) {
- key.onPressed();
- sDrawingProxy.invalidateKey(key);
- }
-
public GestureStrokeDrawingPoints getGestureStrokeDrawingPoints() {
return mGestureStrokeDrawingPoints;
}
@@ -837,7 +823,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
}
private void processDraggingFingerOutFromOldKey(final Key oldKey) {
- setReleasedKeyGraphics(oldKey);
+ setReleasedKeyGraphics(oldKey, true /* withAnimation */);
callListenerOnRelease(oldKey, oldKey.getCode(), true /* withSliding */);
startKeySelectionByDraggingFinger(oldKey);
sTimerProxy.cancelKeyTimersOf(this);
@@ -880,12 +866,12 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
}
onUpEvent(x, y, eventTime);
cancelTrackingForAction();
- setReleasedKeyGraphics(oldKey);
+ setReleasedKeyGraphics(oldKey, true /* withAnimation */);
} else {
if (!mIsDetectingGesture) {
cancelTrackingForAction();
}
- setReleasedKeyGraphics(oldKey);
+ setReleasedKeyGraphics(oldKey, true /* withAnimation */);
}
}
@@ -913,7 +899,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
onGestureMoveEvent(x, y, eventTime, true /* isMajorEvent */, newKey);
if (sInGesture) {
mCurrentKey = null;
- setReleasedKeyGraphics(oldKey);
+ setReleasedKeyGraphics(oldKey, true /* withAnimation */);
return;
}
}
@@ -978,7 +964,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
final int currentRepeatingKeyCode = mCurrentRepeatingKeyCode;
mCurrentRepeatingKeyCode = Constants.NOT_A_CODE;
// Release the last pressed key.
- setReleasedKeyGraphics(currentKey);
+ setReleasedKeyGraphics(currentKey, true /* withAnimation */);
if (isShowingMoreKeysPanel()) {
if (!mIsTrackingForActionDisabled) {
@@ -1015,14 +1001,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
}
}
- public void onShowMoreKeysPanel(final MoreKeysPanel panel) {
- setReleasedKeyGraphics(mCurrentKey);
- final int translatedX = panel.translateX(mLastX);
- final int translatedY = panel.translateY(mLastY);
- panel.onDownEvent(translatedX, translatedY, mPointerId, SystemClock.uptimeMillis());
- mMoreKeysPanel = panel;
- }
-
@Override
public void cancelTrackingForAction() {
if (isShowingMoreKeysPanel()) {
@@ -1035,14 +1013,49 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
return !mIsTrackingForActionDisabled;
}
- public void cancelLongPressTimer() {
+ public void onLongPressed() {
sTimerProxy.cancelLongPressTimersOf(this);
+ if (isShowingMoreKeysPanel()) {
+ return;
+ }
+ final Key key = getKey();
+ if (key == null) {
+ return;
+ }
+ if (key.hasNoPanelAutoMoreKey()) {
+ cancelKeyTracking();
+ final int moreKeyCode = key.getMoreKeys()[0].mCode;
+ sListener.onPressKey(moreKeyCode, 0 /* repeatCont */, true /* isSinglePointer */);
+ sListener.onCodeInput(moreKeyCode, Constants.NOT_A_COORDINATE,
+ Constants.NOT_A_COORDINATE, false /* isKeyRepeat */);
+ sListener.onReleaseKey(moreKeyCode, false /* withSliding */);
+ return;
+ }
+ final int code = key.getCode();
+ if (code == Constants.CODE_SPACE || code == Constants.CODE_LANGUAGE_SWITCH) {
+ // Long pressing the space key invokes IME switcher dialog.
+ if (sListener.onCustomRequest(Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER)) {
+ cancelKeyTracking();
+ sListener.onReleaseKey(code, false /* withSliding */);
+ return;
+ }
+ }
+
+ setReleasedKeyGraphics(key, false /* withAnimation */);
+ final MoreKeysPanel moreKeysPanel = sDrawingProxy.showMoreKeysKeyboard(key, this);
+ if (moreKeysPanel == null) {
+ return;
+ }
+ final int translatedX = moreKeysPanel.translateX(mLastX);
+ final int translatedY = moreKeysPanel.translateY(mLastY);
+ moreKeysPanel.onDownEvent(translatedX, translatedY, mPointerId, SystemClock.uptimeMillis());
+ mMoreKeysPanel = moreKeysPanel;
}
- public void onLongPressed() {
+ private void cancelKeyTracking() {
resetKeySelectionByDraggingFinger();
cancelTrackingForAction();
- setReleasedKeyGraphics(mCurrentKey);
+ setReleasedKeyGraphics(mCurrentKey, true /* withAnimation */);
sPointerTrackerQueue.remove(this);
}
@@ -1059,7 +1072,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
private void onCancelEventInternal() {
sTimerProxy.cancelKeyTimersOf(this);
- setReleasedKeyGraphics(mCurrentKey);
+ setReleasedKeyGraphics(mCurrentKey, true /* withAnimation */);
resetKeySelectionByDraggingFinger();
dismissMoreKeysPanel();
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/DrawingProxy.java b/java/src/com/android/inputmethod/keyboard/internal/DrawingProxy.java
index 7fc586a0f..06bdfc41b 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/DrawingProxy.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/DrawingProxy.java
@@ -17,29 +17,36 @@
package com.android.inputmethod.keyboard.internal;
import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.MoreKeysPanel;
import com.android.inputmethod.keyboard.PointerTracker;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface DrawingProxy {
- // TODO: Remove this method.
- public void invalidateKey(@Nullable Key key);
-
- // TODO: Rename this method to onKeyPressed.
- public void showKeyPreview(@Nonnull Key key);
-
- // TODO: Rename this method to onKeyReleased.
- public void dismissKeyPreview(@Nonnull Key key);
+ /**
+ * Called when a key is being pressed.
+ * @param key the {@link Key} that is being pressed.
+ * @param withPreview true if key popup preview should be displayed.
+ */
+ public void onKeyPressed(@Nonnull Key key, boolean withPreview);
/**
- * Dismiss a key preview visual without delay.
- * @param key the key whose preview visual should be dismissed.
+ * Called when a key is being released.
+ * @param key the {@link Key} that is being released.
+ * @param withAnimation when true, key popup preview should be dismissed with animation.
*/
- public void dismissKeyPreviewWithoutDelay(@Nonnull Key key);
+ public void onKeyReleased(@Nonnull Key key, boolean withAnimation);
- // TODO: Rename this method to onKeyLongPressed.
- public void onLongPress(@Nonnull PointerTracker tracker);
+ /**
+ * Start showing more keys keyboard of a key that is being long pressed.
+ * @param key the {@link Key} that is being long pressed and showing more keys keyboard.
+ * @param tracker the {@link PointerTracker} that detects this long pressing.
+ * @return {@link MoreKeysPanel} that is being shown. null if there is no need to show more keys
+ * keyboard.
+ */
+ @Nullable
+ public MoreKeysPanel showMoreKeysKeyboard(@Nonnull Key key, @Nonnull PointerTracker tracker);
/**
* Start a while-typing-animation.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java b/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java
index 8068427bc..91f3558eb 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java
@@ -66,7 +66,7 @@ public final class TimerHandler extends LeakGuardHandlerWrapper<DrawingProxy>
case MSG_LONGPRESS_SHIFT_KEY:
cancelLongPressTimers();
final PointerTracker tracker2 = (PointerTracker) msg.obj;
- drawingProxy.onLongPress(tracker2);
+ tracker2.onLongPressed();
break;
case MSG_UPDATE_BATCH_INPUT:
final PointerTracker tracker3 = (PointerTracker) msg.obj;
@@ -74,8 +74,7 @@ public final class TimerHandler extends LeakGuardHandlerWrapper<DrawingProxy>
startUpdateBatchInputTimer(tracker3);
break;
case MSG_DISMISS_KEY_PREVIEW:
- final Key key = (Key) msg.obj;
- drawingProxy.dismissKeyPreviewWithoutDelay(key);
+ drawingProxy.onKeyReleased((Key) msg.obj, false /* withAnimation */);
break;
case MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT:
drawingProxy.dismissGestureFloatingPreviewTextWithoutDelay();
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 5afb62b69..9c70cad0a 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -263,7 +263,8 @@ final public class BinaryDictionaryGetter {
public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale,
final Context context) {
- final boolean hasDefaultWordList = DictionaryFactory.isDictionaryAvailable(context, locale);
+ final boolean hasDefaultWordList = DictionaryInfoUtils.isDictionaryAvailable(
+ context, locale);
BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context,
hasDefaultWordList);
final File[] cachedWordLists = getCachedWordLists(locale.toString(), context);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index d0d626c54..e363661eb 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -63,6 +63,9 @@ public class DictionaryFacilitator {
// HACK: This threshold is being used when adding a capitalized entry in the User History
// dictionary.
private static final int CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT = 140;
+ // How many words we need to type in a row ({@see mConfidenceInMostProbableLanguage}) to
+ // declare we are confident the user is typing in the most probable language.
+ private static final int CONFIDENCE_THRESHOLD = 3;
private DictionaryGroup[] mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() };
private DictionaryGroup mMostProbableDictionaryGroup = mDictionaryGroups[0];
@@ -138,6 +141,10 @@ public class DictionaryFacilitator {
public final Locale mLocale;
private Dictionary mMainDict;
+ // Confidence that the most probable language is actually the language the user is
+ // typing in. For now, this is simply the number of times a word from this language
+ // has been committed in a row.
+ private int mConfidence = 0;
public float mWeightForTypingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
public float mWeightForGesturingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap =
@@ -260,8 +267,9 @@ public class DictionaryFacilitator {
public void switchMostProbableLanguage(@Nullable final Locale locale) {
if (null == locale) {
// In many cases, there is no locale to a committed word. For example, a typed word
- // that does not auto-correct has no locale. In this case we simply do not change
- // the most probable language.
+ // that is in none of the currently active dictionaries but still does not
+ // auto-correct to anything has no locale. In this case we simply do not change
+ // the most probable language and do not touch confidence.
return;
}
final DictionaryGroup newMostProbableDictionaryGroup =
@@ -272,15 +280,28 @@ public class DictionaryFacilitator {
// facilitator any more. In this case, just not changing things is fine.
return;
}
- mMostProbableDictionaryGroup.mWeightForTypingInLocale =
- DictionaryGroup.WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE;
- mMostProbableDictionaryGroup.mWeightForGesturingInLocale =
- DictionaryGroup.WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE;
- newMostProbableDictionaryGroup.mWeightForTypingInLocale =
- DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
- newMostProbableDictionaryGroup.mWeightForGesturingInLocale =
- DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
- mMostProbableDictionaryGroup = newMostProbableDictionaryGroup;
+ if (newMostProbableDictionaryGroup == mMostProbableDictionaryGroup) {
+ ++newMostProbableDictionaryGroup.mConfidence;
+ } else {
+ mMostProbableDictionaryGroup.mWeightForTypingInLocale =
+ DictionaryGroup.WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE;
+ mMostProbableDictionaryGroup.mWeightForGesturingInLocale =
+ DictionaryGroup.WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE;
+ mMostProbableDictionaryGroup.mConfidence = 0;
+ newMostProbableDictionaryGroup.mWeightForTypingInLocale =
+ DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
+ newMostProbableDictionaryGroup.mWeightForGesturingInLocale =
+ DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
+ mMostProbableDictionaryGroup = newMostProbableDictionaryGroup;
+ }
+ }
+
+ public boolean isConfidentAboutCurrentLanguageBeing(final Locale mLocale) {
+ final DictionaryGroup mostProbableDictionaryGroup = mMostProbableDictionaryGroup;
+ if (!mostProbableDictionaryGroup.mLocale.equals(mLocale)) {
+ return false;
+ }
+ return mostProbableDictionaryGroup.mConfidence >= CONFIDENCE_THRESHOLD;
}
@Nullable
@@ -624,7 +645,8 @@ public class DictionaryFacilitator {
final int timeStampInSeconds, final boolean blockPotentiallyOffensive) {
final ExpandableBinaryDictionary userHistoryDictionary =
dictionaryGroup.getSubDict(Dictionary.TYPE_USER_HISTORY);
- if (userHistoryDictionary == null) {
+ if (userHistoryDictionary == null
+ || !isConfidentAboutCurrentLanguageBeing(userHistoryDictionary.mLocale)) {
return;
}
final int maxFreq = getFrequency(word);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index a395fdeef..781ab06c5 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -19,10 +19,8 @@ package com.android.inputmethod.latin;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
-import android.content.res.Resources;
import android.util.Log;
-import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
import java.io.File;
@@ -43,11 +41,10 @@ public final class DictionaryFactory {
* locale. If none is found, it falls back to the built-in dictionary - if any.
* @param context application context for reading resources
* @param locale the locale for which to create the dictionary
- * @param useFullEditDistance whether to use the full edit distance in suggestions
* @return an initialized instance of DictionaryCollection
*/
public static DictionaryCollection createMainDictionaryFromManager(final Context context,
- final Locale locale, final boolean useFullEditDistance) {
+ final Locale locale) {
if (null == locale) {
Log.e(TAG, "No locale defined for dictionary");
return new DictionaryCollection(Dictionary.TYPE_MAIN, locale,
@@ -61,7 +58,7 @@ public final class DictionaryFactory {
for (final AssetFileAddress f : assetFileList) {
final ReadOnlyBinaryDictionary readOnlyBinaryDictionary =
new ReadOnlyBinaryDictionary(f.mFilename, f.mOffset, f.mLength,
- useFullEditDistance, locale, Dictionary.TYPE_MAIN);
+ false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN);
if (readOnlyBinaryDictionary.isValidDictionary()) {
dictList.add(readOnlyBinaryDictionary);
} else {
@@ -122,26 +119,12 @@ public final class DictionaryFactory {
}
/**
- * Initializes a main dictionary collection from a dictionary pack, with default flags.
- *
- * This searches for a content provider providing a dictionary pack for the specified
- * locale. If none is found, it falls back to the built-in dictionary, if any.
- * @param context application context for reading resources
- * @param locale the locale for which to create the dictionary
- * @return an initialized instance of DictionaryCollection
- */
- public static DictionaryCollection createMainDictionaryFromManager(final Context context,
- final Locale locale) {
- return createMainDictionaryFromManager(context, locale, false /* useFullEditDistance */);
- }
-
- /**
* Initializes a read-only binary dictionary from a raw resource file
* @param context application context for reading resources
* @param locale the locale to use for the resource
* @return an initialized instance of ReadOnlyBinaryDictionary
*/
- protected static ReadOnlyBinaryDictionary createReadOnlyBinaryDictionary(final Context context,
+ private static ReadOnlyBinaryDictionary createReadOnlyBinaryDictionary(final Context context,
final Locale locale) {
AssetFileDescriptor afd = null;
try {
@@ -175,36 +158,4 @@ public final class DictionaryFactory {
}
}
}
-
- /**
- * Create a dictionary from passed data. This is intended for unit tests only.
- * @param dictionaryList the list of files to read, with their offsets and lengths
- * @param useFullEditDistance whether to use the full edit distance in suggestions
- * @return the created dictionary, or null.
- */
- @UsedForTesting
- public static Dictionary createDictionaryForTest(final AssetFileAddress[] dictionaryList,
- final boolean useFullEditDistance, Locale locale) {
- final DictionaryCollection dictionaryCollection =
- new DictionaryCollection(Dictionary.TYPE_MAIN, locale);
- for (final AssetFileAddress address : dictionaryList) {
- final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary(
- address.mFilename, address.mOffset, address.mLength, useFullEditDistance,
- locale, Dictionary.TYPE_MAIN);
- dictionaryCollection.addDictionary(readOnlyBinaryDictionary);
- }
- return dictionaryCollection;
- }
-
- /**
- * Find out whether a dictionary is available for this locale.
- * @param context the context on which to check resources.
- * @param locale the locale to check for.
- * @return whether a (non-placeholder) dictionary is available or not.
- */
- public static boolean isDictionaryAvailable(Context context, Locale locale) {
- final Resources res = context.getResources();
- return 0 != DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale(
- res, locale);
- }
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 7b7b6d35e..66746cb6a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -708,6 +708,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mInputLogic.mSuggest.setAutoCorrectionThreshold(
settingsValues.mAutoCorrectionThreshold);
}
+ mInputLogic.mSuggest.setPlausibilityThreshold(settingsValues.mPlausibilityThreshold);
}
/**
@@ -1007,6 +1008,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
suggest.setAutoCorrectionThreshold(
currentSettingsValues.mAutoCorrectionThreshold);
}
+ suggest.setPlausibilityThreshold(currentSettingsValues.mPlausibilityThreshold);
switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(),
getCurrentRecapitalizeState());
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index a1ac55a20..686c3a4b2 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -110,7 +110,7 @@ public class RichInputMethodManager {
// Initialize additional subtypes.
SubtypeLocaleUtils.init(context);
- final InputMethodSubtype[] additionalSubtypes = getAdditionalSubtypes(context);
+ final InputMethodSubtype[] additionalSubtypes = getAdditionalSubtypes();
setAdditionalInputMethodSubtypes(additionalSubtypes);
final ConnectivityManager connectivityManager =
@@ -119,11 +119,10 @@ public class RichInputMethodManager {
mIsNetworkConnected = (info != null && info.isConnected());
}
- public InputMethodSubtype[] getAdditionalSubtypes(final Context context) {
- SubtypeLocaleUtils.init(context);
- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ public InputMethodSubtype[] getAdditionalSubtypes() {
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
final String prefAdditionalSubtypes = Settings.readPrefAdditionalSubtypes(
- prefs, context.getResources());
+ prefs, mContext.getResources());
return AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefAdditionalSubtypes);
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 4df1d6505..0bf0f687a 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -32,6 +32,9 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
/**
* This class loads a dictionary and provides a list of suggestions for a given sequence of
* characters. This includes corrections and completions.
@@ -62,15 +65,30 @@ public final class Suggest {
}
private float mAutoCorrectionThreshold;
+ private float mPlausibilityThreshold;
public Suggest(final DictionaryFacilitator dictionaryFacilitator) {
mDictionaryFacilitator = dictionaryFacilitator;
}
+ /**
+ * Set the normalized-score threshold for a suggestion to be considered strong enough that we
+ * will auto-correct to this.
+ * @param threshold the threshold
+ */
public void setAutoCorrectionThreshold(final float threshold) {
mAutoCorrectionThreshold = threshold;
}
+ /**
+ * Set the normalized-score threshold for what we consider a "plausible" suggestion, in
+ * the same dimension as the auto-correction threshold.
+ * @param threshold the threshold
+ */
+ public void setPlausibilityThreshold(final float threshold) {
+ mPlausibilityThreshold = threshold;
+ }
+
public interface OnGetSuggestedWordsCallback {
public void onGetSuggestedWords(final SuggestedWords suggestedWords);
}
@@ -115,7 +133,8 @@ public final class Suggest {
return suggestionsContainer;
}
- private static String getWhitelistedWordOrNull(final ArrayList<SuggestedWordInfo> suggestions) {
+ private static SuggestedWordInfo getWhitelistedWordInfoOrNull(
+ @Nonnull final ArrayList<SuggestedWordInfo> suggestions) {
if (suggestions.isEmpty()) {
return null;
}
@@ -123,9 +142,21 @@ public final class Suggest {
if (!firstSuggestedWordInfo.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) {
return null;
}
- return firstSuggestedWordInfo.mWord;
+ return firstSuggestedWordInfo;
}
+ // Quality constants for dictionary match
+ // In increasing order of quality
+ // This source dictionary does not match the typed word.
+ private static final int QUALITY_NO_MATCH = 0;
+ // This source dictionary has a null locale, and the preferred locale is also null.
+ private static final int QUALITY_MATCH_NULL = 1;
+ // This source dictionary has a non-null locale different from the preferred locale. The
+ // preferred locale may be null : this is still better than MATCH_NULL.
+ private static final int QUALITY_MATCH_OTHER_LOCALE = 2;
+ // This source dictionary matches the preferred locale.
+ private static final int QUALITY_MATCH_PREFERRED_LOCALE = 3;
+
// Retrieves suggestions for non-batch input (typing, recorrection, predictions...)
// and calls the callback function with the suggestions.
private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer,
@@ -143,22 +174,67 @@ public final class Suggest {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(),
settingsValuesForSuggestion, SESSION_ID_TYPING);
+ final Locale mostProbableLocale = mDictionaryFacilitator.getMostProbableLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
trailingSingleQuotesCount,
// For transforming suggestions that don't come for any dictionary, we
// use the currently most probable locale as it's our best bet.
- mDictionaryFacilitator.getMostProbableLocale());
- final boolean didRemoveTypedWord =
- SuggestedWordInfo.removeDups(wordComposer.getTypedWord(), suggestionsContainer);
+ mostProbableLocale);
+
+ boolean typedWordExistsInAnotherLanguage = false;
+ int qualityOfFoundSourceDictionary = QUALITY_NO_MATCH;
+ @Nullable Dictionary sourceDictionaryOfRemovedWord = null;
+ for (final SuggestedWordInfo info : suggestionsContainer) {
+ // Search for the best dictionary, defined as the first one with the highest match
+ // quality we can find.
+ if (typedWordString.equals(info.mWord)) {
+ if (mostProbableLocale.equals(info.mSourceDict.mLocale)) {
+ if (qualityOfFoundSourceDictionary < QUALITY_MATCH_PREFERRED_LOCALE) {
+ // Use this source if the old match had lower quality than this match
+ sourceDictionaryOfRemovedWord = info.mSourceDict;
+ qualityOfFoundSourceDictionary = QUALITY_MATCH_PREFERRED_LOCALE;
+ }
+ } else {
+ final int matchQuality = (null == info.mSourceDict.mLocale)
+ ? QUALITY_MATCH_NULL : QUALITY_MATCH_OTHER_LOCALE;
+ if (qualityOfFoundSourceDictionary < matchQuality) {
+ // Use this source if the old match had lower quality than this match
+ sourceDictionaryOfRemovedWord = info.mSourceDict;
+ qualityOfFoundSourceDictionary = matchQuality;
+ }
+ typedWordExistsInAnotherLanguage = true;
+ }
+ }
+ }
- final String whitelistedWord = getWhitelistedWordOrNull(suggestionsContainer);
+ SuggestedWordInfo.removeDups(typedWordString, suggestionsContainer);
+
+ final SuggestedWordInfo whitelistedWordInfo =
+ getWhitelistedWordInfoOrNull(suggestionsContainer);
+ final String whitelistedWord;
+ if (null != whitelistedWordInfo &&
+ (mDictionaryFacilitator.isConfidentAboutCurrentLanguageBeing(
+ whitelistedWordInfo.mSourceDict.mLocale)
+ || (!typedWordExistsInAnotherLanguage
+ && !hasPlausibleCandidateInAnyOtherLanguage(suggestionsContainer,
+ consideredWord, whitelistedWordInfo)))) {
+ // We'll use the whitelist candidate if we are confident the user is typing in the
+ // language of the dictionary it's coming from, or if there is no plausible candidate
+ // coming from another language.
+ whitelistedWord = whitelistedWordInfo.mWord;
+ } else {
+ // If on the contrary we are not confident in the current language and we have
+ // at least a plausible candidate in any other language, then we don't use this
+ // whitelist candidate.
+ whitelistedWord = null;
+ }
final boolean resultsArePredictions = !wordComposer.isComposingWord();
// We allow auto-correction if we have a whitelisted word, or if the word had more than
// one char and was not suggested.
final boolean allowsToBeAutoCorrected = (null != whitelistedWord)
- || (consideredWord.length() > 1 && !didRemoveTypedWord);
+ || (consideredWord.length() > 1 && (null == sourceDictionaryOfRemovedWord));
final boolean hasAutoCorrection;
// If correction is not enabled, we never auto-correct. This is for example for when
@@ -194,7 +270,7 @@ public final class Suggest {
hasAutoCorrection = false;
} else {
final SuggestedWordInfo firstSuggestion = suggestionResults.first();
- if (!AutoCorrectionUtils.suggestionExceedsAutoCorrectionThreshold(
+ if (!AutoCorrectionUtils.suggestionExceedsThreshold(
firstSuggestion, consideredWord, mAutoCorrectionThreshold)) {
// Score is too low for autocorrect
hasAutoCorrection = false;
@@ -209,7 +285,8 @@ public final class Suggest {
final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString,
SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
- Dictionary.DICTIONARY_USER_TYPED,
+ null == sourceDictionaryOfRemovedWord ? Dictionary.DICTIONARY_USER_TYPED
+ : sourceDictionaryOfRemovedWord,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
if (!TextUtils.isEmpty(typedWordString)) {
@@ -242,6 +319,20 @@ public final class Suggest {
false /* isObsoleteSuggestions */, inputStyle, sequenceNumber));
}
+ private boolean hasPlausibleCandidateInAnyOtherLanguage(
+ final ArrayList<SuggestedWordInfo> suggestionsContainer, final String consideredWord,
+ final SuggestedWordInfo whitelistedWordInfo) {
+ for (final SuggestedWordInfo info : suggestionsContainer) {
+ if (whitelistedWordInfo.mSourceDict.mLocale.equals(info.mSourceDict.mLocale)) {
+ continue;
+ }
+ return AutoCorrectionUtils.suggestionExceedsThreshold(info, consideredWord,
+ mPlausibilityThreshold);
+ }
+ // No candidate in another language
+ return false;
+ }
+
// Retrieves suggestions for the batch input
// and calls the callback function with the suggestions.
private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 49153d261..30dd51aed 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -355,37 +355,30 @@ public class SuggestedWords {
}
// This will always remove the higher index if a duplicate is found.
- public static boolean removeDups(final String typedWord,
- ArrayList<SuggestedWordInfo> candidates) {
+ public static void removeDups(@Nullable final String typedWord,
+ @Nonnull ArrayList<SuggestedWordInfo> candidates) {
if (candidates.isEmpty()) {
- return false;
+ return;
}
- final boolean didRemoveTypedWord;
if (!TextUtils.isEmpty(typedWord)) {
- didRemoveTypedWord = removeSuggestedWordInfoFrom(typedWord, candidates,
- -1 /* startIndexExclusive */);
- } else {
- didRemoveTypedWord = false;
+ removeSuggestedWordInfoFromList(typedWord, candidates, -1 /* startIndexExclusive */);
}
for (int i = 0; i < candidates.size(); ++i) {
- removeSuggestedWordInfoFrom(candidates.get(i).mWord, candidates,
+ removeSuggestedWordInfoFromList(candidates.get(i).mWord, candidates,
i /* startIndexExclusive */);
}
- return didRemoveTypedWord;
}
- private static boolean removeSuggestedWordInfoFrom(final String word,
- final ArrayList<SuggestedWordInfo> candidates, final int startIndexExclusive) {
- boolean didRemove = false;
+ private static void removeSuggestedWordInfoFromList(
+ @Nonnull final String word, @Nonnull final ArrayList<SuggestedWordInfo> candidates,
+ final int startIndexExclusive) {
for (int i = startIndexExclusive + 1; i < candidates.size(); ++i) {
final SuggestedWordInfo previous = candidates.get(i);
if (word.equals(previous.mWord)) {
- didRemove = true;
candidates.remove(i);
--i;
}
}
- return didRemove;
}
}
diff --git a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
index 123ab208c..982d4c690 100644
--- a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
+++ b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
@@ -69,7 +69,7 @@ public final class SystemBroadcastReceiver extends BroadcastReceiver {
// subtypes when the package is replaced.
RichInputMethodManager.init(context);
final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
- final InputMethodSubtype[] additionalSubtypes = richImm.getAdditionalSubtypes(context);
+ final InputMethodSubtype[] additionalSubtypes = richImm.getAdditionalSubtypes();
richImm.setAdditionalInputMethodSubtypes(additionalSubtypes);
LauncherIconVisibilityManager.updateSetupWizardIconVisibility(context);
} else if (Intent.ACTION_BOOT_COMPLETED.equals(intentAction)) {
diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java
index b749aa51a..21ea8f859 100644
--- a/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java
+++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java
@@ -196,16 +196,6 @@ final class CustomInputStylePreference extends DialogPreference
}
}
- private static int getSpinnerPosition(final Spinner spinner) {
- if (spinner == null) return -1;
- return spinner.getSelectedItemPosition();
- }
-
- private static void setSpinnerPosition(final Spinner spinner, final int position) {
- if (spinner == null || position < 0) return;
- spinner.setSelection(position);
- }
-
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
@@ -216,8 +206,6 @@ final class CustomInputStylePreference extends DialogPreference
final SavedState myState = new SavedState(superState);
myState.mSubtype = mSubtype;
- myState.mSubtypeLocaleSelectedPos = getSpinnerPosition(mSubtypeLocaleSpinner);
- myState.mKeyboardLayoutSetSelectedPos = getSpinnerPosition(mKeyboardLayoutSetSpinner);
return myState;
}
@@ -230,15 +218,11 @@ final class CustomInputStylePreference extends DialogPreference
final SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
- setSpinnerPosition(mSubtypeLocaleSpinner, myState.mSubtypeLocaleSelectedPos);
- setSpinnerPosition(mKeyboardLayoutSetSpinner, myState.mKeyboardLayoutSetSelectedPos);
setSubtype(myState.mSubtype);
}
static final class SavedState extends Preference.BaseSavedState {
InputMethodSubtype mSubtype;
- int mSubtypeLocaleSelectedPos;
- int mKeyboardLayoutSetSelectedPos;
public SavedState(final Parcelable superState) {
super(superState);
@@ -247,15 +231,11 @@ final class CustomInputStylePreference extends DialogPreference
@Override
public void writeToParcel(final Parcel dest, final int flags) {
super.writeToParcel(dest, flags);
- dest.writeInt(mSubtypeLocaleSelectedPos);
- dest.writeInt(mKeyboardLayoutSetSelectedPos);
dest.writeParcelable(mSubtype, 0);
}
public SavedState(final Parcel source) {
super(source);
- mSubtypeLocaleSelectedPos = source.readInt();
- mKeyboardLayoutSetSelectedPos = source.readInt();
mSubtype = (InputMethodSubtype)source.readParcelable(null);
}
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 16c053474..490fa827c 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -238,6 +238,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
}
+ public static float readPlausibilityThreshold(final Resources res) {
+ return Float.parseFloat(res.getString(R.string.plausibility_threshold));
+ }
+
public static boolean readBlockPotentiallyOffensive(final SharedPreferences prefs,
final Resources res) {
return prefs.getBoolean(PREF_BLOCK_POTENTIALLY_OFFENSIVE,
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 26415e7d4..c3755792c 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -96,6 +96,7 @@ public class SettingsValues {
public final int mKeyPreviewPopupDismissDelay;
private final boolean mAutoCorrectEnabled;
public final float mAutoCorrectionThreshold;
+ public final float mPlausibilityThreshold;
public final boolean mAutoCorrectionEnabledPerUserSettings;
private final boolean mSuggestionsEnabledPerUserSettings;
private final AsyncResultHolder<AppWorkaroundsUtils> mAppWorkarounds;
@@ -172,6 +173,7 @@ public class SettingsValues {
Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, true);
mAutoCorrectionThreshold = readAutoCorrectionThreshold(res,
autoCorrectionThresholdRawValue);
+ mPlausibilityThreshold = Settings.readPlausibilityThreshold(res);
mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
mGestureFloatingPreviewTextEnabled = !mInputAttributes.mDisableGestureFloatingPreviewText
diff --git a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java
index 120cffbde..2fd257922 100644
--- a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java
@@ -29,9 +29,8 @@ public final class AutoCorrectionUtils {
// Purely static class: can't instantiate.
}
- public static boolean suggestionExceedsAutoCorrectionThreshold(
- final SuggestedWordInfo suggestion, final String consideredWord,
- final float autoCorrectionThreshold) {
+ public static boolean suggestionExceedsThreshold(final SuggestedWordInfo suggestion,
+ final String consideredWord, final float threshold) {
if (null != suggestion) {
// Shortlist a whitelisted word
if (suggestion.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) {
@@ -45,11 +44,11 @@ public final class AutoCorrectionUtils {
if (DBG) {
Log.d(TAG, "Normalized " + consideredWord + "," + suggestion + ","
+ autoCorrectionSuggestionScore + ", " + normalizedScore
- + "(" + autoCorrectionThreshold + ")");
+ + "(" + threshold + ")");
}
- if (normalizedScore >= autoCorrectionThreshold) {
+ if (normalizedScore >= threshold) {
if (DBG) {
- Log.d(TAG, "Auto corrected by S-threshold.");
+ Log.d(TAG, "Exceeds threshold.");
}
return true;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
index 0bcc50dd4..fcce1ecdd 100644
--- a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
@@ -246,6 +246,17 @@ public class DictionaryInfoUtils {
}
/**
+ * Find out whether a dictionary is available for this locale.
+ * @param context the context on which to check resources.
+ * @param locale the locale to check for.
+ * @return whether a (non-placeholder) dictionary is available or not.
+ */
+ public static boolean isDictionaryAvailable(final Context context, final Locale locale) {
+ final Resources res = context.getResources();
+ return 0 != getMainDictionaryResourceIdIfAvailableForLocale(res, locale);
+ }
+
+ /**
* Helper method to return a dictionary res id for a locale, or 0 if none.
* @param res resources for the app
* @param locale dictionary locale