Skip to content
Snippets Groups Projects
Commit bc8df552 authored by Kurt Partridge's avatar Kurt Partridge Committed by Android (Google) Code Review
Browse files

Merge "ResearchLog. Track time of log statements"

parents fdfa03c9 bdbe279c
No related branches found
No related tags found
No related merge requests found
...@@ -18,7 +18,7 @@ package com.android.inputmethod.research; ...@@ -18,7 +18,7 @@ package com.android.inputmethod.research;
import com.android.inputmethod.latin.CollectionUtils; import com.android.inputmethod.latin.CollectionUtils;
import java.util.ArrayList; import java.util.List;
/** /**
* A group of log statements related to each other. * A group of log statements related to each other.
...@@ -35,16 +35,39 @@ import java.util.ArrayList; ...@@ -35,16 +35,39 @@ import java.util.ArrayList;
* been published recently, or whether the LogUnit contains numbers, etc. * been published recently, or whether the LogUnit contains numbers, etc.
*/ */
/* package */ class LogUnit { /* package */ class LogUnit {
private final ArrayList<String[]> mKeysList = CollectionUtils.newArrayList(); private final List<String[]> mKeysList;
private final ArrayList<Object[]> mValuesList = CollectionUtils.newArrayList(); private final List<Object[]> mValuesList;
private final ArrayList<Boolean> mIsPotentiallyPrivate = CollectionUtils.newArrayList(); // Assume that mTimeList is sorted in increasing order. Do not insert null values into
// mTimeList.
private final List<Long> mTimeList;
private final List<Boolean> mIsPotentiallyPrivate;
private String mWord; private String mWord;
private boolean mContainsDigit; private boolean mContainsDigit;
public LogUnit() {
mKeysList = CollectionUtils.newArrayList();
mValuesList = CollectionUtils.newArrayList();
mTimeList = CollectionUtils.newArrayList();
mIsPotentiallyPrivate = CollectionUtils.newArrayList();
}
private LogUnit(final List<String[]> keysList, final List<Object[]> valuesList,
final List<Long> timeList, final List<Boolean> isPotentiallyPrivate) {
mKeysList = keysList;
mValuesList = valuesList;
mTimeList = timeList;
mIsPotentiallyPrivate = isPotentiallyPrivate;
}
/**
* Adds a new log statement. The time parameter in successive calls to this method must be
* monotonically increasing, or splitByTime() will not work.
*/
public void addLogStatement(final String[] keys, final Object[] values, public void addLogStatement(final String[] keys, final Object[] values,
final Boolean isPotentiallyPrivate) { final long time, final boolean isPotentiallyPrivate) {
mKeysList.add(keys); mKeysList.add(keys);
mValuesList.add(values); mValuesList.add(values);
mTimeList.add(time);
mIsPotentiallyPrivate.add(isPotentiallyPrivate); mIsPotentiallyPrivate.add(isPotentiallyPrivate);
} }
...@@ -52,7 +75,7 @@ import java.util.ArrayList; ...@@ -52,7 +75,7 @@ import java.util.ArrayList;
final int size = mKeysList.size(); final int size = mKeysList.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (!mIsPotentiallyPrivate.get(i) || isIncludingPrivateData) { if (!mIsPotentiallyPrivate.get(i) || isIncludingPrivateData) {
researchLog.outputEvent(mKeysList.get(i), mValuesList.get(i)); researchLog.outputEvent(mKeysList.get(i), mValuesList.get(i), mTimeList.get(i));
} }
} }
} }
...@@ -80,4 +103,26 @@ import java.util.ArrayList; ...@@ -80,4 +103,26 @@ import java.util.ArrayList;
public boolean isEmpty() { public boolean isEmpty() {
return mKeysList.isEmpty(); return mKeysList.isEmpty();
} }
/**
* Split this logUnit, with all events before maxTime staying in the current logUnit, and all
* events after maxTime going into a new LogUnit that is returned.
*/
public LogUnit splitByTime(final long maxTime) {
// Assume that mTimeList is in sorted order.
final int length = mTimeList.size();
for (int index = 0; index < length; index++) {
if (mTimeList.get(index) >= maxTime) {
final LogUnit newLogUnit = new LogUnit(
mKeysList.subList(index, length),
mValuesList.subList(index, length),
mTimeList.subList(index, length),
mIsPotentiallyPrivate.subList(index, length));
newLogUnit.mWord = null;
newLogUnit.mContainsDigit = mContainsDigit;
return newLogUnit;
}
}
return new LogUnit();
}
} }
...@@ -207,7 +207,7 @@ public class ResearchLog { ...@@ -207,7 +207,7 @@ public class ResearchLog {
private static final String UPTIME_KEY = "_ut"; private static final String UPTIME_KEY = "_ut";
private static final String EVENT_TYPE_KEY = "_ty"; private static final String EVENT_TYPE_KEY = "_ty";
void outputEvent(final String[] keys, final Object[] values) { void outputEvent(final String[] keys, final Object[] values, final long time) {
// Not thread safe. // Not thread safe.
if (keys.length == 0) { if (keys.length == 0) {
return; return;
...@@ -225,7 +225,7 @@ public class ResearchLog { ...@@ -225,7 +225,7 @@ public class ResearchLog {
} }
mJsonWriter.beginObject(); mJsonWriter.beginObject();
mJsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis()); mJsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis());
mJsonWriter.name(UPTIME_KEY).value(SystemClock.uptimeMillis()); mJsonWriter.name(UPTIME_KEY).value(time);
mJsonWriter.name(EVENT_TYPE_KEY).value(keys[0]); mJsonWriter.name(EVENT_TYPE_KEY).value(keys[0]);
final int length = values.length; final int length = values.length;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
......
...@@ -380,7 +380,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -380,7 +380,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
Log.d(TAG, "stop called"); Log.d(TAG, "stop called");
} }
logStatistics(); logStatistics();
commitCurrentLogUnit(); commitCurrentLogUnit(SystemClock.uptimeMillis());
if (mMainLogBuffer != null) { if (mMainLogBuffer != null) {
publishLogBuffer(mMainLogBuffer, mMainResearchLog, false /* isIncludingPrivateData */); publishLogBuffer(mMainLogBuffer, mMainResearchLog, false /* isIncludingPrivateData */);
...@@ -548,7 +548,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -548,7 +548,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
return; return;
} }
if (includeHistory) { if (includeHistory) {
commitCurrentLogUnit(); commitCurrentLogUnit(SystemClock.uptimeMillis());
} else { } else {
mFeedbackLogBuffer.clear(); mFeedbackLogBuffer.clear();
} }
...@@ -557,7 +557,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -557,7 +557,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
feedbackContents feedbackContents
}; };
feedbackLogUnit.addLogStatement(EVENTKEYS_FEEDBACK, values, feedbackLogUnit.addLogStatement(EVENTKEYS_FEEDBACK, values,
false /* isPotentiallyPrivate */); SystemClock.uptimeMillis(), false /* isPotentiallyPrivate */);
mFeedbackLogBuffer.shiftIn(feedbackLogUnit); mFeedbackLogBuffer.shiftIn(feedbackLogUnit);
publishLogBuffer(mFeedbackLogBuffer, mFeedbackLog, true /* isIncludingPrivateData */); publishLogBuffer(mFeedbackLogBuffer, mFeedbackLog, true /* isIncludingPrivateData */);
mFeedbackLog.close(new Runnable() { mFeedbackLog.close(new Runnable() {
...@@ -658,8 +658,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -658,8 +658,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
private synchronized void enqueuePotentiallyPrivateEvent(final String[] keys, private synchronized void enqueuePotentiallyPrivateEvent(final String[] keys,
final Object[] values) { final Object[] values) {
assert values.length + 1 == keys.length; assert values.length + 1 == keys.length;
final long time = SystemClock.uptimeMillis();
if (isAllowedToLog()) { if (isAllowedToLog()) {
mCurrentLogUnit.addLogStatement(keys, values, true /* isPotentiallyPrivate */); mCurrentLogUnit.addLogStatement(keys, values, time, true /* isPotentiallyPrivate */);
} }
} }
...@@ -681,17 +682,19 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -681,17 +682,19 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
*/ */
private synchronized void enqueueEvent(final String[] keys, final Object[] values) { private synchronized void enqueueEvent(final String[] keys, final Object[] values) {
assert values.length + 1 == keys.length; assert values.length + 1 == keys.length;
final long time = SystemClock.uptimeMillis();
if (isAllowedToLog()) { if (isAllowedToLog()) {
mCurrentLogUnit.addLogStatement(keys, values, false /* isPotentiallyPrivate */); mCurrentLogUnit.addLogStatement(keys, values, time, false /* isPotentiallyPrivate */);
} }
} }
/* package for test */ void commitCurrentLogUnit() { /* package for test */ void commitCurrentLogUnit(final long maxTime) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "commitCurrentLogUnit" + (mCurrentLogUnit.hasWord() ? Log.d(TAG, "commitCurrentLogUnit" + (mCurrentLogUnit.hasWord() ?
": " + mCurrentLogUnit.getWord() : "")); ": " + mCurrentLogUnit.getWord() : ""));
} }
if (!mCurrentLogUnit.isEmpty()) { if (!mCurrentLogUnit.isEmpty()) {
final LogUnit newLogUnit = mCurrentLogUnit.splitByTime(maxTime);
if (mMainLogBuffer != null) { if (mMainLogBuffer != null) {
mMainLogBuffer.shiftIn(mCurrentLogUnit); mMainLogBuffer.shiftIn(mCurrentLogUnit);
if (mMainLogBuffer.isSafeToLog() && mMainResearchLog != null) { if (mMainLogBuffer.isSafeToLog() && mMainResearchLog != null) {
...@@ -703,7 +706,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -703,7 +706,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
if (mFeedbackLogBuffer != null) { if (mFeedbackLogBuffer != null) {
mFeedbackLogBuffer.shiftIn(mCurrentLogUnit); mFeedbackLogBuffer.shiftIn(mCurrentLogUnit);
} }
mCurrentLogUnit = new LogUnit(); mCurrentLogUnit = newLogUnit;
Log.d(TAG, "commitCurrentLogUnit"); Log.d(TAG, "commitCurrentLogUnit");
} }
} }
...@@ -721,7 +724,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -721,7 +724,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
isIncludingPrivateData isIncludingPrivateData
}; };
openingLogUnit.addLogStatement(EVENTKEYS_LOG_SEGMENT_START, values, openingLogUnit.addLogStatement(EVENTKEYS_LOG_SEGMENT_START, values,
false /* isPotentiallyPrivate */); SystemClock.uptimeMillis(), false /* isPotentiallyPrivate */);
researchLog.publish(openingLogUnit, true /* isIncludingPrivateData */); researchLog.publish(openingLogUnit, true /* isIncludingPrivateData */);
LogUnit logUnit; LogUnit logUnit;
while ((logUnit = logBuffer.shiftOut()) != null) { while ((logUnit = logBuffer.shiftOut()) != null) {
...@@ -729,7 +732,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -729,7 +732,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
} }
final LogUnit closingLogUnit = new LogUnit(); final LogUnit closingLogUnit = new LogUnit();
closingLogUnit.addLogStatement(EVENTKEYS_LOG_SEGMENT_END, EVENTKEYS_NULLVALUES, closingLogUnit.addLogStatement(EVENTKEYS_LOG_SEGMENT_END, EVENTKEYS_NULLVALUES,
false /* isPotentiallyPrivate */); SystemClock.uptimeMillis(), false /* isPotentiallyPrivate */);
researchLog.publish(closingLogUnit, true /* isIncludingPrivateData */); researchLog.publish(closingLogUnit, true /* isIncludingPrivateData */);
} }
...@@ -744,13 +747,13 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -744,13 +747,13 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
return false; return false;
} }
private void onWordComplete(final String word) { private void onWordComplete(final String word, final long maxTime) {
Log.d(TAG, "onWordComplete: " + word); 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(); mStatistics.recordWordEntered();
} }
commitCurrentLogUnit(); commitCurrentLogUnit(maxTime);
} }
private static int scrubDigitFromCodePoint(int codePoint) { private static int scrubDigitFromCodePoint(int codePoint) {
...@@ -963,7 +966,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -963,7 +966,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
} }
final ResearchLogger researchLogger = getInstance(); final ResearchLogger researchLogger = getInstance();
researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values); researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values);
researchLogger.commitCurrentLogUnit(); researchLogger.commitCurrentLogUnit(SystemClock.uptimeMillis());
getInstance().stop(); getInstance().stop();
} }
} }
...@@ -1209,7 +1212,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang ...@@ -1209,7 +1212,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final ResearchLogger researchLogger = getInstance(); final ResearchLogger researchLogger = getInstance();
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_RICHINPUTCONNECTION_COMMITTEXT, researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_RICHINPUTCONNECTION_COMMITTEXT,
values); values);
researchLogger.onWordComplete(scrubbedWord); // TODO: Replace Long.MAX_VALUE with timestamp of last data to include
researchLogger.onWordComplete(scrubbedWord, Long.MAX_VALUE);
} }
private static final String[] EVENTKEYS_RICHINPUTCONNECTION_DELETESURROUNDINGTEXT = { private static final String[] EVENTKEYS_RICHINPUTCONNECTION_DELETESURROUNDINGTEXT = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment