1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
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 "chrome/browser/webdata/web_data_service.h"
6
7 #include "base/bind.h"
8 #include "base/stl_util.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/search_engines/template_url.h"
11 #include "chrome/browser/webdata/keyword_table.h"
12 #include "chrome/browser/webdata/logins_table.h"
13 #include "chrome/browser/webdata/web_apps_table.h"
14 #include "chrome/browser/webdata/web_intents_table.h"
15 #include "components/signin/core/browser/webdata/token_service_table.h"
16 #include "components/webdata/common/web_database_service.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/notification_details.h"
19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/notification_source.h"
21 #include "third_party/skia/include/core/SkBitmap.h"
22
23 ////////////////////////////////////////////////////////////////////////////////
24 //
25 // WebDataService implementation.
26 //
27 ////////////////////////////////////////////////////////////////////////////////
28
29 using base::Bind;
30 using base::Time;
31 using content::BrowserThread;
32
WDAppImagesResult()33 WDAppImagesResult::WDAppImagesResult() : has_all_images(false) {}
34
~WDAppImagesResult()35 WDAppImagesResult::~WDAppImagesResult() {}
36
WDKeywordsResult()37 WDKeywordsResult::WDKeywordsResult()
38 : default_search_provider_id(0),
39 builtin_keyword_version(0) {
40 }
41
~WDKeywordsResult()42 WDKeywordsResult::~WDKeywordsResult() {}
43
KeywordBatchModeScoper(WebDataService * service)44 WebDataService::KeywordBatchModeScoper::KeywordBatchModeScoper(
45 WebDataService* service)
46 : service_(service) {
47 if (service_)
48 service_->AdjustKeywordBatchModeLevel(true);
49 }
50
~KeywordBatchModeScoper()51 WebDataService::KeywordBatchModeScoper::~KeywordBatchModeScoper() {
52 if (service_)
53 service_->AdjustKeywordBatchModeLevel(false);
54 }
55
WebDataService(scoped_refptr<WebDatabaseService> wdbs,const ProfileErrorCallback & callback)56 WebDataService::WebDataService(scoped_refptr<WebDatabaseService> wdbs,
57 const ProfileErrorCallback& callback)
58 : WebDataServiceBase(
59 wdbs, callback,
60 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
61 keyword_batch_mode_level_(0) {
62 }
63
64 //////////////////////////////////////////////////////////////////////////////
65 //
66 // Keywords.
67 //
68 //////////////////////////////////////////////////////////////////////////////
69
AddKeyword(const TemplateURLData & data)70 void WebDataService::AddKeyword(const TemplateURLData& data) {
71 if (keyword_batch_mode_level_) {
72 queued_keyword_operations_.push_back(
73 KeywordTable::Operation(KeywordTable::ADD, data));
74 } else {
75 AdjustKeywordBatchModeLevel(true);
76 AddKeyword(data);
77 AdjustKeywordBatchModeLevel(false);
78 }
79 }
80
RemoveKeyword(TemplateURLID id)81 void WebDataService::RemoveKeyword(TemplateURLID id) {
82 if (keyword_batch_mode_level_) {
83 TemplateURLData data;
84 data.id = id;
85 queued_keyword_operations_.push_back(
86 KeywordTable::Operation(KeywordTable::REMOVE, data));
87 } else {
88 AdjustKeywordBatchModeLevel(true);
89 RemoveKeyword(id);
90 AdjustKeywordBatchModeLevel(false);
91 }
92 }
93
UpdateKeyword(const TemplateURLData & data)94 void WebDataService::UpdateKeyword(const TemplateURLData& data) {
95 if (keyword_batch_mode_level_) {
96 queued_keyword_operations_.push_back(
97 KeywordTable::Operation(KeywordTable::UPDATE, data));
98 } else {
99 AdjustKeywordBatchModeLevel(true);
100 UpdateKeyword(data);
101 AdjustKeywordBatchModeLevel(false);
102 }
103 }
104
GetKeywords(WebDataServiceConsumer * consumer)105 WebDataServiceBase::Handle WebDataService::GetKeywords(
106 WebDataServiceConsumer* consumer) {
107 return wdbs_->ScheduleDBTaskWithResult(
108 FROM_HERE, Bind(&WebDataService::GetKeywordsImpl, this), consumer);
109 }
110
SetDefaultSearchProviderID(TemplateURLID id)111 void WebDataService::SetDefaultSearchProviderID(TemplateURLID id) {
112 wdbs_->ScheduleDBTask(
113 FROM_HERE,
114 Bind(&WebDataService::SetDefaultSearchProviderIDImpl, this, id));
115 }
116
SetBuiltinKeywordVersion(int version)117 void WebDataService::SetBuiltinKeywordVersion(int version) {
118 wdbs_->ScheduleDBTask(
119 FROM_HERE,
120 Bind(&WebDataService::SetBuiltinKeywordVersionImpl, this, version));
121 }
122
123 //////////////////////////////////////////////////////////////////////////////
124 //
125 // Web Apps
126 //
127 //////////////////////////////////////////////////////////////////////////////
128
SetWebAppImage(const GURL & app_url,const SkBitmap & image)129 void WebDataService::SetWebAppImage(const GURL& app_url,
130 const SkBitmap& image) {
131 wdbs_->ScheduleDBTask(FROM_HERE,
132 Bind(&WebDataService::SetWebAppImageImpl, this, app_url, image));
133 }
134
SetWebAppHasAllImages(const GURL & app_url,bool has_all_images)135 void WebDataService::SetWebAppHasAllImages(const GURL& app_url,
136 bool has_all_images) {
137 wdbs_->ScheduleDBTask(FROM_HERE,
138 Bind(&WebDataService::SetWebAppHasAllImagesImpl, this, app_url,
139 has_all_images));
140 }
141
RemoveWebApp(const GURL & app_url)142 void WebDataService::RemoveWebApp(const GURL& app_url) {
143 wdbs_->ScheduleDBTask(FROM_HERE,
144 Bind(&WebDataService::RemoveWebAppImpl, this, app_url));
145 }
146
GetWebAppImages(const GURL & app_url,WebDataServiceConsumer * consumer)147 WebDataServiceBase::Handle WebDataService::GetWebAppImages(
148 const GURL& app_url, WebDataServiceConsumer* consumer) {
149 return wdbs_->ScheduleDBTaskWithResult(FROM_HERE,
150 Bind(&WebDataService::GetWebAppImagesImpl, this, app_url), consumer);
151 }
152
153 ////////////////////////////////////////////////////////////////////////////////
154
WebDataService()155 WebDataService::WebDataService()
156 : WebDataServiceBase(
157 NULL, ProfileErrorCallback(),
158 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
159 keyword_batch_mode_level_(0) {
160 }
161
~WebDataService()162 WebDataService::~WebDataService() {
163 DCHECK(!keyword_batch_mode_level_);
164 }
165
AdjustKeywordBatchModeLevel(bool entering_batch_mode)166 void WebDataService::AdjustKeywordBatchModeLevel(bool entering_batch_mode) {
167 if (entering_batch_mode) {
168 ++keyword_batch_mode_level_;
169 } else {
170 DCHECK(keyword_batch_mode_level_);
171 --keyword_batch_mode_level_;
172 if (!keyword_batch_mode_level_ && !queued_keyword_operations_.empty()) {
173 wdbs_->ScheduleDBTask(
174 FROM_HERE,
175 Bind(&WebDataService::PerformKeywordOperationsImpl, this,
176 queued_keyword_operations_));
177 queued_keyword_operations_.clear();
178 }
179 }
180 }
181
182 ////////////////////////////////////////////////////////////////////////////////
183 //
184 // Keywords implementation.
185 //
186 ////////////////////////////////////////////////////////////////////////////////
187
PerformKeywordOperationsImpl(const KeywordTable::Operations & operations,WebDatabase * db)188 WebDatabase::State WebDataService::PerformKeywordOperationsImpl(
189 const KeywordTable::Operations& operations,
190 WebDatabase* db) {
191 return KeywordTable::FromWebDatabase(db)->PerformOperations(operations) ?
192 WebDatabase::COMMIT_NEEDED : WebDatabase::COMMIT_NOT_NEEDED;
193 }
194
GetKeywordsImpl(WebDatabase * db)195 scoped_ptr<WDTypedResult> WebDataService::GetKeywordsImpl(WebDatabase* db) {
196 scoped_ptr<WDTypedResult> result_ptr;
197 WDKeywordsResult result;
198 if (KeywordTable::FromWebDatabase(db)->GetKeywords(&result.keywords)) {
199 result.default_search_provider_id =
200 KeywordTable::FromWebDatabase(db)->GetDefaultSearchProviderID();
201 result.builtin_keyword_version =
202 KeywordTable::FromWebDatabase(db)->GetBuiltinKeywordVersion();
203 result_ptr.reset(new WDResult<WDKeywordsResult>(KEYWORDS_RESULT, result));
204 }
205 return result_ptr.Pass();
206 }
207
SetDefaultSearchProviderIDImpl(TemplateURLID id,WebDatabase * db)208 WebDatabase::State WebDataService::SetDefaultSearchProviderIDImpl(
209 TemplateURLID id,
210 WebDatabase* db) {
211 return KeywordTable::FromWebDatabase(db)->SetDefaultSearchProviderID(id) ?
212 WebDatabase::COMMIT_NEEDED : WebDatabase::COMMIT_NOT_NEEDED;
213 }
214
SetBuiltinKeywordVersionImpl(int version,WebDatabase * db)215 WebDatabase::State WebDataService::SetBuiltinKeywordVersionImpl(
216 int version,
217 WebDatabase* db) {
218 return KeywordTable::FromWebDatabase(db)->SetBuiltinKeywordVersion(version) ?
219 WebDatabase::COMMIT_NEEDED : WebDatabase::COMMIT_NOT_NEEDED;
220 }
221
222 ////////////////////////////////////////////////////////////////////////////////
223 //
224 // Web Apps implementation.
225 //
226 ////////////////////////////////////////////////////////////////////////////////
227
SetWebAppImageImpl(const GURL & app_url,const SkBitmap & image,WebDatabase * db)228 WebDatabase::State WebDataService::SetWebAppImageImpl(
229 const GURL& app_url, const SkBitmap& image, WebDatabase* db) {
230 WebAppsTable::FromWebDatabase(db)->SetWebAppImage(app_url, image);
231 return WebDatabase::COMMIT_NEEDED;
232 }
233
SetWebAppHasAllImagesImpl(const GURL & app_url,bool has_all_images,WebDatabase * db)234 WebDatabase::State WebDataService::SetWebAppHasAllImagesImpl(
235 const GURL& app_url, bool has_all_images, WebDatabase* db) {
236 WebAppsTable::FromWebDatabase(db)->SetWebAppHasAllImages(app_url,
237 has_all_images);
238 return WebDatabase::COMMIT_NEEDED;
239 }
240
RemoveWebAppImpl(const GURL & app_url,WebDatabase * db)241 WebDatabase::State WebDataService::RemoveWebAppImpl(
242 const GURL& app_url, WebDatabase* db) {
243 WebAppsTable::FromWebDatabase(db)->RemoveWebApp(app_url);
244 return WebDatabase::COMMIT_NEEDED;
245 }
246
GetWebAppImagesImpl(const GURL & app_url,WebDatabase * db)247 scoped_ptr<WDTypedResult> WebDataService::GetWebAppImagesImpl(
248 const GURL& app_url, WebDatabase* db) {
249 WDAppImagesResult result;
250 result.has_all_images =
251 WebAppsTable::FromWebDatabase(db)->GetWebAppHasAllImages(app_url);
252 WebAppsTable::FromWebDatabase(db)->GetWebAppImages(app_url, &result.images);
253 return scoped_ptr<WDTypedResult>(
254 new WDResult<WDAppImagesResult>(WEB_APP_IMAGES, result));
255 }
256