am 9033fb1f: Merge "Separate TypingTimeRecorder class"

* commit '9033fb1f6498b4ef0cf339cb3c4a39cd28c337ad':
  Separate TypingTimeRecorder class
main
Tadashi G. Takaoka 2013-12-19 23:20:38 -08:00 committed by Android Git Automerger
commit 3a8e56b6bf
2 changed files with 84 additions and 66 deletions

View File

@ -29,6 +29,7 @@ import com.android.inputmethod.keyboard.internal.GestureStroke.GestureStrokePara
import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints; import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints;
import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints.GestureStrokePreviewParams; import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints.GestureStrokePreviewParams;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue; import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.keyboard.internal.TypingTimeRecorder;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LatinImeLogger;
@ -167,7 +168,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private boolean mIsDetectingGesture = false; // per PointerTracker. private boolean mIsDetectingGesture = false; // per PointerTracker.
private static boolean sInGesture = false; private static boolean sInGesture = false;
private static long sGestureFirstDownTime; private static long sGestureFirstDownTime;
private static TimeRecorder sTimeRecorder; private static TypingTimeRecorder sTypingTimeRecorder;
private static final InputPointers sAggregatedPointers = new InputPointers( private static final InputPointers sAggregatedPointers = new InputPointers(
GestureStroke.DEFAULT_CAPACITY); GestureStroke.DEFAULT_CAPACITY);
private static int sLastRecognitionPointSize = 0; // synchronized using sAggregatedPointers private static int sLastRecognitionPointSize = 0; // synchronized using sAggregatedPointers
@ -224,64 +225,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
} }
} }
static final class TimeRecorder {
private final int mSuppressKeyPreviewAfterBatchInputDuration;
private final int mStaticTimeThresholdAfterFastTyping; // msec
private long mLastTypingTime;
private long mLastLetterTypingTime;
private long mLastBatchInputTime;
public TimeRecorder(final PointerTrackerParams pointerTrackerParams,
final GestureStrokeParams gestureStrokeParams) {
mSuppressKeyPreviewAfterBatchInputDuration =
pointerTrackerParams.mSuppressKeyPreviewAfterBatchInputDuration;
mStaticTimeThresholdAfterFastTyping =
gestureStrokeParams.mStaticTimeThresholdAfterFastTyping;
}
public boolean isInFastTyping(final long eventTime) {
final long elapsedTimeSinceLastLetterTyping = eventTime - mLastLetterTypingTime;
return elapsedTimeSinceLastLetterTyping < mStaticTimeThresholdAfterFastTyping;
}
private boolean wasLastInputTyping() {
return mLastTypingTime >= mLastBatchInputTime;
}
public void onCodeInput(final int code, final long eventTime) {
// Record the letter typing time when
// 1. Letter keys are typed successively without any batch input in between.
// 2. A letter key is typed within the threshold time since the last any key typing.
// 3. A non-letter key is typed within the threshold time since the last letter key
// typing.
if (Character.isLetter(code)) {
if (wasLastInputTyping()
|| eventTime - mLastTypingTime < mStaticTimeThresholdAfterFastTyping) {
mLastLetterTypingTime = eventTime;
}
} else {
if (eventTime - mLastLetterTypingTime < mStaticTimeThresholdAfterFastTyping) {
// This non-letter typing should be treated as a part of fast typing.
mLastLetterTypingTime = eventTime;
}
}
mLastTypingTime = eventTime;
}
public void onEndBatchInput(final long eventTime) {
mLastBatchInputTime = eventTime;
}
public long getLastLetterTypingTime() {
return mLastLetterTypingTime;
}
public boolean needsToSuppressKeyPreviewPopup(final long eventTime) {
return !wasLastInputTyping()
&& eventTime - mLastBatchInputTime < mSuppressKeyPreviewAfterBatchInputDuration;
}
}
// The position and time at which first down event occurred. // The position and time at which first down event occurred.
private long mDownTime; private long mDownTime;
private int[] mDownCoordinates = CoordinateUtils.newInstance(); private int[] mDownCoordinates = CoordinateUtils.newInstance();
@ -349,7 +292,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
sParams = new PointerTrackerParams(mainKeyboardViewAttr); sParams = new PointerTrackerParams(mainKeyboardViewAttr);
sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr); sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr);
sGesturePreviewParams = new GestureStrokePreviewParams(mainKeyboardViewAttr); sGesturePreviewParams = new GestureStrokePreviewParams(mainKeyboardViewAttr);
sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams); sTypingTimeRecorder = new TypingTimeRecorder(
sGestureStrokeParams.mStaticTimeThresholdAfterFastTyping,
sParams.mSuppressKeyPreviewAfterBatchInputDuration);
final Resources res = mainKeyboardViewAttr.getResources(); final Resources res = mainKeyboardViewAttr.getResources();
sNeedsPhantomSuddenMoveEventHack = Boolean.parseBoolean( sNeedsPhantomSuddenMoveEventHack = Boolean.parseBoolean(
@ -490,7 +435,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
} }
// Even if the key is disabled, it should respond if it is in the altCodeWhileTyping state. // Even if the key is disabled, it should respond if it is in the altCodeWhileTyping state.
if (key.isEnabled() || altersCode) { if (key.isEnabled() || altersCode) {
sTimeRecorder.onCodeInput(code, eventTime); sTypingTimeRecorder.onCodeInput(code, eventTime);
if (code == Constants.CODE_OUTPUT_TEXT) { if (code == Constants.CODE_OUTPUT_TEXT) {
sListener.onTextInput(key.getOutputText()); sListener.onTextInput(key.getOutputText());
} else if (code != Constants.CODE_UNSPECIFIED) { } else if (code != Constants.CODE_UNSPECIFIED) {
@ -617,7 +562,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private static boolean needsToSuppressKeyPreviewPopup(final long eventTime) { private static boolean needsToSuppressKeyPreviewPopup(final long eventTime) {
if (!sShouldHandleGesture) return false; if (!sShouldHandleGesture) return false;
return sTimeRecorder.needsToSuppressKeyPreviewPopup(eventTime); return sTypingTimeRecorder.needsToSuppressKeyPreviewPopup(eventTime);
} }
private void setPressedKeyGraphics(final Key key, final long eventTime) { private void setPressedKeyGraphics(final Key key, final long eventTime) {
@ -790,7 +735,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregatedPointers); mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregatedPointers);
if (getActivePointerTrackerCount() == 1) { if (getActivePointerTrackerCount() == 1) {
sInGesture = false; sInGesture = false;
sTimeRecorder.onEndBatchInput(eventTime); sTypingTimeRecorder.onEndBatchInput(eventTime);
sTimerProxy.cancelAllUpdateBatchInputTimers(); sTimerProxy.cancelAllUpdateBatchInputTimers();
if (!mIsTrackingForActionDisabled) { if (!mIsTrackingForActionDisabled) {
if (DEBUG_LISTENER) { if (DEBUG_LISTENER) {
@ -905,7 +850,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
sGestureFirstDownTime = eventTime; sGestureFirstDownTime = eventTime;
} }
mGestureStrokeWithPreviewPoints.onDownEvent(x, y, eventTime, sGestureFirstDownTime, mGestureStrokeWithPreviewPoints.onDownEvent(x, y, eventTime, sGestureFirstDownTime,
sTimeRecorder.getLastLetterTypingTime()); sTypingTimeRecorder.getLastLetterTypingTime());
} }
} }
@ -1102,7 +1047,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// HACK: On some devices, quick successive proximate touches may be reported as a bogus // HACK: On some devices, quick successive proximate touches may be reported as a bogus
// down-move-up event by touch panel firmware. This hack detects such cases and breaks // down-move-up event by touch panel firmware. This hack detects such cases and breaks
// these events into separate up and down events. // these events into separate up and down events.
else if (sNeedsProximateBogusDownMoveUpEventHack && sTimeRecorder.isInFastTyping(eventTime) else if (sNeedsProximateBogusDownMoveUpEventHack
&& sTypingTimeRecorder.isInFastTyping(eventTime)
&& mBogusMoveEventDetector.isCloseToActualDownEvent(x, y)) { && mBogusMoveEventDetector.isCloseToActualDownEvent(x, y)) {
processProximateBogusDownMoveUpEventHack(key, x, y, eventTime, oldKey, lastX, lastY); processProximateBogusDownMoveUpEventHack(key, x, y, eventTime, oldKey, lastX, lastY);
} }
@ -1320,7 +1266,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
return true; return true;
} }
if (sNeedsProximateBogusDownMoveUpEventHack && !mIsAllowedDraggingFinger if (sNeedsProximateBogusDownMoveUpEventHack && !mIsAllowedDraggingFinger
&& sTimeRecorder.isInFastTyping(eventTime) && sTypingTimeRecorder.isInFastTyping(eventTime)
&& mBogusMoveEventDetector.hasTraveledLongDistance(x, y)) { && mBogusMoveEventDetector.hasTraveledLongDistance(x, y)) {
if (DEBUG_MODE) { if (DEBUG_MODE) {
final float keyDiagonal = (float)Math.hypot( final float keyDiagonal = (float)Math.hypot(

View File

@ -0,0 +1,72 @@
/*
* 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;
public final class TypingTimeRecorder {
private final int mStaticTimeThresholdAfterFastTyping; // msec
private final int mSuppressKeyPreviewAfterBatchInputDuration;
private long mLastTypingTime;
private long mLastLetterTypingTime;
private long mLastBatchInputTime;
public TypingTimeRecorder(final int staticTimeThresholdAfterFastTyping,
final int suppressKeyPreviewAfterBatchInputDuration) {
mStaticTimeThresholdAfterFastTyping = staticTimeThresholdAfterFastTyping;
mSuppressKeyPreviewAfterBatchInputDuration = suppressKeyPreviewAfterBatchInputDuration;
}
public boolean isInFastTyping(final long eventTime) {
final long elapsedTimeSinceLastLetterTyping = eventTime - mLastLetterTypingTime;
return elapsedTimeSinceLastLetterTyping < mStaticTimeThresholdAfterFastTyping;
}
private boolean wasLastInputTyping() {
return mLastTypingTime >= mLastBatchInputTime;
}
public void onCodeInput(final int code, final long eventTime) {
// Record the letter typing time when
// 1. Letter keys are typed successively without any batch input in between.
// 2. A letter key is typed within the threshold time since the last any key typing.
// 3. A non-letter key is typed within the threshold time since the last letter key typing.
if (Character.isLetter(code)) {
if (wasLastInputTyping()
|| eventTime - mLastTypingTime < mStaticTimeThresholdAfterFastTyping) {
mLastLetterTypingTime = eventTime;
}
} else {
if (eventTime - mLastLetterTypingTime < mStaticTimeThresholdAfterFastTyping) {
// This non-letter typing should be treated as a part of fast typing.
mLastLetterTypingTime = eventTime;
}
}
mLastTypingTime = eventTime;
}
public void onEndBatchInput(final long eventTime) {
mLastBatchInputTime = eventTime;
}
public long getLastLetterTypingTime() {
return mLastLetterTypingTime;
}
public boolean needsToSuppressKeyPreviewPopup(final long eventTime) {
return !wasLastInputTyping()
&& eventTime - mLastBatchInputTime < mSuppressKeyPreviewAfterBatchInputDuration;
}
}