diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/analytics/AnalyticsEvent.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/analytics/AnalyticsEvent.kt index 6c04a5628c07..97b4e873fa49 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/analytics/AnalyticsEvent.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/analytics/AnalyticsEvent.kt @@ -8,6 +8,8 @@ sealed class AnalyticsEvent(val category: String, val action: String, val name: object ProductSearchStart : AnalyticsEvent("search", "started", null, null) + data class BarcodeDecoder(val success: Boolean = false, val duration: Float = 0f) : AnalyticsEvent("scanner", "scanning", success.toString(), duration) + data class ScannedBarcode(val barcode: String) : AnalyticsEvent("scanner", "scanned", barcode, null) data class ScannedBarcodeResultExpanded(val barcode: String?) : diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/analytics/AnalyticsTrackingEvent.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/analytics/AnalyticsTrackingEvent.kt new file mode 100644 index 000000000000..97357c671e26 --- /dev/null +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/analytics/AnalyticsTrackingEvent.kt @@ -0,0 +1,19 @@ +package openfoodfacts.github.scrachx.openfood.analytics + +import android.app.Activity +import java.util.concurrent.TimeUnit +import kotlin.time.Duration.Companion.milliseconds + +fun Activity.startTrackEvent(event: AnalyticsEvent): AnalyticsTrackingEvent { + return AnalyticsTrackingEvent(event = event) +} + +data class AnalyticsTrackingEvent( + val startDate: Long = System.currentTimeMillis(), + val event: AnalyticsEvent +) { + + fun computeDurationInSeconds(): Float = + (System.currentTimeMillis() - startDate).milliseconds.inWholeSeconds.toFloat() + +} \ No newline at end of file diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/scan/ContinuousScanActivity.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/scan/ContinuousScanActivity.kt index 17fd3f08ac03..48395e17bae8 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/scan/ContinuousScanActivity.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/scan/ContinuousScanActivity.kt @@ -55,9 +55,7 @@ import kotlinx.coroutines.withContext import openfoodfacts.github.scrachx.openfood.AppFlavor import openfoodfacts.github.scrachx.openfood.AppFlavor.Companion.isFlavors import openfoodfacts.github.scrachx.openfood.R -import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent -import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsView -import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.analytics.* import openfoodfacts.github.scrachx.openfood.databinding.ActivityContinuousScanBinding import openfoodfacts.github.scrachx.openfood.features.images.manage.ImagesManageActivity import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity @@ -69,6 +67,7 @@ import openfoodfacts.github.scrachx.openfood.features.product.view.summary.Abstr import openfoodfacts.github.scrachx.openfood.features.product.view.summary.IngredientAnalysisTagsAdapter import openfoodfacts.github.scrachx.openfood.features.product.view.summary.SummaryProductPresenter import openfoodfacts.github.scrachx.openfood.features.shared.BaseActivity +import openfoodfacts.github.scrachx.openfood.features.simplescan.SimpleScanViewModel import openfoodfacts.github.scrachx.openfood.listeners.CommonBottomListenerInstaller.installBottomNavigation import openfoodfacts.github.scrachx.openfood.listeners.CommonBottomListenerInstaller.selectNavigationItem import openfoodfacts.github.scrachx.openfood.models.Barcode @@ -126,6 +125,7 @@ class ContinuousScanActivity : BaseActivity(), IProductView { @Inject lateinit var matomoAnalytics: MatomoAnalytics + private var trackingEvent: AnalyticsTrackingEvent? = null @Inject lateinit var sharedPreferences: SharedPreferences @@ -557,6 +557,7 @@ class ContinuousScanActivity : BaseActivity(), IProductView { cameraView.onResume() } matomoAnalytics.trackView(AnalyticsView.Scanner) + trackingEvent = startTrackEvent(AnalyticsEvent.BarcodeDecoder()) } override fun onPostResume() { @@ -573,6 +574,15 @@ class ContinuousScanActivity : BaseActivity(), IProductView { override fun onPause() { cameraView.stopCameraPreview() super.onPause() + + trackingEvent?.let { + matomoAnalytics.trackEvent( + AnalyticsEvent.BarcodeDecoder( + success = isBarcodeValid(lastBarcode), + duration = it.computeDurationInSeconds(), + ) + ) + } } override fun onStop() { diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/simplescan/SimpleScanActivity.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/simplescan/SimpleScanActivity.kt index 7c15659474e0..d0c1194b22ec 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/simplescan/SimpleScanActivity.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/simplescan/SimpleScanActivity.kt @@ -20,6 +20,10 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import logcat.logcat import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsTrackingEvent +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.analytics.startTrackEvent import openfoodfacts.github.scrachx.openfood.databinding.ActivitySimpleScanBinding import openfoodfacts.github.scrachx.openfood.features.scan.CameraView import openfoodfacts.github.scrachx.openfood.features.simplescan.SimpleScanActivityContract.Companion.KEY_SCANNED_BARCODE @@ -27,6 +31,7 @@ import openfoodfacts.github.scrachx.openfood.features.simplescan.SimpleScanViewM import openfoodfacts.github.scrachx.openfood.features.simplescan.SimpleScanViewModel.SideEffect.ScanTrouble import openfoodfacts.github.scrachx.openfood.models.CameraState import java.util.concurrent.atomic.AtomicBoolean +import javax.inject.Inject @AndroidEntryPoint class SimpleScanActivity : AppCompatActivity() { @@ -37,6 +42,10 @@ class SimpleScanActivity : AppCompatActivity() { private lateinit var cameraView: CameraView<*> private val scannerInitialized = AtomicBoolean(false) + @Inject + lateinit var matomoAnalytics: MatomoAnalytics + private var trackingEvent: AnalyticsTrackingEvent? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivitySimpleScanBinding.inflate(layoutInflater) @@ -79,11 +88,21 @@ class SimpleScanActivity : AppCompatActivity() { override fun onResume() { super.onResume() startScanning() + trackingEvent = startTrackEvent(AnalyticsEvent.BarcodeDecoder()) } override fun onPause() { super.onPause() stopScanning() + + trackingEvent?.let { + matomoAnalytics.trackEvent( + AnalyticsEvent.BarcodeDecoder( + success = viewModel.sideEffectsFlow.replayCache.lastOrNull() is SimpleScanViewModel.SideEffect.BarcodeDetected, + duration = it.computeDurationInSeconds(), + ) + ) + } } override fun onWindowFocusChanged(hasFocus: Boolean) { diff --git a/app/src/test/java/openfoodfacts/github/scrachx/openfood/features/simplescan/SimpleScanViewModelTest.kt b/app/src/test/java/openfoodfacts/github/scrachx/openfood/features/simplescan/SimpleScanViewModelTest.kt index 988a3a1b738b..79ae86016246 100644 --- a/app/src/test/java/openfoodfacts/github/scrachx/openfood/features/simplescan/SimpleScanViewModelTest.kt +++ b/app/src/test/java/openfoodfacts/github/scrachx/openfood/features/simplescan/SimpleScanViewModelTest.kt @@ -36,7 +36,6 @@ class SimpleScanViewModelTest { whenever(prefsRepository.mlScannerEnabled).doReturn(false) whenever(prefsRepository.cameraPref).doReturn(CameraState.Back) - viewModel = SimpleScanViewModel(prefsRepository, dispatchers) }