From 59f9c3d6a0857d2b1423e86dbd463c09ee6805b6 Mon Sep 17 00:00:00 2001 From: Yamil Medina Date: Wed, 2 Oct 2024 12:04:20 -0300 Subject: [PATCH] feat: enable countly performance metrics (WPB-8842) (#3481) --- .../com/wire/android/WireApplication.kt | 2 + .../wire/android/ui/WireActivityViewModel.kt | 12 +-- .../wire/android/util/CurrentScreenManager.kt | 37 ++++--- .../WireNotificationManagerTest.kt | 12 +-- .../android/ui/WireActivityViewModelTest.kt | 10 +- .../topappbar/CommonTopAppBarViewModelTest.kt | 2 +- .../recordaudio/RecordAudioViewModelTest.kt | 4 +- .../AnonymousAnalyticsManagerImpl.kt | 25 +++++ .../AnonymousAnalyticsRecorderImpl.kt | 19 ++++ .../AnonymousAnalyticsManagerTest.kt | 97 ++++++++++++++++++- .../analytics/AnonymousAnalyticsManager.kt | 6 ++ .../AnonymousAnalyticsManagerStub.kt | 4 + .../analytics/AnonymousAnalyticsRecorder.kt | 6 ++ .../AnonymousAnalyticsRecorderStub.kt | 3 + 14 files changed, 205 insertions(+), 34 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/WireApplication.kt b/app/src/main/kotlin/com/wire/android/WireApplication.kt index aebfff39aa6..764acbd3c4f 100644 --- a/app/src/main/kotlin/com/wire/android/WireApplication.kt +++ b/app/src/main/kotlin/com/wire/android/WireApplication.kt @@ -223,6 +223,8 @@ class WireApplication : BaseApp() { dispatcher = Dispatchers.IO ) + AnonymousAnalyticsManagerImpl.applicationOnCreate() + // observe the app visibility state and send AppOpen event if the app goes from the background to the foreground globalAppScope.launch { currentScreenManager diff --git a/app/src/main/kotlin/com/wire/android/ui/WireActivityViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/WireActivityViewModel.kt index 7b0c5e8fea1..1f3073d4a9e 100644 --- a/app/src/main/kotlin/com/wire/android/ui/WireActivityViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/WireActivityViewModel.kt @@ -566,15 +566,15 @@ class WireActivityViewModel @Inject constructor( } private fun CurrentScreen.isGlobalDialogAllowed(): Boolean = when (this) { - CurrentScreen.ImportMedia, - CurrentScreen.DeviceManager -> false + is CurrentScreen.ImportMedia, + is CurrentScreen.DeviceManager -> false - CurrentScreen.InBackground, + is CurrentScreen.InBackground, is CurrentScreen.Conversation, - CurrentScreen.Home, + is CurrentScreen.Home, is CurrentScreen.OtherUserProfile, - CurrentScreen.AuthRelated, - CurrentScreen.SomeOther -> true + is CurrentScreen.AuthRelated, + is CurrentScreen.SomeOther -> true } } diff --git a/app/src/main/kotlin/com/wire/android/util/CurrentScreenManager.kt b/app/src/main/kotlin/com/wire/android/util/CurrentScreenManager.kt index 2b9b05c0925..b2b1558482c 100644 --- a/app/src/main/kotlin/com/wire/android/util/CurrentScreenManager.kt +++ b/app/src/main/kotlin/com/wire/android/util/CurrentScreenManager.kt @@ -20,6 +20,7 @@ package com.wire.android.util +import android.annotation.SuppressLint import android.os.Bundle import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner @@ -27,6 +28,7 @@ import androidx.navigation.NavController import androidx.navigation.NavDestination import com.ramcosta.composedestinations.spec.DestinationSpec import com.wire.android.appLogger +import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl import com.wire.android.navigation.toDestination import com.wire.android.ui.destinations.ConversationScreenDestination import com.wire.android.ui.destinations.CreateAccountDetailsScreenDestination @@ -46,6 +48,7 @@ import com.wire.android.ui.destinations.RegisterDeviceScreenDestination import com.wire.android.ui.destinations.RemoveDeviceScreenDestination import com.wire.android.ui.destinations.SelfDevicesScreenDestination import com.wire.android.ui.destinations.WelcomeScreenDestination +import com.wire.kalium.logger.obfuscateId import com.wire.kalium.logic.data.id.ConversationId import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -67,7 +70,7 @@ class CurrentScreenManager @Inject constructor( ) : DefaultLifecycleObserver, NavController.OnDestinationChangedListener { - private val currentScreenState = MutableStateFlow(CurrentScreen.SomeOther) + private val currentScreenState = MutableStateFlow(CurrentScreen.SomeOther()) /** * An integer that counts up when a screen appears, and counts down when @@ -120,12 +123,17 @@ class CurrentScreenManager @Inject constructor( } override fun onDestinationChanged(controller: NavController, destination: NavDestination, arguments: Bundle?) { + val currentView = currentScreenState.value.toString() + AnonymousAnalyticsManagerImpl.stopView(currentView) val currentItem = destination.toDestination() currentScreenState.value = CurrentScreen.fromDestination( currentItem, arguments, isApplicationVisibleFlow.value ) + + val newView = currentScreenState.value.toString() + AnonymousAnalyticsManagerImpl.recordView(newView) } companion object { @@ -136,30 +144,35 @@ class CurrentScreenManager @Inject constructor( sealed class CurrentScreen { // Home Screen is being displayed - object Home : CurrentScreen() + data object Home : CurrentScreen() // Some Conversation is opened - data class Conversation(val id: ConversationId) : CurrentScreen() + data class Conversation(val id: ConversationId) : CurrentScreen() { + override fun toString(): String = "Conversation(${id.toString().obfuscateId()})" + } // Another User Profile Screen is opened - data class OtherUserProfile(val id: ConversationId) : CurrentScreen() + data class OtherUserProfile(val id: ConversationId) : CurrentScreen() { + override fun toString(): String = "OtherUserProfile(${id.toString().obfuscateId()})" + } // Import media screen is opened - object ImportMedia : CurrentScreen() + data object ImportMedia : CurrentScreen() // SelfDevices screen is opened - object DeviceManager : CurrentScreen() + data object DeviceManager : CurrentScreen() // Auth related screen is opened - object AuthRelated : CurrentScreen() + data class AuthRelated(val route: String?) : CurrentScreen() // Some other screen is opened, kinda "do nothing screen" - object SomeOther : CurrentScreen() + data class SomeOther(val route: String? = null) : CurrentScreen() // App is in background (screen is turned off, or covered by another app), non of the screens is visible - object InBackground : CurrentScreen() + data object InBackground : CurrentScreen() companion object { + @SuppressLint("RestrictedApi") @Suppress("ComplexMethod") fun fromDestination(destination: DestinationSpec<*>?, arguments: Bundle?, isAppVisible: Boolean): CurrentScreen { if (!isAppVisible) { @@ -171,7 +184,7 @@ sealed class CurrentScreen { Conversation(destination.argsFrom(arguments).conversationId) is OtherUserProfileScreenDestination -> - destination.argsFrom(arguments).conversationId?.let { OtherUserProfile(it) } ?: SomeOther + destination.argsFrom(arguments).conversationId?.let { OtherUserProfile(it) } ?: SomeOther(destination.baseRoute) is ImportMediaScreenDestination -> ImportMedia @@ -189,9 +202,9 @@ sealed class CurrentScreen { is E2EIEnrollmentScreenDestination, is E2eiCertificateDetailsScreenDestination, is RegisterDeviceScreenDestination, - is RemoveDeviceScreenDestination -> AuthRelated + is RemoveDeviceScreenDestination -> AuthRelated(destination.baseRoute) - else -> SomeOther + else -> SomeOther(destination?.baseRoute) } } } diff --git a/app/src/test/kotlin/com/wire/android/notification/WireNotificationManagerTest.kt b/app/src/test/kotlin/com/wire/android/notification/WireNotificationManagerTest.kt index 6fdcb2215d0..06964715d57 100644 --- a/app/src/test/kotlin/com/wire/android/notification/WireNotificationManagerTest.kt +++ b/app/src/test/kotlin/com/wire/android/notification/WireNotificationManagerTest.kt @@ -135,7 +135,7 @@ class WireNotificationManagerTest { fun givenNotAuthenticatedUser_whenObserveCalled_thenNothingHappenAndCallNotificationHides() = runTestWithCancellation(dispatcherProvider.main()) { val (arrangement, manager) = Arrangement() - .withCurrentScreen(CurrentScreen.SomeOther) + .withCurrentScreen(CurrentScreen.SomeOther()) .arrange() manager.observeNotificationsAndCallsWhileRunning(listOf(), this) @@ -152,7 +152,7 @@ class WireNotificationManagerTest { val (arrangement, manager) = Arrangement() .withSpecificUserSession(userId = userId, incomingCalls = incomingCalls) .withMessageNotifications(listOf()) - .withCurrentScreen(CurrentScreen.SomeOther) + .withCurrentScreen(CurrentScreen.SomeOther()) .withCurrentUserSession(CurrentSessionResult.Success(AccountInfo.Valid(userId))) .arrange() @@ -174,7 +174,7 @@ class WireNotificationManagerTest { .withSpecificUserSession(userId = user1, incomingCalls = listOf()) .withSpecificUserSession(userId = user2, incomingCalls = incomingCalls) .withMessageNotifications(listOf()) - .withCurrentScreen(CurrentScreen.SomeOther) + .withCurrentScreen(CurrentScreen.SomeOther()) .withCurrentUserSession(CurrentSessionResult.Success(provideAccountInfo(user1.value))) .arrange() @@ -198,7 +198,7 @@ class WireNotificationManagerTest { ) ) ) - .withCurrentScreen(CurrentScreen.SomeOther).arrange() + .withCurrentScreen(CurrentScreen.SomeOther()).arrange() manager.observeNotificationsAndCallsWhileRunning(listOf(), this) runCurrent() @@ -249,7 +249,7 @@ class WireNotificationManagerTest { .withMessageNotifications(messageNotifications) .withIncomingCalls(listOf()) .withOutgoingCalls(listOf()) - .withCurrentScreen(CurrentScreen.SomeOther) + .withCurrentScreen(CurrentScreen.SomeOther()) .arrange() manager.observeNotificationsAndCallsWhileRunning(listOf(provideUserId(TestUser.SELF_USER.id.value)), this) @@ -960,7 +960,7 @@ class WireNotificationManagerTest { ) .withIncomingCalls(listOf()) .withOutgoingCalls(listOf()) - .withCurrentScreen(CurrentScreen.SomeOther) + .withCurrentScreen(CurrentScreen.SomeOther()) .withObserveE2EIRequired(E2EIRequiredResult.NoGracePeriod.Create) .arrange() diff --git a/app/src/test/kotlin/com/wire/android/ui/WireActivityViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/WireActivityViewModelTest.kt index 5161dba9942..8585edc2ee4 100644 --- a/app/src/test/kotlin/com/wire/android/ui/WireActivityViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/WireActivityViewModelTest.kt @@ -465,7 +465,7 @@ class WireActivityViewModelTest { val (_, viewModel) = Arrangement() .withNoCurrentSession() .withNewClient(NewClientResult.InCurrentAccount(listOf(TestClient.CLIENT), USER_ID)) - .withCurrentScreen(MutableStateFlow(CurrentScreen.SomeOther)) + .withCurrentScreen(MutableStateFlow(CurrentScreen.SomeOther())) .arrange() assertEquals( @@ -479,7 +479,7 @@ class WireActivityViewModelTest { val (_, viewModel) = Arrangement() .withNoCurrentSession() .withNewClient(NewClientResult.InOtherAccount(listOf(TestClient.CLIENT), USER_ID, "name", "handle")) - .withCurrentScreen(MutableStateFlow(CurrentScreen.SomeOther)) + .withCurrentScreen(MutableStateFlow(CurrentScreen.SomeOther())) .arrange() assertEquals( @@ -495,7 +495,7 @@ class WireActivityViewModelTest { @Test fun `given newClient is registered when current screen does not allow dialog, then remember NewClient dialog state`() = runTest { - val currentScreenFlow = MutableStateFlow(CurrentScreen.SomeOther) + val currentScreenFlow = MutableStateFlow(CurrentScreen.SomeOther()) val newClientFlow = MutableSharedFlow() val (_, viewModel) = Arrangement() .withNoCurrentSession() @@ -513,7 +513,7 @@ class WireActivityViewModelTest { @Test fun `given newClient is registered when current screen changed to ImportMedea, then remember NewClient dialog state`() = runTest { - val currentScreenFlow = MutableStateFlow(CurrentScreen.SomeOther) + val currentScreenFlow = MutableStateFlow(CurrentScreen.SomeOther()) val (_, viewModel) = Arrangement() .withNoCurrentSession() .withNewClient(NewClientResult.InCurrentAccount(listOf(TestClient.CLIENT), USER_ID)) @@ -628,7 +628,7 @@ class WireActivityViewModelTest { every { observeScreenshotCensoringConfigUseCaseProviderFactory.create(any()).observeScreenshotCensoringConfig } returns observeScreenshotCensoringConfigUseCase coEvery { observeScreenshotCensoringConfigUseCase() } returns flowOf(ObserveScreenshotCensoringConfigResult.Disabled) - coEvery { currentScreenManager.observeCurrentScreen(any()) } returns MutableStateFlow(CurrentScreen.SomeOther) + coEvery { currentScreenManager.observeCurrentScreen(any()) } returns MutableStateFlow(CurrentScreen.SomeOther()) coEvery { globalDataStore.selectedThemeOptionFlow() } returns flowOf(ThemeOption.LIGHT) coEvery { observeIfE2EIRequiredDuringLoginUseCaseProviderFactory.create(any()).observeIfE2EIIsRequiredDuringLogin() } returns flowOf(false) diff --git a/app/src/test/kotlin/com/wire/android/ui/common/topappbar/CommonTopAppBarViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/common/topappbar/CommonTopAppBarViewModelTest.kt index 7aa65761c53..779213b8078 100644 --- a/app/src/test/kotlin/com/wire/android/ui/common/topappbar/CommonTopAppBarViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/common/topappbar/CommonTopAppBarViewModelTest.kt @@ -164,7 +164,7 @@ class CommonTopAppBarViewModelTest { .withOngoingCall(isMuted = false) .withoutOutgoingCall() .withoutIncomingCall() - .withCurrentScreen(CurrentScreen.SomeOther) + .withCurrentScreen(CurrentScreen.SomeOther()) .withSyncState(SyncState.Waiting) .arrange() diff --git a/app/src/test/kotlin/com/wire/android/ui/home/messagecomposer/recordaudio/RecordAudioViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/home/messagecomposer/recordaudio/RecordAudioViewModelTest.kt index 7b2a88c1a92..a8a9c1ee02c 100644 --- a/app/src/test/kotlin/com/wire/android/ui/home/messagecomposer/recordaudio/RecordAudioViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/home/messagecomposer/recordaudio/RecordAudioViewModelTest.kt @@ -391,9 +391,7 @@ class RecordAudioViewModelTest { coEvery { generateAudioFileWithEffects(any(), any(), any()) } returns Unit coEvery { currentScreenManager.observeCurrentScreen(any()) } returns MutableStateFlow( - CurrentScreen.Conversation( - id = DUMMY_CALL.conversationId - ) + CurrentScreen.Conversation(id = DUMMY_CALL.conversationId) ) coEvery { recordAudioMessagePlayer.audioMessageStateFlow } returns flowOf( diff --git a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerImpl.kt b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerImpl.kt index 1a0e72078d8..7e78362974f 100644 --- a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerImpl.kt +++ b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerImpl.kt @@ -170,4 +170,29 @@ object AnonymousAnalyticsManagerImpl : AnonymousAnalyticsManager { Log.w(TAG, "Calling isAnalyticsInitialized with a null recorder.") false } + + override fun recordView(screen: String) { + coroutineScope.launch { + mutex.withLock { + if (!isAnonymousUsageDataEnabled) return@withLock + anonymousAnalyticsRecorder?.recordView(screen) + } + } + } + + override fun stopView(screen: String) { + coroutineScope.launch { + mutex.withLock { + if (!isAnonymousUsageDataEnabled) return@withLock + anonymousAnalyticsRecorder?.stopView(screen) + } + } + } + + override fun applicationOnCreate() { + if (!isAnonymousUsageDataEnabled) return + + anonymousAnalyticsRecorder?.applicationOnCreate() + ?: Log.w(TAG, "Calling applicationOnCreate with a null recorder.") + } } diff --git a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt index 16e8d9e9590..78ef8edb4e4 100644 --- a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt +++ b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt @@ -18,6 +18,7 @@ package com.wire.android.feature.analytics import android.app.Activity +import android.app.Application import android.content.Context import com.wire.android.feature.analytics.model.AnalyticsEvent import com.wire.android.feature.analytics.model.AnalyticsEventConstants @@ -42,8 +43,12 @@ class AnonymousAnalyticsRecorderImpl : AnonymousAnalyticsRecorder { ) .enableTemporaryDeviceIdMode() // Nothing is sent until a proper ID is placed .setLoggingEnabled(analyticsSettings.enableDebugLogging) + countlyConfig.apm.enableAppStartTimeTracking() + countlyConfig.apm.enableForegroundBackgroundTracking() + countlyConfig.setApplication(context.applicationContext as Application) Countly.sharedInstance().init(countlyConfig) + Countly.sharedInstance().consent().giveConsent(arrayOf("apm")) val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0) val globalSegmentations = mapOf( @@ -107,4 +112,18 @@ class AnonymousAnalyticsRecorderImpl : AnonymousAnalyticsRecorder { } override fun isAnalyticsInitialized(): Boolean = Countly.sharedInstance().isInitialized + + override fun applicationOnCreate() { + if (isConfigured) return + + Countly.applicationOnCreate() + } + + override fun recordView(screen: String) { + Countly.sharedInstance().views().startAutoStoppedView(screen) + } + + override fun stopView(screen: String) { + Countly.sharedInstance().views().stopViewWithName(screen) + } } diff --git a/core/analytics-enabled/src/test/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerTest.kt b/core/analytics-enabled/src/test/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerTest.kt index ce8ede35d63..ec45685727f 100644 --- a/core/analytics-enabled/src/test/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerTest.kt +++ b/core/analytics-enabled/src/test/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerTest.kt @@ -231,7 +231,7 @@ class AnonymousAnalyticsManagerTest { advanceUntilIdle() // then - verify(exactly = 1) { + verify { arrangement.anonymousAnalyticsRecorder.onStart(activity) } } @@ -263,6 +263,98 @@ class AnonymousAnalyticsManagerTest { } } + @Test + fun givenManagerInitialized_whenRecordingView_thenScreenIsRecorded() = runTest(dispatcher) { + // given + val (arrangement, manager) = Arrangement() + .withAnonymousAnalyticsRecorderConfigure() + .arrange() + + val screen = "screen" + arrangement.withAnalyticsResult(Arrangement.existingIdentifierResult) + + // when + manager.init( + context = arrangement.context, + analyticsSettings = Arrangement.analyticsSettings, + analyticsResultFlow = arrangement.analyticsResultChannel.consumeAsFlow(), + anonymousAnalyticsRecorder = arrangement.anonymousAnalyticsRecorder, + migrationHandler = arrangement.migrationHandler, + propagationHandler = arrangement.propagationHandler, + dispatcher = dispatcher + ) + advanceUntilIdle() + + manager.recordView(screen) + advanceUntilIdle() + + // then + verify(exactly = 1) { + arrangement.anonymousAnalyticsRecorder.recordView(eq(screen)) + } + } + + @Test + fun givenManagerInitialized_whenStoppingView_thenScreenIsStoppedToRecord() = runTest(dispatcher) { + // given + val (arrangement, manager) = Arrangement() + .withAnonymousAnalyticsRecorderConfigure() + .arrange() + + val screen = "screen" + arrangement.withAnalyticsResult(Arrangement.existingIdentifierResult) + + // when + manager.init( + context = arrangement.context, + analyticsSettings = Arrangement.analyticsSettings, + analyticsResultFlow = arrangement.analyticsResultChannel.consumeAsFlow(), + anonymousAnalyticsRecorder = arrangement.anonymousAnalyticsRecorder, + migrationHandler = arrangement.migrationHandler, + propagationHandler = arrangement.propagationHandler, + dispatcher = dispatcher + ) + advanceUntilIdle() + + manager.stopView(screen) + advanceUntilIdle() + + // then + verify(exactly = 1) { + arrangement.anonymousAnalyticsRecorder.stopView(eq(screen)) + } + } + + @Test + fun givenManagerInitialized_whenApplicationCreated_thenApplicationOnCreateIsRecorded() = runTest(dispatcher) { + // given + val (arrangement, manager) = Arrangement() + .withAnonymousAnalyticsRecorderConfigure() + .arrange() + + arrangement.withAnalyticsResult(Arrangement.existingIdentifierResult) + + // when + manager.init( + context = arrangement.context, + analyticsSettings = Arrangement.analyticsSettings, + analyticsResultFlow = arrangement.analyticsResultChannel.consumeAsFlow(), + anonymousAnalyticsRecorder = arrangement.anonymousAnalyticsRecorder, + migrationHandler = arrangement.migrationHandler, + propagationHandler = arrangement.propagationHandler, + dispatcher = dispatcher + ) + advanceUntilIdle() + + manager.applicationOnCreate() + advanceUntilIdle() + + // then + verify(exactly = 1) { + arrangement.anonymousAnalyticsRecorder.applicationOnCreate() + } + } + private class Arrangement { @MockK lateinit var context: Context @@ -284,6 +376,9 @@ class AnonymousAnalyticsManagerTest { every { anonymousAnalyticsRecorder.onStop() } returns Unit every { anonymousAnalyticsRecorder.onStart(any()) } returns Unit every { anonymousAnalyticsRecorder.sendEvent(any()) } returns Unit + every { anonymousAnalyticsRecorder.recordView(any()) } returns Unit + every { anonymousAnalyticsRecorder.stopView(any()) } returns Unit + every { anonymousAnalyticsRecorder.applicationOnCreate() } returns Unit coEvery { anonymousAnalyticsRecorder.setTrackingIdentifierWithMerge(any(), any(), any()) } returns Unit coEvery { anonymousAnalyticsRecorder.setTrackingIdentifierWithoutMerge(any(), any(), any(), any()) } returns Unit } diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManager.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManager.kt index f58a956032e..bc45d4b3335 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManager.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManager.kt @@ -48,5 +48,11 @@ interface AnonymousAnalyticsManager { fun onStop(activity: Activity) + fun applicationOnCreate() + fun isAnalyticsInitialized(): Boolean + + fun recordView(screen: String) + + fun stopView(screen: String) } diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerStub.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerStub.kt index 83734370994..d7bfd09158f 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerStub.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerStub.kt @@ -45,5 +45,9 @@ open class AnonymousAnalyticsManagerStub : AnonymousAnalyticsManager { override fun onStop(activity: Activity) = Unit + override fun applicationOnCreate() = Unit + override fun isAnalyticsInitialized(): Boolean = false + override fun recordView(screen: String) = Unit + override fun stopView(screen: String) = Unit } diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorder.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorder.kt index 80c226d3221..db193e0dd09 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorder.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorder.kt @@ -50,4 +50,10 @@ interface AnonymousAnalyticsRecorder { ) fun isAnalyticsInitialized(): Boolean + + fun applicationOnCreate() + + fun recordView(screen: String) + + fun stopView(screen: String) } diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderStub.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderStub.kt index c4fae9fd2cf..a60ed0fc44d 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderStub.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderStub.kt @@ -47,4 +47,7 @@ open class AnonymousAnalyticsRecorderStub : AnonymousAnalyticsRecorder { ) = Unit override fun isAnalyticsInitialized(): Boolean = false + override fun applicationOnCreate() = Unit + override fun recordView(screen: String) = Unit + override fun stopView(screen: String) = Unit }