8000 Feature/david/apptp/retention engagement (#1799) · xpcom-bsd/Android-1@8183280 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8183280

Browse files
authored
Feature/david/apptp/retention engagement (duckduckgo#1799)
* add measurings for the time spent in the text heave screens * cleanup and spotless * ensure we are counting on screen time only * added missing pixels * added pixels for company trackers screen * using the proper pixel this time * fixed failing test * proper pixel name * fixed test * added missing pixels
1 parent f117976 commit 8183280

File tree

9 files changed

+102
-10
lines changed

9 files changed

+102
-10
lines changed

vpn/src/main/java/com/duckduckgo/mobile/android/vpn/apps/ui/TrackingProtectionExclusionListActivity.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import com.duckduckgo.mobile.android.vpn.apps.TrackingProtectionAppInfo
3636
import com.duckduckgo.mobile.android.vpn.apps.ViewState
3737
import com.duckduckgo.mobile.android.vpn.breakage.ReportBreakageContract
3838
import com.duckduckgo.mobile.android.vpn.databinding.ActivityTrackingProtectionExclusionListBinding
39+
import com.duckduckgo.mobile.android.vpn.pixels.DeviceShieldPixels
3940
import com.duckduckgo.mobile.android.vpn.service.TrackerBlockingVpnService
4041
import com.facebook.shimmer.ShimmerFrameLayout
4142
import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG
@@ -57,6 +58,9 @@ class TrackingProtectionExclusionListActivity :
5758
@AppCoroutineScope
5859
lateinit var appCoroutineScope: CoroutineScope
5960

61+
@Inject
62+
lateinit var deviceShieldPixels: DeviceShieldPixels
63+
6064
private val binding: ActivityTrackingProtectionExclusionListBinding by viewBinding()
6165

6266
private val viewModel: ExcludedAppsViewModel by bindViewModel()
@@ -80,6 +84,8 @@ class TrackingProtectionExclusionListActivity :
8084

8185
bindViews()
8286
observeViewModel()
87+
88+
deviceShieldPixels.didShowExclusionListActivity()
8389
}
8490

8591
override fun onCreateOptionsMenu(menu: Menu): Boolean {

vpn/src/main/java/com/duckduckgo/mobile/android/vpn/pixels/DeviceShieldPixelNames.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,10 @@ enum class DeviceShieldPixelNames(override val pixelName: String) : Pixel.PixelN
9797
ATP_KILLED_VPN_REVOKED("m_atp_ev_revoke_kill_c"),
9898

9999
ATP_DID_SHOW_PRIVACY_REPORT_ARTICLE("m_atp_imp_article_c"),
100+
ATP_DID_SHOW_PRIVACY_REPORT_ARTICLE_DAILY("m_atp_imp_article_d"),
100101

101102
ATP_DID_SHOW_ONBOARDING_FAQ("m_atp_imp_onboarding_faq_c"),
103+
ATP_DID_SHOW_ONBOARDING_FAQ_DAILY("m_atp_imp_onboarding_faq_d"),
102104

103105
ATP_ESTABLISH_TUN_INTERFACE_ERROR_DAILY("m_atp_ev_establish_tun_error_d"),
104106
ATP_ESTABLISH_TUN_INTERFACE_ERROR("m_atp_ev_establish_tun_error_c"),
@@ -159,8 +161,25 @@ enum class DeviceShieldPixelNames(override val pixelName: String) : Pixel.PixelN
159161
ATP_RECEIVED_UNKNOWN_PACKET_PROTOCOL_DAILY("m_atp_ev_unknown_packet_%d_d"),
160162

161163
ATP_DID_SHOW_VPN_CONFLICT_DIALOG("m_atp_imp_vpn_conflict_dialog_c"),
164+
ATP_DID_CHOOSE_DISMISS_VPN_CONFLICT_DIALOG_DAILY("m_atp_ev_vpn_conflict_dialog_dismiss_d"),
162165
ATP_DID_CHOOSE_DISMISS_VPN_CONFLICT_DIALOG("m_atp_ev_vpn_conflict_dialog_dismiss_c"),
166+
ATP_DID_CHOOSE_OPEN_SETTINGS_VPN_CONFLICT_DIALOG_DAILY("m_atp_ev_vpn_conflict_dialog_open_settings_d"),
163167
ATP_DID_CHOOSE_OPEN_SETTINGS_VPN_CONFLICT_DIALOG("m_atp_ev_vpn_conflict_dialog_open_settings_c"),
164-
ATP_DID_CHOOSE_CONTINUIE_OPEN_SETTINGS_VPN_CONFLICT_DIALOG("m_atp_ev_vpn_conflict_dialog_continue_c"),
168+
ATP_DID_CHOOSE_CONTINUE_VPN_CONFLICT_DIALOG("m_atp_ev_vpn_conflict_dialog_continue_c"),
169+
ATP_DID_CHOOSE_CONTINUE_VPN_CONFLICT_DIALOG_DAILY("m_atp_ev_vpn_conflict_dialog_continue_d"),
170+
171+
ATP_DID_OPEN_BETA_INSTRUCTIONS("m_atp_imp_beta_instructions_c"),
172+
ATP_DID_OPEN_BETA_INSTRUCTIONS_DAILY("m_atp_imp_beta_instructions_d"),
173+
174+
ATP_DID_SHOW_EXCLUSION_LIST_ACTIVITY_UNIQUE("m_atp_imp_exclusion_list_activity_u"),
175+
ATP_DID_SHOW_EXCLUSION_LIST_ACTIVITY_DAILY("m_atp_imp_exclusion_list_activity_d"),
176+
ATP_DID_SHOW_EXCLUSION_LIST_ACTIVITY("m_atp_imp_exclusion_list_activity_c"),
177+
ATP_DID_OPEN_EXCLUSION_LIST_ACTIVITY_FROM_TRACKERS("m_atp_ev_exclusion_list_activity_open_trackers_c"),
178+
ATP_DID_OPEN_EXCLUSION_LIST_ACTIVITY_FROM_TRACKERS_DAILY("m_atp_ev_exclusion_list_activity_open_trackers_d"),
179+
ATP_DID_OPEN_EXCLUSION_LIST_ACTIVITY_FROM_TRACKERS_UNIQUE("m_atp_ev_exclusion_list_activity_open_trackers_u"),
180+
181+
ATP_DID_SHOW_COMPANY_TRACKERS_ACTIVITY_UNIQUE("m_atp_imp_company_trackers_activity_u"),
182+
ATP_DID_SHOW_COMPANY_TRACKERS_ACTIVITY_DAILY("m_atp_imp_company_trackers_activity_d"),
183+
ATP_DID_SHOW_COMPANY_TRACKERS_ACTIVITY("m_atp_imp_company_trackers_activity_c"),
165184
;
166185
}

vpn/src/main/java/com/duckduckgo/mobile/android/vpn/pixels/DeviceShieldPixels.kt

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,27 @@ interface DeviceShieldPixels {
323323
* Will fire when the VPN Process is restarted as a result of bad health mitigation
324324
*/
325325
fun didRestartVpnProcessOnBadHealth()
326+
327+
/** Will fire when Beta instructions CTA is pressed */
328+
fun didOpenBetaInstructions()
329+
330+
/**
331+
* This fun will fire two pixels
332+
* daily -> fire only once a day no matter how many times we call this fun
333+
* count -> fire a pixel on every call
334+
*/
335+
fun didShowExclusionListActivity()
336+
337+
/**
338+
* Will fire when the user wants to open the Exclusion List Activity from the Trackers Screen
339+
*/
340+
fun didOpenExclusionListActivityFromTrackersScreen()
341+
342+
/**
343+
* Will fire when the user opens the Company Trackers Screen
344+
*/
345+
fun didOpenCompanyTrackersScreen()
346+
326347
}
327348

328349
@ContributesBinding(AppScope::class)
@@ -502,10 +523,12 @@ class RealDeviceShieldPixels @Inject constructor(
502523

503524
override fun privacyReportArticleDisplayed() {
504525
firePixel(DeviceShieldPixelNames.ATP_DID_SHOW_PRIVACY_REPORT_ARTICLE)
526+
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_SHOW_PRIVACY_REPORT_ARTICLE_DAILY)
505527
}
506528

507529
override fun privacyReportOnboardingFAQDisplayed() {
508530
firePixel(DeviceShieldPixelNames.ATP_DID_SHOW_ONBOARDING_FAQ)
531+
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_SHOW_ONBOARDING_FAQ_DAILY)
509532
}
510533

511534
override fun vpnEstablishTunInterfaceError() {
@@ -604,18 +627,18 @@ class RealDeviceShieldPixels @Inject constructor(
604627
}
605628

606629
override fun didChooseToDismissVpnConflicDialog() {
607-
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_DISMISS_VPN_CONFLICT_DIALOG)
630+
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_DISMISS_VPN_CONFLICT_DIALOG_DAILY)
608631
firePixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_DISMISS_VPN_CONFLICT_DIALOG)
609632
}
610633

611634
override fun didChooseToOpenSettingsFromVpnConflicDialog() {
612-
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_OPEN_SETTINGS_VPN_CONFLICT_DIALOG)
635+
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_OPEN_SETTINGS_VPN_CONFLICT_DIALOG_DAILY)
613636
firePixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_OPEN_SETTINGS_VPN_CONFLICT_DIALOG)
614637
}
615638

616639
override fun didChooseToContinueFromVpnConflicDialog() {
617-
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_OPEN_SETTINGS_VPN_CONFLICT_DIALOG)
618-
firePixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_OPEN_SETTINGS_VPN_CONFLICT_DIALOG)
640+
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_CONTINUE_VPN_CONFLICT_DIALOG_DAILY)
641+
firePixel(DeviceShieldPixelNames.ATP_DID_CHOOSE_CONTINUE_VPN_CONFLICT_DIALOG)
619642
}
620643

621644
override fun didShowWaitlistDialog() {
@@ -665,6 +688,32 @@ class RealDeviceShieldPixels @Inject constructor(
665688
firePixel(DeviceShieldPixelNames.ATP_DID_RESTART_VPN_PROCESS_ON_BAD_HEALTH)
666689
}
667690

691+
override fun didOpenBetaInstructions() {
692+
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_OPEN_BETA_INSTRUCTIONS_DAILY)
693+
firePixel(DeviceShieldPixelNames.ATP_DID_OPEN_BETA_INSTRUCTIONS)
694+
}
695+
696+
override fun didShowExclusionListActivity() {
697+
tryToFireUniquePixel(DeviceShieldPixelNames.ATP_DID_SHOW_EXCLUSION_LIST_ACTIVITY_UNIQUE)
698+
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_SHOW_EXCLUSION_LIST_ACTIVITY_DAILY)
699+
firePixel(DeviceShieldPixelNames.ATP_DID_SHOW_EXCLUSION_LIST_ACTIVITY)
700+
}
701+
702+
override fun didOpenExclusionListActivityFromTrackersScreen() {
703+
tryToFireUniquePixel(
704+
DeviceShieldPixelNames.ATP_DID_OPEN_EXCLUSION_LIST_ACTIVITY_FROM_TRACKERS_UNIQUE,
705+
tag = FIRST_OPEN_ENTRY_POINT_TAG
706+
)
707+
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_OPEN_EXCLUSION_LIST_ACTIVITY_FROM_TRACKERS_DAILY)
708+
firePixel(DeviceShieldPixelNames.ATP_DID_OPEN_EXCLUSION_LIST_ACTIVITY_FROM_TRACKERS)
709+
}
710+
711+
override fun didOpenCompanyTrackersScreen() {
712+
tryToFireUniquePixel(DeviceShieldPixelNames.ATP_DID_SHOW_COMPANY_TRACKERS_ACTIVITY_UNIQUE)
713+
tryToFireDailyPixel(DeviceShieldPixelNames.ATP_DID_SHOW_COMPANY_TRACKERS_ACTIVITY_DAILY)
714+
firePixel(DeviceShieldPixelNames.ATP_DID_SHOW_COMPANY_TRACKERS_ACTIVITY)
715+
}
716+
668717
private fun suddenKill() {
669718
firePixel(DeviceShieldPixelNames.ATP_KILLED)
670719
}
@@ -727,6 +776,7 @@ class RealDeviceShieldPixels @Inject constructor(
727776

728777
companion object {
729778
private const val FIRST_ENABLE_ENTRY_POINT_TAG = "FIRST_ENABLE_ENTRY_POINT_TAG"
779+
private const val FIRST_OPEN_ENTRY_POINT_TAG = "FIRST_OPEN_ENTRY_POINT_TAG"
730780

731781
@VisibleForTesting
732782
const val DS_PIXELS_PREF_FILE = "com.duckduckgo.mobile.android.device.shield.pixels"

vpn/src/main/java/com/duckduckgo/mobile/android/vpn/ui/onboarding/DeviceShieldOnboardingActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class DeviceShieldOnboardingActivity : AppCompatActivity(R.layout.activity_devic
9191
private fun configureUI() {
9292
viewPager.adapter = DeviceShieldOnboardingAdapter(viewModel.pages)
9393
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
94+
9495
override fun onPageSelected(position: Int) {
9596
showOnboardingPage(position)
9697
super.onPageSelected(position)

vpn/src/main/java/com/duckduckgo/mobile/android/vpn/ui/report/DeviceShieldAppTrackersInfo.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,23 @@ import android.os.Bundle
2222
import com.duckduckgo.app.global.DuckDuckGoActivity
2323
import com.duckduckgo.mobile.android.ui.viewbinding.viewBinding
2424
import com.duckduckgo.mobile.android.vpn.databinding.ActivityAppTrackersInfoBinding
25+
import com.duckduckgo.mobile.android.vpn.pixels.DeviceShieldPixels
26+
import javax.inject.Inject
2527

2628
class DeviceShieldAppTrackersInfo : DuckDuckGoActivity() {
2729

30+
@Inject
31+
lateinit var deviceShieldPixels: DeviceShieldPixels
32+
2833
private val binding: ActivityAppTrackersInfoBinding by viewBinding()
2934

3035
override fun onCreate(savedInstanceState: Bundle?) {
3136
super.onCreate(savedInstanceState)
3237

3338
setContentView(binding.root)
3439
setupToolbar(binding.includeToolbar.toolbar)
40+
41+
deviceShieldPixels.privacyReportArticleDisplayed()
3542
}
3643

3744
override fun onSupportNavigateUp(): Boolean {

vpn/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/AppTPCompanyTrackersActivity.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,19 @@ import com.duckduckgo.mobile.android.vpn.R
3434
import com.duckduckgo.mobile.android.vpn.breakage.ReportBreakageContract
3535
import com.duckduckgo.mobile.android.vpn.breakage.ReportBreakageScreen
3636
import com.duckduckgo.mobile.android.vpn.databinding.ActivityApptpCompanyTrackersActivityBinding
37+
import com.du F438 ckduckgo.mobile.android.vpn.pixels.DeviceShieldPixels
3738
import com.duckduckgo.mobile.android.vpn.ui.onboarding.DeviceShieldFAQActivity
3839
import com.google.android.material.snackbar.Snackbar
3940
import kotlinx.android.synthetic.main.include_company_trackers_toolbar.*
4041
import kotlinx.coroutines.flow.collect
4142
import kotlinx.coroutines.launch
43+
import javax.inject.Inject
4244

4345
class AppTPCompanyTrackersActivity : DuckDuckGoActivity() {
4446

47+
@Inject
48+
lateinit var pixels: DeviceShieldPixels
49+
4550
private val binding: ActivityApptpCompanyTrackersActivityBinding by viewBinding()
4651
private val viewModel: AppTPCompanyTrackersViewModel by bindViewModel()
4752

@@ -74,6 +79,8 @@ class AppTPCompanyTrackersActivity : DuckDuckGoActivity() {
7479

7580
observeViewModel()
7681
binding.activityRecyclerView.adapter = itemsAdapter
82+
83+
pixels.didOpenCompanyTrackersScreen()
7784
}
7885

7986
private fun observeViewModel() {

vpn/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/DeviceShieldTrackerActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ class DeviceShieldTrackerActivity :
230230
}
231231

232232
private fun launchExcludedApps(shouldListBeEnabled: Boolean) {
233+
deviceShieldPixels.didOpenExclusionListActivityFromTrackersScreen()
233234
startActivity(TrackingProtectionExclusionListActivity.intent(this, shouldListBeEnabled))
234235
}
235236

@@ -258,6 +259,7 @@ class DeviceShieldTrackerActivity :
258259
}
259260

260261
override fun onOpenAppProtection() {
262+
deviceShieldPixels.didChooseToDisableOneAppFromDialog()
261263
viewModel.onViewEvent(DeviceShieldTrackerActivityViewModel.ViewEvent.LaunchExcludedApps)
262264
}
263265

vpn/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/DeviceShieldTrackerActivityViewModel.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ class DeviceShieldTrackerActivityViewModel @Inject constructor(
111111
viewModelScope.launch(dispatcherProvider.io()) {
112112
val vpnState = vpnStateMonitor.getState().state
113113
sendCommand(Command.LaunchExcludedApps(vpnState == VpnRunningState.ENABLED))
114-
deviceShieldPixels.didChooseToDisableOneAppFromDialog()
115114
}
116115
}
117116

@@ -125,11 +124,11 @@ class DeviceShieldTrackerActivityViewModel @Inject constructor(
125124
internal fun onViewEvent(viewEvent: ViewEvent) {
126125
viewModelScope.launch {
127126
when (viewEvent) {
128-
ViewEvent.LaunchAppTrackersFAQ -> {
129-
deviceShieldPixels.privacyReportArticleDisplayed()
130-
command.send(Command.LaunchAppTrackersFAQ)
127+
ViewEvent.LaunchAppTrackersFAQ -> command.send(Command.LaunchAppTrackersFAQ)
128+
ViewEvent.LaunchBetaInstructions -> {
129+
deviceShieldPixels.didOpenBetaInstructions()
130+
command.send(Command.LaunchBetaInstructions)
131131
}
132-
ViewEvent.LaunchBetaInstructions -> command.send(Command.LaunchBetaInstructions)
133132
ViewEvent.LaunchDeviceShieldFAQ -> command.send(Command.LaunchDeviceShieldFAQ)
134133
ViewEvent.LaunchExcludedApps -> launchExcludedApps()
135134
ViewEvent.LaunchMostRecentActivity -> command.send(Command.LaunchMostRecentActivity)

vpn/src/test/java/com/duckduckgo/mobile/android/vpn/pixels/RealDeviceShieldPixelsTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ class RealDeviceShieldPixelsTest {
295295
deviceShieldPixels.privacyReportArticleDisplayed()
296296

297297
verify(pixel, times(2)).fire(DeviceShieldPixelNames.ATP_DID_SHOW_PRIVACY_REPORT_ARTICLE.pixelName)
298+
verify(pixel, times(1)).fire(DeviceShieldPixelNames.ATP_DID_SHOW_PRIVACY_REPORT_ARTICLE_DAILY.pixelName)
298299
verifyNoMoreInteractions(pixel)
299300
}
300301

0 commit comments

Comments
 (0)
0