Merge "researchLogger detail on IME sessions"

This commit is contained in:
Kurt Partridge 2012-04-19 20:35:21 -07:00 committed by Android (Google) Code Review
commit 4d43d6f96e
4 changed files with 109 additions and 79 deletions

View file

@ -467,6 +467,9 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon(keyboard.mIconsSet) : null; mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon(keyboard.mIconsSet) : null;
final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
mSpacebarTextSize = keyHeight * mSpacebarTextRatio; mSpacebarTextSize = keyHeight * mSpacebarTextRatio;
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinKeyboardView_setKeyboard(keyboard);
}
} }
/** /**

View file

@ -634,7 +634,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
editorInfo.inputType, editorInfo.imeOptions)); editorInfo.inputType, editorInfo.imeOptions));
} }
if (ProductionFlag.IS_EXPERIMENTAL) { if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_onStartInputViewInternal(editorInfo); ResearchLogger.latinIME_onStartInputViewInternal(editorInfo, mPrefs);
} }
if (InputAttributes.inPrivateImeOptions(null, NO_MICROPHONE_COMPAT, editorInfo)) { if (InputAttributes.inPrivateImeOptions(null, NO_MICROPHONE_COMPAT, editorInfo)) {
Log.w(TAG, "Deprecated private IME option specified: " Log.w(TAG, "Deprecated private IME option specified: "

View file

@ -18,10 +18,12 @@ package com.android.inputmethod.latin;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.Process; import android.os.Process;
import android.os.SystemClock; import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -45,6 +47,7 @@ import java.nio.ByteBuffer;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Map;
/** /**
* Logs the use of the LatinIME keyboard. * Logs the use of the LatinIME keyboard.
@ -68,7 +71,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
* Isolates management of files. This variable should never be null, but can be changed * Isolates management of files. This variable should never be null, but can be changed
* to support testing. * to support testing.
*/ */
private LogFileManager mLogFileManager; /* package */ LogFileManager mLogFileManager;
/** /**
* Manages the file(s) that stores the logs. * Manages the file(s) that stores the logs.
@ -93,63 +96,53 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mIms = ims; mIms = ims;
} }
public synchronized boolean createLogFile() { public synchronized void createLogFile() throws IOException {
try { createLogFile(DEFAULT_FILENAME);
return createLogFile(DEFAULT_FILENAME);
} catch (IOException e) {
e.printStackTrace();
Log.w(TAG, e);
return false;
}
} }
public synchronized boolean createLogFile(final SharedPreferences prefs) { public synchronized void createLogFile(final SharedPreferences prefs)
try { throws IOException {
final String filename = final String filename =
prefs.getString(RESEARCH_LOG_FILENAME_KEY, DEFAULT_FILENAME); prefs.getString(RESEARCH_LOG_FILENAME_KEY, DEFAULT_FILENAME);
return createLogFile(filename); createLogFile(filename);
} catch (IOException e) {
Log.w(TAG, e);
e.printStackTrace();
}
return false;
} }
public synchronized boolean createLogFile(final String filename) public synchronized void createLogFile(final String filename)
throws IOException { throws IOException {
if (mIms == null) { if (mIms == null) {
Log.w(TAG, "InputMethodService is not configured. Logging is off."); final String msg = "InputMethodService is not configured. Logging is off.";
return false; Log.w(TAG, msg);
throw new IOException(msg);
} }
final File filesDir = mIms.getFilesDir(); final File filesDir = mIms.getFilesDir();
if (filesDir == null || !filesDir.exists()) { if (filesDir == null || !filesDir.exists()) {
Log.w(TAG, "Storage directory does not exist. Logging is off."); final String msg = "Storage directory does not exist. Logging is off.";
return false; Log.w(TAG, msg);
throw new IOException(msg);
} }
close(); close();
final File file = new File(filesDir, filename); final File file = new File(filesDir, filename);
mFile = file; mFile = file;
file.setReadable(false, false);
boolean append = true; boolean append = true;
if (file.exists() && file.lastModified() + LOGFILE_PURGE_INTERVAL < if (file.exists() && file.lastModified() + LOGFILE_PURGE_INTERVAL <
System.currentTimeMillis()) { System.currentTimeMillis()) {
append = false; append = false;
} }
mPrintWriter = new PrintWriter(new BufferedWriter(new FileWriter(file, append)), true); mPrintWriter = new PrintWriter(new BufferedWriter(new FileWriter(file, append)), true);
return true;
} }
public synchronized boolean append(final String s) { public synchronized boolean append(final String s) {
final PrintWriter printWriter = mPrintWriter; PrintWriter printWriter = mPrintWriter;
if (printWriter == null) { if (printWriter == null || !mFile.exists()) {
if (DEBUG) { if (DEBUG) {
Log.w(TAG, "PrintWriter is null... attempting to create default log file"); Log.w(TAG, "PrintWriter is null... attempting to create default log file");
} }
if (!createLogFile()) { try {
if (DEBUG) { createLogFile();
Log.w(TAG, "Failed to create log file. Not logging."); printWriter = mPrintWriter;
return false; } catch (IOException e) {
} Log.w(TAG, "Failed to create log file. Not logging.");
return false;
} }
} }
printWriter.print(s); printWriter.print(s);
@ -161,9 +154,15 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
if (mPrintWriter != null) { if (mPrintWriter != null) {
mPrintWriter.close(); mPrintWriter.close();
mPrintWriter = null; mPrintWriter = null;
if (DEBUG) {
Log.d(TAG, "logfile closed");
}
} }
if (mFile != null) { if (mFile != null) {
mFile.delete(); mFile.delete();
if (DEBUG) {
Log.d(TAG, "logfile deleted");
}
mFile = null; mFile = null;
} }
} }
@ -173,6 +172,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mPrintWriter.close(); mPrintWriter.close();
mPrintWriter = null; mPrintWriter = null;
mFile = null; mFile = null;
if (DEBUG) {
Log.d(TAG, "logfile closed");
}
} }
} }
@ -240,12 +242,16 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
sInstance.initInternal(ims, prefs); sInstance.initInternal(ims, prefs);
} }
public void initInternal(final InputMethodService ims, final SharedPreferences prefs) { /* package */ void initInternal(final InputMethodService ims, final SharedPreferences prefs) {
mIms = ims; mIms = ims;
final LogFileManager logFileManager = mLogFileManager; final LogFileManager logFileManager = mLogFileManager;
if (logFileManager != null) { if (logFileManager != null) {
logFileManager.init(ims); logFileManager.init(ims);
logFileManager.createLogFile(prefs); try {
logFileManager.createLogFile(prefs);
} catch (IOException e) {
e.printStackTrace();
}
} }
if (prefs != null) { if (prefs != null) {
sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false); sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false);
@ -253,19 +259,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
} }
} }
/**
* Change to a different logFileManager.
*
* @throws IllegalArgumentException if logFileManager is null
*/
void setLogFileManager(final LogFileManager manager) {
if (manager == null) {
throw new IllegalArgumentException("warning: trying to set null logFileManager");
} else {
mLogFileManager = manager;
}
}
/** /**
* Represents a category of logging events that share the same subfield structure. * Represents a category of logging events that share the same subfield structure.
*/ */
@ -377,6 +370,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
private static final boolean LATINKEYBOARDVIEW_ONLONGPRESS_ENABLED = DEFAULT_ENABLED; private static final boolean LATINKEYBOARDVIEW_ONLONGPRESS_ENABLED = DEFAULT_ENABLED;
private static final boolean LATINKEYBOARDVIEW_ONPROCESSMOTIONEVENT_ENABLED private static final boolean LATINKEYBOARDVIEW_ONPROCESSMOTIONEVENT_ENABLED
= DEFAULT_ENABLED; = DEFAULT_ENABLED;
private static final boolean LATINKEYBOARDVIEW_SETKEYBOARD_ENABLED = DEFAULT_ENABLED;
private static final boolean POINTERTRACKER_CALLLISTENERONCANCELINPUT_ENABLED private static final boolean POINTERTRACKER_CALLLISTENERONCANCELINPUT_ENABLED
= DEFAULT_ENABLED; = DEFAULT_ENABLED;
private static final boolean POINTERTRACKER_CALLLISTENERONCODEINPUT_ENABLED private static final boolean POINTERTRACKER_CALLLISTENERONCODEINPUT_ENABLED
@ -413,12 +407,21 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "Write: " + '[' + logGroup.mLogString + ']' + log); Log.d(TAG, "Write: " + '[' + logGroup.mLogString + ']' + log);
} }
if (mLogFileManager.append(builder.toString())) { final String s = builder.toString();
if (mLogFileManager.append(s)) {
// success // success
} else { } else {
if (DEBUG) { if (DEBUG) {
Log.w(TAG, "Unable to write to log."); Log.w(TAG, "Unable to write to log.");
} }
// perhaps logfile was deleted. try to recreate and relog.
try {
mLogFileManager.createLogFile(PreferenceManager
.getDefaultSharedPreferences(mIms));
mLogFileManager.append(s);
} catch (IOException e) {
e.printStackTrace();
}
} }
} }
}); });
@ -474,6 +477,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
} }
} }
// TODO: Remove keyboardState logging that is redundant in light of
// latinKeyboardView_setKeyboard
public static void keyboardState_onCancelInput(final boolean isSinglePointer, public static void keyboardState_onCancelInput(final boolean isSinglePointer,
final KeyboardState keyboardState) { final KeyboardState keyboardState) {
if (UnsLogGroup.KEYBOARDSTATE_ONCANCELINPUT_ENABLED) { if (UnsLogGroup.KEYBOARDSTATE_ONCANCELINPUT_ENABLED) {
@ -637,14 +642,22 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
} }
} }
public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo) { public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo,
final SharedPreferences prefs) {
if (UnsLogGroup.LATINIME_ONSTARTINPUTVIEWINTERNAL_ENABLED) { if (UnsLogGroup.LATINIME_ONSTARTINPUTVIEWINTERNAL_ENABLED) {
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
builder.append("onStartInputView: editorInfo:"); builder.append("onStartInputView: editorInfo:");
builder.append("inputType="); builder.append("\tinputType=");
builder.append(editorInfo.inputType); builder.append(Integer.toHexString(editorInfo.inputType));
builder.append("imeOptions="); builder.append("\timeOptions=");
builder.append(editorInfo.imeOptions); builder.append(Integer.toHexString(editorInfo.imeOptions));
builder.append("\tdisplay="); builder.append(Build.DISPLAY);
builder.append("\tmodel="); builder.append(Build.MODEL);
for (Map.Entry<String,?> entry : prefs.getAll().entrySet()) {
builder.append("\t" + entry.getKey());
Object value = entry.getValue();
builder.append("=" + ((value == null) ? "<null>" : value.toString()));
}
logUnstructured("LatinIME_onStartInputViewInternal", builder.toString()); logUnstructured("LatinIME_onStartInputViewInternal", builder.toString());
} }
} }
@ -745,6 +758,42 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
} }
} }
public static void latinKeyboardView_setKeyboard(final Keyboard keyboard) {
if (UnsLogGroup.LATINKEYBOARDVIEW_SETKEYBOARD_ENABLED) {
StringBuilder builder = new StringBuilder();
builder.append("id=");
builder.append(keyboard.mId);
builder.append("\tw=");
builder.append(keyboard.mOccupiedWidth);
builder.append("\th=");
builder.append(keyboard.mOccupiedHeight);
builder.append("\tkeys=[");
boolean first = true;
for (Key key : keyboard.mKeys) {
if (first) {
first = false;
} else {
builder.append(",");
}
builder.append("{code:");
builder.append(key.mCode);
builder.append(",altCode:");
builder.append(key.mAltCode);
builder.append(",x:");
builder.append(key.mX);
builder.append(",y:");
builder.append(key.mY);
builder.append(",w:");
builder.append(key.mWidth);
builder.append(",h:");
builder.append(key.mHeight);
builder.append("}");
}
builder.append("]");
logUnstructured("LatinKeyboardView_setKeyboard", builder.toString());
}
}
public static void latinIME_revertCommit(final String originallyTypedWord) { public static void latinIME_revertCommit(final String originallyTypedWord) {
if (UnsLogGroup.LATINIME_REVERTCOMMIT_ENABLED) { if (UnsLogGroup.LATINIME_REVERTCOMMIT_ENABLED) {
logUnstructured("LatinIME_revertCommit", originallyTypedWord); logUnstructured("LatinIME_revertCommit", originallyTypedWord);

View file

@ -107,31 +107,15 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> {
return setBooleanPreference(PREF_DEBUG_MODE, value, false); return setBooleanPreference(PREF_DEBUG_MODE, value, false);
} }
// overload this to configure preferences in a way specific to a subclass's tests
protected void configurePreferences() {
// please avoid changing preferences any more than is necessary, as an interruption
// during a test will leave the user's preferences in a bad state.
}
// restore any preferences set in configurePreferences()
protected void restorePreferences() {
// undo any effects from configurePreferences()
}
@Override @Override
protected void setUp() { protected void setUp() throws Exception {
try { super.setUp();
super.setUp();
} catch (Exception e) {
e.printStackTrace();
}
mTextView = new TextView(getContext()); mTextView = new TextView(getContext());
mTextView.setInputType(InputType.TYPE_CLASS_TEXT); mTextView.setInputType(InputType.TYPE_CLASS_TEXT);
mTextView.setEnabled(true); mTextView.setEnabled(true);
setupService(); setupService();
mLatinIME = getService(); mLatinIME = getService();
final boolean previousDebugSetting = setDebugMode(true); final boolean previousDebugSetting = setDebugMode(true);
configurePreferences();
mLatinIME.onCreate(); mLatinIME.onCreate();
setDebugMode(previousDebugSetting); setDebugMode(previousDebugSetting);
initSubtypeMap(); initSubtypeMap();
@ -153,12 +137,6 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> {
changeLanguage("en_US"); changeLanguage("en_US");
} }
@Override
protected void tearDown() throws Exception {
super.tearDown();
restorePreferences();
}
private void initSubtypeMap() { private void initSubtypeMap() {
final InputMethodManager imm = (InputMethodManager)mLatinIME.getSystemService( final InputMethodManager imm = (InputMethodManager)mLatinIME.getSystemService(
Context.INPUT_METHOD_SERVICE); Context.INPUT_METHOD_SERVICE);