diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/view/HomeView.kt b/app/src/main/java/no/nordicsemi/android/nrftoolbox/view/HomeView.kt index 31e365a7..01e783c0 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/view/HomeView.kt +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/view/HomeView.kt @@ -14,6 +14,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import no.nordicsemi.android.analytics.Link +import no.nordicsemi.android.analytics.Profile import no.nordicsemi.android.analytics.ProfileOpenEvent import no.nordicsemi.android.logger.LoggerAppRunner import no.nordicsemi.android.nrftoolbox.BuildConfig @@ -57,14 +59,14 @@ fun HomeScreen() { FeatureButton(R.drawable.ic_gls, R.string.gls_module, R.string.gls_module_full) { viewModel.openProfile(ProfileDestination.GLS) - viewModel.logEvent(ProfileOpenEvent.GLS) + viewModel.logEvent(ProfileOpenEvent(Profile.GLS)) } Spacer(modifier = Modifier.height(16.dp)) FeatureButton(R.drawable.ic_bps, R.string.bps_module, R.string.bps_module_full) { viewModel.openProfile(ProfileDestination.BPS) - viewModel.logEvent(ProfileOpenEvent.BPS) + viewModel.logEvent(ProfileOpenEvent(Profile.BPS)) } Spacer(modifier = Modifier.height(16.dp)) @@ -79,42 +81,42 @@ fun HomeScreen() { FeatureButton(R.drawable.ic_csc, R.string.csc_module, R.string.csc_module_full, state.isCSCModuleRunning) { viewModel.openProfile(ProfileDestination.CSC) - viewModel.logEvent(ProfileOpenEvent.CSC) + viewModel.logEvent(ProfileOpenEvent(Profile.CSC)) } Spacer(modifier = Modifier.height(16.dp)) FeatureButton(R.drawable.ic_hrs, R.string.hrs_module, R.string.hrs_module_full, state.isHRSModuleRunning) { viewModel.openProfile(ProfileDestination.HRS) - viewModel.logEvent(ProfileOpenEvent.HRS) + viewModel.logEvent(ProfileOpenEvent(Profile.HRS)) } Spacer(modifier = Modifier.height(16.dp)) FeatureButton(R.drawable.ic_hts, R.string.hts_module, R.string.hts_module_full, state.isHTSModuleRunning) { viewModel.openProfile(ProfileDestination.HTS) - viewModel.logEvent(ProfileOpenEvent.HTS) + viewModel.logEvent(ProfileOpenEvent(Profile.HTS)) } Spacer(modifier = Modifier.height(16.dp)) FeatureButton(R.drawable.ic_rscs, R.string.rscs_module, R.string.rscs_module_full, state.isRSCSModuleRunning) { viewModel.openProfile(ProfileDestination.RSCS) - viewModel.logEvent(ProfileOpenEvent.RSCS) + viewModel.logEvent(ProfileOpenEvent(Profile.RSCS)) } Spacer(modifier = Modifier.height(16.dp)) FeatureButton(R.drawable.ic_cgm, R.string.cgm_module, R.string.cgm_module_full, state.isCGMModuleRunning) { viewModel.openProfile(ProfileDestination.CGMS) - viewModel.logEvent(ProfileOpenEvent.CGMS) + viewModel.logEvent(ProfileOpenEvent(Profile.CGMS)) } Spacer(modifier = Modifier.height(16.dp)) FeatureButton(R.drawable.ic_prx, R.string.prx_module, R.string.prx_module_full, state.isPRXModuleRunning) { viewModel.openProfile(ProfileDestination.PRX) - viewModel.logEvent(ProfileOpenEvent.PRX) + viewModel.logEvent(ProfileOpenEvent(Profile.PRX)) } Spacer(modifier = Modifier.height(16.dp)) @@ -129,7 +131,7 @@ fun HomeScreen() { FeatureButton(R.drawable.ic_uart, R.string.uart_module, R.string.uart_module_full, state.isUARTModuleRunning) { viewModel.openProfile(ProfileDestination.UART) - viewModel.logEvent(ProfileOpenEvent.UART) + viewModel.logEvent(ProfileOpenEvent(Profile.UART)) } Spacer(modifier = Modifier.height(16.dp)) @@ -149,7 +151,7 @@ fun HomeScreen() { } else { uriHandler.openUri(DFU_LINK) } - viewModel.logEvent(ProfileOpenEvent.DFU) + viewModel.logEvent(ProfileOpenEvent(Link.DFU)) } Spacer(modifier = Modifier.height(16.dp)) @@ -160,7 +162,7 @@ fun HomeScreen() { FeatureButton(R.drawable.ic_logger, R.string.logger_module, R.string.logger_module_full, null, loggerDescription) { viewModel.openLogger() - viewModel.logEvent(ProfileOpenEvent.LOGGER) + viewModel.logEvent(ProfileOpenEvent(Link.LOGGER)) } Spacer(modifier = Modifier.height(16.dp)) diff --git a/lib_analytics/src/main/java/no/nordicsemi/android/analytics/AppAnalytics.kt b/lib_analytics/src/main/java/no/nordicsemi/android/analytics/AppAnalytics.kt index 2da66107..9639975b 100644 --- a/lib_analytics/src/main/java/no/nordicsemi/android/analytics/AppAnalytics.kt +++ b/lib_analytics/src/main/java/no/nordicsemi/android/analytics/AppAnalytics.kt @@ -16,7 +16,7 @@ class AppAnalytics @Inject constructor( private val firebase by lazy { FirebaseAnalytics.getInstance(context) } - fun logEvent(event: AppEvent) { - firebase.logEvent(event.eventName, null) + fun logEvent(event: FirebaseEvent) { + firebase.logEvent(event.eventName, event.params) } } diff --git a/lib_analytics/src/main/java/no/nordicsemi/android/analytics/Events.kt b/lib_analytics/src/main/java/no/nordicsemi/android/analytics/Events.kt new file mode 100644 index 00000000..9a4aaf21 --- /dev/null +++ b/lib_analytics/src/main/java/no/nordicsemi/android/analytics/Events.kt @@ -0,0 +1,50 @@ +package no.nordicsemi.android.analytics + +import android.os.Bundle + +sealed class FirebaseEvent(val eventName: String, val params: Bundle?) + +object AppOpenEvent : FirebaseEvent("APP_OPEN", null) + +class ProfileOpenEvent : FirebaseEvent { + + constructor(profile: Profile) : super(EVENT_NAME, createBundle(profile.displayName)) + + constructor(link: Link) : super(EVENT_NAME, createBundle(link.displayName)) + + companion object { + private const val EVENT_NAME = "PROFILE_OPEN" + } +} + +class ProfileConnectedEvent : FirebaseEvent { + + constructor(profile: Profile) : super(EVENT_NAME, createBundle(profile.displayName)) + + constructor(link: Link) : super(EVENT_NAME, createBundle(link.displayName)) + + companion object { + private const val EVENT_NAME = "PROFILE_CONNECTED" + } +} + +const val PROFILE_PARAM_KEY = "PROFILE_NAME" + +private fun createBundle(name: String): Bundle { + return Bundle().apply { putString(PROFILE_PARAM_KEY, name) } +} + +sealed class UARTAnalyticsEvent(eventName: String, params: Bundle?) : FirebaseEvent(eventName, params) + +class UARTSendAnalyticsEvent(mode: UARTMode) : UARTAnalyticsEvent("UART_SEND_EVENT", createParams(mode)) { + + companion object { + fun createParams(mode: UARTMode) = Bundle().apply { + putString("MODE", mode.displayName) + } + } +} + +class UARTCreateConfiguration : UARTAnalyticsEvent("UART_CREATE_CONF", null) + +class UARTChangeConfiguration : UARTAnalyticsEvent("UART_CHANGE_CONF", null) diff --git a/lib_analytics/src/main/java/no/nordicsemi/android/analytics/ProfileOpenEvent.kt b/lib_analytics/src/main/java/no/nordicsemi/android/analytics/ProfileOpenEvent.kt deleted file mode 100644 index c072e2d6..00000000 --- a/lib_analytics/src/main/java/no/nordicsemi/android/analytics/ProfileOpenEvent.kt +++ /dev/null @@ -1,24 +0,0 @@ -package no.nordicsemi.android.analytics - -sealed interface AppEvent { - val eventName: String -} - -object AppOpenEvent : AppEvent { - override val eventName: String = "APP_OPEN" -} - -enum class ProfileOpenEvent(override val eventName: String) : AppEvent { - BPS("BPS_PROFILE_OPEN"), - CGMS("CGMS_PROFILE_OPEN"), - CSC("CSC_PROFILE_OPEN"), - GLS("GLS_PROFILE_OPEN"), - HRS("HRS_PROFILE_OPEN"), - HTS("HTS_PROFILE_OPEN"), - PRX("PRX_PROFILE_OPEN"), - RSCS("RSCS_PROFILE_OPEN"), - UART("UART_PROFILE_OPEN"), - - DFU("DFU_PROFILE_OPEN"), - LOGGER("LOGGER_PROFILE_OPEN"), -} diff --git a/lib_analytics/src/main/java/no/nordicsemi/android/analytics/Profiles.kt b/lib_analytics/src/main/java/no/nordicsemi/android/analytics/Profiles.kt new file mode 100644 index 00000000..bac24535 --- /dev/null +++ b/lib_analytics/src/main/java/no/nordicsemi/android/analytics/Profiles.kt @@ -0,0 +1,23 @@ +package no.nordicsemi.android.analytics + +enum class Profile(val displayName: String) { + BPS("BPS"), + CGMS("CGMS"), + CSC("CSC"), + GLS("GLS"), + HRS("HRS"), + HTS("HTS"), + PRX("PRX"), + RSCS("RSCS"), + UART("UART"); +} + +enum class Link(val displayName: String) { + DFU("DFU"), + LOGGER("LOGGER"); +} + +enum class UARTMode(val displayName: String) { + MACRO("MACRO"), + TEXT("TEXT") +} \ No newline at end of file diff --git a/profile_bps/build.gradle b/profile_bps/build.gradle index 459d5360..7d90a59b 100644 --- a/profile_bps/build.gradle +++ b/profile_bps/build.gradle @@ -2,6 +2,7 @@ apply from: rootProject.file("library.gradle") apply plugin: 'kotlin-parcelize' dependencies { + implementation project(":lib_analytics") implementation project(":lib_service") implementation project(":lib_theme") implementation project(":lib_utils") diff --git a/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt b/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt index 8ea7928a..1fb8c533 100644 --- a/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt +++ b/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt @@ -7,10 +7,14 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import no.nordicsemi.android.analytics.AppAnalytics +import no.nordicsemi.android.analytics.Profile +import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.bps.data.BPS_SERVICE_UUID import no.nordicsemi.android.bps.repository.BPSRepository import no.nordicsemi.android.bps.view.* import no.nordicsemi.android.navigation.* +import no.nordicsemi.android.service.SuccessResult import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.getDevice import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice @@ -20,7 +24,8 @@ import javax.inject.Inject @HiltViewModel internal class BPSViewModel @Inject constructor( private val repository: BPSRepository, - private val navigationManager: NavigationManager + private val navigationManager: NavigationManager, + private val analytics: AppAnalytics ) : ViewModel() { private val _state = MutableStateFlow(NoDeviceState) @@ -53,6 +58,10 @@ internal class BPSViewModel @Inject constructor( private fun connectDevice(device: DiscoveredBluetoothDevice) { repository.downloadData(device).onEach { _state.value = WorkingState(it) + + (it as? SuccessResult)?.let { + analytics.logEvent(ProfileConnectedEvent(Profile.BPS)) + } }.launchIn(viewModelScope) } } diff --git a/profile_cgms/build.gradle b/profile_cgms/build.gradle index 5a6b3f72..1fa9270c 100644 --- a/profile_cgms/build.gradle +++ b/profile_cgms/build.gradle @@ -6,6 +6,7 @@ android { } dependencies { + implementation project(":lib_analytics") implementation project(":lib_service") implementation project(":lib_theme") implementation project(":lib_utils") diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/viewmodel/CGMViewModel.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/viewmodel/CGMViewModel.kt index 9cf47f27..cbd679b2 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/viewmodel/CGMViewModel.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/viewmodel/CGMViewModel.kt @@ -5,11 +5,15 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import no.nordicsemi.android.analytics.AppAnalytics +import no.nordicsemi.android.analytics.Profile +import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.cgms.data.CGMS_SERVICE_UUID import no.nordicsemi.android.cgms.repository.CGMRepository import no.nordicsemi.android.cgms.data.CGMServiceCommand import no.nordicsemi.android.cgms.view.* import no.nordicsemi.android.navigation.* +import no.nordicsemi.android.service.SuccessResult import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.getDevice import no.nordicsemi.ui.scanner.ScannerDestinationId @@ -18,7 +22,8 @@ import javax.inject.Inject @HiltViewModel internal class CGMViewModel @Inject constructor( private val repository: CGMRepository, - private val navigationManager: NavigationManager + private val navigationManager: NavigationManager, + private val analytics: AppAnalytics ) : ViewModel() { private val _state = MutableStateFlow(NoDeviceState) @@ -33,6 +38,10 @@ internal class CGMViewModel @Inject constructor( repository.data.onEach { _state.value = WorkingState(it) + + (it as? SuccessResult)?.let { + analytics.logEvent(ProfileConnectedEvent(Profile.CGMS)) + } }.launchIn(viewModelScope) } diff --git a/profile_csc/build.gradle b/profile_csc/build.gradle index b5a6c8cd..95e5bcf2 100644 --- a/profile_csc/build.gradle +++ b/profile_csc/build.gradle @@ -2,6 +2,7 @@ apply from: rootProject.file("library.gradle") apply plugin: 'kotlin-parcelize' dependencies { + implementation project(":lib_analytics") implementation project(":lib_service") implementation project(":lib_theme") implementation project(":lib_utils") diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt index ec692fbd..b0ff2c19 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt @@ -5,10 +5,14 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import no.nordicsemi.android.analytics.AppAnalytics +import no.nordicsemi.android.analytics.Profile +import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.csc.data.CSC_SERVICE_UUID import no.nordicsemi.android.csc.repository.CSCRepository import no.nordicsemi.android.csc.view.* import no.nordicsemi.android.navigation.* +import no.nordicsemi.android.service.SuccessResult import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.getDevice import no.nordicsemi.ui.scanner.ScannerDestinationId @@ -17,7 +21,8 @@ import javax.inject.Inject @HiltViewModel internal class CSCViewModel @Inject constructor( private val repository: CSCRepository, - private val navigationManager: NavigationManager + private val navigationManager: NavigationManager, + private val analytics: AppAnalytics ) : ViewModel() { private val _state = MutableStateFlow(CSCViewState()) @@ -32,6 +37,10 @@ internal class CSCViewModel @Inject constructor( repository.data.onEach { _state.value = _state.value.copy(cscManagerState = WorkingState(it)) + + (it as? SuccessResult)?.let { + analytics.logEvent(ProfileConnectedEvent(Profile.CSC)) + } }.launchIn(viewModelScope) } diff --git a/profile_gls/build.gradle b/profile_gls/build.gradle index 4322b8ca..8382e92d 100644 --- a/profile_gls/build.gradle +++ b/profile_gls/build.gradle @@ -6,6 +6,7 @@ android { } dependencies { + implementation project(":lib_analytics") implementation project(":lib_service") implementation project(":lib_theme") implementation project(":lib_utils") diff --git a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt index eb62319b..0aa8e8ef 100644 --- a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt +++ b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt @@ -4,11 +4,15 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* +import no.nordicsemi.android.analytics.AppAnalytics +import no.nordicsemi.android.analytics.Profile +import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.gls.GlsDetailsDestinationId import no.nordicsemi.android.gls.repository.GLSRepository import no.nordicsemi.android.gls.data.GLS_SERVICE_UUID import no.nordicsemi.android.gls.main.view.* import no.nordicsemi.android.navigation.* +import no.nordicsemi.android.service.SuccessResult import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.getDevice import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice @@ -18,7 +22,8 @@ import javax.inject.Inject @HiltViewModel internal class GLSViewModel @Inject constructor( private val repository: GLSRepository, - private val navigationManager: NavigationManager + private val navigationManager: NavigationManager, + private val analytics: AppAnalytics ) : ViewModel() { private val _state = MutableStateFlow(NoDeviceState) @@ -54,6 +59,10 @@ internal class GLSViewModel @Inject constructor( private fun connectDevice(device: DiscoveredBluetoothDevice) { repository.downloadData(device).onEach { _state.value = WorkingState(it) + + (it as? SuccessResult)?.let { + analytics.logEvent(ProfileConnectedEvent(Profile.GLS)) + } }.launchIn(viewModelScope) } } diff --git a/profile_hrs/build.gradle b/profile_hrs/build.gradle index 3c89c30f..6cc0298d 100644 --- a/profile_hrs/build.gradle +++ b/profile_hrs/build.gradle @@ -6,6 +6,7 @@ android { } dependencies { + implementation project(":lib_analytics") implementation project(":lib_service") implementation project(":lib_theme") implementation project(":lib_utils") diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/viewmodel/HRSViewModel.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/viewmodel/HRSViewModel.kt index b5d8aa90..9a9b27f5 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/viewmodel/HRSViewModel.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/viewmodel/HRSViewModel.kt @@ -5,10 +5,14 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import no.nordicsemi.android.analytics.AppAnalytics +import no.nordicsemi.android.analytics.Profile +import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.hrs.data.HRS_SERVICE_UUID import no.nordicsemi.android.hrs.service.HRSRepository import no.nordicsemi.android.hrs.view.* import no.nordicsemi.android.navigation.* +import no.nordicsemi.android.service.SuccessResult import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.getDevice import no.nordicsemi.ui.scanner.ScannerDestinationId @@ -17,7 +21,8 @@ import javax.inject.Inject @HiltViewModel internal class HRSViewModel @Inject constructor( private val repository: HRSRepository, - private val navigationManager: NavigationManager + private val navigationManager: NavigationManager, + private val analytics: AppAnalytics ) : ViewModel() { private val _state = MutableStateFlow(NoDeviceState) @@ -33,6 +38,10 @@ internal class HRSViewModel @Inject constructor( repository.data.onEach { val zoomIn = (_state.value as? WorkingState)?.zoomIn ?: false _state.value = WorkingState(it, zoomIn) + + (it as? SuccessResult)?.let { + analytics.logEvent(ProfileConnectedEvent(Profile.HRS)) + } }.launchIn(viewModelScope) } diff --git a/profile_hts/build.gradle b/profile_hts/build.gradle index 735ac727..db875eaf 100644 --- a/profile_hts/build.gradle +++ b/profile_hts/build.gradle @@ -2,6 +2,7 @@ apply from: rootProject.file("library.gradle") apply plugin: 'kotlin-parcelize' dependencies { + implementation project(":lib_analytics") implementation project(":lib_service") implementation project(":lib_theme") implementation project(":lib_utils") diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/viewmodel/HTSViewModel.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/viewmodel/HTSViewModel.kt index 3e8b63a3..dfe398e0 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/viewmodel/HTSViewModel.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/viewmodel/HTSViewModel.kt @@ -5,10 +5,14 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import no.nordicsemi.android.analytics.AppAnalytics +import no.nordicsemi.android.analytics.Profile +import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.hts.data.HTS_SERVICE_UUID import no.nordicsemi.android.hts.repository.HTSRepository import no.nordicsemi.android.hts.view.* import no.nordicsemi.android.navigation.* +import no.nordicsemi.android.service.SuccessResult import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.getDevice import no.nordicsemi.ui.scanner.ScannerDestinationId @@ -17,7 +21,8 @@ import javax.inject.Inject @HiltViewModel internal class HTSViewModel @Inject constructor( private val repository: HTSRepository, - private val navigationManager: NavigationManager + private val navigationManager: NavigationManager, + private val analytics: AppAnalytics ) : ViewModel() { private val _state = MutableStateFlow(HTSViewState()) @@ -32,6 +37,10 @@ internal class HTSViewModel @Inject constructor( repository.data.onEach { _state.value = _state.value.copy(htsManagerState = WorkingState(it)) + + (it as? SuccessResult)?.let { + analytics.logEvent(ProfileConnectedEvent(Profile.HTS)) + } }.launchIn(viewModelScope) } diff --git a/profile_prx/build.gradle b/profile_prx/build.gradle index 6d940edc..040d27f4 100644 --- a/profile_prx/build.gradle +++ b/profile_prx/build.gradle @@ -6,6 +6,7 @@ android { } dependencies { + implementation project(":lib_analytics") implementation project(":lib_service") implementation project(":lib_theme") implementation project(":lib_utils") diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt index 4aac1ea3..f33b8c7d 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt @@ -5,10 +5,14 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import no.nordicsemi.android.analytics.AppAnalytics +import no.nordicsemi.android.analytics.Profile +import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.navigation.* import no.nordicsemi.android.prx.data.PRX_SERVICE_UUID import no.nordicsemi.android.prx.repository.PRXRepository import no.nordicsemi.android.prx.view.* +import no.nordicsemi.android.service.SuccessResult import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.getDevice import no.nordicsemi.ui.scanner.ScannerDestinationId @@ -17,7 +21,8 @@ import javax.inject.Inject @HiltViewModel internal class PRXViewModel @Inject constructor( private val repository: PRXRepository, - private val navigationManager: NavigationManager + private val navigationManager: NavigationManager, + private val analytics: AppAnalytics ) : ViewModel() { private val _state = MutableStateFlow(NoDeviceState) @@ -32,6 +37,10 @@ internal class PRXViewModel @Inject constructor( repository.data.onEach { _state.value = WorkingState(it) + + (it as? SuccessResult)?.let { + analytics.logEvent(ProfileConnectedEvent(Profile.PRX)) + } }.launchIn(viewModelScope) } diff --git a/profile_rscs/build.gradle b/profile_rscs/build.gradle index 526911f2..4562a695 100644 --- a/profile_rscs/build.gradle +++ b/profile_rscs/build.gradle @@ -6,6 +6,7 @@ android { } dependencies { + implementation project(":lib_analytics") implementation project(":lib_service") implementation project(":lib_theme") implementation project(":lib_utils") diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt index 03c00310..afa9e7d1 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt @@ -5,10 +5,14 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import no.nordicsemi.android.analytics.AppAnalytics +import no.nordicsemi.android.analytics.Profile +import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.navigation.* import no.nordicsemi.android.rscs.data.RSCS_SERVICE_UUID import no.nordicsemi.android.rscs.repository.RSCSRepository import no.nordicsemi.android.rscs.view.* +import no.nordicsemi.android.service.SuccessResult import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.getDevice import no.nordicsemi.ui.scanner.ScannerDestinationId @@ -17,7 +21,8 @@ import javax.inject.Inject @HiltViewModel internal class RSCSViewModel @Inject constructor( private val repository: RSCSRepository, - private val navigationManager: NavigationManager + private val navigationManager: NavigationManager, + private val analytics: AppAnalytics ) : ViewModel() { private val _state = MutableStateFlow(NoDeviceState) @@ -32,6 +37,10 @@ internal class RSCSViewModel @Inject constructor( repository.data.onEach { _state.value = WorkingState(it) + + (it as? SuccessResult)?.let { + analytics.logEvent(ProfileConnectedEvent(Profile.RSCS)) + } }.launchIn(viewModelScope) } diff --git a/profile_uart/build.gradle b/profile_uart/build.gradle index cc25b94c..41d41506 100644 --- a/profile_uart/build.gradle +++ b/profile_uart/build.gradle @@ -23,6 +23,7 @@ protobuf { } dependencies { + implementation project(":lib_analytics") implementation project(":lib_service") implementation project(":lib_theme") implementation project(":lib_utils") diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/viewmodel/UARTViewModel.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/viewmodel/UARTViewModel.kt index 690dd5a6..87fa9e51 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/viewmodel/UARTViewModel.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/viewmodel/UARTViewModel.kt @@ -6,12 +6,12 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import no.nordicsemi.android.analytics.* import no.nordicsemi.android.navigation.* import no.nordicsemi.android.service.IdleResult -import no.nordicsemi.android.uart.data.UARTConfiguration -import no.nordicsemi.android.uart.data.UARTMacro +import no.nordicsemi.android.service.SuccessResult +import no.nordicsemi.android.uart.data.* import no.nordicsemi.android.uart.data.UARTPersistentDataSource -import no.nordicsemi.android.uart.data.UART_SERVICE_UUID import no.nordicsemi.android.uart.repository.UARTRepository import no.nordicsemi.android.uart.view.* import no.nordicsemi.android.utils.exhaustive @@ -23,7 +23,8 @@ import javax.inject.Inject internal class UARTViewModel @Inject constructor( private val repository: UARTRepository, private val navigationManager: NavigationManager, - private val dataSource: UARTPersistentDataSource + private val dataSource: UARTPersistentDataSource, + private val analytics: AppAnalytics ) : ViewModel() { private val _state = MutableStateFlow(UARTViewState()) @@ -41,6 +42,10 @@ internal class UARTViewModel @Inject constructor( return@onEach } _state.value = _state.value.copy(uartManagerState = WorkingState(it)) + + (it as? SuccessResult)?.let { + analytics.logEvent(ProfileConnectedEvent(Profile.UART)) + } }.launchIn(viewModelScope) dataSource.getConfigurations().onEach { @@ -76,7 +81,7 @@ internal class UARTViewModel @Inject constructor( is OnCreateMacro -> addNewMacro(event.macro) OnDeleteMacro -> deleteMacro() DisconnectEvent -> disconnect() - is OnRunMacro -> repository.runMacro(event.macro) + is OnRunMacro -> runMacro(event.macro) NavigateUp -> navigationManager.navigateUp() is OnEditMacro -> onEditMacro(event) OnEditFinish -> onEditFinish() @@ -86,11 +91,21 @@ internal class UARTViewModel @Inject constructor( OnEditConfiguration -> onEditConfiguration() ClearOutputItems -> repository.clearItems() OpenLogger -> repository.openLogger() - is OnRunInput -> repository.sendText(event.text, event.newLineChar) + is OnRunInput -> sendText(event.text, event.newLineChar) MacroInputSwitchClick -> onMacroInputSwitch() }.exhaustive } + private fun runMacro(macro: UARTMacro) { + repository.runMacro(macro) + analytics.logEvent(UARTSendAnalyticsEvent(UARTMode.MACRO)) + } + + private fun sendText(text: String, newLineChar: MacroEol) { + repository.sendText(text, newLineChar) + analytics.logEvent(UARTSendAnalyticsEvent(UARTMode.TEXT)) + } + private fun onMacroInputSwitch() { _state.value = _state.value.copy(isInputVisible = !state.value.isInputVisible) } @@ -106,6 +121,7 @@ internal class UARTViewModel @Inject constructor( _state.value = _state.value.copy(selectedConfigurationName = event.name) } saveLastConfigurationName(event.name) + analytics.logEvent(UARTCreateConfiguration()) } private fun onEditMacro(event: OnEditMacro) { @@ -118,6 +134,7 @@ internal class UARTViewModel @Inject constructor( private fun onConfigurationSelected(event: OnConfigurationSelected) { saveLastConfigurationName(event.configuration.name) + analytics.logEvent(UARTChangeConfiguration()) } private fun saveLastConfigurationName(name: String) {