Bug 1950205 - Add recent searches settings. r=android-reviewers,android-l10n-reviewers,delphine,gl
Differential Revision: https://phabricator.services.mozilla.com/D239774
This commit is contained in:
@@ -50,8 +50,8 @@ private const val MAXIMUM_ALLOWED_SUGGESTIONS_LIMIT_REACHED =
|
|||||||
* highest scored suggestion URL.
|
* highest scored suggestion URL.
|
||||||
* @param showEditSuggestion optional parameter to specify if the suggestion should show the edit button.
|
* @param showEditSuggestion optional parameter to specify if the suggestion should show the edit button.
|
||||||
* @param suggestionsHeader optional parameter to specify if the suggestion should have a header
|
* @param suggestionsHeader optional parameter to specify if the suggestion should have a header
|
||||||
* @param showSuggestionsWhenEmpty optional parameter to specify if suggestions should be shown even
|
* @param showSuggestionsOnlyWhenEmpty optional parameter to specify if suggestions should be shown
|
||||||
* when the input text is empty.
|
* only when the input text is empty.
|
||||||
*/
|
*/
|
||||||
class SearchTermSuggestionsProvider(
|
class SearchTermSuggestionsProvider(
|
||||||
private val historyStorage: PlacesHistoryStorage,
|
private val historyStorage: PlacesHistoryStorage,
|
||||||
@@ -63,7 +63,7 @@ class SearchTermSuggestionsProvider(
|
|||||||
private val engine: Engine? = null,
|
private val engine: Engine? = null,
|
||||||
private val showEditSuggestion: Boolean = true,
|
private val showEditSuggestion: Boolean = true,
|
||||||
private val suggestionsHeader: String? = null,
|
private val suggestionsHeader: String? = null,
|
||||||
private val showSuggestionsWhenEmpty: Boolean = false,
|
private val showSuggestionsOnlyWhenEmpty: Boolean = false,
|
||||||
) : AwesomeBar.SuggestionProvider {
|
) : AwesomeBar.SuggestionProvider {
|
||||||
init {
|
init {
|
||||||
if (maxNumberOfSuggestions > SEARCH_TERMS_MAXIMUM_ALLOWED_SUGGESTIONS_LIMIT) {
|
if (maxNumberOfSuggestions > SEARCH_TERMS_MAXIMUM_ALLOWED_SUGGESTIONS_LIMIT) {
|
||||||
@@ -78,12 +78,13 @@ class SearchTermSuggestionsProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun onInputChanged(text: String): List<AwesomeBar.Suggestion> = coroutineScope {
|
override suspend fun onInputChanged(text: String): List<AwesomeBar.Suggestion> = coroutineScope {
|
||||||
|
val shouldReturnEmpty =
|
||||||
|
(text.isBlank() && !showSuggestionsOnlyWhenEmpty) ||
|
||||||
|
(text.isNotBlank() && showSuggestionsOnlyWhenEmpty)
|
||||||
|
|
||||||
|
if (shouldReturnEmpty) return@coroutineScope emptyList()
|
||||||
|
|
||||||
historyStorage.cancelReads(text)
|
historyStorage.cancelReads(text)
|
||||||
|
|
||||||
if (!showSuggestionsWhenEmpty && text.isBlank()) {
|
|
||||||
return@coroutineScope emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
val suggestions = withContext(this.coroutineContext) {
|
val suggestions = withContext(this.coroutineContext) {
|
||||||
historyStorage.getHistoryMetadataSince(Long.MIN_VALUE)
|
historyStorage.getHistoryMetadataSince(Long.MIN_VALUE)
|
||||||
.asSequence()
|
.asSequence()
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class SearchTermSuggestionsProviderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN an empty input and should show suggestions when empty WHEN querying suggestions THEN return suggestions from configured history storage`() = runTest {
|
fun `GIVEN only an empty input should show suggestions THEN return suggestions from configured history storage only when input is empty`() = runTest {
|
||||||
val searchEngineIcon: Bitmap = mock()
|
val searchEngineIcon: Bitmap = mock()
|
||||||
val provider = SearchTermSuggestionsProvider(
|
val provider = SearchTermSuggestionsProvider(
|
||||||
historyStorage = storage,
|
historyStorage = storage,
|
||||||
@@ -86,10 +86,10 @@ class SearchTermSuggestionsProviderTest {
|
|||||||
searchEngine = searchEngine,
|
searchEngine = searchEngine,
|
||||||
icon = searchEngineIcon,
|
icon = searchEngineIcon,
|
||||||
showEditSuggestion = true,
|
showEditSuggestion = true,
|
||||||
showSuggestionsWhenEmpty = true,
|
showSuggestionsOnlyWhenEmpty = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
val suggestions = provider.onInputChanged("")
|
var suggestions = provider.onInputChanged("")
|
||||||
|
|
||||||
assertEquals(1, suggestions.size)
|
assertEquals(1, suggestions.size)
|
||||||
assertEquals(provider, suggestions[0].provider)
|
assertEquals(provider, suggestions[0].provider)
|
||||||
@@ -103,14 +103,56 @@ class SearchTermSuggestionsProviderTest {
|
|||||||
assertNotNull(suggestions[0].onSuggestionClicked)
|
assertNotNull(suggestions[0].onSuggestionClicked)
|
||||||
assertNull(suggestions[0].onChipClicked)
|
assertNull(suggestions[0].onChipClicked)
|
||||||
assertEquals(Int.MAX_VALUE - 2, suggestions[0].score)
|
assertEquals(Int.MAX_VALUE - 2, suggestions[0].score)
|
||||||
|
|
||||||
|
suggestions = provider.onInputChanged("fir")
|
||||||
|
assertEquals(0, suggestions.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN only not empty input should show suggestions THEN return suggestions from configured history storage only when input is not empty`() = runTest {
|
||||||
|
val searchEngineIcon: Bitmap = mock()
|
||||||
|
val provider = SearchTermSuggestionsProvider(
|
||||||
|
historyStorage = storage,
|
||||||
|
searchUseCase = mock(),
|
||||||
|
searchEngine = searchEngine,
|
||||||
|
icon = searchEngineIcon,
|
||||||
|
showEditSuggestion = true,
|
||||||
|
)
|
||||||
|
|
||||||
|
var suggestions = provider.onInputChanged("")
|
||||||
|
assertEquals(0, suggestions.size)
|
||||||
|
|
||||||
|
suggestions = provider.onInputChanged("fir")
|
||||||
|
assertEquals(1, suggestions.size)
|
||||||
|
assertEquals(provider, suggestions[0].provider)
|
||||||
|
assertEquals(historyEntry.key.searchTerm, suggestions[0].title)
|
||||||
|
assertNull(suggestions[0].description)
|
||||||
|
assertEquals(historyEntry.key.searchTerm, suggestions[0].editSuggestion)
|
||||||
|
assertEquals(searchEngineIcon, suggestions[0].icon)
|
||||||
|
assertNull(suggestions[0].indicatorIcon)
|
||||||
|
assertTrue(suggestions[0].chips.isEmpty())
|
||||||
|
assertTrue(suggestions[0].flags.isEmpty())
|
||||||
|
assertNotNull(suggestions[0].onSuggestionClicked)
|
||||||
|
assertNull(suggestions[0].onChipClicked)
|
||||||
|
assertEquals(Int.MAX_VALUE - 2, suggestions[0].score)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN an empty input WHEN querying suggestions THEN cleanup all read operations for the current query`() = runTest {
|
fun `GIVEN an empty input AND should show empty query WHEN querying suggestions THEN do not cleanup read operations for the empty query`() = runTest {
|
||||||
val provider = SearchTermSuggestionsProvider(storage, mock(), searchEngine)
|
val provider = SearchTermSuggestionsProvider(storage, mock(), searchEngine)
|
||||||
|
|
||||||
provider.onInputChanged("")
|
provider.onInputChanged("")
|
||||||
|
|
||||||
|
verify(storage, never()).cancelReads()
|
||||||
|
verify(storage, never()).cancelReads("")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN an empty input AND should show empty query WHEN querying suggestions THEN cleanup read operations for the empty query`() = runTest {
|
||||||
|
val provider = SearchTermSuggestionsProvider(storage, mock(), searchEngine, showSuggestionsOnlyWhenEmpty = true)
|
||||||
|
|
||||||
|
provider.onInputChanged("")
|
||||||
|
|
||||||
verify(storage, never()).cancelReads()
|
verify(storage, never()).cancelReads()
|
||||||
verify(storage).cancelReads("")
|
verify(storage).cancelReads("")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -479,11 +479,11 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
|
|||||||
observeClipboardState()
|
observeClipboardState()
|
||||||
observeSuggestionProvidersState()
|
observeSuggestionProvidersState()
|
||||||
|
|
||||||
val isPrivate = (requireActivity() as HomeActivity).browsingModeManager.mode.isPrivate
|
val browsingMode = (requireActivity() as HomeActivity).browsingModeManager.mode
|
||||||
if (
|
if (view.context.settings().shouldShowTrendingOrRecentSearchSuggestions(
|
||||||
view.context.settings().shouldShowTrendingSearchSuggestions(
|
browsingMode = browsingMode,
|
||||||
isPrivate,
|
isTrendingSuggestionSupported = requireComponents.core.store.state.search
|
||||||
requireComponents.core.store.state.search.selectedOrDefaultSearchEngine,
|
.selectedOrDefaultSearchEngine?.trendingUrl != null,
|
||||||
) && (
|
) && (
|
||||||
store.state.query.isNotEmpty() ||
|
store.state.query.isNotEmpty() ||
|
||||||
FxNimbus.features.searchSuggestionsOnHomepage.value().enabled
|
FxNimbus.features.searchSuggestionsOnHomepage.value().enabled
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ class AwesomeBarView(
|
|||||||
state: SearchProviderState,
|
state: SearchProviderState,
|
||||||
): MutableSet<AwesomeBar.SuggestionProvider> {
|
): MutableSet<AwesomeBar.SuggestionProvider> {
|
||||||
val providersToAdd = mutableSetOf<AwesomeBar.SuggestionProvider>()
|
val providersToAdd = mutableSetOf<AwesomeBar.SuggestionProvider>()
|
||||||
val isPrivate = activity.browsingModeManager.mode.isPrivate
|
val browsingMode = activity.browsingModeManager.mode
|
||||||
|
|
||||||
when (state.searchEngineSource) {
|
when (state.searchEngineSource) {
|
||||||
is SearchEngineSource.History -> {
|
is SearchEngineSource.History -> {
|
||||||
@@ -314,11 +314,13 @@ class AwesomeBarView(
|
|||||||
|
|
||||||
if (state.showSearchTermHistory) {
|
if (state.showSearchTermHistory) {
|
||||||
getSearchTermSuggestionsProvider(
|
getSearchTermSuggestionsProvider(
|
||||||
state.searchEngineSource,
|
searchEngineSource = state.searchEngineSource,
|
||||||
activity.settings().shouldShowTrendingSearchSuggestions(
|
)?.let { providersToAdd.add(it) }
|
||||||
isPrivate,
|
}
|
||||||
state.searchEngineSource.searchEngine,
|
|
||||||
),
|
if (activity.settings().shouldShowRecentSearchSuggestions) {
|
||||||
|
getRecentSearchSuggestionsProvider(
|
||||||
|
searchEngineSource = state.searchEngineSource,
|
||||||
)?.let { providersToAdd.add(it) }
|
)?.let { providersToAdd.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,8 +409,8 @@ class AwesomeBarView(
|
|||||||
providersToAdd.add(searchEngineSuggestionProvider)
|
providersToAdd.add(searchEngineSuggestionProvider)
|
||||||
|
|
||||||
if (activity.settings().shouldShowTrendingSearchSuggestions(
|
if (activity.settings().shouldShowTrendingSearchSuggestions(
|
||||||
isPrivate,
|
browsingMode = browsingMode,
|
||||||
state.searchEngineSource.searchEngine,
|
isTrendingSuggestionSupported = state.searchEngineSource.searchEngine?.trendingUrl != null,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
providersToAdd.add(defaultTopSitesSuggestionProvider)
|
providersToAdd.add(defaultTopSitesSuggestionProvider)
|
||||||
@@ -483,7 +485,6 @@ class AwesomeBarView(
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
internal fun getSearchTermSuggestionsProvider(
|
internal fun getSearchTermSuggestionsProvider(
|
||||||
searchEngineSource: SearchEngineSource,
|
searchEngineSource: SearchEngineSource,
|
||||||
showSuggestionsWhenEmpty: Boolean = false,
|
|
||||||
): AwesomeBar.SuggestionProvider? {
|
): AwesomeBar.SuggestionProvider? {
|
||||||
val validSearchEngine = searchEngineSource.searchEngine ?: return null
|
val validSearchEngine = searchEngineSource.searchEngine ?: return null
|
||||||
|
|
||||||
@@ -494,7 +495,23 @@ class AwesomeBarView(
|
|||||||
icon = getDrawable(activity, R.drawable.ic_history)?.toBitmap(),
|
icon = getDrawable(activity, R.drawable.ic_history)?.toBitmap(),
|
||||||
engine = engineForSpeculativeConnects,
|
engine = engineForSpeculativeConnects,
|
||||||
suggestionsHeader = getSearchEngineSuggestionsHeader(searchEngineSource.searchEngine),
|
suggestionsHeader = getSearchEngineSuggestionsHeader(searchEngineSource.searchEngine),
|
||||||
showSuggestionsWhenEmpty = showSuggestionsWhenEmpty,
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
internal fun getRecentSearchSuggestionsProvider(
|
||||||
|
searchEngineSource: SearchEngineSource,
|
||||||
|
): AwesomeBar.SuggestionProvider? {
|
||||||
|
val validSearchEngine = searchEngineSource.searchEngine ?: return null
|
||||||
|
|
||||||
|
return SearchTermSuggestionsProvider(
|
||||||
|
historyStorage = components.core.historyStorage,
|
||||||
|
searchUseCase = historySearchTermUseCase,
|
||||||
|
searchEngine = validSearchEngine,
|
||||||
|
icon = getDrawable(activity, R.drawable.ic_history)?.toBitmap(),
|
||||||
|
engine = engineForSpeculativeConnects,
|
||||||
|
suggestionsHeader = activity.getString(R.string.recent_searches_header),
|
||||||
|
showSuggestionsOnlyWhenEmpty = true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,12 @@ class SecretSettingsFragment : PreferenceFragmentCompat() {
|
|||||||
onPreferenceChangeListener = SharedPreferenceUpdater()
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requirePreference<SwitchPreference>(R.string.pref_key_enable_recent_searches).apply {
|
||||||
|
isVisible = Config.channel.isNightlyOrDebug
|
||||||
|
isChecked = context.settings().isRecentSearchesVisible
|
||||||
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
||||||
|
}
|
||||||
|
|
||||||
requirePreference<SwitchPreference>(R.string.pref_key_enable_fxsuggest).apply {
|
requirePreference<SwitchPreference>(R.string.pref_key_enable_fxsuggest).apply {
|
||||||
isVisible = FeatureFlags.FX_SUGGEST
|
isVisible = FeatureFlags.FX_SUGGEST
|
||||||
isChecked = context.settings().enableFxSuggest
|
isChecked = context.settings().enableFxSuggest
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ class SearchEngineFragment : PreferenceFragmentCompat() {
|
|||||||
requirePreference<CheckBoxPreference>(R.string.pref_key_show_trending_search_suggestions).apply {
|
requirePreference<CheckBoxPreference>(R.string.pref_key_show_trending_search_suggestions).apply {
|
||||||
isVisible = context.settings().isTrendingSearchesVisible
|
isVisible = context.settings().isTrendingSearchesVisible
|
||||||
}
|
}
|
||||||
|
requirePreference<SwitchPreference>(R.string.pref_key_show_recent_search_suggestions).apply {
|
||||||
|
isVisible = context.settings().isRecentSearchesVisible
|
||||||
|
}
|
||||||
|
|
||||||
view?.hideKeyboard()
|
view?.hideKeyboard()
|
||||||
}
|
}
|
||||||
@@ -74,6 +77,9 @@ class SearchEngineFragment : PreferenceFragmentCompat() {
|
|||||||
context.settings().shouldShowSearchSuggestions
|
context.settings().shouldShowSearchSuggestions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val recentSearchSuggestionsPreference =
|
||||||
|
requirePreference<SwitchPreference>(R.string.pref_key_show_recent_search_suggestions)
|
||||||
|
|
||||||
val autocompleteURLsPreference =
|
val autocompleteURLsPreference =
|
||||||
requirePreference<SwitchPreference>(R.string.pref_key_enable_autocomplete_urls).apply {
|
requirePreference<SwitchPreference>(R.string.pref_key_enable_autocomplete_urls).apply {
|
||||||
isChecked = context.settings().shouldAutocompleteInAwesomebar
|
isChecked = context.settings().shouldAutocompleteInAwesomebar
|
||||||
@@ -134,6 +140,7 @@ class SearchEngineFragment : PreferenceFragmentCompat() {
|
|||||||
showClipboardSuggestions.onPreferenceChangeListener = SharedPreferenceUpdater()
|
showClipboardSuggestions.onPreferenceChangeListener = SharedPreferenceUpdater()
|
||||||
searchSuggestionsInPrivatePreference.onPreferenceChangeListener = SharedPreferenceUpdater()
|
searchSuggestionsInPrivatePreference.onPreferenceChangeListener = SharedPreferenceUpdater()
|
||||||
trendingSearchSuggestionsPreference.onPreferenceChangeListener = SharedPreferenceUpdater()
|
trendingSearchSuggestionsPreference.onPreferenceChangeListener = SharedPreferenceUpdater()
|
||||||
|
recentSearchSuggestionsPreference.onPreferenceChangeListener = SharedPreferenceUpdater()
|
||||||
showVoiceSearchPreference.onPreferenceChangeListener = object : Preference.OnPreferenceChangeListener {
|
showVoiceSearchPreference.onPreferenceChangeListener = object : Preference.OnPreferenceChangeListener {
|
||||||
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
|
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
|
||||||
val newBooleanValue = newValue as? Boolean ?: return false
|
val newBooleanValue = newValue as? Boolean ?: return false
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import android.view.accessibility.AccessibilityManager
|
|||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.annotation.VisibleForTesting.Companion.PRIVATE
|
import androidx.annotation.VisibleForTesting.Companion.PRIVATE
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import mozilla.components.browser.state.search.SearchEngine
|
|
||||||
import mozilla.components.concept.engine.Engine.HttpsOnlyMode
|
import mozilla.components.concept.engine.Engine.HttpsOnlyMode
|
||||||
import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingMode
|
import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingMode
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
||||||
@@ -1119,11 +1118,39 @@ class Settings(private val appContext: Context) : PreferencesHolder {
|
|||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if trending searches should be shown to the user.
|
* Returns true if trending search suggestions should be shown to the user.
|
||||||
*/
|
*/
|
||||||
fun shouldShowTrendingSearchSuggestions(isPrivate: Boolean, searchEngine: SearchEngine?) =
|
fun shouldShowTrendingSearchSuggestions(
|
||||||
trendingSearchSuggestionsEnabled && isTrendingSearchesVisible &&
|
browsingMode: BrowsingMode,
|
||||||
searchEngine?.trendingUrl != null && (!isPrivate || shouldShowSearchSuggestionsInPrivate)
|
isTrendingSuggestionSupported: Boolean,
|
||||||
|
) =
|
||||||
|
trendingSearchSuggestionsEnabled && isTrendingSearchesVisible && isTrendingSuggestionSupported &&
|
||||||
|
(!browsingMode.isPrivate || shouldShowSearchSuggestionsInPrivate)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the user have enabled recent search in the search suggestions setting preference.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
internal var recentSearchSuggestionsEnabled by booleanPreference(
|
||||||
|
appContext.getPreferenceKey(R.string.pref_key_show_recent_search_suggestions),
|
||||||
|
default = true,
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if recent searches should be shown to the user.
|
||||||
|
*/
|
||||||
|
val shouldShowRecentSearchSuggestions: Boolean
|
||||||
|
get() = recentSearchSuggestionsEnabled && isRecentSearchesVisible
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if trending searches or recent searches should be shown to the user.
|
||||||
|
*/
|
||||||
|
fun shouldShowTrendingOrRecentSearchSuggestions(
|
||||||
|
browsingMode: BrowsingMode,
|
||||||
|
isTrendingSuggestionSupported: Boolean,
|
||||||
|
) =
|
||||||
|
shouldShowTrendingSearchSuggestions(browsingMode, isTrendingSuggestionSupported) ||
|
||||||
|
shouldShowRecentSearchSuggestions
|
||||||
|
|
||||||
var showSearchSuggestionsInPrivateOnboardingFinished by booleanPreference(
|
var showSearchSuggestionsInPrivateOnboardingFinished by booleanPreference(
|
||||||
appContext.getPreferenceKey(R.string.pref_key_show_search_suggestions_in_private_onboarding),
|
appContext.getPreferenceKey(R.string.pref_key_show_search_suggestions_in_private_onboarding),
|
||||||
@@ -1990,12 +2017,19 @@ class Settings(private val appContext: Context) : PreferencesHolder {
|
|||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if Trending Searches is enabled.
|
* Indicates if Trending Search Suggestions are enabled.
|
||||||
*/
|
*/
|
||||||
var isTrendingSearchesVisible by lazyFeatureFlagPreference(
|
var isTrendingSearchesVisible by booleanPreference(
|
||||||
key = appContext.getPreferenceKey(R.string.pref_key_enable_trending_searches),
|
key = appContext.getPreferenceKey(R.string.pref_key_enable_trending_searches),
|
||||||
default = { FxNimbus.features.trendingSearches.value().enabled },
|
default = FxNimbus.features.trendingSearches.value().enabled,
|
||||||
featureFlag = true,
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if Recent Search Suggestions are enabled.
|
||||||
|
*/
|
||||||
|
var isRecentSearchesVisible by booleanPreference(
|
||||||
|
key = appContext.getPreferenceKey(R.string.pref_key_enable_recent_searches),
|
||||||
|
default = FxNimbus.features.recentSearches.value().enabled,
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -129,6 +129,7 @@
|
|||||||
<string name="pref_key_show_search_suggestions_in_private" translatable="false">pref_key_show_search_suggestions_in_private</string>
|
<string name="pref_key_show_search_suggestions_in_private" translatable="false">pref_key_show_search_suggestions_in_private</string>
|
||||||
<string name="pref_key_show_search_suggestions_in_private_onboarding" translatable="false">pref_key_show_search_suggestions_in_privateonboarding</string>
|
<string name="pref_key_show_search_suggestions_in_private_onboarding" translatable="false">pref_key_show_search_suggestions_in_privateonboarding</string>
|
||||||
<string name="pref_key_show_trending_search_suggestions" translatable="false">pref_key_show_trending_search_suggestions</string>
|
<string name="pref_key_show_trending_search_suggestions" translatable="false">pref_key_show_trending_search_suggestions</string>
|
||||||
|
<string name="pref_key_show_recent_search_suggestions" translatable="false">pref_key_show_recent_search_suggestions</string>
|
||||||
<string name="pref_key_show_voice_search" translatable="false">pref_key_show_voice_search</string>
|
<string name="pref_key_show_voice_search" translatable="false">pref_key_show_voice_search</string>
|
||||||
<string name="pref_key_enable_autocomplete_urls" translatable="false">pref_key_enable_domain_autocomplete</string>
|
<string name="pref_key_enable_autocomplete_urls" translatable="false">pref_key_enable_domain_autocomplete</string>
|
||||||
<string name="pref_key_show_sponsored_suggestions" translatable="false">pref_key_show_sponsored_suggestions</string>
|
<string name="pref_key_show_sponsored_suggestions" translatable="false">pref_key_show_sponsored_suggestions</string>
|
||||||
@@ -403,6 +404,7 @@
|
|||||||
<string name="pref_key_enable_homepage_as_new_tab" translatable="false">pref_key_enable_homepage_as_new_tab</string>
|
<string name="pref_key_enable_homepage_as_new_tab" translatable="false">pref_key_enable_homepage_as_new_tab</string>
|
||||||
<string name="pref_key_enable_unified_trust_panel" translatable="false">pref_key_enable_unified_trust_panel</string>
|
<string name="pref_key_enable_unified_trust_panel" translatable="false">pref_key_enable_unified_trust_panel</string>
|
||||||
<string name="pref_key_enable_trending_searches" translatable="false">pref_key_enable_trending_searches</string>
|
<string name="pref_key_enable_trending_searches" translatable="false">pref_key_enable_trending_searches</string>
|
||||||
|
<string name="pref_key_enable_recent_searches" translatable="false">pref_key_enable_recent_searches</string>
|
||||||
|
|
||||||
<!-- Growth Data -->
|
<!-- Growth Data -->
|
||||||
<string name="pref_key_growth_set_as_default" translatable="false">pref_key_growth_set_as_default</string>
|
<string name="pref_key_growth_set_as_default" translatable="false">pref_key_growth_set_as_default</string>
|
||||||
|
|||||||
@@ -103,6 +103,8 @@
|
|||||||
<string name="preferences_debug_settings_unified_trust_panel" translatable="false">Enable Unified Trust Panel</string>
|
<string name="preferences_debug_settings_unified_trust_panel" translatable="false">Enable Unified Trust Panel</string>
|
||||||
<!-- Label for enabling Trending Searches -->
|
<!-- Label for enabling Trending Searches -->
|
||||||
<string name="preferences_debug_settings_trending_searches" translatable="false">Enable Trending Searches</string>
|
<string name="preferences_debug_settings_trending_searches" translatable="false">Enable Trending Searches</string>
|
||||||
|
<!-- Label for enabling Recent Searches -->
|
||||||
|
<string name="preferences_debug_settings_recent_searches" translatable="false">Enable Recent Searches</string>
|
||||||
|
|
||||||
<!-- Label for enabling the DNS over HTTPS settings -->
|
<!-- Label for enabling the DNS over HTTPS settings -->
|
||||||
<string name="preferences_debug_settings_enable_doh_settings" translatable="false">Enable DNS over HTTPS settings</string>
|
<string name="preferences_debug_settings_enable_doh_settings" translatable="false">Enable DNS over HTTPS settings</string>
|
||||||
|
|||||||
@@ -789,6 +789,8 @@
|
|||||||
<string name="preferences_show_search_suggestions_in_private">Show in private sessions</string>
|
<string name="preferences_show_search_suggestions_in_private">Show in private sessions</string>
|
||||||
<!-- Preference title for switch preference to show trending search suggestions -->
|
<!-- Preference title for switch preference to show trending search suggestions -->
|
||||||
<string name="preferences_show_trending_search_suggestions">Show trending suggestions</string>
|
<string name="preferences_show_trending_search_suggestions">Show trending suggestions</string>
|
||||||
|
<!-- Preference title for switch preference to show recent search suggestions -->
|
||||||
|
<string name="preferences_show_recent_search_suggestions">Show recent searches</string>
|
||||||
<!-- Preference title for switch preference to show a clipboard suggestion when searching -->
|
<!-- Preference title for switch preference to show a clipboard suggestion when searching -->
|
||||||
<string name="preferences_show_clipboard_suggestions">Show clipboard suggestions</string>
|
<string name="preferences_show_clipboard_suggestions">Show clipboard suggestions</string>
|
||||||
<!-- Preference title for switch preference to suggest browsing history when searching -->
|
<!-- Preference title for switch preference to suggest browsing history when searching -->
|
||||||
@@ -2540,6 +2542,8 @@
|
|||||||
<string name="google_search_engine_suggestion_header">Google Search</string>
|
<string name="google_search_engine_suggestion_header">Google Search</string>
|
||||||
<!-- Title for search suggestions when the default search suggestion engine is anything other than Google. The first parameter is default search engine name. -->
|
<!-- Title for search suggestions when the default search suggestion engine is anything other than Google. The first parameter is default search engine name. -->
|
||||||
<string name="other_default_search_engine_suggestion_header">%s search</string>
|
<string name="other_default_search_engine_suggestion_header">%s search</string>
|
||||||
|
<!-- Title for recent search suggestions. -->
|
||||||
|
<string name="recent_searches_header">Recent Searches</string>
|
||||||
|
|
||||||
<!-- Default browser experiment -->
|
<!-- Default browser experiment -->
|
||||||
<!-- Default browser card title -->
|
<!-- Default browser card title -->
|
||||||
|
|||||||
@@ -44,6 +44,11 @@
|
|||||||
android:layout="@layout/checkbox_left_preference"
|
android:layout="@layout/checkbox_left_preference"
|
||||||
android:title="@string/preferences_show_trending_search_suggestions"
|
android:title="@string/preferences_show_trending_search_suggestions"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
<SwitchPreference
|
||||||
|
app:iconSpaceReserved="false"
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="@string/pref_key_show_recent_search_suggestions"
|
||||||
|
android:title="@string/preferences_show_recent_search_suggestions" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
|||||||
@@ -72,6 +72,10 @@
|
|||||||
android:key="@string/pref_key_enable_trending_searches"
|
android:key="@string/pref_key_enable_trending_searches"
|
||||||
android:title="@string/preferences_debug_settings_trending_searches"
|
android:title="@string/preferences_debug_settings_trending_searches"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="@string/pref_key_enable_recent_searches"
|
||||||
|
android:title="@string/preferences_debug_settings_recent_searches"
|
||||||
|
app:iconSpaceReserved="false" />
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="@string/pref_key_enable_debug_drawer"
|
android:key="@string/pref_key_enable_debug_drawer"
|
||||||
|
|||||||
@@ -1477,6 +1477,32 @@ class AwesomeBarViewTest {
|
|||||||
assertEquals(0, result.filterIsInstance<TrendingSearchProvider>().size)
|
assertEquals(0, result.filterIsInstance<TrendingSearchProvider>().size)
|
||||||
assertEquals(0, result.filterIsInstance<TopSitesSuggestionProvider>().size)
|
assertEquals(0, result.filterIsInstance<TopSitesSuggestionProvider>().size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN should show recent searches WHEN configuring providers THEN add the recent search suggestions provider`() {
|
||||||
|
every { activity.settings() } returns mockk(relaxed = true) {
|
||||||
|
every { shouldShowRecentSearchSuggestions } returns true
|
||||||
|
}
|
||||||
|
val state = getSearchProviderState(
|
||||||
|
searchEngineSource = SearchEngineSource.Default(mockk(relaxed = true)),
|
||||||
|
)
|
||||||
|
val result = awesomeBarView.getProvidersToAdd(state)
|
||||||
|
|
||||||
|
assertEquals(2, result.filterIsInstance<SearchTermSuggestionsProvider>().size)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN should not show recent searches WHEN configuring providers THEN don't add the recent search suggestions provider`() {
|
||||||
|
every { activity.settings() } returns mockk(relaxed = true) {
|
||||||
|
every { shouldShowRecentSearchSuggestions } returns false
|
||||||
|
}
|
||||||
|
val state = getSearchProviderState(
|
||||||
|
searchEngineSource = SearchEngineSource.Default(mockk(relaxed = true)),
|
||||||
|
)
|
||||||
|
val result = awesomeBarView.getProvidersToAdd(state)
|
||||||
|
|
||||||
|
assertEquals(1, result.filterIsInstance<SearchTermSuggestionsProvider>().size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -128,6 +128,11 @@ class SearchEngineFragmentTest {
|
|||||||
every { testContext.components.core.store.state.search } returns mockk(relaxed = true)
|
every { testContext.components.core.store.state.search } returns mockk(relaxed = true)
|
||||||
every { any<SearchState>().selectedOrDefaultSearchEngine } returns mockk(relaxed = true)
|
every { any<SearchState>().selectedOrDefaultSearchEngine } returns mockk(relaxed = true)
|
||||||
}
|
}
|
||||||
|
every {
|
||||||
|
fragment.findPreference<SwitchPreference>(testContext.getString(R.string.pref_key_show_recent_search_suggestions))
|
||||||
|
} returns mockk(relaxed = true) {
|
||||||
|
every { context } returns testContext
|
||||||
|
}
|
||||||
|
|
||||||
// Trigger the preferences setup.
|
// Trigger the preferences setup.
|
||||||
fragment.onResume()
|
fragment.onResume()
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ package org.mozilla.fenix.utils
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
|
||||||
import io.mockk.mockkStatic
|
import io.mockk.mockkStatic
|
||||||
import io.mockk.spyk
|
import io.mockk.spyk
|
||||||
import mozilla.components.browser.state.search.SearchEngine
|
|
||||||
import mozilla.components.concept.engine.Engine.HttpsOnlyMode.DISABLED
|
import mozilla.components.concept.engine.Engine.HttpsOnlyMode.DISABLED
|
||||||
import mozilla.components.concept.engine.Engine.HttpsOnlyMode.ENABLED
|
import mozilla.components.concept.engine.Engine.HttpsOnlyMode.ENABLED
|
||||||
import mozilla.components.concept.engine.Engine.HttpsOnlyMode.ENABLED_PRIVATE_ONLY
|
import mozilla.components.concept.engine.Engine.HttpsOnlyMode.ENABLED_PRIVATE_ONLY
|
||||||
@@ -1153,64 +1151,75 @@ class SettingsTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `GIVEN trending searches is enabled, visible and search engine supports it THEN should show trending searches`() {
|
fun `GIVEN trending searches is enabled, visible and search engine supports it THEN should show trending searches`() {
|
||||||
val settings = spyk(settings)
|
val settings = spyk(settings)
|
||||||
val searchEngine: SearchEngine = mockk(relaxed = true)
|
|
||||||
every { settings.trendingSearchSuggestionsEnabled } returns true
|
every { settings.trendingSearchSuggestionsEnabled } returns true
|
||||||
every { settings.isTrendingSearchesVisible } returns true
|
every { settings.isTrendingSearchesVisible } returns true
|
||||||
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
||||||
every { searchEngine.trendingUrl } returns "https://mozilla.org"
|
|
||||||
|
|
||||||
assertTrue(settings.shouldShowTrendingSearchSuggestions(true, searchEngine))
|
assertTrue(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Private, true))
|
||||||
assertTrue(settings.shouldShowTrendingSearchSuggestions(false, searchEngine))
|
assertTrue(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Normal, true))
|
||||||
|
|
||||||
every { settings.trendingSearchSuggestionsEnabled } returns false
|
every { settings.trendingSearchSuggestionsEnabled } returns false
|
||||||
every { settings.isTrendingSearchesVisible } returns true
|
every { settings.isTrendingSearchesVisible } returns true
|
||||||
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
||||||
|
|
||||||
assertFalse(settings.shouldShowTrendingSearchSuggestions(true, searchEngine))
|
assertFalse(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Private, true))
|
||||||
assertFalse(settings.shouldShowTrendingSearchSuggestions(false, searchEngine))
|
assertFalse(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Normal, true))
|
||||||
|
|
||||||
every { settings.trendingSearchSuggestionsEnabled } returns true
|
every { settings.trendingSearchSuggestionsEnabled } returns true
|
||||||
every { settings.isTrendingSearchesVisible } returns false
|
every { settings.isTrendingSearchesVisible } returns false
|
||||||
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
||||||
|
|
||||||
assertFalse(settings.shouldShowTrendingSearchSuggestions(true, searchEngine))
|
assertFalse(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Private, true))
|
||||||
assertFalse(settings.shouldShowTrendingSearchSuggestions(false, searchEngine))
|
assertFalse(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Normal, true))
|
||||||
|
|
||||||
every { settings.trendingSearchSuggestionsEnabled } returns false
|
every { settings.trendingSearchSuggestionsEnabled } returns false
|
||||||
every { settings.isTrendingSearchesVisible } returns false
|
every { settings.isTrendingSearchesVisible } returns false
|
||||||
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
||||||
|
|
||||||
assertFalse(settings.shouldShowTrendingSearchSuggestions(true, searchEngine))
|
assertFalse(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Private, true))
|
||||||
assertFalse(settings.shouldShowTrendingSearchSuggestions(false, searchEngine))
|
assertFalse(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Normal, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN search engine does not supports trending search THEN should not show trending searches`() {
|
fun `GIVEN search engine does not supports trending search THEN should not show trending searches`() {
|
||||||
val settings = spyk(settings)
|
val settings = spyk(settings)
|
||||||
val searchEngine: SearchEngine = mockk(relaxed = true)
|
|
||||||
every { settings.trendingSearchSuggestionsEnabled } returns true
|
every { settings.trendingSearchSuggestionsEnabled } returns true
|
||||||
every { settings.isTrendingSearchesVisible } returns true
|
every { settings.isTrendingSearchesVisible } returns true
|
||||||
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
||||||
every { searchEngine.trendingUrl } returns null
|
|
||||||
|
|
||||||
assertFalse(settings.shouldShowTrendingSearchSuggestions(false, searchEngine))
|
assertFalse(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Private, false))
|
||||||
assertFalse(settings.shouldShowTrendingSearchSuggestions(true, searchEngine))
|
assertFalse(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Normal, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN is private tab THEN should show trending searches only if allowed`() {
|
fun `GIVEN is private tab THEN should show trending searches only if allowed`() {
|
||||||
val settings = spyk(settings)
|
val settings = spyk(settings)
|
||||||
val searchEngine: SearchEngine = mockk(relaxed = true)
|
|
||||||
every { settings.trendingSearchSuggestionsEnabled } returns true
|
every { settings.trendingSearchSuggestionsEnabled } returns true
|
||||||
every { settings.isTrendingSearchesVisible } returns true
|
every { settings.isTrendingSearchesVisible } returns true
|
||||||
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
every { settings.shouldShowSearchSuggestionsInPrivate } returns true
|
||||||
every { searchEngine.trendingUrl } returns "abc"
|
|
||||||
|
|
||||||
assertTrue(settings.shouldShowTrendingSearchSuggestions(true, searchEngine))
|
assertTrue(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Private, true))
|
||||||
assertTrue(settings.shouldShowTrendingSearchSuggestions(false, searchEngine))
|
assertTrue(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Normal, true))
|
||||||
|
|
||||||
every { settings.shouldShowSearchSuggestionsInPrivate } returns false
|
every { settings.shouldShowSearchSuggestionsInPrivate } returns false
|
||||||
assertFalse(settings.shouldShowTrendingSearchSuggestions(true, searchEngine))
|
assertFalse(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Private, true))
|
||||||
assertTrue(settings.shouldShowTrendingSearchSuggestions(false, searchEngine))
|
assertTrue(settings.shouldShowTrendingSearchSuggestions(BrowsingMode.Normal, true))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN recent search is enable THEN should show recent searches only if recent search is visible`() {
|
||||||
|
val settings = spyk(settings)
|
||||||
|
every { settings.recentSearchSuggestionsEnabled } returns true
|
||||||
|
every { settings.isRecentSearchesVisible } returns true
|
||||||
|
|
||||||
|
assertTrue(settings.shouldShowRecentSearchSuggestions)
|
||||||
|
|
||||||
|
every { settings.isRecentSearchesVisible } returns false
|
||||||
|
every { settings.recentSearchSuggestionsEnabled } returns true
|
||||||
|
assertFalse(settings.shouldShowRecentSearchSuggestions)
|
||||||
|
|
||||||
|
every { settings.isRecentSearchesVisible } returns true
|
||||||
|
every { settings.recentSearchSuggestionsEnabled } returns false
|
||||||
|
assertFalse(settings.shouldShowRecentSearchSuggestions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user