Merge "Add Gmail timing to Analytics" into ub-gmail-ur12-dev
diff --git a/src/com/android/mail/analytics/Analytics.java b/src/com/android/mail/analytics/Analytics.java
index 551f468..778f3e0 100644
--- a/src/com/android/mail/analytics/Analytics.java
+++ b/src/com/android/mail/analytics/Analytics.java
@@ -85,6 +85,9 @@
public void sendEvent(String category, String action, String label, long value) {}
@Override
+ public void sendTiming(String category, long millis, String name, String label) {}
+
+ @Override
public void sendMenuItemEvent(String category, int itemResId, String label, long value) {}
@Override
diff --git a/src/com/android/mail/analytics/AnalyticsTimer.java b/src/com/android/mail/analytics/AnalyticsTimer.java
new file mode 100644
index 0000000..88bc270
--- /dev/null
+++ b/src/com/android/mail/analytics/AnalyticsTimer.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 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.mail.analytics;
+
+import android.os.SystemClock;
+
+import com.google.common.collect.Maps;
+
+import java.util.Map;
+
+/**
+ * Generic static singleton timer that keeps track of start time of various events. It logs the
+ * event's duration into Analytics using the provided naming information.
+ * This timer class supports multiple data points per event ("lapping").
+ *
+ * This class also holds some defaults constant IDs that we log. This provides an easy way to check
+ * what data we are logging as well as ensuring that the IDs are consistent when accessed by
+ * different classes.
+ */
+public class AnalyticsTimer {
+ public static final String OPEN_CONV_VIEW_FROM_LIST = "open_conv_from_list";
+
+ private final Map<String, Long> mStartTimes = Maps.newConcurrentMap();
+
+ // Static singleton class to ensure that you can access the timer from anywhere in the code
+ private static final AnalyticsTimer mInstance = new AnalyticsTimer();
+
+ private AnalyticsTimer() {}
+
+ public static AnalyticsTimer getInstance() {
+ return mInstance;
+ }
+
+ public void trackStart(String id) {
+ mStartTimes.put(id, SystemClock.uptimeMillis());
+ }
+
+ /**
+ * Logs the duration of the event with the provided category, name, and label.
+ * This method can be destructive, meaning that any additional calls without calling
+ * {@link AnalyticsTimer#trackStart(String)} will do nothing
+ * We allow the method to be destructive to prevent the following cases from happening:
+ * - recurring methods that call this with irrelevant mapped start times.
+ * - multiple entry ways to the method that calls this, thus misusing the
+ * start time.
+ * With destructive read, we ensure that we only log the event that we care about and only once.
+ * @param id id of the event
+ * @param isDestructive if you are done with this tag (used for multiple data points per tag)
+ * @param category category for analytics logging
+ * @param name name for analytics logging
+ * @param label label for analytics logging
+ */
+ public void logDuration(String id, boolean isDestructive, String category, String name,
+ String label) {
+ Long value = isDestructive ? mStartTimes.remove(id) : mStartTimes.get(id);
+ if (value != null) {
+ Analytics.getInstance().sendTiming(category, SystemClock.uptimeMillis() - value, name,
+ label);
+ }
+ }
+}
diff --git a/src/com/android/mail/analytics/Tracker.java b/src/com/android/mail/analytics/Tracker.java
index a96677c..6a9e710 100644
--- a/src/com/android/mail/analytics/Tracker.java
+++ b/src/com/android/mail/analytics/Tracker.java
@@ -27,6 +27,7 @@
void activityStart(Activity a);
void activityStop(Activity a);
void sendEvent(String category, String action, String label, long value);
+ void sendTiming(String category, long millis, String name, String label);
void sendMenuItemEvent(String category, int itemResId, String label, long value);
void sendView(String view);
void setCustomDimension(int index, String value);
diff --git a/src/com/android/mail/ui/ConversationListFragment.java b/src/com/android/mail/ui/ConversationListFragment.java
index d5ec425..6951537 100644
--- a/src/com/android/mail/ui/ConversationListFragment.java
+++ b/src/com/android/mail/ui/ConversationListFragment.java
@@ -39,6 +39,7 @@
import com.android.mail.ConversationListContext;
import com.android.mail.R;
import com.android.mail.analytics.Analytics;
+import com.android.mail.analytics.AnalyticsTimer;
import com.android.mail.browse.ConversationCursor;
import com.android.mail.browse.ConversationItemView;
import com.android.mail.browse.ConversationItemViewModel;
@@ -622,6 +623,7 @@
// this is a peek.
Analytics.getInstance().sendEvent("peek", null, null, mSelectedSet.size());
}
+ AnalyticsTimer.getInstance().trackStart(AnalyticsTimer.OPEN_CONV_VIEW_FROM_LIST);
viewConversation(position);
}
} else {
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index e1a24e7..5d54b94 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -47,6 +47,7 @@
import com.android.mail.FormattedDateBuilder;
import com.android.mail.R;
import com.android.mail.analytics.Analytics;
+import com.android.mail.analytics.AnalyticsTimer;
import com.android.mail.browse.ConversationContainer;
import com.android.mail.browse.ConversationContainer.OverlayPosition;
import com.android.mail.browse.ConversationMessage;
@@ -619,6 +620,10 @@
private void revealConversation() {
timerMark("revealing conversation");
mProgressController.dismissLoadingStatus(mOnProgressDismiss);
+ if (isUserVisible()) {
+ AnalyticsTimer.getInstance().logDuration(AnalyticsTimer.OPEN_CONV_VIEW_FROM_LIST,
+ true /* isDestructive */, "open_conversation", "from_list", null);
+ }
}
private boolean isLoadWaiting() {