diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 53051d033..27a5cadf2 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -145,6 +145,7 @@
+
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index cb1358726..78c5f1834 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -86,6 +86,7 @@
16.6666%
100
+ 300
550%
1000
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index b771463c2..a60e4496b 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -104,6 +104,7 @@
- @fraction/config_gesture_dynamic_distance_threshold_to
- @fraction/config_gesture_sampling_minimum_distance
- @integer/config_gesture_recognition_minimum_time
+ - @integer/config_gesture_recognition_update_time
- @fraction/config_gesture_recognition_speed_threshold
- @integer/config_suppress_key_preview_after_batch_input_duration
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index d5f40ad36..b09f9b20c 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -29,6 +29,7 @@ import android.graphics.Paint.Align;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Message;
+import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.Log;
@@ -156,12 +157,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private static final int MSG_REPEAT_KEY = 1;
private static final int MSG_LONGPRESS_KEY = 2;
private static final int MSG_DOUBLE_TAP = 3;
+ private static final int MSG_UPDATE_BATCH_INPUT = 4;
private final int mKeyRepeatStartTimeout;
private final int mKeyRepeatInterval;
private final int mLongPressKeyTimeout;
private final int mLongPressShiftKeyTimeout;
private final int mIgnoreAltCodeKeyTimeout;
+ private final int mGestureRecognitionUpdateTime;
public KeyTimerHandler(final MainKeyboardView outerInstance,
final TypedArray mainKeyboardViewAttr) {
@@ -177,6 +180,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
R.styleable.MainKeyboardView_longPressShiftKeyTimeout, 0);
mIgnoreAltCodeKeyTimeout = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_ignoreAltCodeKeyTimeout, 0);
+ mGestureRecognitionUpdateTime = mainKeyboardViewAttr.getInt(
+ R.styleable.MainKeyboardView_gestureRecognitionUpdateTime, 0);
}
@Override
@@ -201,6 +206,10 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
KeyboardSwitcher.getInstance().onLongPressTimeout(msg.arg1);
}
break;
+ case MSG_UPDATE_BATCH_INPUT:
+ tracker.updateBatchInputByTimer(SystemClock.uptimeMillis());
+ startUpdateBatchInputTimer(tracker);
+ break;
}
}
@@ -349,8 +358,24 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
cancelLongPressTimer();
}
+ @Override
+ public void startUpdateBatchInputTimer(final PointerTracker tracker) {
+ if (mGestureRecognitionUpdateTime <= 0) {
+ return;
+ }
+ removeMessages(MSG_UPDATE_BATCH_INPUT, tracker);
+ sendMessageDelayed(obtainMessage(MSG_UPDATE_BATCH_INPUT, tracker),
+ mGestureRecognitionUpdateTime);
+ }
+
+ @Override
+ public void cancelAllUpdateBatchInputTimer() {
+ removeMessages(MSG_UPDATE_BATCH_INPUT);
+ }
+
public void cancelAllMessages() {
cancelKeyTimers();
+ cancelAllUpdateBatchInputTimer();
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index c8052af6a..bd4a713ec 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -94,6 +94,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public void cancelDoubleTapTimer();
public boolean isInDoubleTapTimeout();
public void cancelKeyTimers();
+ public void startUpdateBatchInputTimer(PointerTracker tracker);
+ public void cancelAllUpdateBatchInputTimer();
public static class Adapter implements TimerProxy {
@Override
@@ -116,6 +118,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public boolean isInDoubleTapTimeout() { return false; }
@Override
public void cancelKeyTimers() {}
+ @Override
+ public void startUpdateBatchInputTimer(PointerTracker tracker) {}
+ @Override
+ public void cancelAllUpdateBatchInputTimer() {}
}
}
@@ -705,27 +711,38 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
mDrawingProxy.showGesturePreviewTrail(this, isOldestTrackerInQueue(this));
}
+ public void updateBatchInputByTimer(final long eventTime) {
+ final int gestureTime = (int)(eventTime - sGestureFirstDownTime);
+ mGestureStrokeWithPreviewPoints.duplicateLastPointWith(gestureTime);
+ updateBatchInput(eventTime);
+ }
+
private void mayUpdateBatchInput(final long eventTime, final Key key) {
if (key != null) {
- synchronized (sAggregratedPointers) {
- final GestureStroke stroke = mGestureStrokeWithPreviewPoints;
- stroke.appendIncrementalBatchPoints(sAggregratedPointers);
- final int size = sAggregratedPointers.getPointerSize();
- if (size > sLastRecognitionPointSize
- && stroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) {
- sLastRecognitionPointSize = size;
- sLastRecognitionTime = eventTime;
- if (DEBUG_LISTENER) {
- Log.d(TAG, String.format("[%d] onUpdateBatchInput: batchPoints=%d",
- mPointerId, size));
- }
- mListener.onUpdateBatchInput(sAggregratedPointers);
- }
- }
+ updateBatchInput(eventTime);
}
mDrawingProxy.showGesturePreviewTrail(this, isOldestTrackerInQueue(this));
}
+ private void updateBatchInput(final long eventTime) {
+ synchronized (sAggregratedPointers) {
+ final GestureStroke stroke = mGestureStrokeWithPreviewPoints;
+ stroke.appendIncrementalBatchPoints(sAggregratedPointers);
+ final int size = sAggregratedPointers.getPointerSize();
+ if (size > sLastRecognitionPointSize
+ && stroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) {
+ sLastRecognitionPointSize = size;
+ sLastRecognitionTime = eventTime;
+ if (DEBUG_LISTENER) {
+ Log.d(TAG, String.format("[%d] onUpdateBatchInput: batchPoints=%d", mPointerId,
+ size));
+ }
+ mTimerProxy.startUpdateBatchInputTimer(this);
+ mListener.onUpdateBatchInput(sAggregratedPointers);
+ }
+ }
+ }
+
private void mayEndBatchInput(final long eventTime) {
synchronized (sAggregratedPointers) {
mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregratedPointers);
@@ -737,6 +754,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d",
mPointerId, sAggregratedPointers.getPointerSize()));
}
+ mTimerProxy.cancelAllUpdateBatchInputTimer();
mListener.onEndBatchInput(sAggregratedPointers);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
index aab14e968..a43e94a75 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
@@ -228,6 +228,17 @@ public class GestureStroke {
return isStartOfAGesture;
}
+ public void duplicateLastPointWith(final int time) {
+ final int lastIndex = mEventTimes.getLength() - 1;
+ if (lastIndex >= 0) {
+ final int x = mXCoordinates.get(lastIndex);
+ final int y = mYCoordinates.get(lastIndex);
+ // TODO: Have appendMajorPoint()
+ appendPoint(x, y, time);
+ updateIncrementalRecognitionSize(x, y, time);
+ }
+ }
+
protected void reset() {
mIncrementalRecognitionSize = 0;
mLastIncrementalBatchSize = 0;
diff --git a/native/jni/src/binary_format.h b/native/jni/src/binary_format.h
index 9a8c315f7..6df92bf0d 100644
--- a/native/jni/src/binary_format.h
+++ b/native/jni/src/binary_format.h
@@ -246,7 +246,7 @@ static inline int childrenAddressSize(const uint8_t flags) {
/* See the note in attributeAddressSize. The same applies here */
}
-static inline int shortcutByteSize(const uint8_t *const dict, const int pos) {
+static AK_FORCE_INLINE int shortcutByteSize(const uint8_t *const dict, const int pos) {
return ((int)(dict[pos] << 8)) + (dict[pos + 1]);
}
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 894e5f1c9..f32ebeca3 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -167,15 +167,15 @@ static inline void prof_out(void) {
}
AKLOGI("Total time is %6.3f ms.",
profile_buf[PROF_BUF_SIZE - 1] * 1000.0f / static_cast(CLOCKS_PER_SEC));
- float all = 0;
+ float all = 0.0f;
for (int i = 0; i < PROF_BUF_SIZE - 1; ++i) {
all += profile_buf[i];
}
- if (all == 0) all = 1;
+ if (all < 1.0f) all = 1.0f;
for (int i = 0; i < PROF_BUF_SIZE - 1; ++i) {
- if (profile_buf[i]) {
+ if (profile_buf[i] > 0.0f) {
AKLOGI("(%d): Used %4.2f%%, %8.4f ms. Called %d times.",
- i, (profile_buf[i] * 100 / all),
+ i, (profile_buf[i] * 100.0f / all),
profile_buf[i] * 1000.0f / static_cast(CLOCKS_PER_SEC),
profile_counter[i]);
}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 6bd46ccfb..4b08d6acb 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -17,7 +17,7 @@
-
+