aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java4
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java1
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DictionaryService.java2
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/EventHandler.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java101
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java55
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java34
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/MatrixUtils.java1
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java12
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/SmoothingUtils.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java155
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java1
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java189
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java55
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java8
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java16
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java (renamed from java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java)94
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java (renamed from java/src/com/android/inputmethod/latin/personalization/PersonalizationDicitonary.java)4
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java14
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateListener.java2
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java36
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java4
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java (renamed from java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDicitonary.java)27
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettings.java1
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java10
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java6
-rw-r--r--java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java4
-rw-r--r--java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java5
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CsvUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java40
-rw-r--r--java/src/com/android/inputmethod/research/MainLogBuffer.java4
-rw-r--r--java/src/com/android/inputmethod/research/MotionEventReader.java10
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLogger.java23
37 files changed, 427 insertions, 512 deletions
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index e195a5406..55282c583 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -32,8 +32,6 @@ import java.lang.reflect.Field;
import java.util.ArrayList;
public final class SuggestionSpanUtils {
- private static final String TAG = SuggestionSpanUtils.class.getSimpleName();
-
// Note that SuggestionSpan.FLAG_AUTO_CORRECTION has been introduced
// in API level 15 (Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1).
public static final Field FIELD_FLAG_AUTO_CORRECTION = CompatUtils.getField(
@@ -60,7 +58,7 @@ public final class SuggestionSpanUtils {
}
final Spannable spannable = new SpannableString(text);
final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null /* locale */,
- new String[] {} /* suggestions */, (int)OBJ_FLAG_AUTO_CORRECTION,
+ new String[] {} /* suggestions */, OBJ_FLAG_AUTO_CORRECTION,
SuggestionSpanPickedNotificationReceiver.class);
spannable.setSpan(suggestionSpan, 0, text.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
index 62b905dc5..1d9b9991e 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
@@ -54,7 +54,6 @@ public final class DictionaryProvider extends ContentProvider {
private static final String QUERY_PARAMETER_MAY_PROMPT_USER = "mayPrompt";
private static final String QUERY_PARAMETER_TRUE = "true";
private static final String QUERY_PARAMETER_DELETE_RESULT = "result";
- private static final String QUERY_PARAMETER_SUCCESS = "success";
private static final String QUERY_PARAMETER_FAILURE = "failure";
public static final String QUERY_PARAMETER_PROTOCOL_VERSION = "protocol";
private static final int NO_MATCH = 0;
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
index 939c25f10..41916b614 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
@@ -50,8 +50,6 @@ import java.util.concurrent.TimeUnit;
* to access, and mark the current state as such.
*/
public final class DictionaryService extends Service {
- private static final String TAG = DictionaryService.class.getName();
-
/**
* The package name, to use in the intent actions.
*/
diff --git a/java/src/com/android/inputmethod/dictionarypack/EventHandler.java b/java/src/com/android/inputmethod/dictionarypack/EventHandler.java
index d8aa33bb8..859f1b35b 100644
--- a/java/src/com/android/inputmethod/dictionarypack/EventHandler.java
+++ b/java/src/com/android/inputmethod/dictionarypack/EventHandler.java
@@ -21,8 +21,6 @@ import android.content.Context;
import android.content.Intent;
public final class EventHandler extends BroadcastReceiver {
- private static final String TAG = EventHandler.class.getName();
-
/**
* Receives a intent broadcast.
*
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 6aa43b994..43baf6172 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -55,14 +55,12 @@ import com.android.inputmethod.keyboard.internal.KeyDrawParams;
import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams;
import com.android.inputmethod.keyboard.internal.PreviewPlacerView;
import com.android.inputmethod.keyboard.internal.SlidingKeyInputPreview;
-import com.android.inputmethod.keyboard.internal.TouchScreenRegulator;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.settings.DebugSettings;
-import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
@@ -116,13 +114,9 @@ import java.util.WeakHashMap;
* @attr ref R.styleable#MainKeyboardView_suppressKeyPreviewAfterBatchInputDuration
*/
public final class MainKeyboardView extends KeyboardView implements PointerTracker.KeyEventHandler,
- PointerTracker.DrawingProxy, MoreKeysPanel.Controller,
- TouchScreenRegulator.ProcessMotionEvent {
+ PointerTracker.DrawingProxy, MoreKeysPanel.Controller {
private static final String TAG = MainKeyboardView.class.getSimpleName();
- // TODO: Kill process when the usability study mode was changed.
- private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy;
-
/** Listener for {@link KeyboardActionListener}. */
private KeyboardActionListener mKeyboardActionListener;
@@ -184,8 +178,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
// TODO: Make this parameter customizable by user via settings.
private int mGestureFloatingPreviewTextLingerTimeout;
- private final TouchScreenRegulator mTouchScreenRegulator;
-
private KeyDetector mKeyDetector;
private final boolean mHasDistinctMultitouch;
private int mOldPointerCount = 1;
@@ -203,7 +195,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final int mKeyRepeatStartTimeout;
private final int mKeyRepeatInterval;
- private final int mLongPressShiftLockTimeout;
private final int mIgnoreAltCodeKeyTimeout;
private final int mGestureRecognitionUpdateTime;
@@ -215,8 +206,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
R.styleable.MainKeyboardView_keyRepeatStartTimeout, 0);
mKeyRepeatInterval = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_keyRepeatInterval, 0);
- mLongPressShiftLockTimeout = mainKeyboardViewAttr.getInt(
- R.styleable.MainKeyboardView_longPressShiftLockTimeout, 0);
mIgnoreAltCodeKeyTimeout = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_ignoreAltCodeKeyTimeout, 0);
mGestureRecognitionUpdateTime = mainKeyboardViewAttr.getInt(
@@ -280,31 +269,10 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
@Override
- public void startLongPressTimer(final PointerTracker tracker) {
+ public void startLongPressTimer(final PointerTracker tracker, final int delay) {
cancelLongPressTimer();
- if (tracker == null) {
- return;
- }
- final Key key = tracker.getKey();
- final int delay;
- switch (key.mCode) {
- case Constants.CODE_SHIFT:
- delay = mLongPressShiftLockTimeout;
- break;
- default:
- final int longpressTimeout =
- Settings.getInstance().getCurrent().mKeyLongpressTimeout;
- if (tracker.isInSlidingKeyInputFromModifier()) {
- // We use longer timeout for sliding finger input started from the modifier key.
- delay = longpressTimeout * 3;
- } else {
- delay = longpressTimeout;
- }
- break;
- }
- if (delay > 0) {
- sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
- }
+ if (delay <= 0) return;
+ sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
}
@Override
@@ -475,8 +443,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
public MainKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
- mTouchScreenRegulator = new TouchScreenRegulator(context, this);
-
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
final boolean forceNonDistinctMultitouch = prefs.getBoolean(
DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH, false);
@@ -653,7 +619,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
mKeyDetector.setKeyboard(
keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection());
PointerTracker.setKeyDetector(mKeyDetector);
- mTouchScreenRegulator.setKeyboardGeometry(keyboard.mOccupiedWidth);
mMoreKeysKeyboardCache.clear();
mSpaceKey = keyboard.getKey(Constants.CODE_SPACE);
@@ -901,9 +866,12 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
@Override
- public void showGestureTrail(final PointerTracker tracker) {
+ public void showGestureTrail(final PointerTracker tracker,
+ final boolean showsFloatingPreviewText) {
locatePreviewPlacerView();
- mGestureFloatingPreviewText.setPreviewPosition(tracker);
+ if (showsFloatingPreviewText) {
+ mGestureFloatingPreviewText.setPreviewPosition(tracker);
+ }
mGestureTrailsPreview.setPreviewPosition(tracker);
}
@@ -1072,10 +1040,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
if (getKeyboard() == null) {
return false;
}
- return mTouchScreenRegulator.onTouchEvent(me);
+ // TODO: Add multi-touch to single-touch event converter for non-distinct multi-touch
+ // device.
+ return processMotionEvent(me);
}
- @Override
public boolean processMotionEvent(final MotionEvent me) {
final boolean nonDistinctMultitouch = !mHasDistinctMultitouch;
final int action = me.getActionMasked();
@@ -1097,8 +1066,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
final int y = (int)me.getY(index);
// TODO: This might be moved to the tracker.processMotionEvent() call below.
- if (ENABLE_USABILITY_STUDY_LOG && action != MotionEvent.ACTION_MOVE) {
- writeUsabilityStudyLog(me, action, eventTime, index, id, x, y);
+ if (LatinImeLogger.sUsabilityStudy) {
+ UsabilityStudyLogUtils.writeMotionEvent(me);
}
// TODO: This should be moved to the tracker.processMotionEvent() call below.
// Currently the same "move" event is being logged twice.
@@ -1159,15 +1128,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
final int px = (int)me.getX(i);
final int py = (int)me.getY(i);
tracker.onMoveEvent(px, py, eventTime, me);
- if (ENABLE_USABILITY_STUDY_LOG) {
- writeUsabilityStudyLog(me, action, eventTime, i, pointerId, px, py);
- }
- // TODO: This seems to be no longer necessary, and confusing because it leads to
- // duplicate MotionEvents being recorded.
- // if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- // ResearchLogger.mainKeyboardView_processMotionEvent(
- // me, action, eventTime, i, pointerId, px, py);
- // }
}
} else {
final PointerTracker tracker = PointerTracker.getPointerTracker(id, this);
@@ -1177,35 +1137,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
return true;
}
- private static void writeUsabilityStudyLog(final MotionEvent me, final int action,
- final long eventTime, final int index, final int id, final int x, final int y) {
- final String eventTag;
- switch (action) {
- case MotionEvent.ACTION_UP:
- eventTag = "[Up]";
- break;
- case MotionEvent.ACTION_DOWN:
- eventTag = "[Down]";
- break;
- case MotionEvent.ACTION_POINTER_UP:
- eventTag = "[PointerUp]";
- break;
- case MotionEvent.ACTION_POINTER_DOWN:
- eventTag = "[PointerDown]";
- break;
- case MotionEvent.ACTION_MOVE:
- eventTag = "[Move]";
- break;
- default:
- eventTag = "[Action" + action + "]";
- break;
- }
- final float size = me.getSize(index);
- final float pressure = me.getPressure(index);
- UsabilityStudyLogUtils.getInstance().write(
- eventTag + eventTime + "," + id + "," + x + "," + y + "," + size + "," + pressure);
- }
-
public void cancelAllOngoingEvents() {
mKeyTimerHandler.cancelAllMessages();
mDrawingHandler.cancelAllMessages();
@@ -1398,4 +1329,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
drawIcon(canvas, mSpaceIcon, x, y, iconWidth, iconHeight);
}
}
+
+ public void deallocateMemory() {
+ mGestureTrailsPreview.deallocateMemory();
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index c7b096430..20fc109da 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -34,6 +34,7 @@ import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.ResourceUtils;
@@ -87,14 +88,14 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public void dismissKeyPreview(PointerTracker tracker);
public void showSlidingKeyInputPreview(PointerTracker tracker);
public void dismissSlidingKeyInputPreview();
- public void showGestureTrail(PointerTracker tracker);
+ public void showGestureTrail(PointerTracker tracker, boolean showsFloatingPreviewText);
}
public interface TimerProxy {
public void startTypingStateTimer(Key typedKey);
public boolean isTypingState();
public void startKeyRepeatTimer(PointerTracker tracker);
- public void startLongPressTimer(PointerTracker tracker);
+ public void startLongPressTimer(PointerTracker tracker, int delay);
public void cancelLongPressTimer();
public void startDoubleTapShiftKeyTimer();
public void cancelDoubleTapShiftKeyTimer();
@@ -112,7 +113,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
@Override
public void startKeyRepeatTimer(PointerTracker tracker) {}
@Override
- public void startLongPressTimer(PointerTracker tracker) {}
+ public void startLongPressTimer(PointerTracker tracker, int delay) {}
@Override
public void cancelLongPressTimer() {}
@Override
@@ -137,6 +138,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public final int mTouchNoiseThresholdTime;
public final int mTouchNoiseThresholdDistance;
public final int mSuppressKeyPreviewAfterBatchInputDuration;
+ public final int mLongPressShiftLockTimeout;
public static final PointerTrackerParams DEFAULT = new PointerTrackerParams();
@@ -145,6 +147,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
mTouchNoiseThresholdTime = 0;
mTouchNoiseThresholdDistance = 0;
mSuppressKeyPreviewAfterBatchInputDuration = 0;
+ mLongPressShiftLockTimeout = 0;
}
public PointerTrackerParams(final TypedArray mainKeyboardViewAttr) {
@@ -156,6 +159,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
R.styleable.MainKeyboardView_touchNoiseThresholdDistance, 0);
mSuppressKeyPreviewAfterBatchInputDuration = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_suppressKeyPreviewAfterBatchInputDuration, 0);
+ mLongPressShiftLockTimeout = mainKeyboardViewAttr.getInt(
+ R.styleable.MainKeyboardView_longPressShiftLockTimeout, 0);
}
}
@@ -327,6 +332,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// the more keys panel currently being shown. equals null if no panel is active.
private MoreKeysPanel mMoreKeysPanel;
+ private static final int MULTIPLIER_FOR_LONG_PRESS_TIMEOUT_IN_SLIDING_INPUT = 3;
// true if this pointer is in a sliding key input.
boolean mIsInSlidingKeyInput;
// true if this pointer is in a sliding key input from a modifier key,
@@ -602,10 +608,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
return mIsInSlidingKeyInput;
}
- public boolean isInSlidingKeyInputFromModifier() {
- return mIsInSlidingKeyInputFromModifier;
- }
-
public Key getKey() {
return mCurrentKey;
}
@@ -753,7 +755,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
return sPointerTrackerQueue.size();
}
- public boolean isOldestTrackerInQueue() {
+ private boolean isOldestTrackerInQueue() {
return sPointerTrackerQueue.getOldestElement() == this;
}
@@ -776,7 +778,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
dismissAllMoreKeysPanels();
}
mTimerProxy.cancelLongPressTimer();
- mDrawingProxy.showGestureTrail(this);
+ // A gesture floating preview text will be shown at the oldest pointer/finger on the screen.
+ mDrawingProxy.showGestureTrail(
+ this, isOldestTrackerInQueue() /* showsFloatingPreviewText */);
}
public void updateBatchInputByTimer(final long eventTime) {
@@ -792,7 +796,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (mIsTrackingForActionDisabled) {
return;
}
- mDrawingProxy.showGestureTrail(this);
+ // A gesture floating preview text will be shown at the oldest pointer/finger on the screen.
+ mDrawingProxy.showGestureTrail(
+ this, isOldestTrackerInQueue() /* showsFloatingPreviewText */);
}
private void updateBatchInput(final long eventTime) {
@@ -833,7 +839,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (mIsTrackingForActionDisabled) {
return;
}
- mDrawingProxy.showGestureTrail(this);
+ // A gesture floating preview text will be shown at the oldest pointer/finger on the screen.
+ mDrawingProxy.showGestureTrail(
+ this, isOldestTrackerInQueue() /* showsFloatingPreviewText */);
}
private void cancelBatchInput() {
@@ -1013,7 +1021,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
final int translatedY = mMoreKeysPanel.translateY(y);
mMoreKeysPanel.onMoveEvent(translatedX, translatedY, mPointerId, eventTime);
onMoveKey(x, y);
- mDrawingProxy.showSlidingKeyInputPreview(this);
+ if (mIsInSlidingKeyInputFromModifier) {
+ mDrawingProxy.showSlidingKeyInputPreview(this);
+ }
return;
}
onMoveEventInternal(x, y, eventTime);
@@ -1168,7 +1178,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
slideOutFromOldKey(oldKey, x, y);
}
}
- mDrawingProxy.showSlidingKeyInputPreview(this);
+ if (mIsInSlidingKeyInputFromModifier) {
+ mDrawingProxy.showSlidingKeyInputPreview(this);
+ }
}
public void onUpEvent(final int x, final int y, final long eventTime) {
@@ -1353,7 +1365,22 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// We always need to start the long press timer if the key has its more keys regardless of
// whether or not we are in the sliding input mode.
if (mIsInSlidingKeyInput && key.mMoreKeys == null) return;
- mTimerProxy.startLongPressTimer(this);
+ final int delay;
+ switch (key.mCode) {
+ case Constants.CODE_SHIFT:
+ delay = sParams.mLongPressShiftLockTimeout;
+ break;
+ default:
+ final int longpressTimeout = Settings.getInstance().getCurrent().mKeyLongpressTimeout;
+ if (mIsInSlidingKeyInputFromModifier) {
+ // We use longer timeout for sliding finger input started from the modifier key.
+ delay = longpressTimeout * MULTIPLIER_FOR_LONG_PRESS_TIMEOUT_IN_SLIDING_INPUT;
+ } else {
+ delay = longpressTimeout;
+ }
+ break;
+ }
+ mTimerProxy.startLongPressTimer(this, delay);
}
private void detectAndSendKey(final Key key, final int x, final int y, final long eventTime) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
index 9bfddba42..c6dd9e100 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
@@ -115,9 +115,7 @@ public class GestureFloatingPreviewText extends AbstractDrawingPreview {
@Override
public void setPreviewPosition(final PointerTracker tracker) {
- final boolean needsToUpdateLastPointer =
- tracker.isOldestTrackerInQueue() && isPreviewEnabled();
- if (!needsToUpdateLastPointer) {
+ if (!isPreviewEnabled()) {
return;
}
tracker.getLastCoordinates(mLastPointerCoords);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java
index dff5177ce..d4c25941c 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java
@@ -104,7 +104,12 @@ public final class GestureTrailsPreview extends AbstractDrawingPreview {
freeOffscreenBuffer();
}
+ public void deallocateMemory() {
+ freeOffscreenBuffer();
+ }
+
private void freeOffscreenBuffer() {
+ mOffscreenCanvas.setBitmap(null);
if (mOffscreenBuffer != null) {
mOffscreenBuffer.recycle();
mOffscreenBuffer = null;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 8ead44c31..164910dd4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -29,8 +29,8 @@ import com.android.inputmethod.latin.utils.RecapitalizeStatus;
*
* The input events are {@link #onLoadKeyboard()}, {@link #onSaveKeyboardState()},
* {@link #onPressKey(int,boolean,int)}, {@link #onReleaseKey(int,boolean)},
- * {@link #onCodeInput(int,int)}, {@link #onFinishSlidingInput()}, {@link #onCancelInput()},
- * {@link #onUpdateShiftState(int,int)}.
+ * {@link #onCodeInput(int,int)}, {@link #onFinishSlidingInput()},
+ * {@link #onUpdateShiftState(int,int)}, {@link #onResetKeyboardStateToAlphabet()}.
*
* The actions are {@link SwitchActions}'s methods.
*/
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index 1594df75b..7bb7442f3 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -374,8 +374,7 @@ public final class KeyboardTextsSet {
/* 115 */ "w",
/* 116 */ "y",
/* 117 */ "x",
- // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
- /* 118 */ "\u00F1",
+ /* 118 */ EMPTY,
/* 119 */ "!fixedColumnOrder!2,!hasLabels!,!text/label_time_am,!text/label_time_pm",
/* 120 */ "!icon/settings_key|!code/key_settings",
/* 121 */ "!icon/shortcut_key|!code/key_shortcut",
@@ -625,7 +624,8 @@ public final class KeyboardTextsSet {
/* Language az: Azerbaijani */
private static final String[] LANGUAGE_az = {
- /* 0 */ null,
+ // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+ /* 0 */ "\u00E2",
// U+0259: "ə" LATIN SMALL LETTER SCHWA
/* 1 */ "\u0259",
// U+0131: "ı" LATIN SMALL LETTER DOTLESS I
@@ -776,9 +776,28 @@ public final class KeyboardTextsSet {
/* 8~ */
null, null, null, null, null, null,
/* ~13 */
- // U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT
+ // U+00B7: "·" MIDDLE DOT
// U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
- /* 14 */ "\u0140,\u0142",
+ /* 14 */ "l\u00B7l,\u0142",
+ /* 15~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null,
+ /* ~52 */
+ // U+00B7: "·" MIDDLE DOT
+ /* 53 */ "!fixedColumnOrder!9,\u00B7,\",\',#,-,:,!,\\,,?,@,&,\\%,+,;,/,(,)",
+ /* 54~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null,
+ /* ~107 */
+ /* 108 */ "?,\u00B7",
+ /* 109~ */
+ null, null, null, null, null, null, null, null, null,
+ /* ~117 */
+ // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+ /* 118 */ "\u00E7",
};
/* Language cs: Czech */
@@ -1253,6 +1272,11 @@ public final class KeyboardTextsSet {
/* 109 */ "\"",
/* 110 */ "\'",
/* 111 */ "\'",
+ /* 112~ */
+ null, null, null, null, null, null,
+ /* ~117 */
+ // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+ /* 118 */ "\u00F1",
};
/* Language et: Estonian */
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MatrixUtils.java b/java/src/com/android/inputmethod/keyboard/internal/MatrixUtils.java
index 4916a15b5..c1f374964 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/MatrixUtils.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/MatrixUtils.java
@@ -30,7 +30,6 @@ import java.util.Arrays;
public class MatrixUtils {
private static final String TAG = MatrixUtils.class.getSimpleName();
public static class MatrixOperationFailedException extends Exception {
- private static final String TAG = MatrixOperationFailedException.class.getSimpleName();
private static final long serialVersionUID = 4384485606788583829L;
public MatrixOperationFailedException(String msg) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java b/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java
index 5c9d36702..2787ebfb9 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java
@@ -32,7 +32,7 @@ import com.android.inputmethod.latin.utils.CoordinateUtils;
public final class SlidingKeyInputPreview extends AbstractDrawingPreview {
private final float mPreviewBodyRadius;
- private boolean mShowSlidingKeyInputPreview;
+ private boolean mShowsSlidingKeyInputPreview;
private final int[] mPreviewFrom = CoordinateUtils.newInstance();
private final int[] mPreviewTo = CoordinateUtils.newInstance();
@@ -62,7 +62,7 @@ public final class SlidingKeyInputPreview extends AbstractDrawingPreview {
}
public void dismissSlidingKeyInputPreview() {
- mShowSlidingKeyInputPreview = false;
+ mShowsSlidingKeyInputPreview = false;
getDrawingView().invalidate();
}
@@ -72,7 +72,7 @@ public final class SlidingKeyInputPreview extends AbstractDrawingPreview {
*/
@Override
public void drawPreview(final Canvas canvas) {
- if (!isPreviewEnabled() || !mShowSlidingKeyInputPreview) {
+ if (!isPreviewEnabled() || !mShowsSlidingKeyInputPreview) {
return;
}
@@ -90,13 +90,9 @@ public final class SlidingKeyInputPreview extends AbstractDrawingPreview {
*/
@Override
public void setPreviewPosition(final PointerTracker tracker) {
- if (!tracker.isInSlidingKeyInputFromModifier()) {
- mShowSlidingKeyInputPreview = false;
- return;
- }
tracker.getDownCoordinates(mPreviewFrom);
tracker.getLastCoordinates(mPreviewTo);
- mShowSlidingKeyInputPreview = true;
+ mShowsSlidingKeyInputPreview = true;
getDrawingView().invalidate();
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/SmoothingUtils.java b/java/src/com/android/inputmethod/keyboard/internal/SmoothingUtils.java
index e5665bcdd..10847f62d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/SmoothingUtils.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/SmoothingUtils.java
@@ -62,7 +62,7 @@ public class SmoothingUtils {
for (int j = 0; j < COEFF_COUNT; ++j) {
final int pow = i + j;
for (int k = 0; k < N; ++k) {
- m0[i][j] += (float) Math.pow((double) xs[k], pow);
+ m0[i][j] += (float) Math.pow(xs[k], pow);
}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java b/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java
deleted file mode 100644
index fddd9856e..000000000
--- a/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.keyboard.internal;
-
-import android.content.Context;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.inputmethod.keyboard.MainKeyboardView;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.define.ProductionFlag;
-import com.android.inputmethod.latin.utils.ResourceUtils;
-import com.android.inputmethod.research.ResearchLogger;
-
-public final class TouchScreenRegulator {
- private static final String TAG = TouchScreenRegulator.class.getSimpleName();
- private static boolean DEBUG_MODE = LatinImeLogger.sDBG;
-
- public interface ProcessMotionEvent {
- public boolean processMotionEvent(MotionEvent me);
- }
-
- private final ProcessMotionEvent mView;
- private final boolean mNeedsSuddenJumpingHack;
-
- /** Whether we've started dropping move events because we found a big jump */
- private boolean mDroppingEvents;
- /**
- * Whether multi-touch disambiguation needs to be disabled if a real multi-touch event has
- * occured
- */
- private boolean mDisableDisambiguation;
- /** The distance threshold at which we start treating the touch session as a multi-touch */
- private int mJumpThresholdSquare = Integer.MAX_VALUE;
- private int mLastX;
- private int mLastY;
- // One-seventh of the keyboard width seems like a reasonable threshold
- private static final float JUMP_THRESHOLD_RATIO_TO_KEYBOARD_WIDTH = 1.0f / 7.0f;
-
- public TouchScreenRegulator(final Context context, final ProcessMotionEvent view) {
- mView = view;
- mNeedsSuddenJumpingHack = Boolean.parseBoolean(ResourceUtils.getDeviceOverrideValue(
- context.getResources(), R.array.sudden_jumping_touch_event_device_list));
- }
-
- public void setKeyboardGeometry(final int keyboardWidth) {
- final float jumpThreshold = keyboardWidth * JUMP_THRESHOLD_RATIO_TO_KEYBOARD_WIDTH;
- mJumpThresholdSquare = (int)(jumpThreshold * jumpThreshold);
- }
-
- /**
- * This function checks to see if we need to handle any sudden jumps in the pointer location
- * that could be due to a multi-touch being treated as a move by the firmware or hardware.
- * Once a sudden jump is detected, all subsequent move events are discarded
- * until an UP is received.<P>
- * When a sudden jump is detected, an UP event is simulated at the last position and when
- * the sudden moves subside, a DOWN event is simulated for the second key.
- * @param me the motion event
- * @return true if the event was consumed, so that it doesn't continue to be handled by
- * {@link MainKeyboardView}.
- */
- private boolean handleSuddenJumping(final MotionEvent me) {
- if (!mNeedsSuddenJumpingHack)
- return false;
- final int action = me.getAction();
- final int x = (int) me.getX();
- final int y = (int) me.getY();
- boolean result = false;
-
- // Real multi-touch event? Stop looking for sudden jumps
- if (me.getPointerCount() > 1) {
- mDisableDisambiguation = true;
- }
- if (mDisableDisambiguation) {
- // If UP, reset the multi-touch flag
- if (action == MotionEvent.ACTION_UP) mDisableDisambiguation = false;
- return false;
- }
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- // Reset the "session"
- mDroppingEvents = false;
- mDisableDisambiguation = false;
- break;
- case MotionEvent.ACTION_MOVE:
- // Is this a big jump?
- final int distanceSquare = (mLastX - x) * (mLastX - x) + (mLastY - y) * (mLastY - y);
- // Check the distance.
- if (distanceSquare > mJumpThresholdSquare) {
- // If we're not yet dropping events, start dropping and send an UP event
- if (!mDroppingEvents) {
- mDroppingEvents = true;
- // Send an up event
- MotionEvent translated = MotionEvent.obtain(
- me.getEventTime(), me.getEventTime(),
- MotionEvent.ACTION_UP,
- mLastX, mLastY, me.getMetaState());
- mView.processMotionEvent(translated);
- translated.recycle();
- }
- result = true;
- } else if (mDroppingEvents) {
- // If moves are small and we're already dropping events, continue dropping
- result = true;
- }
- break;
- case MotionEvent.ACTION_UP:
- if (mDroppingEvents) {
- // Send a down event first, as we dropped a bunch of sudden jumps and assume that
- // the user is releasing the touch on the second key.
- MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
- MotionEvent.ACTION_DOWN,
- x, y, me.getMetaState());
- mView.processMotionEvent(translated);
- translated.recycle();
- mDroppingEvents = false;
- // Let the up event get processed as well, result = false
- }
- break;
- }
- // Track the previous coordinate
- mLastX = x;
- mLastY = y;
- return result;
- }
-
- public boolean onTouchEvent(final MotionEvent me) {
- // If there was a sudden jump, return without processing the actual motion event.
- if (handleSuddenJumping(me)) {
- if (DEBUG_MODE)
- Log.w(TAG, "onTouchEvent: ignore sudden jump " + me);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.suddenJumpingTouchEventHandler_onTouchEvent(me);
- }
- return true;
- }
- return mView.processMotionEvent(me);
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 31a892e19..fa301b5a6 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.latin;
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.util.Log;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 9366abd73..614c14308 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -76,7 +76,7 @@ import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.personalization.PersonalizationDictionaryHelper;
-import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
+import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsActivity;
import com.android.inputmethod.latin.settings.SettingsValues;
@@ -169,7 +169,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private boolean mIsMainDictionaryAvailable;
private UserBinaryDictionary mUserDictionary;
- private UserHistoryDictionary mUserHistoryDictionary;
+ private UserHistoryPredictionDictionary mUserHistoryPredictionDictionary;
private boolean mIsUserDictionaryAvailable;
private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
@@ -539,34 +539,32 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
final String localeStr = subtypeLocale.toString();
- final ContactsBinaryDictionary oldContactsDictionary;
- if (mSuggest != null) {
- oldContactsDictionary = mSuggest.getContactsDictionary();
- mSuggest.close();
- } else {
- oldContactsDictionary = null;
- }
- mSuggest = new Suggest(this /* Context */, subtypeLocale,
+ final Suggest newSuggest = new Suggest(this /* Context */, subtypeLocale,
this /* SuggestInitializationListener */);
- if (mSettings.getCurrent().mCorrectionEnabled) {
- mSuggest.setAutoCorrectionThreshold(mSettings.getCurrent().mAutoCorrectionThreshold);
+ final SettingsValues settingsValues = mSettings.getCurrent();
+ if (settingsValues.mCorrectionEnabled) {
+ newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold);
}
mIsMainDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(this, subtypeLocale);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.getInstance().initSuggest(mSuggest);
+ ResearchLogger.getInstance().initSuggest(newSuggest);
}
mUserDictionary = new UserBinaryDictionary(this, localeStr);
mIsUserDictionaryAvailable = mUserDictionary.isEnabled();
- mSuggest.setUserDictionary(mUserDictionary);
-
- resetContactsDictionary(oldContactsDictionary);
+ newSuggest.setUserDictionary(mUserDictionary);
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- mUserHistoryDictionary =
- PersonalizationDictionaryHelper.getUserHistoryDictionary(this, localeStr, prefs);
- mSuggest.setUserHistoryDictionary(mUserHistoryDictionary);
+
+ mUserHistoryPredictionDictionary = PersonalizationDictionaryHelper
+ .getUserHistoryPredictionDictionary(this, localeStr, prefs);
+ newSuggest.setUserHistoryPredictionDictionary(mUserHistoryPredictionDictionary);
+
+ final Suggest oldSuggest = mSuggest;
+ resetContactsDictionary(null != oldSuggest ? oldSuggest.getContactsDictionary() : null);
+ mSuggest = newSuggest;
+ if (oldSuggest != null) oldSuggest.close();
}
/**
@@ -578,8 +576,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
* @param oldContactsDictionary an optional dictionary to use, or null
*/
private void resetContactsDictionary(final ContactsBinaryDictionary oldContactsDictionary) {
+ final Suggest suggest = mSuggest;
final boolean shouldSetDictionary =
- (null != mSuggest && mSettings.getCurrent().mUseContactsDict);
+ (null != suggest && mSettings.getCurrent().mUseContactsDict);
final ContactsBinaryDictionary dictionaryToUse;
if (!shouldSetDictionary) {
@@ -606,8 +605,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- if (null != mSuggest) {
- mSuggest.setContactsDictionary(dictionaryToUse);
+ if (null != suggest) {
+ suggest.setContactsDictionary(dictionaryToUse);
}
}
@@ -619,8 +618,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onDestroy() {
- if (mSuggest != null) {
- mSuggest.close();
+ final Suggest suggest = mSuggest;
+ if (suggest != null) {
+ suggest.close();
mSuggest = null;
}
mSettings.onDestroy();
@@ -714,7 +714,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
super.onStartInputView(editorInfo, restarting);
final KeyboardSwitcher switcher = mKeyboardSwitcher;
final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
- final SettingsValues currentSettingsValues = mSettings.getCurrent();
+ // If we are starting input in a different text field from before, we'll have to reload
+ // settings, so currentSettingsValues can't be final.
+ SettingsValues currentSettingsValues = mSettings.getCurrent();
if (editorInfo == null) {
Log.e(TAG, "Null EditorInfo in onStartInputView()");
@@ -792,7 +794,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Note: the following does a round-trip IPC on the main thread: be careful
final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
- if (null != mSuggest && null != currentLocale && !currentLocale.equals(mSuggest.mLocale)) {
+ final Suggest suggest = mSuggest;
+ if (null != suggest && null != currentLocale && !currentLocale.equals(suggest.mLocale)) {
initSuggest();
}
if (mSuggestionStripView != null) {
@@ -808,9 +811,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (isDifferentTextField) {
mainKeyboardView.closing();
loadSettings();
- // TODO: Need to update currentSettingsValues after loadSettings()
- if (mSuggest != null && currentSettingsValues.mCorrectionEnabled) {
- mSuggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold);
+ currentSettingsValues = mSettings.getCurrent();
+
+ if (suggest != null && currentSettingsValues.mCorrectionEnabled) {
+ suggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold);
}
switcher.loadKeyboard(editorInfo, currentSettingsValues);
@@ -890,6 +894,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) {
mainKeyboardView.cancelAllOngoingEvents();
+ mainKeyboardView.deallocateMemory();
}
// Remove pending messages related to update suggestions
mHandler.cancelUpdateSuggestionStrip();
@@ -1213,10 +1218,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void resetEntireInputState(final int newCursorPosition) {
final boolean shouldFinishComposition = mWordComposer.isComposingWord();
resetComposingState(true /* alsoResetLastComposedWord */);
- if (mSettings.getCurrent().mBigramPredictionEnabled) {
+ final SettingsValues settingsValues = mSettings.getCurrent();
+ if (settingsValues.mBigramPredictionEnabled) {
clearSuggestionStrip();
} else {
- setSuggestedWords(mSettings.getCurrent().mSuggestPuncList, false);
+ setSuggestedWords(settingsValues.mSuggestPuncList, false);
}
mConnection.resetCachesUponCursorMove(newCursorPosition, shouldFinishComposition);
}
@@ -1290,8 +1296,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private boolean maybeDoubleSpacePeriod() {
- if (!mSettings.getCurrent().mCorrectionEnabled) return false;
- if (!mSettings.getCurrent().mUseDoubleSpacePeriod) return false;
+ final SettingsValues settingsValues = mSettings.getCurrent();
+ if (!settingsValues.mCorrectionEnabled) return false;
+ if (!settingsValues.mUseDoubleSpacePeriod) return false;
if (!mHandler.isAcceptingDoubleSpacePeriod()) return false;
final CharSequence lastThree = mConnection.getTextBeforeCursor(3, 0);
if (lastThree != null && lastThree.length() == 3
@@ -1551,12 +1558,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final int spaceState) {
mSpaceState = SPACE_STATE_NONE;
final boolean didAutoCorrect;
- if (mSettings.getCurrent().isWordSeparator(primaryCode)) {
+ final SettingsValues settingsValues = mSettings.getCurrent();
+ if (settingsValues.isWordSeparator(primaryCode)) {
didAutoCorrect = handleSeparator(primaryCode, x, y, spaceState);
} else {
didAutoCorrect = false;
if (SPACE_STATE_PHANTOM == spaceState) {
- if (mSettings.isInternal()) {
+ if (settingsValues.mIsInternal) {
if (mWordComposer.isComposingWord() && mWordComposer.isBatchMode()) {
LatinImeLoggerUtils.onAutoCorrection(
"", mWordComposer.getTypedWord(), " ", mWordComposer);
@@ -1616,8 +1624,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
BatchInputUpdater.getInstance().onStartBatchInput(this);
mHandler.cancelUpdateSuggestionStrip();
mConnection.beginBatchEdit();
+ final SettingsValues settingsValues = mSettings.getCurrent();
if (mWordComposer.isComposingWord()) {
- if (mSettings.isInternal()) {
+ if (settingsValues.mIsInternal) {
if (mWordComposer.isBatchMode()) {
LatinImeLoggerUtils.onAutoCorrection(
"", mWordComposer.getTypedWord(), " ", mWordComposer);
@@ -1646,7 +1655,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
final int codePointBeforeCursor = mConnection.getCodePointBeforeCursor();
if (Character.isLetterOrDigit(codePointBeforeCursor)
- || mSettings.getCurrent().isUsuallyFollowedBySpace(codePointBeforeCursor)) {
+ || settingsValues.isUsuallyFollowedBySpace(codePointBeforeCursor)) {
mSpaceState = SPACE_STATE_PHANTOM;
}
mConnection.endBatchEdit();
@@ -1866,8 +1875,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mConnection.deleteSurroundingText(1, 0);
}
} else {
+ final SettingsValues currentSettings = mSettings.getCurrent();
if (mLastComposedWord.canRevertCommit()) {
- if (mSettings.isInternal()) {
+ if (currentSettings.mIsInternal) {
LatinImeLoggerUtils.onAutoCorrectionCancellation();
}
revertCommit();
@@ -1944,7 +1954,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
}
- if (mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation)) {
+ if (currentSettings.isSuggestionsRequested(mDisplayOrientation)) {
restartSuggestionsOnWordBeforeCursorIfAtEndOfWord();
}
}
@@ -1961,8 +1971,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
if ((SPACE_STATE_WEAK == spaceState || SPACE_STATE_SWAP_PUNCTUATION == spaceState)
&& isFromSuggestionStrip) {
- if (mSettings.getCurrent().isUsuallyPrecededBySpace(code)) return false;
- if (mSettings.getCurrent().isUsuallyFollowedBySpace(code)) return true;
+ final SettingsValues currentSettings = mSettings.getCurrent();
+ if (currentSettings.isUsuallyPrecededBySpace(code)) return false;
+ if (currentSettings.isUsuallyFollowedBySpace(code)) return true;
mConnection.removeTrailingSpace();
}
return false;
@@ -1974,8 +1985,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
// See onStartBatchInput() to see how to do it.
- if (SPACE_STATE_PHANTOM == spaceState &&
- !mSettings.getCurrent().isWordConnector(primaryCode)) {
+ final SettingsValues currentSettings = mSettings.getCurrent();
+ if (SPACE_STATE_PHANTOM == spaceState && !currentSettings.isWordConnector(primaryCode)) {
if (isComposingWord) {
// Sanity check
throw new RuntimeException("Should not be composing here");
@@ -1993,9 +2004,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// dozen milliseconds. Avoid calling it as much as possible, since we are on the UI
// thread here.
if (!isComposingWord && (isAlphabet(primaryCode)
- || mSettings.getCurrent().isWordConnector(primaryCode))
- && mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation) &&
- !mConnection.isCursorTouchingWord(mSettings.getCurrent())) {
+ || currentSettings.isWordConnector(primaryCode))
+ && currentSettings.isSuggestionsRequested(mDisplayOrientation) &&
+ !mConnection.isCursorTouchingWord(currentSettings)) {
// Reset entirely the composing state anyway, then start composing a new word unless
// the character is a single quote. The idea here is, single quote is not a
// separator and it should be treated as a normal character, except in the first
@@ -2038,7 +2049,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (null != mSuggestionStripView) mSuggestionStripView.dismissAddToDictionaryHint();
}
mHandler.postUpdateSuggestionStrip();
- if (mSettings.isInternal()) {
+ if (currentSettings.mIsInternal) {
LatinImeLoggerUtils.onNonSeparator((char)primaryCode, x, y);
}
}
@@ -2051,9 +2062,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final CharSequence selectedText =
mConnection.getSelectedText(0 /* flags, 0 for no styles */);
if (TextUtils.isEmpty(selectedText)) return; // Race condition with the input connection
+ final SettingsValues currentSettings = mSettings.getCurrent();
mRecapitalizeStatus.initialize(mLastSelectionStart, mLastSelectionEnd,
- selectedText.toString(), mSettings.getCurrentLocale(),
- mSettings.getWordSeparators());
+ selectedText.toString(), currentSettings.mLocale,
+ currentSettings.mWordSeparators);
// We trim leading and trailing whitespace.
mRecapitalizeStatus.trim();
// Trimming the object may have changed the length of the string, and we need to
@@ -2087,8 +2099,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// first so that we can insert the separator at the current cursor position.
resetEntireInputState(mLastSelectionStart);
}
+ final SettingsValues currentSettings = mSettings.getCurrent();
if (mWordComposer.isComposingWord()) {
- if (mSettings.getCurrent().mCorrectionEnabled) {
+ if (currentSettings.mCorrectionEnabled) {
// TODO: maybe cache Strings in an <String> sparse array or something
commitCurrentAutoCorrection(new String(new int[]{primaryCode}, 0, 1));
didAutoCorrect = true;
@@ -2101,7 +2114,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
Constants.SUGGESTION_STRIP_COORDINATE == x);
if (SPACE_STATE_PHANTOM == spaceState &&
- mSettings.getCurrent().isUsuallyPrecededBySpace(primaryCode)) {
+ currentSettings.isUsuallyPrecededBySpace(primaryCode)) {
promotePhantomSpace();
}
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -2110,7 +2123,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
sendKeyCodePoint(primaryCode);
if (Constants.CODE_SPACE == primaryCode) {
- if (mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation)) {
+ if (currentSettings.isSuggestionsRequested(mDisplayOrientation)) {
if (maybeDoubleSpacePeriod()) {
mSpaceState = SPACE_STATE_DOUBLE;
} else if (!isShowingPunctuationList()) {
@@ -2125,7 +2138,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
swapSwapperAndSpace();
mSpaceState = SPACE_STATE_SWAP_PUNCTUATION;
} else if (SPACE_STATE_PHANTOM == spaceState
- && mSettings.getCurrent().isUsuallyFollowedBySpace(primaryCode)) {
+ && currentSettings.isUsuallyFollowedBySpace(primaryCode)) {
// If we are in phantom space state, and the user presses a separator, we want to
// stay in phantom space state so that the next keypress has a chance to add the
// space. For example, if I type "Good dat", pick "day" from the suggestion strip
@@ -2143,7 +2156,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// already displayed or not, so it's okay.
setPunctuationSuggestions();
}
- if (mSettings.isInternal()) {
+ if (currentSettings.mIsInternal) {
LatinImeLoggerUtils.onSeparator((char)primaryCode, x, y);
}
@@ -2176,17 +2189,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private boolean isSuggestionsStripVisible() {
+ final SettingsValues currentSettings = mSettings.getCurrent();
if (mSuggestionStripView == null)
return false;
if (mSuggestionStripView.isShowingAddToDictionaryHint())
return true;
- if (null == mSettings.getCurrent())
+ if (null == currentSettings)
return false;
- if (!mSettings.getCurrent().isSuggestionStripVisibleInOrientation(mDisplayOrientation))
+ if (!currentSettings.isSuggestionStripVisibleInOrientation(mDisplayOrientation))
return false;
- if (mSettings.getCurrent().isApplicationSpecifiedCompletionsOn())
+ if (currentSettings.isApplicationSpecifiedCompletionsOn())
return true;
- return mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation);
+ return currentSettings.isSuggestionsRequested(mDisplayOrientation);
}
private void clearSuggestionStrip() {
@@ -2219,10 +2233,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void updateSuggestionStrip() {
mHandler.cancelUpdateSuggestionStrip();
+ final SettingsValues currentSettings = mSettings.getCurrent();
// Check if we have a suggestion engine attached.
if (mSuggest == null
- || !mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation)) {
+ || !currentSettings.isSuggestionsRequested(mDisplayOrientation)) {
if (mWordComposer.isComposingWord()) {
Log.w(TAG, "Called updateSuggestionsOrPredictions but suggestions were not "
+ "requested!");
@@ -2230,7 +2245,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
- if (!mWordComposer.isComposingWord() && !mSettings.getCurrent().mBigramPredictionEnabled) {
+ if (!mWordComposer.isComposingWord() && !currentSettings.mBigramPredictionEnabled) {
setPunctuationSuggestions();
return;
}
@@ -2251,12 +2266,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
// should just skip whitespace if any, so 1.
// TODO: this is slow (2-way IPC) - we should probably cache this instead.
+ final SettingsValues currentSettings = mSettings.getCurrent();
final String prevWord =
- mConnection.getNthPreviousWord(mSettings.getCurrent().mWordSeparators,
+ mConnection.getNthPreviousWord(currentSettings.mWordSeparators,
mWordComposer.isComposingWord() ? 2 : 1);
return suggest.getSuggestedWords(mWordComposer, prevWord, keyboard.getProximityInfo(),
- mSettings.getBlockPotentiallyOffensive(),
- mSettings.getCurrent().mCorrectionEnabled, sessionId);
+ currentSettings.mBlockPotentiallyOffensive,
+ currentSettings.mCorrectionEnabled, sessionId);
}
private SuggestedWords getSuggestedWordsOrOlderSuggestions(final int sessionId) {
@@ -2382,18 +2398,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mConnection.beginBatchEdit();
+ final SettingsValues currentSettings = mSettings.getCurrent();
if (SPACE_STATE_PHANTOM == mSpaceState && suggestion.length() > 0
// In the batch input mode, a manually picked suggested word should just replace
// the current batch input text and there is no need for a phantom space.
&& !mWordComposer.isBatchMode()) {
final int firstChar = Character.codePointAt(suggestion, 0);
- if (!mSettings.getCurrent().isWordSeparator(firstChar)
- || mSettings.getCurrent().isUsuallyPrecededBySpace(firstChar)) {
+ if (!currentSettings.isWordSeparator(firstChar)
+ || currentSettings.isUsuallyPrecededBySpace(firstChar)) {
promotePhantomSpace();
}
}
- if (mSettings.getCurrent().isApplicationSpecifiedCompletionsOn()
+ if (currentSettings.isApplicationSpecifiedCompletionsOn()
&& mApplicationSpecifiedCompletions != null
&& index >= 0 && index < mApplicationSpecifiedCompletions.length) {
mSuggestedWords = SuggestedWords.EMPTY;
@@ -2431,20 +2448,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// AND it's in none of our current dictionaries (main, user or otherwise).
// Please note that if mSuggest is null, it means that everything is off: suggestion
// and correction, so we shouldn't try to show the hint
+ final Suggest suggest = mSuggest;
final boolean showingAddToDictionaryHint =
(SuggestedWordInfo.KIND_TYPED == suggestionInfo.mKind
|| SuggestedWordInfo.KIND_OOV_CORRECTION == suggestionInfo.mKind)
- && mSuggest != null
+ && suggest != null
// If the suggestion is not in the dictionary, the hint should be shown.
- && !AutoCorrectionUtils.isValidWord(mSuggest, suggestion, true);
+ && !AutoCorrectionUtils.isValidWord(suggest, suggestion, true);
- if (mSettings.isInternal()) {
+ if (currentSettings.mIsInternal) {
LatinImeLoggerUtils.onSeparator((char)Constants.CODE_SPACE,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
}
if (showingAddToDictionaryHint && mIsUserDictionaryAvailable) {
mSuggestionStripView.showAddToDictionaryHint(
- suggestion, mSettings.getCurrent().mHintToSaveText);
+ suggestion, currentSettings.mHintToSaveText);
} else {
// If we're not showing the "Touch again to save", then update the suggestion strip.
mHandler.postUpdateSuggestionStrip();
@@ -2470,10 +2488,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void setPunctuationSuggestions() {
- if (mSettings.getCurrent().mBigramPredictionEnabled) {
+ final SettingsValues currentSettings = mSettings.getCurrent();
+ if (currentSettings.mBigramPredictionEnabled) {
clearSuggestionStrip();
} else {
- setSuggestedWords(mSettings.getCurrent().mSuggestPuncList, false);
+ setSuggestedWords(currentSettings.mSuggestPuncList, false);
}
setAutoCorrectionIndicator(false);
setSuggestionStripShown(isSuggestionsStripVisible());
@@ -2481,21 +2500,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private String addToUserHistoryDictionary(final String suggestion) {
if (TextUtils.isEmpty(suggestion)) return null;
- if (mSuggest == null) return null;
+ final Suggest suggest = mSuggest;
+ if (suggest == null) return null;
// If correction is not enabled, we don't add words to the user history dictionary.
// That's to avoid unintended additions in some sensitive fields, or fields that
// expect to receive non-words.
- if (!mSettings.getCurrent().mCorrectionEnabled) return null;
+ final SettingsValues currentSettings = mSettings.getCurrent();
+ if (!currentSettings.mCorrectionEnabled) return null;
- final Suggest suggest = mSuggest;
- final UserHistoryDictionary userHistoryDictionary = mUserHistoryDictionary;
- if (suggest == null || userHistoryDictionary == null) {
- // Avoid concurrent issue
- return null;
- }
- final String prevWord
- = mConnection.getNthPreviousWord(mSettings.getCurrent().mWordSeparators, 2);
+ final UserHistoryPredictionDictionary userHistoryDictionary =
+ mUserHistoryPredictionDictionary;
+ if (userHistoryDictionary == null) return null;
+
+ final String prevWord = mConnection.getNthPreviousWord(currentSettings.mWordSeparators, 2);
final String secondWord;
if (mWordComposer.wasAutoCapitalized() && !mWordComposer.isMostlyCaps()) {
secondWord = suggestion.toLowerCase(mSubtypeSwitcher.getCurrentSubtypeLocale());
@@ -2524,8 +2542,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (mLastSelectionStart != mLastSelectionEnd) return;
// If we don't know the cursor location, return.
if (mLastSelectionStart < 0) return;
- if (!mConnection.isCursorTouchingWord(mSettings.getCurrent())) return;
- final TextRange range = mConnection.getWordRangeAtCursor(mSettings.getWordSeparators(),
+ final SettingsValues currentSettings = mSettings.getCurrent();
+ if (!mConnection.isCursorTouchingWord(currentSettings)) return;
+ final TextRange range = mConnection.getWordRangeAtCursor(currentSettings.mWordSeparators,
0 /* additionalPrecedingWordsCount */);
if (null == range) return; // Happens if we don't have an input connection at all
// If for some strange reason (editor bug or so) we measure the text before the cursor as
@@ -2639,7 +2658,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mConnection.deleteSurroundingText(deleteLength, 0);
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
- mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord);
+ mUserHistoryPredictionDictionary.cancelAddingUserHistory(previousWord, committedWord);
}
mConnection.commitText(originallyTypedWord + mLastComposedWord.mSeparatorString, 1);
if (mSettings.isInternal()) {
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index d07fa47d6..b69e3f8d2 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -56,11 +56,14 @@ public final class RichInputConnection {
private static final int INVALID_CURSOR_POSITION = -1;
/**
- * This variable contains the value LatinIME thinks the cursor position should be at now.
- * This is a few steps in advance of what the TextView thinks it is, because TextView will
- * only know after the IPC calls gets through.
+ * This variable contains an expected value for the cursor position. This is where the
+ * cursor may end up after all the keyboard-triggered updates have passed. We keep this to
+ * compare it to the actual cursor position to guess whether the move was caused by a
+ * keyboard command or not.
+ * It's not really the cursor position: the cursor may not be there yet, and it's also expected
+ * there be cases where it never actually comes to be there.
*/
- private int mCurrentCursorPosition = INVALID_CURSOR_POSITION; // in chars, not code points
+ private int mExpectedCursorPosition = INVALID_CURSOR_POSITION; // in chars, not code points
/**
* This contains the committed text immediately preceding the cursor and the composing
* text if any. It is refreshed when the cursor moves by calling upon the TextView.
@@ -101,16 +104,16 @@ public final class RichInputConnection {
final String reference = (beforeCursor.length() <= actualLength) ? beforeCursor.toString()
: beforeCursor.subSequence(beforeCursor.length() - actualLength,
beforeCursor.length()).toString();
- if (et.selectionStart != mCurrentCursorPosition
+ if (et.selectionStart != mExpectedCursorPosition
|| !(reference.equals(internal.toString()))) {
- final String context = "Expected cursor position = " + mCurrentCursorPosition
+ final String context = "Expected cursor position = " + mExpectedCursorPosition
+ "\nActual cursor position = " + et.selectionStart
+ "\nExpected text = " + internal.length() + " " + internal
+ "\nActual text = " + reference.length() + " " + reference;
((LatinIME)mParent).debugDumpStateAndCrashWithException(context);
} else {
Log.e(TAG, DebugLogUtils.getStackTrace(2));
- Log.e(TAG, "Exp <> Actual : " + mCurrentCursorPosition + " <> " + et.selectionStart);
+ Log.e(TAG, "Exp <> Actual : " + mExpectedCursorPosition + " <> " + et.selectionStart);
}
}
@@ -141,7 +144,7 @@ public final class RichInputConnection {
public void resetCachesUponCursorMove(final int newCursorPosition,
final boolean shouldFinishComposition) {
- mCurrentCursorPosition = newCursorPosition;
+ mExpectedCursorPosition = newCursorPosition;
mComposingText.setLength(0);
mCommittedTextBeforeComposingText.setLength(0);
final CharSequence textBeforeCursor = getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0);
@@ -166,7 +169,7 @@ public final class RichInputConnection {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
mCommittedTextBeforeComposingText.append(mComposingText);
- mCurrentCursorPosition += mComposingText.length();
+ mExpectedCursorPosition += mComposingText.length();
mComposingText.setLength(0);
if (null != mIC) {
mIC.finishComposingText();
@@ -180,7 +183,7 @@ public final class RichInputConnection {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
mCommittedTextBeforeComposingText.append(text);
- mCurrentCursorPosition += text.length() - mComposingText.length();
+ mExpectedCursorPosition += text.length() - mComposingText.length();
mComposingText.setLength(0);
if (null != mIC) {
mIC.commitText(text, i);
@@ -193,7 +196,7 @@ public final class RichInputConnection {
}
public boolean canDeleteCharacters() {
- return mCurrentCursorPosition > 0;
+ return mExpectedCursorPosition > 0;
}
/**
@@ -230,7 +233,7 @@ public final class RichInputConnection {
// heavy pressing of delete, for example DEFAULT_TEXT_CACHE_SIZE - 5 times or so.
// getCapsMode should be updated to be able to return a "not enough info" result so that
// we can get more context only when needed.
- if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mCurrentCursorPosition) {
+ if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mExpectedCursorPosition) {
mCommittedTextBeforeComposingText.append(
getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0));
}
@@ -251,7 +254,7 @@ public final class RichInputConnection {
mCommittedTextBeforeComposingText.length() + mComposingText.length();
// If we have enough characters to satisfy the request, or if we have all characters in
// the text field, then we can return the cached version right away.
- if (cachedLength >= n || cachedLength >= mCurrentCursorPosition) {
+ if (cachedLength >= n || cachedLength >= mExpectedCursorPosition) {
final StringBuilder s = new StringBuilder(mCommittedTextBeforeComposingText);
s.append(mComposingText);
if (s.length() > n) {
@@ -284,10 +287,10 @@ public final class RichInputConnection {
+ remainingChars, 0);
mCommittedTextBeforeComposingText.setLength(len);
}
- if (mCurrentCursorPosition > beforeLength) {
- mCurrentCursorPosition -= beforeLength;
+ if (mExpectedCursorPosition > beforeLength) {
+ mExpectedCursorPosition -= beforeLength;
} else {
- mCurrentCursorPosition = 0;
+ mExpectedCursorPosition = 0;
}
if (null != mIC) {
mIC.deleteSurroundingText(beforeLength, afterLength);
@@ -321,7 +324,7 @@ public final class RichInputConnection {
switch (keyEvent.getKeyCode()) {
case KeyEvent.KEYCODE_ENTER:
mCommittedTextBeforeComposingText.append("\n");
- mCurrentCursorPosition += 1;
+ mExpectedCursorPosition += 1;
break;
case KeyEvent.KEYCODE_DEL:
if (0 == mComposingText.length()) {
@@ -333,18 +336,18 @@ public final class RichInputConnection {
} else {
mComposingText.delete(mComposingText.length() - 1, mComposingText.length());
}
- if (mCurrentCursorPosition > 0) mCurrentCursorPosition -= 1;
+ if (mExpectedCursorPosition > 0) mExpectedCursorPosition -= 1;
break;
case KeyEvent.KEYCODE_UNKNOWN:
if (null != keyEvent.getCharacters()) {
mCommittedTextBeforeComposingText.append(keyEvent.getCharacters());
- mCurrentCursorPosition += keyEvent.getCharacters().length();
+ mExpectedCursorPosition += keyEvent.getCharacters().length();
}
break;
default:
final String text = new String(new int[] { keyEvent.getUnicodeChar() }, 0, 1);
mCommittedTextBeforeComposingText.append(text);
- mCurrentCursorPosition += text.length();
+ mExpectedCursorPosition += text.length();
break;
}
}
@@ -378,7 +381,7 @@ public final class RichInputConnection {
public void setComposingText(final CharSequence text, final int newCursorPosition) {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
- mCurrentCursorPosition += text.length() - mComposingText.length();
+ mExpectedCursorPosition += text.length() - mComposingText.length();
mComposingText.setLength(0);
mComposingText.append(text);
// TODO: support values of i != 1. At this time, this is never called with i != 1.
@@ -400,7 +403,7 @@ public final class RichInputConnection {
ResearchLogger.richInputConnection_setSelection(start, end);
}
}
- mCurrentCursorPosition = start;
+ mExpectedCursorPosition = start;
mCommittedTextBeforeComposingText.setLength(0);
mCommittedTextBeforeComposingText.append(getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0));
}
@@ -423,7 +426,7 @@ public final class RichInputConnection {
// text should never be null, but just in case, it's better to insert nothing than to crash
if (null == text) text = "";
mCommittedTextBeforeComposingText.append(text);
- mCurrentCursorPosition += text.length() - mComposingText.length();
+ mExpectedCursorPosition += text.length() - mComposingText.length();
mComposingText.setLength(0);
if (null != mIC) {
mIC.commitCompletion(completionInfo);
@@ -705,14 +708,14 @@ public final class RichInputConnection {
*/
public boolean isBelatedExpectedUpdate(final int oldSelStart, final int newSelStart) {
// If this is an update that arrives at our expected position, it's a belated update.
- if (newSelStart == mCurrentCursorPosition) return true;
+ if (newSelStart == mExpectedCursorPosition) return true;
// If this is an update that moves the cursor from our expected position, it must be
// an explicit move.
- if (oldSelStart == mCurrentCursorPosition) return false;
+ if (oldSelStart == mExpectedCursorPosition) return false;
// The following returns true if newSelStart is between oldSelStart and
// mCurrentCursorPosition. We assume that if the updated position is between the old
// position and the expected position, then it must be a belated update.
- return (newSelStart - oldSelStart) * (mCurrentCursorPosition - newSelStart) >= 0;
+ return (newSelStart - oldSelStart) * (mExpectedCursorPosition - newSelStart) >= 0;
}
/**
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 647c6f6e1..6b016675a 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -22,7 +22,7 @@ import android.text.TextUtils;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
+import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.BoundedTreeSet;
import com.android.inputmethod.latin.utils.CollectionUtils;
@@ -168,8 +168,10 @@ public final class Suggest {
addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_CONTACTS, contactsDictionary);
}
- public void setUserHistoryDictionary(final UserHistoryDictionary userHistoryDictionary) {
- addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER_HISTORY, userHistoryDictionary);
+ public void setUserHistoryPredictionDictionary(
+ final UserHistoryPredictionDictionary userHistoryPredictionDictionary) {
+ addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER_HISTORY,
+ userHistoryPredictionDictionary);
}
public void setAutoCorrectionThreshold(float threshold) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 000c25270..167c6915c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -982,6 +982,7 @@ public final class BinaryDictIOUtils {
return null;
}
+ private static final int HEADER_READING_BUFFER_SIZE = 16384;
/**
* Convenience method to read the header of a binary file.
*
@@ -991,7 +992,6 @@ public final class BinaryDictIOUtils {
* @param offset The offset in the file where to start reading the data.
* @param length The length of the data file.
*/
- private static final int HEADER_READING_BUFFER_SIZE = 16384;
public static FileHeader getDictionaryFileHeader(
final File file, final long offset, final long length)
throws FileNotFoundException, IOException, UnsupportedFormatException {
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 5a2b24c58..118dc22b8 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -34,6 +34,8 @@ import java.util.LinkedList;
public final class FusionDictionary implements Iterable<Word> {
private static final boolean DBG = MakedictLog.DBG;
+ private static int CHARACTER_NOT_FOUND_INDEX = -1;
+
/**
* A node of the dictionary, containing several CharGroups.
*
@@ -473,7 +475,7 @@ public final class FusionDictionary implements Iterable<Word> {
CharGroup currentGroup = null;
int differentCharIndex = 0; // Set by the loop to the index of the char that differs
int nodeIndex = findIndexOfChar(mRoot, word[charIndex]);
- while (CHARACTER_NOT_FOUND != nodeIndex) {
+ while (CHARACTER_NOT_FOUND_INDEX != nodeIndex) {
currentGroup = currentNode.mData.get(nodeIndex);
differentCharIndex = compareArrays(currentGroup.mChars, word, charIndex);
if (ARRAYS_ARE_EQUAL != differentCharIndex
@@ -485,7 +487,7 @@ public final class FusionDictionary implements Iterable<Word> {
nodeIndex = findIndexOfChar(currentNode, word[charIndex]);
}
- if (-1 == nodeIndex) {
+ if (CHARACTER_NOT_FOUND_INDEX == nodeIndex) {
// No node at this point to accept the word. Create one.
final int insertionIndex = findInsertionIndex(currentNode, word[charIndex]);
final CharGroup newGroup = new CharGroup(
@@ -612,20 +614,18 @@ public final class FusionDictionary implements Iterable<Word> {
return result >= 0 ? result : -result - 1;
}
- private static int CHARACTER_NOT_FOUND = -1;
-
/**
* Find the index of a char in a node, if it exists.
*
* @param node the node to search in.
* @param character the character to search for.
- * @return the position of the character if it's there, or CHARACTER_NOT_FOUND = -1 else.
+ * @return the position of the character if it's there, or CHARACTER_NOT_FOUND_INDEX = -1 else.
*/
private static int findIndexOfChar(final Node node, int character) {
final int insertionIndex = findInsertionIndex(node, character);
- if (node.mData.size() <= insertionIndex) return CHARACTER_NOT_FOUND;
+ if (node.mData.size() <= insertionIndex) return CHARACTER_NOT_FOUND_INDEX;
return character == node.mData.get(insertionIndex).mChars[0] ? insertionIndex
- : CHARACTER_NOT_FOUND;
+ : CHARACTER_NOT_FOUND_INDEX;
}
/**
@@ -640,7 +640,7 @@ public final class FusionDictionary implements Iterable<Word> {
CharGroup currentGroup;
do {
int indexOfGroup = findIndexOfChar(node, codePoints[index]);
- if (CHARACTER_NOT_FOUND == indexOfGroup) return null;
+ if (CHARACTER_NOT_FOUND_INDEX == indexOfGroup) return null;
currentGroup = node.mData.get(indexOfGroup);
if (codePoints.length - index < currentGroup.mChars.length) return null;
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java
index c76dea0bb..9d041f4eb 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.ExpandableDictionary;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -47,16 +46,17 @@ import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantLock;
/**
- * Locally gathers stats about the words user types and various other signals like auto-correction
- * cancellation or manual picks. This allows the keyboard to adapt to the typist over time.
+ * This class is a base class of a dictionary for the personalized prediction language model.
*/
-public class UserHistoryDictionary extends ExpandableDictionary {
- private static final String TAG = UserHistoryDictionary.class.getSimpleName();
- private static final String NAME = UserHistoryDictionary.class.getSimpleName();
+public abstract class DynamicPredictionDictionaryBase extends ExpandableDictionary {
+ public static void registerUpdateListener(PersonalizationDictionaryUpdateListener listener) {
+ // TODO: Implement
+ }
+
+ private static final String TAG = DynamicPredictionDictionaryBase.class.getSimpleName();
public static final boolean DBG_SAVE_RESTORE = false;
- public static final boolean DBG_STRESS_TEST = false;
- public static final boolean DBG_ALWAYS_WRITE = false;
- public static final boolean PROFILE_SAVE_RESTORE = LatinImeLogger.sDBG;
+ private static final boolean DBG_STRESS_TEST = false;
+ private static final boolean PROFILE_SAVE_RESTORE = LatinImeLogger.sDBG;
private static final FormatOptions VERSION3 = new FormatOptions(3,
true /* supportsDynamicUpdate */);
@@ -65,14 +65,7 @@ public class UserHistoryDictionary extends ExpandableDictionary {
private static final int FREQUENCY_FOR_TYPED = 2;
/** Maximum number of pairs. Pruning will start when databases goes above this number. */
- public static final int MAX_HISTORY_BIGRAMS = 10000;
-
- /**
- * When it hits maximum bigram pair, it will delete until you are left with
- * only (sMaxHistoryBigrams - sDeleteHistoryBigrams) pairs.
- * Do not keep this number small to avoid deleting too often.
- */
- public static final int DELETE_HISTORY_BIGRAMS = 1000;
+ private static final int MAX_HISTORY_BIGRAMS = 10000;
/** Locale for which this user history dictionary is storing words */
private final String mLocale;
@@ -85,9 +78,9 @@ public class UserHistoryDictionary extends ExpandableDictionary {
// Should always be false except when we use this class for test
@UsedForTesting boolean isTest = false;
- /* package */ UserHistoryDictionary(final Context context, final String locale,
- final SharedPreferences sp) {
- super(context, Dictionary.TYPE_USER_HISTORY);
+ /* package */ DynamicPredictionDictionaryBase(final Context context, final String locale,
+ final SharedPreferences sp, final String dictionaryType) {
+ super(context, dictionaryType);
mLocale = locale;
mPrefs = sp;
if (mLocale != null && mLocale.length() > 1) {
@@ -102,8 +95,8 @@ public class UserHistoryDictionary extends ExpandableDictionary {
// Also, the database is written to somewhat frequently, so it needs to be kept alive
// throughout the life of the process.
// mOpenHelper.close();
- // Ignore close because we cache UserHistoryDictionary for each language. See getInstance()
- // above.
+ // Ignore close because we cache PersonalizationPredictionDictionary for each language.
+ // See getInstance() above.
// super.close();
}
@@ -184,7 +177,7 @@ public class UserHistoryDictionary extends ExpandableDictionary {
}
@Override
- public void loadDictionaryAsync() {
+ public final void loadDictionaryAsync() {
// This must be run on non-main thread
mBigramListLock.lock();
try {
@@ -194,48 +187,47 @@ public class UserHistoryDictionary extends ExpandableDictionary {
}
}
- private int profTotal;
-
private void loadDictionaryAsyncLocked() {
+ final int[] profTotalCount = { 0 };
+ final String locale = getLocale();
if (DBG_STRESS_TEST) {
try {
- Log.w(TAG, "Start stress in loading: " + mLocale);
+ Log.w(TAG, "Start stress in loading: " + locale);
Thread.sleep(15000);
Log.w(TAG, "End stress in loading");
} catch (InterruptedException e) {
}
}
- final long last = Settings.readLastUserHistoryWriteTime(mPrefs, mLocale);
+ final long last = Settings.readLastUserHistoryWriteTime(mPrefs, locale);
final boolean initializing = last == 0;
final long now = System.currentTimeMillis();
- profTotal = 0;
- final String fileName = NAME + "." + mLocale + ".dict";
+ final String fileName = getDictionaryFileName();
final ExpandableDictionary dictionary = this;
final OnAddWordListener listener = new OnAddWordListener() {
@Override
public void setUnigram(final String word, final String shortcutTarget,
final int frequency) {
- profTotal++;
if (DBG_SAVE_RESTORE) {
Log.d(TAG, "load unigram: " + word + "," + frequency);
}
dictionary.addWord(word, shortcutTarget, frequency);
- mBigramList.addBigram(null, word, (byte)frequency);
+ ++profTotalCount[0];
+ addToBigramListLocked(null, word, (byte)frequency);
}
@Override
public void setBigram(final String word1, final String word2, final int frequency) {
if (word1.length() < Constants.DICTIONARY_MAX_WORD_LENGTH
&& word2.length() < Constants.DICTIONARY_MAX_WORD_LENGTH) {
- profTotal++;
if (DBG_SAVE_RESTORE) {
Log.d(TAG, "load bigram: " + word1 + "," + word2 + "," + frequency);
}
+ ++profTotalCount[0];
dictionary.setBigramAndGetFrequency(
word1, word2, initializing ? new ForgettingCurveParams(true)
: new ForgettingCurveParams(frequency, now, last));
}
- mBigramList.addBigram(word1, word2, (byte)frequency);
+ addToBigramListLocked(word1, word2, (byte)frequency);
}
};
@@ -264,11 +256,21 @@ public class UserHistoryDictionary extends ExpandableDictionary {
if (PROFILE_SAVE_RESTORE) {
final long diff = System.currentTimeMillis() - now;
Log.d(TAG, "PROF: Load UserHistoryDictionary: "
- + mLocale + ", " + diff + "ms. load " + profTotal + "entries.");
+ + locale + ", " + diff + "ms. load " + profTotalCount[0] + "entries.");
}
}
}
+ protected abstract String getDictionaryFileName();
+
+ protected String getLocale() {
+ return mLocale;
+ }
+
+ private void addToBigramListLocked(String word0, String word1, byte fcValue) {
+ mBigramList.addBigram(word0, word1, fcValue);
+ }
+
/**
* Async task to write pending words to the binarydicts.
*/
@@ -277,16 +279,16 @@ public class UserHistoryDictionary extends ExpandableDictionary {
private final UserHistoryDictionaryBigramList mBigramList;
private final boolean mAddLevel0Bigrams;
private final String mLocale;
- private final UserHistoryDictionary mUserHistoryDictionary;
+ private final DynamicPredictionDictionaryBase mDynamicPredictionDictionary;
private final SharedPreferences mPrefs;
private final Context mContext;
public UpdateBinaryTask(final UserHistoryDictionaryBigramList pendingWrites,
- final String locale, final UserHistoryDictionary dict,
+ final String locale, final DynamicPredictionDictionaryBase dict,
final SharedPreferences prefs, final Context context) {
mBigramList = pendingWrites;
mLocale = locale;
- mUserHistoryDictionary = dict;
+ mDynamicPredictionDictionary = dict;
mPrefs = prefs;
mContext = context;
mAddLevel0Bigrams = mBigramList.size() <= MAX_HISTORY_BIGRAMS;
@@ -294,19 +296,19 @@ public class UserHistoryDictionary extends ExpandableDictionary {
@Override
protected Void doInBackground(final Void... v) {
- if (mUserHistoryDictionary.isTest) {
+ if (mDynamicPredictionDictionary.isTest) {
// If isTest == true, wait until the lock is released.
- mUserHistoryDictionary.mBigramListLock.lock();
+ mDynamicPredictionDictionary.mBigramListLock.lock();
try {
doWriteTaskLocked();
} finally {
- mUserHistoryDictionary.mBigramListLock.unlock();
+ mDynamicPredictionDictionary.mBigramListLock.unlock();
}
- } else if (mUserHistoryDictionary.mBigramListLock.tryLock()) {
+ } else if (mDynamicPredictionDictionary.mBigramListLock.tryLock()) {
try {
doWriteTaskLocked();
} finally {
- mUserHistoryDictionary.mBigramListLock.unlock();
+ mDynamicPredictionDictionary.mBigramListLock.unlock();
}
}
return null;
@@ -324,7 +326,8 @@ public class UserHistoryDictionary extends ExpandableDictionary {
}
final long now = PROFILE_SAVE_RESTORE ? System.currentTimeMillis() : 0;
- final String fileName = NAME + "." + mLocale + ".dict";
+ final String fileName =
+ mDynamicPredictionDictionary.getDictionaryFileName();
final File file = new File(mContext.getFilesDir(), fileName);
FileOutputStream out = null;
@@ -360,7 +363,8 @@ public class UserHistoryDictionary extends ExpandableDictionary {
freq = FREQUENCY_FOR_TYPED;
final byte prevFc = mBigramList.getBigrams(word1).get(word2);
} else { // bigram
- final NextWord nw = mUserHistoryDictionary.getBigramWord(word1, word2);
+ final NextWord nw =
+ mDynamicPredictionDictionary.getBigramWord(word1, word2);
if (nw != null) {
final ForgettingCurveParams fcp = nw.getFcParams();
final byte prevFc = mBigramList.getBigrams(word1).get(word2);
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDicitonary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
index d3e2dfec9..19554d639 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDicitonary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
@@ -24,7 +24,7 @@ import android.content.Context;
/**
* This class is a dictionary for the personalized language model that uses binary dictionary.
*/
-public class PersonalizationDicitonary extends ExpandableBinaryDictionary {
+public class PersonalizationDictionary extends ExpandableBinaryDictionary {
private static final String NAME = "personalization";
public static void registerUpdateListener(PersonalizationDictionaryUpdateListener listener) {
@@ -35,7 +35,7 @@ public class PersonalizationDicitonary extends ExpandableBinaryDictionary {
private final String mLocale;
// Singleton
- private PersonalizationDicitonary(final Context context, final String locale) {
+ private PersonalizationDictionary(final Context context, final String locale) {
super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_PERSONALIZATION);
mLocale = locale;
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java
index e09e834bf..f5dae99ef 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java
@@ -29,15 +29,16 @@ public class PersonalizationDictionaryHelper {
private static final String TAG = PersonalizationDictionaryHelper.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final ConcurrentHashMap<String, SoftReference<UserHistoryDictionary>>
+ private static final ConcurrentHashMap<String, SoftReference<UserHistoryPredictionDictionary>>
sLangDictCache = CollectionUtils.newConcurrentHashMap();
- public static UserHistoryDictionary getUserHistoryDictionary(
+ public static UserHistoryPredictionDictionary getUserHistoryPredictionDictionary(
final Context context, final String locale, final SharedPreferences sp) {
synchronized (sLangDictCache) {
if (sLangDictCache.containsKey(locale)) {
- final SoftReference<UserHistoryDictionary> ref = sLangDictCache.get(locale);
- final UserHistoryDictionary dict = ref == null ? null : ref.get();
+ final SoftReference<UserHistoryPredictionDictionary> ref =
+ sLangDictCache.get(locale);
+ final UserHistoryPredictionDictionary dict = ref == null ? null : ref.get();
if (dict != null) {
if (DEBUG) {
Log.w(TAG, "Use cached UserHistoryDictionary for " + locale);
@@ -45,8 +46,9 @@ public class PersonalizationDictionaryHelper {
return dict;
}
}
- final UserHistoryDictionary dict = new UserHistoryDictionary(context, locale, sp);
- sLangDictCache.put(locale, new SoftReference<UserHistoryDictionary>(dict));
+ final UserHistoryPredictionDictionary dict =
+ new UserHistoryPredictionDictionary(context, locale, sp);
+ sLangDictCache.put(locale, new SoftReference<UserHistoryPredictionDictionary>(dict));
return dict;
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateListener.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateListener.java
index 2ec0dc00c..c78e5a95b 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateListener.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateListener.java
@@ -16,6 +16,6 @@
package com.android.inputmethod.latin.personalization;
-public class PersonalizationDictionaryUpdateListener {
+public interface PersonalizationDictionaryUpdateListener {
// TODO: Implement
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
new file mode 100644
index 000000000..955bd2762
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.personalization;
+
+import com.android.inputmethod.latin.Dictionary;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public class PersonalizationPredictionDictionary extends DynamicPredictionDictionaryBase {
+ private static final String NAME = PersonalizationPredictionDictionary.class.getSimpleName();
+
+ /* package */ PersonalizationPredictionDictionary(final Context context, final String locale,
+ final SharedPreferences sp) {
+ super(context, locale, sp, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA);
+ }
+
+ @Override
+ protected String getDictionaryFileName() {
+ return NAME + "." + getLocale() + ".dict";
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java
index b93630a18..f21db25a6 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java
@@ -53,7 +53,7 @@ public final class UserHistoryDictionaryBigramList {
* Called when loaded from the SQL DB.
*/
public void addBigram(String word1, String word2, byte fcValue) {
- if (UserHistoryDictionary.DBG_SAVE_RESTORE) {
+ if (UserHistoryPredictionDictionary.DBG_SAVE_RESTORE) {
Log.d(TAG, "--- add bigram: " + word1 + ", " + word2 + ", " + fcValue);
}
final HashMap<String, Byte> map;
@@ -73,7 +73,7 @@ public final class UserHistoryDictionaryBigramList {
* Called when inserted to the SQL DB.
*/
public void updateBigram(String word1, String word2, byte fcValue) {
- if (UserHistoryDictionary.DBG_SAVE_RESTORE) {
+ if (UserHistoryPredictionDictionary.DBG_SAVE_RESTORE) {
Log.d(TAG, "--- update bigram: " + word1 + ", " + word2 + ", " + fcValue);
}
final HashMap<String, Byte> map;
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDicitonary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java
index 3e7772584..d11784454 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDicitonary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java
@@ -17,30 +17,23 @@
package com.android.inputmethod.latin.personalization;
import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.ExpandableDictionary;
import android.content.Context;
import android.content.SharedPreferences;
/**
- * This class is a dictionary for the personalized prediction language model implemented in Java.
+ * Locally gathers stats about the words user types and various other signals like auto-correction
+ * cancellation or manual picks. This allows the keyboard to adapt to the typist over time.
*/
-public class PersonalizationPredictionDicitonary extends ExpandableDictionary {
- public static void registerUpdateListener(PersonalizationDictionaryUpdateListener listener) {
- // TODO: Implement
- }
-
- /** Locale for which this user history dictionary is storing words */
- private final String mLocale;
- private final SharedPreferences mPrefs;
-
- // Singleton
- private PersonalizationPredictionDicitonary(final Context context, final String locale,
+public class UserHistoryPredictionDictionary extends DynamicPredictionDictionaryBase {
+ private static final String NAME = UserHistoryPredictionDictionary.class.getSimpleName();
+ /* package */ UserHistoryPredictionDictionary(final Context context, final String locale,
final SharedPreferences sp) {
- super(context, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA);
- mLocale = locale;
- mPrefs = sp;
+ super(context, locale, sp, Dictionary.TYPE_USER_HISTORY);
}
- // TODO: Implement
+ @Override
+ protected String getDictionaryFileName() {
+ return NAME + "." + getLocale() + ".dict";
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index 34ea2279d..e675f428e 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -32,7 +32,6 @@ import com.android.inputmethod.latin.utils.ApplicationUtils;
public final class DebugSettings extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener {
- private static final String TAG = DebugSettings.class.getSimpleName();
public static final String PREF_DEBUG_MODE = "debug_mode";
public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index b690fed78..2631cd317 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -93,7 +93,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
private Resources mRes;
private SharedPreferences mPrefs;
- private Locale mCurrentLocale;
private SettingsValues mSettingsValues;
private static final Settings sInstance = new Settings();
@@ -128,16 +127,15 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
Log.w(TAG, "onSharedPreferenceChanged called before loadSettings.");
return;
}
- loadSettings(mCurrentLocale, mSettingsValues.mInputAttributes);
+ loadSettings(mSettingsValues.mLocale, mSettingsValues.mInputAttributes);
}
public void loadSettings(final Locale locale, final InputAttributes inputAttributes) {
- mCurrentLocale = locale;
final SharedPreferences prefs = mPrefs;
final RunInLocale<SettingsValues> job = new RunInLocale<SettingsValues>() {
@Override
protected SettingsValues job(final Resources res) {
- return new SettingsValues(prefs, res, inputAttributes);
+ return new SettingsValues(prefs, locale, res, inputAttributes);
}
};
mSettingsValues = job.runInLocale(mRes, locale);
@@ -160,10 +158,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return mSettingsValues.isWordSeparator(code);
}
- public Locale getCurrentLocale() {
- return mCurrentLocale;
- }
-
public boolean getBlockPotentiallyOffensive() {
return mSettingsValues.mBlockPotentiallyOffensive;
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 3fa00bb2e..8aafb0738 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -32,11 +32,11 @@ import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.InputTypeUtils;
-import com.android.inputmethod.latin.utils.RunInLocale;
import com.android.inputmethod.latin.utils.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Locale;
/**
* When you call the constructor of this class, you may want to change the current system locale by
@@ -75,6 +75,7 @@ public final class SettingsValues {
public final boolean mGestureFloatingPreviewTextEnabled;
public final boolean mSlidingKeyInputPreviewEnabled;
public final int mKeyLongpressTimeout;
+ public final Locale mLocale;
// From the input box
public final InputAttributes mInputAttributes;
@@ -97,8 +98,9 @@ public final class SettingsValues {
// Debug settings
public final boolean mIsInternal;
- public SettingsValues(final SharedPreferences prefs, final Resources res,
+ public SettingsValues(final SharedPreferences prefs, final Locale locale, final Resources res,
final InputAttributes inputAttributes) {
+ mLocale = locale;
// Get the resources
mDelayUpdateOldSuggestions = res.getInteger(R.integer.config_delay_update_old_suggestions);
mSymbolsPrecededBySpace =
diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java
index ba5a68460..21426d1eb 100644
--- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java
+++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java
@@ -274,4 +274,8 @@ public class UserDictionaryAddWordContents {
localesList.add(new LocaleRenderer(activity, null)); // meaning: select another locale
return localesList;
}
+
+ public String getCurrentUserDictionaryLocale() {
+ return mLocale;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java
index 8b8bd5e03..4fc132f68 100644
--- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java
+++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java
@@ -60,6 +60,7 @@ public class UserDictionaryAddWordFragment extends Fragment
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
+ getActivity().getActionBar().setTitle(R.string.edit_personal_dictionary);
// Keep the instance so that we remember mContents when configuration changes (eg rotation)
setRetainInstance(true);
}
@@ -82,6 +83,8 @@ public class UserDictionaryAddWordFragment extends Fragment
mContents = new UserDictionaryAddWordContents(mRootView,
mContents /* oldInstanceToBeEdited */);
}
+ getActivity().getActionBar().setSubtitle(UserDictionarySettingsUtils.getLocaleDisplayName(
+ getActivity(), mContents.getCurrentUserDictionaryLocale()));
return mRootView;
}
@@ -100,7 +103,7 @@ public class UserDictionaryAddWordFragment extends Fragment
/**
* Callback for the framework when a menu option is pressed.
*
- * @param MenuItem the item that was pressed
+ * @param item the item that was pressed
* @return false to allow normal menu processing to proceed, true to consume it here
*/
@Override
diff --git a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
index 159ebb1b9..36b927eea 100644
--- a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
@@ -22,7 +22,7 @@ import java.util.ArrayList;
/**
* Utility methods for parsing and serializing Comma-Separated Values. The public APIs of this
- * utility class are {@link #split(String)}, {@link #split(int,String)}, {@link #join(String)},
+ * utility class are {@link #split(String)}, {@link #split(int,String)}, {@link #join(String...)},
* {@link #join(int,String...)}, and {@link #join(int,int[],String...)}.
*
* This class implements CSV parsing and serializing methods conforming to RFC 4180 with an
diff --git a/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java b/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java
index ef9cacf61..06826dac0 100644
--- a/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java
@@ -25,6 +25,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
import android.util.Log;
+import android.view.MotionEvent;
import com.android.inputmethod.latin.LatinImeLogger;
@@ -109,6 +110,43 @@ public final class UsabilityStudyLogUtils {
LatinImeLogger.onPrintAllUsabilityStudyLogs();
}
+ public static void writeMotionEvent(final MotionEvent me) {
+ final int action = me.getActionMasked();
+ final long eventTime = me.getEventTime();
+ final int pointerCount = me.getPointerCount();
+ for (int index = 0; index < pointerCount; index++) {
+ final int id = me.getPointerId(index);
+ final int x = (int)me.getX(index);
+ final int y = (int)me.getY(index);
+ final float size = me.getSize(index);
+ final float pressure = me.getPressure(index);
+
+ final String eventTag;
+ switch (action) {
+ case MotionEvent.ACTION_UP:
+ eventTag = "[Up]";
+ break;
+ case MotionEvent.ACTION_DOWN:
+ eventTag = "[Down]";
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ eventTag = "[PointerUp]";
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ eventTag = "[PointerDown]";
+ break;
+ case MotionEvent.ACTION_MOVE:
+ eventTag = "[Move]";
+ break;
+ default:
+ eventTag = "[Action" + action + "]";
+ break;
+ }
+ getInstance().write(eventTag + eventTime + "," + id + "," + x + "," + y + "," + size
+ + "," + pressure);
+ }
+ }
+
public void write(final String log) {
mLoggingHandler.post(new Runnable() {
@Override
@@ -191,7 +229,7 @@ public final class UsabilityStudyLogUtils {
Log.w(USABILITY_TAG, e2);
return;
}
- if (destFile == null || !destFile.exists()) {
+ if (!destFile.exists()) {
Log.w(USABILITY_TAG, "Dest file doesn't exist.");
return;
}
diff --git a/java/src/com/android/inputmethod/research/MainLogBuffer.java b/java/src/com/android/inputmethod/research/MainLogBuffer.java
index 3482153b4..6df7c1708 100644
--- a/java/src/com/android/inputmethod/research/MainLogBuffer.java
+++ b/java/src/com/android/inputmethod/research/MainLogBuffer.java
@@ -119,9 +119,9 @@ public abstract class MainLogBuffer extends FixedLogBuffer {
*
* @param logUnits a LogUnit list to check for publishability
* @param nGramSize the smallest n-gram acceptable to be published. if
- * {@link ResearchLogger.IS_LOGGING_EVERYTHING} is true, then publish if there are more than
+ * {@link ResearchLogger#IS_LOGGING_EVERYTHING} is true, then publish if there are more than
* {@code minNGramSize} words in the logUnits, otherwise wait. if {@link
- * ResearchLogger.IS_LOGGING_EVERYTHING} is false, then ensure that there are exactly nGramSize
+ * ResearchLogger#IS_LOGGING_EVERYTHING} is false, then ensure that there are exactly nGramSize
* words in the LogUnits.
*
* @return one of the {@code PUBLISHABILITY_*} result codes defined in this class.
diff --git a/java/src/com/android/inputmethod/research/MotionEventReader.java b/java/src/com/android/inputmethod/research/MotionEventReader.java
index fbfd9b531..3388645b7 100644
--- a/java/src/com/android/inputmethod/research/MotionEventReader.java
+++ b/java/src/com/android/inputmethod/research/MotionEventReader.java
@@ -315,16 +315,6 @@ public class MotionEventReader {
return pointerCoords;
}
- /**
- * Tests that {@code x} is uninitialized.
- *
- * Assumes that {@code x} will never be given a valid value less than 0, and that
- * UNINITIALIZED_FLOAT is less than 0.0f.
- */
- private boolean isUninitializedFloat(final float x) {
- return x < 0.0f;
- }
-
private void addMotionEventData(final ReplayData replayData, final int actionType,
final long time, final PointerProperties[] pointerProperties,
final PointerCoords[] pointerCoords) {
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index ed047e13a..fc8615b71 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -180,7 +180,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
private ResearchLogDirectory mResearchLogDirectory;
private SplashScreen mSplashScreen;
- private Intent mUploadIntent;
private Intent mUploadNowIntent;
/* package for test */ LogUnit mCurrentLogUnit = new LogUnit();
@@ -233,7 +232,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
resetLogBuffers();
// Initialize external services
- mUploadIntent = new Intent(mLatinIME, UploaderService.class);
mUploadNowIntent = new Intent(mLatinIME, UploaderService.class);
mUploadNowIntent.putExtra(UploaderService.EXTRA_UPLOAD_UNCONDITIONALLY, true);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -319,12 +317,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
restart();
}
- private void setLoggingAllowed(final boolean enableLogging) {
- if (mPrefs == null) return;
- sIsLogging = enableLogging;
- ResearchSettings.writeResearchLoggerEnabledFlag(mPrefs, enableLogging);
- }
-
private void checkForEmptyEditor() {
if (mLatinIME == null) {
return;
@@ -1261,10 +1253,23 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
private static final LogStatement LOGSTATEMENT_LATINIME_PICKSUGGESTIONMANUALLY =
new LogStatement("LatinIMEPickSuggestionManually", true, false, "replacedWord", "index",
"suggestion", "x", "y", "isBatchMode", "score", "kind", "sourceDict");
+ /**
+ * Log a call to LatinIME.pickSuggestionManually().
+ *
+ * @param replacedWord the typed word that this manual suggestion replaces. May not be null.
+ * @param index the index in the suggestion strip
+ * @param suggestion the committed suggestion. May not be null.
+ * @param isBatchMode whether this was input in batch mode, aka gesture.
+ * @param score the internal score of the suggestion, as output by the dictionary
+ * @param kind the kind of suggestion, as one of the SuggestedWordInfo#KIND_* constants
+ * @param sourceDict the source origin of this word, as one of the Dictionary#TYPE_* constants.
+ */
public static void latinIME_pickSuggestionManually(final String replacedWord,
final int index, final String suggestion, final boolean isBatchMode,
final int score, final int kind, final String sourceDict) {
final ResearchLogger researchLogger = getInstance();
+ // Note : suggestion can't be null here, because it's only called in a place where it
+ // can't be null.
if (!replacedWord.equals(suggestion.toString())) {
// The user chose something other than what was already there.
researchLogger.setCurrentLogUnitContainsUserDeletions();
@@ -1273,7 +1278,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final String scrubbedWord = scrubDigitsFromString(suggestion);
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_PICKSUGGESTIONMANUALLY,
scrubDigitsFromString(replacedWord), index,
- suggestion == null ? null : scrubbedWord, Constants.SUGGESTION_STRIP_COORDINATE,
+ scrubbedWord, Constants.SUGGESTION_STRIP_COORDINATE,
Constants.SUGGESTION_STRIP_COORDINATE, isBatchMode, score, kind, sourceDict);
researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, Long.MAX_VALUE, isBatchMode);
researchLogger.mStatistics.recordManualSuggestion(SystemClock.uptimeMillis());