#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "components/search_engines/template_url_service.h"
#include <algorithm>
#include <iterator>
#include <memory>
#include <string>
#include <utility>
#include "base/auto_reset.h"
#include "base/base64.h"
#include "base/base64url.h"
#include "base/check_deref.h"
#include "base/check_is_test.h"
#include "base/containers/contains.h"
#include "base/containers/flat_map.h"
#include "base/debug/crash_logging.h"
#include "base/feature_list.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/i18n/case_conversion.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/observer_list.h"
#include "base/rand_util.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/search_engines/choice_made_location.h"
#include "components/search_engines/enterprise/enterprise_site_search_manager.h"
#include "components/search_engines/keyword_web_data_service.h"
#include "components/search_engines/search_engine_choice/search_engine_choice_service.h"
#include "components/search_engines/search_engine_choice/search_engine_choice_utils.h"
#include "components/search_engines/search_engine_type.h"
#include "components/search_engines/search_engines_pref_names.h"
#include "components/search_engines/search_terms_data.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_data.h"
#include "components/search_engines/template_url_prepopulate_data.h"
#include "components/search_engines/template_url_service_client.h"
#include "components/search_engines/template_url_service_observer.h"
#include "components/search_engines/template_url_starter_pack_data.h"
#include "components/search_engines/util.h"
#include "components/sync/model/sync_change.h"
#include "components/sync/model/sync_change_processor.h"
#include "components/sync/protocol/entity_specifics.pb.h"
#include "components/sync/protocol/search_engine_specifics.pb.h"
#include "components/url_formatter/url_fixer.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_ANDROID)
#include "components/search_engines/android/template_url_service_android.h"
#endif
TemplateURLSet;
SyncDataMap;
namespace {
const char kDeleteSyncedEngineHistogramName[] = …;
const char kKeywordModeUsageByEngineTypeHistogramName[] = …;
enum DeleteSyncedSearchEngineEvent { … };
bool ShouldRemoveSyncChange(size_t index,
syncer::SyncChangeList* change_list,
const SyncDataMap* sync_data) { … }
void PruneSyncChanges(const SyncDataMap* sync_data,
syncer::SyncChangeList* change_list) { … }
bool IsFromSync(const TemplateURL* turl, const SyncDataMap& sync_data) { … }
void LogDuplicatesHistogram(
const TemplateURLService::TemplateURLVector& template_urls) { … }
bool Contains(TemplateURLService::OwnedTemplateURLVector* template_urls,
const TemplateURL* turl) { … }
bool IsCreatedByExtension(const TemplateURL* template_url) { … }
bool ShouldMergeEnterpriseSiteSearchEngines(const TemplateURL& existing_turl,
const TemplateURL& new_values) { … }
TemplateURL MergeEnterpriseSiteSearchEngines(const TemplateURL& existing_turl,
const TemplateURL& new_values) { … }
}
class TemplateURLService::LessWithPrefix { … };
class TemplateURLService::Scoper { … };
class TemplateURLService::PreLoadingProviders { … };
TemplateURLService::TemplateURLService(
PrefService& prefs,
search_engines::SearchEngineChoiceService& search_engine_choice_service,
std::unique_ptr<SearchTermsData> search_terms_data,
const scoped_refptr<KeywordWebDataService>& web_data_service,
std::unique_ptr<TemplateURLServiceClient> client,
const base::RepeatingClosure& dsp_change_callback
#if BUILDFLAG(IS_CHROMEOS_LACROS)
,
bool for_lacros_main_profile
#endif
)
: … { … }
TemplateURLService::TemplateURLService(
PrefService& prefs,
search_engines::SearchEngineChoiceService& search_engine_choice_service,
base::span<const TemplateURLService::Initializer> initializers)
: … { … }
TemplateURLService::~TemplateURLService() { … }
void TemplateURLService::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) { … }
#if BUILDFLAG(IS_ANDROID)
base::android::ScopedJavaLocalRef<jobject> TemplateURLService::GetJavaObject() {
if (!template_url_service_android_) {
template_url_service_android_ =
std::make_unique<TemplateUrlServiceAndroid>(this);
}
return template_url_service_android_->GetJavaObject();
}
#endif
bool TemplateURLService::CanAddAutogeneratedKeyword(
const std::u16string& keyword,
const GURL& url) { … }
bool TemplateURLService::IsPrepopulatedOrDefaultProviderByPolicy(
const TemplateURL* t_url) const { … }
bool TemplateURLService::ShowInDefaultList(const TemplateURL* t_url) const { … }
bool TemplateURLService::ShowInActivesList(const TemplateURL* t_url) const { … }
bool TemplateURLService::HiddenFromLists(const TemplateURL* t_url) const { … }
bool TemplateURLService::FeaturedOverridesNonFeatured(
const TemplateURL* template_url) const { … }
void TemplateURLService::AddMatchingKeywords(const std::u16string& prefix,
bool supports_replacement_only,
TemplateURLVector* matches) { … }
TemplateURL* TemplateURLService::GetTemplateURLForKeyword(
const std::u16string& keyword) { … }
const TemplateURL* TemplateURLService::GetTemplateURLForKeyword(
const std::u16string& keyword) const { … }
TemplateURL* TemplateURLService::GetTemplateURLForGUID(
const std::string& sync_guid) { … }
const TemplateURL* TemplateURLService::GetTemplateURLForGUID(
const std::string& sync_guid) const { … }
TemplateURL* TemplateURLService::GetTemplateURLForHost(
const std::string& host) { … }
const TemplateURL* TemplateURLService::GetTemplateURLForHost(
const std::string& host) const { … }
size_t TemplateURLService::GetTemplateURLCountForHostForLogging(
const std::string& host) const { … }
TemplateURL* TemplateURLService::Add(
std::unique_ptr<TemplateURL> template_url) { … }
TemplateURL* TemplateURLService::AddWithOverrides(
std::unique_ptr<TemplateURL> template_url,
const std::u16string& short_name,
const std::u16string& keyword,
const std::string& url) { … }
void TemplateURLService::Remove(const TemplateURL* template_url) { … }
void TemplateURLService::RemoveExtensionControlledTURL(
const std::string& extension_id,
TemplateURL::Type type) { … }
void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after,
base::Time created_before) { … }
void TemplateURLService::RemoveAutoGeneratedForUrlsBetween(
const base::RepeatingCallback<bool(const GURL&)>& url_filter,
base::Time created_after,
base::Time created_before) { … }
void TemplateURLService::RegisterOmniboxKeyword(
const std::string& extension_id,
const std::string& extension_name,
const std::string& keyword,
const std::string& template_url_string,
const base::Time& extension_install_time) { … }
TemplateURLService::TemplateURLVector TemplateURLService::GetTemplateURLs() { … }
std::unique_ptr<search_engines::ChoiceScreenData>
TemplateURLService::GetChoiceScreenData() { … }
TemplateURLService::TemplateURLVector
TemplateURLService::GetFeaturedEnterpriseSearchEngines() const { … }
#if BUILDFLAG(IS_ANDROID)
TemplateURLService::OwnedTemplateURLDataVector
TemplateURLService::GetTemplateURLsForCountry(const std::string& country_code) {
return TemplateURLPrepopulateData::GetLocalPrepopulatedEngines(country_code,
prefs_.get());
}
#endif
void TemplateURLService::IncrementUsageCount(TemplateURL* url) { … }
void TemplateURLService::ResetTemplateURL(TemplateURL* url,
const std::u16string& title,
const std::u16string& keyword,
const std::string& search_url) { … }
void TemplateURLService::SetIsActiveTemplateURL(TemplateURL* url,
bool is_active) { … }
#if BUILDFLAG(IS_ANDROID)
TemplateURLData TemplateURLService::CreatePlayAPITemplateURLData(
const std::u16string& keyword,
const std::u16string& name,
const std::string& search_url,
const std::string& suggest_url,
const std::string& favicon_url,
const std::string& new_tab_url,
const std::string& image_url,
const std::string& image_url_post_params,
const std::string& image_translate_url,
const std::string& image_translate_source_language_param_key,
const std::string& image_translate_target_language_param_key) {
TemplateURLData data;
data.SetShortName(name);
data.SetKeyword(keyword);
data.SetURL(search_url);
data.suggestions_url = suggest_url;
data.favicon_url = GURL(favicon_url);
data.new_tab_url = new_tab_url;
data.image_url = image_url;
data.image_url_post_params = image_url_post_params;
data.image_translate_url = image_translate_url;
data.image_translate_source_language_param_key =
image_translate_source_language_param_key;
data.image_translate_target_language_param_key =
image_translate_target_language_param_key;
data.created_from_play_api = true;
data.safe_for_autoreplace = false;
data.is_active = TemplateURLData::ActiveStatus::kTrue;
return data;
}
bool TemplateURLService::ResetPlayAPISearchEngine(
const TemplateURLData& new_play_api_turl_data) {
CHECK(loaded());
CHECK(new_play_api_turl_data.created_from_play_api);
auto new_play_api_turl =
std::make_unique<TemplateURL>(new_play_api_turl_data);
SCOPED_CRASH_KEY_NUMBER("ResetPlayAPISearchEngine", "OldDspSource",
default_search_provider_source_);
SCOPED_CRASH_KEY_STRING64(
"ResetPlayAPISearchEngine", "OldDspKw",
default_search_provider_
? base::UTF16ToUTF8(default_search_provider_->keyword())
: "<null>");
std::u16string old_play_keyword;
Scoper scoper{this};
const auto match_range =
keyword_to_turl_.equal_range(new_play_api_turl->keyword());
for (auto it = match_range.first; it != match_range.second; ++it) {
TemplateURL* same_keyword_engine = it->second;
if (same_keyword_engine->created_from_play_api()) {
continue;
}
if (same_keyword_engine->IsBetterThanConflictingEngine(
new_play_api_turl.get())) {
return false;
}
}
auto found = base::ranges::find_if(template_urls_,
&TemplateURL::created_from_play_api);
if (found != template_urls_.cend()) {
TemplateURL* old_play_api_engine = found->get();
old_play_keyword = old_play_api_engine->keyword();
if (old_play_api_engine == default_search_provider_) {
CHECK(CanMakeDefault(new_play_api_turl.get()), base::NotFatalUntil::M129);
default_search_provider_ = nullptr;
}
Remove(old_play_api_engine);
}
SCOPED_CRASH_KEY_STRING64("ResetPlayAPISearchEngine", "OldPlayKw",
base::UTF16ToUTF8(old_play_keyword));
TemplateURL* new_play_api_turl_ptr = Add(std::move(new_play_api_turl));
CHECK(new_play_api_turl_ptr, base::NotFatalUntil::M129);
if (CanMakeDefault(new_play_api_turl_ptr)) {
SetUserSelectedDefaultSearchProvider(
new_play_api_turl_ptr,
search_engines::ChoiceMadeLocation::kChoiceScreen);
}
CHECK(default_search_provider_, base::NotFatalUntil::M132);
return true;
}
#endif
void TemplateURLService::UpdateProviderFavicons(
const GURL& potential_search_url,
const GURL& favicon_url) { … }
bool TemplateURLService::CanMakeDefault(const TemplateURL* url) const { … }
void TemplateURLService::SetUserSelectedDefaultSearchProvider(
TemplateURL* url,
search_engines::ChoiceMadeLocation choice_made_location) { … }
const TemplateURL* TemplateURLService::GetDefaultSearchProvider() const { … }
const TemplateURL*
TemplateURLService::GetDefaultSearchProviderIgnoringExtensions() const { … }
bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider(
const GURL& url) const { … }
GURL TemplateURLService::GenerateSearchURLForDefaultSearchProvider(
const std::u16string& search_terms) const { … }
std::optional<TemplateURLService::SearchMetadata>
TemplateURLService::ExtractSearchMetadata(const GURL& url) const { … }
bool TemplateURLService::IsSideSearchSupportedForDefaultSearchProvider() const { … }
bool TemplateURLService::IsSideImageSearchSupportedForDefaultSearchProvider()
const { … }
GURL TemplateURLService::GenerateSideSearchURLForDefaultSearchProvider(
const GURL& search_url,
const std::string& version) const { … }
GURL TemplateURLService::RemoveSideSearchParamFromURL(
const GURL& search_url) const { … }
GURL TemplateURLService::GenerateSideImageSearchURLForDefaultSearchProvider(
const GURL& search_url,
const std::string& version) const { … }
GURL TemplateURLService::RemoveSideImageSearchParamFromURL(
const GURL& search_url) const { … }
bool TemplateURLService::IsExtensionControlledDefaultSearch() const { … }
void TemplateURLService::RepairPrepopulatedSearchEngines() { … }
void TemplateURLService::RepairStarterPackEngines() { … }
void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) { … }
void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) { … }
void TemplateURLService::Load() { … }
base::CallbackListSubscription TemplateURLService::RegisterOnLoadedCallback(
base::OnceClosure callback) { … }
void TemplateURLService::EmitTemplateURLActiveOnStartupHistogram(
OwnedTemplateURLVector* template_urls) { … }
void TemplateURLService::OnWebDataServiceRequestDone(
KeywordWebDataService::Handle h,
std::unique_ptr<WDTypedResult> result) { … }
std::u16string TemplateURLService::GetKeywordShortName(
const std::u16string& keyword,
bool* is_omnibox_api_extension_keyword,
bool* is_gemini_keyword) const { … }
void TemplateURLService::OnHistoryURLVisited(const URLVisitedDetails& details) { … }
void TemplateURLService::Shutdown() { … }
void TemplateURLService::WaitUntilReadyToSync(base::OnceClosure done) { … }
syncer::SyncDataList TemplateURLService::GetAllSyncData(
syncer::DataType type) const { … }
std::optional<syncer::ModelError> TemplateURLService::ProcessSyncChanges(
const base::Location& from_here,
const syncer::SyncChangeList& change_list) { … }
base::WeakPtr<syncer::SyncableService> TemplateURLService::AsWeakPtr() { … }
std::optional<syncer::ModelError> TemplateURLService::MergeDataAndStartSyncing(
syncer::DataType type,
const syncer::SyncDataList& initial_sync_data,
std::unique_ptr<syncer::SyncChangeProcessor> sync_processor) { … }
void TemplateURLService::StopSyncing(syncer::DataType type) { … }
void TemplateURLService::ProcessTemplateURLChange(
const base::Location& from_here,
const TemplateURL* turl,
syncer::SyncChange::SyncChangeType type) { … }
bool TemplateURLService::IsEeaChoiceCountry() { … }
#if BUILDFLAG(IS_ANDROID)
bool TemplateURLService::ShouldShowUpdatedSettings() {
return search_engine_choice_service_->ShouldShowUpdatedSettings();
}
#endif
std::string TemplateURLService::GetSessionToken() { … }
void TemplateURLService::ClearSessionToken() { … }
TemplateURLData::ActiveStatus TemplateURLService::ActiveStatusFromSync(
sync_pb::SearchEngineSpecifics_ActiveStatus is_active) { … }
sync_pb::SearchEngineSpecifics_ActiveStatus
TemplateURLService::ActiveStatusToSync(
TemplateURLData::ActiveStatus is_active) { … }
syncer::SyncData TemplateURLService::CreateSyncDataFromTemplateURL(
const TemplateURL& turl) { … }
std::unique_ptr<TemplateURL>
TemplateURLService::CreateTemplateURLFromTemplateURLAndSyncData(
TemplateURLServiceClient* client,
PrefService* prefs,
search_engines::SearchEngineChoiceService* search_engine_choice_service,
const SearchTermsData& search_terms_data,
const TemplateURL* existing_turl,
const syncer::SyncData& sync_data,
syncer::SyncChangeList* change_list) { … }
SyncDataMap TemplateURLService::CreateGUIDToSyncDataMap(
const syncer::SyncDataList& sync_data) { … }
void TemplateURLService::Init() { … }
void TemplateURLService::ApplyInitializersForTesting(
base::span<const TemplateURLService::Initializer> initializers) { … }
void TemplateURLService::RemoveFromMaps(const TemplateURL* template_url) { … }
void TemplateURLService::AddToMaps(TemplateURL* template_url) { … }
void TemplateURLService::SetTemplateURLs(
std::unique_ptr<OwnedTemplateURLVector> urls) { … }
void TemplateURLService::ChangeToLoadedState() { … }
bool TemplateURLService::CanAddAutogeneratedKeywordForHost(
const std::string& host) const { … }
bool TemplateURLService::Update(TemplateURL* existing_turl,
const TemplateURL& new_values) { … }
void TemplateURLService::UpdateTemplateURLIfPrepopulated(
TemplateURL* template_url,
PrefService* prefs,
search_engines::SearchEngineChoiceService* search_engine_choice_service) { … }
void TemplateURLService::MaybeUpdateDSEViaPrefs(TemplateURL* synced_turl) { … }
void TemplateURLService::UpdateKeywordSearchTermsForURL(
const URLVisitedDetails& details) { … }
void TemplateURLService::UpdateTemplateURLVisitTime(TemplateURL* url) { … }
void TemplateURLService::AddTabToSearchVisit(const TemplateURL& t_url) { … }
void TemplateURLService::ApplyDefaultSearchChange(
const TemplateURLData* data,
DefaultSearchManager::Source source) { … }
bool TemplateURLService::ApplyDefaultSearchChangeForTesting(
const TemplateURLData* data,
DefaultSearchManager::Source source) { … }
bool TemplateURLService::ApplyDefaultSearchChangeNoMetrics(
const TemplateURLData* data,
DefaultSearchManager::Source source) { … }
void TemplateURLService::ApplyEnterpriseSiteSearchChanges(
TemplateURLService::OwnedTemplateURLVector&& policy_site_search_engines) { … }
void TemplateURLService::EnterpriseSiteSearchChanged(
OwnedTemplateURLDataVector&& policy_site_search_engines) { … }
TemplateURL* TemplateURLService::Add(std::unique_ptr<TemplateURL> template_url,
bool newly_adding) { … }
void TemplateURLService::UpdateDefaultProvidersCreatedByPolicy(
OwnedTemplateURLVector* template_urls,
const TemplateURLData* default_from_prefs,
bool is_mandatory) { … }
void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url,
const std::string& guid) { … }
void TemplateURLService::MergeInSyncTemplateURL(
TemplateURL* sync_turl,
const SyncDataMap& sync_data,
syncer::SyncChangeList* change_list,
SyncDataMap* local_data) { … }
void TemplateURLService::PatchMissingSyncGUIDs(
OwnedTemplateURLVector* template_urls) { … }
void TemplateURLService::OnDefaultSearchProviderGUIDChanged() { … }
void TemplateURLService::MaybeSetIsActiveSearchEngines(
OwnedTemplateURLVector* template_urls) { … }
template <typename Container>
void TemplateURLService::AddMatchingKeywordsHelper(
const Container& keyword_to_turl,
const std::u16string& prefix,
bool supports_replacement_only,
TemplateURLVector* matches) { … }
TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL(
int prepopulated_id) { … }
TemplateURL* TemplateURLService::FindStarterPackTemplateURL(
int starter_pack_id) { … }
TemplateURL* TemplateURLService::FindTemplateURLForExtension(
const std::string& extension_id,
TemplateURL::Type type) { … }
TemplateURL* TemplateURLService::FindMatchingDefaultExtensionTemplateURL(
const TemplateURLData& data) { … }
bool TemplateURLService::RemoveDuplicateReplaceableEnginesOf(
TemplateURL* candidate) { … }
bool TemplateURLService::MatchesDefaultSearchProvider(TemplateURL* turl) const { … }
std::unique_ptr<EnterpriseSiteSearchManager>
TemplateURLService::GetEnterpriseSiteSearchManager(PrefService* prefs) { … }
void TemplateURLService::LogSiteSearchPolicyConflict(
const TemplateURLService::OwnedTemplateURLVector&
policy_site_search_engines) { … }