Skip to content

Commit 6ee01f5

Browse files
authored
Cleanup the code to remove the experiments and use new feature flags (#6777)
Task/Issue URL: https://app.asana.com/1/137249556945/project/1200581511062568/task/1210824886441068?focus=true ### Description Refactored the widget-related experiment implementation by replacing the experiment-based approach with feature toggles. 1. Removing `OnboardingHomeScreenWidgetExperiment` and `PostCtaExperienceExperiment` classes and their implementations 2. Updating the `OnboardingHomeScreenWidgetToggles` and `PostCtaExperienceToggles` interfaces to use simple feature toggles 3. Removing experiment-related pixel tracking and metrics collection 4. Updating the widget-related functionality to use the new toggle-based approach 5. Renaming and moving files for clarity The PR removes complex experiment tracking code and replaces it with a more straightforward feature toggle implementation, making the codebase more maintainable and easier to understand. ### Steps to test this PR - [x] Fresh install from this branch. - [x] Don't skip onboarding. Go through the pre-onboarding and once you can access the Settings, override the privacy config with this one: https://www.jsonblob.com/api/1415374897584201728 - [x] Continue with onboarding until you see the last Dax dialog (the one with the wings). Close it. - [x] Open a new tab and confirm you see the widget prompt as in the left screenshot (Onboarding widget prompt). - [x] Go to Settings. - [x] Tap on the "Home Screen Widget", last option in the "Protections" section at the top. Confirm you see the widget prompt as in the right screenshot (Settings widget prompt). ### NO UI changes, reference screenshots | Onboarding widget prompt | Settings widget prompt | | ------ | ----- | |<img width="1080" height="2340" alt="Screenshot_20250910_173903" src="https://github.com/user-attachments/assets/11fb2145-0c63-48f5-9f24-50a42b089e71" />|<img width="1080" height="2340" alt="Screenshot_20250910_174312" src="https://github.com/user-attachments/assets/af14164c-472c-430b-9cf1-edcb521b4036" />|
1 parent 6ace350 commit 6ee01f5

25 files changed

+128
-1353
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ import com.duckduckgo.app.browser.commands.NavigationCommand
9191
import com.duckduckgo.app.browser.commands.NavigationCommand.Navigate
9292
import com.duckduckgo.app.browser.customtabs.CustomTabPixelNames
9393
import com.duckduckgo.app.browser.defaultbrowsing.prompts.AdditionalDefaultBrowserPrompts
94-
import com.duckduckgo.app.browser.defaultbrowsing.prompts.ui.experiment.OnboardingHomeScreenWidgetExperiment
9594
import com.duckduckgo.app.browser.duckplayer.DUCK_PLAYER_FEATURE_NAME
9695
import com.duckduckgo.app.browser.duckplayer.DUCK_PLAYER_PAGE_FEATURE_NAME
9796
import com.duckduckgo.app.browser.duckplayer.DuckPlayerJSHelper
@@ -122,6 +121,7 @@ import com.duckduckgo.app.browser.santize.NonHttpAppLinkChecker
122121
import com.duckduckgo.app.browser.session.WebViewSessionStorage
123122
import com.duckduckgo.app.browser.tabs.TabManager
124123
import com.duckduckgo.app.browser.trafficquality.AndroidFeaturesHeaderPlugin.Companion.X_DUCKDUCKGO_ANDROID_HEADER
124+
import com.duckduckgo.app.browser.ui.dialogs.widgetprompt.OnboardingHomeScreenWidgetToggles
125125
import com.duckduckgo.app.browser.viewstate.BrowserViewState
126126
import com.duckduckgo.app.browser.viewstate.CtaViewState
127127
import com.duckduckgo.app.browser.viewstate.FindInPageViewState
@@ -561,7 +561,7 @@ class BrowserTabViewModelTest {
561561
private val mockSiteHttpErrorHandler: HttpCodeSiteErrorHandler = mock()
562562
private val mockSubscriptionsJSHelper: SubscriptionsJSHelper = mock()
563563
private val mockReactivateUsersExperiment: ReactivateUsersExperiment = mock()
564-
private val mockOnboardingHomeScreenWidgetExperiment: OnboardingHomeScreenWidgetExperiment = mock()
564+
private val mockOnboardingHomeScreenWidgetToggles: OnboardingHomeScreenWidgetToggles = mock()
565565
private val mockRebrandingFeatureToggle: SubscriptionRebrandingFeatureToggle = mock()
566566
private val tabManager: TabManager = mock()
567567

@@ -674,7 +674,7 @@ class BrowserTabViewModelTest {
674674
subscriptions = subscriptions,
675675
duckPlayer = mockDuckPlayer,
676676
brokenSitePrompt = mockBrokenSitePrompt,
677-
onboardingHomeScreenWidgetExperiment = mockOnboardingHomeScreenWidgetExperiment,
677+
onboardingHomeScreenWidgetToggles = mockOnboardingHomeScreenWidgetToggles,
678678
onboardingDesignExperimentManager = mockOnboardingDesignExperimentManager,
679679
rebrandingFeatureToggle = mockRebrandingFeatureToggle,
680680
)

app/src/androidTest/java/com/duckduckgo/app/cta/ui/CtaViewModelTest.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import androidx.room.Room
2525
import androidx.test.platform.app.InstrumentationRegistry
2626
import com.duckduckgo.app.browser.DuckDuckGoUrlDetectorImpl
2727
import com.duckduckgo.app.browser.R
28-
import com.duckduckgo.app.browser.defaultbrowsing.prompts.ui.experiment.OnboardingHomeScreenWidgetExperiment
28+
import com.duckduckgo.app.browser.ui.dialogs.widgetprompt.OnboardingHomeScreenWidgetToggles
2929
import com.duckduckgo.app.cta.db.DismissedCtaDao
3030
import com.duckduckgo.app.cta.model.CtaId
3131
import com.duckduckgo.app.cta.model.DismissedCta
@@ -60,6 +60,7 @@ import com.duckduckgo.duckplayer.api.DuckPlayer.DuckPlayerState.DISABLED
6060
import com.duckduckgo.duckplayer.api.DuckPlayer.DuckPlayerState.ENABLED
6161
import com.duckduckgo.duckplayer.api.DuckPlayer.UserPreferences
6262
import com.duckduckgo.duckplayer.api.PrivatePlayerMode.AlwaysAsk
63+
import com.duckduckgo.feature.toggles.api.FakeFeatureToggleFactory
6364
import com.duckduckgo.feature.toggles.api.Toggle
6465
import com.duckduckgo.subscriptions.api.SubscriptionRebrandingFeatureToggle
6566
import com.duckduckgo.subscriptions.api.Subscriptions
@@ -121,7 +122,7 @@ class CtaViewModelTest {
121122

122123
private val mockBrokenSitePrompt: BrokenSitePrompt = mock()
123124

124-
private val mockOnboardingHomeScreenWidgetExperiment: OnboardingHomeScreenWidgetExperiment = mock()
125+
private val fakeOnboardingHomeScreenWidgetToggles = FakeFeatureToggleFactory.create(OnboardingHomeScreenWidgetToggles::class.java)
125126

126127
private val mockOnboardingDesignExperimentManager: OnboardingDesignExperimentManager = mock()
127128

@@ -183,7 +184,7 @@ class CtaViewModelTest {
183184
subscriptions = mockSubscriptions,
184185
duckPlayer = mockDuckPlayer,
185186
brokenSitePrompt = mockBrokenSitePrompt,
186-
onboardingHomeScreenWidgetExperiment = mockOnboardingHomeScreenWidgetExperiment,
187+
onboardingHomeScreenWidgetToggles = fakeOnboardingHomeScreenWidgetToggles,
187188
onboardingDesignExperimentManager = mockOnboardingDesignExperimentManager,
188189
rebrandingFeatureToggle = mockRebrandingFeatureToggle,
189190
)
@@ -356,7 +357,8 @@ class CtaViewModelTest {
356357
fun whenRefreshCtaOnHomeTabAndHideTipsIsTrueAndWidgetCompatibleThenReturnWidgetCta() = runTest {
357358
whenever(mockSettingsDataStore.hideTips).thenReturn(true)
358359
whenever(mockWidgetCapabilities.supportsAutomaticWidgetAdd).thenReturn(true)
359-
whenever(mockOnboardingHomeScreenWidgetExperiment.isOnboardingHomeScreenWidgetExperiment()).thenReturn(false)
360+
fakeOnboardingHomeScreenWidgetToggles.self().setRawStoredState(Toggle.State(true))
361+
fakeOnboardingHomeScreenWidgetToggles.onboardingHomeScreenWidgetPrompt().setRawStoredState(Toggle.State(false))
360362

361363
val value = testee.refreshCta(coroutineRule.testDispatcher, isBrowserShowing = false, detectedRefreshPatterns = detectedRefreshPatterns)
362364
assertTrue(value is HomePanelCta.AddWidgetAuto)
@@ -382,7 +384,8 @@ class CtaViewModelTest {
382384
whenever(mockSettingsDataStore.hideTips).thenReturn(true)
383385
whenever(mockWidgetCapabilities.supportsAutomaticWidgetAdd).thenReturn(true)
384386
whenever(mockWidgetCapabilities.hasInstalledWidgets).thenReturn(false)
385-
whenever(mockOnboardingHomeScreenWidgetExperiment.isOnboardingHomeScreenWidgetExperiment()).thenReturn(false)
387+
fakeOnboardingHomeScreenWidgetToggles.self().setRawStoredState(Toggle.State(true))
388+
fakeOnboardingHomeScreenWidgetToggles.onboardingHomeScreenWidgetPrompt().setRawStoredState(Toggle.State(false))
386389

387390
val value = testee.refreshCta(coroutineRule.testDispatcher, isBrowserShowing = false, detectedRefreshPatterns = detectedRefreshPatterns)
388391
assertTrue(value is HomePanelCta.AddWidgetAuto)
@@ -393,7 +396,8 @@ class CtaViewModelTest {
393396
whenever(mockSettingsDataStore.hideTips).thenReturn(true)
394397
whenever(mockWidgetCapabilities.supportsAutomaticWidgetAdd).thenReturn(true)
395398
whenever(mockWidgetCapabilities.hasInstalledWidgets).thenReturn(false)
396-
whenever(mockOnboardingHomeScreenWidgetExperiment.isOnboardingHomeScreenWidgetExperiment()).thenReturn(true)
399+
fakeOnboardingHomeScreenWidgetToggles.self().setRawStoredState(Toggle.State(true))
400+
fakeOnboardingHomeScreenWidgetToggles.onboardingHomeScreenWidgetPrompt().setRawStoredState(Toggle.State(true))
397401

398402
val value = testee.refreshCta(coroutineRule.testDispatcher, isBrowserShowing = false, detectedRefreshPatterns = detectedRefreshPatterns)
399403
assertTrue(value is HomePanelCta.AddWidgetAutoOnboardingExperiment)
@@ -897,7 +901,8 @@ class CtaViewModelTest {
897901
whenever(mockDismissedCtaDao.exists(CtaId.DAX_INTRO_VISIT_SITE)).thenReturn(true)
898902
whenever(mockDismissedCtaDao.exists(CtaId.DAX_END)).thenReturn(true)
899903
whenever(mockWidgetCapabilities.supportsAutomaticWidgetAdd).thenReturn(true)
900-
whenever(mockOnboardingHomeScreenWidgetExperiment.isOnboardingHomeScreenWidgetExperiment()).thenReturn(false)
904+
fakeOnboardingHomeScreenWidgetToggles.self().setRawStoredState(Toggle.State(true))
905+
fakeOnboardingHomeScreenWidgetToggles.onboardingHomeScreenWidgetPrompt().setRawStoredState(Toggle.State(false))
901906

902907
val value = testee.refreshCta(coroutineRule.testDispatcher, isBrowserShowing = false, detectedRefreshPatterns = detectedRefreshPatterns)
903908
assertFalse(value is DaxBubbleCta.DaxPrivacyProCta)

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ import com.duckduckgo.app.browser.customtabs.CustomTabPixelNames
124124
import com.duckduckgo.app.browser.customtabs.CustomTabViewModel.Companion.CUSTOM_TAB_NAME_PREFIX
125125
import com.duckduckgo.app.browser.databinding.FragmentBrowserTabBinding
126126
import com.duckduckgo.app.browser.databinding.HttpAuthenticationBinding
127-
import com.duckduckgo.app.browser.defaultbrowsing.prompts.ui.experiment.ExperimentalHomeScreenWidgetBottomSheetDialog
128127
import com.duckduckgo.app.browser.downloader.BlobConverterInjector
129128
import com.duckduckgo.app.browser.favicon.FaviconManager
130129
import com.duckduckgo.app.browser.filechooser.FileChooserIntentBuilder
@@ -159,6 +158,7 @@ import com.duckduckgo.app.browser.tabpreview.WebViewPreviewGenerator
159158
import com.duckduckgo.app.browser.tabpreview.WebViewPreviewPersister
160159
import com.duckduckgo.app.browser.ui.dialogs.AutomaticFireproofDialogOptions
161160
import com.duckduckgo.app.browser.ui.dialogs.LaunchInExternalAppOptions
161+
import com.duckduckgo.app.browser.ui.dialogs.widgetprompt.AlternativeHomeScreenWidgetBottomSheetDialog
162162
import com.duckduckgo.app.browser.urlextraction.DOMUrlExtractor
163163
import com.duckduckgo.app.browser.urlextraction.UrlExtractingWebView
164164
import com.duckduckgo.app.browser.urlextraction.UrlExtractingWebViewClient
@@ -603,7 +603,7 @@ class BrowserTabFragment :
603603

604604
private lateinit var popupMenu: BrowserPopupMenu
605605
private lateinit var ctaBottomSheet: PromoBottomSheetDialog
606-
private lateinit var experimentalBottomSheet: ExperimentalHomeScreenWidgetBottomSheetDialog
606+
private lateinit var widgetBottomSheetDialog: AlternativeHomeScreenWidgetBottomSheetDialog
607607

608608
private lateinit var autoCompleteSuggestionsAdapter: BrowserAutoCompleteSuggestionsAdapter
609609

@@ -4646,23 +4646,23 @@ class BrowserTabFragment :
46464646

46474647
private fun showBottomSheetCta(configuration: HomePanelCta) {
46484648
if (configuration is AddWidgetAutoOnboardingExperiment) {
4649-
showExperimentalHomeWidget(configuration)
4649+
showAlternativeHomeWidgetPrompt(configuration)
46504650
} else {
46514651
showHomeCta(configuration)
46524652
}
46534653
}
46544654

4655-
private fun showExperimentalHomeWidget(
4655+
private fun showAlternativeHomeWidgetPrompt(
46564656
configuration: HomePanelCta,
46574657
) {
46584658
hideDaxCta()
46594659

4660-
if (!::experimentalBottomSheet.isInitialized) {
4661-
experimentalBottomSheet = ExperimentalHomeScreenWidgetBottomSheetDialog(
4660+
if (!::widgetBottomSheetDialog.isInitialized) {
4661+
widgetBottomSheetDialog = AlternativeHomeScreenWidgetBottomSheetDialog(
46624662
context = requireContext(),
46634663
isLightModeEnabled = appTheme.isLightModeEnabled(),
46644664
)
4665-
experimentalBottomSheet.eventListener = object : ExperimentalHomeScreenWidgetBottomSheetDialog.EventListener {
4665+
widgetBottomSheetDialog.eventListener = object : AlternativeHomeScreenWidgetBottomSheetDialog.EventListener {
46664666
override fun onShown() {
46674667
viewModel.onCtaShown()
46684668
}
@@ -4679,10 +4679,10 @@ class BrowserTabFragment :
46794679
viewModel.onUserClickCtaSecondaryButton(configuration)
46804680
}
46814681
}
4682-
experimentalBottomSheet.show()
4682+
widgetBottomSheetDialog.show()
46834683
} else {
4684-
if (!experimentalBottomSheet.isShowing) {
4685-
experimentalBottomSheet.show()
4684+
if (!widgetBottomSheetDialog.isShowing) {
4685+
widgetBottomSheetDialog.show()
46864686
}
46874687
}
46884688
}

app/src/main/java/com/duckduckgo/app/browser/defaultbrowsing/prompts/ui/experiment/OnboardingHomeScreenWidgetExperiment.kt

Lines changed: 0 additions & 140 deletions
This file was deleted.

0 commit comments

Comments
 (0)