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: add analytics initial events (WPB-10589) 🍒 #3436

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
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
Loading