8000 Measure impact of events in retention (#3224) · transmatecode/Android@7ca2c3b · GitHub
[go: up one dir, main page]

Skip to content

Commit 7ca2c3b

Browse files
authored
Measure impact of events in retention (duckduckgo#3224)
Task/Issue URL: https://app.asana.com/0/0/1204601774518723/f ### Description Implemented new pixel which will send as parameters app events performed prior to the specified date. ### Steps to test this PR - smoke test Asana task: https://app.asana.com/0/0/1204601774518724/f ### No UI changes
1 parent 6d64f9e commit 7ca2c3b

File tree

35 files changed

+477
-17
lines changed

35 files changed

+477
-17
lines changed

app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/VpnFeaturesRegistryImpl.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package com.duckduckgo.mobile.android.vpn
1919
import android.content.Context
2020
import android.content.SharedPreferences
2121
import androidx.core.content.edit
22+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentType
23+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
2224
import com.duckduckgo.mobile.android.vpn.prefs.VpnSharedPreferencesProvider
2325
import com.duckduckgo.mobile.android.vpn.service.TrackerBlockingVpnService
2426
import java.util.UUID
@@ -30,6 +32,7 @@ private const val IS_INITIALIZED = "IS_INITIALIZED"
3032
internal class VpnFeaturesRegistryImpl(
3133
private val vpnServiceWrapper: VpnServiceWrapper,
3234
private val sharedPreferencesProvider: VpnSharedPreferencesProvider,
35+
private val featureSegmentsManager: FeatureSegmentsManager,
3336
) : VpnFeaturesRegistry {
3437

3538
private val preferences: SharedPreferences by lazy {
@@ -44,6 +47,7 @@ internal class VpnFeaturesRegistryImpl(
4447
putString(feature.featureName, UUID.randomUUID().toString())
4548
}
4649
vpnServiceWrapper.restartVpnService(forceRestart = true)
50+
featureSegmentsManager.addUserToFeatureSegment(FeatureSegmentType.APP_TP_ENABLED)
4751
}
4852

4953
@Synchronized

app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/di/VpnAppModule.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import android.content.res.Resources
2121
import android.net.ConnectivityManager
2222
import androidx.room.Room
2323
import com.duckduckgo.app.global.DispatcherProvider
24+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
2425
import com.duckduckgo.di.scopes.AppScope
2526
import com.duckduckgo.mobile.android.vpn.VpnFeaturesRegistry
2627
import com.duckduckgo.mobile.android.vpn.VpnFeaturesRegistryImpl
@@ -99,8 +100,9 @@ object VpnAppModule {
99100
fun provideVpnFeaturesRegistry(
100101
context: Context,
101102
sharedPreferencesProvider: VpnSharedPreferencesProvider,
103+
featureSegmentsManager: FeatureSegmentsManager,
102104
): VpnFeaturesRegistry {
103-
return VpnFeaturesRegistryImpl(VpnServiceWrapper(context), sharedPreferencesProvider)
105+
return VpnFeaturesRegistryImpl(VpnServiceWrapper(context), sharedPreferencesProvider, featureSegmentsManager)
104106
}
105107

106108
@Provides

app-tracking-protection/vpn-impl/src/test/java/com/duckduckgo/mobile/android/vpn/VpnFeaturesRegistryImplTest.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package com.duckduckgo.mobile.android.vpn
1919
import androidx.test.ext.junit.runners.AndroidJUnit4
2020
import androidx.test.platform.app.InstrumentationRegistry
2121
import com.duckduckgo.app.global.api.InMemorySharedPreferences
22+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
2223
import com.duckduckgo.mobile.android.vpn.prefs.VpnSharedPreferencesProvider
2324
import kotlinx.coroutines.ExperimentalCoroutinesApi
2425
import kotlinx.coroutines.test.runTest
@@ -33,6 +34,7 @@ import org.mockito.kotlin.*
3334
class VpnFeaturesRegistryImplTest {
3435

3536
private val sharedPreferencesProvider: VpnSharedPreferencesProvider = mock()
37+
private val mockFeatureSegmentsManager: FeatureSegmentsManager = mock()
3638
private lateinit var vpnServiceWrapper: TestVpnServiceWrapper
3739

3840
private lateinit var vpnFeaturesRegistry: VpnFeaturesRegistry
@@ -46,7 +48,7 @@ class VpnFeaturesRegistryImplTest {
4648
sharedPreferencesProvider.getSharedPreferences(eq("com.duckduckgo.mobile.android.vpn.feature.registry.v1"), eq(true), eq(false)),
4749
).thenReturn(prefs)
4850

49-
vpnFeaturesRegistry = VpnFeaturesRegistryImpl(vpnServiceWrapper, sharedPreferencesProvider)
51+
vpnFeaturesRegistry = VpnFeaturesRegistryImpl(vpnServiceWrapper, sharedPreferencesProvider, mockFeatureSegmentsManager)
5052
}
5153

5254
@Test

app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ import com.duckduckgo.app.privacy.model.UserWhitelistedDomain
108108
import com.duckduckgo.app.settings.db.SettingsDataStore
109109
import com.duckduckgo.app.statistics.VariantManager
110110
import com.duckduckgo.app.statistics.api.StatisticsUpdater
111+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
111112
import com.duckduckgo.app.statistics.pixels.Pixel
112113
import com.duckduckgo.app.statistics.pixels.Pixel.PixelParameter.CTA_SHOWN
113114
import com.duckduckgo.app.statistics.pixels.Pixel.PixelValues.DAX_APPTP_CTA
@@ -333,6 +334,9 @@ class BrowserTabViewModelTest {
333334
@Mock
334335
private lateinit var mockUserAllowListRepository: UserAllowListRepository
335336

337+
@Mock
338+
private lateinit var mockFeatureSegmentsManager: FeatureSegmentsManager
339+
336340
private lateinit var remoteMessagingModel: RemoteMessagingModel
337341

338342
private val lazyFaviconManager = Lazy { mockFaviconManager }
@@ -504,6 +508,7 @@ class BrowserTabViewModelTest {
504508
autofillCapabilityChecker = autofillCapabilityChecker,
505509
autofillFireproofDialogSuppressor = autofillFireproofDialogSuppressor,
506510
automaticSavedLoginsMonitor = automaticSavedLoginsMonitor,
511+
featureSegmentsManager = mockFeatureSegmentsManager,
507512
)
508513

509514
testee.loadData("abc", null, false, false)

app/src/androidTest/java/com/duckduckgo/app/di/StubStatisticsModule.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import com.duckduckgo.app.statistics.AtbInitializerListener
2525
import com.duckduckgo.app.statistics.api.PixelSender
2626
import com.duckduckgo.app.statistics.api.StatisticsService
2727
import com.duckduckgo.app.statistics.api.StatisticsUpdater
28+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
2829
import com.duckduckgo.app.statistics.pixels.Pixel
2930
import com.duckduckgo.app.statistics.store.StatisticsDataStore
3031
import com.duckduckgo.di.DaggerSet
@@ -109,8 +110,9 @@ class StubStatisticsModule {
109110
statisticsDataStore: StatisticsDataStore,
110111
statisticsUpdater: StatisticsUpdater,
111112
listeners: DaggerSet<AtbInitializerListener>,
113+
featureSegmentsManager: FeatureSegmentsManager,
112114
): MainProcessLifecycleObserver {
113-
return AtbInitializer(appCoroutineScope, statisticsDataStore, statisticsUpdater, listeners)
115+
return AtbInitializer(appCoroutineScope, statisticsDataStore, statisticsUpdater, listeners, featureSegmentsManager)
114116
}
115117

116118
@Provides

app/src/androidTest/java/com/duckduckgo/app/integration/AtbIntegrationTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import com.duckduckgo.app.statistics.VariantManager
2727
import com.duckduckgo.app.statistics.api.RefreshRetentionAtbPlugin
2828
import com.duckduckgo.app.statistics.api.StatisticsRequester
2929
import com.duckduckgo.app.statistics.api.StatisticsService
30+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
3031
import com.duckduckgo.app.statistics.model.Atb
3132
import com.duckduckgo.app.statistics.store.StatisticsDataStore
3233
import com.duckduckgo.app.statistics.store.StatisticsSharedPreferences

app/src/main/java/com/duckduckgo/app/bookmarks/ui/BookmarksViewModel.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import com.duckduckgo.app.browser.favicon.FaviconManager
2727
import com.duckduckgo.app.global.DispatcherProvider
2828
import com.duckduckgo.app.global.SingleLiveEvent
2929
import com.duckduckgo.app.pixels.AppPixelName
30+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentType.BOOKMARKS_IMPORTED
31+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
3032
import com.duckduckgo.app.statistics.pixels.Pixel
3133
import com.duckduckgo.di.scopes.ActivityScope
3234
import com.duckduckgo.savedsites.api.SavedSitesRepository
@@ -55,6 +57,7 @@ class BookmarksViewModel @Inject constructor(
5557
private val pixel: Pixel,
5658
private val syncEngine: SyncEngine,
5759
private val dispatcherProvider: DispatcherProvider,
60+
private val featureSegmentsManager: FeatureSegmentsManager,
5861
) : EditSavedSiteListener, AddBookmarkFolderListener, EditBookmarkFolderListener, ViewModel() {
5962

6063
data class ViewState(
@@ -159,6 +162,9 @@ class BookmarksViewModel @Inject constructor(
159162
withContext(dispatcherProvider.main()) {
160163
command.value = ImportedSavedSites(result)
161164
}
165+
if (result is ImportSavedSitesResult.Success) {
166+
featureSegmentsManager.addUserToFeatureSegment(BOOKMARKS_IMPORTED)
167+
}
162168
}
163169
}
164170

app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import com.duckduckgo.app.settings.SettingsActivity
6363
import com.duckduckgo.app.settings.db.SettingsDataStore
6464
import com.duckduckgo.app.sitepermissions.SitePermissionsActivity
6565
import com.duckduckgo.app.statistics.VariantManager
66+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
6667
import com.duckduckgo.app.statistics.pixels.Pixel
6768
import com.duckduckgo.app.tabs.model.TabEntity
6869
import com.duckduckgo.di.scopes.ActivityScope
@@ -115,6 +116,9 @@ open class BrowserActivity : DuckDuckGoActivity() {
115116
@Inject
116117
lateinit var globalActivityStarter: GlobalActivityStarter
117118

119+
@Inject
120+
lateinit var featureSegmentsManager: FeatureSegmentsManager
121+
118122
@Inject
119123
@AppCoroutineScope
120124
lateinit var appCoroutineScope: CoroutineScope
@@ -423,6 +427,7 @@ open class BrowserActivity : DuckDuckGoActivity() {
423427
settingsDataStore = settingsDataStore,
424428
userEventsStore = userEventsStore,
425429
appCoroutineScope = appCoroutineScope,
430+
featureSegmentsManager = featureSegmentsManager,
426431
)
427432
dialog.clearStarted = {
428433
removeObservers()

app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao
9999
import com.duckduckgo.app.privacy.db.UserWhitelistDao
100100
import com.duckduckgo.app.settings.db.SettingsDataStore
101101
import com.duckduckgo.app.statistics.api.StatisticsUpdater
102+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentType
103+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
102104
import com.duckduckgo.app.statistics.pixels.Pixel
103105
import com.duckduckgo.app.statistics.pixels.Pixel.PixelParameter
104106
import com.duckduckgo.app.statistics.pixels.Pixel.PixelParameter.FAVORITE_MENU_ITEM_STATE
@@ -189,6 +191,7 @@ class BrowserTabViewModel @Inject constructor(
189191
private val sitePermissionsManager: SitePermissionsManager,
190192
private val autofillFireproofDialogSuppressor: AutofillFireproofDialogSuppressor,
191193
private val automaticSavedLoginsMonitor: AutomaticSavedLoginsMonitor,
194+
private val featureSegmentsManager: FeatureSegmentsManager,
192195
) : WebViewClientListener,
193196
EditSavedSiteListener,
194197
UrlExtractionListener,
@@ -880,6 +883,7 @@ class BrowserTabViewModel @Inject constructor(
880883
viewModelScope.launch(dispatchers.io()) {
881884
searchCountDao.incrementSearchCount()
882885
}
886+
featureSegmentsManager.searchMade()
883887

884888
val verticalParameter = extractVerticalParameter(url)
885889
var urlToNavigate = queryUrlConverter.convertQueryToUrl(trimmedInput, verticalParameter, queryOrigin)
@@ -1897,6 +1901,7 @@ class BrowserTabViewModel @Inject constructor(
18971901
viewModelScope.launch {
18981902
val favorite = withContext(dispatchers.io()) {
18991903
if (url.isNotBlank()) {
1904+
featureSegmentsManager.addUserToFeatureSegment(FeatureSegmentType.FAVOURITE_SET)
19001905
faviconManager.persistCachedFavicon(tabId, url)
19011906
savedSitesRepository.insertFavorite(title = title, url = url)
19021907
} else {
@@ -2793,6 +2798,7 @@ class BrowserTabViewModel @Inject constructor(
27932798
url: String,
27942799
credentials: LoginCredentials,
27952800
): LoginCredentials? {
2801+
featureSegmentsManager.addUserToFeatureSegment(FeatureSegmentType.LOGIN_SAVED)
27962802
return withContext(appCoroutineScope.coroutineContext) {
27972803
autofillStore.saveCredentials(url, credentials)
27982804
}

app/src/main/java/com/duckduckgo/app/browser/autofill/AutofillCredentialsSelectionResultHandler.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import com.duckduckgo.app.browser.R
2525
import com.duckduckgo.app.di.AppCoroutineScope
2626
import com.duckduckgo.app.global.DefaultDispatcherProvider
2727
import com.duckduckgo.app.global.DispatcherProvider
28+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentType
29+
import com.duckduckgo.app.statistics.api.featureusage.FeatureSegmentsManager
2830
import com.duckduckgo.app.statistics.pixels.Pixel
2931
import com.duckduckgo.autofill.api.CredentialAutofillPickerDialog
3032
import com.duckduckgo.autofill.api.CredentialSavePickerDialog
@@ -64,6 +66,7 @@ class AutofillCredentialsSelectionResultHandler @Inject constructor(
6466
private val autofillDialogSuppressor: AutofillFireproofDialogSuppressor,
6567
private val autoSavedLoginsMonitor: AutomaticSavedLoginsMonitor,
6668
private val existingCredentialMatchDetector: ExistingCredentialMatchDetector,
69+
private val featureSegmentsManager: FeatureSegmentsManager,
6770
) {
6871

6972
suspend fun processAutofillCredentialSelectionResult(
@@ -244,6 +247,7 @@ class AutofillCredentialsSelectionResultHandler @Inject constructor(
244247
)?.id?.let { savedId ->
245248
Timber.i("New login saved because no exact matches were found, with ID: $savedId")
246249
autoSavedLoginsMonitor.setAutoSavedLoginId(savedId, tabId)
250+
featureSegmentsManager.addUserToFeatureSegment(FeatureSegmentType.LOGIN_SAVED)
247251
}
248252
}
249253
}

0 commit comments

Comments
 (0)
0