From 274b1a149c941b14bb6b96ece8084ae8eb900614 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 30 Jun 2022 11:42:57 +0100 Subject: [PATCH] moving analytics config to the config module, it's now up to forks to opt out rather than relying on the package name to not be vector --- .../main/java/im/vector/app/config/Config.kt | 57 +++++++++++++++++++ .../im/vector/app/config/AnalyticsConfig.kt | 27 --------- .../im/vector/app/core/di/SingletonModule.kt | 19 ++++++- .../app/features/analytics/AnalyticsConfig.kt | 14 ++--- .../features/analytics/impl/PostHogFactory.kt | 4 +- .../ui/consent/AnalyticsOptInFragment.kt | 8 +-- .../features/home/HomeActivityViewModel.kt | 5 +- .../VectorSettingsSecurityPrivacyFragment.kt | 5 +- .../im/vector/app/config/AnalyticsConfig.kt | 32 ----------- .../test/fixtures/AnalyticsConfigFixture.kt | 7 +-- 10 files changed, 94 insertions(+), 84 deletions(-) delete mode 100644 vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt delete mode 100644 vector/src/release/java/im/vector/app/config/AnalyticsConfig.kt diff --git a/vector-config/src/main/java/im/vector/app/config/Config.kt b/vector-config/src/main/java/im/vector/app/config/Config.kt index 7577e6dba5..f96df302e9 100644 --- a/vector-config/src/main/java/im/vector/app/config/Config.kt +++ b/vector-config/src/main/java/im/vector/app/config/Config.kt @@ -36,4 +36,61 @@ object Config { * - Changing the value from `true` to `false` will force the app to return to the background sync / Firebase Push. */ const val ALLOW_EXTERNAL_UNIFIED_PUSH_DISTRIBUTORS = true + + /** + * The analytics configuration to use for the Debug build type. + * Can be disabled by providing Analytics.Disabled + */ + val DEBUG_ANALYTICS_CONFIG = Analytics.PostHog( + postHogHost = "https://posthog.element.dev", + postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN", + policyLink = "https://element.io/cookie-policy", + ) + + /** + * The analytics configuration to use for the Release build type. + * Can be disabled by providing Analytics.Disabled + */ + val RELEASE_ANALYTICS_CONFIG = Analytics.PostHog( + postHogHost = "https://posthog.hss.element.io", + postHogApiKey = "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO", + policyLink = "https://element.io/cookie-policy", + ) + + /** + * The analytics configuration to use for the Nightly build type. + * Can be disabled by providing Analytics.Disabled + */ + val NIGHTLY_ANALYTICS_CONFIG = RELEASE_ANALYTICS_CONFIG +} + +/** + * The types of analytics Element currently supports + */ +sealed interface Analytics { + + /** + * Disables the analytics integrations. + */ + object Disabled : Analytics + + /** + * Analytics integration via PostHog. + */ + data class PostHog( + /** + * The PostHog instance url. + */ + val postHogHost: String, + + /** + * The PostHog instance API key. + */ + val postHogApiKey: String, + + /** + * A URL to more information about the analytics collection. + */ + val policyLink: String, + ) : Analytics } diff --git a/vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt b/vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt deleted file mode 100644 index 63f14f72f6..0000000000 --- a/vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2021 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.app.config - -import im.vector.app.BuildConfig -import im.vector.app.features.analytics.AnalyticsConfig - -val analyticsConfig: AnalyticsConfig = object : AnalyticsConfig { - override val isEnabled = BuildConfig.APPLICATION_ID == "im.vector.app.debug" - override val postHogHost = "https://posthog.element.dev" - override val postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN" - override val policyLink = "https://element.io/cookie-policy" -} diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt index c969df74e4..ea3bf98f26 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -31,9 +31,10 @@ import dagger.hilt.components.SingletonComponent import im.vector.app.BuildConfig import im.vector.app.EmojiCompatWrapper import im.vector.app.EmojiSpanify +import im.vector.app.config.Analytics +import im.vector.app.config.Config import im.vector.app.SpaceStateHandler import im.vector.app.SpaceStateHandlerImpl -import im.vector.app.config.analyticsConfig import im.vector.app.core.dispatchers.CoroutineDispatchers import im.vector.app.core.error.DefaultErrorFormatter import im.vector.app.core.error.ErrorFormatter @@ -207,7 +208,21 @@ object VectorStaticModule { @Provides fun providesAnalyticsConfig(): AnalyticsConfig { - return analyticsConfig + val config: Analytics = when (BuildConfig.BUILD_TYPE) { + "debug" -> Config.DEBUG_ANALYTICS_CONFIG + "nightly" -> Config.NIGHTLY_ANALYTICS_CONFIG + "release" -> Config.RELEASE_ANALYTICS_CONFIG + else -> throw IllegalStateException("Unhandled build type: ${BuildConfig.BUILD_TYPE}") + } + return when (config) { + Analytics.Disabled -> AnalyticsConfig(isEnabled = false, "", "", "") + is Analytics.PostHog -> AnalyticsConfig( + isEnabled = true, + postHogHost = config.postHogHost, + postHogApiKey = config.postHogApiKey, + policyLink = config.policyLink + ) + } } @Provides diff --git a/vector/src/main/java/im/vector/app/features/analytics/AnalyticsConfig.kt b/vector/src/main/java/im/vector/app/features/analytics/AnalyticsConfig.kt index 46119f5563..bffba6fa9c 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/AnalyticsConfig.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/AnalyticsConfig.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright (c) 2022 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ package im.vector.app.features.analytics -interface AnalyticsConfig { - val isEnabled: Boolean - val postHogHost: String - val postHogApiKey: String - val policyLink: String -} +data class AnalyticsConfig( + val isEnabled: Boolean, + val postHogHost: String, + val postHogApiKey: String, + val policyLink: String, +) diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt index 029732f76c..b86c2cf75a 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt @@ -19,10 +19,10 @@ package im.vector.app.features.analytics.impl import android.content.Context import com.posthog.android.PostHog import im.vector.app.BuildConfig -import im.vector.app.config.analyticsConfig +import im.vector.app.features.analytics.AnalyticsConfig import javax.inject.Inject -class PostHogFactory @Inject constructor(private val context: Context) { +class PostHogFactory @Inject constructor(private val context: Context, private val analyticsConfig: AnalyticsConfig) { fun createPosthog(): PostHog { return PostHog.Builder(context, analyticsConfig.postHogApiKey, analyticsConfig.postHogHost) diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt index 320386aebd..a5bafa2ee6 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt @@ -22,17 +22,17 @@ import android.view.View import android.view.ViewGroup import com.airbnb.mvrx.activityViewModel import im.vector.app.R -import im.vector.app.config.analyticsConfig import im.vector.app.core.extensions.setTextWithColoredPart import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.openUrlInChromeCustomTab import im.vector.app.databinding.FragmentAnalyticsOptinBinding +import im.vector.app.features.analytics.AnalyticsConfig import javax.inject.Inject -class AnalyticsOptInFragment @Inject constructor() : - VectorBaseFragment(), - OnBackPressed { +class AnalyticsOptInFragment @Inject constructor( + private val analyticsConfig: AnalyticsConfig, +) : VectorBaseFragment(), OnBackPressed { // Share the view model with the Activity so that the Activity // can decide what to do when the data has been saved diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index eb24a1ba86..cfe76706a5 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -22,11 +22,11 @@ import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import im.vector.app.config.analyticsConfig import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel +import im.vector.app.features.analytics.AnalyticsConfig import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.extensions.toAnalyticsType import im.vector.app.features.analytics.plan.Signup @@ -80,7 +80,8 @@ class HomeActivityViewModel @AssistedInject constructor( private val analyticsStore: AnalyticsStore, private val lightweightSettingsStorage: LightweightSettingsStorage, private val vectorPreferences: VectorPreferences, - private val analyticsTracker: AnalyticsTracker + private val analyticsTracker: AnalyticsTracker, + private val analyticsConfig: AnalyticsConfig, ) : VectorViewModel(initialState) { @AssistedFactory diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index f25ad0661a..ac8a47b81e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -35,7 +35,6 @@ import androidx.recyclerview.widget.RecyclerView import com.airbnb.mvrx.fragmentViewModel import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R -import im.vector.app.config.analyticsConfig import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.dialogs.ExportKeysDialog import im.vector.app.core.extensions.queryExportKeys @@ -51,6 +50,7 @@ import im.vector.app.core.utils.copyToClipboard import im.vector.app.core.utils.openFileSelection import im.vector.app.core.utils.toast import im.vector.app.databinding.DialogImportE2eKeysBinding +import im.vector.app.features.analytics.AnalyticsConfig import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewActions import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewModel @@ -84,7 +84,8 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( private val keysExporter: KeysExporter, private val keysImporter: KeysImporter, private val rawService: RawService, - private val navigator: Navigator + private val navigator: Navigator, + private val analyticsConfig: AnalyticsConfig, ) : VectorSettingsBaseFragment() { override var titleRes = R.string.settings_security_and_privacy diff --git a/vector/src/release/java/im/vector/app/config/AnalyticsConfig.kt b/vector/src/release/java/im/vector/app/config/AnalyticsConfig.kt deleted file mode 100644 index e1427338b2..0000000000 --- a/vector/src/release/java/im/vector/app/config/AnalyticsConfig.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.app.config - -import im.vector.app.BuildConfig -import im.vector.app.features.analytics.AnalyticsConfig - -private val allowedPackageList = listOf( - "im.vector.app", - "im.vector.app.nightly", -) - -val analyticsConfig: AnalyticsConfig = object : AnalyticsConfig { - override val isEnabled = BuildConfig.APPLICATION_ID in allowedPackageList - override val postHogHost = "https://posthog.hss.element.io" - override val postHogApiKey = "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO" - override val policyLink = "https://element.io/cookie-policy" -} diff --git a/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt index 5fbcdd98d1..ea1769ecb2 100644 --- a/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt +++ b/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt @@ -24,10 +24,5 @@ object AnalyticsConfigFixture { postHogHost: String = "http://posthog.url", postHogApiKey: String = "api-key", policyLink: String = "http://policy.link" - ) = object : AnalyticsConfig { - override val isEnabled: Boolean = isEnabled - override val postHogHost = postHogHost - override val postHogApiKey = postHogApiKey - override val policyLink = policyLink - } + ) = AnalyticsConfig(isEnabled, postHogHost, postHogApiKey, policyLink) }