Refactor TextEntryState not to use enum

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

View file

@ -16,117 +16,39 @@
package com.android.inputmethod.latin; 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 android.util.Log;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
public class TextEntryState { public class TextEntryState {
private static final String TAG = TextEntryState.class.getSimpleName();
private static final boolean DEBUG = true;
private static final boolean DBG = false; 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 final String TAG = "TextEntryState"; private static int sState = UNKNOWN;
private static int sPreviousState = UNKNOWN;
private static boolean LOGGING = false; private static void setState(final int newState) {
sPreviousState = sState;
private static int sBackspaceCount = 0; sState = newState;
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 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) { public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord) {
if (typedWord == null) return; if (typedWord == null) return;
if (!typedWord.equals(actualWord)) { setState(ACCEPTED_DEFAULT);
sAutoSuggestCount++;
}
sTypedChars += typedWord.length();
sActualChars += actualWord.length();
sState = State.ACCEPTED_DEFAULT;
LatinImeLogger.logOnAutoSuggestion(typedWord.toString(), actualWord.toString()); 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 // State.ACCEPTED_DEFAULT will be changed to other sub-states
@ -138,151 +60,167 @@ public class TextEntryState {
case SPACE_AFTER_ACCEPTED: case SPACE_AFTER_ACCEPTED:
case PUNCTUATION_AFTER_ACCEPTED: case PUNCTUATION_AFTER_ACCEPTED:
case IN_WORD: case IN_WORD:
sState = State.ACCEPTED_DEFAULT; setState(ACCEPTED_DEFAULT);
break; break;
default: default:
break; break;
} }
displayState(); if (DEBUG) displayState("backToAcceptedDefault", "typedWord", typedWord);
} }
public static void acceptedTyped(@SuppressWarnings("unused") CharSequence typedWord) { public static void acceptedTyped(CharSequence typedWord) {
sWordNotInDictionaryCount++; setState(PICKED_SUGGESTION);
sState = State.PICKED_SUGGESTION; if (DEBUG) displayState("acceptedTyped", "typedWord", typedWord);
displayState();
} }
public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) { public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) {
sManualSuggestCount++; if (sState == RECORRECTING || sState == PICKED_RECORRECTION) {
State oldState = sState; setState(PICKED_RECORRECTION);
if (typedWord.equals(actualWord)) {
acceptedTyped(typedWord);
}
if (oldState == State.RECORRECTING || oldState == State.PICKED_RECORRECTION) {
sState = State.PICKED_RECORRECTION;
} else { } else {
sState = State.PICKED_SUGGESTION; setState(PICKED_SUGGESTION);
} }
displayState(); if (DEBUG)
displayState("acceptedSuggestion", "typedWord", typedWord, "actualWord", actualWord);
} }
public static void selectedForRecorrection() { public static void selectedForRecorrection() {
sState = State.RECORRECTING; setState(RECORRECTING);
displayState(); if (DEBUG) displayState("selectedForRecorrection");
} }
public static void onAbortRecorrection() { public static void onAbortRecorrection() {
if (isRecorrecting()) { if (sState == RECORRECTING || sState == PICKED_RECORRECTION) {
sState = State.START; setState(START);
} }
displayState(); if (DEBUG) displayState("onAbortRecorrection");
} }
public static void typedCharacter(char c, boolean isSeparator) { public static void typedCharacter(char c, boolean isSeparator) {
boolean isSpace = c == ' '; final boolean isSpace = (c == ' ');
switch (sState) { switch (sState) {
case IN_WORD: case IN_WORD:
if (isSpace || isSeparator) { if (isSpace || isSeparator) {
sState = State.START; setState(START);
} else { } else {
// State hasn't changed. // State hasn't changed.
} }
break; break;
case ACCEPTED_DEFAULT: case ACCEPTED_DEFAULT:
case SPACE_AFTER_PICKED: case SPACE_AFTER_PICKED:
if (isSpace) { if (isSpace) {
sState = State.SPACE_AFTER_ACCEPTED; setState(SPACE_AFTER_ACCEPTED);
} else if (isSeparator) { } else if (isSeparator) {
sState = State.PUNCTUATION_AFTER_ACCEPTED; // Swap
} else { setState(PUNCTUATION_AFTER_ACCEPTED);
sState = State.IN_WORD; } else {
} setState(IN_WORD);
break; }
case PICKED_SUGGESTION: break;
case PICKED_RECORRECTION: case PICKED_SUGGESTION:
if (isSpace) { case PICKED_RECORRECTION:
sState = State.SPACE_AFTER_PICKED; if (isSpace) {
} else if (isSeparator) { setState(SPACE_AFTER_PICKED);
// Swap } else if (isSeparator) {
sState = State.PUNCTUATION_AFTER_ACCEPTED; // Swap
} else { setState(PUNCTUATION_AFTER_ACCEPTED);
sState = State.IN_WORD; } else {
} setState(IN_WORD);
break; }
case START: break;
case UNKNOWN: case START:
case SPACE_AFTER_ACCEPTED: case UNKNOWN:
case PUNCTUATION_AFTER_ACCEPTED: case SPACE_AFTER_ACCEPTED:
case PUNCTUATION_AFTER_WORD: case PUNCTUATION_AFTER_ACCEPTED:
if (!isSpace && !isSeparator) { case PUNCTUATION_AFTER_WORD:
sState = State.IN_WORD; if (!isSpace && !isSeparator) {
} else { setState(IN_WORD);
sState = State.START; } else {
} setState(START);
break; }
case UNDO_COMMIT: break;
if (isSpace || isSeparator) { case UNDO_COMMIT:
sState = State.ACCEPTED_DEFAULT; if (isSpace || isSeparator) {
} else { setState(ACCEPTED_DEFAULT);
sState = State.IN_WORD; } else {
} setState(IN_WORD);
break; }
case RECORRECTING: break;
sState = State.START; case RECORRECTING:
break; setState(START);
break;
} }
displayState(); if (DEBUG) displayState("typedCharacter", "char", c, "isSeparator", isSeparator);
} }
public static void backspace() { public static void backspace() {
if (sState == State.ACCEPTED_DEFAULT) { if (sState == ACCEPTED_DEFAULT) {
sState = State.UNDO_COMMIT; setState(UNDO_COMMIT);
sAutoSuggestUndoneCount++;
LatinImeLogger.logOnAutoSuggestionCanceled(); LatinImeLogger.logOnAutoSuggestionCanceled();
} else if (sState == State.UNDO_COMMIT) { } else if (sState == UNDO_COMMIT) {
sState = State.IN_WORD; setState(IN_WORD);
} }
sBackspaceCount++; if (DEBUG) displayState("backspace");
displayState();
} }
public static void reset() { public static void reset() {
sState = State.START; setState(START);
displayState(); if (DEBUG) displayState("reset");
} }
public static State getState() { public static boolean isAcceptedDefault() {
if (DBG) { return sState == ACCEPTED_DEFAULT;
Log.d(TAG, "Returning state = " + sState); }
}
return sState; 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() { 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) { public static String getState() {
if (LOGGING && sKeyLocationFile != null && key.mCode >= 32) { return stateName(sState);
String out = }
"KEY: " + (char) key.mCode
+ " X: " + x private static String stateName(int state) {
+ " Y: " + y switch (state) {
+ " MX: " + (key.mX + key.mWidth / 2) case START: return "START";
+ " MY: " + (key.mY + key.mHeight / 2) case IN_WORD: return "IN_WORD";
+ "\n"; case ACCEPTED_DEFAULT: return "ACCEPTED_DEFAULT";
try { case PICKED_SUGGESTION: return "PICKED_SUGGESTION";
sKeyLocationFile.write(out.getBytes()); case PUNCTUATION_AFTER_WORD: return "PUNCTUATION_AFTER_WORD";
} catch (IOException ioe) { case PUNCTUATION_AFTER_ACCEPTED: return "PUNCTUATION_AFTER_ACCEPTED";
// TODO: May run out of space 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() { private static void displayState(String title, Object ... args) {
if (DBG) { final StringBuilder sb = new StringBuilder(title);
Log.d(TAG, "State = " + sState); 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());
} }
} }