Skip to content

Commit 23f4868

Browse files
committed
Merge branch 'release/5.210.0' into main
2 parents f02110c + 3a657c4 commit 23f4868

File tree

194 files changed

+5592
-425
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

194 files changed

+5592
-425
lines changed

.github/workflows/update-content-scope.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
env:
5858
RELEASE_VERSION: ${{ steps.extract-release-version.outputs._1}}
5959
id: create-pr
60-
uses: peter-evans/create-pull-request@v5.0.2
60+
uses: peter-evans/create-pull-request@v6.1.0
6161
with:
6262
base: "develop"
6363
title: Update content scope scripts to version ${{ steps.extract-release-version.outputs._1}}

.github/workflows/update-ref-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
env:
6565
RELEASE_VERSION: ${{ steps.extract-release-version.outputs._1}}
6666
id: create-pr
67-
uses: peter-evans/create-pull-request@v5
67+
uses: peter-evans/create-pull-request@v6.1.0
6868
with:
6969
base: "develop"
7070
title: Update reference tests to version ${{ steps.extract-release-version.outputs._1}}

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

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -95,27 +95,29 @@ class ReportBreakageCategorySingleChoiceActivity : DuckDuckGoActivity() {
9595
viewModel.setCategories(brokenApp.breakageCategories)
9696
val categories = brokenApp.breakageCategories.map { it.description }
9797
binding.categoriesSelection.onAction {
98-
RadioListAlertDialogBuilder(this)
99-
.setTitle(getString(R.string.atp_ReportBreakageCategoriesTitle))
100-
.setOptions(categories, viewModel.indexSelected + 1)
101-
.setPositiveButton(android.R.string.ok)
102-
.setNegativeButton(android.R.string.cancel)
103-
.addEventListener(
104-
object : RadioListAlertDialogBuilder.EventListener() {
105-
override fun onRadioItemSelected(selectedItem: Int) {
106-
viewModel.onCategoryIndexChanged(selectedItem - 1)
107-
}
108-
109-
override fun onPositiveButtonClicked(selectedItem: Int) {
110-
viewModel.onCategoryAccepted()
111-
}
112-
113-
override fun onNegativeButtonClicked() {
114-
viewModel.onCategorySelectionCancelled()
115-
}
116-
},
117-
)
118-
.show()
98+
if (!isFinishing && !isDestroyed) {
99+
RadioListAlertDialogBuilder(this)
100+
.setTitle(getString(R.string.atp_ReportBreakageCategoriesTitle))
101+
.setOptions(categories, viewModel.indexSelected + 1)
102+
.setPositiveButton(android.R.string.ok)
103+
.setNegativeButton(android.R.string.cancel)
104+
.addEventListener(
105+
object : RadioListAlertDialogBuilder.EventListener() {
106+
override fun onRadioItemSelected(selectedItem: Int) {
107+
viewModel.onCategoryIndexChanged(selectedItem - 1)
108+
}
109+
110+
override fun onPositiveButtonClicked(selectedItem: Int) {
111+
viewModel.onCategoryAccepted()
112+
}
113+
114+
override fun onNegativeButtonClicked() {
115+
viewModel.onCategorySelectionCancelled()
116+
}
117+
},
118+
)
119+
.show()
120+
}
119121
}
120122
binding.ctaNextFormSubmit.setOnClickListener { viewModel.onSubmitPressed() }
121123
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ import com.duckduckgo.app.statistics.api.StatisticsUpdater
147147
import com.duckduckgo.app.statistics.pixels.Pixel
148148
import com.duckduckgo.app.statistics.pixels.Pixel.PixelParameter
149149
import com.duckduckgo.app.statistics.pixels.Pixel.PixelType.COUNT
150+
import com.duckduckgo.app.statistics.pixels.Pixel.PixelType.DAILY
150151
import com.duckduckgo.app.statistics.pixels.Pixel.PixelType.UNIQUE
151152
import com.duckduckgo.app.surrogates.SurrogateResponse
152153
import com.duckduckgo.app.tabs.model.TabEntity
@@ -452,6 +453,8 @@ class BrowserTabViewModelTest {
452453

453454
private val mockEnabledToggle: Toggle = mock { on { it.isEnabled() } doReturn true }
454455

456+
private val mockDisabledToggle: Toggle = mock { on { it.isEnabled() } doReturn false }
457+
455458
private val mockPrivacyProtectionsPopupManager: PrivacyProtectionsPopupManager = mock()
456459

457460
private val mockPrivacyProtectionsToggleUsageListener: PrivacyProtectionsToggleUsageListener = mock()
@@ -666,6 +669,7 @@ class BrowserTabViewModelTest {
666669

667670
@Test
668671
fun whenViewBecomesVisibleAndHomeShowingThenKeyboardShown() = runTest {
672+
whenever(mockExtendedOnboardingFeatureToggles.noBrowserCtas()).thenReturn(mockDisabledToggle)
669673
whenever(mockWidgetCapabilities.hasInstalledWidgets).thenReturn(true)
670674

671675
setBrowserShowing(false)
@@ -687,6 +691,7 @@ class BrowserTabViewModelTest {
687691
fun whenViewBecomesVisibleAndHomeShowingThenRefreshCtaIsCalled() {
688692
runTest {
689693
setBrowserShowing(false)
694+
whenever(mockExtendedOnboardingFeatureToggles.noBrowserCtas()).thenReturn(mockDisabledToggle)
690695
val observer = ValueCaptorObserver<CtaViewState>()
691696
testee.ctaViewState.observeForever(observer)
692697

@@ -2348,6 +2353,7 @@ class BrowserTabViewModelTest {
23482353

23492354
@Test
23502355
fun whenCtaRefreshedAndOnlyStandardAddSupportedAndWidgetAlreadyInstalledThenCtaIsNull() = runTest {
2356+
whenever(mockExtendedOnboardingFeatureToggles.noBrowserCtas()).thenReturn(mockDisabledToggle)
23512357
whenever(mockWidgetCapabilities.supportsAutomaticWidgetAdd).thenReturn(false)
23522358
whenever(mockWidgetCapabilities.hasInstalledWidgets).thenReturn(true)
23532359
testee.refreshCta()
@@ -2357,6 +2363,7 @@ class BrowserTabViewModelTest {
23572363
@Test
23582364
fun whenCtaRefreshedAndIsNewTabIsFalseThenReturnNull() = runTest {
23592365
setBrowserShowing(true)
2366+
whenever(mockExtendedOnboardingFeatureToggles.noBrowserCtas()).thenReturn(mockDisabledToggle)
23602367
whenever(mockWidgetCapabilities.supportsAutomaticWidgetAdd).thenReturn(true)
23612368
whenever(mockWidgetCapabilities.hasInstalledWidgets).thenReturn(false)
23622369
testee.refreshCta()
@@ -2365,6 +2372,7 @@ class BrowserTabViewModelTest {
23652372

23662373
@Test
23672374
fun whenCtaRefreshedAndOnboardingCompleteThenViewStateUpdated() = runTest {
2375+
whenever(mockExtendedOnboardingFeatureToggles.noBrowserCtas()).thenReturn(mockDisabledToggle)
23682376
whenever(mockWidgetCapabilities.supportsAutomaticWidgetAdd).thenReturn(false)
23692377
whenever(mockWidgetCapabilities.hasInstalledWidgets).thenReturn(true)
23702378
whenever(mockDismissedCtaDao.exists(DAX_END)).thenReturn(true)
@@ -2378,6 +2386,7 @@ class BrowserTabViewModelTest {
23782386
@Test
23792387
fun whenCtaRefreshedAndBrowserShowingThenViewStateUpdated() = runTest {
23802388
setBrowserShowing(true)
2389+
whenever(mockExtendedOnboardingFeatureToggles.noBrowserCtas()).thenReturn(mockDisabledToggle)
23812390
whenever(mockWidgetCapabilities.supportsAutomaticWidgetAdd).thenReturn(false)
23822391
whenever(mockWidgetCapabilities.hasInstalledWidgets).thenReturn(true)
23832392
whenever(mockDismissedCtaDao.exists(DAX_END)).thenReturn(true)
@@ -5311,6 +5320,7 @@ class BrowserTabViewModelTest {
53115320

53125321
assertCommandIssued<Command.LaunchTabSwitcher>()
53135322
verify(mockPixel).fire(AppPixelName.TAB_MANAGER_CLICKED)
5323+
verify(mockPixel).fire(AppPixelName.TAB_MANAGER_CLICKED_DAILY, emptyMap(), emptyMap(), DAILY)
53145324
}
53155325

53165326
@Test

app/src/androidTest/java/com/duckduckgo/app/tabs/model/TabDataRepositoryTest.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import com.duckduckgo.app.global.db.AppDatabase
3030
import com.duckduckgo.app.global.model.SiteFactoryImpl
3131
import com.duckduckgo.app.privacy.db.UserAllowListRepository
3232
import com.duckduckgo.app.tabs.db.TabsDao
33+
import com.duckduckgo.app.tabs.store.TabSwitcherDataStore
3334
import com.duckduckgo.app.trackerdetection.EntityLookup
3435
import com.duckduckgo.common.test.CoroutineTestRule
3536
import com.duckduckgo.common.test.InstantSchedulersRule
@@ -409,6 +410,7 @@ class TabDataRepositoryTest {
409410
contentBlocking: ContentBlocking = mock(),
410411
webViewPreviewPersister: WebViewPreviewPersister = mock(),
411412
faviconManager: FaviconManager = mock(),
413+
tabSwitcherDataStore: TabSwitcherDataStore = mock(),
412414
): TabDataRepository {
413415
return TabDataRepository(
414416
dao,
@@ -422,6 +424,7 @@ class TabDataRepositoryTest {
422424
),
423425
webViewPreviewPersister,
424426
faviconManager,
427+
tabSwitcherDataStore,
425428
coroutinesTestRule.testScope,
426429
coroutinesTestRule.testDispatcherProvider,
427430
)

app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@
236236
<activity
237237
android:name="com.duckduckgo.app.dispatchers.IntentDispatcherActivity"
238238
android:theme="@style/Theme.AppCompat.Transparent.NoActionBar"
239-
android:excludeFromRecents="true"
240239
android:exported="true">
241240

242241
<!-- Allows app to become default browser -->
@@ -411,6 +410,11 @@
411410
android:exported="false"
412411
android:label="@string/privateSearchActivityTitle"
413412
android:parentActivityName="com.duckduckgo.app.settings.SettingsActivity" />
413+
<activity
414+
android:name="com.duckduckgo.app.generalsettings.GeneralSettingsActivity"
415+
android:exported="false"
416+
android:label="@string/generalSettingsActivityTitle"
417+
android:parentActivityName="com.duckduckgo.app.settings.SettingsActivity" />
414418
<activity
415419
android:name="com.duckduckgo.app.webtrackingprotection.WebTrackingProtectionActivity"
416420
android:exported="false"

app/src/main/java/com/duckduckgo/app/accessibility/AccessibilitySettingsViewModel.kt

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import androidx.lifecycle.viewModelScope
2121
import com.duckduckgo.anvil.annotations.ContributesViewModel
2222
import com.duckduckgo.app.accessibility.data.AccessibilitySettingsDataStore
2323
import com.duckduckgo.app.statistics.pixels.Pixel
24+
import com.duckduckgo.common.utils.DispatcherProvider
2425
import com.duckduckgo.di.scopes.ActivityScope
2526
import com.duckduckgo.voice.api.VoiceSearchAvailability
2627
import com.duckduckgo.voice.impl.VoiceSearchPixelNames.VOICE_SEARCH_OFF
@@ -30,6 +31,7 @@ import javax.inject.Inject
3031
import kotlinx.coroutines.flow.MutableStateFlow
3132
import kotlinx.coroutines.flow.StateFlow
3233
import kotlinx.coroutines.launch
34+
import kotlinx.coroutines.withContext
3335
import timber.log.Timber
3436

3537
@ContributesViewModel(ActivityScope::class)
@@ -38,6 +40,7 @@ class AccessibilitySettingsViewModel @Inject constructor(
3840
private val voiceSearchAvailability: VoiceSearchAvailability,
3941
private val voiceSearchRepository: VoiceSearchRepository,
4042
private val pixel: Pixel,
43+
private val dispatcherProvider: DispatcherProvider,
4144
) : ViewModel() {
4245

4346
data class ViewState(
@@ -103,19 +106,21 @@ class AccessibilitySettingsViewModel @Inject constructor(
103106
}
104107

105108
fun onVoiceSearchChanged(checked: Boolean) {
106-
voiceSearchRepository.setVoiceSearchUserEnabled(checked)
107-
if (checked) {
108-
voiceSearchRepository.resetVoiceSearchDismissed()
109-
pixel.fire(VOICE_SEARCH_ON)
110-
} else {
111-
pixel.fire(VOICE_SEARCH_OFF)
112-
}
113-
viewModelScope.launch {
114-
viewState.emit(
115-
currentViewState().copy(
116-
voiceSearchEnabled = voiceSearchAvailability.isVoiceSearchAvailable,
117-
),
118-
)
109+
viewModelScope.launch(dispatcherProvider.io()) {
110+
voiceSearchRepository.setVoiceSearchUserEnabled(checked)
111+
if (checked) {
112+
voiceSearchRepository.resetVoiceSearchDismissed()
113+
pixel.fire(VOICE_SEARCH_ON)
114+
} else {
115+
pixel.fire(VOICE_SEARCH_OFF)
116+
}
117+
withContext(dispatcherProvider.main()) {
118+
viewState.emit(
119+
currentViewState().copy(
120+
voiceSearchEnabled = voiceSearchAvailability.isVoiceSearchAvailable,
121+
),
122+
)
123+
}
119124
}
120125
}
121126

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import com.duckduckgo.app.downloads.DownloadsScreens.DownloadsScreenNoParams
4545
import com.duckduckgo.app.feedback.ui.common.FeedbackActivity
4646
import com.duckduckgo.app.fire.DataClearer
4747
import com.duckduckgo.app.fire.DataClearerForegroundAppRestartPixel
48+
import com.duckduckgo.app.firebutton.FireButtonStore
4849
import com.duckduckgo.app.global.*
4950
import com.duckduckgo.app.global.events.db.UserEventsStore
5051
import com.duckduckgo.app.global.rating.PromptCount
@@ -118,6 +119,9 @@ open class BrowserActivity : DuckDuckGoActivity() {
118119

119120
@Inject lateinit var dispatcherProvider: DispatcherProvider
120121

122+
@Inject
123+
lateinit var fireButtonStore: FireButtonStore
124+
121125
private val lastActiveTabs = TabList()
122126

123127
private var currentTab: BrowserTabFragment? = null
@@ -440,6 +444,7 @@ open class BrowserActivity : DuckDuckGoActivity() {
440444
userEventsStore = userEventsStore,
441445
appCoroutineScope = appCoroutineScope,
442446
dispatcherProvider = dispatcherProvider,
447+
fireButtonStore = fireButtonStore,
443448
)
444449
dialog.clearStarted = {
445450
removeObservers()
@@ -676,6 +681,7 @@ open class BrowserActivity : DuckDuckGoActivity() {
676681
override fun onDialogShown() {
677682
viewModel.onGiveFeedbackDialogShown(promptCount)
678683
}
684+
679685
override fun onDialogCancelled() {
680686
viewModel.onUserCancelledGiveFeedbackDialog(promptCount)
681687
}

0 commit comments

Comments
 (0)