commit
0594db1379
28 changed files with 280 additions and 27 deletions
1
.idea/dictionaries/shared.xml
generated
1
.idea/dictionaries/shared.xml
generated
|
|
@ -8,6 +8,7 @@
|
||||||
<w>measurables</w>
|
<w>measurables</w>
|
||||||
<w>onboarding</w>
|
<w>onboarding</w>
|
||||||
<w>placeables</w>
|
<w>placeables</w>
|
||||||
|
<w>posthog</w>
|
||||||
<w>showkase</w>
|
<w>showkase</w>
|
||||||
<w>snackbar</w>
|
<w>snackbar</w>
|
||||||
<w>swipeable</w>
|
<w>swipeable</w>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class FakeAnalyticsService(
|
||||||
private val didAskUserConsentFlow = MutableStateFlow(didAskUserConsent)
|
private val didAskUserConsentFlow = MutableStateFlow(didAskUserConsent)
|
||||||
val capturedEvents = mutableListOf<VectorAnalyticsEvent>()
|
val capturedEvents = mutableListOf<VectorAnalyticsEvent>()
|
||||||
|
|
||||||
override fun getAvailableAnalyticsProviders(): List<AnalyticsProvider> = emptyList()
|
override fun getAvailableAnalyticsProviders(): Set<AnalyticsProvider> = emptySet()
|
||||||
|
|
||||||
override fun getUserConsent(): Flow<Boolean> = isEnabledFlow
|
override fun getUserConsent(): Flow<Boolean> = isEnabledFlow
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ dependencies {
|
||||||
implementation(projects.features.ftue.api)
|
implementation(projects.features.ftue.api)
|
||||||
implementation(projects.libraries.matrixui)
|
implementation(projects.libraries.matrixui)
|
||||||
implementation(projects.features.logout.api)
|
implementation(projects.features.logout.api)
|
||||||
|
implementation(projects.services.analytics.api)
|
||||||
implementation(projects.services.toolbox.api)
|
implementation(projects.services.toolbox.api)
|
||||||
implementation(libs.datetime)
|
implementation(libs.datetime)
|
||||||
implementation(libs.accompanist.placeholder)
|
implementation(libs.accompanist.placeholder)
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,12 @@ fun DeveloperSettingsView(
|
||||||
RageshakePreferencesView(
|
RageshakePreferencesView(
|
||||||
state = state.rageshakeState,
|
state = state.rageshakeState,
|
||||||
)
|
)
|
||||||
|
PreferenceCategory(title = "Crash", showDivider = false) {
|
||||||
|
PreferenceText(
|
||||||
|
title = "Crash the app 💥",
|
||||||
|
onClick = { error("This crash is a test.") }
|
||||||
|
)
|
||||||
|
}
|
||||||
val cache = state.cacheSize
|
val cache = state.cacheSize
|
||||||
PreferenceCategory(title = "Cache", showDivider = false) {
|
PreferenceCategory(title = "Cache", showDivider = false) {
|
||||||
PreferenceText(
|
PreferenceText(
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||||
import io.element.android.libraries.matrix.api.user.getCurrentUser
|
import io.element.android.libraries.matrix.api.user.getCurrentUser
|
||||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
||||||
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -43,6 +44,7 @@ class PreferencesRootPresenter @Inject constructor(
|
||||||
private val logoutPresenter: LogoutPreferencePresenter,
|
private val logoutPresenter: LogoutPreferencePresenter,
|
||||||
private val matrixClient: MatrixClient,
|
private val matrixClient: MatrixClient,
|
||||||
private val sessionVerificationService: SessionVerificationService,
|
private val sessionVerificationService: SessionVerificationService,
|
||||||
|
private val analyticsService: AnalyticsService,
|
||||||
private val buildType: BuildType,
|
private val buildType: BuildType,
|
||||||
private val versionFormatter: VersionFormatter,
|
private val versionFormatter: VersionFormatter,
|
||||||
private val snackbarDispatcher: SnackbarDispatcher,
|
private val snackbarDispatcher: SnackbarDispatcher,
|
||||||
|
|
@ -58,6 +60,7 @@ class PreferencesRootPresenter @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
||||||
|
val hasAnalyticsProviders = remember { analyticsService.getAvailableAnalyticsProviders().isNotEmpty() }
|
||||||
|
|
||||||
// Session verification status (unknown, not verified, verified)
|
// Session verification status (unknown, not verified, verified)
|
||||||
val sessionVerifiedStatus by sessionVerificationService.sessionVerifiedStatus.collectAsState()
|
val sessionVerifiedStatus by sessionVerificationService.sessionVerifiedStatus.collectAsState()
|
||||||
|
|
@ -72,6 +75,7 @@ class PreferencesRootPresenter @Inject constructor(
|
||||||
myUser = matrixUser.value,
|
myUser = matrixUser.value,
|
||||||
version = versionFormatter.get(),
|
version = versionFormatter.get(),
|
||||||
showCompleteVerification = sessionIsNotVerified,
|
showCompleteVerification = sessionIsNotVerified,
|
||||||
|
showAnalyticsSettings = hasAnalyticsProviders,
|
||||||
showDeveloperSettings = showDeveloperSettings,
|
showDeveloperSettings = showDeveloperSettings,
|
||||||
snackbarMessage = snackbarMessage,
|
snackbarMessage = snackbarMessage,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ data class PreferencesRootState(
|
||||||
val myUser: MatrixUser?,
|
val myUser: MatrixUser?,
|
||||||
val version: String,
|
val version: String,
|
||||||
val showCompleteVerification: Boolean,
|
val showCompleteVerification: Boolean,
|
||||||
|
val showAnalyticsSettings: Boolean,
|
||||||
val showDeveloperSettings: Boolean,
|
val showDeveloperSettings: Boolean,
|
||||||
val snackbarMessage: SnackbarMessage?,
|
val snackbarMessage: SnackbarMessage?,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ fun aPreferencesRootState() = PreferencesRootState(
|
||||||
myUser = null,
|
myUser = null,
|
||||||
version = "Version 1.1 (1)",
|
version = "Version 1.1 (1)",
|
||||||
showCompleteVerification = true,
|
showCompleteVerification = true,
|
||||||
|
showAnalyticsSettings = true,
|
||||||
showDeveloperSettings = true,
|
showDeveloperSettings = true,
|
||||||
snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete),
|
snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -82,11 +82,13 @@ fun PreferencesRootView(
|
||||||
)
|
)
|
||||||
Divider()
|
Divider()
|
||||||
}
|
}
|
||||||
PreferenceText(
|
if (state.showAnalyticsSettings) {
|
||||||
title = stringResource(id = CommonStrings.common_analytics),
|
PreferenceText(
|
||||||
icon = Icons.Outlined.InsertChart,
|
title = stringResource(id = CommonStrings.common_analytics),
|
||||||
onClick = onOpenAnalytics,
|
icon = Icons.Outlined.InsertChart,
|
||||||
)
|
onClick = onOpenAnalytics,
|
||||||
|
)
|
||||||
|
}
|
||||||
PreferenceText(
|
PreferenceText(
|
||||||
title = stringResource(id = CommonStrings.action_report_bug),
|
title = stringResource(id = CommonStrings.action_report_bug),
|
||||||
icon = Icons.Outlined.BugReport,
|
icon = Icons.Outlined.BugReport,
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import app.cash.molecule.RecompositionMode
|
||||||
import app.cash.molecule.moleculeFlow
|
import app.cash.molecule.moleculeFlow
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.features.logout.impl.DefaultLogoutPreferencePresenter
|
import io.element.android.features.logout.impl.DefaultLogoutPreferencePresenter
|
||||||
import io.element.android.libraries.architecture.Async
|
import io.element.android.libraries.architecture.Async
|
||||||
import io.element.android.libraries.core.meta.BuildType
|
import io.element.android.libraries.core.meta.BuildType
|
||||||
|
|
@ -41,6 +42,7 @@ class PreferencesRootPresenterTest {
|
||||||
logoutPresenter,
|
logoutPresenter,
|
||||||
matrixClient,
|
matrixClient,
|
||||||
FakeSessionVerificationService(),
|
FakeSessionVerificationService(),
|
||||||
|
FakeAnalyticsService(),
|
||||||
BuildType.DEBUG,
|
BuildType.DEBUG,
|
||||||
FakeVersionFormatter(),
|
FakeVersionFormatter(),
|
||||||
SnackbarDispatcher(),
|
SnackbarDispatcher(),
|
||||||
|
|
@ -61,6 +63,7 @@ class PreferencesRootPresenterTest {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
assertThat(loadedState.showDeveloperSettings).isEqualTo(true)
|
assertThat(loadedState.showDeveloperSettings).isEqualTo(true)
|
||||||
|
assertThat(loadedState.showAnalyticsSettings).isEqualTo(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:2.0.0"
|
||||||
|
|
||||||
# Analytics
|
# Analytics
|
||||||
posthog = "com.posthog.android:posthog:2.0.3"
|
posthog = "com.posthog.android:posthog:2.0.3"
|
||||||
sentry_android = "io.sentry:sentry-android:6.26.0"
|
sentry = "io.sentry:sentry-android:6.26.0"
|
||||||
matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:42b2faa417c1e95f430bf8f6e379adba25ad5ef8"
|
matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:42b2faa417c1e95f430bf8f6e379adba25ad5ef8"
|
||||||
|
|
||||||
# Di
|
# Di
|
||||||
|
|
|
||||||
|
|
@ -103,8 +103,12 @@ fun DependencyHandlerScope.allLibrariesImpl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DependencyHandlerScope.allServicesImpl() {
|
fun DependencyHandlerScope.allServicesImpl() {
|
||||||
|
// For analytics configuration, either use noop, or use the impl, with at least one analyticsproviders implementation
|
||||||
|
// implementation(project(":services:analytics:noop"))
|
||||||
implementation(project(":services:analytics:impl"))
|
implementation(project(":services:analytics:impl"))
|
||||||
implementation(project(":services:analyticsproviders:posthog"))
|
implementation(project(":services:analyticsproviders:posthog"))
|
||||||
|
implementation(project(":services:analyticsproviders:sentry"))
|
||||||
|
|
||||||
implementation(project(":services:apperror:impl"))
|
implementation(project(":services:apperror:impl"))
|
||||||
implementation(project(":services:appnavstate:impl"))
|
implementation(project(":services:appnavstate:impl"))
|
||||||
implementation(project(":services:toolbox:impl"))
|
implementation(project(":services:toolbox:impl"))
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,10 @@ import io.element.android.services.analyticsproviders.api.trackers.ErrorTracker
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface AnalyticsService: AnalyticsTracker, ErrorTracker {
|
interface AnalyticsService: AnalyticsTracker, ErrorTracker {
|
||||||
fun getAvailableAnalyticsProviders(): List<AnalyticsProvider>
|
/**
|
||||||
|
* Get the available analytics providers.
|
||||||
|
*/
|
||||||
|
fun getAvailableAnalyticsProviders(): Set<AnalyticsProvider>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a Flow of Boolean, true if the user has given their consent.
|
* Return a Flow of Boolean, true if the user has given their consent.
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,8 @@ class DefaultAnalyticsService @Inject constructor(
|
||||||
observeSessions()
|
observeSessions()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAvailableAnalyticsProviders(): List<AnalyticsProvider> {
|
override fun getAvailableAnalyticsProviders(): Set<AnalyticsProvider> {
|
||||||
return analyticsProviders.sortedBy { it.index }
|
return analyticsProviders
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUserConsent(): Flow<Boolean> {
|
override fun getUserConsent(): Flow<Boolean> {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "io.element.android.services.analytics.impl"
|
namespace = "io.element.android.services.analytics.noop"
|
||||||
}
|
}
|
||||||
|
|
||||||
anvil {
|
anvil {
|
||||||
|
|
@ -28,6 +28,7 @@ anvil {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.dagger)
|
implementation(libs.dagger)
|
||||||
|
implementation(projects.libraries.architecture)
|
||||||
implementation(projects.libraries.di)
|
implementation(projects.libraries.di)
|
||||||
api(projects.services.analytics.api)
|
api(projects.services.analytics.api)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 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 io.element.android.services.analytics.noop
|
||||||
|
|
||||||
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
|
import im.vector.app.features.analytics.itf.VectorAnalyticsEvent
|
||||||
|
import im.vector.app.features.analytics.itf.VectorAnalyticsScreen
|
||||||
|
import im.vector.app.features.analytics.plan.UserProperties
|
||||||
|
import io.element.android.libraries.di.AppScope
|
||||||
|
import io.element.android.libraries.di.SingleIn
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
|
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@SingleIn(AppScope::class)
|
||||||
|
@ContributesBinding(AppScope::class)
|
||||||
|
class NoopAnalyticsService @Inject constructor(
|
||||||
|
) : AnalyticsService {
|
||||||
|
override fun getAvailableAnalyticsProviders(): Set<AnalyticsProvider> = emptySet()
|
||||||
|
override fun getUserConsent(): Flow<Boolean> = flowOf(false)
|
||||||
|
override suspend fun setUserConsent(userConsent: Boolean) = Unit
|
||||||
|
override fun didAskUserConsent(): Flow<Boolean> = flowOf(true)
|
||||||
|
override suspend fun setDidAskUserConsent() = Unit
|
||||||
|
override fun getAnalyticsId(): Flow<String> = flowOf("")
|
||||||
|
override suspend fun setAnalyticsId(analyticsId: String) = Unit
|
||||||
|
override suspend fun onSignOut() = Unit
|
||||||
|
override suspend fun reset() = Unit
|
||||||
|
override fun capture(event: VectorAnalyticsEvent) = Unit
|
||||||
|
override fun screen(screen: VectorAnalyticsScreen) = Unit
|
||||||
|
override fun updateUserProperties(userProperties: UserProperties) = Unit
|
||||||
|
override fun trackError(throwable: Throwable) = Unit
|
||||||
|
}
|
||||||
|
|
@ -20,11 +20,6 @@ import io.element.android.services.analyticsproviders.api.trackers.AnalyticsTrac
|
||||||
import io.element.android.services.analyticsproviders.api.trackers.ErrorTracker
|
import io.element.android.services.analyticsproviders.api.trackers.ErrorTracker
|
||||||
|
|
||||||
interface AnalyticsProvider: AnalyticsTracker, ErrorTracker {
|
interface AnalyticsProvider: AnalyticsTracker, ErrorTracker {
|
||||||
/**
|
|
||||||
* Allow to sort providers, from lower index to higher index.
|
|
||||||
*/
|
|
||||||
val index: Int
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User friendly name.
|
* User friendly name.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ import javax.inject.Inject
|
||||||
class PosthogAnalyticsProvider @Inject constructor(
|
class PosthogAnalyticsProvider @Inject constructor(
|
||||||
private val postHogFactory: PostHogFactory,
|
private val postHogFactory: PostHogFactory,
|
||||||
) : AnalyticsProvider {
|
) : AnalyticsProvider {
|
||||||
override val index = PosthogConfig.index
|
|
||||||
override val name = PosthogConfig.name
|
override val name = PosthogConfig.name
|
||||||
|
|
||||||
private var posthog: PostHog? = null
|
private var posthog: PostHog? = null
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
package io.element.android.services.analyticsproviders.posthog
|
package io.element.android.services.analyticsproviders.posthog
|
||||||
|
|
||||||
object PosthogConfig {
|
object PosthogConfig {
|
||||||
const val index = 0
|
|
||||||
const val name = "Posthog"
|
const val name = "Posthog"
|
||||||
const val postHogHost = "https://posthog.element.dev"
|
const val postHogHost = "https://posthog.element.dev"
|
||||||
const val postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN"
|
const val postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN"
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,4 @@ package io.element.android.services.analyticsproviders.posthog.log
|
||||||
|
|
||||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||||
|
|
||||||
val analyticsTag = LoggerTag("Analytics")
|
internal val analyticsTag = LoggerTag("Posthog")
|
||||||
|
|
|
||||||
35
services/analyticsproviders/sentry/build.gradle.kts
Normal file
35
services/analyticsproviders/sentry/build.gradle.kts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 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.
|
||||||
|
*/
|
||||||
|
plugins {
|
||||||
|
id("io.element.android-library")
|
||||||
|
alias(libs.plugins.anvil)
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "io.element.android.services.analyticsproviders.sentry"
|
||||||
|
}
|
||||||
|
|
||||||
|
anvil {
|
||||||
|
generateDaggerFactories.set(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(libs.dagger)
|
||||||
|
implementation(libs.sentry)
|
||||||
|
implementation(projects.libraries.core)
|
||||||
|
implementation(projects.libraries.di)
|
||||||
|
implementation(projects.services.analyticsproviders.api)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright (c) 2023 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<application>
|
||||||
|
<!-- Sentry auto-initialization disabled -->
|
||||||
|
<meta-data
|
||||||
|
android:name="io.sentry.auto-init"
|
||||||
|
android:value="false" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 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 io.element.android.services.analyticsproviders.sentry
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.squareup.anvil.annotations.ContributesMultibinding
|
||||||
|
import im.vector.app.features.analytics.itf.VectorAnalyticsEvent
|
||||||
|
import im.vector.app.features.analytics.itf.VectorAnalyticsScreen
|
||||||
|
import im.vector.app.features.analytics.plan.UserProperties
|
||||||
|
import io.element.android.libraries.core.meta.BuildMeta
|
||||||
|
import io.element.android.libraries.core.meta.BuildType
|
||||||
|
import io.element.android.libraries.di.AppScope
|
||||||
|
import io.element.android.libraries.di.ApplicationContext
|
||||||
|
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
|
||||||
|
import io.element.android.services.analyticsproviders.sentry.log.analyticsTag
|
||||||
|
import io.sentry.Sentry
|
||||||
|
import io.sentry.SentryOptions
|
||||||
|
import io.sentry.android.core.SentryAndroid
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ContributesMultibinding(AppScope::class)
|
||||||
|
class SentryAnalyticsProvider @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
|
) : AnalyticsProvider {
|
||||||
|
override val name = SentryConfig.name
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
Timber.tag(analyticsTag.value).d("Initializing Sentry")
|
||||||
|
if (Sentry.isEnabled()) return
|
||||||
|
SentryAndroid.init(context) { options ->
|
||||||
|
options.dsn = SentryConfig.dns
|
||||||
|
options.beforeSend = SentryOptions.BeforeSendCallback { event, _ -> event }
|
||||||
|
options.tracesSampleRate = 1.0
|
||||||
|
options.isEnableUserInteractionTracing = true
|
||||||
|
options.environment = buildMeta.buildType.toSentryEnv()
|
||||||
|
options.diagnosticLevel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stop() {
|
||||||
|
Timber.tag(analyticsTag.value).d("Stopping Sentry")
|
||||||
|
Sentry.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun capture(event: VectorAnalyticsEvent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun screen(screen: VectorAnalyticsScreen) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateUserProperties(userProperties: UserProperties) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun trackError(throwable: Throwable) {
|
||||||
|
Sentry.captureException(throwable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun BuildType.toSentryEnv() = when (this) {
|
||||||
|
BuildType.RELEASE -> SentryConfig.envRelease
|
||||||
|
BuildType.NIGHTLY,
|
||||||
|
BuildType.DEBUG -> SentryConfig.envDebug
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 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 io.element.android.services.analyticsproviders.sentry
|
||||||
|
|
||||||
|
object SentryConfig {
|
||||||
|
const val name = "Sentry"
|
||||||
|
const val dns = "https://32f7ff6a6e724f90838b7654042b2e81@sentry.tools.element.io/59"
|
||||||
|
const val envDebug = "DEBUG"
|
||||||
|
const val envRelease = "RELEASE"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 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 io.element.android.services.analyticsproviders.sentry.log
|
||||||
|
|
||||||
|
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||||
|
|
||||||
|
internal val analyticsTag = LoggerTag("Sentry")
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fb77df9e072715ed947537e4474d504b5b5d533bfe9cd888362a421fea5b53b5
|
oid sha256:6c0a16524e1017274eeb0f07a50a47c6351af9a901355b54cccbc9ec799e79f4
|
||||||
size 44068
|
size 45174
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fb77df9e072715ed947537e4474d504b5b5d533bfe9cd888362a421fea5b53b5
|
oid sha256:6c0a16524e1017274eeb0f07a50a47c6351af9a901355b54cccbc9ec799e79f4
|
||||||
size 44068
|
size 45174
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:004a25de04aac1ca9cbbad77581e0b52a6f8fba30aa2e64c03a791c54b297d5a
|
oid sha256:abb7854a1e47764a907434cdf32e138b95c947bab682da485eea86f9726cf3b9
|
||||||
size 48875
|
size 49946
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:004a25de04aac1ca9cbbad77581e0b52a6f8fba30aa2e64c03a791c54b297d5a
|
oid sha256:abb7854a1e47764a907434cdf32e138b95c947bab682da485eea86f9726cf3b9
|
||||||
size 48875
|
size 49946
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue