Merge "researchLogger detail on IME sessions"
This commit is contained in:
commit
4d43d6f96e
4 changed files with 109 additions and 79 deletions
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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: "
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue