only output every kth word to log
multi-project CL with Ib5b544b9b2d8b0e4419238976b2e274e5ac564f8 Bug: 6188932 Change-Id: Iea68cf36924d6fda126130a98431a6ce02ba251emain
parent
01106f6a10
commit
e961188e9f
|
@ -197,6 +197,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
Log.d(TAG, "stop called");
|
Log.d(TAG, "stop called");
|
||||||
if (mLoggingHandler != null && mLoggingState == LOGGING_STATE_ON) {
|
if (mLoggingHandler != null && mLoggingState == LOGGING_STATE_ON) {
|
||||||
mLoggingState = LOGGING_STATE_STOPPING;
|
mLoggingState = LOGGING_STATE_STOPPING;
|
||||||
|
flushEventQueue(true);
|
||||||
// put this in the Handler queue so pending writes are processed first.
|
// put this in the Handler queue so pending writes are processed first.
|
||||||
mLoggingHandler.post(new Runnable() {
|
mLoggingHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -379,11 +380,52 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
mCurrentLogUnit.addLogAtom(keys, values, false);
|
mCurrentLogUnit.addLogAtom(keys, values, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used to track how often words are logged. Too-frequent logging can leak
|
||||||
|
// semantics, disclosing private data.
|
||||||
|
/* package for test */ static class LoggingFrequencyState {
|
||||||
|
private static final int DEFAULT_WORD_LOG_FREQUENCY = 10;
|
||||||
|
private int mWordsRemainingToSkip;
|
||||||
|
private final int mFrequency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks how often words may be uploaded.
|
||||||
|
*
|
||||||
|
* @param frequency 1=Every word, 2=Every other word, etc.
|
||||||
|
*/
|
||||||
|
public LoggingFrequencyState(int frequency) {
|
||||||
|
mFrequency = frequency;
|
||||||
|
mWordsRemainingToSkip = mFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onWordLogged() {
|
||||||
|
mWordsRemainingToSkip = mFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onWordNotLogged() {
|
||||||
|
if (mWordsRemainingToSkip > 1) {
|
||||||
|
mWordsRemainingToSkip--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSafeToLog() {
|
||||||
|
return mWordsRemainingToSkip <= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package for test */ LoggingFrequencyState mLoggingFrequencyState =
|
||||||
|
new LoggingFrequencyState(LoggingFrequencyState.DEFAULT_WORD_LOG_FREQUENCY);
|
||||||
|
|
||||||
/* package for test */ boolean isPrivacyThreat(String word) {
|
/* package for test */ boolean isPrivacyThreat(String word) {
|
||||||
// currently: word not in dictionary or contains numbers.
|
// Current checks:
|
||||||
|
// - Word not in dictionary
|
||||||
|
// - Word contains numbers
|
||||||
|
// - Privacy-safe word not logged recently
|
||||||
if (TextUtils.isEmpty(word)) {
|
if (TextUtils.isEmpty(word)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!mLoggingFrequencyState.isSafeToLog()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
final int length = word.length();
|
final int length = word.length();
|
||||||
boolean hasLetter = false;
|
boolean hasLetter = false;
|
||||||
for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
|
for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
|
||||||
|
@ -410,15 +452,26 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onWordComplete(String word) {
|
||||||
|
final boolean isPrivacyThreat = isPrivacyThreat(word);
|
||||||
|
flushEventQueue(isPrivacyThreat);
|
||||||
|
if (isPrivacyThreat) {
|
||||||
|
mLoggingFrequencyState.onWordNotLogged();
|
||||||
|
} else {
|
||||||
|
mLoggingFrequencyState.onWordLogged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write out enqueued LogEvents to the log, possibly dropping privacy sensitive events.
|
* Write out enqueued LogEvents to the log, possibly dropping privacy sensitive events.
|
||||||
*/
|
*/
|
||||||
/* package for test */ synchronized void flushQueue(boolean removePotentiallyPrivateEvents) {
|
/* package for test */ synchronized void flushEventQueue(
|
||||||
|
boolean removePotentiallyPrivateEvents) {
|
||||||
if (isAllowedToLog()) {
|
if (isAllowedToLog()) {
|
||||||
mCurrentLogUnit.setRemovePotentiallyPrivateEvents(removePotentiallyPrivateEvents);
|
mCurrentLogUnit.setRemovePotentiallyPrivateEvents(removePotentiallyPrivateEvents);
|
||||||
mLoggingHandler.post(mCurrentLogUnit);
|
mLoggingHandler.post(mCurrentLogUnit);
|
||||||
mCurrentLogUnit = new LogUnit();
|
|
||||||
}
|
}
|
||||||
|
mCurrentLogUnit = new LogUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void outputEvent(final String[] keys, final Object[] values) {
|
private synchronized void outputEvent(final String[] keys, final Object[] values) {
|
||||||
|
@ -652,7 +705,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final ResearchLogger researchLogger = getInstance();
|
final ResearchLogger researchLogger = getInstance();
|
||||||
researchLogger.enqueuePotentiallyPrivateEvent(
|
researchLogger.enqueuePotentiallyPrivateEvent(
|
||||||
EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values);
|
EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values);
|
||||||
researchLogger.flushQueue(researchLogger.isPrivacyThreat(autoCorrection));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = {
|
private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = {
|
||||||
|
@ -665,7 +717,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
};
|
};
|
||||||
final ResearchLogger researchLogger = getInstance();
|
final ResearchLogger researchLogger = getInstance();
|
||||||
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_COMMITTEXT, values);
|
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_COMMITTEXT, values);
|
||||||
researchLogger.flushQueue(researchLogger.isPrivacyThreat(scrubbedWord));
|
researchLogger.onWordComplete(scrubbedWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = {
|
private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = {
|
||||||
|
@ -743,7 +795,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.flushQueue(true); // Play it safe. Remove privacy-sensitive events.
|
researchLogger.flushEventQueue(true); // Play it safe. Remove privacy-sensitive events.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,7 +876,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final ResearchLogger researchLogger = getInstance();
|
final ResearchLogger researchLogger = getInstance();
|
||||||
researchLogger.enqueuePotentiallyPrivateEvent(
|
researchLogger.enqueuePotentiallyPrivateEvent(
|
||||||
EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values);
|
EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values);
|
||||||
researchLogger.flushQueue(researchLogger.isPrivacyThreat(cs.toString()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = {
|
private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = {
|
||||||
|
@ -839,7 +890,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final ResearchLogger researchLogger = getInstance();
|
final ResearchLogger researchLogger = getInstance();
|
||||||
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY,
|
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY,
|
||||||
values);
|
values);
|
||||||
researchLogger.flushQueue(researchLogger.isPrivacyThreat(suggestion.toString()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = {
|
private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = {
|
||||||
|
|
Loading…
Reference in New Issue