1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/search_engines/keyword_web_data_service.h"
7 #include "base/functional/bind.h"
8 #include "base/location.h"
9 #include "base/task/single_thread_task_runner.h"
10 #include "build/build_config.h"
11 #include "components/search_engines/keyword_table.h"
12 #include "components/search_engines/template_url_data.h"
13 #include "components/webdata/common/web_data_results.h"
14 #include "components/webdata/common/web_database_service.h"
18 WebDatabase::State PerformKeywordOperationsImpl(
19 const KeywordTable::Operations& operations,
21 return KeywordTable::FromWebDatabase(db)->PerformOperations(operations)
22 ? WebDatabase::COMMIT_NEEDED
23 : WebDatabase::COMMIT_NOT_NEEDED;
26 std::unique_ptr<WDTypedResult> GetKeywordsImpl(WebDatabase* db) {
27 KeywordTable* const keyword_table = KeywordTable::FromWebDatabase(db);
28 WDKeywordsResult result;
29 if (!keyword_table || !keyword_table->GetKeywords(&result.keywords)) {
33 result.default_search_provider_id =
34 keyword_table->GetDefaultSearchProviderID();
35 result.builtin_keyword_version = keyword_table->GetBuiltinKeywordVersion();
36 result.starter_pack_version = keyword_table->GetStarterPackKeywordVersion();
37 return std::make_unique<WDResult<WDKeywordsResult>>(KEYWORDS_RESULT, result);
40 WebDatabase::State SetDefaultSearchProviderIDImpl(TemplateURLID id,
42 return KeywordTable::FromWebDatabase(db)->SetDefaultSearchProviderID(id)
43 ? WebDatabase::COMMIT_NEEDED
44 : WebDatabase::COMMIT_NOT_NEEDED;
47 WebDatabase::State SetBuiltinKeywordVersionImpl(int version, WebDatabase* db) {
48 return KeywordTable::FromWebDatabase(db)->SetBuiltinKeywordVersion(version)
49 ? WebDatabase::COMMIT_NEEDED
50 : WebDatabase::COMMIT_NOT_NEEDED;
53 WebDatabase::State SetStarterPackKeywordVersionImpl(int version,
55 return KeywordTable::FromWebDatabase(db)->SetStarterPackKeywordVersion(
57 ? WebDatabase::COMMIT_NEEDED
58 : WebDatabase::COMMIT_NOT_NEEDED;
63 WDKeywordsResult::WDKeywordsResult() = default;
65 WDKeywordsResult::WDKeywordsResult(const WDKeywordsResult&) = default;
67 WDKeywordsResult& WDKeywordsResult::operator=(const WDKeywordsResult&) =
70 WDKeywordsResult::~WDKeywordsResult() = default;
72 KeywordWebDataService::BatchModeScoper::BatchModeScoper(
73 KeywordWebDataService* service)
76 service_->AdjustBatchModeLevel(true);
79 KeywordWebDataService::BatchModeScoper::~BatchModeScoper() {
81 service_->AdjustBatchModeLevel(false);
84 KeywordWebDataService::KeywordWebDataService(
85 scoped_refptr<WebDatabaseService> wdbs,
86 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
87 : WebDataServiceBase(std::move(wdbs), std::move(ui_task_runner)),
90 base::BindRepeating(&KeywordWebDataService::CommitQueuedOperations,
91 base::Unretained(this))) {}
93 void KeywordWebDataService::AddKeyword(const TemplateURLData& data) {
94 if (batch_mode_level_) {
95 queued_keyword_operations_.push_back(
96 KeywordTable::Operation(KeywordTable::ADD, data));
98 AdjustBatchModeLevel(true);
100 AdjustBatchModeLevel(false);
104 void KeywordWebDataService::RemoveKeyword(TemplateURLID id) {
105 if (batch_mode_level_) {
106 TemplateURLData data;
108 queued_keyword_operations_.push_back(
109 KeywordTable::Operation(KeywordTable::REMOVE, data));
111 AdjustBatchModeLevel(true);
113 AdjustBatchModeLevel(false);
117 void KeywordWebDataService::UpdateKeyword(const TemplateURLData& data) {
118 if (batch_mode_level_) {
119 queued_keyword_operations_.push_back(
120 KeywordTable::Operation(KeywordTable::UPDATE, data));
122 AdjustBatchModeLevel(true);
124 AdjustBatchModeLevel(false);
128 WebDataServiceBase::Handle KeywordWebDataService::GetKeywords(
129 WebDataServiceConsumer* consumer) {
130 // Force pending changes to be visible immediately so the results of this call
131 // won't be out of date.
132 CommitQueuedOperations();
134 return wdbs_->ScheduleDBTaskWithResult(
135 FROM_HERE, base::BindOnce(&GetKeywordsImpl), consumer);
138 void KeywordWebDataService::SetDefaultSearchProviderID(TemplateURLID id) {
139 wdbs_->ScheduleDBTask(FROM_HERE,
140 base::BindOnce(&SetDefaultSearchProviderIDImpl, id));
143 void KeywordWebDataService::SetBuiltinKeywordVersion(int version) {
144 wdbs_->ScheduleDBTask(FROM_HERE,
145 base::BindOnce(&SetBuiltinKeywordVersionImpl, version));
148 void KeywordWebDataService::SetStarterPackKeywordVersion(int version) {
149 wdbs_->ScheduleDBTask(
150 FROM_HERE, base::BindOnce(&SetStarterPackKeywordVersionImpl, version));
153 void KeywordWebDataService::ShutdownOnUISequence() {
154 CommitQueuedOperations();
155 WebDataServiceBase::ShutdownOnUISequence();
158 KeywordWebDataService::~KeywordWebDataService() {
159 DCHECK(!batch_mode_level_);
160 DCHECK(queued_keyword_operations_.empty());
163 void KeywordWebDataService::AdjustBatchModeLevel(bool entering_batch_mode) {
164 if (entering_batch_mode) {
167 DCHECK(batch_mode_level_);
169 if (!batch_mode_level_ && !queued_keyword_operations_.empty() &&
170 !timer_.IsRunning()) {
171 // When killing an app on Android/iOS, shutdown isn't guaranteed to be
172 // called. Finishing this task immediately ensures the table is fully
173 // populated even if the app is killed before the timer expires.
174 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
175 CommitQueuedOperations();
183 void KeywordWebDataService::CommitQueuedOperations() {
184 if (!queued_keyword_operations_.empty()) {
185 wdbs_->ScheduleDBTask(FROM_HERE,
186 base::BindOnce(&PerformKeywordOperationsImpl,
187 queued_keyword_operations_));
188 queued_keyword_operations_.clear();