Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: show analytics initialized for automation (WPB-10600) #3330

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading