From 33bf34fe30533f0df7b3556e20b8adf8b2f8f44b Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Wed, 25 Apr 2018 11:00:38 -0500 Subject: [PATCH] Convert to Firebase Analytics and Crashlytics --- app/build.gradle | 8 +- app/google-services.json | 42 +++++++++ app/src/debug/res/xml/google_analytics.xml | 4 - app/src/googleplay/AndroidManifest.xml | 4 + .../java/org/tasks/analytics/Tracker.java | 90 +++++++------------ .../ErrorReportingSingleThreadExecutor.java | 40 --------- app/src/main/java/org/tasks/Tasks.java | 4 - .../tasks/injection/ApplicationModule.java | 10 --- .../tasks/preferences/BasicPreferences.java | 7 +- .../org/tasks/preferences/Preferences.java | 3 +- app/src/release/res/xml/google_analytics.xml | 60 ------------- build.gradle | 5 ++ 12 files changed, 92 insertions(+), 185 deletions(-) create mode 100644 app/google-services.json delete mode 100644 app/src/debug/res/xml/google_analytics.xml delete mode 100644 app/src/main/java/org/tasks/ErrorReportingSingleThreadExecutor.java delete mode 100644 app/src/release/res/xml/google_analytics.xml diff --git a/app/build.gradle b/app/build.gradle index 58d348757..a39d52cda 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,6 @@ apply plugin: 'com.android.application' apply plugin: 'checkstyle' +apply plugin: 'io.fabric' repositories { jcenter() @@ -108,7 +109,7 @@ configurations { final DAGGER_VERSION = '2.9' final BUTTERKNIFE_VERSION = '8.8.1' -final GPS_VERSION = '12.0.1' +final GPS_VERSION = '15.0.0' final SUPPORT_VERSION = '27.1.1' final ROOM_VERSION = '1.1.0-beta3' final STETHO_VERSION = '1.5.0' @@ -169,8 +170,9 @@ dependencies { implementation 'com.google.api-client:google-api-client-android:1.22.0' implementation 'com.android.billingclient:billing:1.0' + googleplayImplementation 'com.crashlytics.sdk.android:crashlytics:2.9.1' + googleplayImplementation "com.google.firebase:firebase-core:${GPS_VERSION}" googleplayImplementation "com.google.android.gms:play-services-location:${GPS_VERSION}" - googleplayImplementation "com.google.android.gms:play-services-analytics:${GPS_VERSION}" googleplayImplementation "com.google.android.gms:play-services-auth:${GPS_VERSION}" googleplayImplementation "com.google.android.gms:play-services-places:${GPS_VERSION}" @@ -184,3 +186,5 @@ dependencies { androidTestImplementation "com.android.support.test:rules:${TESTING_SUPPORT_VERSION}" androidTestImplementation "com.android.support:support-annotations:${SUPPORT_VERSION}" } + +apply plugin: 'com.google.gms.google-services' diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 000000000..944b59e67 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "363426363175", + "firebase_url": "https://tasks-98543.firebaseio.com", + "project_id": "tasks-98543", + "storage_bucket": "tasks-98543.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:363426363175:android:9bc4739db40ecb39", + "android_client_info": { + "package_name": "org.tasks" + } + }, + "oauth_client": [ + { + "client_id": "363426363175-n0862rti6ect01fr3t4m229hqvvu1s8a.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyACOYpQZEIkpF2EykbufMOZXn9QVrP_5lI" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/src/debug/res/xml/google_analytics.xml b/app/src/debug/res/xml/google_analytics.xml deleted file mode 100644 index 7695f27f8..000000000 --- a/app/src/debug/res/xml/google_analytics.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - UA-71449238-1 - \ No newline at end of file diff --git a/app/src/googleplay/AndroidManifest.xml b/app/src/googleplay/AndroidManifest.xml index d92eea818..481e0ee95 100644 --- a/app/src/googleplay/AndroidManifest.xml +++ b/app/src/googleplay/AndroidManifest.xml @@ -24,6 +24,10 @@ + + diff --git a/app/src/googleplay/java/org/tasks/analytics/Tracker.java b/app/src/googleplay/java/org/tasks/analytics/Tracker.java index 20d306ade..3b80077b0 100644 --- a/app/src/googleplay/java/org/tasks/analytics/Tracker.java +++ b/app/src/googleplay/java/org/tasks/analytics/Tracker.java @@ -3,70 +3,43 @@ package org.tasks.analytics; import static org.tasks.billing.BillingClient.BillingResponseToString; import android.content.Context; +import android.os.Bundle; import com.android.billingclient.api.BillingClient.BillingResponse; -import com.google.android.gms.analytics.ExceptionParser; -import com.google.android.gms.analytics.ExceptionReporter; -import com.google.android.gms.analytics.GoogleAnalytics; -import com.google.android.gms.analytics.HitBuilders; -import com.google.android.gms.analytics.StandardExceptionParser; -import com.google.common.base.Strings; +import com.crashlytics.android.Crashlytics; +import com.google.firebase.analytics.FirebaseAnalytics; +import com.google.firebase.analytics.FirebaseAnalytics.Event; +import com.google.firebase.analytics.FirebaseAnalytics.Param; +import io.fabric.sdk.android.Fabric; import javax.inject.Inject; -import org.tasks.BuildConfig; -import org.tasks.R; import org.tasks.injection.ApplicationScope; import org.tasks.injection.ForApplication; +import org.tasks.preferences.Preferences; import timber.log.Timber; @ApplicationScope public class Tracker { - private final GoogleAnalytics analytics; - private final com.google.android.gms.analytics.Tracker tracker; - private final ExceptionParser exceptionParser; + private final FirebaseAnalytics analytics; private final Context context; + private final boolean enabled; @Inject - public Tracker(@ForApplication Context context) { + public Tracker(@ForApplication Context context, Preferences preferences) { this.context = context; - analytics = GoogleAnalytics.getInstance(context); - tracker = analytics.newTracker(R.xml.google_analytics); - tracker.setAppVersion(Integer.toString(BuildConfig.VERSION_CODE)); - final StandardExceptionParser standardExceptionParser = - new StandardExceptionParser(context, null); - exceptionParser = - (thread, throwable) -> { - StringBuilder stack = - new StringBuilder() - .append(standardExceptionParser.getDescription(thread, throwable)) - .append("\n") - .append(throwable.getClass().getName()) - .append("\n"); - for (StackTraceElement element : throwable.getStackTrace()) { - stack.append(element.toString()).append("\n"); - } - return stack.toString(); - }; - ExceptionReporter reporter = - new ExceptionReporter(tracker, Thread.getDefaultUncaughtExceptionHandler(), context); - reporter.setExceptionParser(exceptionParser); - Thread.setDefaultUncaughtExceptionHandler(reporter); - } - - public void setTrackingEnabled(boolean enabled) { - analytics.setAppOptOut(!enabled); + enabled = preferences.isTrackingEnabled(); + if (enabled) { + analytics = FirebaseAnalytics.getInstance(context); + Fabric.with(context, new Crashlytics()); + } else { + analytics = null; + } } public void reportException(Throwable t) { - reportException(Thread.currentThread(), t); - } - - public void reportException(Thread thread, Throwable t) { Timber.e(t); - tracker.send( - new HitBuilders.ExceptionBuilder() - .setDescription(exceptionParser.getDescription(thread.getName(), t)) - .setFatal(false) - .build()); + if (enabled) { + Crashlytics.logException(t); + } } public void reportEvent(Tracking.Events event) { @@ -85,21 +58,20 @@ public class Tracker { reportEvent(event.category, action, label); } - private void reportEvent(int category, String action, String label) { - HitBuilders.EventBuilder eventBuilder = - new HitBuilders.EventBuilder().setCategory(context.getString(category)).setAction(action); - if (!Strings.isNullOrEmpty(label)) { - eventBuilder.setLabel(label); + private void reportEvent(int categoryRes, String action, String label) { + if (!enabled) { + return; } - tracker.send(eventBuilder.build()); } public void reportIabResult(@BillingResponse int response, String sku) { - tracker.send( - new HitBuilders.EventBuilder() - .setCategory(context.getString(R.string.tracking_category_iab)) - .setAction(sku) - .setLabel(BillingResponseToString(response)) - .build()); + if (!enabled) { + return; + } + + Bundle bundle = new Bundle(); + bundle.putString(Param.ITEM_ID, sku); + bundle.putString(Param.SUCCESS, BillingResponseToString(response)); + analytics.logEvent(Event.ECOMMERCE_PURCHASE, bundle); } } diff --git a/app/src/main/java/org/tasks/ErrorReportingSingleThreadExecutor.java b/app/src/main/java/org/tasks/ErrorReportingSingleThreadExecutor.java deleted file mode 100644 index 0b03d3b67..000000000 --- a/app/src/main/java/org/tasks/ErrorReportingSingleThreadExecutor.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.tasks; - -import static java.util.concurrent.Executors.newSingleThreadExecutor; - -import android.support.annotation.NonNull; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import org.tasks.analytics.Tracker; - -public class ErrorReportingSingleThreadExecutor - implements Executor, Thread.UncaughtExceptionHandler { - - private final ExecutorService executorService; - private final Tracker tracker; - - public ErrorReportingSingleThreadExecutor(String nameFormat, Tracker tracker) { - executorService = - newSingleThreadExecutor( - new ThreadFactoryBuilder() - .setNameFormat(String.format("%s-%%d", nameFormat)) - .setUncaughtExceptionHandler(this) - .build()); - this.tracker = tracker; - } - - @Override - public void execute(@NonNull Runnable runnable) { - try { - executorService.execute(runnable); - } catch (Exception e) { - tracker.reportException(e); - } - } - - @Override - public void uncaughtException(Thread thread, Throwable throwable) { - tracker.reportException(thread, throwable); - } -} diff --git a/app/src/main/java/org/tasks/Tasks.java b/app/src/main/java/org/tasks/Tasks.java index 364e48144..faeede4e0 100644 --- a/app/src/main/java/org/tasks/Tasks.java +++ b/app/src/main/java/org/tasks/Tasks.java @@ -3,7 +3,6 @@ package org.tasks; import com.jakewharton.threetenabp.AndroidThreeTen; import com.todoroo.astrid.service.StartupService; import javax.inject.Inject; -import org.tasks.analytics.Tracker; import org.tasks.injection.ApplicationComponent; import org.tasks.injection.InjectingApplication; import org.tasks.jobs.JobCreator; @@ -16,7 +15,6 @@ public class Tasks extends InjectingApplication { @Inject StartupService startupService; @Inject Preferences preferences; - @Inject Tracker tracker; @Inject FlavorSetup flavorSetup; @Inject BuildSetup buildSetup; @Inject ThemeCache themeCache; @@ -28,8 +26,6 @@ public class Tasks extends InjectingApplication { public void onCreate() { super.onCreate(); - tracker.setTrackingEnabled(preferences.isTrackingEnabled()); - if (!buildSetup.setup()) { return; } diff --git a/app/src/main/java/org/tasks/injection/ApplicationModule.java b/app/src/main/java/org/tasks/injection/ApplicationModule.java index 528753859..9fb72f337 100644 --- a/app/src/main/java/org/tasks/injection/ApplicationModule.java +++ b/app/src/main/java/org/tasks/injection/ApplicationModule.java @@ -10,9 +10,6 @@ import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.provider.Astrid2TaskProvider; import dagger.Module; import dagger.Provides; -import java.util.concurrent.Executor; -import javax.inject.Named; -import org.tasks.ErrorReportingSingleThreadExecutor; import org.tasks.analytics.Tracker; import org.tasks.data.AlarmDao; import org.tasks.data.CaldavDao; @@ -53,13 +50,6 @@ public class ApplicationModule { return context; } - @Provides - @ApplicationScope - @Named("iab-executor") - public Executor getIabExecutor(Tracker tracker) { - return new ErrorReportingSingleThreadExecutor("iab-executor", tracker); - } - @Provides @ApplicationScope public Database getAppDatabase(Tracker tracker) { diff --git a/app/src/main/java/org/tasks/preferences/BasicPreferences.java b/app/src/main/java/org/tasks/preferences/BasicPreferences.java index a9752ef35..e9eb6aecd 100644 --- a/app/src/main/java/org/tasks/preferences/BasicPreferences.java +++ b/app/src/main/java/org/tasks/preferences/BasicPreferences.java @@ -125,11 +125,8 @@ public class BasicPreferences extends InjectingPreferenceActivity findPreference(getString(R.string.p_collect_statistics)) .setOnPreferenceChangeListener( (preference, newValue) -> { - if (newValue != null) { - tracker.setTrackingEnabled((boolean) newValue); - return true; - } - return false; + showRestartDialog(); + return true; }); findPreference(R.string.backup_BAc_import) diff --git a/app/src/main/java/org/tasks/preferences/Preferences.java b/app/src/main/java/org/tasks/preferences/Preferences.java index a4b0dd156..1ee14b0fc 100644 --- a/app/src/main/java/org/tasks/preferences/Preferences.java +++ b/app/src/main/java/org/tasks/preferences/Preferences.java @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; +import org.tasks.BuildConfig; import org.tasks.R; import org.tasks.data.TaskAttachment; import org.tasks.injection.ForApplication; @@ -182,7 +183,7 @@ public class Preferences { } public boolean isTrackingEnabled() { - return getBoolean(R.string.p_collect_statistics, true); + return !BuildConfig.DEBUG && getBoolean(R.string.p_collect_statistics, true); } public String getDefaultCalendar() { diff --git a/app/src/release/res/xml/google_analytics.xml b/app/src/release/res/xml/google_analytics.xml deleted file mode 100644 index 1919d90f4..000000000 --- a/app/src/release/res/xml/google_analytics.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - UA-43015607-3 - - true - TaskEditActivity - AACRecordingActivity - AddAttachmentActivity - ShortcutConfigActivity - ShareLinkActivity - NotificationActivity - MyFilePickerActivity - MissedCallActivity - GtasksLoginActivity - - VoiceCommandActivity - TaskerSettingsActivity - - TaskListActivity - TagSettingsActivity - SnoozeActivity - CustomFilterActivity - CameraActivity - CalendarSelectionActivity - - CalendarReminderActivity - - BeastModePreferences - - FilterSettingsActivity - ColorPickerActivity - DateAndTimePickerActivity - - DatePickerActivity - FilterSelectionActivity - - TimePickerActivity - FileExplore - GtasksPreferences - DashClockSettings - DefaultsPreferences - OldTaskPreferences - ReminderPreferences - - AppearancePreferences - BackupPreferences - BasicPreferences - DateShortcutPreferences - HelpAndFeedbackActivity - - MiscellaneousPreferences - - WidgetConfigActivity - CaldavSettingsActivity - - CaldavAccountSettingsActivity - - PurchaseActivity - \ No newline at end of file diff --git a/build.gradle b/build.gradle index d2df30da1..101d8a6c5 100644 --- a/build.gradle +++ b/build.gradle @@ -6,9 +6,14 @@ buildscript { repositories { jcenter() google() + maven { + url 'https://maven.fabric.io/public' + } } dependencies { classpath 'com.android.tools.build:gradle:3.1.2' + classpath 'com.google.gms:google-services:3.2.0' + classpath 'io.fabric.tools:gradle:1.25.1' } }