Log query refinement to event log

A click on the query refine button will now generate an event such as:
I/qsb_click( 1719): [1,com.android.browser/.BookmarkSearch::|google:8:|google:8:|google:8:|google:8:|google:8:|google:8:|google:8:,web,7,1]

The final 1 distinguishes this from regular suggestion clicks.

Bug: 2836179
Change-Id: Ic0580dd1bf398524a0143e1df6c331dbeabfc448
diff --git a/src/com/android/quicksearchbox/EventLogLogger.java b/src/com/android/quicksearchbox/EventLogLogger.java
index 4dc6dd7..b1fc1b2 100644
--- a/src/com/android/quicksearchbox/EventLogLogger.java
+++ b/src/com/android/quicksearchbox/EventLogLogger.java
@@ -28,6 +28,9 @@
  */
 public class EventLogLogger implements Logger {
 
+    private static final int SUGGESTION_CLICK_TYPE_LAUNCH = 0;
+    private static final int SUGGESTION_CLICK_TYPE_REFINE = 1;
+
     private static final char LIST_SEPARATOR = '|';
 
     private final Context mContext;
@@ -69,10 +72,21 @@
 
     public void logSuggestionClick(int position,
             SuggestionCursor suggestionCursor, Collection<Corpus> queriedCorpora) {
+        logQsbClick(position, suggestionCursor, queriedCorpora, SUGGESTION_CLICK_TYPE_LAUNCH);
+    }
+
+    public void logRefine(int position, SuggestionCursor suggestionCursor,
+            Collection<Corpus> queriedCorpora) {
+        logQsbClick(position, suggestionCursor, queriedCorpora, SUGGESTION_CLICK_TYPE_REFINE);
+    }
+
+    private void logQsbClick(int position, SuggestionCursor suggestionCursor,
+            Collection<Corpus> queriedCorpora, int clickType) {
         String suggestions = getSuggestions(suggestionCursor);
         String corpora = getCorpusLogNames(queriedCorpora);
         int numChars = suggestionCursor.getUserQuery().length();
-        EventLogTags.writeQsbClick(position, suggestions, corpora, numChars);
+        EventLogTags.writeQsbClick(position, suggestions, corpora, numChars,
+                clickType);
     }
 
     public void logSearch(Corpus corpus, int startMethod, int numChars) {
diff --git a/src/com/android/quicksearchbox/EventLogTags.logtags b/src/com/android/quicksearchbox/EventLogTags.logtags
index 46b33b3..9b463dd 100644
--- a/src/com/android/quicksearchbox/EventLogTags.logtags
+++ b/src/com/android/quicksearchbox/EventLogTags.logtags
@@ -28,10 +28,13 @@
 #   TODO: define format of suggestion log names
 # @param queried_sources A pipe-separated list of the sources that were queried to produce
 #        the list of suggestions shown.
-# @param Number of characters in the query typed by the user
-# TODO: action key?
+# @param num_chars Number of characters in the query typed by the user
+# @param click_type
+#     SUGGESTION_CLICK_TYPE_LAUNCH = 0
+#     SUGGESTION_CLICK_TYPE_REFINE = 1
+#
 # TODO: latency?
-71002 qsb_click (position|1),(suggestions|3),(queried_sources|3),(num_chars|1)
+71002 qsb_click (position|1),(suggestions|3),(queried_sources|3),(num_chars|1),(click_type|1)
 
 # User launched a typed search
 # @param search_source Name of the selected search source
diff --git a/src/com/android/quicksearchbox/Logger.java b/src/com/android/quicksearchbox/Logger.java
index 5d6fc7f..7427593 100644
--- a/src/com/android/quicksearchbox/Logger.java
+++ b/src/com/android/quicksearchbox/Logger.java
@@ -48,6 +48,17 @@
             Collection<Corpus> queriedCorpora);
 
     /**
+     * The user clicked the query refine button.
+     *
+     * @param position 0-based position of the suggestion in the UI.
+     * @param suggestionCursor all the suggestions shown in the UI.
+     * @param queriedCorpora all corpora that were queried to produce the suggestions in
+     *        {@code suggestionCursor}, ordered by rank.
+     */
+    void logRefine(int position, SuggestionCursor suggestionCursor,
+            Collection<Corpus> queriedCorpora);
+
+    /**
      * The user launched a search.
      *
      * @param startMethod One of {@link #SEARCH_METHOD_BUTTON} or {@link #SEARCH_METHOD_KEYBOARD}.
diff --git a/src/com/android/quicksearchbox/NoLogger.java b/src/com/android/quicksearchbox/NoLogger.java
index 32d6a06..2347633 100644
--- a/src/com/android/quicksearchbox/NoLogger.java
+++ b/src/com/android/quicksearchbox/NoLogger.java
@@ -35,6 +35,10 @@
             SuggestionCursor suggestionCursor, Collection<Corpus> queriedCorpora) {
     }
 
+    public void logRefine(int position, SuggestionCursor suggestionCursor,
+            Collection<Corpus> queriedCorpora) {
+    }
+
     public void logSearch(Corpus corpus, int startMethod, int numChars) {
     }
 
diff --git a/src/com/android/quicksearchbox/SearchActivity.java b/src/com/android/quicksearchbox/SearchActivity.java
index 0e293ae..8adda0f 100644
--- a/src/com/android/quicksearchbox/SearchActivity.java
+++ b/src/com/android/quicksearchbox/SearchActivity.java
@@ -51,6 +51,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Set;
 
 /**
  * The main activity for Quick Search Box. Shows the search UI.
@@ -536,6 +537,25 @@
         return mSuggestionsAdapter.getCurrentSuggestions();
     }
 
+    protected SuggestionCursor getCurrentSuggestions(int position) {
+        SuggestionCursor suggestions = getCurrentSuggestions();
+        if (suggestions == null) {
+            return null;
+        }
+        int count = suggestions.getCount();
+        if (position < 0 || position >= count) {
+            Log.w(TAG, "Invalid suggestion position " + position + ", count = " + count);
+            return null;
+        }
+        suggestions.moveTo(position);
+        return suggestions;
+    }
+
+    protected Set<Corpus> getCurrentIncludedCorpora() {
+        Suggestions suggestions = mSuggestionsAdapter.getSuggestions();
+        return suggestions == null ? null : suggestions.getIncludedCorpora();
+    }
+
     protected void launchIntent(Intent intent) {
         if (intent == null) {
             return;
@@ -550,18 +570,14 @@
     }
 
     protected boolean launchSuggestion(int position) {
-        SuggestionCursor suggestions = getCurrentSuggestions();
-        if (position < 0 || position >= suggestions.getCount()) {
-            Log.w(TAG, "Tried to launch invalid suggestion " + position);
-            return false;
-        }
+        SuggestionCursor suggestions = getCurrentSuggestions(position);
+        if (suggestions == null) return false;
 
         if (DBG) Log.d(TAG, "Launching suggestion " + position);
         mTookAction = true;
 
         // Log suggestion click
-        Collection<Corpus> corpora = mSuggestionsAdapter.getSuggestions().getIncludedCorpora();
-        getLogger().logSuggestionClick(position, suggestions, corpora);
+        getLogger().logSuggestionClick(position, suggestions, getCurrentIncludedCorpora());
 
         // Create shortcut
         getShortcutRepository().reportClick(suggestions, position);
@@ -588,6 +604,27 @@
         return false;
     }
 
+    protected void refineSuggestion(int position) {
+        if (DBG) Log.d(TAG, "query refine clicked, pos " + position);
+        SuggestionCursor suggestions = getCurrentSuggestions(position);
+        if (suggestions == null) {
+            return;
+        }
+        String query = suggestions.getSuggestionQuery();
+        if (TextUtils.isEmpty(query)) {
+            return;
+        }
+
+        // Log refine click
+        getLogger().logRefine(position, suggestions, getCurrentIncludedCorpora());
+
+        // Put query + space in query text view
+        String queryWithSpace = query + ' ';
+        setQuery(queryWithSpace, false);
+        updateSuggestions(queryWithSpace);
+        mQueryTextView.requestFocus();
+    }
+
     protected int getSelectedPosition() {
         return mSuggestionsView.getSelectedPosition();
     }
@@ -801,18 +838,7 @@
        }
 
        public void onSuggestionQueryRefineClicked(int position) {
-           if (DBG) Log.d(TAG, "query refine clicked, pos " + position);
-           SuggestionCursor suggestions = getCurrentSuggestions();
-           if (suggestions != null) {
-               suggestions.moveTo(position);
-               String query = suggestions.getSuggestionQuery();
-               if (!TextUtils.isEmpty(query)) {
-                   query += " ";
-                   setQuery(query, false);
-                   updateSuggestions(query);
-                   mQueryTextView.requestFocus();
-               }
-           }
+           refineSuggestion(position);
        }
     }