log through group level abstractions

For the groups:
- LogGroup.MOTION subfields now deteremined in Utils.writeMotionEvent() rather
  than in LatinKeyboardView.processMotionEvent()
- LogGroup.KEY is now logged throguh LatinIME.onCodeInput() rather than
  Utils.push().  This catches keys more generally, including modifiers, and
  records touch positions for everything.  Removed now-redundant
  Utils.writeBackspace() and Utils.writeChar().
- LogGroup.CORRECTION uses Utils.writeCorrection(), and formats instead of
  leaving this to callers.
- LogGroup.STATE_CHANGE uses Utils.writeStateChange().  Optional fields are
  still left to callers, as this group has more variety.

Formats have changed to incorporate new fields.

Minor housekeeping:

ENABLE_USABILITY_STUDY_LOG constants replaced with variable references, as
the logging feature can be changed in Settings and therefore dynamically
changes.

New log format:

20120322-111203.621+0900        1332382323621   s       [onStartInputView]      com.socialnmobile.dictapps.notepad.color.note   2131624043      147457  1140850694
20120322-111204.912+0900        1332382324912   m       [Down]  2782355 0       243     171     0.5666667       0.895
20120322-111204.975+0900        1332382324975   m       [Move]  2782419 0       240     171     0.6     1.17
20120322-111204.983+0900        1332382324983   m       [Move]  2782428 0       238     171     0.6     1.1899999
20120322-111204.992+0900        1332382324992   m       [Move]  2782437 0       236     171     0.6     1.1899999
20120322-111205.002+0900        1332382325002   m       [Move]  2782446 0       232     170     0.6     1.1899999
20120322-111205.012+0900        1332382325012   m       [Move]  2782456 0       227     169     0.6     1.125
20120322-111205.021+0900        1332382325021   m       [Move]  2782465 0       224     168     0.6     1.125
20120322-111205.031+0900        1332382325031   m       [Move]  2782475 0       221     167     0.6     0.895
20120322-111205.040+0900        1332382325040   m       [Move]  2782483 0       213     164     0.6     0.58
20120322-111205.047+0900        1332382325047   m       [Up]    2782491 0       213     164     0.6     0.58
20120322-111205.052+0900        1332382325052   k       'D'     243     171
20120322-111205.228+0900        1332382325228   m       [Down]  2782622 0       171     71      0.6333334       1.275
20120322-111205.243+0900        1332382325243   m       [Move]  2782677 0       178     69      0.6333334       1.275
20120322-111205.325+0900        1332382325325   m       [Up]    2782750 0       178     69      0.6333334       1.275
20120322-111205.333+0900        1332382325333   k       'e'     171     71
20120322-111205.509+0900        1332382325509   m       [Down]  2782936 0       265     139     0.53333336      0.885
20120322-111205.512+0900        1332382325512   m       [Move]  2782954 0       265     141     0.53333336      1.04
20120322-111205.552+0900        1332382325552   m       [Move]  2782973 0       265     143     0.5666667       1.14
20120322-111205.663+0900        1332382325663   m       [Up]    2783102 0       265     143     0.5666667       1.14
20120322-111205.668+0900        1332382325668   k       'f'     265     139
20120322-111206.140+0900        1332382326140   m       [Down]  2783584 0       348     352     0.53333336      0.675
20120322-111206.206+0900        1332382326206   m       [Move]  2783648 0       348     354     0.5666667       0.73499995
20120322-111206.223+0900        1332382326223   m       [Move]  2783666 0       348     356     0.5666667       0.545
20120322-111206.232+0900        1332382326232   m       [Up]    2783674 0       348     356     0.5666667       0.545
20120322-111206.236+0900        1332382326236   k       ' '     348     352
20120322-111206.245+0900        1332382326245   c       [----]  Def             -1

Bug: 6188932
Change-Id: Iea46a0c683f858b72005b8e81191ef1d70262dca
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index da7d01a..dca15de 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -54,7 +54,6 @@
 import com.android.inputmethod.latin.SubtypeUtils;
 import com.android.inputmethod.latin.Utils;
 import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils;
-import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils.LogGroup;
 
 import java.util.Locale;
 import java.util.WeakHashMap;
@@ -70,9 +69,6 @@
         SuddenJumpingTouchEventHandler.ProcessMotionEvent {
     private static final String TAG = LatinKeyboardView.class.getSimpleName();
 
-    // TODO: Kill process when the usability study mode was changed.
-    private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy;
-
     /** Listener for {@link KeyboardActionListener}. */
     private KeyboardActionListener mKeyboardActionListener;
 
@@ -672,6 +668,8 @@
         final int index = me.getActionIndex();
         final int id = me.getPointerId(index);
         final int x, y;
+        final float size = me.getSize(index);
+        final float pressure = me.getPressure(index);
         if (mMoreKeysPanel != null && id == mMoreKeysPanelPointerTrackerId) {
             x = mMoreKeysPanel.translateX((int)me.getX(index));
             y = mMoreKeysPanel.translateY((int)me.getY(index));
@@ -679,32 +677,11 @@
             x = (int)me.getX(index);
             y = (int)me.getY(index);
         }
-        if (ENABLE_USABILITY_STUDY_LOG) {
-            final String eventTag;
-            switch (action) {
-                case MotionEvent.ACTION_UP:
-                    eventTag = "[Up]";
-                    break;
-                case MotionEvent.ACTION_DOWN:
-                    eventTag = "[Down]";
-                    break;
-                case MotionEvent.ACTION_POINTER_UP:
-                    eventTag = "[PointerUp]";
-                    break;
-                case MotionEvent.ACTION_POINTER_DOWN:
-                    eventTag = "[PointerDown]";
-                    break;
-                case MotionEvent.ACTION_MOVE: // Skip this as being logged below
-                    eventTag = "";
-                    break;
-                default:
-                    eventTag = "[Action" + action + "]";
-                    break;
-            }
-            if (!TextUtils.isEmpty(eventTag)) {
-                UsabilityStudyLogUtils.getInstance().write(LogGroup.MOTION_EVENT,
-                        eventTag + eventTime + "," + id + "," + x + "," + y + ","
-                        + me.getSize(index) + "," + me.getPressure(index));
+        if (LatinImeLogger.sUsabilityStudy) {
+            if (action != MotionEvent.ACTION_MOVE) {
+                // Skip ACTION_MOVE events as they are logged below
+                UsabilityStudyLogUtils.getInstance().writeMotionEvent(action, eventTime, id, x,
+                        y, size, pressure);
             }
         }
 
@@ -764,11 +741,9 @@
                     py = (int)me.getY(i);
                 }
                 tracker.onMoveEvent(px, py, eventTime);
-                if (ENABLE_USABILITY_STUDY_LOG) {
-                    UsabilityStudyLogUtils.getInstance().write(
-                            LogGroup.MOTION_EVENT,
-                            "[Move]" + eventTime + "," + me.getPointerId(i) + "," + px + "," + py
-                                    + "," + me.getSize(i) + "," + me.getPressure(i));
+                if (LatinImeLogger.sUsabilityStudy) {
+                    UsabilityStudyLogUtils.getInstance().writeMotionEvent(action, eventTime, id,
+                            px, py, size, pressure);
                 }
             }
         } else {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index e67f0ea..48fb798 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -68,6 +68,7 @@
 import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.keyboard.KeyboardView;
 import com.android.inputmethod.keyboard.LatinKeyboardView;
+import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils;
 import com.android.inputmethod.latin.suggestions.SuggestionsView;
 
 import java.io.FileDescriptor;
@@ -1266,6 +1267,11 @@
             mDeleteCount = 0;
         }
         mLastKeyTime = when;
+
+        if (LatinImeLogger.sUsabilityStudy) {
+            UsabilityStudyLogUtils.getInstance().writeKeyEvent(primaryCode, x, y);
+        }
+
         final KeyboardSwitcher switcher = mKeyboardSwitcher;
         // The space state depends only on the last character pressed and its own previous
         // state. Here, we revert the space state to neutral if the key is actually modifying
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index 36a3d30..35b4f12 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -29,7 +29,9 @@
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Log;
+import android.view.MotionEvent;
 
+import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 
 import java.io.BufferedReader;
@@ -135,9 +137,6 @@
         // TODO: accept code points
         public void push(char c, int x, int y) {
             if (!mEnabled) return;
-            if (mUsabilityStudy) {
-                UsabilityStudyLogUtils.getInstance().writeChar(c, x, y);
-            }
             mCharBuf[mEnd] = c;
             mXBuf[mEnd] = x;
             mYBuf[mEnd] = y;
@@ -276,30 +275,57 @@
             }
         }
 
-        public static void writeBackSpace(int x, int y) {
-            UsabilityStudyLogUtils.getInstance().write(
-                    LogGroup.KEY, "<backspace>\t" + x + "\t" + y);
+        public void writeMotionEvent(final int action, final long eventTime, final int id,
+                final int x, final int y, final float size, final float pressure) {
+            final String eventTag;
+            switch (action) {
+                case MotionEvent.ACTION_CANCEL: eventTag = "[Cancel]"; break;
+                case MotionEvent.ACTION_UP: eventTag = "[Up]"; break;
+                case MotionEvent.ACTION_DOWN: eventTag = "[Down]"; break;
+                case MotionEvent.ACTION_POINTER_UP: eventTag = "[PointerUp]"; break;
+                case MotionEvent.ACTION_POINTER_DOWN: eventTag = "[PointerDown]"; break;
+                case MotionEvent.ACTION_MOVE: eventTag = "[Move]"; break;
+                case MotionEvent.ACTION_OUTSIDE: eventTag = "[Outside]"; break;
+                default: eventTag = "[Action" + action + "]"; break;
+            }
+            if (!TextUtils.isEmpty(eventTag)) {
+                StringBuilder sb = new StringBuilder();
+                sb.append(eventTag);
+                sb.append('\t'); sb.append(eventTime);
+                sb.append('\t'); sb.append(id);
+                sb.append('\t'); sb.append(x);
+                sb.append('\t'); sb.append(y);
+                sb.append('\t'); sb.append(size);
+                sb.append('\t'); sb.append(pressure);
+                write(LogGroup.MOTION_EVENT, sb.toString());
+            }
         }
 
-        public void writeChar(char c, int x, int y) {
-            String inputChar = String.valueOf(c);
-            switch (c) {
-                case '\n':
-                    inputChar = "<enter>";
-                    break;
-                case '\t':
-                    inputChar = "<tab>";
-                    break;
-                case ' ':
-                    inputChar = "<space>";
-                    break;
-            }
-            UsabilityStudyLogUtils.getInstance().write(LogGroup.KEY,
-                    inputChar + "\t" + x + "\t" + y);
+        public void writeKeyEvent(int code, int x, int y) {
+            final StringBuilder sb = new StringBuilder();
+            sb.append(Keyboard.printableCode(code));
+            sb.append('\t'); sb.append(x);
+            sb.append('\t'); sb.append(y);
+            write(LogGroup.KEY, sb.toString());
+
+            // TODO: replace with a cleaner flush+retrieve mechanism
             LatinImeLogger.onPrintAllUsabilityStudyLogs();
         }
 
-        public void write(final LogGroup logGroup, final String log) {
+        public void writeCorrection(String subgroup, String before, String after, int position) {
+            final StringBuilder sb = new StringBuilder();
+            sb.append(subgroup);
+            sb.append('\t'); sb.append(before);
+            sb.append('\t'); sb.append(after);
+            sb.append('\t'); sb.append(position);
+            write(LogGroup.CORRECTION, sb.toString());
+        }
+
+        public void writeStateChange(String subgroup, String details) {
+            write(LogGroup.STATE_CHANGE, subgroup + "\t" + details);
+        }
+
+        private void write(final LogGroup logGroup, final String log) {
             mLoggingHandler.post(new Runnable() {
                 @Override
                 public void run() {