Merge "[Rlog3] improve stat recording"

main
Kurt Partridge 2012-12-18 09:54:04 -08:00 committed by Android (Google) Code Review
commit 8432c1317a
4 changed files with 58 additions and 28 deletions

View File

@ -1628,6 +1628,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mConnection.setComposingText(batchInputText, 1); mConnection.setComposingText(batchInputText, 1);
mExpectingUpdateSelection = true; mExpectingUpdateSelection = true;
mConnection.endBatchEdit(); mConnection.endBatchEdit();
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_onEndBatchInput(batchInputText, 0);
}
// Space state must be updated before calling updateShiftState // Space state must be updated before calling updateShiftState
mSpaceState = SPACE_STATE_PHANTOM; mSpaceState = SPACE_STATE_PHANTOM;
mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.updateShiftState();

View File

@ -62,12 +62,16 @@ import java.util.List;
mIsPartOfMegaword = isPartOfMegaword; mIsPartOfMegaword = isPartOfMegaword;
} }
private static final Object[] NULL_VALUES = new Object[0];
/** /**
* Adds a new log statement. The time parameter in successive calls to this method must be * Adds a new log statement. The time parameter in successive calls to this method must be
* monotonically increasing, or splitByTime() will not work. * monotonically increasing, or splitByTime() will not work.
*/ */
public void addLogStatement(final LogStatement logStatement, final Object[] values, public void addLogStatement(final LogStatement logStatement, final long time,
final long time) { Object... values) {
if (values == null) {
values = NULL_VALUES;
}
mLogStatementList.add(logStatement); mLogStatementList.add(logStatement);
mValuesList.add(values); mValuesList.add(values);
mTimeList.add(time); mTimeList.add(time);

View File

@ -565,10 +565,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mFeedbackLogBuffer.clear(); mFeedbackLogBuffer.clear();
} }
final LogUnit feedbackLogUnit = new LogUnit(); final LogUnit feedbackLogUnit = new LogUnit();
final Object[] values = { feedbackLogUnit.addLogStatement(LOGSTATEMENT_FEEDBACK, SystemClock.uptimeMillis(),
feedbackContents feedbackContents);
};
feedbackLogUnit.addLogStatement(LOGSTATEMENT_FEEDBACK, values, SystemClock.uptimeMillis());
mFeedbackLogBuffer.shiftIn(feedbackLogUnit); mFeedbackLogBuffer.shiftIn(feedbackLogUnit);
publishLogBuffer(mFeedbackLogBuffer, mFeedbackLog, true /* isIncludingPrivateData */); publishLogBuffer(mFeedbackLogBuffer, mFeedbackLog, true /* isIncludingPrivateData */);
mFeedbackLog.close(new Runnable() { mFeedbackLog.close(new Runnable() {
@ -653,19 +651,14 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
} }
} }
private static final Object[] NULL_VALUES = {};
/** /**
* Buffer a research log event, flagging it as privacy-sensitive. * Buffer a research log event, flagging it as privacy-sensitive.
*/ */
private synchronized void enqueueEvent(LogStatement logStatement, Object... values) { private synchronized void enqueueEvent(LogStatement logStatement, Object... values) {
if (values == null) {
values = NULL_VALUES;
}
assert values.length == logStatement.mKeys.length; assert values.length == logStatement.mKeys.length;
if (isAllowedToLog()) { if (isAllowedToLog()) {
final long time = SystemClock.uptimeMillis(); final long time = SystemClock.uptimeMillis();
mCurrentLogUnit.addLogStatement(logStatement, values, time); mCurrentLogUnit.addLogStatement(logStatement, time, values);
} }
} }
@ -701,11 +694,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
/* package for test */ void publishLogBuffer(final LogBuffer logBuffer, /* package for test */ void publishLogBuffer(final LogBuffer logBuffer,
final ResearchLog researchLog, final boolean isIncludingPrivateData) { final ResearchLog researchLog, final boolean isIncludingPrivateData) {
final LogUnit openingLogUnit = new LogUnit(); final LogUnit openingLogUnit = new LogUnit();
final Object[] values = { openingLogUnit.addLogStatement(LOGSTATEMENT_LOG_SEGMENT_OPENING, SystemClock.uptimeMillis(),
isIncludingPrivateData isIncludingPrivateData);
};
openingLogUnit.addLogStatement(LOGSTATEMENT_LOG_SEGMENT_OPENING, values,
SystemClock.uptimeMillis());
researchLog.publish(openingLogUnit, true /* isIncludingPrivateData */); researchLog.publish(openingLogUnit, true /* isIncludingPrivateData */);
LogUnit logUnit; LogUnit logUnit;
while ((logUnit = logBuffer.shiftOut()) != null) { while ((logUnit = logBuffer.shiftOut()) != null) {
@ -716,7 +706,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
researchLog.publish(logUnit, isIncludingPrivateData); researchLog.publish(logUnit, isIncludingPrivateData);
} }
final LogUnit closingLogUnit = new LogUnit(); final LogUnit closingLogUnit = new LogUnit();
closingLogUnit.addLogStatement(LOGSTATEMENT_LOG_SEGMENT_CLOSING, NULL_VALUES, closingLogUnit.addLogStatement(LOGSTATEMENT_LOG_SEGMENT_CLOSING,
SystemClock.uptimeMillis()); SystemClock.uptimeMillis());
researchLog.publish(closingLogUnit, true /* isIncludingPrivateData */); researchLog.publish(closingLogUnit, true /* isIncludingPrivateData */);
} }
@ -732,19 +722,21 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
return false; return false;
} }
private static final LogStatement LOGSTATEMENT_COMMIT_AUTOSPACE = private static final LogStatement LOGSTATEMENT_COMMIT_RECORD_SPLIT_WORDS =
new LogStatement("CommitAutospace", true, false); new LogStatement("recordSplitWords", true, false);
private void onWordComplete(final String word, final long maxTime, final boolean isPartial) { private void onWordComplete(final String word, final long maxTime, final boolean isSplitWords) {
Log.d(TAG, "onWordComplete: " + word);
if (word != null && word.length() > 0 && hasLetters(word)) { if (word != null && word.length() > 0 && hasLetters(word)) {
mCurrentLogUnit.setWord(word); mCurrentLogUnit.setWord(word);
mStatistics.recordWordEntered(); final boolean isDictionaryWord = mDictionary != null
&& mDictionary.isValidWord(word);
mStatistics.recordWordEntered(isDictionaryWord);
} }
final LogUnit newLogUnit = mCurrentLogUnit.splitByTime(maxTime); final LogUnit newLogUnit = mCurrentLogUnit.splitByTime(maxTime);
enqueueCommitText(word); enqueueCommitText(word);
if (isPartial) { if (isSplitWords) {
enqueueEvent(LOGSTATEMENT_COMMIT_AUTOSPACE, NULL_VALUES); enqueueEvent(LOGSTATEMENT_COMMIT_RECORD_SPLIT_WORDS);
enqueueCommitText(" "); enqueueCommitText(" ");
mStatistics.recordSplitWords();
} }
commitCurrentLogUnit(); commitCurrentLogUnit();
mCurrentLogUnit = newLogUnit; mCurrentLogUnit = newLogUnit;
@ -1205,11 +1197,23 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
getInstance().enqueueEvent(LOGSTATEMENT_USER_TIMESTAMP); getInstance().enqueueEvent(LOGSTATEMENT_USER_TIMESTAMP);
} }
private static final LogStatement LOGSTATEMENT_LATINIME_ONENDBATCHINPUT =
new LogStatement("LatinIMEOnEndBatchInput", true, false, "enteredText",
"enteredWordPos");
public static void latinIME_onEndBatchInput(final CharSequence enteredText,
final int enteredWordPos) {
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_ONENDBATCHINPUT, enteredText,
enteredWordPos);
researchLogger.mStatistics.recordGestureInput();
}
private static final LogStatement LOGSTATEMENT_STATISTICS = private static final LogStatement LOGSTATEMENT_STATISTICS =
new LogStatement("Statistics", false, false, "charCount", "letterCount", "numberCount", new LogStatement("Statistics", false, false, "charCount", "letterCount", "numberCount",
"spaceCount", "deleteOpsCount", "wordCount", "isEmptyUponStarting", "spaceCount", "deleteOpsCount", "wordCount", "isEmptyUponStarting",
"isEmptinessStateKnown", "averageTimeBetweenKeys", "averageTimeBeforeDelete", "isEmptinessStateKnown", "averageTimeBetweenKeys", "averageTimeBeforeDelete",
"averageTimeDuringRepeatedDelete", "averageTimeAfterDelete"); "averageTimeDuringRepeatedDelete", "averageTimeAfterDelete",
"dictionaryWordCount", "splitWordsCount", "gestureInputCount");
private static void logStatistics() { private static void logStatistics() {
final ResearchLogger researchLogger = getInstance(); final ResearchLogger researchLogger = getInstance();
final Statistics statistics = researchLogger.mStatistics; final Statistics statistics = researchLogger.mStatistics;
@ -1219,6 +1223,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
statistics.mIsEmptinessStateKnown, statistics.mKeyCounter.getAverageTime(), statistics.mIsEmptinessStateKnown, statistics.mKeyCounter.getAverageTime(),
statistics.mBeforeDeleteKeyCounter.getAverageTime(), statistics.mBeforeDeleteKeyCounter.getAverageTime(),
statistics.mDuringRepeatedDeleteKeysCounter.getAverageTime(), statistics.mDuringRepeatedDeleteKeysCounter.getAverageTime(),
statistics.mAfterDeleteKeyCounter.getAverageTime()); statistics.mAfterDeleteKeyCounter.getAverageTime(),
statistics.mDictionaryWordCount, statistics.mSplitWordsCount,
statistics.mGestureInputCount);
} }
} }

View File

@ -36,6 +36,12 @@ public class Statistics {
int mDeleteKeyCount; int mDeleteKeyCount;
// Number of words entered during a session. // Number of words entered during a session.
int mWordCount; int mWordCount;
// Number of words found in the dictionary.
int mDictionaryWordCount;
// Number of words split and spaces automatically entered.
int mSplitWordsCount;
// Number of gestures that were input.
int mGestureInputCount;
// Whether the text field was empty upon editing // Whether the text field was empty upon editing
boolean mIsEmptyUponStarting; boolean mIsEmptyUponStarting;
boolean mIsEmptinessStateKnown; boolean mIsEmptinessStateKnown;
@ -143,8 +149,19 @@ public class Statistics {
mLastTapTime = time; mLastTapTime = time;
} }
public void recordWordEntered() { public void recordWordEntered(final boolean isDictionaryWord) {
mWordCount++; mWordCount++;
if (isDictionaryWord) {
mDictionaryWordCount++;
}
}
public void recordSplitWords() {
mSplitWordsCount++;
}
public void recordGestureInput() {
mGestureInputCount++;
} }
public void setIsEmptyUponStarting(final boolean isEmpty) { public void setIsEmptyUponStarting(final boolean isEmpty) {