From 2e42cca719ecd0d9db90c020798fa3eb1b6122de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Tue, 17 Dec 2024 13:11:13 +0100 Subject: [PATCH 1/5] feat: Track ended call [#WPB-14256] --- .../android/di/accountScoped/CallsModule.kt | 5 ++ .../wire/android/ui/WireActivityViewModel.kt | 15 ++++ .../ui/debug/DebugDataOptionsViewModel.kt | 4 + .../feature/analytics/model/AnalyticsEvent.kt | 79 ++++++++++++++++++- kalium | 2 +- 5 files changed, 102 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/di/accountScoped/CallsModule.kt b/app/src/main/kotlin/com/wire/android/di/accountScoped/CallsModule.kt index 803e627db87..c0b3481852c 100644 --- a/app/src/main/kotlin/com/wire/android/di/accountScoped/CallsModule.kt +++ b/app/src/main/kotlin/com/wire/android/di/accountScoped/CallsModule.kt @@ -202,4 +202,9 @@ class CallsModule { @Provides fun provideObserveConferenceCallingEnabledUseCase(callsScope: CallsScope) = callsScope.observeConferenceCallingEnabled + + @ViewModelScoped + @Provides + fun provideObserveRecentlyEndedCallMetadataUseCase(callsScope: CallsScope) = + callsScope.observeRecentlyEndedCallMetadata } 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 fc173d079cb..faff8803843 100644 --- a/app/src/main/kotlin/com/wire/android/ui/WireActivityViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/WireActivityViewModel.kt @@ -37,6 +37,8 @@ import com.wire.android.feature.AccountSwitchUseCase import com.wire.android.feature.SwitchAccountActions import com.wire.android.feature.SwitchAccountParam import com.wire.android.feature.SwitchAccountResult +import com.wire.android.feature.analytics.AnonymousAnalyticsManager +import com.wire.android.feature.analytics.model.AnalyticsEvent import com.wire.android.migration.MigrationManager import com.wire.android.services.ServicesManager import com.wire.android.ui.authentication.devices.model.displayName @@ -62,6 +64,7 @@ import com.wire.kalium.logic.data.logout.LogoutReason import com.wire.kalium.logic.data.sync.SyncState import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.appVersioning.ObserveIfAppUpdateRequiredUseCase +import com.wire.kalium.logic.feature.call.usecase.ObserveRecentlyEndedCallMetadataUseCase import com.wire.kalium.logic.feature.client.ClearNewClientsForUserUseCase import com.wire.kalium.logic.feature.client.NewClientResult import com.wire.kalium.logic.feature.client.ObserveNewClientsUseCase @@ -122,6 +125,8 @@ class WireActivityViewModel @Inject constructor( private val globalDataStore: Lazy, private val observeIfE2EIRequiredDuringLoginUseCaseProviderFactory: ObserveIfE2EIRequiredDuringLoginUseCaseProvider.Factory, private val workManager: Lazy, + private val observeRecentlyEndedCallMetadata: ObserveRecentlyEndedCallMetadataUseCase, + private val analyticsManager: AnonymousAnalyticsManager ) : ViewModel() { var globalAppState: GlobalAppState by mutableStateOf(GlobalAppState()) @@ -151,6 +156,16 @@ class WireActivityViewModel @Inject constructor( observeScreenshotCensoringConfigState() observeAppThemeState() observeLogoutState() + trackRecentlyEndedCall() + } + + private fun trackRecentlyEndedCall() { + viewModelScope.launch { + observeRecentlyEndedCallMetadata() + .collect { metadata -> + analyticsManager.sendEvent(AnalyticsEvent.RecentlyEndedCallEvent(metadata)) + } + } } private suspend fun shouldEnrollToE2ei(): Boolean = observeCurrentValidUserId.first()?.let { diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt index e98c20eb903..0ab26a09b8b 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt @@ -304,6 +304,10 @@ class DebugDataOptionsViewModelImpl } is MLSKeyPackageCountResult.Failure.Generic -> {} + + MLSKeyPackageCountResult.Failure.NotEnabled -> { + // TODO + } } } } diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt index b08eb4585b5..086bf658f29 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt @@ -17,6 +17,21 @@ */ package com.wire.android.feature.analytics.model +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_AV_SWITCH_TOGGLE +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CALL_DIRECTION +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CALL_DURATION +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CALL_PARTICIPANTS +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CALL_SCREEN_SHARE +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CALL_VIDEO +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CONVERSATION_GUESTS +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CONVERSATION_GUESTS_PRO +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CONVERSATION_SERVICES +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CONVERSATION_SIZE +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CONVERSATION_TYPE +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_END_REASON +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_IS_TEAM_MEMBER +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_UNIQUE_SCREEN_SHARE import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_QUALITY_REVIEW_IGNORE_REASON import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_QUALITY_REVIEW_IGNORE_REASON_KEY import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_QUALITY_REVIEW_LABEL_ANSWERED @@ -29,8 +44,6 @@ import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CLICKED_ import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CLICKED_PERSONAL_MIGRATION_CTA_EVENT import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CONTRIBUTED_LOCATION import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MESSAGE_ACTION_KEY -import com.wire.android.feature.analytics.model.AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE_PERSONAL -import com.wire.android.feature.analytics.model.AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE_TEAM import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MIGRATION_DOT_ACTIVE import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_BACK_TO_WIRE_CLICKED import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_CONTINUE_CLICKED @@ -40,8 +53,12 @@ import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_TE import com.wire.android.feature.analytics.model.AnalyticsEventConstants.PERSONAL_TEAM_CREATION_FLOW_CANCELLED import com.wire.android.feature.analytics.model.AnalyticsEventConstants.PERSONAL_TEAM_CREATION_FLOW_COMPLETED import com.wire.android.feature.analytics.model.AnalyticsEventConstants.PERSONAL_TEAM_CREATION_FLOW_STARTED_EVENT +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE_PERSONAL +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE_TEAM import com.wire.android.feature.analytics.model.AnalyticsEventConstants.STEP_MODAL_CREATE_TEAM import com.wire.android.feature.analytics.model.AnalyticsEventConstants.USER_PROFILE_OPENED +import com.wire.kalium.logic.data.call.RecentlyEndedCallMetadata +import com.wire.kalium.logic.data.conversation.Conversation interface AnalyticsEvent { /** @@ -129,6 +146,45 @@ interface AnalyticsEvent { } } + data class RecentlyEndedCallEvent(val metadata: RecentlyEndedCallMetadata) : AnalyticsEvent { + override val key: String = CALLING_ENDED + + override fun toSegmentation(): Map { + return mapOf( + CALLING_ENDED_IS_TEAM_MEMBER to metadata.isTeamMember, + CALLING_ENDED_CALL_SCREEN_SHARE to metadata.callDetails.screenShareDurationInSeconds, + CALLING_ENDED_UNIQUE_SCREEN_SHARE to metadata.callDetails.callScreenShareUniques, + CALLING_ENDED_CALL_DIRECTION to metadata.toCallDirection(), + CALLING_ENDED_CALL_DURATION to metadata.callDetails.callDurationInSeconds, + CALLING_ENDED_CONVERSATION_TYPE to metadata.toConversationType(), + CALLING_ENDED_CONVERSATION_SIZE to metadata.conversationDetails.conversationSize, + CALLING_ENDED_CONVERSATION_GUESTS to metadata.conversationDetails.conversationGuests, + CALLING_ENDED_CONVERSATION_GUESTS_PRO to metadata.conversationDetails.conversationGuestsPro, + CALLING_ENDED_CALL_PARTICIPANTS to metadata.callDetails.callParticipantsCount, + CALLING_ENDED_END_REASON to metadata.callEndReason, + CALLING_ENDED_CONVERSATION_SERVICES to metadata.callDetails.conversationServices, + CALLING_ENDED_AV_SWITCH_TOGGLE to metadata.callDetails.callAVSwitchToggle, + CALLING_ENDED_CALL_VIDEO to metadata.callDetails.callVideoEnabled, + ) + } + + private fun RecentlyEndedCallMetadata.toCallDirection(): String { + return if (callDetails.isOutgoingCall) { + "outgoing" + } else { + "incoming" + } + } + + private fun RecentlyEndedCallMetadata.toConversationType(): String { + return when (conversationDetails.conversationType) { + Conversation.Type.ONE_ON_ONE -> "one_to_one" + Conversation.Type.GROUP -> "group" + else -> "unknown" + } + } + } + /** * Backup */ @@ -336,6 +392,7 @@ object AnalyticsEventConstants { */ const val CALLING_INITIATED = "calling.initiated_call" const val CALLING_JOINED = "calling.joined_call" + const val CALLING_ENDED = "calling.ended_call" const val CALLING_QUALITY_REVIEW = "calling.call_quality_review" const val CALLING_QUALITY_REVIEW_LABEL_KEY = "label" @@ -346,6 +403,24 @@ object AnalyticsEventConstants { const val CALLING_QUALITY_REVIEW_IGNORE_REASON_KEY = "ignore-reason" const val CALLING_QUALITY_REVIEW_IGNORE_REASON = "muted" + /** + * Call ended + */ + const val CALLING_ENDED_IS_TEAM_MEMBER = "is_team_member" + const val CALLING_ENDED_CALL_SCREEN_SHARE = "call_screen_share_duration" + const val CALLING_ENDED_UNIQUE_SCREEN_SHARE = "call_screen_share_unique" + const val CALLING_ENDED_CALL_DIRECTION = "call_direction" + const val CALLING_ENDED_CALL_DURATION = "call_duration" + const val CALLING_ENDED_CONVERSATION_TYPE = "conversation_type" + const val CALLING_ENDED_CONVERSATION_SIZE = "conversation_size" + const val CALLING_ENDED_CONVERSATION_GUESTS = "conversation_guests" + const val CALLING_ENDED_CONVERSATION_GUESTS_PRO = "conversation_guest_pro" + const val CALLING_ENDED_CALL_PARTICIPANTS = "call_participants" + const val CALLING_ENDED_END_REASON = "call_end_reason" + const val CALLING_ENDED_CONVERSATION_SERVICES = "conversation_services" + const val CALLING_ENDED_AV_SWITCH_TOGGLE = "call_av_switch_toggle" + const val CALLING_ENDED_CALL_VIDEO = "call_video" + /** * Backup */ diff --git a/kalium b/kalium index 0667f9b780a..1ca6dfc988e 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit 0667f9b780a8262768b0c37af3d49d4f83c55701 +Subproject commit 1ca6dfc988eeccf550858620ae1dadf8e49555da From 8e7ad41a6598e72a3ba33af826178937b7faa651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Wed, 18 Dec 2024 10:52:02 +0100 Subject: [PATCH 2/5] Update kalium --- kalium | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kalium b/kalium index 1ca6dfc988e..91b8319e99d 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit 1ca6dfc988eeccf550858620ae1dadf8e49555da +Subproject commit 91b8319e99d83e486751967c8adf4f027d57a82e From 5530df1423c83eda42ffd39f496bc9bbdfb900e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Wed, 18 Dec 2024 11:38:19 +0100 Subject: [PATCH 3/5] Fix tests --- .../android/ui/WireActivityViewModelTest.kt | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) 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 f7070a642bf..c3f22e31920 100644 --- a/app/src/test/kotlin/com/wire/android/ui/WireActivityViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/WireActivityViewModelTest.kt @@ -33,6 +33,7 @@ import com.wire.android.di.ObserveIfE2EIRequiredDuringLoginUseCaseProvider import com.wire.android.di.ObserveScreenshotCensoringConfigUseCaseProvider import com.wire.android.di.ObserveSyncStateUseCaseProvider import com.wire.android.feature.AccountSwitchUseCase +import com.wire.android.feature.analytics.AnonymousAnalyticsManager import com.wire.android.framework.TestClient import com.wire.android.framework.TestUser import com.wire.android.migration.MigrationManager @@ -53,6 +54,7 @@ import com.wire.kalium.logic.data.auth.AccountInfo import com.wire.kalium.logic.data.auth.PersistentWebSocketStatus import com.wire.kalium.logic.data.call.Call import com.wire.kalium.logic.data.call.CallStatus +import com.wire.kalium.logic.data.call.RecentlyEndedCallMetadata import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.id.QualifiedID @@ -61,6 +63,7 @@ import com.wire.kalium.logic.data.sync.SyncState import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.appVersioning.ObserveIfAppUpdateRequiredUseCase import com.wire.kalium.logic.feature.call.usecase.ObserveEstablishedCallsUseCase +import com.wire.kalium.logic.feature.call.usecase.ObserveRecentlyEndedCallMetadataUseCase import com.wire.kalium.logic.feature.client.ClearNewClientsForUserUseCase import com.wire.kalium.logic.feature.client.NewClientResult import com.wire.kalium.logic.feature.client.ObserveNewClientsUseCase @@ -729,6 +732,7 @@ class WireActivityViewModelTest { flowOf(false) every { workManager.cancelAllWorkByTag(any()) } returns OperationImpl() every { workManager.enqueueUniquePeriodicWork(any(), any(), any()) } returns OperationImpl() + coEvery { observeRecentlyEndedCallMetadata() } returns flowOf(recentlyEndedCallMetadata) } @MockK @@ -793,6 +797,12 @@ class WireActivityViewModelTest { @MockK lateinit var workManager: WorkManager + @MockK + lateinit var observeRecentlyEndedCallMetadata: ObserveRecentlyEndedCallMetadataUseCase + + @MockK + lateinit var analyticsManager: AnonymousAnalyticsManager + @MockK lateinit var observeEstablishedCalls: ObserveEstablishedCallsUseCase @@ -826,7 +836,9 @@ class WireActivityViewModelTest { observeScreenshotCensoringConfigUseCaseProviderFactory = observeScreenshotCensoringConfigUseCaseProviderFactory, globalDataStore = { globalDataStore }, observeIfE2EIRequiredDuringLoginUseCaseProviderFactory = observeIfE2EIRequiredDuringLoginUseCaseProviderFactory, - workManager = { workManager } + workManager = { workManager }, + observeRecentlyEndedCallMetadata = observeRecentlyEndedCallMetadata, + analyticsManager = analyticsManager ) } @@ -974,6 +986,28 @@ class WireActivityViewModelTest { callerTeamName = "team1" ) + val recentlyEndedCallMetadata = RecentlyEndedCallMetadata( + callEndReason = 1, + callDetails = RecentlyEndedCallMetadata.CallDetails( + isCallScreenShare = false, + screenShareDurationInSeconds = 20L, + callScreenShareUniques = 5, + isOutgoingCall = true, + callDurationInSeconds = 100L, + callParticipantsCount = 5, + conversationServices = 1, + callAVSwitchToggle = false, + callVideoEnabled = false + ), + conversationDetails = RecentlyEndedCallMetadata.ConversationDetails( + conversationType = Conversation.Type.ONE_ON_ONE, + conversationSize = 5, + conversationGuests = 2, + conversationGuestsPro = 1 + ), + isTeamMember = true + ) + fun invalidAccountInfo(logoutReason: LogoutReason): AccountInfo.Invalid = AccountInfo.Invalid(USER_ID, logoutReason) } } From 2565ffb968d9c9482ee26e0e587827d0a4dc3ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Thu, 19 Dec 2024 10:51:50 +0100 Subject: [PATCH 4/5] Code review --- .../com/wire/android/WireApplication.kt | 19 +++++++++++++++++++ .../android/di/accountScoped/CallsModule.kt | 9 ++------- .../wire/android/ui/WireActivityViewModel.kt | 17 +---------------- .../android/ui/WireActivityViewModelTest.kt | 13 +------------ .../feature/analytics/model/AnalyticsEvent.kt | 2 +- 5 files changed, 24 insertions(+), 36 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/WireApplication.kt b/app/src/main/kotlin/com/wire/android/WireApplication.kt index d67de8e4c97..d55717eea4f 100644 --- a/app/src/main/kotlin/com/wire/android/WireApplication.kt +++ b/app/src/main/kotlin/com/wire/android/WireApplication.kt @@ -32,6 +32,7 @@ import com.wire.android.datastore.UserDataStoreProvider import com.wire.android.debug.DatabaseProfilingManager import com.wire.android.di.ApplicationScope import com.wire.android.di.KaliumCoreLogic +import com.wire.android.feature.analytics.AnonymousAnalyticsManager import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl import com.wire.android.feature.analytics.AnonymousAnalyticsRecorderImpl import com.wire.android.feature.analytics.globalAnalyticsManager @@ -48,10 +49,12 @@ import com.wire.kalium.logger.KaliumLogLevel import com.wire.kalium.logger.KaliumLogger import com.wire.kalium.logic.CoreLogger import com.wire.kalium.logic.CoreLogic +import com.wire.kalium.logic.feature.session.CurrentSessionResult import dagger.Lazy import dagger.hilt.android.HiltAndroidApp import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch @@ -93,6 +96,9 @@ class WireApplication : BaseApp() { @Inject lateinit var databaseProfilingManager: DatabaseProfilingManager + @Inject + lateinit var analyticsManager: Lazy + override val workManagerConfiguration: Configuration get() = Configuration.Builder() .setWorkerFactory(wireWorkerFactory.get()) @@ -121,6 +127,19 @@ class WireApplication : BaseApp() { appLogger.i("$TAG global observers") globalObserversManager.get().observe() + + observeRecentlyEndedCall() + } + } + + private suspend fun observeRecentlyEndedCall() { + coreLogic.get().getGlobalScope().session.currentSessionFlow().collectLatest { sessionResult -> + if (sessionResult is CurrentSessionResult.Success && sessionResult.accountInfo.isValid()) { + coreLogic.get().getSessionScope(sessionResult.accountInfo.userId).calls.observeRecentlyEndedCallMetadata() + .collect { metadata -> + analyticsManager.get().sendEvent(AnalyticsEvent.RecentlyEndedCallEvent(metadata)) + } + } } } diff --git a/app/src/main/kotlin/com/wire/android/di/accountScoped/CallsModule.kt b/app/src/main/kotlin/com/wire/android/di/accountScoped/CallsModule.kt index c0b3481852c..99d5a287ad4 100644 --- a/app/src/main/kotlin/com/wire/android/di/accountScoped/CallsModule.kt +++ b/app/src/main/kotlin/com/wire/android/di/accountScoped/CallsModule.kt @@ -19,8 +19,6 @@ package com.wire.android.di.accountScoped import com.wire.android.di.CurrentAccount import com.wire.android.di.KaliumCoreLogic -import dagger.Module -import dagger.Provides import com.wire.kalium.logic.CoreLogic import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.call.CallsScope @@ -40,6 +38,8 @@ import com.wire.kalium.logic.feature.call.usecase.TurnLoudSpeakerOnUseCase import com.wire.kalium.logic.feature.call.usecase.UnMuteCallUseCase import com.wire.kalium.logic.feature.call.usecase.video.SetVideoSendStateUseCase import com.wire.kalium.logic.feature.call.usecase.video.UpdateVideoStateUseCase +import dagger.Module +import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.components.ViewModelComponent import dagger.hilt.android.scopes.ViewModelScoped @@ -202,9 +202,4 @@ class CallsModule { @Provides fun provideObserveConferenceCallingEnabledUseCase(callsScope: CallsScope) = callsScope.observeConferenceCallingEnabled - - @ViewModelScoped - @Provides - fun provideObserveRecentlyEndedCallMetadataUseCase(callsScope: CallsScope) = - callsScope.observeRecentlyEndedCallMetadata } 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 faff8803843..ddcf9d3f0b4 100644 --- a/app/src/main/kotlin/com/wire/android/ui/WireActivityViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/WireActivityViewModel.kt @@ -37,8 +37,6 @@ import com.wire.android.feature.AccountSwitchUseCase import com.wire.android.feature.SwitchAccountActions import com.wire.android.feature.SwitchAccountParam import com.wire.android.feature.SwitchAccountResult -import com.wire.android.feature.analytics.AnonymousAnalyticsManager -import com.wire.android.feature.analytics.model.AnalyticsEvent import com.wire.android.migration.MigrationManager import com.wire.android.services.ServicesManager import com.wire.android.ui.authentication.devices.model.displayName @@ -64,7 +62,6 @@ import com.wire.kalium.logic.data.logout.LogoutReason import com.wire.kalium.logic.data.sync.SyncState import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.appVersioning.ObserveIfAppUpdateRequiredUseCase -import com.wire.kalium.logic.feature.call.usecase.ObserveRecentlyEndedCallMetadataUseCase import com.wire.kalium.logic.feature.client.ClearNewClientsForUserUseCase import com.wire.kalium.logic.feature.client.NewClientResult import com.wire.kalium.logic.feature.client.ObserveNewClientsUseCase @@ -124,9 +121,7 @@ class WireActivityViewModel @Inject constructor( private val observeScreenshotCensoringConfigUseCaseProviderFactory: ObserveScreenshotCensoringConfigUseCaseProvider.Factory, private val globalDataStore: Lazy, private val observeIfE2EIRequiredDuringLoginUseCaseProviderFactory: ObserveIfE2EIRequiredDuringLoginUseCaseProvider.Factory, - private val workManager: Lazy, - private val observeRecentlyEndedCallMetadata: ObserveRecentlyEndedCallMetadataUseCase, - private val analyticsManager: AnonymousAnalyticsManager + private val workManager: Lazy ) : ViewModel() { var globalAppState: GlobalAppState by mutableStateOf(GlobalAppState()) @@ -156,16 +151,6 @@ class WireActivityViewModel @Inject constructor( observeScreenshotCensoringConfigState() observeAppThemeState() observeLogoutState() - trackRecentlyEndedCall() - } - - private fun trackRecentlyEndedCall() { - viewModelScope.launch { - observeRecentlyEndedCallMetadata() - .collect { metadata -> - analyticsManager.sendEvent(AnalyticsEvent.RecentlyEndedCallEvent(metadata)) - } - } } private suspend fun shouldEnrollToE2ei(): Boolean = observeCurrentValidUserId.first()?.let { 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 c3f22e31920..c2744f0635f 100644 --- a/app/src/test/kotlin/com/wire/android/ui/WireActivityViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/WireActivityViewModelTest.kt @@ -33,7 +33,6 @@ import com.wire.android.di.ObserveIfE2EIRequiredDuringLoginUseCaseProvider import com.wire.android.di.ObserveScreenshotCensoringConfigUseCaseProvider import com.wire.android.di.ObserveSyncStateUseCaseProvider import com.wire.android.feature.AccountSwitchUseCase -import com.wire.android.feature.analytics.AnonymousAnalyticsManager import com.wire.android.framework.TestClient import com.wire.android.framework.TestUser import com.wire.android.migration.MigrationManager @@ -63,7 +62,6 @@ import com.wire.kalium.logic.data.sync.SyncState import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.appVersioning.ObserveIfAppUpdateRequiredUseCase import com.wire.kalium.logic.feature.call.usecase.ObserveEstablishedCallsUseCase -import com.wire.kalium.logic.feature.call.usecase.ObserveRecentlyEndedCallMetadataUseCase import com.wire.kalium.logic.feature.client.ClearNewClientsForUserUseCase import com.wire.kalium.logic.feature.client.NewClientResult import com.wire.kalium.logic.feature.client.ObserveNewClientsUseCase @@ -732,7 +730,6 @@ class WireActivityViewModelTest { flowOf(false) every { workManager.cancelAllWorkByTag(any()) } returns OperationImpl() every { workManager.enqueueUniquePeriodicWork(any(), any(), any()) } returns OperationImpl() - coEvery { observeRecentlyEndedCallMetadata() } returns flowOf(recentlyEndedCallMetadata) } @MockK @@ -797,12 +794,6 @@ class WireActivityViewModelTest { @MockK lateinit var workManager: WorkManager - @MockK - lateinit var observeRecentlyEndedCallMetadata: ObserveRecentlyEndedCallMetadataUseCase - - @MockK - lateinit var analyticsManager: AnonymousAnalyticsManager - @MockK lateinit var observeEstablishedCalls: ObserveEstablishedCallsUseCase @@ -836,9 +827,7 @@ class WireActivityViewModelTest { observeScreenshotCensoringConfigUseCaseProviderFactory = observeScreenshotCensoringConfigUseCaseProviderFactory, globalDataStore = { globalDataStore }, observeIfE2EIRequiredDuringLoginUseCaseProviderFactory = observeIfE2EIRequiredDuringLoginUseCaseProviderFactory, - workManager = { workManager }, - observeRecentlyEndedCallMetadata = observeRecentlyEndedCallMetadata, - analyticsManager = analyticsManager + workManager = { workManager } ) } diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt index 086bf658f29..b133c02d172 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt @@ -180,7 +180,7 @@ interface AnalyticsEvent { return when (conversationDetails.conversationType) { Conversation.Type.ONE_ON_ONE -> "one_to_one" Conversation.Type.GROUP -> "group" - else -> "unknown" + else -> throw IllegalStateException("Call should not happen for ${conversationDetails.conversationType}") } } } From 96f3e6785330a42b883d4cac49c8100d44933f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Fri, 20 Dec 2024 15:55:21 +0100 Subject: [PATCH 5/5] Code review --- .../kotlin/com/wire/android/WireApplication.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/WireApplication.kt b/app/src/main/kotlin/com/wire/android/WireApplication.kt index d55717eea4f..58ed10c4a55 100644 --- a/app/src/main/kotlin/com/wire/android/WireApplication.kt +++ b/app/src/main/kotlin/com/wire/android/WireApplication.kt @@ -54,9 +54,10 @@ import dagger.Lazy import dagger.hilt.android.HiltAndroidApp import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import javax.inject.Inject @@ -133,14 +134,14 @@ class WireApplication : BaseApp() { } private suspend fun observeRecentlyEndedCall() { - coreLogic.get().getGlobalScope().session.currentSessionFlow().collectLatest { sessionResult -> - if (sessionResult is CurrentSessionResult.Success && sessionResult.accountInfo.isValid()) { - coreLogic.get().getSessionScope(sessionResult.accountInfo.userId).calls.observeRecentlyEndedCallMetadata() - .collect { metadata -> - analyticsManager.get().sendEvent(AnalyticsEvent.RecentlyEndedCallEvent(metadata)) - } + coreLogic.get().getGlobalScope().session.currentSessionFlow().filterIsInstance(CurrentSessionResult.Success::class) + .filter { session -> session.accountInfo.isValid() } + .flatMapLatest { session -> + coreLogic.get().getSessionScope(session.accountInfo.userId).calls.observeRecentlyEndedCallMetadata() + } + .collect { metadata -> + analyticsManager.get().sendEvent(AnalyticsEvent.RecentlyEndedCallEvent(metadata)) } - } } private fun enableStrictMode() {