[Rlog78a] Annotate logUnits with corrections

If the user makes a correction to a word, this is now explicitly indicated
in the logUnit.

Change-Id: I8638aadd7b8c8e32bbc9c4b020548d786513d887
diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java
index cfba289..70bbf9d 100644
--- a/java/src/com/android/inputmethod/research/LogUnit.java
+++ b/java/src/com/android/inputmethod/research/LogUnit.java
@@ -60,6 +60,7 @@
     private String mWord;
     private boolean mMayContainDigit;
     private boolean mIsPartOfMegaword;
+    private boolean mContainsCorrection;
 
     public LogUnit() {
         mLogStatementList = new ArrayList<LogStatement>();
@@ -274,6 +275,14 @@
         return mMayContainDigit;
     }
 
+    public void setContainsCorrection() {
+        mContainsCorrection = true;
+    }
+
+    public boolean containsCorrection() {
+        return mContainsCorrection;
+    }
+
     public boolean isEmpty() {
         return mLogStatementList.isEmpty();
     }
@@ -301,6 +310,7 @@
                         true /* isPartOfMegaword */);
                 newLogUnit.mWord = null;
                 newLogUnit.mMayContainDigit = mMayContainDigit;
+                newLogUnit.mContainsCorrection = mContainsCorrection;
 
                 // Purge the logStatements and associated data from this LogUnit.
                 laterLogStatements.clear();
@@ -320,6 +330,7 @@
         mTimeList.addAll(logUnit.mTimeList);
         mWord = null;
         mMayContainDigit = mMayContainDigit || logUnit.mMayContainDigit;
+        mContainsCorrection = mContainsCorrection || logUnit.mContainsCorrection;
         mIsPartOfMegaword = false;
     }
 }
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index a2bcf44..a46216c 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -720,6 +720,10 @@
         mCurrentLogUnit.setMayContainDigit();
     }
 
+    private void setCurrentLogUnitContainsCorrection() {
+        mCurrentLogUnit.setContainsCorrection();
+    }
+
     /* package for test */ void commitCurrentLogUnit() {
         if (DEBUG) {
             Log.d(TAG, "commitCurrentLogUnit" + (mCurrentLogUnit.hasWord() ?
@@ -850,7 +854,7 @@
             mCurrentLogUnit.setWord(word);
             final boolean isDictionaryWord = dictionary != null
                     && dictionary.isValidWord(word);
-            mStatistics.recordWordEntered(isDictionaryWord);
+            mStatistics.recordWordEntered(isDictionaryWord, mCurrentLogUnit.containsCorrection());
         }
         final LogUnit newLogUnit = mCurrentLogUnit.splitByTime(maxTime);
         enqueueCommitText(word, isBatchMode);
@@ -1181,6 +1185,7 @@
                 scrubDigitsFromString(replacedWord), index,
                 suggestion == null ? null : scrubbedWord, Constants.SUGGESTION_STRIP_COORDINATE,
                 Constants.SUGGESTION_STRIP_COORDINATE);
+        researchLogger.setCurrentLogUnitContainsCorrection();
         researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, Long.MAX_VALUE, isBatchMode);
         researchLogger.mStatistics.recordManualSuggestion(SystemClock.uptimeMillis());
     }
@@ -1340,6 +1345,9 @@
         researchLogger.enqueueEvent(logUnit != null ? logUnit : researchLogger.mCurrentLogUnit,
                 LOGSTATEMENT_LATINIME_REVERTCOMMIT, committedWord, originallyTypedWord,
                 separatorString);
+        if (logUnit != null) {
+            logUnit.setContainsCorrection();
+        }
         researchLogger.mStatistics.recordRevertCommit(SystemClock.uptimeMillis());
         researchLogger.commitCurrentLogUnitAsWord(originallyTypedWord, Long.MAX_VALUE, isBatchMode);
     }
@@ -1500,6 +1508,7 @@
         final ResearchLogger researchLogger = getInstance();
         final String scrubbedWord = scrubDigitsFromString(committedWord);
         researchLogger.enqueueEvent(LOGSTATEMENT_COMMIT_PARTIAL_TEXT);
+        researchLogger.mStatistics.recordAutoCorrection(SystemClock.uptimeMillis());
         researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, lastTimestampOfWordData,
                 isBatchMode);
     }
@@ -1740,7 +1749,7 @@
                     "averageTimeDuringRepeatedDelete", "averageTimeAfterDelete",
                     "dictionaryWordCount", "splitWordsCount", "gestureInputCount",
                     "gestureCharsCount", "gesturesDeletedCount", "manualSuggestionsCount",
-                    "revertCommitsCount");
+                    "revertCommitsCount", "correctedWordsCount", "autoCorrectionsCount");
     private static void logStatistics() {
         final ResearchLogger researchLogger = getInstance();
         final Statistics statistics = researchLogger.mStatistics;
@@ -1754,6 +1763,7 @@
                 statistics.mDictionaryWordCount, statistics.mSplitWordsCount,
                 statistics.mGesturesInputCount, statistics.mGesturesCharsCount,
                 statistics.mGesturesDeletedCount, statistics.mManualSuggestionsCount,
-                statistics.mRevertCommitsCount);
+                statistics.mRevertCommitsCount, statistics.mCorrectedWordsCount,
+                statistics.mAutoCorrectionsCount);
     }
 }
diff --git a/java/src/com/android/inputmethod/research/Statistics.java b/java/src/com/android/inputmethod/research/Statistics.java
index a920265..f0cb157 100644
--- a/java/src/com/android/inputmethod/research/Statistics.java
+++ b/java/src/com/android/inputmethod/research/Statistics.java
@@ -25,6 +25,7 @@
     private static final String TAG = Statistics.class.getSimpleName();
     private static final boolean DEBUG = false && ProductionFlag.IS_EXPERIMENTAL_DEBUG;
 
+    // TODO: Cleanup comments to only including those giving meaningful information.
     // Number of characters entered during a typing session
     int mCharCount;
     // Number of letter characters entered during a typing session
@@ -41,6 +42,8 @@
     int mDictionaryWordCount;
     // Number of words split and spaces automatically entered.
     int mSplitWordsCount;
+    // Number of words entered during a session.
+    int mCorrectedWordsCount;
     // Number of gestures that were input.
     int mGesturesInputCount;
     // Number of gestures that were deleted.
@@ -49,6 +52,8 @@
     int mGesturesCharsCount;
     // Number of manual suggestions chosen.
     int mManualSuggestionsCount;
+    // Number of times that autocorrection was invoked.
+    int mAutoCorrectionsCount;
     // Number of times a commit was reverted in this session.
     int mRevertCommitsCount;
     // Whether the text field was empty upon editing
@@ -113,10 +118,12 @@
         mWordCount = 0;
         mDictionaryWordCount = 0;
         mSplitWordsCount = 0;
+        mCorrectedWordsCount = 0;
         mGesturesInputCount = 0;
         mGesturesDeletedCount = 0;
         mManualSuggestionsCount = 0;
         mRevertCommitsCount = 0;
+        mAutoCorrectionsCount = 0;
         mIsEmptyUponStarting = true;
         mIsEmptinessStateKnown = false;
         mKeyCounter.reset();
@@ -152,11 +159,15 @@
         }
     }
 
-    public void recordWordEntered(final boolean isDictionaryWord) {
+    public void recordWordEntered(final boolean isDictionaryWord,
+            final boolean containsCorrection) {
         mWordCount++;
         if (isDictionaryWord) {
             mDictionaryWordCount++;
         }
+        if (containsCorrection) {
+            mCorrectedWordsCount++;
+        }
     }
 
     public void recordSplitWords() {
@@ -184,6 +195,11 @@
         recordUserAction(time, false /* isDeletion */);
     }
 
+    public void recordAutoCorrection(final long time) {
+        mAutoCorrectionsCount++;
+        recordUserAction(time, false /* isDeletion */);
+    }
+
     public void recordRevertCommit(final long time) {
         mRevertCommitsCount++;
         recordUserAction(time, true /* isDeletion */);