4a4b6d42a7
Move the logic that determines how to handle gesture typing from PointerTracker to BatchInputArbiter class. This change must be checked in together with Ia7db8f4fb7. Change-Id: I5e9f786de58d8a3cb0407ae562af707710ec37fb
181 lines
8.4 KiB
Java
181 lines
8.4 KiB
Java
/*
|
|
* 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;
|
|
}
|
|
}
|