Refactor TextEntryState not to use enum

Bug: 3504990
Change-Id: Id1ae9715d9f9ba99702e4cd5c243026a84d6861d
main
Tadashi G. Takaoka 2011-03-02 17:02:06 -08:00
parent 1eff7d77c8
commit 662bb7c26c
2 changed files with 149 additions and 220 deletions

View File

@ -542,7 +542,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSubtypeSwitcher.updateParametersOnStartInputView();
TextEntryState.newSession(this);
TextEntryState.reset();
// Most such things we decide below in initializeInputAttributesAndGetMode, but we need to
// know now whether this is a password text field, because we need to know now whether we
@ -746,15 +746,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mVoiceConnector.setVoiceInputHighlighted(false);
} else if (!mHasValidSuggestions && !mJustAccepted) {
switch (TextEntryState.getState()) {
case ACCEPTED_DEFAULT:
TextEntryState.reset();
// $FALL-THROUGH$
case SPACE_AFTER_PICKED:
if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) {
if (TextEntryState.isAcceptedDefault())
TextEntryState.reset();
mJustAddedAutoSpace = false; // The user moved the cursor.
break;
default:
break;
}
}
mJustAccepted = false;
@ -832,7 +827,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mVoiceConnector.hideVoiceWindow(mConfigurationChanging);
mWordHistory.clear();
super.hideWindow();
TextEntryState.endSession();
}
@Override
@ -1231,7 +1225,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.postUpdateShiftKeyState();
TextEntryState.backspace();
if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) {
if (TextEntryState.isUndoCommit()) {
revertLastWord(deleteChar);
ic.endBatchEdit();
return;
@ -1391,14 +1385,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Handle the case of ". ." -> " .." with auto-space if necessary
// before changing the TextEntryState.
if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
&& primaryCode == Keyboard.CODE_PERIOD) {
if (TextEntryState.isPunctuationAfterAccepted() && primaryCode == Keyboard.CODE_PERIOD) {
reswapPeriodAndSpace();
}
TextEntryState.typedCharacter((char) primaryCode, true);
if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
&& primaryCode != Keyboard.CODE_ENTER) {
if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER) {
swapPunctuationAndSpace();
} else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
doubleSpace();
@ -1430,7 +1422,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
if (inputView != null)
inputView.closing();
TextEntryState.endSession();
}
private void saveWordInHistory(CharSequence result) {

View File

@ -16,117 +16,39 @@
package com.android.inputmethod.latin;
import com.android.inputmethod.keyboard.Key;
import android.content.Context;
import android.text.format.DateFormat;
import android.util.Log;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
public class TextEntryState {
private static final boolean DBG = false;
private static final String TAG = TextEntryState.class.getSimpleName();
private static final boolean DEBUG = true;
private static final String TAG = "TextEntryState";
private static final int UNKNOWN = 0;
private static final int START = 1;
private static final int IN_WORD = 2;
private static final int ACCEPTED_DEFAULT = 3;
private static final int PICKED_SUGGESTION = 4;
private static final int PUNCTUATION_AFTER_WORD = 5;
private static final int PUNCTUATION_AFTER_ACCEPTED = 6;
private static final int SPACE_AFTER_ACCEPTED = 7;
private static final int SPACE_AFTER_PICKED = 8;
private static final int UNDO_COMMIT = 9;
private static final int RECORRECTING = 10;
private static final int PICKED_RECORRECTION = 11;
private static boolean LOGGING = false;
private static int sState = UNKNOWN;
private static int sPreviousState = UNKNOWN;
private static int sBackspaceCount = 0;
private static int sAutoSuggestCount = 0;
private static int sAutoSuggestUndoneCount = 0;
private static int sManualSuggestCount = 0;
private static int sWordNotInDictionaryCount = 0;
private static int sSessionCount = 0;
private static int sTypedChars;
private static int sActualChars;
public enum State {
UNKNOWN,
START,
IN_WORD,
ACCEPTED_DEFAULT,
PICKED_SUGGESTION,
PUNCTUATION_AFTER_WORD,
PUNCTUATION_AFTER_ACCEPTED,
SPACE_AFTER_ACCEPTED,
SPACE_AFTER_PICKED,
UNDO_COMMIT,
RECORRECTING,
PICKED_RECORRECTION,
private static void setState(final int newState) {
sPreviousState = sState;
sState = newState;
}
private static State sState = State.UNKNOWN;
private static FileOutputStream sKeyLocationFile;
private static FileOutputStream sUserActionFile;
public static void newSession(Context context) {
sSessionCount++;
sAutoSuggestCount = 0;
sBackspaceCount = 0;
sAutoSuggestUndoneCount = 0;
sManualSuggestCount = 0;
sWordNotInDictionaryCount = 0;
sTypedChars = 0;
sActualChars = 0;
sState = State.START;
if (LOGGING) {
try {
sKeyLocationFile = context.openFileOutput("key.txt", Context.MODE_APPEND);
sUserActionFile = context.openFileOutput("action.txt", Context.MODE_APPEND);
} catch (IOException ioe) {
Log.e("TextEntryState", "Couldn't open file for output: " + ioe);
}
}
}
public static void endSession() {
if (sKeyLocationFile == null) {
return;
}
try {
sKeyLocationFile.close();
// Write to log file
// Write timestamp, settings,
String out = DateFormat.format("MM:dd hh:mm:ss", Calendar.getInstance().getTime())
.toString()
+ " BS: " + sBackspaceCount
+ " auto: " + sAutoSuggestCount
+ " manual: " + sManualSuggestCount
+ " typed: " + sWordNotInDictionaryCount
+ " undone: " + sAutoSuggestUndoneCount
+ " saved: " + ((float) (sActualChars - sTypedChars) / sActualChars)
+ "\n";
sUserActionFile.write(out.getBytes());
sUserActionFile.close();
sKeyLocationFile = null;
sUserActionFile = null;
} catch (IOException ioe) {
// ignore
}
}
public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord) {
if (typedWord == null) return;
if (!typedWord.equals(actualWord)) {
sAutoSuggestCount++;
}
sTypedChars += typedWord.length();
sActualChars += actualWord.length();
sState = State.ACCEPTED_DEFAULT;
setState(ACCEPTED_DEFAULT);
LatinImeLogger.logOnAutoSuggestion(typedWord.toString(), actualWord.toString());
displayState();
if (DEBUG)
displayState("acceptedDefault", "typedWord", typedWord, "actualWord", actualWord);
}
// State.ACCEPTED_DEFAULT will be changed to other sub-states
@ -138,151 +60,167 @@ public class TextEntryState {
case SPACE_AFTER_ACCEPTED:
case PUNCTUATION_AFTER_ACCEPTED:
case IN_WORD:
sState = State.ACCEPTED_DEFAULT;
setState(ACCEPTED_DEFAULT);
break;
default:
break;
}
displayState();
if (DEBUG) displayState("backToAcceptedDefault", "typedWord", typedWord);
}
public static void acceptedTyped(@SuppressWarnings("unused") CharSequence typedWord) {
sWordNotInDictionaryCount++;
sState = State.PICKED_SUGGESTION;
displayState();
public static void acceptedTyped(CharSequence typedWord) {
setState(PICKED_SUGGESTION);
if (DEBUG) displayState("acceptedTyped", "typedWord", typedWord);
}
public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) {
sManualSuggestCount++;
State oldState = sState;
if (typedWord.equals(actualWord)) {
acceptedTyped(typedWord);
}
if (oldState == State.RECORRECTING || oldState == State.PICKED_RECORRECTION) {
sState = State.PICKED_RECORRECTION;
if (sState == RECORRECTING || sState == PICKED_RECORRECTION) {
setState(PICKED_RECORRECTION);
} else {
sState = State.PICKED_SUGGESTION;
setState(PICKED_SUGGESTION);
}
displayState();
if (DEBUG)
displayState("acceptedSuggestion", "typedWord", typedWord, "actualWord", actualWord);
}
public static void selectedForRecorrection() {
sState = State.RECORRECTING;
displayState();
setState(RECORRECTING);
if (DEBUG) displayState("selectedForRecorrection");
}
public static void onAbortRecorrection() {
if (isRecorrecting()) {
sState = State.START;
if (sState == RECORRECTING || sState == PICKED_RECORRECTION) {
setState(START);
}
displayState();
if (DEBUG) displayState("onAbortRecorrection");
}
public static void typedCharacter(char c, boolean isSeparator) {
boolean isSpace = c == ' ';
final boolean isSpace = (c == ' ');
switch (sState) {
case IN_WORD:
if (isSpace || isSeparator) {
sState = State.START;
} else {
// State hasn't changed.
}
break;
case ACCEPTED_DEFAULT:
case SPACE_AFTER_PICKED:
if (isSpace) {
sState = State.SPACE_AFTER_ACCEPTED;
} else if (isSeparator) {
sState = State.PUNCTUATION_AFTER_ACCEPTED;
} else {
sState = State.IN_WORD;
}
break;
case PICKED_SUGGESTION:
case PICKED_RECORRECTION:
if (isSpace) {
sState = State.SPACE_AFTER_PICKED;
} else if (isSeparator) {
// Swap
sState = State.PUNCTUATION_AFTER_ACCEPTED;
} else {
sState = State.IN_WORD;
}
break;
case START:
case UNKNOWN:
case SPACE_AFTER_ACCEPTED:
case PUNCTUATION_AFTER_ACCEPTED:
case PUNCTUATION_AFTER_WORD:
if (!isSpace && !isSeparator) {
sState = State.IN_WORD;
} else {
sState = State.START;
}
break;
case UNDO_COMMIT:
if (isSpace || isSeparator) {
sState = State.ACCEPTED_DEFAULT;
} else {
sState = State.IN_WORD;
}
break;
case RECORRECTING:
sState = State.START;
break;
case IN_WORD:
if (isSpace || isSeparator) {
setState(START);
} else {
// State hasn't changed.
}
break;
case ACCEPTED_DEFAULT:
case SPACE_AFTER_PICKED:
if (isSpace) {
setState(SPACE_AFTER_ACCEPTED);
} else if (isSeparator) {
// Swap
setState(PUNCTUATION_AFTER_ACCEPTED);
} else {
setState(IN_WORD);
}
break;
case PICKED_SUGGESTION:
case PICKED_RECORRECTION:
if (isSpace) {
setState(SPACE_AFTER_PICKED);
} else if (isSeparator) {
// Swap
setState(PUNCTUATION_AFTER_ACCEPTED);
} else {
setState(IN_WORD);
}
break;
case START:
case UNKNOWN:
case SPACE_AFTER_ACCEPTED:
case PUNCTUATION_AFTER_ACCEPTED:
case PUNCTUATION_AFTER_WORD:
if (!isSpace && !isSeparator) {
setState(IN_WORD);
} else {
setState(START);
}
break;
case UNDO_COMMIT:
if (isSpace || isSeparator) {
setState(ACCEPTED_DEFAULT);
} else {
setState(IN_WORD);
}
break;
case RECORRECTING:
setState(START);
break;
}
displayState();
if (DEBUG) displayState("typedCharacter", "char", c, "isSeparator", isSeparator);
}
public static void backspace() {
if (sState == State.ACCEPTED_DEFAULT) {
sState = State.UNDO_COMMIT;
sAutoSuggestUndoneCount++;
if (sState == ACCEPTED_DEFAULT) {
setState(UNDO_COMMIT);
LatinImeLogger.logOnAutoSuggestionCanceled();
} else if (sState == State.UNDO_COMMIT) {
sState = State.IN_WORD;
} else if (sState == UNDO_COMMIT) {
setState(IN_WORD);
}
sBackspaceCount++;
displayState();
if (DEBUG) displayState("backspace");
}
public static void reset() {
sState = State.START;
displayState();
setState(START);
if (DEBUG) displayState("reset");
}
public static State getState() {
if (DBG) {
Log.d(TAG, "Returning state = " + sState);
}
return sState;
public static boolean isAcceptedDefault() {
return sState == ACCEPTED_DEFAULT;
}
public static boolean isSpaceAfterPicked() {
return sState == SPACE_AFTER_PICKED;
}
public static boolean isUndoCommit() {
return sState == UNDO_COMMIT;
}
public static boolean isPunctuationAfterAccepted() {
return sState == PUNCTUATION_AFTER_ACCEPTED;
}
public static boolean isRecorrecting() {
return sState == State.RECORRECTING || sState == State.PICKED_RECORRECTION;
return sState == RECORRECTING || sState == PICKED_RECORRECTION;
}
public static void keyPressedAt(Key key, int x, int y) {
if (LOGGING && sKeyLocationFile != null && key.mCode >= 32) {
String out =
"KEY: " + (char) key.mCode
+ " X: " + x
+ " Y: " + y
+ " MX: " + (key.mX + key.mWidth / 2)
+ " MY: " + (key.mY + key.mHeight / 2)
+ "\n";
try {
sKeyLocationFile.write(out.getBytes());
} catch (IOException ioe) {
// TODO: May run out of space
}
public static String getState() {
return stateName(sState);
}
private static String stateName(int state) {
switch (state) {
case START: return "START";
case IN_WORD: return "IN_WORD";
case ACCEPTED_DEFAULT: return "ACCEPTED_DEFAULT";
case PICKED_SUGGESTION: return "PICKED_SUGGESTION";
case PUNCTUATION_AFTER_WORD: return "PUNCTUATION_AFTER_WORD";
case PUNCTUATION_AFTER_ACCEPTED: return "PUNCTUATION_AFTER_ACCEPTED";
case SPACE_AFTER_ACCEPTED: return "SPACE_AFTER_ACCEPTED";
case SPACE_AFTER_PICKED: return "SPACE_AFTER_PICKED";
case UNDO_COMMIT: return "UNDO_COMMIT";
case RECORRECTING: return "RECORRECTING";
case PICKED_RECORRECTION: return "PICKED_RECORRECTION";
default: return "UNKNOWN";
}
}
private static void displayState() {
if (DBG) {
Log.d(TAG, "State = " + sState);
private static void displayState(String title, Object ... args) {
final StringBuilder sb = new StringBuilder(title);
sb.append(':');
for (int i = 0; i < args.length; i += 2) {
sb.append(' ');
sb.append(args[i]);
sb.append('=');
sb.append(args[i+1].toString());
}
sb.append(" state=");
sb.append(stateName(sState));
sb.append(" previous=");
sb.append(stateName(sPreviousState));
Log.d(TAG, sb.toString());
}
}