aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java146
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/BatchInputArbiter.java181
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/GestureStrokeRecognitionPoints.java46
-rw-r--r--java/src/com/android/inputmethod/latin/Constants.java7
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java48
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java6
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java15
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java49
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java6
9 files changed, 356 insertions, 148 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index d4e3e2928..5e02926de 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -22,12 +22,13 @@ import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
+import com.android.inputmethod.keyboard.internal.BatchInputArbiter;
+import com.android.inputmethod.keyboard.internal.BatchInputArbiter.BatchInputArbiterListener;
import com.android.inputmethod.keyboard.internal.BogusMoveEventDetector;
import com.android.inputmethod.keyboard.internal.GestureEnabler;
import com.android.inputmethod.keyboard.internal.GestureStrokeDrawingParams;
import com.android.inputmethod.keyboard.internal.GestureStrokeDrawingPoints;
import com.android.inputmethod.keyboard.internal.GestureStrokeRecognitionParams;
-import com.android.inputmethod.keyboard.internal.GestureStrokeRecognitionPoints;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.keyboard.internal.TypingTimeRecorder;
import com.android.inputmethod.latin.Constants;
@@ -43,7 +44,8 @@ import com.android.inputmethod.research.ResearchLogger;
import java.util.ArrayList;
-public final class PointerTracker implements PointerTrackerQueue.Element {
+public final class PointerTracker implements PointerTrackerQueue.Element,
+ BatchInputArbiterListener {
private static final String TAG = PointerTracker.class.getSimpleName();
private static final boolean DEBUG_EVENT = false;
private static final boolean DEBUG_MOVE_EVENT = false;
@@ -160,12 +162,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private boolean mIsDetectingGesture = false; // per PointerTracker.
private static boolean sInGesture = false;
- private static long sGestureFirstDownTime;
private static TypingTimeRecorder sTypingTimeRecorder;
- private static final InputPointers sAggregatedPointers = new InputPointers(
- GestureStrokeRecognitionPoints.DEFAULT_CAPACITY);
- private static int sLastRecognitionPointSize = 0; // synchronized using sAggregatedPointers
- private static long sLastRecognitionTime = 0; // synchronized using sAggregatedPointers
// The position and time at which first down event occurred.
private long mDownTime;
@@ -203,7 +200,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// true if dragging finger is allowed.
private boolean mIsAllowedDraggingFinger;
- private final GestureStrokeRecognitionPoints mGestureStrokeRecognitionPoints;
+ private final BatchInputArbiter mBatchInputArbiter;
private final GestureStrokeDrawingPoints mGestureStrokeDrawingPoints;
// TODO: Add PointerTrackerFactory singleton and move some class static methods into it.
@@ -287,8 +284,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private PointerTracker(final int id) {
mPointerId = id;
- mGestureStrokeRecognitionPoints = new GestureStrokeRecognitionPoints(
- id, sGestureStrokeRecognitionParams);
+ mBatchInputArbiter = new BatchInputArbiter(id, sGestureStrokeRecognitionParams);
mGestureStrokeDrawingPoints = new GestureStrokeDrawingPoints(sGestureStrokeDrawingParams);
}
@@ -410,7 +406,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
mKeyboardLayoutHasBeenChanged = true;
final int keyWidth = mKeyboard.mMostCommonKeyWidth;
final int keyHeight = mKeyboard.mMostCommonKeyHeight;
- mGestureStrokeRecognitionPoints.setKeyboardGeometry(keyWidth, mKeyboard.mOccupiedHeight);
+ mBatchInputArbiter.setKeyboardGeometry(keyWidth, mKeyboard.mOccupiedHeight);
final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY);
if (newKey != mCurrentKey) {
if (sDrawingProxy != null) {
@@ -578,26 +574,15 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
return sPointerTrackerQueue.getOldestElement() == this;
}
- /**
- * Determines whether the batch input has started or not.
- * @return true if the batch input has started successfully.
- */
- private boolean mayStartBatchInput() {
- if (!mGestureStrokeRecognitionPoints.isStartOfAGesture()) {
- return false;
- }
+ // Implements {@link BatchInputArbiterListener}.
+ @Override
+ public void onStartBatchInput() {
if (DEBUG_LISTENER) {
Log.d(TAG, String.format("[%d] onStartBatchInput", mPointerId));
}
- synchronized (sAggregatedPointers) {
- sAggregatedPointers.reset();
- sLastRecognitionPointSize = 0;
- sLastRecognitionTime = 0;
- sListener.onStartBatchInput();
- dismissAllMoreKeysPanels();
- sTimerProxy.cancelLongPressTimerOf(this);
- }
- return true;
+ sListener.onStartBatchInput();
+ dismissAllMoreKeysPanels();
+ sTimerProxy.cancelLongPressTimerOf(this);
}
private void showGestureTrail() {
@@ -610,55 +595,38 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
public void updateBatchInputByTimer(final long syntheticMoveEventTime) {
- final int gestureTime = (int)(syntheticMoveEventTime - sGestureFirstDownTime);
- mGestureStrokeRecognitionPoints.duplicateLastPointWith(gestureTime);
- updateBatchInput(syntheticMoveEventTime);
- }
-
- private void updateBatchInput(final long moveEventTime) {
- synchronized (sAggregatedPointers) {
- final GestureStrokeRecognitionPoints stroke = mGestureStrokeRecognitionPoints;
- stroke.appendIncrementalBatchPoints(sAggregatedPointers);
- final int size = sAggregatedPointers.getPointerSize();
- if (size > sLastRecognitionPointSize
- && stroke.hasRecognitionTimePast(moveEventTime, sLastRecognitionTime)) {
- if (DEBUG_LISTENER) {
- Log.d(TAG, String.format("[%d] onUpdateBatchInput: batchPoints=%d", mPointerId,
- size));
- }
- sTimerProxy.startUpdateBatchInputTimer(this);
- sListener.onUpdateBatchInput(sAggregatedPointers);
- // The listener may change the size of the pointers (when auto-committing
- // for example), so we need to get the size from the pointers again.
- sLastRecognitionPointSize = sAggregatedPointers.getPointerSize();
- sLastRecognitionTime = moveEventTime;
- }
+ mBatchInputArbiter.updateBatchInputByTimer(syntheticMoveEventTime, this);
+ }
+
+ // Implements {@link BatchInputArbiterListener}.
+ @Override
+ public void onUpdateBatchInput(final InputPointers aggregatedPointers, final long eventTime) {
+ if (DEBUG_LISTENER) {
+ Log.d(TAG, String.format("[%d] onUpdateBatchInput: batchPoints=%d", mPointerId,
+ aggregatedPointers.getPointerSize()));
}
+ sListener.onUpdateBatchInput(aggregatedPointers);
}
- /**
- * Determines whether the batch input has ended successfully or continues.
- * @param upEventTime the event time of this pointer up.
- * @return true if the batch input has ended successfully, false if it continues.
- */
- private boolean mayEndBatchInput(final long upEventTime) {
- boolean hasEndBatchInputSuccessfully = false;
- synchronized (sAggregatedPointers) {
- mGestureStrokeRecognitionPoints.appendAllBatchPoints(sAggregatedPointers);
- if (getActivePointerTrackerCount() == 1) {
- hasEndBatchInputSuccessfully = true;
- sTypingTimeRecorder.onEndBatchInput(upEventTime);
- sTimerProxy.cancelAllUpdateBatchInputTimers();
- if (!mIsTrackingForActionDisabled) {
- if (DEBUG_LISTENER) {
- Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d",
- mPointerId, sAggregatedPointers.getPointerSize()));
- }
- sListener.onEndBatchInput(sAggregatedPointers);
- }
- }
+ // Implements {@link BatchInputArbiterListener}.
+ @Override
+ public void onStartUpdateBatchInputTimer() {
+ sTimerProxy.startUpdateBatchInputTimer(this);
+ }
+
+ // Implements {@link BatchInputArbiterListener}.
+ @Override
+ public void onEndBatchInput(final InputPointers aggregatedPointers, final long eventTime) {
+ sTypingTimeRecorder.onEndBatchInput(eventTime);
+ sTimerProxy.cancelAllUpdateBatchInputTimers();
+ if (mIsTrackingForActionDisabled) {
+ return;
+ }
+ if (DEBUG_LISTENER) {
+ Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d",
+ mPointerId, aggregatedPointers.getPointerSize()));
}
- return hasEndBatchInputSuccessfully;
+ sListener.onEndBatchInput(aggregatedPointers);
}
private void cancelBatchInput() {
@@ -753,15 +721,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
mIsDetectingGesture = (mKeyboard != null) && mKeyboard.mId.isAlphabetKeyboard()
&& key != null && !key.isModifier();
if (mIsDetectingGesture) {
- if (getActivePointerTrackerCount() == 1) {
- sGestureFirstDownTime = eventTime;
- }
- final int elapsedTimeSinceFirstDown = (int)(eventTime - sGestureFirstDownTime);
- final int elapsedTimeSinceLastTyping = (int)(
- eventTime - sTypingTimeRecorder.getLastLetterTypingTime());
- mGestureStrokeRecognitionPoints.onDownEvent(x, y, elapsedTimeSinceFirstDown,
- elapsedTimeSinceLastTyping);
- mGestureStrokeDrawingPoints.onDownEvent(x, y, elapsedTimeSinceFirstDown);
+ mBatchInputArbiter.addDownEventPoint(x, y, eventTime,
+ sTypingTimeRecorder.getLastLetterTypingTime(), getActivePointerTrackerCount());
+ mGestureStrokeDrawingPoints.onDownEvent(
+ x, y, mBatchInputArbiter.getElapsedTimeSinceFirstDown(eventTime));
}
}
@@ -820,31 +783,27 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (!mIsDetectingGesture) {
return;
}
- final int beforeLength = mGestureStrokeRecognitionPoints.getLength();
- final int elapsedTimeSinceFirstDown = (int)(eventTime - sGestureFirstDownTime);
- final boolean onValidArea = mGestureStrokeRecognitionPoints.addPointOnKeyboard(
- x, y, elapsedTimeSinceFirstDown, isMajorEvent);
- if (mGestureStrokeRecognitionPoints.getLength() > beforeLength) {
- sTimerProxy.startUpdateBatchInputTimer(this);
- }
+ final boolean onValidArea = mBatchInputArbiter.addMoveEventPoint(
+ x, y, eventTime, isMajorEvent, this);
// If the move event goes out from valid batch input area, cancel batch input.
if (!onValidArea) {
cancelBatchInput();
return;
}
- mGestureStrokeDrawingPoints.onMoveEvent(x, y, elapsedTimeSinceFirstDown);
+ mGestureStrokeDrawingPoints.onMoveEvent(
+ x, y, mBatchInputArbiter.getElapsedTimeSinceFirstDown(eventTime));
// If the MoreKeysPanel is showing then do not attempt to enter gesture mode. However,
// the gestured touch points are still being recorded in case the panel is dismissed.
if (isShowingMoreKeysPanel()) {
return;
}
if (!sInGesture && key != null && Character.isLetter(key.getCode())
- && mayStartBatchInput()) {
+ && mBatchInputArbiter.mayStartBatchInput(this)) {
sInGesture = true;
}
if (sInGesture) {
if (key != null) {
- updateBatchInput(eventTime);
+ mBatchInputArbiter.updateBatchInput(eventTime, this);
}
showGestureTrail();
}
@@ -1097,7 +1056,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (currentKey != null) {
callListenerOnRelease(currentKey, currentKey.getCode(), true /* withSliding */);
}
- if (mayEndBatchInput(eventTime)) {
+ if (mBatchInputArbiter.mayEndBatchInput(
+ eventTime, getActivePointerTrackerCount(), this)) {
sInGesture = false;
}
showGestureTrail();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/BatchInputArbiter.java b/java/src/com/android/inputmethod/keyboard/internal/BatchInputArbiter.java
new file mode 100644
index 000000000..cd9875955
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/BatchInputArbiter.java
@@ -0,0 +1,181 @@
+/*
+ * 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.keyboard.internal;
+
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.InputPointers;
+
+/**
+ * This class arbitrates batch input.
+ * An instance of this class holds a {@link GestureStrokeRecognitionPoints}.
+ * And it arbitrates multiple strokes gestured by multiple fingers and aggregates those gesture
+ * points into one batch input.
+ */
+public class BatchInputArbiter {
+ public interface BatchInputArbiterListener {
+ public void onStartBatchInput();
+ public void onUpdateBatchInput(
+ final InputPointers aggregatedPointers, final long moveEventTime);
+ public void onStartUpdateBatchInputTimer();
+ public void onEndBatchInput(final InputPointers aggregatedPointers, final long upEventTime);
+ }
+
+ // The starting time of the first stroke of a gesture input.
+ private static long sGestureFirstDownTime;
+ // The {@link InputPointers} that includes all events of a gesture input.
+ private static final InputPointers sAggregatedPointers = new InputPointers(
+ Constants.DEFAULT_GESTURE_POINTS_CAPACITY);
+ private static int sLastRecognitionPointSize = 0; // synchronized using sAggregatedPointers
+ private static long sLastRecognitionTime = 0; // synchronized using sAggregatedPointers
+
+ private final GestureStrokeRecognitionPoints mRecognitionPoints;
+
+ public BatchInputArbiter(final int pointerId, final GestureStrokeRecognitionParams params) {
+ mRecognitionPoints = new GestureStrokeRecognitionPoints(pointerId, params);
+ }
+
+ public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) {
+ mRecognitionPoints.setKeyboardGeometry(keyWidth, keyboardHeight);
+ }
+
+ /**
+ * Calculate elapsed time since the first gesture down.
+ * @param eventTime the time of this event.
+ * @return the elapsed time in millisecond from the first gesture down.
+ */
+ public int getElapsedTimeSinceFirstDown(final long eventTime) {
+ return (int)(eventTime - sGestureFirstDownTime);
+ }
+
+ /**
+ * Add a down event point.
+ * @param x the x-coordinate of this down event.
+ * @param y the y-coordinate of this down event.
+ * @param downEventTime the time of this down event.
+ * @param lastLetterTypingTime the last typing input time.
+ * @param activePointerCount the number of active pointers when this pointer down event occurs.
+ */
+ public void addDownEventPoint(final int x, final int y, final long downEventTime,
+ final long lastLetterTypingTime, final int activePointerCount) {
+ if (activePointerCount == 1) {
+ sGestureFirstDownTime = downEventTime;
+ }
+ final int elapsedTimeSinceFirstDown = getElapsedTimeSinceFirstDown(downEventTime);
+ final int elapsedTimeSinceLastTyping = (int)(downEventTime - lastLetterTypingTime);
+ mRecognitionPoints.addDownEventPoint(
+ x, y, elapsedTimeSinceFirstDown, elapsedTimeSinceLastTyping);
+ }
+
+ /**
+ * Add a move event point.
+ * @param x the x-coordinate of this move event.
+ * @param y the y-coordinate of this move event.
+ * @param moveEventTime the time of this move event.
+ * @param isMajorEvent false if this is a historical move event.
+ * @param listener {@link BatchInputArbiterListener#onStartUpdateBatchInputTimer()} of this
+ * <code>listener</code> may be called if enough move points have been added.
+ * @return true if this move event occurs on the valid gesture area.
+ */
+ public boolean addMoveEventPoint(final int x, final int y, final long moveEventTime,
+ final boolean isMajorEvent, final BatchInputArbiterListener listener) {
+ final int beforeLength = mRecognitionPoints.getLength();
+ final boolean onValidArea = mRecognitionPoints.addEventPoint(
+ x, y, getElapsedTimeSinceFirstDown(moveEventTime), isMajorEvent);
+ if (mRecognitionPoints.getLength() > beforeLength) {
+ listener.onStartUpdateBatchInputTimer();
+ }
+ return onValidArea;
+ }
+
+ /**
+ * Determine whether the batch input has started or not.
+ * @param listener {@link BatchInputArbiterListener#onStartBatchInput()} of this
+ * <code>listener</code> will be called when the batch input has started successfully.
+ * @return true if the batch input has started successfully.
+ */
+ public boolean mayStartBatchInput(final BatchInputArbiterListener listener) {
+ if (!mRecognitionPoints.isStartOfAGesture()) {
+ return false;
+ }
+ synchronized (sAggregatedPointers) {
+ sAggregatedPointers.reset();
+ sLastRecognitionPointSize = 0;
+ sLastRecognitionTime = 0;
+ listener.onStartBatchInput();
+ }
+ return true;
+ }
+
+ /**
+ * Add synthetic move event point. After adding the point,
+ * {@link #updateBatchInput(long,BatchInputArbiterListener)} will be called internally.
+ * @param syntheticMoveEventTime the synthetic move event time.
+ * @param listener the listener to be passed to
+ * {@link #updateBatchInput(long,BatchInputArbiterListener)}.
+ */
+ public void updateBatchInputByTimer(final long syntheticMoveEventTime,
+ final BatchInputArbiterListener listener) {
+ mRecognitionPoints.duplicateLastPointWith(
+ getElapsedTimeSinceFirstDown(syntheticMoveEventTime));
+ updateBatchInput(syntheticMoveEventTime, listener);
+ }
+
+ /**
+ * Determine whether we have enough gesture points to lookup dictionary.
+ * @param moveEventTime the time of this move event.
+ * @param listener {@link BatchInputArbiterListener#onUpdateBatchInput(InputPointers,long)} of
+ * this <code>listener</code> will be called when enough event points we have. Also
+ * {@link BatchInputArbiterListener#onStartUpdateBatchInputTimer()} will be called to have
+ * possible future synthetic move event.
+ */
+ public void updateBatchInput(final long moveEventTime,
+ final BatchInputArbiterListener listener) {
+ synchronized (sAggregatedPointers) {
+ mRecognitionPoints.appendIncrementalBatchPoints(sAggregatedPointers);
+ final int size = sAggregatedPointers.getPointerSize();
+ if (size > sLastRecognitionPointSize && mRecognitionPoints.hasRecognitionTimePast(
+ moveEventTime, sLastRecognitionTime)) {
+ listener.onUpdateBatchInput(sAggregatedPointers, moveEventTime);
+ listener.onStartUpdateBatchInputTimer();
+ // The listener may change the size of the pointers (when auto-committing
+ // for example), so we need to get the size from the pointers again.
+ sLastRecognitionPointSize = sAggregatedPointers.getPointerSize();
+ sLastRecognitionTime = moveEventTime;
+ }
+ }
+ }
+
+ /**
+ * Determine whether the batch input has ended successfully or continues.
+ * @param upEventTime the time of this up event.
+ * @param activePointerCount the number of active pointers when this pointer up event occurs.
+ * @param listener {@link BatchInputArbiterListener#onEndBatchInput(InputPointers,long)} of this
+ * <code>listener</code> will be called when the batch input has started successfully.
+ * @return true if the batch input has ended successfully.
+ */
+ public boolean mayEndBatchInput(final long upEventTime, final int activePointerCount,
+ final BatchInputArbiterListener listener) {
+ synchronized (sAggregatedPointers) {
+ mRecognitionPoints.appendAllBatchPoints(sAggregatedPointers);
+ if (activePointerCount == 1) {
+ listener.onEndBatchInput(sAggregatedPointers, upEventTime);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeRecognitionPoints.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeRecognitionPoints.java
index 5d4f5e826..e49e538aa 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeRecognitionPoints.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeRecognitionPoints.java
@@ -18,14 +18,15 @@ package com.android.inputmethod.keyboard.internal;
import android.util.Log;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.utils.ResizableIntArray;
/**
* This class holds event points to recognize a gesture stroke.
- * TODO: Should be final and package private class.
+ * TODO: Should be package private class.
*/
-public class GestureStrokeRecognitionPoints {
+public final class GestureStrokeRecognitionPoints {
private static final String TAG = GestureStrokeRecognitionPoints.class.getSimpleName();
private static final boolean DEBUG = false;
private static final boolean DEBUG_SPEED = false;
@@ -34,12 +35,13 @@ public class GestureStrokeRecognitionPoints {
// Proportional to the keyboard height.
public static final float EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO = 0.25f;
- public static final int DEFAULT_CAPACITY = 128;
-
private final int mPointerId;
- private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY);
- private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
- private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
+ private final ResizableIntArray mEventTimes = new ResizableIntArray(
+ Constants.DEFAULT_GESTURE_POINTS_CAPACITY);
+ private final ResizableIntArray mXCoordinates = new ResizableIntArray(
+ Constants.DEFAULT_GESTURE_POINTS_CAPACITY);
+ private final ResizableIntArray mYCoordinates = new ResizableIntArray(
+ Constants.DEFAULT_GESTURE_POINTS_CAPACITY);
private final GestureStrokeRecognitionParams mRecognitionParams;
@@ -67,12 +69,14 @@ public class GestureStrokeRecognitionPoints {
private static final int MSEC_PER_SEC = 1000;
+ // TODO: Make this package private
public GestureStrokeRecognitionPoints(final int pointerId,
final GestureStrokeRecognitionParams recognitionParams) {
mPointerId = pointerId;
mRecognitionParams = recognitionParams;
}
+ // TODO: Make this package private
public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) {
mKeyWidth = keyWidth;
mMinYCoordinate = -(int)(keyboardHeight * EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
@@ -99,11 +103,13 @@ public class GestureStrokeRecognitionPoints {
}
}
+ // TODO: Make this package private
public int getLength() {
return mEventTimes.getLength();
}
- public void onDownEvent(final int x, final int y, final int elapsedTimeSinceFirstDown,
+ // TODO: Make this package private
+ public void addDownEventPoint(final int x, final int y, final int elapsedTimeSinceFirstDown,
final int elapsedTimeSinceLastTyping) {
reset();
if (elapsedTimeSinceLastTyping < mRecognitionParams.mStaticTimeThresholdAfterFastTyping) {
@@ -113,7 +119,9 @@ public class GestureStrokeRecognitionPoints {
Log.d(TAG, String.format("[%d] onDownEvent: dT=%3d%s", mPointerId,
elapsedTimeSinceLastTyping, mAfterFastTyping ? " afterFastTyping" : ""));
}
- addPointOnKeyboard(x, y, elapsedTimeSinceFirstDown, true /* isMajorEvent */);
+ // Call {@link #addEventPoint(int,int,int,boolean)} to record this down event point as a
+ // major event point.
+ addEventPoint(x, y, elapsedTimeSinceFirstDown, true /* isMajorEvent */);
}
private int getGestureDynamicDistanceThreshold(final int deltaTime) {
@@ -137,6 +145,7 @@ public class GestureStrokeRecognitionPoints {
return mRecognitionParams.mDynamicTimeThresholdFrom - decayedThreshold;
}
+ // TODO: Make this package private
public final boolean isStartOfAGesture() {
if (!hasDetectedFastMove()) {
return false;
@@ -167,6 +176,7 @@ public class GestureStrokeRecognitionPoints {
return isStartOfAGesture;
}
+ // TODO: Make this package private
public void duplicateLastPointWith(final int time) {
final int lastIndex = getLength() - 1;
if (lastIndex >= 0) {
@@ -250,19 +260,20 @@ public class GestureStrokeRecognitionPoints {
}
/**
- * Add a touch event as a gesture point. Returns true if the touch event is on the valid
- * gesture area.
- * @param x the x-coordinate of the touch event
- * @param y the y-coordinate of the touch event
+ * Add an event point to this gesture stroke recognition points. Returns true if the event
+ * point is on the valid gesture area.
+ * @param x the x-coordinate of the event point
+ * @param y the y-coordinate of the event point
* @param time the elapsed time in millisecond from the first gesture down
* @param isMajorEvent false if this is a historical move event
- * @return true if the touch event is on the valid gesture area
+ * @return true if the event point is on the valid gesture area
*/
- public boolean addPointOnKeyboard(final int x, final int y, final int time,
+ // TODO: Make this package private
+ public boolean addEventPoint(final int x, final int y, final int time,
final boolean isMajorEvent) {
final int size = getLength();
if (size <= 0) {
- // Down event
+ // The first event of this stroke (a.k.a. down event).
appendPoint(x, y, time);
updateMajorEvent(x, y, time);
} else {
@@ -291,15 +302,18 @@ public class GestureStrokeRecognitionPoints {
}
}
+ // TODO: Make this package private
public final boolean hasRecognitionTimePast(
final long currentTime, final long lastRecognitionTime) {
return currentTime > lastRecognitionTime + mRecognitionParams.mRecognitionMinimumTime;
}
+ // TODO: Make this package private
public final void appendAllBatchPoints(final InputPointers out) {
appendBatchPoints(out, getLength());
}
+ // TODO: Make this package private
public final void appendIncrementalBatchPoints(final InputPointers out) {
appendBatchPoints(out, mIncrementalRecognitionSize);
}
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index fbd6ef4e9..00b54f593 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -257,6 +257,13 @@ public final class Constants {
public static final int SCREEN_METRICS_LARGE_TABLET = 2;
public static final int SCREEN_METRICS_SMALL_TABLET = 3;
+ /**
+ * Default capacity of gesture points container.
+ * This constant is used by {@link BatchInputArbiter} and etc. to preallocate regions that
+ * contain gesture event points.
+ */
+ public static final int DEFAULT_GESTURE_POINTS_CAPACITY = 128;
+
private Constants() {
// This utility class is not publicly instantiable.
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 68ed23897..d8fb4f2be 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1147,7 +1147,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public boolean onEvaluateFullscreenMode() {
- // Reread resource value here, because this method is called by framework anytime as needed.
+ // Reread resource value here, because this method is called by the framework as needed.
final boolean isFullscreenModeAllowed = Settings.readUseFullscreenMode(getResources());
if (super.onEvaluateFullscreenMode() && isFullscreenModeAllowed) {
// TODO: Remove this hack. Actually we should not really assume NO_EXTRACT_UI
@@ -1272,7 +1272,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onCancelBatchInput() {
- mInputLogic.onCancelBatchInput(mInputUpdater);
+ mInputLogic.onCancelBatchInput(mHandler, mInputUpdater);
}
// TODO[IL]: Make this a package-private standalone class in inputlogic/ and remove all
@@ -1310,17 +1310,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return true;
}
- // Run in the UI thread.
+ // Run on the UI thread.
public void onStartBatchInput() {
synchronized (mLock) {
mHandler.removeMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
mInBatchInput = true;
- mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
- SuggestedWords.EMPTY, false /* dismissGestureFloatingPreviewText */);
}
}
- // Run in the Handler thread.
+ // Run on the Handler thread.
private void updateBatchInput(final InputPointers batchPointers, final int sequenceNumber) {
synchronized (mLock) {
if (!mInBatchInput) {
@@ -1339,7 +1337,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- // Run in the UI thread.
+ // Run on the UI thread.
public void onUpdateBatchInput(final InputPointers batchPointers,
final int sequenceNumber) {
if (mHandler.hasMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP)) {
@@ -1352,12 +1350,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void onCancelBatchInput() {
synchronized (mLock) {
mInBatchInput = false;
- mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
- SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */);
}
}
- // Run in the UI thread.
+ // Run on the UI thread.
public void onEndBatchInput(final InputPointers batchPointers) {
synchronized(mLock) {
getSuggestedWordsGestureLocked(batchPointers, SuggestedWords.NOT_A_SEQUENCE_NUMBER,
@@ -1407,7 +1403,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- // This method must run in UI Thread.
+ // This method must run on the UI Thread.
private void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords,
final boolean dismissGestureFloatingPreviewText) {
showSuggestionStrip(suggestedWords);
@@ -1418,7 +1414,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- // This method must run in UI Thread.
+ // This method must run on the UI Thread.
public void onEndBatchInputAsyncInternal(final SuggestedWords suggestedWords) {
final String batchInputText = suggestedWords.isEmpty() ? null : suggestedWords.getWord(0);
if (TextUtils.isEmpty(batchInputText)) {
@@ -1615,19 +1611,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
false /* isPrediction */);
}
- private void setAutoCorrection(final SuggestedWords suggestedWords, final String typedWord) {
- if (suggestedWords.isEmpty()) return;
- final String autoCorrection;
- if (suggestedWords.mWillAutoCorrect) {
- autoCorrection = suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION);
- } else {
- // We can't use suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD)
- // because it may differ from mWordComposer.mTypedWord.
- autoCorrection = typedWord;
- }
- mInputLogic.mWordComposer.setAutoCorrection(autoCorrection);
- }
-
private void showSuggestionStripWithTypedWord(final SuggestedWords suggestedWords,
final String typedWord) {
if (suggestedWords.isEmpty()) {
@@ -1636,10 +1619,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
clearSuggestionStrip();
return;
}
- setAutoCorrection(suggestedWords, typedWord);
- final boolean isAutoCorrection = suggestedWords.willAutoCorrect();
- setSuggestedWords(suggestedWords, isAutoCorrection);
- setAutoCorrectionIndicator(isAutoCorrection);
+ final String autoCorrection;
+ if (suggestedWords.mWillAutoCorrect) {
+ autoCorrection = suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION);
+ } else {
+ // We can't use suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD)
+ // because it may differ from mWordComposer.mTypedWord.
+ autoCorrection = typedWord;
+ }
+ mInputLogic.mWordComposer.setAutoCorrection(autoCorrection);
+ setSuggestedWords(suggestedWords, suggestedWords.mWillAutoCorrect);
+ setAutoCorrectionIndicator(suggestedWords.mWillAutoCorrect);
setSuggestionStripShown(isSuggestionsStripVisible());
// An auto-correction is available, cache it in accessibility code so
// we can be speak it if the user touches a key that will insert it.
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 97c89dd4e..f9de89c80 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -104,10 +104,6 @@ public final class SuggestedWords {
return debugString;
}
- public boolean willAutoCorrect() {
- return mWillAutoCorrect;
- }
-
@Override
public String toString() {
// Pretty-print method to help debug
@@ -150,7 +146,7 @@ public final class SuggestedWords {
for (int index = 1; index < previousSize; index++) {
final SuggestedWordInfo prevWordInfo = previousSuggestions.getInfo(index);
final String prevWord = prevWordInfo.mWord;
- // Filter out duplicate suggestion.
+ // Filter out duplicate suggestions.
if (!alreadySeen.contains(prevWord)) {
suggestionsList.add(prevWordInfo);
alreadySeen.add(prevWord);
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 0686ff641..4a4abd7d2 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -68,6 +68,8 @@ public final class InputLogic {
// TODO : Remove this member when we can.
private final LatinIME mLatinIME;
+ private InputLogicHandler mInputLogicHandler;
+
// TODO : make all these fields private as soon as possible.
// Current space state of the input method. This can be any of the above constants.
public int mSpaceState;
@@ -102,6 +104,7 @@ public final class InputLogic {
mWordComposer = new WordComposer();
mEventInterpreter = new EventInterpreter(latinIME);
mConnection = new RichInputConnection(latinIME);
+ mInputLogicHandler = null;
}
/**
@@ -116,12 +119,15 @@ public final class InputLogic {
* @param restarting whether input is starting in the same field as before.
*/
public void startInput(final boolean restarting) {
+ mInputLogicHandler = new InputLogicHandler();
}
/**
* Clean up the input logic after input is finished.
*/
public void finishInput() {
+ mInputLogicHandler.destroy();
+ mInputLogicHandler = null;
}
/**
@@ -297,6 +303,8 @@ public final class InputLogic {
final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler,
final LatinIME.InputUpdater inputUpdater) {
inputUpdater.onStartBatchInput();
+ handler.showGesturePreviewAndSuggestionStrip(
+ SuggestedWords.EMPTY, false /* dismissGestureFloatingPreviewText */);
handler.cancelUpdateSuggestionStrip();
mConnection.beginBatchEdit();
if (mWordComposer.isComposingWord()) {
@@ -397,9 +405,12 @@ public final class InputLogic {
inputUpdater.onEndBatchInput(batchPointers);
}
- // TODO: remove this argument
- public void onCancelBatchInput(final LatinIME.InputUpdater inputUpdater) {
+ // TODO: remove these arguments
+ public void onCancelBatchInput(final LatinIME.UIHandler handler,
+ final LatinIME.InputUpdater inputUpdater) {
inputUpdater.onCancelBatchInput();
+ handler.showGesturePreviewAndSuggestionStrip(
+ SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */);
}
/**
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
new file mode 100644
index 000000000..d611e4bf8
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
@@ -0,0 +1,49 @@
+/*
+ * 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.inputlogic;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+
+/**
+ * A helper to manage deferred tasks for the input logic.
+ */
+// TODO: Make this package private
+public class InputLogicHandler implements Handler.Callback {
+ final Handler mNonUIThreadHandler;
+
+ public InputLogicHandler() {
+ final HandlerThread handlerThread = new HandlerThread(
+ InputLogicHandler.class.getSimpleName());
+ handlerThread.start();
+ mNonUIThreadHandler = new Handler(handlerThread.getLooper(), this);
+ }
+
+ public void destroy() {
+ mNonUIThreadHandler.getLooper().quit();
+ }
+
+ /**
+ * Handle a message.
+ * @see android.os.Handler.Callback#handleMessage(android.os.Message)
+ */
+ @Override
+ public boolean handleMessage(final Message msg) {
+ return true;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 72281e62c..f836e61cb 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -208,7 +208,7 @@ final class SuggestionStripLayoutHelper {
}
final String word = suggestedWords.getWord(indexInSuggestedWords);
final boolean isAutoCorrect = indexInSuggestedWords == 1
- && suggestedWords.willAutoCorrect();
+ && suggestedWords.mWillAutoCorrect;
final boolean isTypedWordValid = indexInSuggestedWords == 0
&& suggestedWords.mTypedWordValid;
if (!isAutoCorrect && !isTypedWordValid) {
@@ -232,7 +232,7 @@ final class SuggestionStripLayoutHelper {
final SuggestedWords suggestedWords) {
final int indexToDisplayMostImportantSuggestion;
final int indexToDisplaySecondMostImportantSuggestion;
- if (suggestedWords.willAutoCorrect()) {
+ if (suggestedWords.mWillAutoCorrect) {
indexToDisplayMostImportantSuggestion = SuggestedWords.INDEX_OF_AUTO_CORRECTION;
indexToDisplaySecondMostImportantSuggestion = SuggestedWords.INDEX_OF_TYPED_WORD;
} else {
@@ -257,7 +257,7 @@ final class SuggestionStripLayoutHelper {
final boolean isSuggested = (indexInSuggestedWords != SuggestedWords.INDEX_OF_TYPED_WORD);
final int color;
- if (positionInStrip == mCenterPositionInStrip && suggestedWords.willAutoCorrect()) {
+ if (positionInStrip == mCenterPositionInStrip && suggestedWords.mWillAutoCorrect) {
color = mColorAutoCorrect;
} else if (positionInStrip == mCenterPositionInStrip && suggestedWords.mTypedWordValid) {
color = mColorValidTypedWord;