Upload upstream chromium 114.0.5735.31
[platform/framework/web/chromium-efl.git] / components / search_engines / keyword_web_data_service.cc
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.
4
5 #include "components/search_engines/keyword_web_data_service.h"
6
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"
15
16 namespace {
17
18 WebDatabase::State PerformKeywordOperationsImpl(
19     const KeywordTable::Operations& operations,
20     WebDatabase* db) {
21   return KeywordTable::FromWebDatabase(db)->PerformOperations(operations)
22              ? WebDatabase::COMMIT_NEEDED
23              : WebDatabase::COMMIT_NOT_NEEDED;
24 }
25
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)) {
30     return nullptr;
31   }
32
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);
38 }
39
40 WebDatabase::State SetDefaultSearchProviderIDImpl(TemplateURLID id,
41                                                   WebDatabase* db) {
42   return KeywordTable::FromWebDatabase(db)->SetDefaultSearchProviderID(id)
43              ? WebDatabase::COMMIT_NEEDED
44              : WebDatabase::COMMIT_NOT_NEEDED;
45 }
46
47 WebDatabase::State SetBuiltinKeywordVersionImpl(int version, WebDatabase* db) {
48   return KeywordTable::FromWebDatabase(db)->SetBuiltinKeywordVersion(version)
49              ? WebDatabase::COMMIT_NEEDED
50              : WebDatabase::COMMIT_NOT_NEEDED;
51 }
52
53 WebDatabase::State SetStarterPackKeywordVersionImpl(int version,
54                                                     WebDatabase* db) {
55   return KeywordTable::FromWebDatabase(db)->SetStarterPackKeywordVersion(
56              version)
57              ? WebDatabase::COMMIT_NEEDED
58              : WebDatabase::COMMIT_NOT_NEEDED;
59 }
60
61 }  // namespace
62
63 WDKeywordsResult::WDKeywordsResult() = default;
64
65 WDKeywordsResult::WDKeywordsResult(const WDKeywordsResult&) = default;
66
67 WDKeywordsResult& WDKeywordsResult::operator=(const WDKeywordsResult&) =
68     default;
69
70 WDKeywordsResult::~WDKeywordsResult() = default;
71
72 KeywordWebDataService::BatchModeScoper::BatchModeScoper(
73     KeywordWebDataService* service)
74     : service_(service) {
75   if (service_)
76     service_->AdjustBatchModeLevel(true);
77 }
78
79 KeywordWebDataService::BatchModeScoper::~BatchModeScoper() {
80   if (service_)
81     service_->AdjustBatchModeLevel(false);
82 }
83
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)),
88       timer_(FROM_HERE,
89              base::Seconds(5),
90              base::BindRepeating(&KeywordWebDataService::CommitQueuedOperations,
91                                  base::Unretained(this))) {}
92
93 void KeywordWebDataService::AddKeyword(const TemplateURLData& data) {
94   if (batch_mode_level_) {
95     queued_keyword_operations_.push_back(
96         KeywordTable::Operation(KeywordTable::ADD, data));
97   } else {
98     AdjustBatchModeLevel(true);
99     AddKeyword(data);
100     AdjustBatchModeLevel(false);
101   }
102 }
103
104 void KeywordWebDataService::RemoveKeyword(TemplateURLID id) {
105   if (batch_mode_level_) {
106     TemplateURLData data;
107     data.id = id;
108     queued_keyword_operations_.push_back(
109         KeywordTable::Operation(KeywordTable::REMOVE, data));
110   } else {
111     AdjustBatchModeLevel(true);
112     RemoveKeyword(id);
113     AdjustBatchModeLevel(false);
114   }
115 }
116
117 void KeywordWebDataService::UpdateKeyword(const TemplateURLData& data) {
118   if (batch_mode_level_) {
119     queued_keyword_operations_.push_back(
120         KeywordTable::Operation(KeywordTable::UPDATE, data));
121   } else {
122     AdjustBatchModeLevel(true);
123     UpdateKeyword(data);
124     AdjustBatchModeLevel(false);
125   }
126 }
127
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();
133
134   return wdbs_->ScheduleDBTaskWithResult(
135       FROM_HERE, base::BindOnce(&GetKeywordsImpl), consumer);
136 }
137
138 void KeywordWebDataService::SetDefaultSearchProviderID(TemplateURLID id) {
139   wdbs_->ScheduleDBTask(FROM_HERE,
140                         base::BindOnce(&SetDefaultSearchProviderIDImpl, id));
141 }
142
143 void KeywordWebDataService::SetBuiltinKeywordVersion(int version) {
144   wdbs_->ScheduleDBTask(FROM_HERE,
145                         base::BindOnce(&SetBuiltinKeywordVersionImpl, version));
146 }
147
148 void KeywordWebDataService::SetStarterPackKeywordVersion(int version) {
149   wdbs_->ScheduleDBTask(
150       FROM_HERE, base::BindOnce(&SetStarterPackKeywordVersionImpl, version));
151 }
152
153 void KeywordWebDataService::ShutdownOnUISequence() {
154   CommitQueuedOperations();
155   WebDataServiceBase::ShutdownOnUISequence();
156 }
157
158 KeywordWebDataService::~KeywordWebDataService() {
159   DCHECK(!batch_mode_level_);
160   DCHECK(queued_keyword_operations_.empty());
161 }
162
163 void KeywordWebDataService::AdjustBatchModeLevel(bool entering_batch_mode) {
164   if (entering_batch_mode) {
165     ++batch_mode_level_;
166   } else {
167     DCHECK(batch_mode_level_);
168     --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();
176 #else
177       timer_.Reset();
178 #endif
179     }
180   }
181 }
182
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();
189   }
190   timer_.Stop();
191 }