misc analytics
* lots of new menu items
* log auto-advance setting
* log message header taps
* log photo-viewer menu items
* log conversation views (including enclosing label, synced state,
message count)
* log folder views (including bucketed total counts)
* log pager swipes (including folder type)
Bug: 11253673
Change-Id: Iffdcbf19b202fbb3b6b33e0f7f0e9e4c24fa948d
diff --git a/src/com/android/mail/analytics/Analytics.java b/src/com/android/mail/analytics/Analytics.java
index 73e6a06..551f468 100644
--- a/src/com/android/mail/analytics/Analytics.java
+++ b/src/com/android/mail/analytics/Analytics.java
@@ -47,6 +47,8 @@
public static final int CD_INDEX_REPLY_ALL_SETTING = 7;
+ public static final int CD_INDEX_AUTO_ADVANCE = 8;
+
private static Tracker sInstance;
private Analytics() {
diff --git a/src/com/android/mail/analytics/AnalyticsUtils.java b/src/com/android/mail/analytics/AnalyticsUtils.java
index a1c162e..ab74d34 100644
--- a/src/com/android/mail/analytics/AnalyticsUtils.java
+++ b/src/com/android/mail/analytics/AnalyticsUtils.java
@@ -93,6 +93,8 @@
s = "mark_unread";
} else if (id == R.id.show_original) {
s = "show_original";
+ } else if (id == R.id.add_file_attachment) {
+ s = "add_file_attachment";
} else if (id == R.id.add_photo_attachment) {
s = "add_photo_attachment";
} else if (id == R.id.add_cc_bcc) {
@@ -105,6 +107,38 @@
s = "compose_discard_draft";
} else if (id == R.id.search) {
s = "search";
+ } else if (id == R.id.print_all) {
+ s = "print_all";
+ } else if (id == R.id.print_message) {
+ s = "print_message";
+ } else if (id == R.id.star) {
+ s = "star";
+ } else if (id == R.id.remove_star) {
+ s = "unstar";
+ } else if (id == R.id.reply) {
+ s = "reply";
+ } else if (id == R.id.reply_all) {
+ s = "reply_all";
+ } else if (id == R.id.forward) {
+ s = "forward";
+ } else if (id == R.id.edit_draft) {
+ s = "edit_draft";
+ } else if (id == R.id.details_collapsed_content) {
+ s = "expand_message_details";
+ } else if (id == R.id.details_expanded_content) {
+ s = "collapse_message_details";
+ } else if (id == R.id.upper_header) {
+ s = "message_upper_header";
+ } else if (id == R.id.download_again || id == R.id.menu_download_again) {
+ s = "download_again";
+ } else if (id == R.id.menu_save) {
+ s = "photo_save";
+ } else if (id == R.id.menu_save_all) {
+ s = "photo_save_all";
+ } else if (id == R.id.menu_share) {
+ s = "photo_share";
+ } else if (id == R.id.menu_share_all) {
+ s = "photo_share_all";
} else {
s = null;
}
diff --git a/src/com/android/mail/browse/MessageHeaderView.java b/src/com/android/mail/browse/MessageHeaderView.java
index 909c7a2..3f41a13 100644
--- a/src/com/android/mail/browse/MessageHeaderView.java
+++ b/src/com/android/mail/browse/MessageHeaderView.java
@@ -48,6 +48,7 @@
import com.android.mail.ContactInfo;
import com.android.mail.ContactInfoSource;
import com.android.mail.R;
+import com.android.mail.analytics.Analytics;
import com.android.mail.browse.ConversationViewAdapter.BorderItem;
import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem;
import com.android.mail.compose.ComposeActivity;
@@ -928,6 +929,12 @@
LogUtils.i(LOG_TAG, "unrecognized header tap: %d", id);
handled = false;
}
+
+ if (handled && id != R.id.overflow) {
+ Analytics.getInstance().sendMenuItemEvent(Analytics.EVENT_CATEGORY_MENU_ITEM, id,
+ "message_header", 0);
+ }
+
return handled;
}
diff --git a/src/com/android/mail/photo/MailPhotoViewActivity.java b/src/com/android/mail/photo/MailPhotoViewActivity.java
index 0562568..560c817 100644
--- a/src/com/android/mail/photo/MailPhotoViewActivity.java
+++ b/src/com/android/mail/photo/MailPhotoViewActivity.java
@@ -36,6 +36,7 @@
import com.android.ex.photo.fragments.PhotoViewFragment;
import com.android.ex.photo.views.ProgressBarWrapper;
import com.android.mail.R;
+import com.android.mail.analytics.Analytics;
import com.android.mail.browse.AttachmentActionHandler;
import com.android.mail.providers.Attachment;
import com.android.mail.providers.UIProvider;
@@ -193,6 +194,10 @@
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final int itemId = item.getItemId();
+
+ Analytics.getInstance().sendMenuItemEvent(Analytics.EVENT_CATEGORY_MENU_ITEM, itemId,
+ "photo_viewer", 0);
+
if (itemId == android.R.id.home) {
// app icon in action bar clicked; go back to conversation
finish();
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index 2b43c18..86b8311 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -2159,17 +2159,38 @@
final int autoAdvance;
if (AUTO_ADVANCE_MODE_NEWER.equals(autoAdvanceSetting)) {
- autoAdvance = UIProvider.AutoAdvance.NEWER;
+ autoAdvance = NEWER;
} else if (AUTO_ADVANCE_MODE_OLDER.equals(autoAdvanceSetting)) {
- autoAdvance = UIProvider.AutoAdvance.OLDER;
+ autoAdvance = OLDER;
} else if (AUTO_ADVANCE_MODE_LIST.equals(autoAdvanceSetting)) {
- autoAdvance = UIProvider.AutoAdvance.LIST;
+ autoAdvance = LIST;
} else {
- autoAdvance = UIProvider.AutoAdvance.UNSET;
+ autoAdvance = UNSET;
}
return autoAdvance;
}
+
+ public static String getAutoAdvanceStr(int autoAdvance) {
+ final String str;
+
+ switch (autoAdvance) {
+ case OLDER:
+ str = AUTO_ADVANCE_MODE_OLDER;
+ break;
+ case NEWER:
+ str = AUTO_ADVANCE_MODE_NEWER;
+ break;
+ case LIST:
+ str = AUTO_ADVANCE_MODE_LIST;
+ break;
+ default:
+ str = "unset";
+ break;
+ }
+
+ return str;
+ }
}
/**
diff --git a/src/com/android/mail/ui/AbstractConversationViewFragment.java b/src/com/android/mail/ui/AbstractConversationViewFragment.java
index 100f31c..97758de 100644
--- a/src/com/android/mail/ui/AbstractConversationViewFragment.java
+++ b/src/com/android/mail/ui/AbstractConversationViewFragment.java
@@ -45,6 +45,7 @@
import com.android.mail.providers.AccountObserver;
import com.android.mail.providers.Address;
import com.android.mail.providers.Conversation;
+import com.android.mail.providers.Folder;
import com.android.mail.providers.ListParams;
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.CursorStatus;
@@ -110,6 +111,8 @@
private boolean mHasConversationBeenTransformed;
private boolean mHasConversationTransformBeenReverted;
+ protected boolean mConversationSeen = false;
+
private final AccountObserver mAccountObserver = new AccountObserver() {
@Override
public void onChanged(Account newAccount) {
@@ -516,6 +519,31 @@
});
}
+ /**
+ * @see Folder#getTypeDescription()
+ */
+ protected String getCurrentFolderTypeDesc() {
+ final Folder currFolder;
+ if (mActivity != null) {
+ currFolder = mActivity.getFolderController().getFolder();
+ } else {
+ currFolder = null;
+ }
+ final String folderStr;
+ if (currFolder != null) {
+ folderStr = currFolder.getTypeDescription();
+ } else {
+ folderStr = "unknown_folder";
+ }
+ return folderStr;
+ }
+
+ private void logConversationView() {
+ final String folderStr = getCurrentFolderTypeDesc();
+ Analytics.getInstance().sendEvent("view_conversation", folderStr,
+ mConversation.isRemote ? "unsynced" : "synced", mConversation.getNumMessages());
+ }
+
protected void onConversationSeen() {
LogUtils.d(LOG_TAG, "AbstractConversationViewFragment#onConversationSeen()");
@@ -526,6 +554,13 @@
return;
}
+ // this method is called 2x on rotation; debounce this a bit so as not to
+ // dramatically skew analytics data too much. Ideally, it should be called zero times
+ // on rotation...
+ if (!mConversationSeen) {
+ logConversationView();
+ }
+
mViewState.setInfoForConversation(mConversation);
LogUtils.d(LOG_TAG, "onConversationSeen() - mSuppressMarkingViewed = %b",
@@ -557,6 +592,8 @@
}
}
activity.getListHandler().onConversationSeen();
+
+ mConversationSeen = true;
}
protected ConversationViewState getNewViewState() {
diff --git a/src/com/android/mail/ui/AnimatedAdapter.java b/src/com/android/mail/ui/AnimatedAdapter.java
index e86ebc9..d898fc1 100644
--- a/src/com/android/mail/ui/AnimatedAdapter.java
+++ b/src/com/android/mail/ui/AnimatedAdapter.java
@@ -227,6 +227,9 @@
(newAccount.settings.replyBehavior == UIProvider.DefaultReplyBehavior.REPLY)
? "reply"
: "reply_all");
+ Analytics.getInstance().setCustomDimension(Analytics.CD_INDEX_AUTO_ADVANCE,
+ UIProvider.AutoAdvance.getAutoAdvanceStr(
+ newAccount.settings.getAutoAdvanceSetting()));
return accountChanged;
}
diff --git a/src/com/android/mail/ui/ConversationListFragment.java b/src/com/android/mail/ui/ConversationListFragment.java
index 2abd2bc..36885d1 100644
--- a/src/com/android/mail/ui/ConversationListFragment.java
+++ b/src/com/android/mail/ui/ConversationListFragment.java
@@ -884,6 +884,19 @@
saveLastScrolledPosition();
}
+ // log the first cursor load. don't log on each updated cursor!
+ if (newCursor != null && (mListAdapter == null || mListAdapter.getCursor() == null)) {
+ // try to get an order-of-magnitude sense for message count within folders
+ final long countLog;
+ if (mFolder.totalCount > 0) {
+ countLog = Math.round(Math.log10(mFolder.totalCount));
+ } else {
+ countLog = 0;
+ }
+ Analytics.getInstance().sendEvent("view_folder", mFolder.getTypeDescription(),
+ Long.toString(countLog), mFolder.totalCount);
+ }
+
mListAdapter.swapCursor(newCursor);
// When the conversation cursor is *updated*, we get back the same instance. In that
// situation, CursorAdapter.swapCursor() silently returns, without forcing a
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index a07c3b7..233ea9a 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -46,6 +46,7 @@
import com.android.mail.FormattedDateBuilder;
import com.android.mail.R;
+import com.android.mail.analytics.Analytics;
import com.android.mail.browse.ConversationContainer;
import com.android.mail.browse.ConversationContainer.OverlayPosition;
import com.android.mail.browse.ConversationMessage;
@@ -502,13 +503,30 @@
if (!userVisible) {
mProgressController.dismissLoadingStatus();
} else if (mViewsCreated) {
+ String loadTag = null;
+ final boolean isInitialLoading = mActivity.getConversationUpdater()
+ .isInitialConversationLoading();
+
if (getMessageCursor() != null) {
LogUtils.d(LOG_TAG, "Fragment is now user-visible, onConversationSeen: %s", this);
+ if (!isInitialLoading) {
+ loadTag = "preloaded";
+ }
onConversationSeen();
} else if (isLoadWaiting()) {
LogUtils.d(LOG_TAG, "Fragment is now user-visible, showing conversation: %s", this);
+ if (!isInitialLoading) {
+ loadTag = "load_deferred";
+ }
handleDelayedConversationLoad();
}
+
+ if (loadTag != null) {
+ // pager swipes are visibility transitions to 'visible' except during initial
+ // pager load on A) enter conversation mode B) rotate C) 2-pane conv-mode list-tap
+ Analytics.getInstance().sendEvent("pager_swipe", loadTag,
+ getCurrentFolderTypeDesc(), 0);
+ }
}
if (mWebView != null) {