Skip to content

Commit

Permalink
feat: show analytics initialized for automation (WPB-10600) (#3330)
Browse files Browse the repository at this point in the history
Signed-off-by: alexandreferris <[email protected]>

(cherry picked from commit a404cdf)
Signed-off-by: alexandreferris <[email protected]>
  • Loading branch information
alexandreferris committed Aug 16, 2024
1 parent 683d79a commit d5dafc8
Show file tree
Hide file tree
Showing 18 changed files with 117 additions and 27 deletions.
8 changes: 8 additions & 0 deletions app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.wire.kalium.logic.data.id.FederatedIdMapper
import com.wire.kalium.logic.data.id.QualifiedIdMapper
import com.wire.kalium.logic.data.id.QualifiedIdMapperImpl
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.feature.analytics.GetCurrentAnalyticsTrackingIdentifierUseCase
import com.wire.kalium.logic.feature.auth.AddAuthenticatedUserUseCase
import com.wire.kalium.logic.feature.auth.LogoutUseCase
import com.wire.kalium.logic.feature.connection.BlockUserUseCase
Expand Down Expand Up @@ -473,4 +474,11 @@ class UseCaseModule {
@KaliumCoreLogic coreLogic: CoreLogic,
@CurrentAccount currentAccount: UserId
): FetchConversationMLSVerificationStatusUseCase = coreLogic.getSessionScope(currentAccount).fetchConversationMLSVerificationStatus

@ViewModelScoped
@Provides
fun provideGetCurrentAnalyticsTrackingIdentifierUseCase(
@KaliumCoreLogic coreLogic: CoreLogic,
@CurrentAccount currentAccount: UserId
): GetCurrentAnalyticsTrackingIdentifierUseCase = coreLogic.getSessionScope(currentAccount).getCurrentAnalyticsTrackingIdentifier
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ class AnalyticsUsageViewModel @Inject constructor(
val isAnalyticsUsageEnabled = dataStore.isAnonymousUsageDataEnabled().first()
val isAnalyticsConfigurationEnabled = analyticsEnabled is AnalyticsConfiguration.Enabled
val isProdBackend = when (val serverConfig = selfServerConfig()) {
is SelfServerConfigUseCase.Result.Success -> serverConfig.serverLinks.links.api == ServerConfig.PRODUCTION.api
is SelfServerConfigUseCase.Result.Success ->
serverConfig.serverLinks.links.api == ServerConfig.PRODUCTION.api
|| serverConfig.serverLinks.links.api == ServerConfig.STAGING.api
is SelfServerConfigUseCase.Result.Failure -> false
}

Expand Down
17 changes: 17 additions & 0 deletions app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import androidx.compose.ui.res.stringResource
import com.wire.android.BuildConfig
import com.wire.android.R
import com.wire.android.di.hiltViewModelScoped
import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl
import com.wire.android.model.Clickable
import com.wire.android.ui.common.RowItemTemplate
import com.wire.android.ui.common.WireDialog
Expand Down Expand Up @@ -136,6 +137,22 @@ fun DebugDataOptionsContent(
onClick = { onCopyText(state.debugId) }
)
)

SettingsItem(
title = stringResource(id = R.string.debug_analytics_enabled_title),
text = AnonymousAnalyticsManagerImpl.isAnalyticsInitialized().toString()
)

SettingsItem(
title = stringResource(id = R.string.debug_analytics_tracking_identifier_title),
text = state.analyticsTrackingId,
trailingIcon = R.drawable.ic_copy,
onIconPressed = Clickable(
enabled = true,
onClick = { onCopyText(state.analyticsTrackingId) }
)
)

if (BuildConfig.DEBUG) {
GetE2EICertificateSwitch(
enrollE2EI = enrollE2EICertificate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ data class DebugDataOptionsState(
val certificate: String = "null",
val showCertificate: Boolean = false,
val startGettingE2EICertificate: Boolean = false,
val analyticsTrackingId: String = "null"
)
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.wire.android.util.getGitBuildId
import com.wire.kalium.logic.CoreFailure
import com.wire.kalium.logic.E2EIFailure
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.feature.analytics.GetCurrentAnalyticsTrackingIdentifierUseCase
import com.wire.kalium.logic.feature.e2ei.CheckCrlRevocationListUseCase
import com.wire.kalium.logic.feature.e2ei.usecase.E2EIEnrollmentResult
import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountResult
Expand Down Expand Up @@ -73,7 +74,8 @@ class DebugDataOptionsViewModelImpl
private val updateApiVersions: UpdateApiVersionsScheduler,
private val mlsKeyPackageCount: MLSKeyPackageCountUseCase,
private val restartSlowSyncProcessForRecovery: RestartSlowSyncProcessForRecoveryUseCase,
private val checkCrlRevocationList: CheckCrlRevocationListUseCase
private val checkCrlRevocationList: CheckCrlRevocationListUseCase,
private val getCurrentAnalyticsTrackingIdentifier: GetCurrentAnalyticsTrackingIdentifierUseCase
) : ViewModel(), DebugDataOptionsViewModel {

var state by mutableStateOf(
Expand All @@ -85,6 +87,17 @@ class DebugDataOptionsViewModelImpl
observeMlsMetadata()
checkIfCanTriggerManualMigration()
setGitHashAndDeviceId()
setAnalyticsTrackingId()
}

private fun setAnalyticsTrackingId() {
viewModelScope.launch {
getCurrentAnalyticsTrackingIdentifier()?.let { trackingId ->
state = state.copy(
analyticsTrackingId = trackingId
)
}
}
}

private fun setGitHashAndDeviceId() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fun PrivacySettingsConfigScreen(
) {
with(viewModel) {
PrivacySettingsScreenContent(
isAnonymousUsageDataEnabled = state.isAnonymousUsageDataEnabled,
isAnonymousUsageDataEnabled = state.isAnalyticsUsageEnabled,
areReadReceiptsEnabled = state.areReadReceiptsEnabled,
setReadReceiptsState = ::setReadReceiptsState,
isTypingIndicatorEnabled = state.isTypingIndicatorEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
package com.wire.android.ui.home.settings.privacy

data class PrivacySettingsState(
val isAnonymousUsageDataEnabled: Boolean = true,
val isAnalyticsUsageEnabled: Boolean = true,
val shouldShowAnalyticsUsage: Boolean = false,
val areReadReceiptsEnabled: Boolean = true,
val isTypingIndicatorEnabled: Boolean = true,
val screenshotCensoringConfig: ScreenshotCensoringConfig = ScreenshotCensoringConfig.ENABLED_BY_USER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.wire.android.appLogger
import com.wire.android.datastore.UserDataStore
import com.wire.android.ui.analytics.AnalyticsConfiguration
import com.wire.android.util.dispatchers.DispatcherProvider
import com.wire.kalium.logic.configuration.server.ServerConfig
import com.wire.kalium.logic.feature.user.SelfServerConfigUseCase
import com.wire.kalium.logic.feature.user.readReceipts.ObserveReadReceiptsEnabledUseCase
import com.wire.kalium.logic.feature.user.readReceipts.PersistReadReceiptsStatusConfigUseCase
import com.wire.kalium.logic.feature.user.readReceipts.ReadReceiptStatusConfigResult
Expand All @@ -42,6 +45,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject

@Suppress("LongParameterList")
@HiltViewModel
class PrivacySettingsViewModel @Inject constructor(
private val dispatchers: DispatcherProvider,
Expand All @@ -51,6 +55,8 @@ class PrivacySettingsViewModel @Inject constructor(
private val observeScreenshotCensoringConfig: ObserveScreenshotCensoringConfigUseCase,
private val persistTypingIndicatorStatusConfig: PersistTypingIndicatorStatusConfigUseCase,
private val observeTypingIndicatorEnabled: ObserveTypingIndicatorEnabledUseCase,
private val analyticsEnabled: AnalyticsConfiguration,
private val selfServerConfig: SelfServerConfigUseCase,
private val dataStore: UserDataStore
) : ViewModel() {

Expand All @@ -66,7 +72,7 @@ class PrivacySettingsViewModel @Inject constructor(
dataStore.isAnonymousUsageDataEnabled()
) { readReceiptsEnabled, typingIndicatorEnabled, screenshotCensoringConfig, anonymousUsageDataEnabled ->
PrivacySettingsState(
isAnonymousUsageDataEnabled = anonymousUsageDataEnabled,
isAnalyticsUsageEnabled = anonymousUsageDataEnabled,
areReadReceiptsEnabled = readReceiptsEnabled,
isTypingIndicatorEnabled = typingIndicatorEnabled,
screenshotCensoringConfig = when (screenshotCensoringConfig) {
Expand All @@ -82,6 +88,20 @@ class PrivacySettingsViewModel @Inject constructor(
)
}.collect { state = it }
}

viewModelScope.launch {
val isAnalyticsConfigurationEnabled = analyticsEnabled is AnalyticsConfiguration.Enabled
val isValidBackend = when (val serverConfig = selfServerConfig()) {
is SelfServerConfigUseCase.Result.Success ->
serverConfig.serverLinks.links.api == ServerConfig.PRODUCTION.api
|| serverConfig.serverLinks.links.api == ServerConfig.STAGING.api
is SelfServerConfigUseCase.Result.Failure -> false
}

state = state.copy(
shouldShowAnalyticsUsage = isAnalyticsConfigurationEnabled && isValidBackend
)
}
}

fun setReadReceiptsState(isEnabled: Boolean) {
Expand Down Expand Up @@ -137,7 +157,7 @@ class PrivacySettingsViewModel @Inject constructor(
dataStore.setIsAnonymousAnalyticsEnabled(enabled)
}
state = state.copy(
isAnonymousUsageDataEnabled = enabled
isAnalyticsUsageEnabled = enabled
)
}
}
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
<string name="app_version">App version</string>
<string name="build_variant_name">Build variant</string>
<string name="debug_id" translatable="false">Debug Identifier</string>
<string name="debug_analytics_enabled_title" translatable="false">Analytics Initialized</string>
<string name="debug_analytics_tracking_identifier_title" translatable="false">
Analytics Tracking Identifier
</string>
<string name="label_new">New</string>
<string name="label_login">Login</string>
<string name="label_ok">OK</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class AnalyticsUsageViewModelTest {
fun `should hide or show Analytics Usage dialog - handle accordingly`(params: TestParams) = runTest {
// given
val (_, viewModel) = Arrangement()
.withProdBackend(params.isProdBackend)
.withServerConfig(params.serverConfig)
.withAnalyticsUsageEnabled(params.isAnalyticsUsageEnabled)
.withIsDialogSeen(params.isDialogSeen)
.arrange(analyticsConfiguration = params.analyticsConfiguration)
Expand All @@ -59,7 +59,7 @@ class AnalyticsUsageViewModelTest {
fun `given dialog is shown, when user agrees to analytics usage, then setting analytics to enabled and dialog to seen`() = runTest {
// given
val (arrangement, viewModel) = Arrangement()
.withProdBackend(true)
.withServerConfig(STAGING_SERVER_CONFIG)
.withAnalyticsUsageEnabled(false)
.withIsDialogSeen(false)
.arrange(analyticsConfiguration = AnalyticsConfiguration.Enabled)
Expand All @@ -81,7 +81,7 @@ class AnalyticsUsageViewModelTest {
fun `given dialog is shown, when user declines analytics usage, then setting analytics to disabled and dialog to seen`() = runTest {
// given
val (arrangement, viewModel) = Arrangement()
.withProdBackend(true)
.withServerConfig(PRODUCTION_SERVER_CONFIG)
.withAnalyticsUsageEnabled(false)
.withIsDialogSeen(false)
.arrange(analyticsConfiguration = AnalyticsConfiguration.Enabled)
Expand Down Expand Up @@ -110,9 +110,9 @@ class AnalyticsUsageViewModelTest {
coEvery { dataStore.setIsAnalyticsDialogSeen() } returns Unit
}

fun withProdBackend(isProd: Boolean) = apply {
fun withServerConfig(serverConfig: ServerConfig) = apply {
coEvery { selfServerConfig() } returns SelfServerConfigUseCase.Result.Success(
serverLinks = if (isProd) PRODUCTION_SERVER_CONFIG else CUSTOM_SERVER_CONFIG
serverLinks = serverConfig
)
}
fun withAnalyticsUsageEnabled(enabled: Boolean) = apply {
Expand All @@ -127,52 +127,50 @@ class AnalyticsUsageViewModelTest {
dataStore = dataStore,
selfServerConfig = selfServerConfig
)

private companion object {
val PRODUCTION_SERVER_CONFIG = newServerConfig(1).copy(links = ServerConfig.PRODUCTION)
val CUSTOM_SERVER_CONFIG = newServerConfig(1).copy(links = ServerConfig.STAGING)
}
}

companion object {
val PRODUCTION_SERVER_CONFIG = newServerConfig(1).copy(links = ServerConfig.PRODUCTION)
val STAGING_SERVER_CONFIG = newServerConfig(1).copy(links = ServerConfig.STAGING)
val CUSTOM_SERVER_CONFIG = newServerConfig(1).copy(links = ServerConfig.DUMMY)

enum class TestParams(
val isProdBackend: Boolean,
val serverConfig: ServerConfig,
val isAnalyticsUsageEnabled: Boolean,
val isDialogSeen: Boolean,
val analyticsConfiguration: AnalyticsConfiguration,
val expected: Boolean
) {
SHOULD_SHOW_DIALOG(
true,
PRODUCTION_SERVER_CONFIG,
false,
false,
AnalyticsConfiguration.Enabled,
true
),
SHOULD_HIDE_DIALOG(
true,
STAGING_SERVER_CONFIG,
false,
true,
AnalyticsConfiguration.Enabled,
false
),
ANALYTICS_ALREADY_ENABLED(
true,
STAGING_SERVER_CONFIG,
true,
true,
AnalyticsConfiguration.Enabled,
false
),
CUSTOM_BACKEND(
false,
CUSTOM_SERVER_CONFIG,
false,
false,
AnalyticsConfiguration.Enabled,
false
),
ANALYTICS_CONFIGURATION_DISABLED(
true,
PRODUCTION_SERVER_CONFIG,
false,
false,
AnalyticsConfiguration.Disabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ package com.wire.android.ui.home.settings.privacy
import com.wire.android.config.CoroutineTestExtension
import com.wire.android.config.TestDispatcherProvider
import com.wire.android.datastore.UserDataStore
import com.wire.android.ui.analytics.AnalyticsConfiguration
import com.wire.android.util.newServerConfig
import com.wire.kalium.logic.configuration.server.ServerConfig
import com.wire.kalium.logic.feature.user.SelfServerConfigUseCase
import com.wire.kalium.logic.feature.user.readReceipts.ObserveReadReceiptsEnabledUseCase
import com.wire.kalium.logic.feature.user.readReceipts.PersistReadReceiptsStatusConfigUseCase
import com.wire.kalium.logic.feature.user.readReceipts.ReadReceiptStatusConfigResult
Expand Down Expand Up @@ -54,7 +58,7 @@ class PrivacySettingsViewModelTest {
// then
assertEquals(
true,
viewModel.state.isAnonymousUsageDataEnabled
viewModel.state.isAnalyticsUsageEnabled
)
}

Expand All @@ -69,7 +73,7 @@ class PrivacySettingsViewModelTest {
// then
assertEquals(
false,
viewModel.state.isAnonymousUsageDataEnabled
viewModel.state.isAnalyticsUsageEnabled
)
}

Expand All @@ -86,7 +90,7 @@ class PrivacySettingsViewModelTest {
// then
assertEquals(
false,
viewModel.state.isAnonymousUsageDataEnabled
viewModel.state.isAnalyticsUsageEnabled
)
}

Expand All @@ -103,7 +107,7 @@ class PrivacySettingsViewModelTest {
// then
assertEquals(
true,
viewModel.state.isAnonymousUsageDataEnabled
viewModel.state.isAnalyticsUsageEnabled
)
}

Expand All @@ -114,6 +118,7 @@ class PrivacySettingsViewModelTest {
val observeScreenshotCensoringConfig = mockk<ObserveScreenshotCensoringConfigUseCase>()
val persistTypingIndicatorStatusConfig = mockk<PersistTypingIndicatorStatusConfigUseCase>()
val observeTypingIndicatorEnabled = mockk<ObserveTypingIndicatorEnabledUseCase>()
val selfServerConfig = mockk<SelfServerConfigUseCase>()
val dataStore = mockk<UserDataStore>()

val viewModel by lazy {
Expand All @@ -125,6 +130,8 @@ class PrivacySettingsViewModelTest {
observeScreenshotCensoringConfig = observeScreenshotCensoringConfig,
persistTypingIndicatorStatusConfig = persistTypingIndicatorStatusConfig,
observeTypingIndicatorEnabled = observeTypingIndicatorEnabled,
analyticsEnabled = AnalyticsConfiguration.Enabled,
selfServerConfig = selfServerConfig,
dataStore = dataStore
)
}
Expand All @@ -140,6 +147,9 @@ class PrivacySettingsViewModelTest {
coEvery { persistTypingIndicatorStatusConfig.invoke(true) } returns TypingIndicatorConfigResult.Success
coEvery { observeTypingIndicatorEnabled() } returns flowOf(true)
coEvery { dataStore.setIsAnonymousAnalyticsEnabled(any()) } returns Unit
coEvery { selfServerConfig.invoke() } returns SelfServerConfigUseCase.Result.Success(
serverLinks = newServerConfig(1).copy(links = ServerConfig.STAGING)
)
}

fun withEnabledAnonymousUsageData() = apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,10 @@ object AnonymousAnalyticsManagerImpl : AnonymousAnalyticsManager {
is AnalyticsIdentifierResult.Disabled -> {}
}
}

override fun isAnalyticsInitialized(): Boolean =
anonymousAnalyticsRecorder?.isAnalyticsInitialized() ?: run {
Log.w(TAG, "Calling isAnalyticsInitialized with a null recorder.")
false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,6 @@ class AnonymousAnalyticsRecorderImpl : AnonymousAnalyticsRecorder {
)
Countly.sharedInstance().userProfile().save()
}

override fun isAnalyticsInitialized(): Boolean = Countly.sharedInstance().isInitialized
}
Loading

0 comments on commit d5dafc8

Please sign in to comment.