Log when a search result is selected or search is abandoned (2/3)

* Added Parcelable SearchState to hold info about the search
  results presented to the user and which selection was made.
* Added a Logger method to send a SearchEvent to clearcut.

Bug 26697731

Change-Id: I7848263ac845dc8aed733dd5d3e2efa1f52ef764
diff --git a/src/com/android/contacts/common/logging/Logger.java b/src/com/android/contacts/common/logging/Logger.java
index cb8a3f8..4e24caa 100644
--- a/src/com/android/contacts/common/logging/Logger.java
+++ b/src/com/android/contacts/common/logging/Logger.java
@@ -42,11 +42,11 @@
         if (logger != null) {
             logger.logScreenViewImpl(screenType);
         }
-
         final String screenName = ScreenEvent.getScreenNameWithTag(
                 activity.getClass().getSimpleName(), tag);
         AnalyticsUtil.sendScreenView(screenName, activity, tag);
     }
 
     public abstract void logScreenViewImpl(int screenType);
+    public abstract void logSearchEventImpl(SearchState searchState);
 }
diff --git a/src/com/android/contacts/common/logging/ScreenEvent.java b/src/com/android/contacts/common/logging/ScreenEvent.java
index 6d6306d..4d282d6 100644
--- a/src/com/android/contacts/common/logging/ScreenEvent.java
+++ b/src/com/android/contacts/common/logging/ScreenEvent.java
@@ -21,12 +21,17 @@
  * Stores constants identifying individual screens/dialogs/fragments in the application, and also
  * provides a mapping of integer id -> screen name mappings for analytics purposes.
  */
-public class ScreenEvent {
+public final class ScreenEvent {
     private static final String FRAGMENT_TAG_SEPARATOR = "#";
 
+    // Should match ContactsExtension.ScreenEvent.ScreenType values in
+    // http://cs/google3/logs/proto/wireless/android/contacts/contacts_extensions.proto
     public static final int UNKNOWN = 0;
-
     public static final int SEARCH = 1;
+    public static final int SEARCH_EXIT = 2;
+
+    public static final String TAG_SEARCH = "Search";
+    public static final String TAG_SEARCH_EXIT = "SearchExit";
 
     /**
      * Build a tagged version of the provided screenName if the tag is non-empty.
diff --git a/src/com/android/contacts/common/logging/SearchState.java b/src/com/android/contacts/common/logging/SearchState.java
new file mode 100644
index 0000000..f4719e4
--- /dev/null
+++ b/src/com/android/contacts/common/logging/SearchState.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 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.contacts.common.logging;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.common.base.Objects;
+
+/**
+ * Describes the results of a user search for a particular contact.
+ */
+public final class SearchState implements Parcelable {
+
+    /** The length of the query string input by the user. */
+    public int queryLength;
+
+    /** The number of partitions (groups of results) presented to the user. */
+    public int numPartitions;
+
+    /** The total number of results (across all partitions) presented to the user. */
+    public int numResults;
+
+    /** The number of results presented to the user in the partition that was selected. */
+    public int numResultsInSelectedPartition = -1;
+
+    /** The zero-based index of the partition in which the clicked query result resides. */
+    public int selectedPartition = -1;
+
+    /** The index of the clicked query result within its partition. */
+    public int selectedIndexInPartition = -1;
+
+    /**
+     * The zero-based index of the clicked query result among all results displayed to the user
+     * (across partitions).
+     */
+    public int selectedIndex = -1;
+
+    public static final Creator<SearchState> CREATOR = new Creator<SearchState>() {
+        @Override
+        public SearchState createFromParcel(Parcel in) {
+            return new SearchState(in);
+        }
+
+        @Override
+        public SearchState[] newArray(int size) {
+            return new SearchState[size];
+        }
+    };
+
+    public SearchState() {
+    }
+
+    protected SearchState(Parcel source) {
+        readFromParcel(source);
+    }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(this)
+                .add("queryLength", queryLength)
+                .add("numPartitions", numPartitions)
+                .add("numResults", numResults)
+                .add("numResultsInSelectedPartition", numResultsInSelectedPartition)
+                .add("selectedPartition", selectedPartition)
+                .add("selectedIndexInPartition", selectedIndexInPartition)
+                .add("selectedIndex", selectedIndex)
+                .toString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(queryLength);
+        dest.writeInt(numPartitions);
+        dest.writeInt(numResults);
+        dest.writeInt(numResultsInSelectedPartition);
+        dest.writeInt(selectedPartition);
+        dest.writeInt(selectedIndexInPartition);
+        dest.writeInt(selectedIndex);
+    }
+
+    private void readFromParcel(Parcel source) {
+        queryLength = source.readInt();
+        numPartitions = source.readInt();
+        numResults = source.readInt();
+        numResultsInSelectedPartition = source.readInt();
+        selectedPartition = source.readInt();
+        selectedIndexInPartition = source.readInt();
+        selectedIndex = source.readInt();
+    }
+}
diff --git a/src/com/android/contacts/commonbind/logging/ClearcutLoggerHelper.java b/src/com/android/contacts/commonbind/logging/ClearcutLoggerHelper.java
index 5cc2095..25c401c 100644
--- a/src/com/android/contacts/commonbind/logging/ClearcutLoggerHelper.java
+++ b/src/com/android/contacts/commonbind/logging/ClearcutLoggerHelper.java
@@ -16,6 +16,7 @@
 package com.android.contacts.commonbind.logging;
 
 import com.android.contacts.common.logging.Logger;
+import com.android.contacts.common.logging.SearchState;
 
 /**
  * No-op clearcut logger implementation.
@@ -37,4 +38,8 @@
     @Override
     public void logScreenViewImpl(int screenType) {
     }
+
+    @Override
+    public void logSearchEventImpl(SearchState searchState) {
+    }
 }