Log contacts screen events to clearcut 1/2

* Allow the ContactsApplication to be exteneded
* Add an abstract Logger class to be the primary
  utility to log events. Currently it goes to both
  clearcut and google analytics (like Dialer).
* Fix a broken intent in the all intents test
  activity.

Bug 18388581

Change-Id: I8f2d555b06484fecc2fdb6517847c12a0874fd2f
diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java
index 798614c..f0dc91b 100644
--- a/src/com/android/contacts/ContactsApplication.java
+++ b/src/com/android/contacts/ContactsApplication.java
@@ -29,16 +29,13 @@
 import android.provider.ContactsContract.Contacts;
 import android.util.Log;
 
-import com.android.contacts.common.ContactPhotoManager;
-import com.android.contacts.common.list.ContactListFilterController;
-import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.testing.InjectedServices;
 import com.android.contacts.common.util.Constants;
 import com.android.contacts.commonbind.analytics.AnalyticsUtil;
 
 import com.google.common.annotations.VisibleForTesting;
 
-public final class ContactsApplication extends Application {
+public class ContactsApplication extends Application {
     private static final boolean ENABLE_LOADER_LOG = false; // Don't submit with true
     private static final boolean ENABLE_FRAGMENT_LOG = false; // Don't submit with true
 
@@ -48,8 +45,6 @@
      * To enable: adb shell setprop log.tag.ContactsStrictMode DEBUG
      */
     public static final String STRICT_MODE_TAG = "ContactsStrictMode";
-    private ContactPhotoManager mContactPhotoManager;
-    private ContactListFilterController mContactListFilterController;
 
     /**
      * Overrides the system services with mocks for testing.
diff --git a/src/com/android/contacts/logging/Logger.java b/src/com/android/contacts/logging/Logger.java
new file mode 100644
index 0000000..521def7
--- /dev/null
+++ b/src/com/android/contacts/logging/Logger.java
@@ -0,0 +1,57 @@
+/*
+ * 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.logging;
+
+import android.app.Activity;
+import android.app.Application;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.contacts.commonbind.analytics.AnalyticsUtil;
+import com.android.contactsbind.ClearcutLoggerHelper;
+
+/**
+ * Logs analytics events.
+ */
+public abstract class Logger {
+    public static final String TAG = "Logger";
+
+    public static Logger getInstance() {
+        return ClearcutLoggerHelper.getInstance();
+    }
+
+    /**
+     * Logs an event indicating that a screen was displayed.
+     *
+     * @param screenType integer identifier of the displayed screen
+     * @param activity Parent activity of the displayed screen.
+     */
+    public static void logScreenView(int screenType, Activity activity) {
+        final Logger logger = getInstance();
+        if (logger != null) {
+            logger.logScreenViewImpl(screenType);
+        }
+
+        final String screenName = ScreenEvent.getScreenName(screenType);
+        if (TextUtils.isEmpty(screenName)) {
+            Log.w(TAG, "Unknown screenType: " + screenType);
+        } else {
+            AnalyticsUtil.sendScreenView(screenName, activity, /* tag */ null);
+        }
+    }
+
+    public abstract void logScreenViewImpl(int screenType);
+}
diff --git a/src/com/android/contacts/logging/ScreenEvent.java b/src/com/android/contacts/logging/ScreenEvent.java
new file mode 100644
index 0000000..5b1b6bb
--- /dev/null
+++ b/src/com/android/contacts/logging/ScreenEvent.java
@@ -0,0 +1,70 @@
+/*
+ * 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.logging;
+
+import android.text.TextUtils;
+
+import com.android.contacts.activities.PeopleActivity;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 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 {
+    private static final Map<Integer, String> sScreenNameMap = new HashMap<>();
+
+    private static final String FRAGMENT_TAG_SEPARATOR = "#";
+
+    public static final int UNKNOWN = 0;
+
+    public static final int SEARCH = 1;
+
+    static {
+        sScreenNameMap.put(SEARCH, getScreenNameWithTag(
+                PeopleActivity.class.getSimpleName(), "Search"));
+    }
+
+    /**
+     * For a given screen type, returns the actual screen name that is used for logging/analytics
+     * purposes.
+     *
+     * @param screenType unique ID of a type of screen
+     *
+     * @return the tagged version of the screen name corresponding to the provided screenType,
+     *         or {@null} if the provided screenType is unknown.
+     */
+    public static String getScreenName(int screenType) {
+        return sScreenNameMap.get(screenType);
+    }
+
+    /**
+     * Build a tagged version of the provided screenName if the tag is non-empty.
+     *
+     * @param screenName Name of the screen.
+     * @param tag Optional tag describing the screen.
+     * @return the unchanged screenName if the tag is {@code null} or empty, the tagged version of
+     *         the screenName otherwise.
+     */
+    public static String getScreenNameWithTag(String screenName, String tag) {
+        if (TextUtils.isEmpty(tag)) {
+            return screenName;
+        }
+        return screenName + FRAGMENT_TAG_SEPARATOR + tag;
+    }
+}
diff --git a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
index fcd3e8b..6514d23 100644
--- a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
+++ b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
@@ -47,7 +47,7 @@
 
 import com.android.contacts.tests.R;
 
-import com.google.common.collect.Lists;
+import java.util.ArrayList;
 
 /**
  * An activity that provides access to various modes of the contacts application.
@@ -631,6 +631,10 @@
         row2.put(Email.LABEL, "Green Bot");
         row2.put(Email.ADDRESS, "android@android.com");
 
-        intent.putParcelableArrayListExtra(Insert.DATA, Lists.newArrayList(row1, row2));
+        final ArrayList<ContentValues> rows = new ArrayList<>();
+        rows.add(row1);
+        rows.add(row2);
+
+        intent.putParcelableArrayListExtra(Insert.DATA, rows);
     }
 }