1 /* 2 * Copyright (C) 2008-2009 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.inputmethod.latin; 18 19 import android.content.Context; 20 import android.text.format.DateFormat; 21 import android.util.Log; 22 23 import android.inputmethodservice.Keyboard.Key; 24 25 import java.io.FileOutputStream; 26 import java.io.IOException; 27 import java.util.Calendar; 28 29 public class TextEntryState { 30 31 private static boolean LOGGING = false; 32 33 private static int sBackspaceCount = 0; 34 35 private static int sAutoSuggestCount = 0; 36 37 private static int sAutoSuggestUndoneCount = 0; 38 39 private static int sManualSuggestCount = 0; 40 41 private static int sWordNotInDictionaryCount = 0; 42 43 private static int sSessionCount = 0; 44 45 private static int sTypedChars; 46 47 private static int sActualChars; 48 49 private static final String[] STATES = { 50 "Unknown", 51 "Start", 52 "In word", 53 "Accepted default", 54 "Picked suggestion", 55 "Punc. after word", 56 "Punc. after accepted", 57 "Space after accepted", 58 "Space after picked", 59 "Undo commit" 60 }; 61 62 public static final int STATE_UNKNOWN = 0; 63 public static final int STATE_START = 1; 64 public static final int STATE_IN_WORD = 2; 65 public static final int STATE_ACCEPTED_DEFAULT = 3; 66 public static final int STATE_PICKED_SUGGESTION = 4; 67 public static final int STATE_PUNCTUATION_AFTER_WORD = 5; 68 public static final int STATE_PUNCTUATION_AFTER_ACCEPTED = 6; 69 public static final int STATE_SPACE_AFTER_ACCEPTED = 7; 70 public static final int STATE_SPACE_AFTER_PICKED = 8; 71 public static final int STATE_UNDO_COMMIT = 9; 72 73 private static int sState = STATE_UNKNOWN; 74 75 private static FileOutputStream sKeyLocationFile; 76 private static FileOutputStream sUserActionFile; 77 newSession(Context context)78 public static void newSession(Context context) { 79 sSessionCount++; 80 sAutoSuggestCount = 0; 81 sBackspaceCount = 0; 82 sAutoSuggestUndoneCount = 0; 83 sManualSuggestCount = 0; 84 sWordNotInDictionaryCount = 0; 85 sTypedChars = 0; 86 sActualChars = 0; 87 sState = STATE_START; 88 89 if (LOGGING) { 90 try { 91 sKeyLocationFile = context.openFileOutput("key.txt", Context.MODE_APPEND); 92 sUserActionFile = context.openFileOutput("action.txt", Context.MODE_APPEND); 93 } catch (IOException ioe) { 94 Log.e("TextEntryState", "Couldn't open file for output: " + ioe); 95 } 96 } 97 } 98 endSession()99 public static void endSession() { 100 if (sKeyLocationFile == null) { 101 return; 102 } 103 try { 104 sKeyLocationFile.close(); 105 // Write to log file 106 // Write timestamp, settings, 107 String out = DateFormat.format("MM:dd hh:mm:ss", Calendar.getInstance().getTime()) 108 .toString() 109 + " BS: " + sBackspaceCount 110 + " auto: " + sAutoSuggestCount 111 + " manual: " + sManualSuggestCount 112 + " typed: " + sWordNotInDictionaryCount 113 + " undone: " + sAutoSuggestUndoneCount 114 + " saved: " + ((float) (sActualChars - sTypedChars) / sActualChars) 115 + "\n"; 116 sUserActionFile.write(out.getBytes()); 117 sUserActionFile.close(); 118 sKeyLocationFile = null; 119 sUserActionFile = null; 120 } catch (IOException ioe) { 121 122 } 123 } 124 acceptedDefault(CharSequence typedWord, CharSequence actualWord)125 public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord) { 126 if (!typedWord.equals(actualWord)) { 127 sAutoSuggestCount++; 128 } 129 sTypedChars += typedWord.length(); 130 sActualChars += actualWord.length(); 131 sState = STATE_ACCEPTED_DEFAULT; 132 } 133 acceptedTyped(CharSequence typedWord)134 public static void acceptedTyped(CharSequence typedWord) { 135 sWordNotInDictionaryCount++; 136 sState = STATE_PICKED_SUGGESTION; 137 } 138 acceptedSuggestion(CharSequence typedWord, CharSequence actualWord)139 public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) { 140 sManualSuggestCount++; 141 if (typedWord.equals(actualWord)) { 142 acceptedTyped(typedWord); 143 } 144 sState = STATE_PICKED_SUGGESTION; 145 } 146 typedCharacter(char c, boolean isSeparator)147 public static void typedCharacter(char c, boolean isSeparator) { 148 boolean isSpace = c == ' '; 149 switch (sState) { 150 case STATE_IN_WORD: 151 if (isSpace || isSeparator) { 152 sState = STATE_START; 153 } else { 154 // State hasn't changed. 155 } 156 break; 157 case STATE_ACCEPTED_DEFAULT: 158 case STATE_SPACE_AFTER_PICKED: 159 if (isSpace) { 160 sState = STATE_SPACE_AFTER_ACCEPTED; 161 } else if (isSeparator) { 162 sState = STATE_PUNCTUATION_AFTER_ACCEPTED; 163 } else { 164 sState = STATE_IN_WORD; 165 } 166 break; 167 case STATE_PICKED_SUGGESTION: 168 if (isSpace) { 169 sState = STATE_SPACE_AFTER_PICKED; 170 } else if (isSeparator) { 171 // Swap 172 sState = STATE_PUNCTUATION_AFTER_ACCEPTED; 173 } else { 174 sState = STATE_IN_WORD; 175 } 176 break; 177 case STATE_START: 178 case STATE_UNKNOWN: 179 case STATE_SPACE_AFTER_ACCEPTED: 180 case STATE_PUNCTUATION_AFTER_ACCEPTED: 181 case STATE_PUNCTUATION_AFTER_WORD: 182 if (!isSpace && !isSeparator) { 183 sState = STATE_IN_WORD; 184 } else { 185 sState = STATE_START; 186 } 187 break; 188 case STATE_UNDO_COMMIT: 189 if (isSpace || isSeparator) { 190 sState = STATE_ACCEPTED_DEFAULT; 191 } else { 192 sState = STATE_IN_WORD; 193 } 194 } 195 } 196 backspace()197 public static void backspace() { 198 if (sState == STATE_ACCEPTED_DEFAULT) { 199 sState = STATE_UNDO_COMMIT; 200 sAutoSuggestUndoneCount++; 201 } else if (sState == STATE_UNDO_COMMIT) { 202 sState = STATE_IN_WORD; 203 } 204 sBackspaceCount++; 205 } 206 reset()207 public static void reset() { 208 sState = STATE_START; 209 } 210 getState()211 public static int getState() { 212 return sState; 213 } 214 keyPressedAt(Key key, int x, int y)215 public static void keyPressedAt(Key key, int x, int y) { 216 if (LOGGING && sKeyLocationFile != null && key.codes[0] >= 32) { 217 String out = 218 "KEY: " + (char) key.codes[0] 219 + " X: " + x 220 + " Y: " + y 221 + " MX: " + (key.x + key.width / 2) 222 + " MY: " + (key.y + key.height / 2) 223 + "\n"; 224 try { 225 sKeyLocationFile.write(out.getBytes()); 226 } catch (IOException ioe) { 227 // TODO: May run out of space 228 } 229 } 230 } 231 } 232 233