diff --git a/app/src/benchmark/kotlin/ru/pixnews/inject/NoOpAnalyticsModule.kt b/app/src/benchmark/kotlin/ru/pixnews/inject/NoOpAnalyticsModule.kt new file mode 100644 index 00000000..b68f03e3 --- /dev/null +++ b/app/src/benchmark/kotlin/ru/pixnews/inject/NoOpAnalyticsModule.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024, the Pixnews project authors and contributors. Please see the AUTHORS file for details. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ + +package ru.pixnews.inject + +import com.squareup.anvil.annotations.ContributesTo +import dagger.Module +import dagger.Provides +import dagger.Reusable +import ru.pixnews.foundation.analytics.Analytics +import ru.pixnews.foundation.analytics.NoOpAnalytics +import ru.pixnews.foundation.di.base.scopes.AppScope + +@ContributesTo(AppScope::class, replaces = [AnalyticsModule::class]) +@Module +object NoOpAnalyticsModule { + @Provides + @Reusable + fun provideAnalytics(): Analytics = NoOpAnalytics +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2c49387c..5208a928 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -58,6 +58,12 @@ + + diff --git a/app/src/main/kotlin/ru/pixnews/MainActivity.kt b/app/src/main/kotlin/ru/pixnews/MainActivity.kt index aa948331..b1852fb4 100644 --- a/app/src/main/kotlin/ru/pixnews/MainActivity.kt +++ b/app/src/main/kotlin/ru/pixnews/MainActivity.kt @@ -10,6 +10,7 @@ import androidx.activity.compose.setContent import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import co.touchlab.kermit.Logger import ru.pixnews.feature.root.PixnewsRootContent +import ru.pixnews.foundation.analytics.Analytics import ru.pixnews.foundation.appconfig.AppConfig import ru.pixnews.foundation.di.ui.base.activity.BaseActivity import ru.pixnews.foundation.di.ui.base.activity.ContributesActivity @@ -32,12 +33,16 @@ class MainActivity : BaseActivity() { @Inject internal lateinit var appLoadingStatus: AppLoadingStatus + @Inject + internal lateinit var analytics: Analytics + override fun onPostInjectPreCreate() { setupSplashScreen() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + analytics.logEvent("main_activity_created") setContent { PixnewsRootContent( appConfig = appConfig, diff --git a/app/src/main/kotlin/ru/pixnews/PixnewsApplication.kt b/app/src/main/kotlin/ru/pixnews/PixnewsApplication.kt index 5ab5f359..3ef2046e 100644 --- a/app/src/main/kotlin/ru/pixnews/PixnewsApplication.kt +++ b/app/src/main/kotlin/ru/pixnews/PixnewsApplication.kt @@ -12,7 +12,8 @@ import ru.pixnews.inject.MainPixnewsAppComponent import javax.inject.Inject class PixnewsApplication : Application(), Configuration.Provider { - override val workManagerConfiguration = localWorkManagerConfiguration + override val workManagerConfiguration + get() = localWorkManagerConfiguration @field:Inject lateinit var localWorkManagerConfiguration: Configuration diff --git a/app/src/main/kotlin/ru/pixnews/inject/AnalyticsModule.kt b/app/src/main/kotlin/ru/pixnews/inject/AnalyticsModule.kt index 94d7b1fe..18e8192b 100644 --- a/app/src/main/kotlin/ru/pixnews/inject/AnalyticsModule.kt +++ b/app/src/main/kotlin/ru/pixnews/inject/AnalyticsModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, the Pixnews project authors and contributors. Please see the AUTHORS file for details. + * Copyright (c) 2024, the Pixnews project authors and contributors. Please see the AUTHORS file for details. * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ @@ -10,13 +10,13 @@ import dagger.Binds import dagger.Module import dagger.Reusable import ru.pixnews.foundation.analytics.Analytics -import ru.pixnews.foundation.analytics.NoOpAnalytics import ru.pixnews.foundation.di.base.scopes.AppScope +import ru.pixnews.inject.analytics.LoggingAnalytics @ContributesTo(AppScope::class) @Module interface AnalyticsModule { @Binds @Reusable - fun provideAnalytics(analytics: NoOpAnalytics): Analytics + fun bindAnalytics(analytics: LoggingAnalytics): Analytics } diff --git a/app/src/main/kotlin/ru/pixnews/inject/analytics/FirebaseAnalytics.kt b/app/src/main/kotlin/ru/pixnews/inject/analytics/FirebaseAnalytics.kt new file mode 100644 index 00000000..19fb3148 --- /dev/null +++ b/app/src/main/kotlin/ru/pixnews/inject/analytics/FirebaseAnalytics.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024, the Pixnews project authors and contributors. Please see the AUTHORS file for details. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ + +package ru.pixnews.inject.analytics + +import androidx.core.os.bundleOf +import com.google.firebase.Firebase +import com.google.firebase.analytics.analytics +import ru.pixnews.foundation.analytics.Analytics + +object FirebaseAnalytics : Analytics { + private val analytics = Firebase.analytics + + override fun setEnableAnalytics(enable: Boolean) { + analytics.setAnalyticsCollectionEnabled(enable) + } + + override fun setUserId(userId: String?) { + analytics.setUserId(userId) + } + + override fun setUserProperty(name: String, value: String) { + analytics.setUserProperty(name, value) + } + + override fun logEvent(name: String, params: Map?) { + val paramsBundle = if (params != null) { + bundleOf(pairs = params.entries.map { it.key to it.value }.toTypedArray()) + } else { + null + } + analytics.logEvent(name, paramsBundle) + } +} diff --git a/app/src/main/kotlin/ru/pixnews/inject/analytics/LoggingAnalytics.kt b/app/src/main/kotlin/ru/pixnews/inject/analytics/LoggingAnalytics.kt new file mode 100644 index 00000000..2f1aca3e --- /dev/null +++ b/app/src/main/kotlin/ru/pixnews/inject/analytics/LoggingAnalytics.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024, the Pixnews project authors and contributors. Please see the AUTHORS file for details. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ + +package ru.pixnews.inject.analytics + +import co.touchlab.kermit.Logger +import ru.pixnews.foundation.analytics.Analytics +import javax.inject.Inject + +class LoggingAnalytics @Inject constructor( + logger: Logger, +) : Analytics { + private val log: Logger = logger.withTag("Analytics") + override fun setEnableAnalytics(enable: Boolean) { + log.i { "setEnableAnalytics($enable)" } + } + + override fun setUserId(userId: String?) { + log.i { "setUserId($userId)" } + } + + override fun setUserProperty(name: String, value: String) { + log.i { "setUserProperty($name, $value)" } + } + + override fun logEvent(name: String, params: Map?) { + log.i { "Event `$name`: $params" } + } +} diff --git a/app/src/release/kotlin/ru/pixnews/app/inject/FirebaseAnalyticsModule.kt b/app/src/release/kotlin/ru/pixnews/app/inject/FirebaseAnalyticsModule.kt new file mode 100644 index 00000000..7bcda615 --- /dev/null +++ b/app/src/release/kotlin/ru/pixnews/app/inject/FirebaseAnalyticsModule.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024, the Pixnews project authors and contributors. Please see the AUTHORS file for details. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ + +package ru.pixnews.app.inject + +import com.squareup.anvil.annotations.ContributesTo +import dagger.Module +import dagger.Provides +import dagger.Reusable +import ru.pixnews.foundation.analytics.Analytics +import ru.pixnews.foundation.di.base.scopes.AppScope +import ru.pixnews.inject.AnalyticsModule +import ru.pixnews.inject.analytics.FirebaseAnalytics + +@ContributesTo(AppScope::class, replaces = [AnalyticsModule::class]) +@Module +public object FirebaseAnalyticsModule { + @Provides + @Reusable + fun bindsAnalytics(): Analytics = FirebaseAnalytics +} diff --git a/foundation/analytics/main/ru/pixnews/foundation/analytics/Analytics.kt b/foundation/analytics/main/ru/pixnews/foundation/analytics/Analytics.kt index 3a327689..8b4d7da2 100644 --- a/foundation/analytics/main/ru/pixnews/foundation/analytics/Analytics.kt +++ b/foundation/analytics/main/ru/pixnews/foundation/analytics/Analytics.kt @@ -6,8 +6,6 @@ package ru.pixnews.foundation.analytics public interface Analytics { - public fun setCurrentScreenName(screenName: String, screenClass: String) - public fun setEnableAnalytics(enable: Boolean) public fun setUserId(userId: String?) diff --git a/foundation/analytics/main/ru/pixnews/foundation/analytics/NoOpAnalytics.kt b/foundation/analytics/main/ru/pixnews/foundation/analytics/NoOpAnalytics.kt index 745edef9..555c797a 100644 --- a/foundation/analytics/main/ru/pixnews/foundation/analytics/NoOpAnalytics.kt +++ b/foundation/analytics/main/ru/pixnews/foundation/analytics/NoOpAnalytics.kt @@ -5,9 +5,7 @@ package ru.pixnews.foundation.analytics -public class NoOpAnalytics : Analytics { - public override fun setCurrentScreenName(screenName: String, screenClass: String): Unit = Unit - +public object NoOpAnalytics : Analytics { public override fun setEnableAnalytics(enable: Boolean): Unit = Unit public override fun setUserId(userId: String?): Unit = Unit diff --git a/gradle/plugin/project/android/convention/ru.pixnews.gradle.android.application.gradle.kts b/gradle/plugin/project/android/convention/ru.pixnews.gradle.android.application.gradle.kts index 088dcee1..af038c16 100644 --- a/gradle/plugin/project/android/convention/ru.pixnews.gradle.android.application.gradle.kts +++ b/gradle/plugin/project/android/convention/ru.pixnews.gradle.android.application.gradle.kts @@ -32,7 +32,11 @@ extensions.configure("android") { defaultConfig { targetSdk = versionCatalog.findVersion("targetSdk").get().displayName.toInt() - manifestPlaceholders["firebase_crashlytics_collection_enabled"] = "false" + manifestPlaceholders += listOf( + "firebase_crashlytics_collection_enabled" to "false", + "firebase_analytics_collection_deactivated" to "true", + "google_analytics_adid_collection_enabled" to "false", + ) } val releaseConfig = ReleaseConfig(project) @@ -45,11 +49,21 @@ extensions.configure("android") { isCrunchPngs = false proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") signingConfig = signingConfigs.getByName(if (releaseConfig.useReleaseKeystore) "release" else "debug") + manifestPlaceholders += listOf( + "firebase_crashlytics_collection_enabled" to "true", + "firebase_analytics_collection_deactivated" to "false", + "google_analytics_adid_collection_enabled" to "true", + ) } getByName("debug") { applicationIdSuffix = ".debug" signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf("instrumentedTests", "release") + manifestPlaceholders += listOf( + "firebase_crashlytics_collection_enabled" to "false", + "firebase_analytics_collection_deactivated" to "false", + "google_analytics_adid_collection_enabled" to "true", + ) } create("benchmark") { initWith(release) @@ -62,6 +76,12 @@ extensions.configure("android") { proguardFiles("proguard-benchmark.pro") matchingFallbacks += "release" + + manifestPlaceholders += listOf( + "firebase_crashlytics_collection_enabled" to "false", + "firebase_analytics_collection_deactivated" to "true", + "google_analytics_adid_collection_enabled" to "false", + ) } } diff --git a/script/enable_firebase_analytics.sh b/script/enable_firebase_analytics.sh new file mode 100755 index 00000000..56a4c346 --- /dev/null +++ b/script/enable_firebase_analytics.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +adb shell setprop log.tag.FA VERBOSE +adb shell setprop log.tag.FA-SVC VERBOSE +adb shell setprop debug.firebase.analytics.app ru.pixnews.debug +# adb logcat -v time -s FA FA-SVC