aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java76
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java86
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLogger.java266
-rw-r--r--java/src/com/android/inputmethod/research/Statistics.java146
4 files changed, 390 insertions, 184 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index f8a6fc884..f3614399a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -891,13 +891,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
}
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_onDisplayCompletions(applicationSpecifiedCompletions);
- }
if (!mCurrentSettings.isApplicationSpecifiedCompletionsOn()) return;
mApplicationSpecifiedCompletions = applicationSpecifiedCompletions;
if (applicationSpecifiedCompletions == null) {
clearSuggestionStrip();
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_onDisplayCompletions(null);
+ }
return;
}
@@ -919,6 +919,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// this case? This says to keep whatever the user typed.
mWordComposer.setAutoCorrection(mWordComposer.getTypedWord());
setSuggestionStripShown(true);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_onDisplayCompletions(applicationSpecifiedCompletions);
+ }
}
private void setSuggestionStripShownInternal(boolean shown, boolean needsInputViewShown) {
@@ -1038,9 +1041,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final CharSequence typedWord = mWordComposer.getTypedWord();
if (typedWord.length() > 0) {
mConnection.commitText(typedWord, 1);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_commitText(typedWord);
- }
final CharSequence prevWord = addToUserHistoryDictionary(typedWord);
mLastComposedWord = mWordComposer.commitWord(
LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, typedWord.toString(),
@@ -1083,12 +1083,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (lastTwo != null && lastTwo.length() == 2
&& lastTwo.charAt(0) == Keyboard.CODE_SPACE) {
mConnection.deleteSurroundingText(2, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(2);
- }
mConnection.commitText(lastTwo.charAt(1) + " ", 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_swapSwapperAndSpaceWhileInBatchEdit();
+ ResearchLogger.latinIME_swapSwapperAndSpace();
}
mKeyboardSwitcher.updateShiftState();
}
@@ -1105,9 +1102,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.cancelDoubleSpacesTimer();
mConnection.deleteSurroundingText(2, 0);
mConnection.commitText(". ", 1);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_doubleSpaceAutoPeriod();
- }
mKeyboardSwitcher.updateShiftState();
return true;
}
@@ -1171,9 +1165,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void performEditorAction(int actionId) {
mConnection.performEditorAction(actionId);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_performEditorAction(actionId);
- }
}
private void handleLanguageSwitchKey() {
@@ -1210,6 +1201,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
if (code >= '0' && code <= '9') {
super.sendKeyChar((char)code);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_sendKeyCodePoint(code);
+ }
return;
}
@@ -1226,9 +1220,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final String text = new String(new int[] { code }, 0, 1);
mConnection.commitText(text, text.length());
}
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_sendKeyCodePoint(code);
- }
}
// Implementation of {@link KeyboardActionListener}.
@@ -1338,9 +1329,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
sendKeyCodePoint(Keyboard.CODE_SPACE);
}
mConnection.commitText(text, 1);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_commitText(text);
- }
mConnection.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
@@ -1435,9 +1423,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// like the smiley key or the .com key.
final int length = mEnteredText.length();
mConnection.deleteSurroundingText(length, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(length);
- }
// If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
// In addition we know that spaceState is false, and that we should not be
// reverting any autocorrect at this point. So we can safely return.
@@ -1457,9 +1442,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.postUpdateSuggestionStrip();
} else {
mConnection.deleteSurroundingText(1, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(1);
- }
}
} else {
if (mLastComposedWord.canRevertCommit()) {
@@ -1488,9 +1470,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final int lengthToDelete = mLastSelectionEnd - mLastSelectionStart;
mConnection.setSelection(mLastSelectionEnd, mLastSelectionEnd);
mConnection.deleteSurroundingText(lengthToDelete, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(lengthToDelete);
- }
} else {
// There is no selection, just delete one character.
if (NOT_A_CURSOR_POSITION == mLastSelectionEnd) {
@@ -1509,14 +1488,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else {
mConnection.deleteSurroundingText(1, 0);
}
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(1);
- }
if (mDeleteCount > DELETE_ACCELERATE_AT) {
mConnection.deleteSurroundingText(1, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(1);
- }
}
}
if (mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) {
@@ -1840,10 +1813,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
+ "is empty? Impossible! I must commit suicide.");
}
Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_commitCurrentAutoCorrection(typedWord,
- autoCorrection.toString());
- }
mExpectingUpdateSelection = true;
commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD,
separatorCodePoint);
@@ -1869,13 +1838,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// So, LatinImeLogger logs "" as a user's input.
LatinImeLogger.logOnManualSuggestion("", suggestion.toString(), index, suggestedWords);
// Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_punctuationSuggestion(index, suggestion, x, y);
- }
final int primaryCode = suggestion.charAt(0);
onCodeInput(primaryCode,
KeyboardActionListener.SUGGESTION_STRIP_COORDINATE,
KeyboardActionListener.SUGGESTION_STRIP_COORDINATE);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_punctuationSuggestion(index, suggestion, x, y);
+ }
return;
}
@@ -1902,10 +1871,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final CompletionInfo completionInfo = mApplicationSpecifiedCompletions[index];
mConnection.commitCompletion(completionInfo);
mConnection.endBatchEdit();
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_pickApplicationSpecifiedCompletion(index,
- completionInfo.getText(), x, y);
- }
return;
}
@@ -1914,12 +1879,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final String replacedWord = mWordComposer.getTypedWord().toString();
LatinImeLogger.logOnManualSuggestion(replacedWord,
suggestion.toString(), index, suggestedWords);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion, x, y);
- }
mExpectingUpdateSelection = true;
commitChosenWord(suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK,
LastComposedWord.NOT_A_SEPARATOR);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion, x, y);
+ }
mConnection.endBatchEdit();
// Don't allow cancellation of manual pick
mLastComposedWord.deactivate();
@@ -1954,9 +1919,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
this, chosenWord, suggestedWords, mIsMainDictionaryAvailable), 1);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_commitText(chosenWord);
- }
// Add the word to the user history dictionary
final CharSequence prevWord = addToUserHistoryDictionary(chosenWord);
// TODO: figure out here if this is an auto-correct or if the best word is actually
@@ -2023,9 +1985,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mWordComposer.setComposingWord(word, mKeyboardSwitcher.getKeyboard());
final int length = word.length();
mConnection.deleteSurroundingText(length, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(length);
- }
mConnection.setComposingText(word, 1);
mHandler.postUpdateSuggestionStrip();
}
@@ -2053,9 +2012,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
mConnection.deleteSurroundingText(deleteLength, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(deleteLength);
- }
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
mUserHistoryDictionary.cancelAddingUserHistory(
previousWord.toString(), committedWord.toString());
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 8b4c17322..41e59e92d 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -55,7 +55,9 @@ public class RichInputConnection {
public void beginBatchEdit() {
if (++mNestLevel == 1) {
mIC = mParent.getCurrentInputConnection();
- if (null != mIC) mIC.beginBatchEdit();
+ if (null != mIC) {
+ mIC.beginBatchEdit();
+ }
} else {
if (DBG) {
throw new RuntimeException("Nest level too deep");
@@ -66,7 +68,9 @@ public class RichInputConnection {
}
public void endBatchEdit() {
if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
- if (--mNestLevel == 0 && null != mIC) mIC.endBatchEdit();
+ if (--mNestLevel == 0 && null != mIC) {
+ mIC.endBatchEdit();
+ }
}
private void checkBatchEdit() {
@@ -79,12 +83,22 @@ public class RichInputConnection {
public void finishComposingText() {
checkBatchEdit();
- if (null != mIC) mIC.finishComposingText();
+ if (null != mIC) {
+ mIC.finishComposingText();
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.richInputConnection_finishComposingText();
+ }
+ }
}
public void commitText(final CharSequence text, final int i) {
checkBatchEdit();
- if (null != mIC) mIC.commitText(text, i);
+ if (null != mIC) {
+ mIC.commitText(text, i);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.richInputConnection_commitText(text, i);
+ }
+ }
}
public int getCursorCapsMode(final int inputType) {
@@ -107,37 +121,72 @@ public class RichInputConnection {
public void deleteSurroundingText(final int i, final int j) {
checkBatchEdit();
- if (null != mIC) mIC.deleteSurroundingText(i, j);
+ if (null != mIC) {
+ mIC.deleteSurroundingText(i, j);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.richInputConnection_deleteSurroundingText(i, j);
+ }
+ }
}
public void performEditorAction(final int actionId) {
mIC = mParent.getCurrentInputConnection();
- if (null != mIC) mIC.performEditorAction(actionId);
+ if (null != mIC) {
+ mIC.performEditorAction(actionId);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.richInputConnection_performEditorAction(actionId);
+ }
+ }
}
public void sendKeyEvent(final KeyEvent keyEvent) {
checkBatchEdit();
- if (null != mIC) mIC.sendKeyEvent(keyEvent);
+ if (null != mIC) {
+ mIC.sendKeyEvent(keyEvent);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.richInputConnection_sendKeyEvent(keyEvent);
+ }
+ }
}
public void setComposingText(final CharSequence text, final int i) {
checkBatchEdit();
- if (null != mIC) mIC.setComposingText(text, i);
+ if (null != mIC) {
+ mIC.setComposingText(text, i);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.richInputConnection_setComposingText(text, i);
+ }
+ }
}
public void setSelection(final int from, final int to) {
checkBatchEdit();
- if (null != mIC) mIC.setSelection(from, to);
+ if (null != mIC) {
+ mIC.setSelection(from, to);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.richInputConnection_setSelection(from, to);
+ }
+ }
}
public void commitCorrection(final CorrectionInfo correctionInfo) {
checkBatchEdit();
- if (null != mIC) mIC.commitCorrection(correctionInfo);
+ if (null != mIC) {
+ mIC.commitCorrection(correctionInfo);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.richInputConnection_commitCorrection(correctionInfo);
+ }
+ }
}
public void commitCompletion(final CompletionInfo completionInfo) {
checkBatchEdit();
- if (null != mIC) mIC.commitCompletion(completionInfo);
+ if (null != mIC) {
+ mIC.commitCompletion(completionInfo);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.richInputConnection_commitCompletion(completionInfo);
+ }
+ }
}
public CharSequence getNthPreviousWord(final String sentenceSeperators, final int n) {
@@ -315,9 +364,6 @@ public class RichInputConnection {
if (lastOne != null && lastOne.length() == 1
&& lastOne.charAt(0) == Keyboard.CODE_SPACE) {
deleteSurroundingText(1, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(1);
- }
}
}
@@ -382,13 +428,7 @@ public class RichInputConnection {
return false;
}
deleteSurroundingText(2, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(2);
- }
commitText(" ", 1);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_revertDoubleSpaceWhileInBatchEdit();
- }
return true;
}
@@ -409,13 +449,7 @@ public class RichInputConnection {
return false;
}
deleteSurroundingText(2, 0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_deleteSurroundingText(2);
- }
commitText(" " + textBeforeCursor.subSequence(0, 1), 1);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_revertSwapPunctuation();
- }
return true;
}
}
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index 68bd98a23..07b8c5995 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -34,15 +34,18 @@ import android.graphics.Paint.Style;
import android.inputmethodservice.InputMethodService;
import android.os.Build;
import android.os.IBinder;
+import android.os.SystemClock;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.Button;
@@ -135,10 +138,12 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
private Dictionary mDictionary;
private KeyboardSwitcher mKeyboardSwitcher;
private InputMethodService mInputMethodService;
+ private final Statistics mStatistics;
private ResearchLogUploader mResearchLogUploader;
private ResearchLogger() {
+ mStatistics = Statistics.getInstance();
}
public static ResearchLogger getInstance() {
@@ -268,10 +273,35 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
return new File(filesDir, sb.toString());
}
+ private void checkForEmptyEditor() {
+ if (mInputMethodService == null) {
+ return;
+ }
+ final InputConnection ic = mInputMethodService.getCurrentInputConnection();
+ if (ic == null) {
+ return;
+ }
+ final CharSequence textBefore = ic.getTextBeforeCursor(1, 0);
+ if (!TextUtils.isEmpty(textBefore)) {
+ mStatistics.setIsEmptyUponStarting(false);
+ return;
+ }
+ final CharSequence textAfter = ic.getTextAfterCursor(1, 0);
+ if (!TextUtils.isEmpty(textAfter)) {
+ mStatistics.setIsEmptyUponStarting(false);
+ return;
+ }
+ if (textBefore != null && textAfter != null) {
+ mStatistics.setIsEmptyUponStarting(true);
+ }
+ }
+
private void start() {
maybeShowSplashScreen();
updateSuspendedState();
requestIndicatorRedraw();
+ mStatistics.reset();
+ checkForEmptyEditor();
if (!isAllowedToLog()) {
// Log.w(TAG, "not in usability mode; not logging");
return;
@@ -295,6 +325,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
}
/* package */ void stop() {
+ logStatistics();
+ publishLogUnit(mCurrentLogUnit, true);
+ mCurrentLogUnit = new LogUnit();
+
if (mMainResearchLog != null) {
mMainResearchLog.stop();
}
@@ -303,6 +337,26 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
}
}
+ private static final String[] EVENTKEYS_STATISTICS = {
+ "Statistics", "charCount", "letterCount", "numberCount", "spaceCount", "deleteOpsCount",
+ "wordCount", "isEmptyUponStarting", "isEmptinessStateKnown", "averageTimeBetweenKeys",
+ "averageTimeBeforeDelete", "averageTimeDuringRepeatedDelete", "averageTimeAfterDelete"
+ };
+ private static void logStatistics() {
+ final ResearchLogger researchLogger = getInstance();
+ final Statistics statistics = researchLogger.mStatistics;
+ final Object[] values = {
+ statistics.mCharCount, statistics.mLetterCount, statistics.mNumberCount,
+ statistics.mSpaceCount, statistics.mDeleteKeyCount,
+ statistics.mWordCount, statistics.mIsEmptyUponStarting,
+ statistics.mIsEmptinessStateKnown, statistics.mKeyCounter.getAverageTime(),
+ statistics.mBeforeDeleteKeyCounter.getAverageTime(),
+ statistics.mDuringRepeatedDeleteKeysCounter.getAverageTime(),
+ statistics.mAfterDeleteKeyCounter.getAverageTime()
+ };
+ researchLogger.enqueueEvent(EVENTKEYS_STATISTICS, values);
+ }
+
private void setLoggingAllowed(boolean enableLogging) {
if (mPrefs == null) {
return;
@@ -703,6 +757,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mLoggingFrequencyState.onWordLogged();
}
mCurrentLogUnit = new LogUnit();
+ mStatistics.recordWordEntered();
}
private void publishLogUnit(LogUnit logUnit, boolean isPrivacySensitive) {
@@ -846,20 +901,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
stop();
}
- private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = {
- "LatinIMECommitText", "typedWord"
- };
-
- public static void latinIME_commitText(final CharSequence typedWord) {
- final String scrubbedWord = scrubDigitsFromString(typedWord.toString());
- final Object[] values = {
- scrubbedWord
- };
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_COMMITTEXT, values);
- researchLogger.onWordComplete(scrubbedWord);
- }
-
private static final String[] EVENTKEYS_USER_FEEDBACK = {
"UserFeedback", "FeedbackContents"
};
@@ -911,48 +952,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final Object[] values = {
Keyboard.printableCode(scrubDigitFromCodePoint(code)), x, y
};
- getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values);
- }
-
- private static final String[] EVENTKEYS_CORRECTION = {
- "LogCorrection", "subgroup", "before", "after", "position"
- };
- public static void logCorrection(final String subgroup, final String before, final String after,
- final int position) {
- final Object[] values = {
- subgroup, scrubDigitsFromString(before), scrubDigitsFromString(after), position
- };
- getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_CORRECTION, values);
- }
-
- private static final String[] EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION = {
- "LatinIMECommitCurrentAutoCorrection", "typedWord", "autoCorrection"
- };
- public static void latinIME_commitCurrentAutoCorrection(final String typedWord,
- final String autoCorrection) {
- final Object[] values = {
- scrubDigitsFromString(typedWord), scrubDigitsFromString(autoCorrection)
- };
final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueuePotentiallyPrivateEvent(
- EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values);
- }
-
- private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = {
- "LatinIMEDeleteSurroundingText", "length"
- };
- public static void latinIME_deleteSurroundingText(final int length) {
- final Object[] values = {
- length
- };
- getInstance().enqueueEvent(EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT, values);
- }
-
- private static final String[] EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD = {
- "LatinIMEDoubleSpaceAutoPeriod"
- };
- public static void latinIME_doubleSpaceAutoPeriod() {
- getInstance().enqueueEvent(EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD, EVENTKEYS_NULLVALUES);
+ researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values);
+ researchLogger.mStatistics.recordChar(code, SystemClock.uptimeMillis());
}
private static final String[] EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS = {
@@ -979,6 +981,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
public static void latinIME_onWindowHidden(final int savedSelectionStart,
final int savedSelectionEnd, final InputConnection ic) {
if (ic != null) {
+ // Capture the TextView contents. This will trigger onUpdateSelection(), so we
+ // set sLatinIMEExpectingUpdateSelection so that when onUpdateSelection() is called,
+ // it can tell that it was generated by the logging code, and not by the user, and
+ // therefore keep user-visible state as is.
ic.beginBatchEdit();
ic.performContextMenuAction(android.R.id.selectAll);
CharSequence charSequence = ic.getSelectedText(0);
@@ -1048,29 +1054,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONUPDATESELECTION, values);
}
- private static final String[] EVENTKEYS_LATINIME_PERFORMEDITORACTION = {
- "LatinIMEPerformEditorAction", "imeActionNext"
- };
- public static void latinIME_performEditorAction(final int imeActionNext) {
- final Object[] values = {
- imeActionNext
- };
- getInstance().enqueueEvent(EVENTKEYS_LATINIME_PERFORMEDITORACTION, values);
- }
-
- private static final String[] EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION = {
- "LatinIMEPickApplicationSpecifiedCompletion", "index", "text", "x", "y"
- };
- public static void latinIME_pickApplicationSpecifiedCompletion(final int index,
- final CharSequence cs, int x, int y) {
- final Object[] values = {
- index, cs, x, y
- };
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueuePotentiallyPrivateEvent(
- EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values);
- }
-
private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = {
"LatinIMEPickSuggestionManually", "replacedWord", "index", "suggestion", "x", "y"
};
@@ -1096,21 +1079,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
getInstance().enqueueEvent(EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION, values);
}
- private static final String[] EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT = {
- "LatinIMERevertDoubleSpaceWhileInBatchEdit"
- };
- public static void latinIME_revertDoubleSpaceWhileInBatchEdit() {
- getInstance().enqueueEvent(EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT,
- EVENTKEYS_NULLVALUES);
- }
-
- private static final String[] EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION = {
- "LatinIMERevertSwapPunctuation"
- };
- public static void latinIME_revertSwapPunctuation() {
- getInstance().enqueueEvent(EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION, EVENTKEYS_NULLVALUES);
- }
-
private static final String[] EVENTKEYS_LATINIME_SENDKEYCODEPOINT = {
"LatinIMESendKeyCodePoint", "code"
};
@@ -1121,12 +1089,11 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_SENDKEYCODEPOINT, values);
}
- private static final String[] EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT = {
- "LatinIMESwapSwapperAndSpaceWhileInBatchEdit"
+ private static final String[] EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACE = {
+ "LatinIMESwapSwapperAndSpace"
};
- public static void latinIME_swapSwapperAndSpaceWhileInBatchEdit() {
- getInstance().enqueueEvent(EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT,
- EVENTKEYS_NULLVALUES);
+ public static void latinIME_swapSwapperAndSpace() {
+ getInstance().enqueueEvent(EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACE, EVENTKEYS_NULLVALUES);
}
private static final String[] EVENTKEYS_MAINKEYBOARDVIEW_ONLONGPRESS = {
@@ -1245,6 +1212,109 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_POINTERTRACKER_ONMOVEEVENT, values);
}
+ private static final String[] EVENTKEYS_RICHINPUTCONNECTION_COMMITCOMPLETION = {
+ "RichInputConnectionCommitCompletion", "completionInfo"
+ };
+ public static void richInputConnection_commitCompletion(final CompletionInfo completionInfo) {
+ final Object[] values = {
+ completionInfo
+ };
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.enqueuePotentiallyPrivateEvent(
+ EVENTKEYS_RICHINPUTCONNECTION_COMMITCOMPLETION, values);
+ }
+
+ private static final String[] EVENTKEYS_RICHINPUTCONNECTION_COMMITCORRECTION = {
+ "RichInputConnectionCommitCorrection", "CorrectionInfo"
+ };
+ public static void richInputConnection_commitCorrection(CorrectionInfo correctionInfo) {
+ final String typedWord = correctionInfo.getOldText().toString();
+ final String autoCorrection = correctionInfo.getNewText().toString();
+ final Object[] values = {
+ scrubDigitsFromString(typedWord), scrubDigitsFromString(autoCorrection)
+ };
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.enqueuePotentiallyPrivateEvent(
+ EVENTKEYS_RICHINPUTCONNECTION_COMMITCORRECTION, values);
+ }
+
+ private static final String[] EVENTKEYS_RICHINPUTCONNECTION_COMMITTEXT = {
+ "RichInputConnectionCommitText", "typedWord", "newCursorPosition"
+ };
+ public static void richInputConnection_commitText(final CharSequence typedWord,
+ final int newCursorPosition) {
+ final String scrubbedWord = scrubDigitsFromString(typedWord.toString());
+ final Object[] values = {
+ scrubbedWord, newCursorPosition
+ };
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_RICHINPUTCONNECTION_COMMITTEXT,
+ values);
+ researchLogger.onWordComplete(scrubbedWord);
+ }
+
+ private static final String[] EVENTKEYS_RICHINPUTCONNECTION_DELETESURROUNDINGTEXT = {
+ "RichInputConnectionDeleteSurroundingText", "beforeLength", "afterLength"
+ };
+ public static void richInputConnection_deleteSurroundingText(final int beforeLength,
+ final int afterLength) {
+ final Object[] values = {
+ beforeLength, afterLength
+ };
+ getInstance().enqueueEvent(EVENTKEYS_RICHINPUTCONNECTION_DELETESURROUNDINGTEXT, values);
+ }
+
+ private static final String[] EVENTKEYS_RICHINPUTCONNECTION_FINISHCOMPOSINGTEXT = {
+ "RichInputConnectionFinishComposingText"
+ };
+ public static void richInputConnection_finishComposingText() {
+ getInstance().enqueueEvent(EVENTKEYS_RICHINPUTCONNECTION_FINISHCOMPOSINGTEXT,
+ EVENTKEYS_NULLVALUES);
+ }
+
+ private static final String[] EVENTKEYS_RICHINPUTCONNECTION_PERFORMEDITORACTION = {
+ "RichInputConnectionPerformEditorAction", "imeActionNext"
+ };
+ public static void richInputConnection_performEditorAction(final int imeActionNext) {
+ final Object[] values = {
+ imeActionNext
+ };
+ getInstance().enqueueEvent(EVENTKEYS_RICHINPUTCONNECTION_PERFORMEDITORACTION, values);
+ }
+
+ private static final String[] EVENTKEYS_RICHINPUTCONNECTION_SENDKEYEVENT = {
+ "RichInputConnectionSendKeyEvent", "eventTime", "action", "code"
+ };
+ public static void richInputConnection_sendKeyEvent(final KeyEvent keyEvent) {
+ final Object[] values = {
+ keyEvent.getEventTime(),
+ keyEvent.getAction(),
+ keyEvent.getKeyCode()
+ };
+ getInstance().enqueueEvent(EVENTKEYS_RICHINPUTCONNECTION_SENDKEYEVENT, values);
+ }
+
+ private static final String[] EVENTKEYS_RICHINPUTCONNECTION_SETCOMPOSINGTEXT = {
+ "RichInputConnectionSetComposingText", "text", "newCursorPosition"
+ };
+ public static void richInputConnection_setComposingText(final CharSequence text,
+ final int newCursorPosition) {
+ final Object[] values = {
+ text, newCursorPosition
+ };
+ getInstance().enqueueEvent(EVENTKEYS_RICHINPUTCONNECTION_SETCOMPOSINGTEXT, values);
+ }
+
+ private static final String[] EVENTKEYS_RICHINPUTCONNECTION_SETSELECTION = {
+ "RichInputConnectionSetSelection", "from", "to"
+ };
+ public static void richInputConnection_setSelection(final int from, final int to) {
+ final Object[] values = {
+ from, to
+ };
+ getInstance().enqueueEvent(EVENTKEYS_RICHINPUTCONNECTION_SETSELECTION, values);
+ }
+
private static final String[] EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT = {
"SuddenJumpingTouchEventHandlerOnTouchEvent", "motionEvent"
};
diff --git a/java/src/com/android/inputmethod/research/Statistics.java b/java/src/com/android/inputmethod/research/Statistics.java
new file mode 100644
index 000000000..4a2cd079c
--- /dev/null
+++ b/java/src/com/android/inputmethod/research/Statistics.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2012 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.research;
+
+import com.android.inputmethod.keyboard.Keyboard;
+
+public class Statistics {
+ // Number of characters entered during a typing session
+ int mCharCount;
+ // Number of letter characters entered during a typing session
+ int mLetterCount;
+ // Number of number characters entered
+ int mNumberCount;
+ // Number of space characters entered
+ int mSpaceCount;
+ // Number of delete operations entered (taps on the backspace key)
+ int mDeleteKeyCount;
+ // Number of words entered during a session.
+ int mWordCount;
+ // Whether the text field was empty upon editing
+ boolean mIsEmptyUponStarting;
+ boolean mIsEmptinessStateKnown;
+
+ // Timers to count average time to enter a key, first press a delete key,
+ // between delete keys, and then to return typing after a delete key.
+ final AverageTimeCounter mKeyCounter = new AverageTimeCounter();
+ final AverageTimeCounter mBeforeDeleteKeyCounter = new AverageTimeCounter();
+ final AverageTimeCounter mDuringRepeatedDeleteKeysCounter = new AverageTimeCounter();
+ final AverageTimeCounter mAfterDeleteKeyCounter = new AverageTimeCounter();
+
+ static class AverageTimeCounter {
+ int mCount;
+ int mTotalTime;
+
+ public void reset() {
+ mCount = 0;
+ mTotalTime = 0;
+ }
+
+ public void add(long deltaTime) {
+ mCount++;
+ mTotalTime += deltaTime;
+ }
+
+ public int getAverageTime() {
+ if (mCount == 0) {
+ return 0;
+ }
+ return mTotalTime / mCount;
+ }
+ }
+
+ // To account for the interruptions when the user's attention is directed elsewhere, times
+ // longer than MIN_TYPING_INTERMISSION are not counted when estimating this statistic.
+ public static final int MIN_TYPING_INTERMISSION = 5 * 1000; // in milliseconds
+ public static final int MIN_DELETION_INTERMISSION = 15 * 1000; // in milliseconds
+
+ // The last time that a tap was performed
+ private long mLastTapTime;
+ // The type of the last keypress (delete key or not)
+ boolean mIsLastKeyDeleteKey;
+
+ private static final Statistics sInstance = new Statistics();
+
+ public static Statistics getInstance() {
+ return sInstance;
+ }
+
+ private Statistics() {
+ reset();
+ }
+
+ public void reset() {
+ mCharCount = 0;
+ mLetterCount = 0;
+ mNumberCount = 0;
+ mSpaceCount = 0;
+ mDeleteKeyCount = 0;
+ mWordCount = 0;
+ mIsEmptyUponStarting = true;
+ mIsEmptinessStateKnown = false;
+ mKeyCounter.reset();
+ mBeforeDeleteKeyCounter.reset();
+ mDuringRepeatedDeleteKeysCounter.reset();
+ mAfterDeleteKeyCounter.reset();
+
+ mLastTapTime = 0;
+ mIsLastKeyDeleteKey = false;
+ }
+
+ public void recordChar(int codePoint, long time) {
+ final long delta = time - mLastTapTime;
+ if (codePoint == Keyboard.CODE_DELETE) {
+ mDeleteKeyCount++;
+ if (delta < MIN_DELETION_INTERMISSION) {
+ if (mIsLastKeyDeleteKey) {
+ mDuringRepeatedDeleteKeysCounter.add(delta);
+ } else {
+ mBeforeDeleteKeyCounter.add(delta);
+ }
+ }
+ mIsLastKeyDeleteKey = true;
+ } else {
+ mCharCount++;
+ if (Character.isDigit(codePoint)) {
+ mNumberCount++;
+ }
+ if (Character.isLetter(codePoint)) {
+ mLetterCount++;
+ }
+ if (Character.isSpaceChar(codePoint)) {
+ mSpaceCount++;
+ }
+ if (mIsLastKeyDeleteKey && delta < MIN_DELETION_INTERMISSION) {
+ mAfterDeleteKeyCounter.add(delta);
+ } else if (!mIsLastKeyDeleteKey && delta < MIN_TYPING_INTERMISSION) {
+ mKeyCounter.add(delta);
+ }
+ mIsLastKeyDeleteKey = false;
+ }
+ mLastTapTime = time;
+ }
+
+ public void recordWordEntered() {
+ mWordCount++;
+ }
+
+ public void setIsEmptyUponStarting(final boolean isEmpty) {
+ mIsEmptyUponStarting = isEmpty;
+ mIsEmptinessStateKnown = true;
+ }
+}