diff options
Diffstat (limited to 'java/src/com/android/inputmethod/research')
6 files changed, 292 insertions, 99 deletions
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; } |