Skip to content

Commit

Permalink
feat: add analytics initial events (WPB-10589) 🍒 (#3436)
Browse files Browse the repository at this point in the history
Signed-off-by: alexandreferris <[email protected]>
Co-authored-by: Yamil Medina <[email protected]>
Co-authored-by: Alexandre Ferris <[email protected]>
  • Loading branch information
3 people authored Sep 12, 2024
1 parent 0be7bbe commit 458be14
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 19 deletions.
5 changes: 5 additions & 0 deletions app/src/main/kotlin/com/wire/android/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import android.media.AudioAttributes
import android.media.MediaPlayer
import androidx.core.app.NotificationManagerCompat
import com.wire.android.BuildConfig
import com.wire.android.feature.analytics.AnonymousAnalyticsManager
import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl
import com.wire.android.mapper.MessageResourceProvider
import com.wire.android.ui.analytics.AnalyticsConfiguration
import com.wire.android.ui.home.appLock.CurrentTimestampProvider
Expand Down Expand Up @@ -95,4 +97,7 @@ object AppModule {
@Provides
fun provideAnalyticsConfiguration() =
if (BuildConfig.ANALYTICS_ENABLED) AnalyticsConfiguration.Enabled else AnalyticsConfiguration.Disabled

@Provides
fun provideAnonymousAnalyticsManager(): AnonymousAnalyticsManager = AnonymousAnalyticsManagerImpl
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ import com.wire.android.appLogger
import com.wire.android.feature.sketch.destinations.DrawingCanvasScreenDestination
import com.wire.android.feature.sketch.model.DrawingCanvasNavArgs
import com.wire.android.feature.sketch.model.DrawingCanvasNavBackArgs
import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl
import com.wire.android.feature.analytics.model.AnalyticsEvent
import com.wire.android.mapper.MessageDateTimeGroup
import com.wire.android.media.audiomessage.AudioState
import com.wire.android.model.Clickable
Expand Down Expand Up @@ -309,6 +311,7 @@ fun ConversationScreen(
getOngoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.CallJoined())
}
}
)
Expand All @@ -322,6 +325,7 @@ fun ConversationScreen(
getOutgoingCallIntent(activity, conversationListCallViewModel.conversationId.toString()).run {
activity.startActivity(this)
}
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.CallJoined())
}
showDialog.value = ConversationScreenDialogType.NONE
}, onDialogDismiss = {
Expand All @@ -348,12 +352,13 @@ fun ConversationScreen(
getOutgoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
},
onOpenOngoingCallScreen = {
getOngoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
}
) {
getOngoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
}
)
},
onDialogDismiss = {
showDialog.value = ConversationScreenDialogType.NONE
Expand Down Expand Up @@ -393,12 +398,13 @@ fun ConversationScreen(
getOutgoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
},
onOpenOngoingCallScreen = {
getOngoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
}
) {
getOngoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
}
)
},
onDialogDismiss = { showDialog.value = ConversationScreenDialogType.NONE }
)
Expand Down Expand Up @@ -477,15 +483,17 @@ fun ConversationScreen(
getOutgoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
},
onOpenOngoingCallScreen = {
getOngoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
}
) {
getOngoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
}
)
},
onJoinCall = {
conversationListCallViewModel.joinOngoingCall {
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.CallJoined())
getOngoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
Expand Down Expand Up @@ -743,13 +751,15 @@ private fun startCallIfPossible(
} else {
conversationListCallViewModel.endEstablishedCallIfAny {
onOpenOutgoingCallScreen(conversationListCallViewModel.conversationId)
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.CallInitiated())
}
ConversationScreenDialogType.NONE
}
}

ConferenceCallingResult.Disabled.Established -> {
onOpenOngoingCallScreen(conversationListCallViewModel.conversationId)
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.CallJoined())
ConversationScreenDialogType.NONE
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.wire.android.R
import com.wire.android.appLogger
import com.wire.android.feature.analytics.AnonymousAnalyticsManager
import com.wire.android.feature.analytics.model.AnalyticsEvent
import com.wire.android.media.PingRinger
import com.wire.android.model.SnackBarMessage
import com.wire.android.navigation.SavedStateViewModel
Expand Down Expand Up @@ -65,6 +67,7 @@ import com.wire.kalium.logic.feature.message.SendTextMessageUseCase
import com.wire.kalium.logic.feature.message.draft.RemoveMessageDraftUseCase
import com.wire.kalium.logic.functional.Either
import com.wire.kalium.logic.functional.onFailure
import com.wire.kalium.logic.functional.onSuccess
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableSharedFlow
Expand Down Expand Up @@ -96,6 +99,7 @@ class SendMessageViewModel @Inject constructor(
private val observeConversationUnderLegalHoldNotified: ObserveConversationUnderLegalHoldNotifiedUseCase,
private val sendLocation: SendLocationUseCase,
private val removeMessageDraft: RemoveMessageDraftUseCase,
private val analyticsManager: AnonymousAnalyticsManager
) : SavedStateViewModel(savedStateHandle) {

private val conversationNavArgs: ConversationNavArgs = savedStateHandle.navArgs()
Expand Down Expand Up @@ -199,6 +203,7 @@ class SendMessageViewModel @Inject constructor(
mentions = newMentions.map { it.intoMessageMention() },
)
.handleLegalHoldFailureAfterSendingMessage(conversationId)
.handleNonAssetContributionEvent(messageBundle)
}
}

Expand Down Expand Up @@ -231,20 +236,23 @@ class SendMessageViewModel @Inject constructor(
quotedMessageId = quotedMessageId
)
.handleLegalHoldFailureAfterSendingMessage(conversationId)
.handleNonAssetContributionEvent(messageBundle)
}
}

is ComposableMessageBundle.LocationBundle -> {
with(messageBundle) {
sendLocation(conversationId, location.latitude.toFloat(), location.longitude.toFloat(), locationName, zoom)
.handleLegalHoldFailureAfterSendingMessage(conversationId)
.handleNonAssetContributionEvent(messageBundle)
}
}

is Ping -> {
pingRinger.ping(R.raw.ping_from_me, isReceivingPing = false)
sendKnock(conversationId = messageBundle.conversationId, hotKnock = false)
.handleLegalHoldFailureAfterSendingMessage(messageBundle.conversationId)
.handleNonAssetContributionEvent(messageBundle)
}
}
}
Expand Down Expand Up @@ -297,6 +305,7 @@ class SendMessageViewModel @Inject constructor(
audioLengthInMs = 0L
)
.handleLegalHoldFailureAfterSendingMessage(conversationId)
.handleAssetContributionEvent(assetType)
}

AttachmentType.VIDEO,
Expand All @@ -317,6 +326,7 @@ class SendMessageViewModel @Inject constructor(
)
)
.handleLegalHoldFailureAfterSendingMessage(conversationId)
.handleAssetContributionEvent(assetType)
} catch (e: OutOfMemoryError) {
appLogger.e("There was an OutOfMemory error while uploading the asset")
onSnackbarMessage(ConversationSnackbarMessages.ErrorSendingAsset)
Expand All @@ -328,6 +338,37 @@ class SendMessageViewModel @Inject constructor(
}
}

private fun Either<CoreFailure?, Unit>.handleAssetContributionEvent(
assetType: AttachmentType
) = also {
onSuccess {
val event = when (assetType) {
AttachmentType.IMAGE -> AnalyticsEvent.Contributed.Photo()
AttachmentType.VIDEO -> AnalyticsEvent.Contributed.Video()
AttachmentType.GENERIC_FILE -> AnalyticsEvent.Contributed.File()
AttachmentType.AUDIO -> AnalyticsEvent.Contributed.Audio()
}
analyticsManager.sendEvent(event)
}
}

private fun Either<CoreFailure, Unit>.handleNonAssetContributionEvent(messageBundle: MessageBundle) = also {
onSuccess {
val event = when (messageBundle) {
// assets are not handled here, as they need extra processing
is ComposableMessageBundle.UriPickedBundle,
is ComposableMessageBundle.AudioMessageBundle,
is ComposableMessageBundle.AttachmentPickedBundle -> return@also

is ComposableMessageBundle.LocationBundle -> AnalyticsEvent.Contributed.Location()
is Ping -> AnalyticsEvent.Contributed.Ping()
is ComposableMessageBundle.EditMessageBundle,
is ComposableMessageBundle.SendTextMessageBundle -> AnalyticsEvent.Contributed.Text()
}
analyticsManager.sendEvent(event)
}
}

private fun CoreFailure.handleLegalHoldFailureAfterSendingMessage(conversationId: ConversationId) = also {
if (this is LegalHoldEnabledForConversationFailure) {
sureAboutMessagingDialogState = when (val currentState = sureAboutMessagingDialogState) {
Expand Down Expand Up @@ -419,6 +460,7 @@ class SendMessageViewModel @Inject constructor(
}
sureAboutMessagingDialogState = SureAboutMessagingDialogState.Hidden
}

private companion object {
const val MAX_LIMIT_MESSAGE_SEND = 20
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.hilt.navigation.compose.hiltViewModel
import com.wire.android.R
import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl
import com.wire.android.feature.analytics.model.AnalyticsEvent
import com.wire.android.navigation.NavigationCommand
import com.wire.android.navigation.Navigator
import com.wire.android.ui.LocalActivity
Expand Down Expand Up @@ -151,6 +153,7 @@ fun ConversationRouterHomeBridge(
}
val onJoinedCall: (ConversationId) -> Unit = remember(navigator) {
{
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.CallJoined())
getOngoingCallIntent(activity, it.toString()).run {
activity.startActivity(this)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import androidx.lifecycle.viewModelScope
import com.wire.android.BuildConfig
import com.wire.android.appLogger
import com.wire.android.datastore.UserDataStore
import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl
import com.wire.android.feature.analytics.model.AnalyticsEvent
import com.wire.android.ui.common.textfield.textAsFlow
import com.wire.android.util.FileManager
import com.wire.android.util.dispatchers.DispatcherProvider
Expand Down Expand Up @@ -124,6 +126,7 @@ class BackupAndRestoreViewModel
is CreateBackupResult.Failure -> {
state = state.copy(backupCreationProgress = BackupCreationProgress.Failed)
appLogger.e("Failed to create backup: ${result.coreFailure}")
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.BackupExportFailed())
}
}
}
Expand Down Expand Up @@ -185,6 +188,7 @@ class BackupAndRestoreViewModel
importDatabase(importedBackupPath)
} else {
state = state.copy(restoreFileValidation = RestoreFileValidation.IncompatibleBackup)
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.BackupRestoreFailed())
}
}
}
Expand All @@ -196,6 +200,8 @@ class BackupAndRestoreViewModel
is VerifyBackupResult.Failure.Generic -> result.error.toString()
VerifyBackupResult.Failure.InvalidBackupFile -> "No valid files found in the backup"
}

AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.BackupRestoreFailed())
appLogger.e("Failed to extract backup files: $errorMessage")
}
}
Expand All @@ -211,6 +217,7 @@ class BackupAndRestoreViewModel
updateCreationProgress(PROGRESS_75)
delay(SMALL_DELAY)
state = state.copy(backupRestoreProgress = BackupRestoreProgress.Finished)
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.BackupRestoreSucceeded())
}

is RestoreBackupResult.Failure -> {
Expand All @@ -222,6 +229,7 @@ class BackupAndRestoreViewModel
restoreFileValidation = RestoreFileValidation.IncompatibleBackup,
backupRestoreProgress = BackupRestoreProgress.Failed
)
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.BackupRestoreFailed())
}
}
}
Expand All @@ -242,14 +250,17 @@ class BackupAndRestoreViewModel
restorePasswordValidation = PasswordValidation.Valid
)
restoreBackupPasswordState.clearText()
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.BackupRestoreSucceeded())
}

is RestoreBackupResult.Failure -> {
mapBackupRestoreFailure(result.failure)
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.BackupRestoreFailed())
}
}
} else {
state = state.copy(backupRestoreProgress = BackupRestoreProgress.Failed)
AnonymousAnalyticsManagerImpl.sendEvent(event = AnalyticsEvent.BackupRestoreFailed())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package com.wire.android.ui.home.conversations.sendmessage
import androidx.lifecycle.SavedStateHandle
import com.wire.android.config.TestDispatcherProvider
import com.wire.android.config.mockUri
import com.wire.android.feature.analytics.AnonymousAnalyticsManager
import com.wire.android.framework.FakeKaliumFileSystem
import com.wire.android.media.PingRinger
import com.wire.android.ui.home.conversations.ConversationNavArgs
Expand Down Expand Up @@ -139,6 +140,9 @@ internal class SendMessageViewModelArrangement {

private val fakeKaliumFileSystem = FakeKaliumFileSystem()

@MockK
lateinit var analyticsManager: AnonymousAnalyticsManager

private val viewModel by lazy {
SendMessageViewModel(
sendTextMessage = sendTextMessage,
Expand All @@ -158,7 +162,8 @@ internal class SendMessageViewModelArrangement {
observeConversationUnderLegalHoldNotified = observeConversationUnderLegalHoldNotified,
sendLocation = sendLocation,
removeMessageDraft = removeMessageDraftUseCase,
savedStateHandle = savedStateHandle
savedStateHandle = savedStateHandle,
analyticsManager = analyticsManager
)
}

Expand Down
Loading

0 comments on commit 458be14

Please sign in to comment.