Skip to content

Commit

Permalink
Feature-based analytics tracking, replace log with timber (#427)
Browse files Browse the repository at this point in the history
* Replace log with timber

* Replace log with timber

* Replace log with timber

* Replace log with timber

* Fix linting

* Add indent

* Add matomo dependency

* Introduce feature based tracking

* Inject analytics tracker

* Provide analytics instance with strings

* Remove unused imports

* Restructure folders

* Track basic events

* Track basic events: Resources, Settings screens

* fix ktlint

* fix ktlint

---------

Co-authored-by: mdrlzy <mordeniusss@gmail.com>
  • Loading branch information
hieuwu and mdrlzy authored Mar 14, 2024
1 parent 795f5ea commit f260b31
Show file tree
Hide file tree
Showing 29 changed files with 434 additions and 105 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ dependencies {
androidTestImplementation "androidx.test:rules:$test_rule_version"
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_core_version"
implementation "com.github.wseemann:FFmpegMediaMetadataRetriever:$ffmeg_media_retriever_version"
implementation "com.github.matomo-org:matomo-sdk-android:$matomo_analytics_version"

implementation "org.apache.tika:tika-core:$tika_core"
implementation "com.airbnb.android:lottie:$lottie_version"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dev.arkbuilders.navigator.analytics

import android.content.Context
import dagger.Module
import dagger.Provides
import dev.arkbuilders.navigator.analytics.folders.FoldersAnalytics
import dev.arkbuilders.navigator.analytics.folders.FoldersAnalyticsImpl
import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics
import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalyticsImpl
import dev.arkbuilders.navigator.analytics.resources.ResourcesAnalytics
import dev.arkbuilders.navigator.analytics.resources.ResourcesAnalyticsImpl
import dev.arkbuilders.navigator.analytics.settings.SettingsAnalytics
import dev.arkbuilders.navigator.analytics.settings.SettingsAnalyticsImpl
import org.matomo.sdk.Tracker
import javax.inject.Singleton

@Module
class AnalyticsModule {

@Singleton
@Provides
fun provideFolderAnalytics(
matomoTracker: Tracker,
context: Context
): FoldersAnalytics =
FoldersAnalyticsImpl(matomoTracker = matomoTracker, context = context)

@Singleton
@Provides
fun provideResourcesAnalytics(
matomoTracker: Tracker
): ResourcesAnalytics = ResourcesAnalyticsImpl(matomoTracker)

@Singleton
@Provides
fun provideGalleryAnalytics(
matomoTracker: Tracker,
): GalleryAnalytics = GalleryAnalyticsImpl(matomoTracker)

@Singleton
@Provides
fun provideSettingsAnalytics(
matomoTracker: Tracker
): SettingsAnalytics = SettingsAnalyticsImpl(matomoTracker)
}
14 changes: 14 additions & 0 deletions app/src/main/java/dev/arkbuilders/navigator/analytics/Utils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package dev.arkbuilders.navigator.analytics

import org.matomo.sdk.Tracker
import org.matomo.sdk.extra.TrackHelper

fun Tracker.trackScreen(build: TrackHelper.() -> TrackHelper.Screen) {
val matomoTracker = this
build(TrackHelper.track()).with(matomoTracker)
}

fun Tracker.trackEvent(build: TrackHelper.() -> TrackHelper.EventBuilder) {
val matomoTracker = this
build(TrackHelper.track()).with(matomoTracker)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package dev.arkbuilders.navigator.analytics.folders

interface FoldersAnalytics {
fun trackScreen()
fun trackRootOpen()
fun trackFavOpen()
fun trackRootAdded()
fun trackFavAdded()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.arkbuilders.navigator.analytics.folders

import android.content.Context
import dev.arkbuilders.navigator.analytics.trackEvent
import dev.arkbuilders.navigator.analytics.trackScreen
import org.matomo.sdk.Tracker
import javax.inject.Inject

class FoldersAnalyticsImpl @Inject constructor(
private val matomoTracker: Tracker,
private val context: Context
) : FoldersAnalytics {

override fun trackScreen() = matomoTracker
.trackScreen { screen(SCREEN_NAME) }

override fun trackRootOpen() = matomoTracker.trackScreenEvent("Root opened")

override fun trackFavOpen() = matomoTracker.trackScreenEvent("Fav opened")

override fun trackRootAdded() = matomoTracker.trackScreenEvent("Root added")

override fun trackFavAdded() = matomoTracker.trackScreenEvent("Fav added")

private fun Tracker.trackScreenEvent(action: String) = this.trackEvent {
event(SCREEN_NAME, action)
}

companion object {
private const val SCREEN_NAME = "Folders screen"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package dev.arkbuilders.navigator.analytics.gallery

interface GalleryAnalytics {
fun trackScreen()
fun trackResOpen()
fun trackResShare()
fun trackResInfo()
fun trackResEdit()
fun trackResRemove()
fun trackTagSelect()
fun trackTagRemove()
fun trackTagsEdit()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package dev.arkbuilders.navigator.analytics.gallery

import dev.arkbuilders.navigator.analytics.trackEvent
import dev.arkbuilders.navigator.analytics.trackScreen
import org.matomo.sdk.Tracker

class GalleryAnalyticsImpl(
private val matomoTracker: Tracker
) : GalleryAnalytics {
override fun trackScreen() = matomoTracker.trackScreen {
screen(SCREEN_NAME)
}

override fun trackResOpen() = matomoTracker.trackScreenEvent("Resource open")

override fun trackResShare() = matomoTracker.trackScreenEvent("Resource share")

override fun trackResInfo() = matomoTracker.trackScreenEvent("Resource info")

override fun trackResEdit() = matomoTracker.trackScreenEvent("Resource edit")

override fun trackResRemove() = matomoTracker.trackScreenEvent("Resource remove")

override fun trackTagSelect() = matomoTracker.trackScreenEvent("Tag select")

override fun trackTagRemove() = matomoTracker.trackScreenEvent("Tag remove")

override fun trackTagsEdit() = matomoTracker.trackScreenEvent("Tags edit")

private fun Tracker.trackScreenEvent(action: String) = this.trackEvent {
event(SCREEN_NAME, action)
}

companion object {
private const val SCREEN_NAME = "Gallery screen"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package dev.arkbuilders.navigator.analytics.resources

import dev.arkbuilders.arklib.data.storage.StorageException
import dev.arkbuilders.components.tagselector.QueryMode
import dev.arkbuilders.components.tagselector.TagsSorting
import dev.arkbuilders.navigator.data.utils.Sorting

interface ResourcesAnalytics {
fun trackScreen()
fun trackResClick()
fun trackMoveSelectedRes()
fun trackCopySelectedRes()
fun trackRemoveSelectedRes()
fun trackShareSelectedRes()
fun trackResShuffle()
fun trackTagSortCriteria(tagsSorting: TagsSorting)
fun trackResSortCriteria(sorting: Sorting)
fun trackQueryModeChanged(queryMode: QueryMode)
fun trackStorageProvideException(exception: StorageException)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package dev.arkbuilders.navigator.analytics.resources

import dev.arkbuilders.arklib.data.storage.StorageException
import dev.arkbuilders.components.tagselector.QueryMode
import dev.arkbuilders.components.tagselector.TagsSorting
import dev.arkbuilders.navigator.analytics.trackEvent
import dev.arkbuilders.navigator.analytics.trackScreen
import dev.arkbuilders.navigator.data.utils.Sorting
import org.matomo.sdk.Tracker
import org.matomo.sdk.extra.TrackHelper

class ResourcesAnalyticsImpl(
private val matomoTracker: Tracker
) : ResourcesAnalytics {
override fun trackScreen() = matomoTracker.trackScreen { screen(SCREEN_NAME) }

override fun trackResClick() =
matomoTracker.trackScreenEvent("Resource Click")

override fun trackMoveSelectedRes() =
matomoTracker.trackScreenEvent("Move selected resources")

override fun trackCopySelectedRes() =
matomoTracker.trackScreenEvent("Copy selected resources")

override fun trackRemoveSelectedRes() =
matomoTracker.trackScreenEvent("Remove selected resources")

override fun trackShareSelectedRes() =
matomoTracker.trackScreenEvent("Share selected resources")

override fun trackResShuffle() =
matomoTracker.trackScreenEvent("Shuffle resources")

override fun trackTagSortCriteria(tagsSorting: TagsSorting) =
matomoTracker.trackScreenEvent("Tag sorting criteria: ${tagsSorting.name}")

override fun trackResSortCriteria(sorting: Sorting) =
matomoTracker.trackScreenEvent("Resources sorting criteria: ${sorting.name}")

override fun trackQueryModeChanged(queryMode: QueryMode) =
matomoTracker.trackScreenEvent("Query mode: ${queryMode.name}")

override fun trackStorageProvideException(exception: StorageException) =
TrackHelper
.track()
.exception(exception)
.description("Storage provide")
.fatal(false)
.with(matomoTracker)

private fun Tracker.trackScreenEvent(action: String) = this.trackEvent {
event(SCREEN_NAME, action)
}

companion object {
private const val SCREEN_NAME = "Resources screen"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.arkbuilders.navigator.analytics.settings

interface SettingsAnalytics {
fun trackScreen()
fun trackBooleanPref(name: String, enabled: Boolean)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package dev.arkbuilders.navigator.analytics.settings

import dev.arkbuilders.navigator.analytics.trackEvent
import dev.arkbuilders.navigator.analytics.trackScreen
import org.matomo.sdk.Tracker

class SettingsAnalyticsImpl(
private val matomoTracker: Tracker
) : SettingsAnalytics {
override fun trackScreen() = matomoTracker.trackScreen { screen(SCREEN_NAME) }

override fun trackBooleanPref(name: String, enabled: Boolean) {
val enabledStr = if (enabled) "enabled" else "disabled"
matomoTracker
.trackEvent { event(SCREEN_NAME, "$name is $enabledStr") }
}

companion object {
private const val SCREEN_NAME = "Settings screen"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import dev.arkbuilders.navigator.presentation.screen.resources.adapter.FileItemV
import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourcesGridPresenter
import dev.arkbuilders.navigator.presentation.screen.settings.SettingsFragment
import dev.arkbuilders.arkfilepicker.folders.FoldersRepo
import dev.arkbuilders.navigator.analytics.AnalyticsModule
import dev.arkbuilders.navigator.di.modules.DispatcherModule
import javax.inject.Singleton

Expand All @@ -36,6 +37,7 @@ import javax.inject.Singleton
CiceroneModule::class,
RepoModule::class,
DispatcherModule::class,
AnalyticsModule::class,
]
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import dev.arkbuilders.navigator.data.utils.DevicePathsExtractor
import dev.arkbuilders.navigator.data.utils.DevicePathsExtractorImpl
import dev.arkbuilders.navigator.presentation.App
import dev.arkbuilders.navigator.presentation.utils.StringProvider
import org.matomo.sdk.Matomo
import org.matomo.sdk.Tracker
import org.matomo.sdk.TrackerBuilder
import javax.inject.Singleton

@Module
Expand All @@ -29,4 +32,12 @@ class AppModule {
@Singleton
fun provideDevicePathsExtractor(application: App): DevicePathsExtractor =
DevicePathsExtractorImpl(application)

@Provides
@Singleton
fun provideMatomoAnalytics(ctx: Context): Tracker =
TrackerBuilder.createDefault(
"https://ark-builders.matomo.cloud/matomo.php",
2
).build(Matomo.getInstance(ctx))
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package dev.arkbuilders.navigator.di.modules

import android.util.Log
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.CoroutineScope
Expand All @@ -16,6 +15,7 @@ import dev.arkbuilders.arklib.user.tags.TagsStorageRepo
import dev.arkbuilders.navigator.data.preferences.Preferences
import dev.arkbuilders.navigator.data.stats.StatsStorageRepo
import dev.arkbuilders.navigator.data.utils.LogTags.MAIN
import timber.log.Timber
import javax.inject.Named
import javax.inject.Singleton

Expand All @@ -37,7 +37,7 @@ class RepoModule {
fun resourceIndexRepo(
foldersRepo: FoldersRepo
): ResourceIndexRepo {
Log.d(MAIN, "creating ResourceIndexRepo")
Timber.d(MAIN, "creating ResourceIndexRepo")
return ResourceIndexRepo(foldersRepo)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package dev.arkbuilders.navigator.presentation

import android.app.Application
import android.os.StrictMode
import dev.arkbuilders.arkfilepicker.folders.FoldersRepo
import dev.arkbuilders.arklib.initArkLib
import dev.arkbuilders.arklib.initRustLogger
import dev.arkbuilders.navigator.BuildConfig
import dev.arkbuilders.navigator.R
import dev.arkbuilders.navigator.data.preferences.PreferenceKey
import dev.arkbuilders.navigator.di.AppComponent
import dev.arkbuilders.navigator.di.DaggerAppComponent
import dev.arkbuilders.navigator.data.preferences.PreferenceKey
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand All @@ -15,9 +18,6 @@ import org.acra.config.httpSender
import org.acra.data.StringFormat
import org.acra.ktx.initAcra
import org.acra.sender.HttpSender
import dev.arkbuilders.arkfilepicker.folders.FoldersRepo
import dev.arkbuilders.arklib.initArkLib
import dev.arkbuilders.arklib.initRustLogger
import timber.log.Timber

class App : Application() {
Expand All @@ -37,7 +37,6 @@ class App : Application() {

override fun onCreate() {
super.onCreate()

System.loadLibrary("arklib")
FoldersRepo.init(this)
initArkLib()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package dev.arkbuilders.navigator.presentation.dialog.rootsscan

import android.util.Log
import dev.arkbuilders.navigator.data.utils.DevicePathsExtractor
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ensureActive
Expand All @@ -10,6 +9,7 @@ import moxy.MvpPresenter
import moxy.presenterScope
import dev.arkbuilders.arklib.arkFolder
import dev.arkbuilders.navigator.data.utils.LogTags
import timber.log.Timber
import java.nio.file.Path
import java.util.LinkedList
import java.util.Queue
Expand Down Expand Up @@ -61,7 +61,7 @@ class RootsScanDialogPresenter : MvpPresenter<RootsScanView>() {
} else
queue.addAll(folder.listDirectoryEntries().filter(Path::isDirectory))
} catch (e: Exception) {
Log.w(LogTags.FILES, "Can't scan $folder due to $e")
Timber.w(LogTags.FILES, "Can't scan $folder due to $e")
withContext(Dispatchers.Main) {
viewState.toastFolderSkip(folder)
}
Expand Down
Loading

0 comments on commit f260b31

Please sign in to comment.