diff options
Diffstat (limited to 'java/src/com/android/inputmethod/research')
5 files changed, 74 insertions, 44 deletions
diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java index 1a9a720f3..e91976a03 100644 --- a/java/src/com/android/inputmethod/research/LogUnit.java +++ b/java/src/com/android/inputmethod/research/LogUnit.java @@ -151,10 +151,10 @@ import java.util.List; continue; } // Only retrieve the jsonWriter if we need to. If we don't get this far, then - // researchLog.getValidJsonWriterLocked() will not ever be called, and the file - // will not have been opened for writing. + // researchLog.getInitializedJsonWriterLocked() will not ever be called, and the + // file will not have been opened for writing. if (jsonWriter == null) { - jsonWriter = researchLog.getValidJsonWriterLocked(); + jsonWriter = researchLog.getInitializedJsonWriterLocked(); outputLogUnitStart(jsonWriter, canIncludePrivateData); } logStatement.outputToLocked(jsonWriter, mTimeList.get(i), mValuesList.get(i)); diff --git a/java/src/com/android/inputmethod/research/LoggingUtils.java b/java/src/com/android/inputmethod/research/LoggingUtils.java new file mode 100644 index 000000000..1261d6780 --- /dev/null +++ b/java/src/com/android/inputmethod/research/LoggingUtils.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 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 android.view.MotionEvent; + +/* package */ class LoggingUtils { + private LoggingUtils() { + // This utility class is not publicly instantiable. + } + + /* package */ static String getMotionEventActionTypeString(final int actionType) { + switch (actionType) { + case MotionEvent.ACTION_CANCEL: return "CANCEL"; + case MotionEvent.ACTION_UP: return "UP"; + case MotionEvent.ACTION_DOWN: return "DOWN"; + case MotionEvent.ACTION_POINTER_UP: return "POINTER_UP"; + case MotionEvent.ACTION_POINTER_DOWN: return "POINTER_DOWN"; + case MotionEvent.ACTION_MOVE: return "MOVE"; + case MotionEvent.ACTION_OUTSIDE: return "OUTSIDE"; + default: return "ACTION_" + actionType; + } + } +} diff --git a/java/src/com/android/inputmethod/research/MainLogBuffer.java b/java/src/com/android/inputmethod/research/MainLogBuffer.java index 3a87bf1df..45b83dd76 100644 --- a/java/src/com/android/inputmethod/research/MainLogBuffer.java +++ b/java/src/com/android/inputmethod/research/MainLogBuffer.java @@ -64,15 +64,6 @@ public abstract class MainLogBuffer extends FixedLogBuffer { // The size of the n-grams logged. E.g. N_GRAM_SIZE = 2 means to sample bigrams. public static final int N_GRAM_SIZE = 2; - // Whether all words should be recorded, leaving unsampled word between bigrams. Useful for - // testing. - /* package for test */ static final boolean IS_LOGGING_EVERYTHING = false - && ProductionFlag.IS_EXPERIMENTAL_DEBUG; - - // The number of words between n-grams to omit from the log. - private static final int DEFAULT_NUMBER_OF_WORDS_BETWEEN_SAMPLES = - IS_LOGGING_EVERYTHING ? 0 : (DEBUG ? 2 : 18); - private Suggest mSuggest; private boolean mIsStopping = false; @@ -82,17 +73,21 @@ public abstract class MainLogBuffer extends FixedLogBuffer { // after a sample is taken. /* package for test */ int mNumWordsUntilSafeToSample; - public MainLogBuffer() { - super(N_GRAM_SIZE + DEFAULT_NUMBER_OF_WORDS_BETWEEN_SAMPLES); - mNumWordsBetweenNGrams = DEFAULT_NUMBER_OF_WORDS_BETWEEN_SAMPLES; - final Random random = new Random(); - mNumWordsUntilSafeToSample = DEBUG ? 0 : random.nextInt(mNumWordsBetweenNGrams + 1); + public MainLogBuffer(final int wordsBetweenSamples, final int numInitialWordsToIgnore) { + super(N_GRAM_SIZE + wordsBetweenSamples); + mNumWordsBetweenNGrams = wordsBetweenSamples; + mNumWordsUntilSafeToSample = DEBUG ? 0 : numInitialWordsToIgnore; } public void setSuggest(final Suggest suggest) { mSuggest = suggest; } + private Dictionary getDictionary() { + if (mSuggest == null || !mSuggest.hasMainDictionary()) return null; + return mSuggest.getMainDictionary(); + } + public void resetWordCounter() { mNumWordsUntilSafeToSample = mNumWordsBetweenNGrams; } @@ -114,7 +109,7 @@ public abstract class MainLogBuffer extends FixedLogBuffer { */ private boolean isSafeNGram(final ArrayList<LogUnit> logUnits, final int minNGramSize) { // Bypass privacy checks when debugging. - if (IS_LOGGING_EVERYTHING) { + if (ResearchLogger.IS_LOGGING_EVERYTHING) { if (mIsStopping) { return true; } @@ -137,16 +132,13 @@ public abstract class MainLogBuffer extends FixedLogBuffer { if (mNumWordsUntilSafeToSample > 0) { return false; } - if (mSuggest == null || !mSuggest.hasMainDictionary()) { - // Main dictionary is unavailable. Since we cannot check it, we cannot tell if a - // word is out-of-vocabulary or not. Therefore, we must judge the entire buffer - // contents to potentially pose a privacy risk. - return false; - } // Reload the dictionary in case it has changed (e.g., because the user has changed // languages). - final Dictionary dictionary = mSuggest.getMainDictionary(); + final Dictionary dictionary = getDictionary(); if (dictionary == null) { + // Main dictionary is unavailable. Since we cannot check it, we cannot tell if a + // word is out-of-vocabulary or not. Therefore, we must judge the entire buffer + // contents to potentially pose a privacy risk. return false; } @@ -220,10 +212,10 @@ public abstract class MainLogBuffer extends FixedLogBuffer { final boolean canIncludePrivateData); @Override - protected void shiftOutWords(int numWords) { - int oldNumActualWords = getNumActualWords(); + protected void shiftOutWords(final int numWords) { + final int oldNumActualWords = getNumActualWords(); super.shiftOutWords(numWords); - int numWordsShifted = oldNumActualWords - getNumActualWords(); + final int numWordsShifted = oldNumActualWords - getNumActualWords(); mNumWordsUntilSafeToSample -= numWordsShifted; if (DEBUG) { Log.d(TAG, "wordsUntilSafeToSample now at " + mNumWordsUntilSafeToSample); diff --git a/java/src/com/android/inputmethod/research/ResearchLog.java b/java/src/com/android/inputmethod/research/ResearchLog.java index 5114977d8..4dff17530 100644 --- a/java/src/com/android/inputmethod/research/ResearchLog.java +++ b/java/src/com/android/inputmethod/research/ResearchLog.java @@ -206,7 +206,7 @@ public class ResearchLog { * Return a JsonWriter for this ResearchLog. It is initialized the first time this method is * called. The cached value is returned in future calls. */ - public JsonWriter getValidJsonWriterLocked() { + public JsonWriter getInitializedJsonWriterLocked() { try { if (mJsonWriter == NULL_JSON_WRITER && mFile != null) { final FileOutputStream fos = diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java index 45212913e..25633d630 100644 --- a/java/src/com/android/inputmethod/research/ResearchLogger.java +++ b/java/src/com/android/inputmethod/research/ResearchLogger.java @@ -88,6 +88,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Random; import java.util.UUID; /** @@ -132,13 +133,21 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang private static final String USER_RECORDING_FILENAME_SUFFIX = ".txt"; private static final SimpleDateFormat TIMESTAMP_DATEFORMAT = new SimpleDateFormat("yyyyMMddHHmmssS", Locale.US); + // Whether all words should be recorded, leaving unsampled word between bigrams. Useful for + // testing. + /* package for test */ static final boolean IS_LOGGING_EVERYTHING = false + && ProductionFlag.IS_EXPERIMENTAL_DEBUG; + // The number of words between n-grams to omit from the log. + private static final int NUMBER_OF_WORDS_BETWEEN_SAMPLES = + IS_LOGGING_EVERYTHING ? 0 : (DEBUG ? 2 : 18); + // Whether to show an indicator on the screen that logging is on. Currently a very small red // dot in the lower right hand corner. Most users should not notice it. private static final boolean IS_SHOWING_INDICATOR = true; // Change the default indicator to something very visible. Currently two red vertical bars on // either side of they keyboard. private static final boolean IS_SHOWING_INDICATOR_CLEARLY = false || - (MainLogBuffer.IS_LOGGING_EVERYTHING && ProductionFlag.IS_EXPERIMENTAL_DEBUG); + (IS_LOGGING_EVERYTHING && ProductionFlag.IS_EXPERIMENTAL_DEBUG); // FEEDBACK_WORD_BUFFER_SIZE should add 1 because it must also hold the feedback LogUnit itself. public static final int FEEDBACK_WORD_BUFFER_SIZE = (Integer.MAX_VALUE - 1) + 1; @@ -464,11 +473,12 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } if (mMainLogBuffer == null) { mMainResearchLog = new ResearchLog(createLogFile(mFilesDir), mLatinIME); - mMainLogBuffer = new MainLogBuffer() { + final int numWordsToIgnore = new Random().nextInt(NUMBER_OF_WORDS_BETWEEN_SAMPLES + 1); + mMainLogBuffer = new MainLogBuffer(NUMBER_OF_WORDS_BETWEEN_SAMPLES, numWordsToIgnore) { @Override protected void publish(final ArrayList<LogUnit> logUnits, boolean canIncludePrivateData) { - canIncludePrivateData |= MainLogBuffer.IS_LOGGING_EVERYTHING; + canIncludePrivateData |= IS_LOGGING_EVERYTHING; final int length = logUnits.size(); for (int i = 0; i < length; i++) { final LogUnit logUnit = logUnits.get(i); @@ -1190,7 +1200,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang Integer.toHexString(editorInfo.inputType), Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId, Build.DISPLAY, Build.MODEL, prefs, versionCode, versionName, - OUTPUT_FORMAT_VERSION, MainLogBuffer.IS_LOGGING_EVERYTHING, + OUTPUT_FORMAT_VERSION, IS_LOGGING_EVERYTHING, ProductionFlag.IS_EXPERIMENTAL_DEBUG); } catch (NameNotFoundException e) { e.printStackTrace(); @@ -1226,17 +1236,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang 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) { - final String actionString; - switch (action) { - case MotionEvent.ACTION_CANCEL: actionString = "CANCEL"; break; - case MotionEvent.ACTION_UP: actionString = "UP"; break; - case MotionEvent.ACTION_DOWN: actionString = "DOWN"; break; - case MotionEvent.ACTION_POINTER_UP: actionString = "POINTER_UP"; break; - case MotionEvent.ACTION_POINTER_DOWN: actionString = "POINTER_DOWN"; break; - case MotionEvent.ACTION_MOVE: actionString = "MOVE"; break; - case MotionEvent.ACTION_OUTSIDE: actionString = "OUTSIDE"; break; - default: actionString = "ACTION_" + action; break; - } + final String actionString = LoggingUtils.getMotionEventActionTypeString(action); final ResearchLogger researchLogger = getInstance(); researchLogger.enqueueEvent(LOGSTATEMENT_MAIN_KEYBOARD_VIEW_PROCESS_MOTION_EVENT, actionString, false /* IS_LOGGING_RELATED */, MotionEvent.obtain(me)); |