diff options
Diffstat (limited to 'java/src/com/android/inputmethod/research')
3 files changed, 150 insertions, 50 deletions
diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java index 7b45ff175..cfba28909 100644 --- a/java/src/com/android/inputmethod/research/LogUnit.java +++ b/java/src/com/android/inputmethod/research/LogUnit.java @@ -133,7 +133,7 @@ import java.util.Map; // will not have been opened for writing. if (jsonWriter == null) { jsonWriter = researchLog.getValidJsonWriterLocked(); - outputLogUnitStart(jsonWriter); + outputLogUnitStart(jsonWriter, isIncludingPrivateData); } outputLogStatementToLocked(jsonWriter, mLogStatementList.get(i), mValuesList.get(i), mTimeList.get(i)); @@ -169,11 +169,14 @@ import java.util.Map; private static final String LOG_UNIT_BEGIN_KEY = "logUnitStart"; private static final String LOG_UNIT_END_KEY = "logUnitEnd"; - private void outputLogUnitStart(final JsonWriter jsonWriter) { + private void outputLogUnitStart(final JsonWriter jsonWriter, + final boolean isIncludingPrivateData) { try { jsonWriter.beginObject(); jsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis()); - jsonWriter.name(WORD_KEY).value(getWord()); + if (isIncludingPrivateData) { + jsonWriter.name(WORD_KEY).value(getWord()); + } jsonWriter.name(EVENT_TYPE_KEY).value(LOG_UNIT_BEGIN_KEY); jsonWriter.endObject(); } catch (IOException e) { diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java index f609a2710..8b6bff495 100644 --- a/java/src/com/android/inputmethod/research/ResearchLogger.java +++ b/java/src/com/android/inputmethod/research/ResearchLogger.java @@ -741,6 +741,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } } + private static final LogStatement LOGSTATEMENT_UNCOMMIT_CURRENT_LOGUNIT = + new LogStatement("UncommitCurrentLogUnit", false, false); public void uncommitCurrentLogUnit(final String expectedWord, final boolean dumpCurrentLogUnit) { // The user has deleted this word and returned to the previous. Check that the word in the @@ -779,6 +781,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang if (mFeedbackLogBuffer != null) { mFeedbackLogBuffer.unshiftIn(); } + enqueueEvent(LOGSTATEMENT_UNCOMMIT_CURRENT_LOGUNIT); if (DEBUG) { Log.d(TAG, "uncommitCurrentLogUnit (dump=" + dumpCurrentLogUnit + ") back to " + (mCurrentLogUnit.hasWord() ? ": '" + mCurrentLogUnit.getWord() + "'" : "")); @@ -849,6 +852,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang mCurrentLogUnit = newLogUnit; } + private void setSavedDownEventTime(final long time) { + mSavedDownEventTime = time; + } + public void onWordFinished(final String word, final boolean isBatchMode) { commitCurrentLogUnitAsWord(word, mSavedDownEventTime, isBatchMode); mSavedDownEventTime = Long.MAX_VALUE; @@ -998,7 +1005,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang if (action == MotionEvent.ACTION_DOWN) { // Subtract 1 from eventTime so the down event is included in the later // LogUnit, not the earlier (the test is for inequality). - researchLogger.mSavedDownEventTime = eventTime - 1; + researchLogger.setSavedDownEventTime(eventTime - 1); } } } @@ -1164,7 +1171,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang suggestion == null ? null : scrubbedWord, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE); researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, Long.MAX_VALUE, isBatchMode); - researchLogger.mStatistics.recordManualSuggestion(); + researchLogger.mStatistics.recordManualSuggestion(SystemClock.uptimeMillis()); } /** @@ -1174,21 +1181,21 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang */ private static final LogStatement LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION = new LogStatement("LatinIMEPunctuationSuggestion", false, false, "index", "suggestion", - "x", "y"); + "x", "y", "isPrediction"); public static void latinIME_punctuationSuggestion(final int index, final String suggestion, - final boolean isBatchMode) { + final boolean isBatchMode, final boolean isPrediction) { final ResearchLogger researchLogger = getInstance(); researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION, index, suggestion, - Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE); + Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, + isPrediction); researchLogger.commitCurrentLogUnitAsWord(suggestion, Long.MAX_VALUE, isBatchMode); } /** * Log a call to LatinIME.sendKeyCodePoint(). * - * SystemResponse: The IME is simulating a hardware keypress. This happens for numbers; other - * input typically goes through RichInputConnection.setComposingText() and - * RichInputConnection.commitText(). + * SystemResponse: The IME is inserting text into the TextView for numbers, fixed strings, or + * some other unusual mechanism. */ private static final LogStatement LOGSTATEMENT_LATINIME_SENDKEYCODEPOINT = new LogStatement("LatinIMESendKeyCodePoint", true, false, "code"); @@ -1202,6 +1209,24 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } /** + * Log a call to LatinIME.promotePhantomSpace(). + * + * SystemResponse: The IME is inserting a real space in place of a phantom space. + */ + private static final LogStatement LOGSTATEMENT_LATINIME_PROMOTEPHANTOMSPACE = + new LogStatement("LatinIMEPromotPhantomSpace", false, false); + public static void latinIME_promotePhantomSpace() { + final ResearchLogger researchLogger = getInstance(); + final LogUnit logUnit; + if (researchLogger.mMainLogBuffer == null) { + logUnit = researchLogger.mCurrentLogUnit; + } else { + logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit(); + } + researchLogger.enqueueEvent(logUnit, LOGSTATEMENT_LATINIME_PROMOTEPHANTOMSPACE); + } + + /** * Log a call to LatinIME.swapSwapperAndSpace(). * * SystemResponse: A symbol has been swapped with a space character. E.g. punctuation may swap @@ -1213,7 +1238,12 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang public static void latinIME_swapSwapperAndSpace(final CharSequence originalCharacters, final String charactersAfterSwap) { final ResearchLogger researchLogger = getInstance(); - final LogUnit logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit(); + final LogUnit logUnit; + if (researchLogger.mMainLogBuffer == null) { + logUnit = null; + } else { + logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit(); + } if (logUnit != null) { researchLogger.enqueueEvent(logUnit, LOGSTATEMENT_LATINIME_SWAPSWAPPERANDSPACE, originalCharacters, charactersAfterSwap); @@ -1258,8 +1288,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang public static void mainKeyboardView_setKeyboard(final Keyboard keyboard) { final KeyboardId kid = keyboard.mId; final boolean isPasswordView = kid.passwordInput(); - getInstance().setIsPasswordView(isPasswordView); - getInstance().enqueueEvent(LOGSTATEMENT_MAINKEYBOARDVIEW_SETKEYBOARD, + final ResearchLogger researchLogger = getInstance(); + researchLogger.setIsPasswordView(isPasswordView); + researchLogger.enqueueEvent(LOGSTATEMENT_MAINKEYBOARDVIEW_SETKEYBOARD, KeyboardId.elementIdToName(kid.mElementId), kid.mLocale + ":" + kid.mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), kid.mOrientation, kid.mWidth, KeyboardId.modeName(kid.mMode), kid.imeAction(), @@ -1278,22 +1309,27 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang */ private static final LogStatement LOGSTATEMENT_LATINIME_REVERTCOMMIT = new LogStatement("LatinIMERevertCommit", true, false, "committedWord", - "originallyTypedWord"); + "originallyTypedWord", "separatorString"); public static void latinIME_revertCommit(final String committedWord, - final String originallyTypedWord, final boolean isBatchMode) { + final String originallyTypedWord, final boolean isBatchMode, + final String separatorString) { final ResearchLogger researchLogger = getInstance(); - // Assume that mCurrentLogUnit has been restored to contain the reverted word. - final LogUnit logUnit = researchLogger.mCurrentLogUnit; + // TODO: Verify that mCurrentLogUnit has been restored and contains the reverted word. + final LogUnit logUnit; + if (researchLogger.mMainLogBuffer == null) { + logUnit = null; + } else { + logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit(); + } if (originallyTypedWord.length() > 0 && hasLetters(originallyTypedWord)) { if (logUnit != null) { - // Probably not necessary, but setting as a precaution in case the word isn't - // committed later. logUnit.setWord(originallyTypedWord); } } researchLogger.enqueueEvent(logUnit != null ? logUnit : researchLogger.mCurrentLogUnit, - LOGSTATEMENT_LATINIME_REVERTCOMMIT, committedWord, originallyTypedWord); - researchLogger.mStatistics.recordRevertCommit(); + LOGSTATEMENT_LATINIME_REVERTCOMMIT, committedWord, originallyTypedWord, + separatorString); + researchLogger.mStatistics.recordRevertCommit(SystemClock.uptimeMillis()); researchLogger.commitCurrentLogUnitAsWord(originallyTypedWord, Long.MAX_VALUE, isBatchMode); } @@ -1424,10 +1460,17 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang final String scrubbedTypedWord = scrubDigitsFromString(typedWord); final String scrubbedAutoCorrection = scrubDigitsFromString(autoCorrection); final ResearchLogger researchLogger = getInstance(); - researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_COMMITCURRENTAUTOCORRECTION, - scrubbedTypedWord, scrubbedAutoCorrection, separatorString); researchLogger.commitCurrentLogUnitAsWord(scrubbedAutoCorrection, Long.MAX_VALUE, isBatchMode); + + // Add the autocorrection logStatement at the end of the logUnit for the committed word. + // We have to do this after calling commitCurrentLogUnitAsWord, because it may split the + // current logUnit, and then we have to peek to get the logUnit reference back. + final LogUnit logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit(); + // TODO: Add test to confirm that the commitCurrentAutoCorrection log statement should + // always be added to logUnit (if non-null) and not mCurrentLogUnit. + researchLogger.enqueueEvent(logUnit, LOGSTATEMENT_LATINIME_COMMITCURRENTAUTOCORRECTION, + scrubbedTypedWord, scrubbedAutoCorrection, separatorString); } private boolean isExpectingCommitText = false; @@ -1616,20 +1659,58 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang final ResearchLogger researchLogger = getInstance(); researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_ONENDBATCHINPUT, enteredText, enteredWordPos); - researchLogger.mStatistics.recordGestureInput(enteredText.length()); + researchLogger.mStatistics.recordGestureInput(enteredText.length(), + SystemClock.uptimeMillis()); + } + + /** + * Log a call to LatinIME.handleBackspace() that is not a batch delete. + * + * UserInput: The user is deleting one or more characters by hitting the backspace key once. + * The covers single character deletes as well as deleting selections. + */ + private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE = + new LogStatement("LatinIMEHandleBackspace", true, false, "numCharacters"); + public static void latinIME_handleBackspace(final int numCharacters) { + final ResearchLogger researchLogger = getInstance(); + researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE, numCharacters); } /** - * Log a call to LatinIME.handleBackspace(). + * Log a call to LatinIME.handleBackspace() that is a batch delete. * * UserInput: The user is deleting a gestured word by hitting the backspace key once. */ private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE_BATCH = - new LogStatement("LatinIMEHandleBackspaceBatch", true, false, "deletedText"); - public static void latinIME_handleBackspace_batch(final CharSequence deletedText) { + new LogStatement("LatinIMEHandleBackspaceBatch", true, false, "deletedText", + "numCharacters"); + public static void latinIME_handleBackspace_batch(final CharSequence deletedText, + final int numCharacters) { final ResearchLogger researchLogger = getInstance(); - researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE_BATCH, deletedText); - researchLogger.mStatistics.recordGestureDelete(); + researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE_BATCH, deletedText, + numCharacters); + researchLogger.mStatistics.recordGestureDelete(deletedText.length(), + SystemClock.uptimeMillis()); + } + + /** + * Log a long interval between user operation. + * + * UserInput: The user has not done anything for a while. + */ + private static final LogStatement LOGSTATEMENT_ONUSERPAUSE = new LogStatement("OnUserPause", + false, false, "intervalInMs"); + public static void onUserPause(final long interval) { + final ResearchLogger researchLogger = getInstance(); + researchLogger.enqueueEvent(LOGSTATEMENT_ONUSERPAUSE, interval); + } + + public static void latinIME_handleSeparator() { + // Reset the saved down event time. For tapping, motion events, etc. before the separator + // are assigned to the previous LogUnit, and events after the separator are assigned to the + // next LogUnit. In the case of multitap, this might capture down events corresponding to + // the next word, however it should not be more than a character or two. + getInstance().setSavedDownEventTime(SystemClock.uptimeMillis()); } /** diff --git a/java/src/com/android/inputmethod/research/Statistics.java b/java/src/com/android/inputmethod/research/Statistics.java index e9c02c919..a9202651e 100644 --- a/java/src/com/android/inputmethod/research/Statistics.java +++ b/java/src/com/android/inputmethod/research/Statistics.java @@ -134,17 +134,9 @@ public class Statistics { if (DEBUG) { Log.d(TAG, "recordChar() called"); } - final long delta = time - mLastTapTime; if (codePoint == Constants.CODE_DELETE) { mDeleteKeyCount++; - if (delta < MIN_DELETION_INTERMISSION) { - if (mIsLastKeyDeleteKey) { - mDuringRepeatedDeleteKeysCounter.add(delta); - } else { - mBeforeDeleteKeyCounter.add(delta); - } - } - mIsLastKeyDeleteKey = true; + recordUserAction(time, true /* isDeletion */); } else { mCharCount++; if (Character.isDigit(codePoint)) { @@ -156,14 +148,8 @@ public class Statistics { 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; + recordUserAction(time, false /* isDeletion */); } - mLastTapTime = time; } public void recordWordEntered(final boolean isDictionaryWord) { @@ -177,9 +163,10 @@ public class Statistics { mSplitWordsCount++; } - public void recordGestureInput(final int numCharsEntered) { + public void recordGestureInput(final int numCharsEntered, final long time) { mGesturesInputCount++; mGesturesCharsCount += numCharsEntered; + recordUserAction(time, false /* isDeletion */); } public void setIsEmptyUponStarting(final boolean isEmpty) { @@ -187,14 +174,43 @@ public class Statistics { mIsEmptinessStateKnown = true; } - public void recordGestureDelete() { + public void recordGestureDelete(final int length, final long time) { mGesturesDeletedCount++; + recordUserAction(time, true /* isDeletion */); } - public void recordManualSuggestion() { + + public void recordManualSuggestion(final long time) { mManualSuggestionsCount++; + recordUserAction(time, false /* isDeletion */); } - public void recordRevertCommit() { + public void recordRevertCommit(final long time) { mRevertCommitsCount++; + recordUserAction(time, true /* isDeletion */); + } + + private void recordUserAction(final long time, final boolean isDeletion) { + final long delta = time - mLastTapTime; + if (isDeletion) { + if (delta < MIN_DELETION_INTERMISSION) { + if (mIsLastKeyDeleteKey) { + mDuringRepeatedDeleteKeysCounter.add(delta); + } else { + mBeforeDeleteKeyCounter.add(delta); + } + } else { + ResearchLogger.onUserPause(delta); + } + } else { + if (mIsLastKeyDeleteKey && delta < MIN_DELETION_INTERMISSION) { + mAfterDeleteKeyCounter.add(delta); + } else if (!mIsLastKeyDeleteKey && delta < MIN_TYPING_INTERMISSION) { + mKeyCounter.add(delta); + } else { + ResearchLogger.onUserPause(delta); + } + } + mIsLastKeyDeleteKey = isDeletion; + mLastTapTime = time; } } |