aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java15
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java6
-rw-r--r--java/src/com/android/inputmethod/research/FixedLogBuffer.java123
-rw-r--r--java/src/com/android/inputmethod/research/JsonUtils.java54
-rw-r--r--java/src/com/android/inputmethod/research/LogBuffer.java96
-rw-r--r--java/src/com/android/inputmethod/research/LogUnit.java3
-rw-r--r--java/src/com/android/inputmethod/research/MainLogBuffer.java22
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLogger.java93
8 files changed, 301 insertions, 111 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index bb5c276a1..6eeee9c2a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1131,7 +1131,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
commitChosenWord(typedWord, LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD,
separatorString);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.getInstance().onWordComplete(typedWord, Long.MAX_VALUE);
+ ResearchLogger.getInstance().onWordFinished(typedWord);
}
}
}
@@ -1171,8 +1171,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final String text = lastTwo.charAt(1) + " ";
mConnection.commitText(text, 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.getInstance().onWordComplete(text, Long.MAX_VALUE);
- ResearchLogger.latinIME_swapSwapperAndSpace();
+ ResearchLogger.latinIME_swapSwapperAndSpace(text);
}
mKeyboardSwitcher.updateShiftState();
}
@@ -1192,7 +1191,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final String textToInsert = ". ";
mConnection.commitText(textToInsert, 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.getInstance().onWordComplete(textToInsert, Long.MAX_VALUE);
+ ResearchLogger.latinIME_maybeDoubleSpacePeriod(textToInsert);
}
mKeyboardSwitcher.updateShiftState();
return true;
@@ -1441,7 +1440,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
mConnection.commitText(text, 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.getInstance().onWordComplete(text, Long.MAX_VALUE);
+ ResearchLogger.latinIME_onTextInput(text);
}
mConnection.endBatchEdit();
// Space state must be updated before calling updateShiftState
@@ -1700,7 +1699,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
if (SPACE_STATE_DOUBLE == spaceState) {
mHandler.cancelDoubleSpacePeriodTimer();
- if (mConnection.revertDoubleSpace()) {
+ if (mConnection.revertDoubleSpacePeriod()) {
// No need to reset mSpaceState, it has already be done (that's why we
// receive it as a parameter)
return;
@@ -2078,12 +2077,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (ProductionFlag.IS_INTERNAL) {
Stats.onAutoCorrection(typedWord, autoCorrection, separatorString, mWordComposer);
}
- mExpectingUpdateSelection = true;
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIme_commitCurrentAutoCorrection(typedWord, autoCorrection,
separatorString);
}
-
+ mExpectingUpdateSelection = true;
commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD,
separatorString);
if (!typedWord.equals(autoCorrection)) {
@@ -2295,7 +2293,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_revertCommit(committedWord, originallyTypedWord);
- ResearchLogger.getInstance().onWordComplete(originallyTypedWord, Long.MAX_VALUE);
}
// Don't restart suggestion yet. We'll restart if the user deletes the
// separator.
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 9cb24b54e..0d3ebacb1 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -643,7 +643,7 @@ public final class RichInputConnection {
return word;
}
- public boolean revertDoubleSpace() {
+ public boolean revertDoubleSpacePeriod() {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
// Here we test whether we indeed have a period and a space before us. This should not
// be needed, but it's there just in case something went wrong.
@@ -660,7 +660,7 @@ public final class RichInputConnection {
final String doubleSpace = " ";
commitText(doubleSpace, 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.getInstance().onWordComplete(doubleSpace, Long.MAX_VALUE);
+ ResearchLogger.richInputConnection_revertDoubleSpacePeriod(doubleSpace);
}
return true;
}
@@ -685,7 +685,7 @@ public final class RichInputConnection {
final String text = " " + textBeforeCursor.subSequence(0, 1);
commitText(text, 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.getInstance().onWordComplete(text, Long.MAX_VALUE);
+ ResearchLogger.richInputConnection_revertSwapPunctuation(text);
}
return true;
}
diff --git a/java/src/com/android/inputmethod/research/FixedLogBuffer.java b/java/src/com/android/inputmethod/research/FixedLogBuffer.java
new file mode 100644
index 000000000..f3302d856
--- /dev/null
+++ b/java/src/com/android/inputmethod/research/FixedLogBuffer.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.research;
+
+import java.util.LinkedList;
+
+/**
+ * A buffer that holds a fixed number of LogUnits.
+ *
+ * LogUnits are added in and shifted out in temporal order. Only a subset of the LogUnits are
+ * actual words; the other LogUnits do not count toward the word limit. Once the buffer reaches
+ * capacity, adding another LogUnit that is a word evicts the oldest LogUnits out one at a time to
+ * stay under the capacity limit.
+ *
+ * This variant of a LogBuffer has a limited memory footprint because of its limited size. This
+ * makes it useful, for example, for recording a window of the user's most recent actions in case
+ * they want to report an observed error that they do not know how to reproduce.
+ */
+public class FixedLogBuffer extends LogBuffer {
+ /* package for test */ int mWordCapacity;
+ // The number of members of mLogUnits that are actual words.
+ private int mNumActualWords;
+
+ /**
+ * Create a new LogBuffer that can hold a fixed number of LogUnits that are words (and
+ * unlimited number of non-word LogUnits), and that outputs its result to a researchLog.
+ *
+ * @param wordCapacity maximum number of words
+ */
+ public FixedLogBuffer(final int wordCapacity) {
+ super();
+ if (wordCapacity <= 0) {
+ throw new IllegalArgumentException("wordCapacity must be 1 or greater.");
+ }
+ mWordCapacity = wordCapacity;
+ mNumActualWords = 0;
+ }
+
+ protected int getNumActualWords() {
+ return mNumActualWords;
+ }
+
+ /**
+ * Adds a new LogUnit to the front of the LIFO queue, evicting existing LogUnit's
+ * (oldest first) if word capacity is reached.
+ */
+ @Override
+ public void shiftIn(final LogUnit newLogUnit) {
+ if (newLogUnit.getWord() == null) {
+ // This LogUnit isn't a word, so it doesn't count toward the word-limit.
+ super.shiftIn(newLogUnit);
+ return;
+ }
+ if (mNumActualWords == mWordCapacity) {
+ shiftOutThroughFirstWord();
+ }
+ super.shiftIn(newLogUnit);
+ mNumActualWords++; // Must be a word, or we wouldn't be here.
+ }
+
+ private void shiftOutThroughFirstWord() {
+ final LinkedList<LogUnit> logUnits = getLogUnits();
+ while (!logUnits.isEmpty()) {
+ final LogUnit logUnit = logUnits.removeFirst();
+ onShiftOut(logUnit);
+ if (logUnit.hasWord()) {
+ // Successfully shifted out a word-containing LogUnit and made space for the new
+ // LogUnit.
+ mNumActualWords--;
+ break;
+ }
+ }
+ }
+
+ /**
+ * Removes all LogUnits from the buffer without calling onShiftOut().
+ */
+ @Override
+ public void clear() {
+ super.clear();
+ mNumActualWords = 0;
+ }
+
+ /**
+ * Called when a LogUnit is removed from the LogBuffer as a result of a shiftIn. LogUnits are
+ * removed in the order entered. This method is not called when shiftOut is called directly.
+ *
+ * Base class does nothing; subclasses may override if they want to record non-privacy sensitive
+ * events that fall off the end.
+ */
+ protected void onShiftOut(final LogUnit logUnit) {
+ }
+
+ /**
+ * Called to deliberately remove the oldest LogUnit. Usually called when draining the
+ * LogBuffer.
+ */
+ @Override
+ public LogUnit shiftOut() {
+ if (isEmpty()) {
+ return null;
+ }
+ final LogUnit logUnit = super.shiftOut();
+ if (logUnit.hasWord()) {
+ mNumActualWords--;
+ }
+ return logUnit;
+ }
+}
diff --git a/java/src/com/android/inputmethod/research/JsonUtils.java b/java/src/com/android/inputmethod/research/JsonUtils.java
index cb331d7f9..1dfd01c69 100644
--- a/java/src/com/android/inputmethod/research/JsonUtils.java
+++ b/java/src/com/android/inputmethod/research/JsonUtils.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.research;
import android.content.SharedPreferences;
import android.util.JsonWriter;
+import android.view.MotionEvent;
import android.view.inputmethod.CompletionInfo;
import com.android.inputmethod.keyboard.Key;
@@ -27,6 +28,9 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import java.io.IOException;
import java.util.Map;
+/**
+ * Routines for mapping classes and variables to JSON representations for logging.
+ */
/* package */ class JsonUtils {
private JsonUtils() {
// This utility class is not publicly instantiable.
@@ -100,4 +104,54 @@ import java.util.Map;
jsonWriter.endArray();
jsonWriter.endObject();
}
+
+ /* package */ static void writeJson(final MotionEvent me, final JsonWriter jsonWriter)
+ throws IOException {
+ jsonWriter.beginObject();
+ jsonWriter.name("pointerIds");
+ jsonWriter.beginArray();
+ final int pointerCount = me.getPointerCount();
+ for (int index = 0; index < pointerCount; index++) {
+ jsonWriter.value(me.getPointerId(index));
+ }
+ jsonWriter.endArray();
+
+ jsonWriter.name("xyt");
+ jsonWriter.beginArray();
+ final int historicalSize = me.getHistorySize();
+ for (int index = 0; index < historicalSize; index++) {
+ jsonWriter.beginObject();
+ jsonWriter.name("t");
+ jsonWriter.value(me.getHistoricalEventTime(index));
+ jsonWriter.name("d");
+ jsonWriter.beginArray();
+ for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
+ jsonWriter.beginObject();
+ jsonWriter.name("x");
+ jsonWriter.value(me.getHistoricalX(pointerIndex, index));
+ jsonWriter.name("y");
+ jsonWriter.value(me.getHistoricalY(pointerIndex, index));
+ jsonWriter.endObject();
+ }
+ jsonWriter.endArray();
+ jsonWriter.endObject();
+ }
+ jsonWriter.beginObject();
+ jsonWriter.name("t");
+ jsonWriter.value(me.getEventTime());
+ jsonWriter.name("d");
+ jsonWriter.beginArray();
+ for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
+ jsonWriter.beginObject();
+ jsonWriter.name("x");
+ jsonWriter.value(me.getX(pointerIndex));
+ jsonWriter.name("y");
+ jsonWriter.value(me.getY(pointerIndex));
+ jsonWriter.endObject();
+ }
+ jsonWriter.endArray();
+ jsonWriter.endObject();
+ jsonWriter.endArray();
+ jsonWriter.endObject();
+ }
}
diff --git a/java/src/com/android/inputmethod/research/LogBuffer.java b/java/src/com/android/inputmethod/research/LogBuffer.java
index a3c3e89de..14e8d08a2 100644
--- a/java/src/com/android/inputmethod/research/LogBuffer.java
+++ b/java/src/com/android/inputmethod/research/LogBuffer.java
@@ -16,102 +16,44 @@
package com.android.inputmethod.research;
-import com.android.inputmethod.latin.CollectionUtils;
-
import java.util.LinkedList;
/**
- * A buffer that holds a fixed number of LogUnits.
+ * Maintain a FIFO queue of LogUnits.
*
- * LogUnits are added in and shifted out in temporal order. Only a subset of the LogUnits are
- * actual words; the other LogUnits do not count toward the word limit. Once the buffer reaches
- * capacity, adding another LogUnit that is a word evicts the oldest LogUnits out one at a time to
- * stay under the capacity limit.
+ * This class provides an unbounded queue. This is useful when the user is aware that their actions
+ * are being recorded, such as when they are trying to reproduce a bug. In this case, there should
+ * not be artificial restrictions on how many events that can be saved.
*/
public class LogBuffer {
- protected final LinkedList<LogUnit> mLogUnits;
- /* package for test */ int mWordCapacity;
- // The number of members of mLogUnits that are actual words.
- protected int mNumActualWords;
-
- /**
- * Create a new LogBuffer that can hold a fixed number of LogUnits that are words (and
- * unlimited number of non-word LogUnits), and that outputs its result to a researchLog.
- *
- * @param wordCapacity maximum number of words
- */
- LogBuffer(final int wordCapacity) {
- if (wordCapacity <= 0) {
- throw new IllegalArgumentException("wordCapacity must be 1 or greater.");
- }
- mLogUnits = CollectionUtils.newLinkedList();
- mWordCapacity = wordCapacity;
- mNumActualWords = 0;
- }
+ // TODO: Gracefully handle situations in which this LogBuffer is consuming too much memory.
+ // This may happen, for example, if the user has forgotten that data is being logged.
+ private final LinkedList<LogUnit> mLogUnits;
- /**
- * Adds a new LogUnit to the front of the LIFO queue, evicting existing LogUnit's
- * (oldest first) if word capacity is reached.
- */
- public void shiftIn(LogUnit newLogUnit) {
- if (newLogUnit.getWord() == null) {
- // This LogUnit isn't a word, so it doesn't count toward the word-limit.
- mLogUnits.add(newLogUnit);
- return;
- }
- if (mNumActualWords == mWordCapacity) {
- shiftOutThroughFirstWord();
- }
- mLogUnits.add(newLogUnit);
- mNumActualWords++; // Must be a word, or we wouldn't be here.
+ public LogBuffer() {
+ mLogUnits = new LinkedList<LogUnit>();
}
- private void shiftOutThroughFirstWord() {
- while (!mLogUnits.isEmpty()) {
- final LogUnit logUnit = mLogUnits.removeFirst();
- onShiftOut(logUnit);
- if (logUnit.hasWord()) {
- // Successfully shifted out a word-containing LogUnit and made space for the new
- // LogUnit.
- mNumActualWords--;
- break;
- }
- }
+ protected LinkedList<LogUnit> getLogUnits() {
+ return mLogUnits;
}
- /**
- * Removes all LogUnits from the buffer without calling onShiftOut().
- */
public void clear() {
mLogUnits.clear();
- mNumActualWords = 0;
}
- /**
- * Called when a LogUnit is removed from the LogBuffer as a result of a shiftIn. LogUnits are
- * removed in the order entered. This method is not called when shiftOut is called directly.
- *
- * Base class does nothing; subclasses may override.
- */
- protected void onShiftOut(LogUnit logUnit) {
+ public void shiftIn(final LogUnit logUnit) {
+ mLogUnits.add(logUnit);
+ }
+
+ public boolean isEmpty() {
+ return mLogUnits.isEmpty();
}
- /**
- * Called to deliberately remove the oldest LogUnit. Usually called when draining the
- * LogBuffer.
- */
public LogUnit shiftOut() {
- if (mLogUnits.isEmpty()) {
+ if (isEmpty()) {
return null;
}
- final LogUnit logUnit = mLogUnits.removeFirst();
- if (logUnit.hasWord()) {
- mNumActualWords--;
- }
- return logUnit;
- }
-
- public boolean isEmpty() {
- return mLogUnits.isEmpty();
+ return mLogUnits.removeFirst();
}
}
diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java
index 27c4027de..bcb144f5f 100644
--- a/java/src/com/android/inputmethod/research/LogUnit.java
+++ b/java/src/com/android/inputmethod/research/LogUnit.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.research;
import android.content.SharedPreferences;
import android.util.JsonWriter;
import android.util.Log;
+import android.view.MotionEvent;
import android.view.inputmethod.CompletionInfo;
import com.android.inputmethod.keyboard.Key;
@@ -189,6 +190,8 @@ import java.util.Map;
JsonUtils.writeJson((Key[]) value, jsonWriter);
} else if (value instanceof SuggestedWords) {
JsonUtils.writeJson((SuggestedWords) value, jsonWriter);
+ } else if (value instanceof MotionEvent) {
+ JsonUtils.writeJson((MotionEvent) value, jsonWriter);
} else if (value == null) {
jsonWriter.nullValue();
} else {
diff --git a/java/src/com/android/inputmethod/research/MainLogBuffer.java b/java/src/com/android/inputmethod/research/MainLogBuffer.java
index 0185e5fc0..bec21d7e0 100644
--- a/java/src/com/android/inputmethod/research/MainLogBuffer.java
+++ b/java/src/com/android/inputmethod/research/MainLogBuffer.java
@@ -22,15 +22,24 @@ import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.define.ProductionFlag;
+import java.util.LinkedList;
import java.util.Random;
-public class MainLogBuffer extends LogBuffer {
+/**
+ * Provide a log buffer of fixed length that enforces privacy restrictions.
+ *
+ * The privacy restrictions include making sure that no numbers are logged, that all logged words
+ * are in the dictionary, and that words are recorded infrequently enough that the user's meaning
+ * cannot be easily determined.
+ */
+public class MainLogBuffer extends FixedLogBuffer {
private static final String TAG = MainLogBuffer.class.getSimpleName();
private static final boolean DEBUG = false && ProductionFlag.IS_EXPERIMENTAL_DEBUG;
// The size of the n-grams logged. E.g. N_GRAM_SIZE = 2 means to sample bigrams.
private static final int N_GRAM_SIZE = 2;
- // The number of words between n-grams to omit from the log.
+ // The number of words between n-grams to omit from the log. If debugging, record 50% of all
+ // words. Otherwise, only record 10%.
private static final int DEFAULT_NUMBER_OF_WORDS_BETWEEN_SAMPLES =
ProductionFlag.IS_EXPERIMENTAL_DEBUG ? 2 : 18;
@@ -56,7 +65,7 @@ public class MainLogBuffer extends LogBuffer {
mWordsUntilSafeToSample = random.nextInt(mMinWordPeriod);
}
- public void setSuggest(Suggest suggest) {
+ public void setSuggest(final Suggest suggest) {
mSuggest = suggest;
}
@@ -108,9 +117,10 @@ public class MainLogBuffer extends LogBuffer {
}
// Check each word in the buffer. If any word poses a privacy threat, we cannot upload the
// complete buffer contents in detail.
- final int length = mLogUnits.size();
+ final LinkedList<LogUnit> logUnits = getLogUnits();
+ final int length = logUnits.size();
for (int i = 0; i < length; i++) {
- final LogUnit logUnit = mLogUnits.get(i);
+ final LogUnit logUnit = logUnits.get(i);
final String word = logUnit.getWord();
if (word == null) {
// Digits outside words are a privacy threat.
@@ -133,7 +143,7 @@ public class MainLogBuffer extends LogBuffer {
}
@Override
- protected void onShiftOut(LogUnit logUnit) {
+ protected void onShiftOut(final LogUnit logUnit) {
if (mResearchLog != null) {
mResearchLog.publish(logUnit, false /* isIncludingPrivateData */);
}
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index 709746ee3..b1484e696 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -154,6 +154,11 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
private LogUnit mCurrentLogUnit = new LogUnit();
+ // Gestured or tapped words may be committed after the gesture of the next word has started.
+ // To ensure that the gesture data of the next word is not associated with the previous word,
+ // thereby leaking private data, we store the time of the down event that started the second
+ // gesture, and when committing the earlier word, split the LogUnit.
+ private long mSavedDownEventTime;
private ResearchLogger() {
mStatistics = Statistics.getInstance();
}
@@ -377,7 +382,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mFeedbackLog = new ResearchLog(createLogFile(mFilesDir));
// LogBuffer is one more than FEEDBACK_WORD_BUFFER_SIZE, because it must also hold
// the feedback LogUnit itself.
- mFeedbackLogBuffer = new LogBuffer(FEEDBACK_WORD_BUFFER_SIZE + 1);
+ mFeedbackLogBuffer = new FixedLogBuffer(FEEDBACK_WORD_BUFFER_SIZE + 1);
}
}
@@ -638,7 +643,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mMainKeyboardView.invalidateAllKeys();
}
-
public void paintIndicator(KeyboardView view, Paint paint, Canvas canvas, int width,
int height) {
// TODO: Reimplement using a keyboard background image specific to the ResearchLogger
@@ -741,9 +745,15 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
return false;
}
+ /**
+ * Commit the portion of mCurrentLogUnit before maxTime as a worded logUnit.
+ *
+ * After this operation completes, mCurrentLogUnit will hold any logStatements that happened
+ * after maxTime.
+ */
private static final LogStatement LOGSTATEMENT_COMMIT_RECORD_SPLIT_WORDS =
new LogStatement("recordSplitWords", true, false);
- public void onWordComplete(final String word, final long maxTime) {
+ /* package for test */ void commitCurrentLogUnitAsWord(final String word, final long maxTime) {
final Dictionary dictionary = getDictionary();
if (word != null && word.length() > 0 && hasLetters(word)) {
mCurrentLogUnit.setWord(word);
@@ -757,6 +767,11 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mCurrentLogUnit = newLogUnit;
}
+ public void onWordFinished(final String word) {
+ commitCurrentLogUnitAsWord(word, mSavedDownEventTime);
+ mSavedDownEventTime = Long.MAX_VALUE;
+ }
+
private static int scrubDigitFromCodePoint(int codePoint) {
return Character.isDigit(codePoint) ? DIGIT_REPLACEMENT_CODEPOINT : codePoint;
}
@@ -880,8 +895,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
*
*/
private static final LogStatement LOGSTATEMENT_MAIN_KEYBOARD_VIEW_PROCESS_MOTION_EVENT =
- new LogStatement("MainKeyboardViewProcessMotionEvent", true, false, "action",
- "eventTime", "id", "x", "y", "size", "pressure");
+ new LogStatement("MotionEvent", true, false, "action", "MotionEvent");
public static void mainKeyboardView_processMotionEvent(final MotionEvent me, final int action,
final long eventTime, final int index, final int id, final int x, final int y) {
if (me != null) {
@@ -896,10 +910,14 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
case MotionEvent.ACTION_OUTSIDE: actionString = "OUTSIDE"; break;
default: actionString = "ACTION_" + action; break;
}
- final float size = me.getSize(index);
- final float pressure = me.getPressure(index);
- getInstance().enqueueEvent(LOGSTATEMENT_MAIN_KEYBOARD_VIEW_PROCESS_MOTION_EVENT,
- actionString, eventTime, id, x, y, size, pressure);
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.enqueueEvent(LOGSTATEMENT_MAIN_KEYBOARD_VIEW_PROCESS_MOTION_EVENT,
+ actionString, MotionEvent.obtain(me));
+ if (action == MotionEvent.ACTION_DOWN) {
+ // Subtract 1 from eventTime so the down event is included in the later
+ // LogUnit, not the earlier (the test is for inequality).
+ researchLogger.mSavedDownEventTime = eventTime - 1;
+ }
}
}
@@ -1038,6 +1056,16 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
}
/**
+ * Log a call to LatinIME.onTextInput().
+ *
+ * SystemResponse: Raw text is added to the TextView.
+ */
+ public static void latinIME_onTextInput(final String text) {
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.commitCurrentLogUnitAsWord(text, Long.MAX_VALUE);
+ }
+
+ /**
* Log a call to LatinIME.pickSuggestionManually().
*
* UserAction: The user has chosen a specific word from the suggestion strip.
@@ -1053,7 +1081,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
scrubDigitsFromString(replacedWord), index,
suggestion == null ? null : scrubbedWord, Constants.SUGGESTION_STRIP_COORDINATE,
Constants.SUGGESTION_STRIP_COORDINATE);
- researchLogger.onWordComplete(scrubbedWord, Long.MAX_VALUE);
+ researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, Long.MAX_VALUE);
researchLogger.mStatistics.recordManualSuggestion();
}
@@ -1069,7 +1097,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION, index, suggestion,
Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE);
- researchLogger.onWordComplete(suggestion, Long.MAX_VALUE);
+ researchLogger.commitCurrentLogUnitAsWord(suggestion, Long.MAX_VALUE);
}
/**
@@ -1098,8 +1126,20 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
*/
private static final LogStatement LOGSTATEMENT_LATINIME_SWAPSWAPPERANDSPACE =
new LogStatement("LatinIMESwapSwapperAndSpace", false, false);
- public static void latinIME_swapSwapperAndSpace() {
- getInstance().enqueueEvent(LOGSTATEMENT_LATINIME_SWAPSWAPPERANDSPACE);
+ public static void latinIME_swapSwapperAndSpace(final String text) {
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.commitCurrentLogUnitAsWord(text, Long.MAX_VALUE);
+ researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_SWAPSWAPPERANDSPACE);
+ }
+
+ /**
+ * Log a call to LatinIME.maybeDoubleSpacePeriod().
+ *
+ * SystemResponse: Two spaces have been replaced by period space.
+ */
+ public static void latinIME_maybeDoubleSpacePeriod(final String text) {
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.commitCurrentLogUnitAsWord(text, Long.MAX_VALUE);
}
/**
@@ -1156,6 +1196,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_REVERTCOMMIT, committedWord,
originallyTypedWord);
researchLogger.mStatistics.recordRevertCommit();
+ researchLogger.commitCurrentLogUnitAsWord(originallyTypedWord, Long.MAX_VALUE);
}
/**
@@ -1250,6 +1291,26 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
}
/**
+ * Log a call to RichInputConnection.revertDoubleSpacePeriod().
+ *
+ * SystemResponse: The IME has reverted ". ", which had previously replaced two typed spaces.
+ */
+ public static void richInputConnection_revertDoubleSpacePeriod(final String doubleSpace) {
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.commitCurrentLogUnitAsWord(doubleSpace, Long.MAX_VALUE);
+ }
+
+ /**
+ * Log a call to RichInputConnection.revertSwapPunctuation().
+ *
+ * SystemResponse: The IME has reverted a punctuation swap.
+ */
+ public static void richInputConnection_revertSwapPunctuation(final String text) {
+ final ResearchLogger researchLogger = getInstance();
+ researchLogger.commitCurrentLogUnitAsWord(text, Long.MAX_VALUE);
+ }
+
+ /**
* Log a call to LatinIME.commitCurrentAutoCorrection().
*
* SystemResponse: The IME has committed an auto-correction. An auto-correction changes the raw
@@ -1265,7 +1326,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_COMMITCURRENTAUTOCORRECTION,
scrubbedTypedWord, scrubbedAutoCorrection, separatorString);
- researchLogger.onWordComplete(scrubbedAutoCorrection, Long.MAX_VALUE);
+ researchLogger.commitCurrentLogUnitAsWord(scrubbedAutoCorrection, Long.MAX_VALUE);
}
private boolean isExpectingCommitText = false;
@@ -1284,7 +1345,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final ResearchLogger researchLogger = getInstance();
final String scrubbedWord = scrubDigitsFromString(committedWord.toString());
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_COMMIT_PARTIAL_TEXT);
- researchLogger.onWordComplete(scrubbedWord, lastTimestampOfWordData);
+ researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, lastTimestampOfWordData);
researchLogger.mStatistics.recordSplitWords();
}
@@ -1303,7 +1364,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
if (!researchLogger.isExpectingCommitText) {
researchLogger.enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTIONCOMMITTEXT,
newCursorPosition);
- researchLogger.onWordComplete(scrubbedWord, Long.MAX_VALUE);
+ researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, Long.MAX_VALUE);
}
researchLogger.isExpectingCommitText = false;
}