mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-24 18:36:21 +03:00
Update to analytics events 0.23.0 and refactor
This commit is contained in:
parent
09c68f3421
commit
a363e392b4
6 changed files with 75 additions and 34 deletions
|
@ -53,6 +53,7 @@ import im.vector.app.core.pushers.FcmHelper
|
||||||
import im.vector.app.core.resources.BuildMeta
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.features.analytics.DecryptionFailureTracker
|
import im.vector.app.features.analytics.DecryptionFailureTracker
|
||||||
import im.vector.app.features.analytics.VectorAnalytics
|
import im.vector.app.features.analytics.VectorAnalytics
|
||||||
|
import im.vector.app.features.analytics.plan.SuperProperties
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
import im.vector.app.features.configuration.VectorConfiguration
|
import im.vector.app.features.configuration.VectorConfiguration
|
||||||
import im.vector.app.features.invite.InvitesAcceptor
|
import im.vector.app.features.invite.InvitesAcceptor
|
||||||
|
@ -130,6 +131,12 @@ class VectorApplication :
|
||||||
appContext = this
|
appContext = this
|
||||||
flipperProxy.init(matrix)
|
flipperProxy.init(matrix)
|
||||||
vectorAnalytics.init()
|
vectorAnalytics.init()
|
||||||
|
vectorAnalytics.updateSuperProperties(
|
||||||
|
SuperProperties(
|
||||||
|
appPlatform = SuperProperties.AppPlatform.EA,
|
||||||
|
cryptoSDK = SuperProperties.CryptoSDK.Rust,
|
||||||
|
)
|
||||||
|
)
|
||||||
invitesAcceptor.initialize()
|
invitesAcceptor.initialize()
|
||||||
autoRageShaker.initialize()
|
autoRageShaker.initialize()
|
||||||
decryptionFailureTracker.start()
|
decryptionFailureTracker.start()
|
||||||
|
|
|
@ -160,7 +160,7 @@ dependencies {
|
||||||
api 'com.facebook.stetho:stetho:1.6.0'
|
api 'com.facebook.stetho:stetho:1.6.0'
|
||||||
|
|
||||||
// Analytics
|
// Analytics
|
||||||
api 'com.github.matrix-org:matrix-analytics-events:0.22.0'
|
api 'com.github.matrix-org:matrix-analytics-events:0.23.0'
|
||||||
|
|
||||||
api libs.google.phonenumber
|
api libs.google.phonenumber
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ import im.vector.app.core.dispatchers.CoroutineDispatchers
|
||||||
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
import im.vector.app.core.services.GuardServiceStarter
|
import im.vector.app.core.services.GuardServiceStarter
|
||||||
import im.vector.app.core.session.ConfigureAndStartSessionUseCase
|
import im.vector.app.core.session.ConfigureAndStartSessionUseCase
|
||||||
import im.vector.app.features.analytics.VectorAnalytics
|
|
||||||
import im.vector.app.features.analytics.plan.SuperProperties
|
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
import im.vector.app.features.crypto.keysrequest.KeyRequestHandler
|
import im.vector.app.features.crypto.keysrequest.KeyRequestHandler
|
||||||
import im.vector.app.features.crypto.verification.IncomingVerificationRequestHandler
|
import im.vector.app.features.crypto.verification.IncomingVerificationRequestHandler
|
||||||
|
@ -58,7 +56,6 @@ class ActiveSessionHolder @Inject constructor(
|
||||||
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
|
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
|
||||||
private val applicationCoroutineScope: CoroutineScope,
|
private val applicationCoroutineScope: CoroutineScope,
|
||||||
private val coroutineDispatchers: CoroutineDispatchers,
|
private val coroutineDispatchers: CoroutineDispatchers,
|
||||||
private val vectorAnalytics: VectorAnalytics,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private var activeSessionReference: AtomicReference<Session?> = AtomicReference()
|
private var activeSessionReference: AtomicReference<Session?> = AtomicReference()
|
||||||
|
@ -75,13 +72,6 @@ class ActiveSessionHolder @Inject constructor(
|
||||||
session.callSignalingService().addCallListener(callManager)
|
session.callSignalingService().addCallListener(callManager)
|
||||||
imageManager.onSessionStarted(session)
|
imageManager.onSessionStarted(session)
|
||||||
guardServiceStarter.start()
|
guardServiceStarter.start()
|
||||||
vectorAnalytics.updateSuperProperties(
|
|
||||||
SuperProperties(
|
|
||||||
platformCodeName = SuperProperties.PlatformCodeName.EA,
|
|
||||||
cryptoSDK = SuperProperties.CryptoSDK.Rust,
|
|
||||||
cryptoSDKVersion = session.cryptoService().getCryptoVersion(applicationContext, false)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun clearActiveSession() {
|
suspend fun clearActiveSession() {
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.features.analytics.impl
|
||||||
|
|
||||||
|
import im.vector.app.ActiveSessionDataSource
|
||||||
|
import im.vector.app.features.analytics.plan.SuperProperties
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gathers the super properties that are static to this platform or
|
||||||
|
* that can be automatically resolved from the current session.
|
||||||
|
*/
|
||||||
|
class AutoSuperPropertiesFlowProvider @Inject constructor(
|
||||||
|
activeSessionDataSource: ActiveSessionDataSource,
|
||||||
|
) {
|
||||||
|
|
||||||
|
val superPropertiesFlow: Flow<SuperProperties> = activeSessionDataSource.stream()
|
||||||
|
.map { session ->
|
||||||
|
SuperProperties(
|
||||||
|
appPlatform = SuperProperties.AppPlatform.EA,
|
||||||
|
cryptoSDK = SuperProperties.CryptoSDK.Rust,
|
||||||
|
cryptoSDKVersion = session.getOrNull()?.cryptoService()?.getCryptoVersion(false)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.distinctUntilChanged()
|
||||||
|
}
|
|
@ -42,6 +42,7 @@ class DefaultVectorAnalytics @Inject constructor(
|
||||||
private val analyticsConfig: AnalyticsConfig,
|
private val analyticsConfig: AnalyticsConfig,
|
||||||
private val analyticsStore: AnalyticsStore,
|
private val analyticsStore: AnalyticsStore,
|
||||||
private val lateInitUserPropertiesFactory: LateInitUserPropertiesFactory,
|
private val lateInitUserPropertiesFactory: LateInitUserPropertiesFactory,
|
||||||
|
private val autoSuperPropertiesFlowProvider: AutoSuperPropertiesFlowProvider,
|
||||||
@NamedGlobalScope private val globalScope: CoroutineScope
|
@NamedGlobalScope private val globalScope: CoroutineScope
|
||||||
) : VectorAnalytics {
|
) : VectorAnalytics {
|
||||||
|
|
||||||
|
@ -69,6 +70,7 @@ class DefaultVectorAnalytics @Inject constructor(
|
||||||
override fun init() {
|
override fun init() {
|
||||||
observeUserConsent()
|
observeUserConsent()
|
||||||
observeAnalyticsId()
|
observeAnalyticsId()
|
||||||
|
observeAutoSuperProperties()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUserConsent(): Flow<Boolean> {
|
override fun getUserConsent(): Flow<Boolean> {
|
||||||
|
@ -116,6 +118,12 @@ class DefaultVectorAnalytics @Inject constructor(
|
||||||
.launchIn(globalScope)
|
.launchIn(globalScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun observeAutoSuperProperties() {
|
||||||
|
autoSuperPropertiesFlowProvider.superPropertiesFlow.onEach {
|
||||||
|
updateSuperProperties(it)
|
||||||
|
}.launchIn(globalScope)
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun identifyPostHog() {
|
private suspend fun identifyPostHog() {
|
||||||
val id = analyticsId ?: return
|
val id = analyticsId ?: return
|
||||||
if (!userConsent.orFalse()) return
|
if (!userConsent.orFalse()) return
|
||||||
|
@ -171,20 +179,14 @@ class DefaultVectorAnalytics @Inject constructor(
|
||||||
|
|
||||||
override fun capture(event: VectorAnalyticsEvent) {
|
override fun capture(event: VectorAnalyticsEvent) {
|
||||||
Timber.tag(analyticsTag.value).d("capture($event)")
|
Timber.tag(analyticsTag.value).d("capture($event)")
|
||||||
posthog
|
posthog?.takeIf { userConsent == true }?.capture(
|
||||||
?.takeIf { userConsent == true }
|
event.getName(), analyticsId, event.getProperties()?.toPostHogProperties().orEmpty().withSuperProperties()
|
||||||
?.capture(
|
|
||||||
event.getName(),
|
|
||||||
analyticsId,
|
|
||||||
event.getProperties()?.toPostHogProperties().orEmpty().withSuperProperties()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun screen(screen: VectorAnalyticsScreen) {
|
override fun screen(screen: VectorAnalyticsScreen) {
|
||||||
Timber.tag(analyticsTag.value).d("screen($screen)")
|
Timber.tag(analyticsTag.value).d("screen($screen)")
|
||||||
posthog
|
posthog?.takeIf { userConsent == true }?.screen(screen.getName(), screen.getProperties()?.toPostHogProperties().orEmpty().withSuperProperties())
|
||||||
?.takeIf { userConsent == true }
|
|
||||||
?.screen(screen.getName(), screen.getProperties()?.toPostHogProperties().orEmpty().withSuperProperties())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateUserProperties(userProperties: UserProperties) {
|
override fun updateUserProperties(userProperties: UserProperties) {
|
||||||
|
@ -198,9 +200,7 @@ class DefaultVectorAnalytics @Inject constructor(
|
||||||
private fun doUpdateUserProperties(userProperties: UserProperties) {
|
private fun doUpdateUserProperties(userProperties: UserProperties) {
|
||||||
// we need a distinct id to set user properties
|
// we need a distinct id to set user properties
|
||||||
val distinctId = analyticsId ?: return
|
val distinctId = analyticsId ?: return
|
||||||
posthog
|
posthog?.takeIf { userConsent == true }?.identify(distinctId, userProperties.getProperties())
|
||||||
?.takeIf { userConsent == true }
|
|
||||||
?.identify(distinctId, userProperties.getProperties())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Map<String, Any?>?.toPostHogProperties(): Map<String, Any>? {
|
private fun Map<String, Any?>?.toPostHogProperties(): Map<String, Any>? {
|
||||||
|
@ -233,7 +233,7 @@ class DefaultVectorAnalytics @Inject constructor(
|
||||||
* Adds super properties to the actual property set.
|
* Adds super properties to the actual property set.
|
||||||
* If a property of the same name is already on the reported event it will not be overwritten.
|
* If a property of the same name is already on the reported event it will not be overwritten.
|
||||||
*/
|
*/
|
||||||
private fun Map<String, Any>.withSuperProperties(): Map<String, Any> {
|
private fun Map<String, Any>.withSuperProperties(): Map<String, Any>? {
|
||||||
val withSuperProperties = this.toMutableMap()
|
val withSuperProperties = this.toMutableMap()
|
||||||
val superProperties = this@DefaultVectorAnalytics.superProperties?.getProperties()
|
val superProperties = this@DefaultVectorAnalytics.superProperties?.getProperties()
|
||||||
superProperties?.forEach {
|
superProperties?.forEach {
|
||||||
|
@ -241,7 +241,7 @@ class DefaultVectorAnalytics @Inject constructor(
|
||||||
withSuperProperties[it.key] = it.value
|
withSuperProperties[it.key] = it.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return withSuperProperties
|
return withSuperProperties.takeIf { it.isEmpty().not() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun trackError(throwable: Throwable) {
|
override fun trackError(throwable: Throwable) {
|
||||||
|
@ -251,13 +251,7 @@ class DefaultVectorAnalytics @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateSuperProperties(updatedProperties: SuperProperties) {
|
override fun updateSuperProperties(updatedProperties: SuperProperties) {
|
||||||
if (this.superProperties == null) {
|
|
||||||
this.superProperties = updatedProperties
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.superProperties = SuperProperties(
|
this.superProperties = SuperProperties(
|
||||||
platformCodeName = updatedProperties.platformCodeName ?: this.superProperties?.platformCodeName,
|
|
||||||
cryptoSDK = updatedProperties.cryptoSDK ?: this.superProperties?.cryptoSDK,
|
cryptoSDK = updatedProperties.cryptoSDK ?: this.superProperties?.cryptoSDK,
|
||||||
appPlatform = updatedProperties.appPlatform ?: this.superProperties?.appPlatform,
|
appPlatform = updatedProperties.appPlatform ?: this.superProperties?.appPlatform,
|
||||||
cryptoSDKVersion = updatedProperties.cryptoSDKVersion ?: superProperties?.cryptoSDKVersion
|
cryptoSDKVersion = updatedProperties.cryptoSDKVersion ?: superProperties?.cryptoSDKVersion
|
||||||
|
|
|
@ -26,9 +26,12 @@ import im.vector.app.test.fixtures.AnalyticsConfigFixture.anAnalyticsConfig
|
||||||
import im.vector.app.test.fixtures.aUserProperties
|
import im.vector.app.test.fixtures.aUserProperties
|
||||||
import im.vector.app.test.fixtures.aVectorAnalyticsEvent
|
import im.vector.app.test.fixtures.aVectorAnalyticsEvent
|
||||||
import im.vector.app.test.fixtures.aVectorAnalyticsScreen
|
import im.vector.app.test.fixtures.aVectorAnalyticsScreen
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
@ -45,6 +48,9 @@ class DefaultVectorAnalyticsTest {
|
||||||
private val fakeAnalyticsStore = FakeAnalyticsStore()
|
private val fakeAnalyticsStore = FakeAnalyticsStore()
|
||||||
private val fakeLateInitUserPropertiesFactory = FakeLateInitUserPropertiesFactory()
|
private val fakeLateInitUserPropertiesFactory = FakeLateInitUserPropertiesFactory()
|
||||||
private val fakeSentryAnalytics = FakeSentryAnalytics()
|
private val fakeSentryAnalytics = FakeSentryAnalytics()
|
||||||
|
private val mockAutoSuperPropertiesFlowProvider = mockk<AutoSuperPropertiesFlowProvider>().also {
|
||||||
|
every { it.superPropertiesFlow } returns flowOf(SuperProperties())
|
||||||
|
}
|
||||||
|
|
||||||
private val defaultVectorAnalytics = DefaultVectorAnalytics(
|
private val defaultVectorAnalytics = DefaultVectorAnalytics(
|
||||||
postHogFactory = FakePostHogFactory(fakePostHog.instance).instance,
|
postHogFactory = FakePostHogFactory(fakePostHog.instance).instance,
|
||||||
|
@ -52,7 +58,8 @@ class DefaultVectorAnalyticsTest {
|
||||||
analyticsStore = fakeAnalyticsStore.instance,
|
analyticsStore = fakeAnalyticsStore.instance,
|
||||||
globalScope = CoroutineScope(Dispatchers.Unconfined),
|
globalScope = CoroutineScope(Dispatchers.Unconfined),
|
||||||
analyticsConfig = anAnalyticsConfig(isEnabled = true),
|
analyticsConfig = anAnalyticsConfig(isEnabled = true),
|
||||||
lateInitUserPropertiesFactory = fakeLateInitUserPropertiesFactory.instance
|
lateInitUserPropertiesFactory = fakeLateInitUserPropertiesFactory.instance,
|
||||||
|
autoSuperPropertiesFlowProvider = mockAutoSuperPropertiesFlowProvider,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -180,7 +187,7 @@ class DefaultVectorAnalyticsTest {
|
||||||
fakeAnalyticsStore.givenUserContent(consent = true)
|
fakeAnalyticsStore.givenUserContent(consent = true)
|
||||||
|
|
||||||
val updatedProperties = SuperProperties(
|
val updatedProperties = SuperProperties(
|
||||||
platformCodeName = SuperProperties.PlatformCodeName.EA,
|
appPlatform = SuperProperties.AppPlatform.EA,
|
||||||
cryptoSDKVersion = "0.0",
|
cryptoSDKVersion = "0.0",
|
||||||
cryptoSDK = SuperProperties.CryptoSDK.Rust
|
cryptoSDK = SuperProperties.CryptoSDK.Rust
|
||||||
)
|
)
|
||||||
|
@ -214,7 +221,7 @@ class DefaultVectorAnalyticsTest {
|
||||||
fakeAnalyticsStore.givenUserContent(consent = true)
|
fakeAnalyticsStore.givenUserContent(consent = true)
|
||||||
|
|
||||||
val superProperties = SuperProperties(
|
val superProperties = SuperProperties(
|
||||||
platformCodeName = SuperProperties.PlatformCodeName.EA,
|
appPlatform = SuperProperties.AppPlatform.EA,
|
||||||
cryptoSDKVersion = "0.0",
|
cryptoSDKVersion = "0.0",
|
||||||
cryptoSDK = SuperProperties.CryptoSDK.Rust
|
cryptoSDK = SuperProperties.CryptoSDK.Rust
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue