Remove non-dictionary words and digit touch data.
Output to the ResearchLogger is now queued and only flushed if the word the user was working on is a dictionary word. multi-project commit with Ic713ec00777fbdcf4a937b3c77b995257e100fc7 Bug: 6188932 Change-Id: I9de15227ff51be23083d9096f1c1b3d83802fff7
This commit is contained in:
parent
4b91046759
commit
6080f6878b
5 changed files with 306 additions and 163 deletions
|
@ -115,4 +115,12 @@ public abstract class Dictionary {
|
||||||
public void close() {
|
public void close() {
|
||||||
// empty base implementation
|
// empty base implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses may override to indicate that this Dictionary is not yet properly initialized.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,8 +82,9 @@ public class DictionaryCollection extends Dictionary {
|
||||||
return maxFreq;
|
return maxFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
@Override
|
||||||
return mDictionaries.isEmpty();
|
public boolean isInitialized() {
|
||||||
|
return !mDictionaries.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -456,6 +456,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
}
|
}
|
||||||
|
|
||||||
mIsMainDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(this, subtypeLocale);
|
mIsMainDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(this, subtypeLocale);
|
||||||
|
if (ProductionFlag.IS_EXPERIMENTAL) {
|
||||||
|
ResearchLogger.getInstance().initSuggest(mSuggest);
|
||||||
|
}
|
||||||
|
|
||||||
mUserDictionary = new UserBinaryDictionary(this, localeStr);
|
mUserDictionary = new UserBinaryDictionary(this, localeStr);
|
||||||
mIsUserDictionaryAvailable = mUserDictionary.isEnabled();
|
mIsUserDictionaryAvailable = mUserDictionary.isEnabled();
|
||||||
|
|
|
@ -51,7 +51,9 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -67,6 +69,7 @@ import java.util.UUID;
|
||||||
public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
private static final String TAG = ResearchLogger.class.getSimpleName();
|
private static final String TAG = ResearchLogger.class.getSimpleName();
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
private static final boolean OUTPUT_ENTIRE_BUFFER = false; // true may disclose private info
|
||||||
/* package */ static boolean sIsLogging = false;
|
/* package */ static boolean sIsLogging = false;
|
||||||
private static final int OUTPUT_FORMAT_VERSION = 1;
|
private static final int OUTPUT_FORMAT_VERSION = 1;
|
||||||
private static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
|
private static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
|
||||||
|
@ -99,10 +102,16 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
// digits entered by the user are replaced with this codepoint.
|
// digits entered by the user are replaced with this codepoint.
|
||||||
/* package for test */ static final int DIGIT_REPLACEMENT_CODEPOINT =
|
/* package for test */ static final int DIGIT_REPLACEMENT_CODEPOINT =
|
||||||
Character.codePointAt("\uE000", 0); // U+E000 is in the "private-use area"
|
Character.codePointAt("\uE000", 0); // U+E000 is in the "private-use area"
|
||||||
|
// U+E001 is in the "private-use area"
|
||||||
|
/* package for test */ static final String WORD_REPLACEMENT_STRING = "\uE001";
|
||||||
// set when LatinIME should ignore an onUpdateSelection() callback that
|
// set when LatinIME should ignore an onUpdateSelection() callback that
|
||||||
// arises from operations in this class
|
// arises from operations in this class
|
||||||
private static boolean sLatinIMEExpectingUpdateSelection = false;
|
private static boolean sLatinIMEExpectingUpdateSelection = false;
|
||||||
|
|
||||||
|
// used to check whether words are not unique
|
||||||
|
private Suggest mSuggest;
|
||||||
|
private Dictionary mDictionary;
|
||||||
|
|
||||||
private static class NullOutputStream extends OutputStream {
|
private static class NullOutputStream extends OutputStream {
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
|
@ -317,6 +326,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
latinIME.showOptionDialog(builder.create());
|
latinIME.showOptionDialog(builder.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initSuggest(Suggest suggest) {
|
||||||
|
mSuggest = suggest;
|
||||||
|
}
|
||||||
|
|
||||||
private void setIsPasswordView(boolean isPasswordView) {
|
private void setIsPasswordView(boolean isPasswordView) {
|
||||||
mIsPasswordView = isPasswordView;
|
mIsPasswordView = isPasswordView;
|
||||||
}
|
}
|
||||||
|
@ -330,122 +343,200 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
private static final String EVENT_TYPE_KEY = "_ty";
|
private static final String EVENT_TYPE_KEY = "_ty";
|
||||||
private static final Object[] EVENTKEYS_NULLVALUES = {};
|
private static final Object[] EVENTKEYS_NULLVALUES = {};
|
||||||
|
|
||||||
|
private LogUnit mCurrentLogUnit = new LogUnit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a description of the event out to the ResearchLog.
|
* Buffer a research log event, flagging it as privacy-sensitive.
|
||||||
*
|
*
|
||||||
* Runs in the background to avoid blocking the UI thread.
|
* This event contains potentially private information. If the word that this event is a part
|
||||||
|
* of is determined to be privacy-sensitive, then this event should not be included in the
|
||||||
|
* output log. The system waits to output until the containing word is known.
|
||||||
*
|
*
|
||||||
* @param keys an array containing a descriptive name for the event, followed by the keys
|
* @param keys an array containing a descriptive name for the event, followed by the keys
|
||||||
* @param values an array of values, either a String or Number. length should be one
|
* @param values an array of values, either a String or Number. length should be one
|
||||||
* less than the keys array
|
* less than the keys array
|
||||||
*/
|
*/
|
||||||
private synchronized void writeEvent(final String[] keys, final Object[] values) {
|
private synchronized void enqueuePotentiallyPrivateEvent(final String[] keys,
|
||||||
|
final Object[] values) {
|
||||||
assert values.length + 1 == keys.length;
|
assert values.length + 1 == keys.length;
|
||||||
|
mCurrentLogUnit.addLogAtom(keys, values, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer a research log event, flaggint it as not privacy-sensitive.
|
||||||
|
*
|
||||||
|
* This event contains no potentially private information. Even if the word that this event
|
||||||
|
* is privacy-sensitive, this event can still safely be sent to the output log. The system
|
||||||
|
* waits until the containing word is known so that this event can be written in the proper
|
||||||
|
* temporal order with other events that may be privacy sensitive.
|
||||||
|
*
|
||||||
|
* @param keys an array containing a descriptive name for the event, followed by the keys
|
||||||
|
* @param values an array of values, either a String or Number. length should be one
|
||||||
|
* less than the keys array
|
||||||
|
*/
|
||||||
|
private synchronized void enqueueEvent(final String[] keys, final Object[] values) {
|
||||||
|
assert values.length + 1 == keys.length;
|
||||||
|
mCurrentLogUnit.addLogAtom(keys, values, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInDictionary(CharSequence word) {
|
||||||
|
return (mDictionary != null) && (mDictionary.isValidWord(word));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write out enqueued LogEvents to the log, filtered for privacy.
|
||||||
|
*
|
||||||
|
* If word is in the dictionary, then it is not privacy-sensitive and all LogEvents related to
|
||||||
|
* it can be written to the log. If the word is not in the dictionary, then it may correspond
|
||||||
|
* to a proper name, which might reveal private information, so neither the word nor any
|
||||||
|
* information related to the word (e.g. the down/motion/up coordinates) should be revealed.
|
||||||
|
* These LogEvents have been marked as privacy-sensitive; non privacy-sensitive events are still
|
||||||
|
* written out.
|
||||||
|
*
|
||||||
|
* @param word the word to be checked for inclusion in the dictionary
|
||||||
|
*/
|
||||||
|
/* package for test */ synchronized void flushQueue(CharSequence word) {
|
||||||
if (isAllowedToLog()) {
|
if (isAllowedToLog()) {
|
||||||
mLoggingHandler.post(new Runnable() {
|
// check for dictionary
|
||||||
@Override
|
if (mDictionary == null && mSuggest != null && mSuggest.hasMainDictionary()) {
|
||||||
public void run() {
|
mDictionary = mSuggest.getMainDictionary();
|
||||||
try {
|
}
|
||||||
mJsonWriter.beginObject();
|
mCurrentLogUnit.setIsPrivacySafe(word != null && isInDictionary(word));
|
||||||
mJsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis());
|
mLoggingHandler.post(mCurrentLogUnit);
|
||||||
mJsonWriter.name(UPTIME_KEY).value(SystemClock.uptimeMillis());
|
mCurrentLogUnit = new LogUnit();
|
||||||
mJsonWriter.name(EVENT_TYPE_KEY).value(keys[0]);
|
}
|
||||||
final int length = values.length;
|
}
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
mJsonWriter.name(keys[i + 1]);
|
private synchronized void outputEvent(final String[] keys, final Object[] values) {
|
||||||
Object value = values[i];
|
try {
|
||||||
if (value instanceof String) {
|
mJsonWriter.beginObject();
|
||||||
mJsonWriter.value((String) value);
|
mJsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis());
|
||||||
} else if (value instanceof Number) {
|
mJsonWriter.name(UPTIME_KEY).value(SystemClock.uptimeMillis());
|
||||||
mJsonWriter.value((Number) value);
|
mJsonWriter.name(EVENT_TYPE_KEY).value(keys[0]);
|
||||||
} else if (value instanceof Boolean) {
|
final int length = values.length;
|
||||||
mJsonWriter.value((Boolean) value);
|
for (int i = 0; i < length; i++) {
|
||||||
} else if (value instanceof CompletionInfo[]) {
|
mJsonWriter.name(keys[i + 1]);
|
||||||
CompletionInfo[] ci = (CompletionInfo[]) value;
|
Object value = values[i];
|
||||||
mJsonWriter.beginArray();
|
if (value instanceof String) {
|
||||||
for (int j = 0; j < ci.length; j++) {
|
mJsonWriter.value((String) value);
|
||||||
mJsonWriter.value(scrubDigitsFromString(ci[j].toString()));
|
} else if (value instanceof Number) {
|
||||||
}
|
mJsonWriter.value((Number) value);
|
||||||
mJsonWriter.endArray();
|
} else if (value instanceof Boolean) {
|
||||||
} else if (value instanceof SharedPreferences) {
|
mJsonWriter.value((Boolean) value);
|
||||||
SharedPreferences prefs = (SharedPreferences) value;
|
} else if (value instanceof CompletionInfo[]) {
|
||||||
mJsonWriter.beginObject();
|
CompletionInfo[] ci = (CompletionInfo[]) value;
|
||||||
for (Map.Entry<String,?> entry : prefs.getAll().entrySet()) {
|
mJsonWriter.beginArray();
|
||||||
mJsonWriter.name(entry.getKey());
|
for (int j = 0; j < ci.length; j++) {
|
||||||
final Object innerValue = entry.getValue();
|
mJsonWriter.value(ci[j].toString());
|
||||||
if (innerValue == null) {
|
}
|
||||||
mJsonWriter.nullValue();
|
mJsonWriter.endArray();
|
||||||
} else if (innerValue instanceof Boolean) {
|
} else if (value instanceof SharedPreferences) {
|
||||||
mJsonWriter.value((Boolean) innerValue);
|
SharedPreferences prefs = (SharedPreferences) value;
|
||||||
} else if (innerValue instanceof Number) {
|
mJsonWriter.beginObject();
|
||||||
mJsonWriter.value((Number) innerValue);
|
for (Map.Entry<String,?> entry : prefs.getAll().entrySet()) {
|
||||||
} else {
|
mJsonWriter.name(entry.getKey());
|
||||||
mJsonWriter.value(innerValue.toString());
|
final Object innerValue = entry.getValue();
|
||||||
}
|
if (innerValue == null) {
|
||||||
}
|
mJsonWriter.nullValue();
|
||||||
mJsonWriter.endObject();
|
} else if (innerValue instanceof Boolean) {
|
||||||
} else if (value instanceof Key[]) {
|
mJsonWriter.value((Boolean) innerValue);
|
||||||
Key[] keys = (Key[]) value;
|
} else if (innerValue instanceof Number) {
|
||||||
mJsonWriter.beginArray();
|
mJsonWriter.value((Number) innerValue);
|
||||||
for (Key key : keys) {
|
} else {
|
||||||
mJsonWriter.beginObject();
|
mJsonWriter.value(innerValue.toString());
|
||||||
mJsonWriter.name("code").value(key.mCode);
|
|
||||||
mJsonWriter.name("altCode").value(key.mAltCode);
|
|
||||||
mJsonWriter.name("x").value(key.mX);
|
|
||||||
mJsonWriter.name("y").value(key.mY);
|
|
||||||
mJsonWriter.name("w").value(key.mWidth);
|
|
||||||
mJsonWriter.name("h").value(key.mHeight);
|
|
||||||
mJsonWriter.endObject();
|
|
||||||
}
|
|
||||||
mJsonWriter.endArray();
|
|
||||||
} else if (value instanceof SuggestedWords) {
|
|
||||||
SuggestedWords words = (SuggestedWords) value;
|
|
||||||
mJsonWriter.beginObject();
|
|
||||||
mJsonWriter.name("typedWordValid").value(words.mTypedWordValid);
|
|
||||||
mJsonWriter.name("hasAutoCorrectionCandidate")
|
|
||||||
.value(words.mHasAutoCorrectionCandidate);
|
|
||||||
mJsonWriter.name("isPunctuationSuggestions")
|
|
||||||
.value(words.mIsPunctuationSuggestions);
|
|
||||||
mJsonWriter.name("allowsToBeAutoCorrected")
|
|
||||||
.value(words.mAllowsToBeAutoCorrected);
|
|
||||||
mJsonWriter.name("isObsoleteSuggestions")
|
|
||||||
.value(words.mIsObsoleteSuggestions);
|
|
||||||
mJsonWriter.name("isPrediction")
|
|
||||||
.value(words.mIsPrediction);
|
|
||||||
mJsonWriter.name("words");
|
|
||||||
mJsonWriter.beginArray();
|
|
||||||
final int size = words.size();
|
|
||||||
for (int j = 0; j < size; j++) {
|
|
||||||
SuggestedWordInfo wordInfo = words.getWordInfo(j);
|
|
||||||
mJsonWriter.value(scrubDigitsFromString(wordInfo.toString()));
|
|
||||||
}
|
|
||||||
mJsonWriter.endArray();
|
|
||||||
mJsonWriter.endObject();
|
|
||||||
} else if (value == null) {
|
|
||||||
mJsonWriter.nullValue();
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Unrecognized type to be logged: " +
|
|
||||||
(value == null ? "<null>" : value.getClass().getName()));
|
|
||||||
mJsonWriter.nullValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mJsonWriter.endObject();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
Log.w(TAG, "Error in JsonWriter; disabling logging");
|
|
||||||
try {
|
|
||||||
mJsonWriter.close();
|
|
||||||
} catch (IllegalStateException e1) {
|
|
||||||
// assume that this is just the json not being terminated properly.
|
|
||||||
// ignore
|
|
||||||
} catch (IOException e1) {
|
|
||||||
e1.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
mJsonWriter = NULL_JSON_WRITER;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mJsonWriter.endObject();
|
||||||
|
} else if (value instanceof Key[]) {
|
||||||
|
Key[] keyboardKeys = (Key[]) value;
|
||||||
|
mJsonWriter.beginArray();
|
||||||
|
for (Key keyboardKey : keyboardKeys) {
|
||||||
|
mJsonWriter.beginObject();
|
||||||
|
mJsonWriter.name("code").value(keyboardKey.mCode);
|
||||||
|
mJsonWriter.name("altCode").value(keyboardKey.mAltCode);
|
||||||
|
mJsonWriter.name("x").value(keyboardKey.mX);
|
||||||
|
mJsonWriter.name("y").value(keyboardKey.mY);
|
||||||
|
mJsonWriter.name("w").value(keyboardKey.mWidth);
|
||||||
|
mJsonWriter.name("h").value(keyboardKey.mHeight);
|
||||||
|
mJsonWriter.endObject();
|
||||||
|
}
|
||||||
|
mJsonWriter.endArray();
|
||||||
|
} else if (value instanceof SuggestedWords) {
|
||||||
|
SuggestedWords words = (SuggestedWords) value;
|
||||||
|
mJsonWriter.beginObject();
|
||||||
|
mJsonWriter.name("typedWordValid").value(words.mTypedWordValid);
|
||||||
|
mJsonWriter.name("hasAutoCorrectionCandidate")
|
||||||
|
.value(words.mHasAutoCorrectionCandidate);
|
||||||
|
mJsonWriter.name("isPunctuationSuggestions")
|
||||||
|
.value(words.mIsPunctuationSuggestions);
|
||||||
|
mJsonWriter.name("allowsToBeAutoCorrected")
|
||||||
|
.value(words.mAllowsToBeAutoCorrected);
|
||||||
|
mJsonWriter.name("isObsoleteSuggestions")
|
||||||
|
.value(words.mIsObsoleteSuggestions);
|
||||||
|
mJsonWriter.name("isPrediction")
|
||||||
|
.value(words.mIsPrediction);
|
||||||
|
mJsonWriter.name("words");
|
||||||
|
mJsonWriter.beginArray();
|
||||||
|
final int size = words.size();
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
SuggestedWordInfo wordInfo = words.getWordInfo(j);
|
||||||
|
mJsonWriter.value(wordInfo.toString());
|
||||||
|
}
|
||||||
|
mJsonWriter.endArray();
|
||||||
|
mJsonWriter.endObject();
|
||||||
|
} else if (value == null) {
|
||||||
|
mJsonWriter.nullValue();
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Unrecognized type to be logged: " +
|
||||||
|
(value == null ? "<null>" : value.getClass().getName()));
|
||||||
|
mJsonWriter.nullValue();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
mJsonWriter.endObject();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.w(TAG, "Error in JsonWriter; disabling logging");
|
||||||
|
try {
|
||||||
|
mJsonWriter.close();
|
||||||
|
} catch (IllegalStateException e1) {
|
||||||
|
// assume that this is just the json not being terminated properly.
|
||||||
|
// ignore
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
mJsonWriter = NULL_JSON_WRITER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LogUnit implements Runnable {
|
||||||
|
private final List<String[]> mKeysList = new ArrayList<String[]>();
|
||||||
|
private final List<Object[]> mValuesList = new ArrayList<Object[]>();
|
||||||
|
private final List<Boolean> mIsPotentiallyPrivate = new ArrayList<Boolean>();
|
||||||
|
private boolean mIsPrivacySafe = false;
|
||||||
|
|
||||||
|
private void addLogAtom(final String[] keys, final Object[] values,
|
||||||
|
final Boolean isPotentiallyPrivate) {
|
||||||
|
mKeysList.add(keys);
|
||||||
|
mValuesList.add(values);
|
||||||
|
mIsPotentiallyPrivate.add(isPotentiallyPrivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIsPrivacySafe(boolean isPrivacySafe) {
|
||||||
|
mIsPrivacySafe = isPrivacySafe;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final int numAtoms = mKeysList.size();
|
||||||
|
for (int atomIndex = 0; atomIndex < numAtoms; atomIndex++) {
|
||||||
|
if (!mIsPrivacySafe && mIsPotentiallyPrivate.get(atomIndex)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final String[] keys = mKeysList.get(atomIndex);
|
||||||
|
final Object[] values = mValuesList.get(atomIndex);
|
||||||
|
ResearchLogger.getInstance().outputEvent(keys, values);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,6 +568,16 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String scrubWord(String word) {
|
||||||
|
if (mDictionary == null) {
|
||||||
|
return WORD_REPLACEMENT_STRING;
|
||||||
|
}
|
||||||
|
if (mDictionary.isValidWord(word)) {
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
return WORD_REPLACEMENT_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_PROCESSMOTIONEVENT = {
|
private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_PROCESSMOTIONEVENT = {
|
||||||
"LatinKeyboardViewProcessMotionEvent", "action", "eventTime", "id", "x", "y", "size",
|
"LatinKeyboardViewProcessMotionEvent", "action", "eventTime", "id", "x", "y", "size",
|
||||||
"pressure"
|
"pressure"
|
||||||
|
@ -500,7 +601,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
actionString, eventTime, id, x, y, size, pressure
|
actionString, eventTime, id, x, y, size, pressure
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINKEYBOARDVIEW_PROCESSMOTIONEVENT, values);
|
getInstance().enqueuePotentiallyPrivateEvent(
|
||||||
|
EVENTKEYS_LATINKEYBOARDVIEW_PROCESSMOTIONEVENT, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +613,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
Keyboard.printableCode(scrubDigitFromCodePoint(code)), x, y
|
Keyboard.printableCode(scrubDigitFromCodePoint(code)), x, y
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values);
|
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_CORRECTION = {
|
private static final String[] EVENTKEYS_CORRECTION = {
|
||||||
|
@ -522,7 +624,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
subgroup, scrubDigitsFromString(before), scrubDigitsFromString(after), position
|
subgroup, scrubDigitsFromString(before), scrubDigitsFromString(after), position
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_CORRECTION, values);
|
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_CORRECTION, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION = {
|
private static final String[] EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION = {
|
||||||
|
@ -533,7 +635,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
scrubDigitsFromString(typedWord), scrubDigitsFromString(autoCorrection)
|
scrubDigitsFromString(typedWord), scrubDigitsFromString(autoCorrection)
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values);
|
final ResearchLogger researchLogger = getInstance();
|
||||||
|
researchLogger.enqueuePotentiallyPrivateEvent(
|
||||||
|
EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values);
|
||||||
|
researchLogger.flushQueue(autoCorrection);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = {
|
private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = {
|
||||||
|
@ -543,7 +648,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
scrubDigitsFromString(typedWord.toString())
|
scrubDigitsFromString(typedWord.toString())
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_COMMITTEXT, values);
|
final ResearchLogger researchLogger = getInstance();
|
||||||
|
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_COMMITTEXT, values);
|
||||||
|
researchLogger.flushQueue(typedWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = {
|
private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = {
|
||||||
|
@ -553,14 +660,14 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
length
|
length
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT, values);
|
getInstance().enqueueEvent(EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD = {
|
private static final String[] EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD = {
|
||||||
"LatinIMEDoubleSpaceAutoPeriod"
|
"LatinIMEDoubleSpaceAutoPeriod"
|
||||||
};
|
};
|
||||||
public static void latinIME_doubleSpaceAutoPeriod() {
|
public static void latinIME_doubleSpaceAutoPeriod() {
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD, EVENTKEYS_NULLVALUES);
|
getInstance().enqueueEvent(EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD, EVENTKEYS_NULLVALUES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS = {
|
private static final String[] EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS = {
|
||||||
|
@ -571,7 +678,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
applicationSpecifiedCompletions
|
applicationSpecifiedCompletions
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS, values);
|
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS,
|
||||||
|
values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ static boolean getAndClearLatinIMEExpectingUpdateSelection() {
|
/* package */ static boolean getAndClearLatinIMEExpectingUpdateSelection() {
|
||||||
|
@ -592,27 +700,35 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
ic.setSelection(savedSelectionStart, savedSelectionEnd);
|
ic.setSelection(savedSelectionStart, savedSelectionEnd);
|
||||||
ic.endBatchEdit();
|
ic.endBatchEdit();
|
||||||
sLatinIMEExpectingUpdateSelection = true;
|
sLatinIMEExpectingUpdateSelection = true;
|
||||||
Object[] values = new Object[2];
|
final Object[] values = new Object[2];
|
||||||
if (TextUtils.isEmpty(charSequence)) {
|
if (OUTPUT_ENTIRE_BUFFER) {
|
||||||
values[0] = false;
|
if (TextUtils.isEmpty(charSequence)) {
|
||||||
values[1] = "";
|
|
||||||
} else {
|
|
||||||
if (charSequence.length() > MAX_INPUTVIEW_LENGTH_TO_CAPTURE) {
|
|
||||||
int length = MAX_INPUTVIEW_LENGTH_TO_CAPTURE;
|
|
||||||
// do not cut in the middle of a supplementary character
|
|
||||||
final char c = charSequence.charAt(length - 1);
|
|
||||||
if (Character.isHighSurrogate(c)) {
|
|
||||||
length--;
|
|
||||||
}
|
|
||||||
final CharSequence truncatedCharSequence = charSequence.subSequence(0, length);
|
|
||||||
values[0] = true;
|
|
||||||
values[1] = scrubDigitsFromString(truncatedCharSequence.toString());
|
|
||||||
} else {
|
|
||||||
values[0] = false;
|
values[0] = false;
|
||||||
values[1] = scrubDigitsFromString(charSequence.toString());
|
values[1] = "";
|
||||||
|
} else {
|
||||||
|
if (charSequence.length() > MAX_INPUTVIEW_LENGTH_TO_CAPTURE) {
|
||||||
|
int length = MAX_INPUTVIEW_LENGTH_TO_CAPTURE;
|
||||||
|
// do not cut in the middle of a supplementary character
|
||||||
|
final char c = charSequence.charAt(length - 1);
|
||||||
|
if (Character.isHighSurrogate(c)) {
|
||||||
|
length--;
|
||||||
|
}
|
||||||
|
final CharSequence truncatedCharSequence = charSequence.subSequence(0,
|
||||||
|
length);
|
||||||
|
values[0] = true;
|
||||||
|
values[1] = truncatedCharSequence.toString();
|
||||||
|
} else {
|
||||||
|
values[0] = false;
|
||||||
|
values[1] = charSequence.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
values[0] = true;
|
||||||
|
values[1] = "";
|
||||||
}
|
}
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values);
|
final ResearchLogger researchLogger = getInstance();
|
||||||
|
researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values);
|
||||||
|
researchLogger.flushQueue(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,7 +744,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId, Build.DISPLAY,
|
Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId, Build.DISPLAY,
|
||||||
Build.MODEL, prefs, OUTPUT_FORMAT_VERSION
|
Build.MODEL, prefs, OUTPUT_FORMAT_VERSION
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL, values);
|
getInstance().enqueueEvent(EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,12 +778,14 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
word = range.mWord;
|
word = range.mWord;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
final ResearchLogger researchLogger = getInstance();
|
||||||
|
final String scrubbedWord = researchLogger.scrubWord(word);
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
lastSelectionStart, lastSelectionEnd, oldSelStart, oldSelEnd, newSelStart,
|
lastSelectionStart, lastSelectionEnd, oldSelStart, oldSelEnd, newSelStart,
|
||||||
newSelEnd, composingSpanStart, composingSpanEnd, expectingUpdateSelection,
|
newSelEnd, composingSpanStart, composingSpanEnd, expectingUpdateSelection,
|
||||||
expectingUpdateSelectionFromLogger, scrubDigitsFromString(word)
|
expectingUpdateSelectionFromLogger, scrubbedWord
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_ONUPDATESELECTION, values);
|
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONUPDATESELECTION, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_PERFORMEDITORACTION = {
|
private static final String[] EVENTKEYS_LATINIME_PERFORMEDITORACTION = {
|
||||||
|
@ -677,7 +795,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
imeActionNext
|
imeActionNext
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_PERFORMEDITORACTION, values);
|
getInstance().enqueueEvent(EVENTKEYS_LATINIME_PERFORMEDITORACTION, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION = {
|
private static final String[] EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION = {
|
||||||
|
@ -688,7 +806,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
index, cs, x, y
|
index, cs, x, y
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values);
|
final ResearchLogger researchLogger = getInstance();
|
||||||
|
researchLogger.enqueuePotentiallyPrivateEvent(
|
||||||
|
EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values);
|
||||||
|
researchLogger.flushQueue(cs.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = {
|
private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = {
|
||||||
|
@ -700,7 +821,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
scrubDigitsFromString(replacedWord), index, suggestion == null ? null :
|
scrubDigitsFromString(replacedWord), index, suggestion == null ? null :
|
||||||
scrubDigitsFromString(suggestion.toString()), x, y
|
scrubDigitsFromString(suggestion.toString()), x, y
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY, values);
|
final ResearchLogger researchLogger = getInstance();
|
||||||
|
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY,
|
||||||
|
values);
|
||||||
|
researchLogger.flushQueue(suggestion.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = {
|
private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = {
|
||||||
|
@ -711,14 +835,14 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
index, suggestion, x, y
|
index, suggestion, x, y
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION, values);
|
getInstance().enqueueEvent(EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT = {
|
private static final String[] EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT = {
|
||||||
"LatinIMERevertDoubleSpaceWhileInBatchEdit"
|
"LatinIMERevertDoubleSpaceWhileInBatchEdit"
|
||||||
};
|
};
|
||||||
public static void latinIME_revertDoubleSpaceWhileInBatchEdit() {
|
public static void latinIME_revertDoubleSpaceWhileInBatchEdit() {
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT,
|
getInstance().enqueueEvent(EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT,
|
||||||
EVENTKEYS_NULLVALUES);
|
EVENTKEYS_NULLVALUES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,7 +850,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
"LatinIMERevertSwapPunctuation"
|
"LatinIMERevertSwapPunctuation"
|
||||||
};
|
};
|
||||||
public static void latinIME_revertSwapPunctuation() {
|
public static void latinIME_revertSwapPunctuation() {
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION, EVENTKEYS_NULLVALUES);
|
getInstance().enqueueEvent(EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION, EVENTKEYS_NULLVALUES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_SENDKEYCODEPOINT = {
|
private static final String[] EVENTKEYS_LATINIME_SENDKEYCODEPOINT = {
|
||||||
|
@ -736,14 +860,14 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
Keyboard.printableCode(scrubDigitFromCodePoint(code))
|
Keyboard.printableCode(scrubDigitFromCodePoint(code))
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_SENDKEYCODEPOINT, values);
|
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_SENDKEYCODEPOINT, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT = {
|
private static final String[] EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT = {
|
||||||
"LatinIMESwapSwapperAndSpaceWhileInBatchEdit"
|
"LatinIMESwapSwapperAndSpaceWhileInBatchEdit"
|
||||||
};
|
};
|
||||||
public static void latinIME_swapSwapperAndSpaceWhileInBatchEdit() {
|
public static void latinIME_swapSwapperAndSpaceWhileInBatchEdit() {
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT,
|
getInstance().enqueueEvent(EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT,
|
||||||
EVENTKEYS_NULLVALUES);
|
EVENTKEYS_NULLVALUES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,14 +875,14 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
"LatinIMESwitchToKeyboardView"
|
"LatinIMESwitchToKeyboardView"
|
||||||
};
|
};
|
||||||
public static void latinIME_switchToKeyboardView() {
|
public static void latinIME_switchToKeyboardView() {
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_SWITCHTOKEYBOARDVIEW, EVENTKEYS_NULLVALUES);
|
getInstance().enqueueEvent(EVENTKEYS_LATINIME_SWITCHTOKEYBOARDVIEW, EVENTKEYS_NULLVALUES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_ONLONGPRESS = {
|
private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_ONLONGPRESS = {
|
||||||
"LatinKeyboardViewOnLongPress"
|
"LatinKeyboardViewOnLongPress"
|
||||||
};
|
};
|
||||||
public static void latinKeyboardView_onLongPress() {
|
public static void latinKeyboardView_onLongPress() {
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINKEYBOARDVIEW_ONLONGPRESS, EVENTKEYS_NULLVALUES);
|
getInstance().enqueueEvent(EVENTKEYS_LATINKEYBOARDVIEW_ONLONGPRESS, EVENTKEYS_NULLVALUES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_SETKEYBOARD = {
|
private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_SETKEYBOARD = {
|
||||||
|
@ -790,7 +914,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
keyboard.mOccupiedHeight,
|
keyboard.mOccupiedHeight,
|
||||||
keyboard.mKeys
|
keyboard.mKeys
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINKEYBOARDVIEW_SETKEYBOARD, values);
|
getInstance().enqueueEvent(EVENTKEYS_LATINKEYBOARDVIEW_SETKEYBOARD, values);
|
||||||
getInstance().setIsPasswordView(isPasswordView);
|
getInstance().setIsPasswordView(isPasswordView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -802,14 +926,14 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
originallyTypedWord
|
originallyTypedWord
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_LATINIME_REVERTCOMMIT, values);
|
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_REVERTCOMMIT, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT = {
|
private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT = {
|
||||||
"PointerTrackerCallListenerOnCancelInput"
|
"PointerTrackerCallListenerOnCancelInput"
|
||||||
};
|
};
|
||||||
public static void pointerTracker_callListenerOnCancelInput() {
|
public static void pointerTracker_callListenerOnCancelInput() {
|
||||||
getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT,
|
getInstance().enqueueEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT,
|
||||||
EVENTKEYS_NULLVALUES);
|
EVENTKEYS_NULLVALUES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -827,7 +951,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
: scrubDigitsFromString(outputText.toString()),
|
: scrubDigitsFromString(outputText.toString()),
|
||||||
x, y, ignoreModifierKey, altersCode, key.isEnabled()
|
x, y, ignoreModifierKey, altersCode, key.isEnabled()
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT, values);
|
getInstance().enqueuePotentiallyPrivateEvent(
|
||||||
|
EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,7 +967,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
Keyboard.printableCode(scrubDigitFromCodePoint(primaryCode)), withSliding,
|
Keyboard.printableCode(scrubDigitFromCodePoint(primaryCode)), withSliding,
|
||||||
ignoreModifierKey, key.isEnabled()
|
ignoreModifierKey, key.isEnabled()
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE, values);
|
getInstance().enqueuePotentiallyPrivateEvent(
|
||||||
|
EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,7 +979,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
deltaT, distanceSquared
|
deltaT, distanceSquared
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_ONDOWNEVENT, values);
|
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_POINTERTRACKER_ONDOWNEVENT, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_POINTERTRACKER_ONMOVEEVENT = {
|
private static final String[] EVENTKEYS_POINTERTRACKER_ONMOVEEVENT = {
|
||||||
|
@ -864,7 +990,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
x, y, lastX, lastY
|
x, y, lastX, lastY
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_ONMOVEEVENT, values);
|
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_POINTERTRACKER_ONMOVEEVENT, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT = {
|
private static final String[] EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT = {
|
||||||
|
@ -875,8 +1001,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
me.toString()
|
me.toString()
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT,
|
getInstance().enqueuePotentiallyPrivateEvent(
|
||||||
values);
|
EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,7 +1014,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
suggestedWords
|
suggestedWords
|
||||||
};
|
};
|
||||||
getInstance().writeEvent(EVENTKEYS_SUGGESTIONSVIEW_SETSUGGESTIONS, values);
|
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_SUGGESTIONSVIEW_SETSUGGESTIONS,
|
||||||
|
values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -896,6 +1023,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
"UserTimestamp"
|
"UserTimestamp"
|
||||||
};
|
};
|
||||||
public void userTimestamp() {
|
public void userTimestamp() {
|
||||||
getInstance().writeEvent(EVENTKEYS_USER_TIMESTAMP, EVENTKEYS_NULLVALUES);
|
getInstance().enqueueEvent(EVENTKEYS_USER_TIMESTAMP, EVENTKEYS_NULLVALUES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
|
|
||||||
private static final boolean DBG = LatinImeLogger.sDBG;
|
private static final boolean DBG = LatinImeLogger.sDBG;
|
||||||
|
|
||||||
private boolean mHasMainDictionary;
|
private Dictionary mMainDictionary;
|
||||||
private ContactsBinaryDictionary mContactsDict;
|
private ContactsBinaryDictionary mContactsDict;
|
||||||
private WhitelistDictionary mWhiteListDictionary;
|
private WhitelistDictionary mWhiteListDictionary;
|
||||||
private final ConcurrentHashMap<String, Dictionary> mUnigramDictionaries =
|
private final ConcurrentHashMap<String, Dictionary> mUnigramDictionaries =
|
||||||
|
@ -98,7 +98,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
final long startOffset, final long length, final Locale locale) {
|
final long startOffset, final long length, final Locale locale) {
|
||||||
final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary,
|
final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary,
|
||||||
startOffset, length /* useFullEditDistance */, false, locale);
|
startOffset, length /* useFullEditDistance */, false, locale);
|
||||||
mHasMainDictionary = null != mainDict;
|
mMainDictionary = mainDict;
|
||||||
addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict);
|
addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict);
|
||||||
addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict);
|
addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict);
|
||||||
initWhitelistAndAutocorrectAndPool(context, locale);
|
initWhitelistAndAutocorrectAndPool(context, locale);
|
||||||
|
@ -129,15 +129,15 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetMainDict(final Context context, final Locale locale) {
|
public void resetMainDict(final Context context, final Locale locale) {
|
||||||
mHasMainDictionary = false;
|
mMainDictionary = null;
|
||||||
new Thread("InitializeBinaryDictionary") {
|
new Thread("InitializeBinaryDictionary") {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final DictionaryCollection newMainDict =
|
final DictionaryCollection newMainDict =
|
||||||
DictionaryFactory.createMainDictionaryFromManager(context, locale);
|
DictionaryFactory.createMainDictionaryFromManager(context, locale);
|
||||||
mHasMainDictionary = null != newMainDict && !newMainDict.isEmpty();
|
|
||||||
addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, newMainDict);
|
addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, newMainDict);
|
||||||
addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, newMainDict);
|
addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, newMainDict);
|
||||||
|
mMainDictionary = newMainDict;
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,11 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
// The main dictionary could have been loaded asynchronously. Don't cache the return value
|
// The main dictionary could have been loaded asynchronously. Don't cache the return value
|
||||||
// of this method.
|
// of this method.
|
||||||
public boolean hasMainDictionary() {
|
public boolean hasMainDictionary() {
|
||||||
return mHasMainDictionary;
|
return null != mMainDictionary && mMainDictionary.isInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary getMainDictionary() {
|
||||||
|
return mMainDictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContactsBinaryDictionary getContactsDictionary() {
|
public ContactsBinaryDictionary getContactsDictionary() {
|
||||||
|
@ -365,7 +369,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
// language, and it will unexpectedly auto-correct. For example, if the user types in
|
// language, and it will unexpectedly auto-correct. For example, if the user types in
|
||||||
// English with no dictionary and has a "Will" in their contact list, "will" would
|
// English with no dictionary and has a "Will" in their contact list, "will" would
|
||||||
// always auto-correct to "Will" which is unwanted. Hence, no main dict => no auto-correct.
|
// always auto-correct to "Will" which is unwanted. Hence, no main dict => no auto-correct.
|
||||||
&& mHasMainDictionary;
|
&& hasMainDictionary();
|
||||||
|
|
||||||
boolean autoCorrectionAvailable = hasAutoCorrection;
|
boolean autoCorrectionAvailable = hasAutoCorrection;
|
||||||
if (correctionMode == CORRECTION_FULL || correctionMode == CORRECTION_FULL_BIGRAM) {
|
if (correctionMode == CORRECTION_FULL || correctionMode == CORRECTION_FULL_BIGRAM) {
|
||||||
|
@ -511,7 +515,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
for (final Dictionary dictionary : dictionaries) {
|
for (final Dictionary dictionary : dictionaries) {
|
||||||
dictionary.close();
|
dictionary.close();
|
||||||
}
|
}
|
||||||
mHasMainDictionary = false;
|
mMainDictionary = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Resolve the inconsistencies between the native auto correction algorithms and
|
// TODO: Resolve the inconsistencies between the native auto correction algorithms and
|
||||||
|
|
Loading…
Reference in a new issue