aboutsummaryrefslogtreecommitdiff
path: root/libs/analytics
diff options
context:
space:
mode:
authorChris Warrington <cmw@google.com>2016-10-18 12:29:21 +0100
committerChris Warrington <cmw@google.com>2016-10-18 12:34:18 +0100
commite3780081075c01aa1dff6d1f373cb43192b33e68 (patch)
treefb734615933a39f3d009210dc0d1457160479b35 /libs/analytics
parent7e05eb7e57827eddc885570bc00aed8a50320dbf (diff)
parent025b8b226c8d8edba2b309ca878572f40512eca7 (diff)
downloadgradle-perf-android-medium-e3780081075c01aa1dff6d1f373cb43192b33e68.tar.gz
Change-Id: I63f5e16d09297c48432192761b840310935eb903
Diffstat (limited to 'libs/analytics')
-rw-r--r--libs/analytics/.gitignore25
-rw-r--r--libs/analytics/LICENSE22
-rw-r--r--libs/analytics/README.md6
-rw-r--r--libs/analytics/WordPressAnalytics/build.gradle89
-rw-r--r--libs/analytics/WordPressAnalytics/gradle.properties-example6
-rw-r--r--libs/analytics/WordPressAnalytics/src/main/AndroidManifest.xml5
-rw-r--r--libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsMetadata.java69
-rw-r--r--libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java271
-rw-r--r--libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java1172
-rw-r--r--libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanelInstructionsForStat.java140
-rw-r--r--libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java589
-rw-r--r--libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/Tracker.java77
-rw-r--r--libs/analytics/build.gradle0
-rw-r--r--libs/analytics/gradle/wrapper/gradle-wrapper.jarbin0 -> 51348 bytes
-rw-r--r--libs/analytics/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xlibs/analytics/gradlew164
-rw-r--r--libs/analytics/gradlew.bat90
-rw-r--r--libs/analytics/settings.gradle1
18 files changed, 2732 insertions, 0 deletions
diff --git a/libs/analytics/.gitignore b/libs/analytics/.gitignore
new file mode 100644
index 000000000..8babf679a
--- /dev/null
+++ b/libs/analytics/.gitignore
@@ -0,0 +1,25 @@
+# generated files
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+tools/deploy-mvn-artifact.conf
+
+# Intellij project files
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# Gradle
+.gradle/
+gradle.properties
+
+# Idea
+.idea/workspace.xml
+*.iml
+
+# OS X
+.DS_Store
+
+# dependencies
diff --git a/libs/analytics/LICENSE b/libs/analytics/LICENSE
new file mode 100644
index 000000000..20efd1b3e
--- /dev/null
+++ b/libs/analytics/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/libs/analytics/README.md b/libs/analytics/README.md
new file mode 100644
index 000000000..0ef374cf6
--- /dev/null
+++ b/libs/analytics/README.md
@@ -0,0 +1,6 @@
+# WordPressCom-Analytics-Android
+Library for handling Analytics tracking in WordPress Android.
+
+Part of the [WordPress-Android] project.
+
+[WordPress-Android]: https://github.com/wordpress-mobile/WordPress-Android
diff --git a/libs/analytics/WordPressAnalytics/build.gradle b/libs/analytics/WordPressAnalytics/build.gradle
new file mode 100644
index 000000000..6332955f4
--- /dev/null
+++ b/libs/analytics/WordPressAnalytics/build.gradle
@@ -0,0 +1,89 @@
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.2.0'
+ }
+}
+
+apply plugin: 'com.android.library'
+apply plugin: 'maven'
+apply plugin: 'signing'
+
+repositories {
+ jcenter()
+}
+
+dependencies {
+ compile 'com.automattic:tracks:1.1.0'
+ compile 'com.mixpanel.android:mixpanel-android:4.6.4'
+ compile 'org.wordpress:utils:1.11.0'
+}
+
+android {
+ publishNonDefault true
+
+ compileSdkVersion 24
+ buildToolsVersion "24.0.2"
+
+ defaultConfig {
+ versionName "1.2.0"
+ minSdkVersion 16
+ targetSdkVersion 24
+ }
+}
+
+version android.defaultConfig.versionName
+group = "org.wordpress"
+archivesBaseName = "analytics"
+
+signing {
+ required {
+ project.properties.containsKey("signing.keyId") && project.properties.containsKey("signing.secretKeyRingFile")
+ }
+ sign configurations.archives
+}
+
+uploadArchives {
+ repositories {
+ mavenDeployer {
+ beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
+
+ repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
+ authentication(userName: project.properties.ossrhUsername, password: project.properties.ossrhPassword)
+ }
+
+ snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
+ authentication(userName: project.properties.ossrhUsername, password: project.properties.ossrhPassword)
+ }
+
+ pom.project {
+ name 'WordPressCom-Analytics-Android'
+ packaging 'aar'
+ description 'Analytics lib for WordPress-Android'
+ url 'https://github.com/wordpress-mobile/WordPressCom-Analytics-Android'
+ scm {
+ connection 'scm:git:https://github.com/wordpress-mobile/WordPressCom-Analytics-Android.git'
+ developerConnection 'scm:git:https://github.com/wordpress-mobile/WordPressCom-Analytics-Android.git'
+ url 'https://github.com/wordpress-mobile/WordPressCom-Analytics-Android'
+ }
+
+ licenses {
+ license {
+ name 'The MIT License (MIT)'
+ url 'http://opensource.org/licenses/MIT'
+ }
+ }
+
+ developers {
+ developer {
+ id 'maxme'
+ name 'Maxime Biais'
+ email 'maxime@automattic.com'
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/libs/analytics/WordPressAnalytics/gradle.properties-example b/libs/analytics/WordPressAnalytics/gradle.properties-example
new file mode 100644
index 000000000..5281d935c
--- /dev/null
+++ b/libs/analytics/WordPressAnalytics/gradle.properties-example
@@ -0,0 +1,6 @@
+ossrhUsername=hello
+ossrhPassword=world
+
+signing.keyId=byebye
+signing.password=secret
+signing.secretKeyRingFile=/home/user/secret.gpg
diff --git a/libs/analytics/WordPressAnalytics/src/main/AndroidManifest.xml b/libs/analytics/WordPressAnalytics/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..d4cf8c539
--- /dev/null
+++ b/libs/analytics/WordPressAnalytics/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.wordpress.android.analytics">
+
+</manifest>
diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsMetadata.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsMetadata.java
new file mode 100644
index 000000000..a49629bc0
--- /dev/null
+++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsMetadata.java
@@ -0,0 +1,69 @@
+package org.wordpress.android.analytics;
+
+public class AnalyticsMetadata {
+ private boolean mIsUserConnected;
+ private boolean mIsWordPressComUser;
+ private boolean mIsJetpackUser;
+ private int mSessionCount;
+ private int mNumBlogs;
+ private String mUsername = "";
+ private String mEmail = "";
+
+ public AnalyticsMetadata() {}
+
+ public boolean isUserConnected() {
+ return mIsUserConnected;
+ }
+
+ public void setUserConnected(boolean isUserConnected) {
+ mIsUserConnected = isUserConnected;
+ }
+
+ public boolean isWordPressComUser() {
+ return mIsWordPressComUser;
+ }
+
+ public void setWordPressComUser(boolean isWordPressComUser) {
+ mIsWordPressComUser = isWordPressComUser;
+ }
+
+ public boolean isJetpackUser() {
+ return mIsJetpackUser;
+ }
+
+ public void setJetpackUser(boolean isJetpackUser) {
+ mIsJetpackUser = isJetpackUser;
+ }
+
+ public int getSessionCount() {
+ return mSessionCount;
+ }
+
+ public void setSessionCount(int sessionCount) {
+ this.mSessionCount = sessionCount;
+ }
+
+ public int getNumBlogs() {
+ return mNumBlogs;
+ }
+
+ public void setNumBlogs(int numBlogs) {
+ this.mNumBlogs = numBlogs;
+ }
+
+ public String getUsername() {
+ return mUsername;
+ }
+
+ public void setUsername(String username) {
+ this.mUsername = username;
+ }
+
+ public String getEmail() {
+ return mEmail;
+ }
+
+ public void setEmail(String email) {
+ this.mEmail = email;
+ }
+}
diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java
new file mode 100644
index 000000000..c160f47a6
--- /dev/null
+++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java
@@ -0,0 +1,271 @@
+package org.wordpress.android.analytics;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public final class AnalyticsTracker {
+ private static boolean mHasUserOptedOut;
+
+ public static final String READER_DETAIL_TYPE_KEY = "post_detail_type";
+ public static final String READER_DETAIL_TYPE_NORMAL = "normal";
+ public static final String READER_DETAIL_TYPE_BLOG_PREVIEW = "preview-blog";
+ public static final String READER_DETAIL_TYPE_TAG_PREVIEW = "preview-tag";
+
+ public enum Stat {
+ APPLICATION_OPENED,
+ APPLICATION_CLOSED,
+ APPLICATION_INSTALLED,
+ APPLICATION_UPGRADED,
+ READER_ACCESSED,
+ READER_ARTICLE_COMMENTED_ON,
+ READER_ARTICLE_LIKED,
+ READER_ARTICLE_OPENED,
+ READER_ARTICLE_UNLIKED,
+ READER_BLOG_BLOCKED,
+ READER_BLOG_FOLLOWED,
+ READER_BLOG_PREVIEWED,
+ READER_BLOG_UNFOLLOWED,
+ READER_DISCOVER_VIEWED,
+ READER_INFINITE_SCROLL,
+ READER_LIST_FOLLOWED,
+ READER_LIST_LOADED,
+ READER_LIST_PREVIEWED,
+ READER_LIST_UNFOLLOWED,
+ READER_TAG_FOLLOWED,
+ READER_TAG_LOADED,
+ READER_TAG_PREVIEWED,
+ READER_TAG_UNFOLLOWED,
+ READER_SEARCH_LOADED,
+ READER_SEARCH_PERFORMED,
+ READER_SEARCH_RESULT_TAPPED,
+ READER_RELATED_POST_CLICKED,
+ STATS_ACCESSED,
+ STATS_INSIGHTS_ACCESSED,
+ STATS_PERIOD_DAYS_ACCESSED,
+ STATS_PERIOD_WEEKS_ACCESSED,
+ STATS_PERIOD_MONTHS_ACCESSED,
+ STATS_PERIOD_YEARS_ACCESSED,
+ STATS_VIEW_ALL_ACCESSED,
+ STATS_SINGLE_POST_ACCESSED,
+ STATS_TAPPED_BAR_CHART,
+ STATS_SCROLLED_TO_BOTTOM,
+ STATS_WIDGET_ADDED,
+ STATS_WIDGET_REMOVED,
+ STATS_WIDGET_TAPPED,
+ EDITOR_CREATED_POST,
+ EDITOR_ADDED_PHOTO_VIA_LOCAL_LIBRARY,
+ EDITOR_ADDED_VIDEO_VIA_LOCAL_LIBRARY,
+ EDITOR_ADDED_PHOTO_VIA_WP_MEDIA_LIBRARY,
+ EDITOR_ADDED_VIDEO_VIA_WP_MEDIA_LIBRARY,
+ EDITOR_UPDATED_POST,
+ EDITOR_SCHEDULED_POST,
+ EDITOR_CLOSED,
+ EDITOR_PUBLISHED_POST,
+ EDITOR_SAVED_DRAFT,
+ EDITOR_DISCARDED_CHANGES,
+ EDITOR_EDITED_IMAGE, // Visual editor only
+ EDITOR_ENABLED_NEW_VERSION, // Visual editor only
+ EDITOR_TOGGLED_OFF, // Visual editor only
+ EDITOR_TOGGLED_ON, // Visual editor only
+ EDITOR_UPLOAD_MEDIA_FAILED, // Visual editor only
+ EDITOR_UPLOAD_MEDIA_RETRIED, // Visual editor only
+ EDITOR_TAPPED_BLOCKQUOTE,
+ EDITOR_TAPPED_BOLD,
+ EDITOR_TAPPED_HTML, // Visual editor only
+ EDITOR_TAPPED_IMAGE,
+ EDITOR_TAPPED_ITALIC,
+ EDITOR_TAPPED_LINK,
+ EDITOR_TAPPED_MORE,
+ EDITOR_TAPPED_STRIKETHROUGH,
+ EDITOR_TAPPED_UNDERLINE,
+ EDITOR_TAPPED_ORDERED_LIST, // Visual editor only
+ EDITOR_TAPPED_UNLINK, // Visual editor only
+ EDITOR_TAPPED_UNORDERED_LIST, // Visual editor only
+ ME_ACCESSED,
+ ME_GRAVATAR_TAPPED,
+ ME_GRAVATAR_TOOLTIP_TAPPED,
+ ME_GRAVATAR_PERMISSIONS_INTERRUPTED,
+ ME_GRAVATAR_PERMISSIONS_DENIED,
+ ME_GRAVATAR_PERMISSIONS_ACCEPTED,
+ ME_GRAVATAR_SHOT_NEW,
+ ME_GRAVATAR_GALLERY_PICKED,
+ ME_GRAVATAR_CROPPED,
+ ME_GRAVATAR_UPLOADED,
+ ME_GRAVATAR_UPLOAD_UNSUCCESSFUL,
+ ME_GRAVATAR_UPLOAD_EXCEPTION,
+ MY_SITE_ACCESSED,
+ NOTIFICATIONS_ACCESSED,
+ NOTIFICATIONS_OPENED_NOTIFICATION_DETAILS,
+ NOTIFICATION_REPLIED_TO,
+ NOTIFICATION_APPROVED,
+ NOTIFICATION_UNAPPROVED,
+ NOTIFICATION_LIKED,
+ NOTIFICATION_UNLIKED,
+ NOTIFICATION_TRASHED,
+ NOTIFICATION_FLAGGED_AS_SPAM,
+ OPENED_POSTS,
+ OPENED_PAGES,
+ OPENED_COMMENTS,
+ OPENED_VIEW_SITE,
+ OPENED_VIEW_ADMIN,
+ OPENED_MEDIA_LIBRARY,
+ OPENED_BLOG_SETTINGS,
+ OPENED_ACCOUNT_SETTINGS,
+ OPENED_APP_SETTINGS,
+ OPENED_MY_PROFILE,
+ OPENED_PEOPLE_MANAGEMENT,
+ OPENED_PERSON,
+ CREATED_ACCOUNT,
+ CREATED_SITE,
+ ACCOUNT_LOGOUT,
+ SHARED_ITEM,
+ ADDED_SELF_HOSTED_SITE,
+ SIGNED_IN,
+ SIGNED_INTO_JETPACK,
+ PERFORMED_JETPACK_SIGN_IN_FROM_STATS_SCREEN,
+ STATS_SELECTED_INSTALL_JETPACK,
+ STATS_SELECTED_CONNECT_JETPACK,
+ PUSH_NOTIFICATION_RECEIVED,
+ PUSH_NOTIFICATION_TAPPED, // Same of opened
+ SUPPORT_OPENED_HELPSHIFT_SCREEN,
+ SUPPORT_SENT_REPLY_TO_SUPPORT_MESSAGE,
+ LOGIN_MAGIC_LINK_EXITED,
+ LOGIN_MAGIC_LINK_FAILED,
+ LOGIN_MAGIC_LINK_OPENED,
+ LOGIN_MAGIC_LINK_REQUESTED,
+ LOGIN_MAGIC_LINK_SUCCEEDED,
+ LOGIN_FAILED,
+ LOGIN_FAILED_TO_GUESS_XMLRPC,
+ LOGIN_INSERTED_INVALID_URL,
+ LOGIN_AUTOFILL_CREDENTIALS_FILLED,
+ LOGIN_AUTOFILL_CREDENTIALS_UPDATED,
+ PERSON_REMOVED,
+ PERSON_UPDATED,
+ PUSH_AUTHENTICATION_APPROVED,
+ PUSH_AUTHENTICATION_EXPIRED,
+ PUSH_AUTHENTICATION_FAILED,
+ PUSH_AUTHENTICATION_IGNORED,
+ NOTIFICATION_SETTINGS_LIST_OPENED,
+ NOTIFICATION_SETTINGS_STREAMS_OPENED,
+ NOTIFICATION_SETTINGS_DETAILS_OPENED,
+ THEMES_ACCESSED_THEMES_BROWSER,
+ THEMES_ACCESSED_SEARCH,
+ THEMES_CHANGED_THEME,
+ THEMES_PREVIEWED_SITE,
+ THEMES_DEMO_ACCESSED,
+ THEMES_CUSTOMIZE_ACCESSED,
+ THEMES_SUPPORT_ACCESSED,
+ THEMES_DETAILS_ACCESSED,
+ ACCOUNT_SETTINGS_LANGUAGE_CHANGED,
+ SITE_SETTINGS_ACCESSED,
+ SITE_SETTINGS_ACCESSED_MORE_SETTINGS,
+ SITE_SETTINGS_LEARN_MORE_CLICKED,
+ SITE_SETTINGS_LEARN_MORE_LOADED,
+ SITE_SETTINGS_ADDED_LIST_ITEM,
+ SITE_SETTINGS_DELETED_LIST_ITEMS,
+ SITE_SETTINGS_SAVED_REMOTELY,
+ SITE_SETTINGS_HINT_TOAST_SHOWN,
+ SITE_SETTINGS_START_OVER_ACCESSED,
+ SITE_SETTINGS_START_OVER_CONTACT_SUPPORT_CLICKED,
+ SITE_SETTINGS_EXPORT_SITE_ACCESSED,
+ SITE_SETTINGS_EXPORT_SITE_REQUESTED,
+ SITE_SETTINGS_EXPORT_SITE_RESPONSE_OK,
+ SITE_SETTINGS_EXPORT_SITE_RESPONSE_ERROR,
+ SITE_SETTINGS_DELETE_SITE_ACCESSED,
+ SITE_SETTINGS_DELETE_SITE_PURCHASES_REQUESTED,
+ SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOWN,
+ SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOW_CLICKED,
+ SITE_SETTINGS_DELETE_SITE_REQUESTED,
+ SITE_SETTINGS_DELETE_SITE_RESPONSE_OK,
+ SITE_SETTINGS_DELETE_SITE_RESPONSE_ERROR,
+ ABTEST_START,
+ TRAIN_TRACKS_RENDER,
+ TRAIN_TRACKS_INTERACT
+ }
+
+ private static final List<Tracker> TRACKERS = new ArrayList<>();
+
+ private AnalyticsTracker() {
+ }
+
+ public static void init(Context context) {
+ loadPrefHasUserOptedOut(context);
+ }
+
+ public static void loadPrefHasUserOptedOut(Context context) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean hasUserOptedOut = !prefs.getBoolean("wp_pref_send_usage_stats", true);
+ if (hasUserOptedOut != mHasUserOptedOut) {
+ mHasUserOptedOut = hasUserOptedOut;
+ }
+ }
+
+ public static void registerTracker(Tracker tracker) {
+ if (tracker != null) {
+ TRACKERS.add(tracker);
+ }
+ }
+
+ public static void track(Stat stat) {
+ if (mHasUserOptedOut) {
+ return;
+ }
+ for (Tracker tracker : TRACKERS) {
+ tracker.track(stat);
+ }
+ }
+
+ public static void track(Stat stat, Map<String, ?> properties) {
+ if (mHasUserOptedOut) {
+ return;
+ }
+ for (Tracker tracker : TRACKERS) {
+ tracker.track(stat, properties);
+ }
+ }
+
+
+ public static void flush() {
+ if (mHasUserOptedOut) {
+ return;
+ }
+ for (Tracker tracker : TRACKERS) {
+ tracker.flush();
+ }
+ }
+
+ public static void endSession(boolean force) {
+ if (mHasUserOptedOut && !force) {
+ return;
+ }
+ for (Tracker tracker : TRACKERS) {
+ tracker.endSession();
+ }
+ }
+
+ public static void registerPushNotificationToken(String regId) {
+ if (mHasUserOptedOut) {
+ return;
+ }
+ for (Tracker tracker : TRACKERS) {
+ tracker.registerPushNotificationToken(regId);
+ }
+ }
+
+ public static void clearAllData() {
+ for (Tracker tracker : TRACKERS) {
+ tracker.clearAllData();
+ }
+ }
+
+ public static void refreshMetadata(AnalyticsMetadata metadata) {
+ for (Tracker tracker : TRACKERS) {
+ tracker.refreshMetadata(metadata);
+ }
+ }
+}
diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java
new file mode 100644
index 000000000..1e1b278f8
--- /dev/null
+++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java
@@ -0,0 +1,1172 @@
+package org.wordpress.android.analytics;
+
+import android.annotation.SuppressLint;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import com.mixpanel.android.mpmetrics.MixpanelAPI;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.wordpress.android.util.AppLog;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+public class AnalyticsTrackerMixpanel extends Tracker {
+ public static final String SESSION_COUNT = "sessionCount";
+
+ private MixpanelAPI mMixpanel;
+ private EnumMap<AnalyticsTracker.Stat, JSONObject> mAggregatedProperties;
+ private static final String MIXPANEL_PLATFORM = "platform";
+ private static final String MIXPANEL_SESSION_COUNT = "session_count";
+ private static final String DOTCOM_USER = "dotcom_user";
+ private static final String JETPACK_USER = "jetpack_user";
+ private static final String MIXPANEL_NUMBER_OF_BLOGS = "number_of_blogs";
+ private static final String APP_LOCALE = "app_locale";
+ private static final String MIXPANEL_ANON_ID = "mixpanel_user_anon_id";
+
+ public AnalyticsTrackerMixpanel(Context context, String token) throws IllegalArgumentException {
+ super(context);
+ mAggregatedProperties = new EnumMap<>(AnalyticsTracker.Stat.class);
+ mMixpanel = MixpanelAPI.getInstance(context, token);
+ }
+
+ @SuppressWarnings("deprecation")
+ @SuppressLint("NewApi")
+ public static void showNotification(Context context, PendingIntent intent, int notificationIcon, CharSequence title,
+ CharSequence message) {
+ final NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ final Notification.Builder builder = new Notification.Builder(context).setSmallIcon(notificationIcon)
+ .setTicker(message).setWhen(System.currentTimeMillis()).setContentTitle(title).setContentText(message)
+ .setContentIntent(intent);
+ Notification notification;
+ notification = builder.build();
+ notification.flags |= Notification.FLAG_AUTO_CANCEL;
+ nm.notify(0, notification);
+ }
+
+ String getAnonIdPrefKey() {
+ return MIXPANEL_ANON_ID;
+ }
+
+ @Override
+ public void track(AnalyticsTracker.Stat stat) {
+ track(stat, null);
+ }
+
+ @Override
+ public void track(AnalyticsTracker.Stat stat, Map<String, ?> properties) {
+ AnalyticsTrackerMixpanelInstructionsForStat instructions = instructionsForStat(stat);
+
+ if (instructions == null) {
+ return;
+ }
+
+ trackMixpanelDataForInstructions(instructions, properties);
+ }
+
+ private void trackMixpanelDataForInstructions(AnalyticsTrackerMixpanelInstructionsForStat instructions,
+ Map<String, ?> properties) {
+ if (instructions.getDisableForSelfHosted()) {
+ return;
+ }
+
+ // Just a security check we're tracking the correct user
+ if (getWordPressComUserName() == null && getAnonID() == null) {
+ this.clearAllData();
+ generateNewAnonID();
+ mMixpanel.identify(getAnonID());
+ }
+
+ trackMixpanelEventForInstructions(instructions, properties);
+ trackMixpanelPropertiesForInstructions(instructions);
+ }
+
+ private void trackMixpanelPropertiesForInstructions(AnalyticsTrackerMixpanelInstructionsForStat instructions) {
+ if (instructions.getPeoplePropertyToIncrement() != null && !instructions.getPeoplePropertyToIncrement()
+ .isEmpty()) {
+ incrementPeopleProperty(instructions.getPeoplePropertyToIncrement());
+ }
+
+ if (instructions.getSuperPropertyToIncrement() != null && !instructions.getSuperPropertyToIncrement()
+ .isEmpty()) {
+ incrementSuperProperty(instructions.getSuperPropertyToIncrement());
+ }
+
+ if (instructions.getPropertyToIncrement() != null && !instructions.getPropertyToIncrement().isEmpty()) {
+ incrementProperty(instructions.getPropertyToIncrement(), instructions.getStatToAttachProperty());
+ }
+
+ if (instructions.getSuperPropertiesToFlag() != null && instructions.getSuperPropertiesToFlag().size() > 0) {
+ for (String superPropertyToFlag : instructions.getSuperPropertiesToFlag()) {
+ flagSuperProperty(superPropertyToFlag);
+ }
+ }
+
+ if (instructions.getPeoplePropertiesToAssign() != null
+ && instructions.getPeoplePropertiesToAssign().size() > 0) {
+ for (Map.Entry<String, Object> entry: instructions.getPeoplePropertiesToAssign().entrySet()) {
+ setValueForPeopleProperty(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ private void setValueForPeopleProperty(String peopleProperty, Object value) {
+ try {
+ mMixpanel.getPeople().set(peopleProperty, value);
+ } catch (OutOfMemoryError outOfMemoryError) {
+ // ignore exception
+ }
+ }
+
+ private void trackMixpanelEventForInstructions(AnalyticsTrackerMixpanelInstructionsForStat instructions,
+ Map<String, ?> properties) {
+ String eventName = instructions.getMixpanelEventName();
+ if (eventName != null && !eventName.isEmpty()) {
+ JSONObject savedPropertiesForStat = propertiesForStat(instructions.getStat());
+ if (savedPropertiesForStat == null) {
+ savedPropertiesForStat = new JSONObject();
+ }
+
+ // Retrieve properties user has already passed in and combine them with the saved properties
+ if (properties != null) {
+ for (Object o : properties.entrySet()) {
+ Map.Entry pairs = (Map.Entry) o;
+ String key = (String) pairs.getKey();
+ try {
+ Object value = pairs.getValue();
+ savedPropertiesForStat.put(key, value);
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.UTILS, e);
+ }
+ }
+ }
+ mMixpanel.track(eventName, savedPropertiesForStat);
+ removePropertiesForStat(instructions.getStat());
+ }
+ }
+
+ @Override
+ public void registerPushNotificationToken(String regId) {
+ try {
+ mMixpanel.getPeople().setPushRegistrationId(regId);
+ } catch (OutOfMemoryError outOfMemoryError) {
+ // ignore exception
+ }
+ }
+
+ @Override
+ public void endSession() {
+ mAggregatedProperties.clear();
+ mMixpanel.flush();
+ }
+
+ @Override
+ public void flush() {
+ mMixpanel.flush();
+ }
+
+ @Override
+ public void refreshMetadata(AnalyticsMetadata metadata) {
+ // Register super properties
+ try {
+ JSONObject properties = new JSONObject();
+ properties.put(MIXPANEL_PLATFORM, "Android");
+ properties.put(MIXPANEL_SESSION_COUNT, metadata.getSessionCount());
+ properties.put(DOTCOM_USER, metadata.isUserConnected());
+ properties.put(JETPACK_USER, metadata.isJetpackUser());
+ properties.put(MIXPANEL_NUMBER_OF_BLOGS, metadata.getNumBlogs());
+ properties.put(APP_LOCALE, mContext.getResources().getConfiguration().locale.toString());
+ mMixpanel.registerSuperProperties(properties);
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.UTILS, e);
+ }
+
+
+ if (metadata.isUserConnected() && metadata.isWordPressComUser()) {
+ setWordPressComUserName(metadata.getUsername());
+ // Re-unify the user
+ if (getAnonID() != null) {
+ mMixpanel.alias(getWordPressComUserName(), getAnonID());
+ clearAnonID();
+ } else {
+ mMixpanel.identify(metadata.getUsername());
+ }
+ } else {
+ // Not wpcom connected. Check if anonID is already present
+ setWordPressComUserName(null);
+ if (getAnonID() == null) {
+ generateNewAnonID();
+ }
+ mMixpanel.identify(getAnonID());
+ }
+
+ // Application opened and start.
+ if (metadata.isUserConnected()) {
+ try {
+ String userID = getWordPressComUserName() != null ? getWordPressComUserName() : getAnonID();
+ if (userID == null) {
+ // This should not be an option here
+ return;
+ }
+
+ mMixpanel.getPeople().identify(userID);
+ JSONObject jsonObj = new JSONObject();
+ jsonObj.put("$username", userID);
+ if (metadata.getEmail() != null) {
+ jsonObj.put("$email", metadata.getEmail());
+ }
+ jsonObj.put("$first_name", userID);
+ mMixpanel.getPeople().set(jsonObj);
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.UTILS, e);
+ } catch (OutOfMemoryError outOfMemoryError) {
+ // ignore exception
+ }
+ }
+ }
+
+ @Override
+ public void clearAllData() {
+ super.clearAllData();
+ mMixpanel.clearSuperProperties();
+ try {
+ mMixpanel.getPeople().clearPushRegistrationId();
+ } catch (OutOfMemoryError outOfMemoryError) {
+ // ignore exception
+ }
+ }
+
+ private AnalyticsTrackerMixpanelInstructionsForStat instructionsForStat(
+ AnalyticsTracker.Stat stat) {
+ AnalyticsTrackerMixpanelInstructionsForStat instructions;
+ switch (stat) {
+ case APPLICATION_OPENED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Application Opened");
+ instructions.setSuperPropertyToIncrement("Application Opened");
+ incrementSessionCount();
+ break;
+ case APPLICATION_CLOSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Application Closed");
+ break;
+ case APPLICATION_INSTALLED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Application Installed");
+ break;
+ case APPLICATION_UPGRADED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Application Upgraded");
+ break;
+ case READER_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_reader");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_reader");
+ break;
+ case READER_ARTICLE_COMMENTED_ON:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Commented on Article");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement(
+ "number_of_times_commented_on_reader_article");
+ instructions.setCurrentDateForPeopleProperty("last_time_commented_on_article");
+ break;
+ case READER_ARTICLE_LIKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Liked Article");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_liked_article");
+ instructions.setCurrentDateForPeopleProperty("last_time_liked_reader_article");
+ break;
+ case READER_ARTICLE_OPENED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Opened Article");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_opened_article");
+ instructions.setCurrentDateForPeopleProperty("last_time_opened_reader_article");
+ break;
+ case READER_ARTICLE_UNLIKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Unliked Article");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_unliked_article");
+ instructions.setCurrentDateForPeopleProperty("last_time_unliked_reader_article");
+ break;
+ case READER_BLOG_BLOCKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Blocked Blog");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_blocked_a_blog");
+ instructions.setCurrentDateForPeopleProperty("last_time_blocked_a_blog");
+ break;
+ case READER_BLOG_FOLLOWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Followed Site");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_followed_site");
+ instructions.setCurrentDateForPeopleProperty("last_time_followed_site");
+ break;
+ case READER_BLOG_PREVIEWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Blog Preview");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_viewed_blog_preview");
+ instructions.setCurrentDateForPeopleProperty("last_time_viewed_blog_preview");
+ break;
+ case READER_BLOG_UNFOLLOWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Unfollowed Site");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_unfollowed_site");
+ instructions.setCurrentDateForPeopleProperty("last_time_unfollowed_site");
+ break;
+ case READER_DISCOVER_VIEWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Discover Content Viewed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement(
+ "number_of_times_discover_content_viewed");
+ instructions.setCurrentDateForPeopleProperty("last_time_discover_content_viewed");
+ break;
+ case READER_INFINITE_SCROLL:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Infinite Scroll");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement(
+ "number_of_times_reader_performed_infinite_scroll");
+ instructions.setCurrentDateForPeopleProperty("last_time_performed_reader_infinite_scroll");
+ break;
+ case READER_LIST_FOLLOWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Followed List");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_followed_list");
+ instructions.setCurrentDateForPeopleProperty("last_time_followed_list");
+ break;
+ case READER_LIST_LOADED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Loaded List");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_loaded_list");
+ instructions.setCurrentDateForPeopleProperty("last_time_loaded_list");
+ break;
+ case READER_LIST_PREVIEWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - List Preview");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_viewed_list_preview");
+ instructions.setCurrentDateForPeopleProperty("last_time_viewed_list_preview");
+ break;
+ case READER_LIST_UNFOLLOWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Unfollowed List");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_unfollowed_list");
+ instructions.setCurrentDateForPeopleProperty("last_time_unfollowed_list");
+ break;
+ case READER_TAG_FOLLOWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Followed Reader Tag");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_followed_reader_tag");
+ instructions.setCurrentDateForPeopleProperty("last_time_followed_reader_tag");
+ break;
+ case READER_TAG_LOADED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Loaded Tag");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_loaded_tag");
+ instructions.setCurrentDateForPeopleProperty("last_time_loaded_tag");
+ break;
+ case READER_TAG_PREVIEWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Tag Preview");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_viewed_tag_preview");
+ instructions.setCurrentDateForPeopleProperty("last_time_viewed_tag_preview");
+ break;
+ case READER_TAG_UNFOLLOWED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Unfollowed Reader Tag");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_unfollowed_reader_tag");
+ instructions.setCurrentDateForPeopleProperty("last_time_unfollowed_reader_tag");
+ break;
+ case READER_SEARCH_LOADED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Loaded Search");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_reader_search_loaded");
+ instructions.setCurrentDateForPeopleProperty("last_time_reader_search_loaded");
+ break;
+ case READER_SEARCH_PERFORMED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Performed Search");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_reader_search_performed");
+ instructions.setCurrentDateForPeopleProperty("last_time_reader_search_performed");
+ break;
+ case READER_SEARCH_RESULT_TAPPED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Tapped Search Result");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_reader_search_result_tapped");
+ instructions.setCurrentDateForPeopleProperty("last_time_reader_search_result_tapped");
+ break;
+ case READER_RELATED_POST_CLICKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Reader - Related Post Clicked");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_reader_related_post_clicked");
+ instructions.setCurrentDateForPeopleProperty("last_time_reader_related_post_clicked");
+ break;
+ case EDITOR_CREATED_POST:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Created Post");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_created_post");
+ instructions.setCurrentDateForPeopleProperty("last_time_created_post_in_editor");
+ break;
+ case EDITOR_SAVED_DRAFT:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Saved Draft");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_saved_draft");
+ instructions.setCurrentDateForPeopleProperty("last_time_saved_draft");
+ break;
+ case EDITOR_DISCARDED_CHANGES:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Discarded Changes");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_discarded_changes");
+ instructions.setCurrentDateForPeopleProperty("last_time_discarded_changes");
+ break;
+ case EDITOR_EDITED_IMAGE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Edited Image");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_edited_image");
+ instructions.setCurrentDateForPeopleProperty("last_time_edited_image");
+ break;
+ case EDITOR_ENABLED_NEW_VERSION:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Enabled New Version");
+ instructions.addSuperPropertyToFlag("enabled_new_editor");
+ break;
+ case EDITOR_TOGGLED_ON:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Toggled New Editor On");
+ instructions.setPeoplePropertyToValue("enabled_new_editor", true);
+ break;
+ case EDITOR_TOGGLED_OFF:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Toggled New Editor Off");
+ instructions.setPeoplePropertyToValue("enabled_new_editor", false);
+ break;
+ case EDITOR_UPLOAD_MEDIA_FAILED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Upload Media Failed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_upload_media_failed");
+ instructions.setCurrentDateForPeopleProperty("last_time_editor_upload_media_failed");
+ break;
+ case EDITOR_UPLOAD_MEDIA_RETRIED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Retried Uploading Media");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_retried_uploading_media");
+ instructions.setCurrentDateForPeopleProperty("last_time_editor_retried_uploading_media");
+ break;
+ case EDITOR_CLOSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Closed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_closed");
+ break;
+ case EDITOR_ADDED_PHOTO_VIA_LOCAL_LIBRARY:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Added Photo via Local Library");
+ instructions.
+ setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_added_photo_via_local_library");
+ instructions.setCurrentDateForPeopleProperty("last_time_added_photo_via_local_library_to_post");
+ break;
+ case EDITOR_ADDED_PHOTO_VIA_WP_MEDIA_LIBRARY:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Added Photo via WP Media Library");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement(
+ "number_of_times_added_photo_via_wp_media_library");
+ instructions.setCurrentDateForPeopleProperty("last_time_added_photo_via_wp_media_library_to_post");
+ break;
+ case EDITOR_ADDED_VIDEO_VIA_LOCAL_LIBRARY:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Added Video via Local Library");
+ instructions.
+ setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_added_video_via_local_library");
+ instructions.setCurrentDateForPeopleProperty("last_time_added_video_via_local_library_to_post");
+ break;
+ case EDITOR_ADDED_VIDEO_VIA_WP_MEDIA_LIBRARY:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Added Video via WP Media Library");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement(
+ "number_of_times_added_video_via_wp_media_library");
+ instructions.setCurrentDateForPeopleProperty("last_time_added_video_via_wp_media_library_to_post");
+ break;
+ case EDITOR_PUBLISHED_POST:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Published Post");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_published_post");
+ instructions.setCurrentDateForPeopleProperty("last_time_published_post");
+ break;
+ case EDITOR_UPDATED_POST:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Updated Post");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_updated_post");
+ instructions.setCurrentDateForPeopleProperty("last_time_updated_post");
+ break;
+ case EDITOR_SCHEDULED_POST:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Scheduled Post");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_scheduled_post");
+ instructions.setCurrentDateForPeopleProperty("last_time_scheduled_post");
+ break;
+ case EDITOR_TAPPED_BLOCKQUOTE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Blockquote Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_blockquote");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_blockquote_in_editor");
+ break;
+ case EDITOR_TAPPED_BOLD:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Bold Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_bold");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_bold_in_editor");
+ break;
+ case EDITOR_TAPPED_IMAGE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Image Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_image");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_image_in_editor");
+ break;
+ case EDITOR_TAPPED_ITALIC:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Italics Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_italic");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_italic_in_editor");
+ break;
+ case EDITOR_TAPPED_LINK:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Link Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_link");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_link_in_editor");
+ break;
+ case EDITOR_TAPPED_MORE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped More Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_more");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_more_in_editor");
+ break;
+ case EDITOR_TAPPED_STRIKETHROUGH:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Strikethrough Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_strikethrough");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_strikethrough_in_editor");
+ break;
+ case EDITOR_TAPPED_UNDERLINE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Underline Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_underline");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_underline_in_editor");
+ break;
+ case EDITOR_TAPPED_HTML:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped HTML Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_html");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_html_in_editor");
+ break;
+ case EDITOR_TAPPED_ORDERED_LIST:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Ordered List Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_ordered_list");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_ordered_list_in_editor");
+ break;
+ case EDITOR_TAPPED_UNLINK:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Unlink Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_unlink");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_unlink_in_editor");
+ break;
+ case EDITOR_TAPPED_UNORDERED_LIST:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Editor - Tapped Unordered List Button");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_editor_tapped_unordered_list");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_unordered_list_in_editor");
+ break;
+ case NOTIFICATIONS_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Notifications - Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_notifications");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_notifications");
+ break;
+ case NOTIFICATIONS_OPENED_NOTIFICATION_DETAILS:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Notifications - Opened Notification Details");
+ instructions.
+ setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_opened_notification_details");
+ instructions.setCurrentDateForPeopleProperty("last_time_opened_notification_details");
+ break;
+ case NOTIFICATION_APPROVED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsWithSuperPropertyAndPeoplePropertyIncrementor(
+ "number_of_notifications_approved");
+ break;
+ case NOTIFICATION_UNAPPROVED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsWithSuperPropertyAndPeoplePropertyIncrementor(
+ "number_of_notifications_unapproved");
+ break;
+ case NOTIFICATION_REPLIED_TO:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsWithSuperPropertyAndPeoplePropertyIncrementor(
+ "number_of_notifications_replied_to");
+ break;
+ case NOTIFICATION_TRASHED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsWithSuperPropertyAndPeoplePropertyIncrementor(
+ "number_of_notifications_trashed");
+ break;
+ case NOTIFICATION_FLAGGED_AS_SPAM:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsWithSuperPropertyAndPeoplePropertyIncrementor(
+ "number_of_notifications_flagged_as_spam");
+ break;
+ case NOTIFICATION_LIKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Notifications - Liked Comment");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_comment_likes_from_notification");
+ break;
+ case NOTIFICATION_UNLIKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Notifications - Unliked Comment");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_comment_unlikes_from_notification");
+ break;
+ case OPENED_POSTS:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Site Menu - Opened Posts");
+ break;
+ case OPENED_PAGES:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Site Menu - Opened Pages");
+ break;
+ case OPENED_COMMENTS:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Site Menu - Opened Comments");
+ break;
+ case OPENED_VIEW_SITE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Site Menu - Opened View Site");
+ break;
+ case OPENED_VIEW_ADMIN:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Site Menu - Opened View Admin");
+ break;
+ case OPENED_MEDIA_LIBRARY:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Site Menu - Opened Media Library");
+ break;
+ case OPENED_BLOG_SETTINGS:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Site Menu - Opened Site Settings");
+ break;
+ case OPENED_ACCOUNT_SETTINGS:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Opened Account Settings");
+ break;
+ case OPENED_APP_SETTINGS:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Opened App Settings");
+ break;
+ case OPENED_MY_PROFILE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Opened My Profile");
+ break;
+ case OPENED_PEOPLE_MANAGEMENT:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("People Management - Accessed List");
+ break;
+ case OPENED_PERSON:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("People Management - Accessed Details");
+ break;
+ case CREATED_ACCOUNT:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Created Account");
+ instructions.setCurrentDateForPeopleProperty("$created");
+ instructions.addSuperPropertyToFlag("created_account_on_mobile");
+ break;
+ case CREATED_SITE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Created Site");
+ break;
+ case SHARED_ITEM:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsWithSuperPropertyAndPeoplePropertyIncrementor("number_of_items_shared");
+ break;
+ case ADDED_SELF_HOSTED_SITE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Added Self Hosted Site");
+ instructions.setCurrentDateForPeopleProperty("last_time_added_self_hosted_site");
+ break;
+ case SIGNED_IN:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Signed In");
+ break;
+ case SIGNED_INTO_JETPACK:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Signed into Jetpack");
+ instructions.addSuperPropertyToFlag("jetpack_user");
+ instructions.addSuperPropertyToFlag("dotcom_user");
+ break;
+ case ACCOUNT_LOGOUT:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Logged Out");
+ break;
+ case PERFORMED_JETPACK_SIGN_IN_FROM_STATS_SCREEN:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Signed into Jetpack from Stats Screen");
+ break;
+ case STATS_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_stats");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_stats");
+ break;
+ case STATS_INSIGHTS_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Insights Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_insights_screen_stats");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_insights_screen_stats");
+ break;
+ case STATS_PERIOD_DAYS_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Period Days Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_days_screen_stats");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_days_screen_stats");
+ break;
+ case STATS_PERIOD_WEEKS_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Period Weeks Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_weeks_screen_stats");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_weeks_screen_stats");
+ break;
+ case STATS_PERIOD_MONTHS_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Period Months Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_months_screen_stats");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_months_screen_stats");
+ break;
+ case STATS_PERIOD_YEARS_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Period Years Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_years_screen_stats");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_years_screen_stats");
+ break;
+ case STATS_VIEW_ALL_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - View All Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_view_all_screen_stats");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_view_all_screen_stats");
+ break;
+ case STATS_SINGLE_POST_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Single Post Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_single_post_screen_stats");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_single_post_screen_stats");
+ break;
+ case STATS_TAPPED_BAR_CHART:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Tapped Bar Chart");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_tapped_stats_bar_chart");
+ instructions.setCurrentDateForPeopleProperty("last_time_tapped_stats_bar_chart");
+ break;
+ case STATS_SCROLLED_TO_BOTTOM:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Scrolled to Bottom");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_scrolled_to_bottom_of_stats");
+ instructions.setCurrentDateForPeopleProperty("last_time_scrolled_to_bottom_of_stats");
+ break;
+ case STATS_SELECTED_INSTALL_JETPACK:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Selected Install Jetpack");
+ break;
+ case STATS_SELECTED_CONNECT_JETPACK:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Selected Connect Jetpack");
+ break;
+ case STATS_WIDGET_ADDED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Widget Added");
+ break;
+ case STATS_WIDGET_REMOVED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Widget Removed");
+ break;
+ case STATS_WIDGET_TAPPED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Stats - Widget Tapped");
+ break;
+ case PUSH_NOTIFICATION_RECEIVED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Push Notification - Received");
+ break;
+ case PUSH_NOTIFICATION_TAPPED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Push Notification - Alert Tapped");
+ break;
+ case SUPPORT_OPENED_HELPSHIFT_SCREEN:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Support - Opened Helpshift Screen");
+ instructions.addSuperPropertyToFlag("opened_helpshift_screen");
+ break;
+ case SUPPORT_SENT_REPLY_TO_SUPPORT_MESSAGE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Support - Replied to Helpshift");
+ instructions.addSuperPropertyToFlag("support_replied_to_helpshift");
+ break;
+ case LOGIN_MAGIC_LINK_EXITED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Magic Link exited");
+ break;
+ case LOGIN_MAGIC_LINK_FAILED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Magic Link failed");
+ break;
+ case LOGIN_MAGIC_LINK_OPENED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Magic Link opened");
+ break;
+ case LOGIN_MAGIC_LINK_REQUESTED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Magic Link requested");
+ break;
+ case LOGIN_MAGIC_LINK_SUCCEEDED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Magic Link succeeded");
+ break;
+ case LOGIN_FAILED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Failed Login");
+ break;
+ case LOGIN_FAILED_TO_GUESS_XMLRPC:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Failed To Guess XMLRPC");
+ break;
+ case LOGIN_INSERTED_INVALID_URL:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Inserted Invalid URL");
+ break;
+ case LOGIN_AUTOFILL_CREDENTIALS_FILLED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Auto Fill Credentials Filled");
+ break;
+ case LOGIN_AUTOFILL_CREDENTIALS_UPDATED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Login - Auto Fill Credentials Updated");
+ break;
+ case PERSON_REMOVED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("People Management - Removed Person");
+ break;
+ case PERSON_UPDATED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("People Management - Updated Person");
+ break;
+ case PUSH_AUTHENTICATION_APPROVED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Push Authentication - Approved");
+ break;
+ case PUSH_AUTHENTICATION_EXPIRED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Push Authentication - Expired");
+ break;
+ case PUSH_AUTHENTICATION_FAILED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Push Authentication - Failed");
+ break;
+ case PUSH_AUTHENTICATION_IGNORED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Push Authentication - Ignored");
+ break;
+ case NOTIFICATION_SETTINGS_LIST_OPENED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Notification Settings - Accessed List");
+ break;
+ case NOTIFICATION_SETTINGS_STREAMS_OPENED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Notification Settings - Accessed Stream");
+ break;
+ case NOTIFICATION_SETTINGS_DETAILS_OPENED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Notification Settings - Accessed Details");
+ break;
+ case ME_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me Tab - Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_me_tab");
+ break;
+ case ME_GRAVATAR_TAPPED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Tapped Gravatar");
+ break;
+ case ME_GRAVATAR_TOOLTIP_TAPPED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Tapped Gravatar Tooltip");
+ break;
+ case ME_GRAVATAR_PERMISSIONS_INTERRUPTED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Gravatar Permissions Interrupted");
+ break;
+ case ME_GRAVATAR_PERMISSIONS_DENIED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Gravatar Permissions Denied");
+ break;
+ case ME_GRAVATAR_PERMISSIONS_ACCEPTED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Gravatar Permissions Accepted");
+ break;
+ case ME_GRAVATAR_SHOT_NEW:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Gravatar Shot New Photo");
+ break;
+ case ME_GRAVATAR_GALLERY_PICKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Gravatar Picked From Gallery");
+ break;
+ case ME_GRAVATAR_CROPPED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Gravatar Cropped");
+ break;
+ case ME_GRAVATAR_UPLOADED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Gravatar Uploaded");
+ break;
+ case ME_GRAVATAR_UPLOAD_UNSUCCESSFUL:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Gravatar Upload Unsuccessful");
+ break;
+ case ME_GRAVATAR_UPLOAD_EXCEPTION:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Me - Gravatar Upload Exception");
+ break;
+ case MY_SITE_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("My Site - Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_my_site");
+ break;
+ case THEMES_ACCESSED_THEMES_BROWSER:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Themes - Accessed Theme Browser");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_accessed_theme_browser");
+ instructions.setCurrentDateForPeopleProperty("last_time_accessed_theme_browser");
+ break;
+ case THEMES_ACCESSED_SEARCH:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Themes - Accessed Theme");
+ break;
+ case THEMES_CHANGED_THEME:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Themes - Changed Theme");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_changed_theme");
+ instructions.setCurrentDateForPeopleProperty("last_time_changed_theme");
+ break;
+ case THEMES_PREVIEWED_SITE:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Themes - Previewed Theme for Site");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_previewed_a_theme");
+ instructions.setCurrentDateForPeopleProperty("last_time_previewed_a_theme");
+ break;
+ case THEMES_DEMO_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Themes - Demo Accessed");
+ break;
+ case THEMES_CUSTOMIZE_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Themes - Customize Accessed");
+ break;
+ case THEMES_SUPPORT_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Themes - Support Accessed");
+ break;
+ case THEMES_DETAILS_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Themes - Details Accessed");
+ break;
+ case ACCOUNT_SETTINGS_LANGUAGE_CHANGED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Account Settings - Changed Language");
+ break;
+ case SITE_SETTINGS_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Settings - Site Settings Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_settings_accessed");
+ break;
+ case SITE_SETTINGS_ACCESSED_MORE_SETTINGS:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Settings - More Settings Accessed");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_more_settings_accessed");
+ break;
+ case SITE_SETTINGS_ADDED_LIST_ITEM:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Settings - Added List Item");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_list_items_added");
+ break;
+ case SITE_SETTINGS_DELETED_LIST_ITEMS:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Settings - Site Deleted List Items");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_list_items_were_deleted");
+ break;
+ case SITE_SETTINGS_HINT_TOAST_SHOWN:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Settings - Preference Hint Shown");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_preference_hints_viewed");
+ break;
+ case SITE_SETTINGS_LEARN_MORE_CLICKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Settings - Learn More Clicked");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_learn_more_clicked");
+ break;
+ case SITE_SETTINGS_LEARN_MORE_LOADED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Settings - Learn More Loaded");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_learn_more_seen");
+ break;
+ case SITE_SETTINGS_SAVED_REMOTELY:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.
+ mixpanelInstructionsForEventName("Settings - Saved Remotely");
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement("number_of_times_settings_updated_remotely");
+ break;
+ case SITE_SETTINGS_START_OVER_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Start Over Accessed");
+ break;
+ case SITE_SETTINGS_START_OVER_CONTACT_SUPPORT_CLICKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Start Over Contact Support Clicked");
+ break;
+ case SITE_SETTINGS_EXPORT_SITE_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Export Site Accessed");
+ break;
+ case SITE_SETTINGS_EXPORT_SITE_REQUESTED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Export Site Requested");
+ break;
+ case SITE_SETTINGS_EXPORT_SITE_RESPONSE_OK:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Export Site Response OK");
+ break;
+ case SITE_SETTINGS_EXPORT_SITE_RESPONSE_ERROR:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Export Site Response Error");
+ break;
+ case SITE_SETTINGS_DELETE_SITE_ACCESSED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Delete Site Accessed");
+ break;
+ case SITE_SETTINGS_DELETE_SITE_PURCHASES_REQUESTED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Delete Site Purchases Requested");
+ break;
+ case SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOWN:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Delete Site Purchases Shown");
+ break;
+ case SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOW_CLICKED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Delete Site Show Purchases Clicked");
+ break;
+ case SITE_SETTINGS_DELETE_SITE_REQUESTED:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Delete Site Requested");
+ break;
+ case SITE_SETTINGS_DELETE_SITE_RESPONSE_OK:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Delete Site Response OK");
+ break;
+ case SITE_SETTINGS_DELETE_SITE_RESPONSE_ERROR:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("Settings - Delete Site Response Error");
+ break;
+ case ABTEST_START:
+ instructions = AnalyticsTrackerMixpanelInstructionsForStat.mixpanelInstructionsForEventName("AB Test - Started");
+ break;
+ case TRAIN_TRACKS_RENDER: case TRAIN_TRACKS_INTERACT:
+ // Do nothing. These events are just for Tracks.
+ instructions = null;
+ break;
+ default:
+ instructions = null;
+ break;
+ }
+ return instructions;
+ }
+
+ private void incrementPeopleProperty(String property) {
+ try {
+ mMixpanel.getPeople().increment(property, 1);
+ } catch (OutOfMemoryError outOfMemoryError) {
+ // ignore exception
+ }
+ }
+
+ @SuppressLint("CommitPrefEdits")
+ private void incrementSuperProperty(String property) {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
+ int propertyCount = preferences.getInt(property, 0);
+ propertyCount++;
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putInt(property, propertyCount);
+ editor.commit();
+
+ try {
+ JSONObject superProperties = mMixpanel.getSuperProperties();
+ superProperties.put(property, propertyCount);
+ mMixpanel.registerSuperProperties(superProperties);
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.UTILS, e);
+ }
+ }
+
+ private void flagSuperProperty(String property) {
+ try {
+ JSONObject superProperties = mMixpanel.getSuperProperties();
+ superProperties.put(property, true);
+ mMixpanel.registerSuperProperties(superProperties);
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.UTILS, e);
+ }
+ }
+
+ private void savePropertyValueForStat(String property, Object value, AnalyticsTracker.Stat stat) {
+ JSONObject properties = mAggregatedProperties.get(stat);
+ if (properties == null) {
+ properties = new JSONObject();
+ mAggregatedProperties.put(stat, properties);
+ }
+
+ try {
+ properties.put(property, value);
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.UTILS, e);
+ }
+ }
+
+ private JSONObject propertiesForStat(AnalyticsTracker.Stat stat) {
+ return mAggregatedProperties.get(stat);
+ }
+
+ private void removePropertiesForStat(AnalyticsTracker.Stat stat) {
+ mAggregatedProperties.remove(stat);
+ }
+
+ private Object propertyForStat(String property, AnalyticsTracker.Stat stat) {
+ JSONObject properties = mAggregatedProperties.get(stat);
+ if (properties == null) {
+ return null;
+ }
+
+ try {
+ return properties.get(property);
+ } catch (JSONException e) {
+ // We are okay with swallowing this exception as the next line will just return a null value
+ }
+
+ return null;
+ }
+
+ private void incrementProperty(String property, AnalyticsTracker.Stat stat) {
+ Object currentValueObj = propertyForStat(property, stat);
+ int currentValue = 1;
+ if (currentValueObj != null) {
+ currentValue = Integer.valueOf(currentValueObj.toString());
+ currentValue++;
+ }
+
+ savePropertyValueForStat(property, Integer.toString(currentValue), stat);
+ }
+
+
+ public void incrementSessionCount() {
+ // Tracking session count will help us isolate users who just installed the app
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
+ int sessionCount = preferences.getInt(SESSION_COUNT, 0);
+ sessionCount++;
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putInt(SESSION_COUNT, sessionCount);
+ editor.apply();
+ }
+}
diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanelInstructionsForStat.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanelInstructionsForStat.java
new file mode 100644
index 000000000..38aefa988
--- /dev/null
+++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanelInstructionsForStat.java
@@ -0,0 +1,140 @@
+package org.wordpress.android.analytics;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+public class AnalyticsTrackerMixpanelInstructionsForStat {
+ private String mMixpanelEventName;
+ private String mSuperPropertyToIncrement;
+ private String mPeoplePropertyToIncrement;
+ private ArrayList<String> mSuperPropertiesToFlag;
+ private AnalyticsTracker.Stat mStatToAttachProperty;
+ private AnalyticsTracker.Stat mStat;
+ private String mPropertyToIncrement;
+ private boolean mDisableForSelfHosted;
+ private Map<String, Object> mPeoplePropertiesToAssign;
+
+ public AnalyticsTrackerMixpanelInstructionsForStat() {
+ mSuperPropertiesToFlag = new ArrayList<String>();
+ mPeoplePropertiesToAssign = new HashMap<String, Object>();
+ }
+
+ public static AnalyticsTrackerMixpanelInstructionsForStat mixpanelInstructionsForEventName(String eventName) {
+ AnalyticsTrackerMixpanelInstructionsForStat instructions = new AnalyticsTrackerMixpanelInstructionsForStat();
+ instructions.setMixpanelEventName(eventName);
+ return instructions;
+ }
+
+ public static AnalyticsTrackerMixpanelInstructionsForStat
+ mixpanelInstructionsWithSuperPropertyAndPeoplePropertyIncrementor(String property) {
+ AnalyticsTrackerMixpanelInstructionsForStat instructions = new AnalyticsTrackerMixpanelInstructionsForStat();
+ instructions.setSuperPropertyAndPeoplePropertyToIncrement(property);
+ return instructions;
+ }
+
+ public static AnalyticsTrackerMixpanelInstructionsForStat mixpanelInstructionsWithPropertyIncrementor(
+ String property, AnalyticsTracker.Stat stat) {
+ AnalyticsTrackerMixpanelInstructionsForStat instructions = new AnalyticsTrackerMixpanelInstructionsForStat();
+ instructions.setStatToAttachProperty(stat);
+ instructions.setPropertyToIncrement(property);
+ return instructions;
+ }
+
+ public String getMixpanelEventName() {
+ return mMixpanelEventName;
+ }
+
+ public void setMixpanelEventName(String mixpanelEventName) {
+ this.mMixpanelEventName = mixpanelEventName;
+ }
+
+ public String getSuperPropertyToIncrement() {
+ return mSuperPropertyToIncrement;
+ }
+
+ public void setSuperPropertyToIncrement(String superPropertyToIncrement) {
+ this.mSuperPropertyToIncrement = superPropertyToIncrement;
+ }
+
+ public String getPeoplePropertyToIncrement() {
+ return mPeoplePropertyToIncrement;
+ }
+
+ public void setPeoplePropertyToIncrement(String peoplePropertyToIncrement) {
+ this.mPeoplePropertyToIncrement = peoplePropertyToIncrement;
+ }
+
+ public void setSuperPropertyAndPeoplePropertyToIncrement(String property) {
+ setSuperPropertyToIncrement(property);
+ setPeoplePropertyToIncrement(property);
+ }
+
+ public AnalyticsTracker.Stat getStatToAttachProperty() {
+ return mStatToAttachProperty;
+ }
+
+ public void setStatToAttachProperty(AnalyticsTracker.Stat statToAttachProperty) {
+ this.mStatToAttachProperty = statToAttachProperty;
+ }
+
+ public String getPropertyToIncrement() {
+ return mPropertyToIncrement;
+ }
+
+ public void setPropertyToIncrement(String propertyToIncrement) {
+ this.mPropertyToIncrement = propertyToIncrement;
+ }
+
+ public boolean getDisableForSelfHosted() {
+ return mDisableForSelfHosted;
+ }
+
+ public void setDisableForSelfHosted(boolean disableForSelfHosted) {
+ this.mDisableForSelfHosted = disableForSelfHosted;
+ }
+
+ public AnalyticsTracker.Stat getStat() {
+ return mStat;
+ }
+
+ public void setStat(AnalyticsTracker.Stat stat) {
+ this.mStat = stat;
+ }
+
+ public ArrayList<String> getSuperPropertiesToFlag() {
+ return mSuperPropertiesToFlag;
+ }
+
+ public void addSuperPropertyToFlag(String superPropertyToFlag) {
+ if (!mSuperPropertiesToFlag.contains(superPropertyToFlag)) {
+ mSuperPropertiesToFlag.add(superPropertyToFlag);
+ }
+ }
+
+ private static final ThreadLocal<DateFormat> AnalyticsDateFormat = new ThreadLocal<DateFormat>() {
+ @Override
+ protected DateFormat initialValue() {
+ DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
+ format.setTimeZone(TimeZone.getTimeZone("UTC"));
+ return format;
+ }
+ };
+
+ public void setCurrentDateForPeopleProperty(String property) {
+ setPeoplePropertyToValue(property, AnalyticsDateFormat.get().format(new Date()));
+ }
+
+ public void setPeoplePropertyToValue(String property, Object value) {
+ mPeoplePropertiesToAssign.put(property, value);
+ }
+
+ public Map<String, Object> getPeoplePropertiesToAssign() {
+ return mPeoplePropertiesToAssign;
+ }
+}
diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java
new file mode 100644
index 000000000..76c181b9b
--- /dev/null
+++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java
@@ -0,0 +1,589 @@
+package org.wordpress.android.analytics;
+
+import android.content.Context;
+
+import com.automattic.android.tracks.TracksClient;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.wordpress.android.util.AppLog;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class AnalyticsTrackerNosara extends Tracker {
+
+ private static final String JETPACK_USER = "jetpack_user";
+ private static final String NUMBER_OF_BLOGS = "number_of_blogs";
+ private static final String TRACKS_ANON_ID = "nosara_tracks_anon_id";
+
+ private static final String EVENTS_PREFIX = "wpandroid_";
+
+ private TracksClient mNosaraClient;
+
+ public AnalyticsTrackerNosara(Context context) throws IllegalArgumentException {
+ super(context);
+ mNosaraClient = TracksClient.getClient(context);
+ }
+
+ String getAnonIdPrefKey() {
+ return TRACKS_ANON_ID;
+ }
+
+ @Override
+ public void track(AnalyticsTracker.Stat stat) {
+ track(stat, null);
+ }
+
+ @Override
+ public void track(AnalyticsTracker.Stat stat, Map<String, ?> properties) {
+ if (mNosaraClient == null) {
+ return;
+ }
+
+ String eventName = getEventNameForStat(stat);
+ if (eventName == null) {
+ AppLog.w(AppLog.T.STATS, "There is NO match for the event " + stat.name() + "stat");
+ return;
+ }
+
+ Map<String, Object> predefinedEventProperties = new HashMap<String, Object>();
+ switch (stat) {
+ case EDITOR_ADDED_PHOTO_VIA_LOCAL_LIBRARY:
+ predefinedEventProperties.put("via", "local_library");
+ break;
+ case EDITOR_ADDED_PHOTO_VIA_WP_MEDIA_LIBRARY:
+ predefinedEventProperties.put("via", "media_library");
+ break;
+ case EDITOR_ADDED_VIDEO_VIA_LOCAL_LIBRARY:
+ predefinedEventProperties.put("via", "local_library");
+ break;
+ case EDITOR_ADDED_VIDEO_VIA_WP_MEDIA_LIBRARY:
+ predefinedEventProperties.put("via", "media_library");
+ break;
+ case EDITOR_TAPPED_BLOCKQUOTE:
+ predefinedEventProperties.put("button", "blockquote");
+ break;
+ case EDITOR_TAPPED_BOLD:
+ predefinedEventProperties.put("button", "bold");
+ break;
+ case EDITOR_TAPPED_IMAGE:
+ predefinedEventProperties.put("button", "image");
+ break;
+ case EDITOR_TAPPED_ITALIC:
+ predefinedEventProperties.put("button", "italic");
+ break;
+ case EDITOR_TAPPED_LINK:
+ predefinedEventProperties.put("button", "link");
+ break;
+ case EDITOR_TAPPED_MORE:
+ predefinedEventProperties.put("button", "more");
+ break;
+ case EDITOR_TAPPED_STRIKETHROUGH:
+ predefinedEventProperties.put("button", "strikethrough");
+ break;
+ case EDITOR_TAPPED_UNDERLINE:
+ predefinedEventProperties.put("button", "underline");
+ break;
+ case EDITOR_TAPPED_HTML:
+ predefinedEventProperties.put("button", "html");
+ break;
+ case EDITOR_TAPPED_ORDERED_LIST:
+ predefinedEventProperties.put("button", "ordered_list");
+ break;
+ case EDITOR_TAPPED_UNLINK:
+ predefinedEventProperties.put("button", "unlink");
+ break;
+ case EDITOR_TAPPED_UNORDERED_LIST:
+ predefinedEventProperties.put("button", "unordered_list");
+ break;
+ case OPENED_POSTS:
+ predefinedEventProperties.put("menu_item", "posts");
+ break;
+ case OPENED_PAGES:
+ predefinedEventProperties.put("menu_item", "pages");
+ break;
+ case OPENED_COMMENTS:
+ predefinedEventProperties.put("menu_item", "comments");
+ break;
+ case OPENED_VIEW_SITE:
+ predefinedEventProperties.put("menu_item", "view_site");
+ break;
+ case OPENED_VIEW_ADMIN:
+ predefinedEventProperties.put("menu_item", "view_admin");
+ break;
+ case OPENED_MEDIA_LIBRARY:
+ predefinedEventProperties.put("menu_item", "media_library");
+ break;
+ case OPENED_BLOG_SETTINGS:
+ predefinedEventProperties.put("menu_item", "site_settings");
+ break;
+ case STATS_PERIOD_DAYS_ACCESSED:
+ predefinedEventProperties.put("period", "days");
+ break;
+ case STATS_PERIOD_WEEKS_ACCESSED:
+ predefinedEventProperties.put("period", "weeks");
+ break;
+ case STATS_PERIOD_MONTHS_ACCESSED:
+ predefinedEventProperties.put("period", "months");
+ break;
+ case STATS_PERIOD_YEARS_ACCESSED:
+ predefinedEventProperties.put("period", "years");
+ break;
+ }
+
+ final String user;
+ final TracksClient.NosaraUserType userType;
+ if (getWordPressComUserName() != null) {
+ user = getWordPressComUserName();
+ userType = TracksClient.NosaraUserType.WPCOM;
+ } else {
+ // This is just a security checks since the anonID is already available here.
+ // refresh metadata is called on login/logout/startup and it loads/generates the anonId when necessary.
+ if (getAnonID() == null) {
+ user = generateNewAnonID();
+ } else {
+ user = getAnonID();
+ }
+ userType = TracksClient.NosaraUserType.ANON;
+ }
+
+
+ // create the merged JSON Object of properties
+ // Properties defined by the user have precedence over the default ones pre-defined at "event level"
+ final JSONObject propertiesToJSON;
+ if (properties != null && properties.size() > 0) {
+ propertiesToJSON = new JSONObject(properties);
+ for (String key : predefinedEventProperties.keySet()) {
+ try {
+ if (propertiesToJSON.has(key)) {
+ AppLog.w(AppLog.T.STATS, "The user has defined a property named: '" + key + "' that will override" +
+ "the same property pre-defined at event level. This may generate unexpected behavior!!");
+ AppLog.w(AppLog.T.STATS, "User value: " + propertiesToJSON.get(key).toString() + " - pre-defined value: " +
+ predefinedEventProperties.get(key).toString());
+ } else {
+ propertiesToJSON.put(key, predefinedEventProperties.get(key));
+ }
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.STATS, "Error while merging user-defined properties with pre-defined properties", e);
+ }
+ }
+ } else{
+ propertiesToJSON = new JSONObject(predefinedEventProperties);
+ }
+
+ if (propertiesToJSON.length() > 0) {
+ mNosaraClient.track(EVENTS_PREFIX + eventName, propertiesToJSON, user, userType);
+ } else {
+ mNosaraClient.track(EVENTS_PREFIX + eventName, user, userType);
+ }
+ }
+
+
+
+ @Override
+ public void endSession() {
+ this.flush();
+ }
+
+ @Override
+ public void flush() {
+ if (mNosaraClient == null) {
+ return;
+ }
+ mNosaraClient.flush();
+ }
+
+ @Override
+ public void refreshMetadata(AnalyticsMetadata metadata) {
+ if (mNosaraClient == null) {
+ return;
+ }
+
+ try {
+ JSONObject properties = new JSONObject();
+ properties.put(JETPACK_USER, metadata.isJetpackUser());
+ properties.put(NUMBER_OF_BLOGS, metadata.getNumBlogs());
+ mNosaraClient.registerUserProperties(properties);
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.UTILS, e);
+ }
+
+ if (metadata.isUserConnected() && metadata.isWordPressComUser()) {
+ setWordPressComUserName(metadata.getUsername());
+ // Re-unify the user
+ if (getAnonID() != null) {
+ mNosaraClient.trackAliasUser(getWordPressComUserName(), getAnonID(), TracksClient.NosaraUserType.WPCOM);
+ clearAnonID();
+ }
+ } else {
+ // Not wpcom connected. Check if anonID is already present
+ setWordPressComUserName(null);
+ if (getAnonID() == null) {
+ generateNewAnonID();
+ }
+ }
+
+
+ }
+
+
+ @Override
+ public void clearAllData() {
+ super.clearAllData();
+ if (mNosaraClient == null) {
+ return;
+ }
+ mNosaraClient.clearUserProperties();
+ }
+
+ @Override
+ public void registerPushNotificationToken(String regId) {
+ return;
+ }
+
+ public static String getEventNameForStat(AnalyticsTracker.Stat stat) {
+ switch (stat) {
+ case APPLICATION_OPENED:
+ return "application_opened";
+ case APPLICATION_CLOSED:
+ return "application_closed";
+ case APPLICATION_INSTALLED:
+ return "application_installed";
+ case APPLICATION_UPGRADED:
+ return "application_upgraded";
+ case READER_ACCESSED:
+ return "reader_accessed";
+ case READER_ARTICLE_COMMENTED_ON:
+ return "reader_article_commented_on";
+ case READER_ARTICLE_LIKED:
+ return "reader_article_liked";
+ case READER_ARTICLE_OPENED:
+ return "reader_article_opened";
+ case READER_ARTICLE_UNLIKED:
+ return "reader_article_unliked";
+ case READER_BLOG_BLOCKED:
+ return "reader_blog_blocked";
+ case READER_BLOG_FOLLOWED:
+ return "reader_site_followed";
+ case READER_BLOG_PREVIEWED:
+ return "reader_blog_previewed";
+ case READER_BLOG_UNFOLLOWED:
+ return "reader_site_unfollowed";
+ case READER_DISCOVER_VIEWED:
+ return "reader_discover_viewed";
+ case READER_INFINITE_SCROLL:
+ return "reader_infinite_scroll_performed";
+ case READER_LIST_FOLLOWED:
+ return "reader_list_followed";
+ case READER_LIST_LOADED:
+ return "reader_list_loaded";
+ case READER_LIST_PREVIEWED:
+ return "reader_list_previewed";
+ case READER_LIST_UNFOLLOWED:
+ return "reader_list_unfollowed";
+ case READER_TAG_FOLLOWED:
+ return "reader_reader_tag_followed";
+ case READER_TAG_LOADED:
+ return "reader_tag_loaded";
+ case READER_TAG_PREVIEWED:
+ return "reader_tag_previewed";
+ case READER_SEARCH_LOADED:
+ return "reader_search_loaded";
+ case READER_SEARCH_PERFORMED:
+ return "reader_search_performed";
+ case READER_SEARCH_RESULT_TAPPED:
+ return "reader_searchcard_clicked";
+ case READER_TAG_UNFOLLOWED:
+ return "reader_reader_tag_unfollowed";
+ case READER_RELATED_POST_CLICKED:
+ return "reader_related_post_clicked";
+ case EDITOR_CREATED_POST:
+ return "editor_post_created";
+ case EDITOR_SAVED_DRAFT:
+ return "editor_draft_saved";
+ case EDITOR_DISCARDED_CHANGES:
+ return "editor_discarded_changes";
+ case EDITOR_EDITED_IMAGE:
+ return "editor_image_edited";
+ case EDITOR_ENABLED_NEW_VERSION:
+ return "editor_enabled_new_version";
+ case EDITOR_TOGGLED_OFF:
+ return "editor_toggled_off";
+ case EDITOR_TOGGLED_ON:
+ return "editor_toggled_on";
+ case EDITOR_UPLOAD_MEDIA_FAILED:
+ return "editor_upload_media_failed";
+ case EDITOR_UPLOAD_MEDIA_RETRIED:
+ return "editor_upload_media_retried";
+ case EDITOR_CLOSED:
+ return "editor_closed";
+ case EDITOR_ADDED_PHOTO_VIA_LOCAL_LIBRARY:
+ return "editor_photo_added";
+ case EDITOR_ADDED_PHOTO_VIA_WP_MEDIA_LIBRARY:
+ return "editor_photo_added";
+ case EDITOR_ADDED_VIDEO_VIA_LOCAL_LIBRARY:
+ return "editor_video_added";
+ case EDITOR_ADDED_VIDEO_VIA_WP_MEDIA_LIBRARY:
+ return "editor_video_added";
+ case EDITOR_PUBLISHED_POST:
+ return "editor_post_published";
+ case EDITOR_UPDATED_POST:
+ return "editor_post_updated";
+ case EDITOR_SCHEDULED_POST:
+ return "editor_post_scheduled";
+ case EDITOR_TAPPED_BLOCKQUOTE:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_BOLD:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_IMAGE:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_ITALIC:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_LINK:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_MORE:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_STRIKETHROUGH:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_UNDERLINE:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_HTML:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_ORDERED_LIST:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_UNLINK:
+ return "editor_button_tapped";
+ case EDITOR_TAPPED_UNORDERED_LIST:
+ return "editor_button_tapped";
+ case NOTIFICATIONS_ACCESSED:
+ return "notifications_accessed";
+ case NOTIFICATIONS_OPENED_NOTIFICATION_DETAILS:
+ return "notifications_notification_details_opened";
+ case NOTIFICATION_APPROVED:
+ return "notifications_approved";
+ case NOTIFICATION_UNAPPROVED:
+ return "notifications_unapproved";
+ case NOTIFICATION_REPLIED_TO:
+ return "notifications_replied_to";
+ case NOTIFICATION_TRASHED:
+ return "notifications_trashed";
+ case NOTIFICATION_FLAGGED_AS_SPAM:
+ return "notifications_flagged_as_spam";
+ case NOTIFICATION_LIKED:
+ return "notifications_comment_liked";
+ case NOTIFICATION_UNLIKED:
+ return "notifications_comment_unliked";
+ case OPENED_POSTS:
+ return "site_menu_opened";
+ case OPENED_PAGES:
+ return "site_menu_opened";
+ case OPENED_COMMENTS:
+ return "site_menu_opened";
+ case OPENED_VIEW_SITE:
+ return "site_menu_opened";
+ case OPENED_VIEW_ADMIN:
+ return "site_menu_opened";
+ case OPENED_MEDIA_LIBRARY:
+ return "site_menu_opened";
+ case OPENED_BLOG_SETTINGS:
+ return "site_menu_opened";
+ case OPENED_ACCOUNT_SETTINGS:
+ return "account_settings_opened";
+ case OPENED_APP_SETTINGS:
+ return "app_settings_opened";
+ case OPENED_MY_PROFILE:
+ return "my_profile_opened";
+ case OPENED_PEOPLE_MANAGEMENT:
+ return "people_management_list_opened";
+ case OPENED_PERSON:
+ return "people_management_details_opened";
+ case CREATED_ACCOUNT:
+ return "account_created";
+ case CREATED_SITE:
+ return "site_created";
+ case SHARED_ITEM:
+ return "item_shared";
+ case ADDED_SELF_HOSTED_SITE:
+ return "self_hosted_blog_added";
+ case SIGNED_IN:
+ return "signed_in";
+ case SIGNED_INTO_JETPACK:
+ return "signed_into_jetpack";
+ case ACCOUNT_LOGOUT:
+ return "account_logout";
+ case PERFORMED_JETPACK_SIGN_IN_FROM_STATS_SCREEN:
+ return "stats_screen_signed_into_jetpack";
+ case STATS_ACCESSED:
+ return "stats_accessed";
+ case STATS_INSIGHTS_ACCESSED:
+ return "stats_insights_accessed";
+ case STATS_PERIOD_DAYS_ACCESSED:
+ return "stats_period_accessed";
+ case STATS_PERIOD_WEEKS_ACCESSED:
+ return "stats_period_accessed";
+ case STATS_PERIOD_MONTHS_ACCESSED:
+ return "stats_period_accessed";
+ case STATS_PERIOD_YEARS_ACCESSED:
+ return "stats_period_accessed";
+ case STATS_VIEW_ALL_ACCESSED:
+ return "stats_view_all_accessed";
+ case STATS_SINGLE_POST_ACCESSED:
+ return "stats_single_post_accessed";
+ case STATS_TAPPED_BAR_CHART:
+ return "stats_bar_chart_tapped";
+ case STATS_SCROLLED_TO_BOTTOM:
+ return "stats_scrolled_to_bottom";
+ case STATS_SELECTED_INSTALL_JETPACK:
+ return "stats_install_jetpack_selected";
+ case STATS_SELECTED_CONNECT_JETPACK:
+ return "stats_connect_jetpack_selected";
+ case STATS_WIDGET_ADDED:
+ return "stats_widget_added";
+ case STATS_WIDGET_REMOVED:
+ return "stats_widget_removed";
+ case STATS_WIDGET_TAPPED:
+ return "stats_widget_tapped";
+ case PUSH_NOTIFICATION_RECEIVED:
+ return "push_notification_received";
+ case PUSH_NOTIFICATION_TAPPED:
+ return "push_notification_alert_tapped";
+ case SUPPORT_OPENED_HELPSHIFT_SCREEN:
+ return "support_helpshift_screen_opened";
+ case SUPPORT_SENT_REPLY_TO_SUPPORT_MESSAGE:
+ return "support_reply_to_support_message_sent";
+ case LOGIN_MAGIC_LINK_EXITED:
+ return "login_magic_link_exited";
+ case LOGIN_MAGIC_LINK_FAILED:
+ return "login_magic_link_failed";
+ case LOGIN_MAGIC_LINK_OPENED:
+ return "login_magic_link_opened";
+ case LOGIN_MAGIC_LINK_REQUESTED:
+ return "login_magic_link_requested";
+ case LOGIN_MAGIC_LINK_SUCCEEDED:
+ return "login_magic_link_succeeded";
+ case LOGIN_FAILED:
+ return "login_failed_to_login";
+ case LOGIN_FAILED_TO_GUESS_XMLRPC:
+ return "login_failed_to_guess_xmlrpc";
+ case LOGIN_INSERTED_INVALID_URL:
+ return "login_inserted_invalid_url";
+ case LOGIN_AUTOFILL_CREDENTIALS_FILLED:
+ return "login_autofill_credentials_filled";
+ case LOGIN_AUTOFILL_CREDENTIALS_UPDATED:
+ return "login_autofill_credentials_updated";
+ case PERSON_REMOVED:
+ return "people_management_person_removed";
+ case PERSON_UPDATED:
+ return "people_management_person_updated";
+ case PUSH_AUTHENTICATION_APPROVED:
+ return "push_authentication_approved";
+ case PUSH_AUTHENTICATION_EXPIRED:
+ return "push_authentication_expired";
+ case PUSH_AUTHENTICATION_FAILED:
+ return "push_authentication_failed";
+ case PUSH_AUTHENTICATION_IGNORED:
+ return "push_authentication_ignored";
+ case NOTIFICATION_SETTINGS_LIST_OPENED:
+ return "notification_settings_list_opened";
+ case NOTIFICATION_SETTINGS_STREAMS_OPENED:
+ return "notification_settings_streams_opened";
+ case NOTIFICATION_SETTINGS_DETAILS_OPENED:
+ return "notification_settings_details_opened";
+ case ME_ACCESSED:
+ return "me_tab_accessed";
+ case ME_GRAVATAR_TAPPED:
+ return "me_gravatar_tapped";
+ case ME_GRAVATAR_TOOLTIP_TAPPED:
+ return "me_gravatar_tooltip_tapped";
+ case ME_GRAVATAR_PERMISSIONS_INTERRUPTED:
+ return "me_gravatar_permissions_interrupted";
+ case ME_GRAVATAR_PERMISSIONS_DENIED:
+ return "me_gravatar_permissions_denied";
+ case ME_GRAVATAR_PERMISSIONS_ACCEPTED:
+ return "me_gravatar_permissions_accepted";
+ case ME_GRAVATAR_SHOT_NEW:
+ return "me_gravatar_shot_new";
+ case ME_GRAVATAR_GALLERY_PICKED:
+ return "me_gravatar_gallery_picked";
+ case ME_GRAVATAR_CROPPED:
+ return "me_gravatar_cropped";
+ case ME_GRAVATAR_UPLOADED:
+ return "me_gravatar_uploaded";
+ case ME_GRAVATAR_UPLOAD_UNSUCCESSFUL:
+ return "me_gravatar_upload_unsuccessful";
+ case ME_GRAVATAR_UPLOAD_EXCEPTION:
+ return "me_gravatar_upload_exception";
+ case MY_SITE_ACCESSED:
+ return "my_site_tab_accessed";
+ case THEMES_ACCESSED_THEMES_BROWSER:
+ return "themes_theme_browser_accessed";
+ case THEMES_ACCESSED_SEARCH:
+ return "themes_search_accessed";
+ case THEMES_CHANGED_THEME:
+ return "themes_theme_changed";
+ case THEMES_PREVIEWED_SITE:
+ return "themes_theme_for_site_previewed";
+ case THEMES_DEMO_ACCESSED:
+ return "themes_demo_accessed";
+ case THEMES_CUSTOMIZE_ACCESSED:
+ return "themes_customize_accessed";
+ case THEMES_SUPPORT_ACCESSED:
+ return "themes_support_accessed";
+ case THEMES_DETAILS_ACCESSED:
+ return "themes_details_accessed";
+ case ACCOUNT_SETTINGS_LANGUAGE_CHANGED:
+ return "account_settings_language_changed";
+ case SITE_SETTINGS_ACCESSED:
+ return "site_settings_accessed";
+ case SITE_SETTINGS_ACCESSED_MORE_SETTINGS:
+ return "site_settings_more_settings_accessed";
+ case SITE_SETTINGS_ADDED_LIST_ITEM:
+ return "site_settings_added_list_item";
+ case SITE_SETTINGS_DELETED_LIST_ITEMS:
+ return "site_settings_deleted_list_items";
+ case SITE_SETTINGS_HINT_TOAST_SHOWN:
+ return "site_settings_hint_toast_shown";
+ case SITE_SETTINGS_LEARN_MORE_CLICKED:
+ return "site_settings_learn_more_clicked";
+ case SITE_SETTINGS_LEARN_MORE_LOADED:
+ return "site_settings_learn_more_loaded";
+ case SITE_SETTINGS_SAVED_REMOTELY:
+ return "site_settings_saved_remotely";
+ case SITE_SETTINGS_START_OVER_ACCESSED:
+ return "site_settings_start_over_accessed";
+ case SITE_SETTINGS_START_OVER_CONTACT_SUPPORT_CLICKED:
+ return "site_settings_start_over_contact_support_clicked";
+ case SITE_SETTINGS_EXPORT_SITE_ACCESSED:
+ return "site_settings_export_site_accessed";
+ case SITE_SETTINGS_EXPORT_SITE_REQUESTED:
+ return "site_settings_export_site_requested";
+ case SITE_SETTINGS_EXPORT_SITE_RESPONSE_OK:
+ return "site_settings_export_site_response_ok";
+ case SITE_SETTINGS_EXPORT_SITE_RESPONSE_ERROR:
+ return "site_settings_export_site_response_error";
+ case SITE_SETTINGS_DELETE_SITE_ACCESSED:
+ return "site_settings_delete_site_accessed";
+ case SITE_SETTINGS_DELETE_SITE_PURCHASES_REQUESTED:
+ return "site_settings_delete_site_purchases_requested";
+ case SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOWN:
+ return "site_settings_delete_site_purchases_shown";
+ case SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOW_CLICKED:
+ return "site_settings_delete_site_purchases_show_clicked";
+ case SITE_SETTINGS_DELETE_SITE_REQUESTED:
+ return "site_settings_delete_site_requested";
+ case SITE_SETTINGS_DELETE_SITE_RESPONSE_OK:
+ return "site_settings_delete_site_response_ok";
+ case SITE_SETTINGS_DELETE_SITE_RESPONSE_ERROR:
+ return "site_settings_delete_site_response_error";
+ case ABTEST_START:
+ return "abtest_start";
+ case TRAIN_TRACKS_RENDER:
+ return "traintracks_render";
+ case TRAIN_TRACKS_INTERACT:
+ return "traintracks_interact";
+ default:
+ return null;
+ }
+ }
+}
diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/Tracker.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/Tracker.java
new file mode 100644
index 000000000..e1b35f125
--- /dev/null
+++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/Tracker.java
@@ -0,0 +1,77 @@
+package org.wordpress.android.analytics;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import java.util.Map;
+import java.util.UUID;
+
+import org.wordpress.android.analytics.AnalyticsTracker.Stat;
+import org.wordpress.android.util.AppLog;
+
+public abstract class Tracker {
+ abstract void track(Stat stat);
+ abstract void track(Stat stat, Map<String, ?> properties);
+ abstract void endSession();
+ abstract void flush();
+ abstract void refreshMetadata(AnalyticsMetadata metadata);
+ abstract void registerPushNotificationToken(String regId);
+ abstract String getAnonIdPrefKey();
+
+ private String mAnonID = null; // do not access this variable directly. Use methods.
+ private String mWpcomUserName = null;
+ Context mContext;
+
+ public Tracker(Context context) throws IllegalArgumentException {
+ if (null == context) {
+ throw new IllegalArgumentException("Tracker requires a not-null context");
+ }
+ mContext = context;
+ }
+
+ void clearAllData() {
+ // Reset the anon ID here
+ clearAnonID();
+ setWordPressComUserName(null);
+ }
+
+ void clearAnonID() {
+ mAnonID = null;
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
+ if (preferences.contains(getAnonIdPrefKey())) {
+ final SharedPreferences.Editor editor = preferences.edit();
+ editor.remove(getAnonIdPrefKey());
+ editor.commit();
+ }
+ }
+
+ String getAnonID() {
+ if (mAnonID == null) {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
+ mAnonID = preferences.getString(getAnonIdPrefKey(), null);
+ }
+ return mAnonID;
+ }
+
+ String generateNewAnonID() {
+ String uuid = UUID.randomUUID().toString().replace("-", "");
+ AppLog.d(AppLog.T.STATS, "New anonID generated in " + this.getClass().getSimpleName() + ": " + uuid);
+
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
+ final SharedPreferences.Editor editor = preferences.edit();
+ editor.putString(getAnonIdPrefKey(), uuid);
+ editor.commit();
+
+ mAnonID = uuid;
+ return uuid;
+ }
+
+ String getWordPressComUserName() {
+ return mWpcomUserName;
+ }
+
+ void setWordPressComUserName(String userName) {
+ mWpcomUserName = userName;
+ }
+}
diff --git a/libs/analytics/build.gradle b/libs/analytics/build.gradle
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/libs/analytics/build.gradle
diff --git a/libs/analytics/gradle/wrapper/gradle-wrapper.jar b/libs/analytics/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..0087cd3b1
--- /dev/null
+++ b/libs/analytics/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/libs/analytics/gradle/wrapper/gradle-wrapper.properties b/libs/analytics/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..26af108cc
--- /dev/null
+++ b/libs/analytics/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Jul 09 11:48:51 CEST 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-all.zip
diff --git a/libs/analytics/gradlew b/libs/analytics/gradlew
new file mode 100755
index 000000000..91a7e269e
--- /dev/null
+++ b/libs/analytics/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/libs/analytics/gradlew.bat b/libs/analytics/gradlew.bat
new file mode 100644
index 000000000..8a0b282aa
--- /dev/null
+++ b/libs/analytics/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/libs/analytics/settings.gradle b/libs/analytics/settings.gradle
new file mode 100644
index 000000000..6ad7b7de9
--- /dev/null
+++ b/libs/analytics/settings.gradle
@@ -0,0 +1 @@
+include ':WordPressAnalytics'