OLD | NEW |
| (Empty) |
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/autofill_web_data_service.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/stl_util.h" | |
9 #include "chrome/browser/webdata/autofill_change.h" | |
10 #include "chrome/browser/webdata/autofill_entry.h" | |
11 #include "chrome/browser/webdata/autofill_table.h" | |
12 #include "chrome/browser/webdata/autofill_web_data_service_observer.h" | |
13 #include "chrome/browser/webdata/web_database_service.h" | |
14 #include "components/autofill/browser/autofill_country.h" | |
15 #include "components/autofill/browser/autofill_profile.h" | |
16 #include "components/autofill/browser/credit_card.h" | |
17 #include "components/autofill/common/form_field_data.h" | |
18 | |
19 using base::Bind; | |
20 using base::Time; | |
21 using content::BrowserThread; | |
22 | |
23 // static | |
24 void AutofillWebDataService::NotifyOfMultipleAutofillChanges( | |
25 AutofillWebDataService* web_data_service) { | |
26 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
27 | |
28 if (!web_data_service) | |
29 return; | |
30 | |
31 BrowserThread::PostTask( | |
32 BrowserThread::UI, FROM_HERE, | |
33 Bind(&AutofillWebDataService::NotifyAutofillMultipleChangedOnUIThread, | |
34 make_scoped_refptr(web_data_service))); | |
35 } | |
36 | |
37 AutofillWebDataService::AutofillWebDataService( | |
38 scoped_refptr<WebDatabaseService> wdbs, | |
39 const ProfileErrorCallback& callback) | |
40 : WebDataServiceBase(wdbs, callback) { | |
41 } | |
42 | |
43 AutofillWebDataService::AutofillWebDataService() | |
44 : WebDataServiceBase(NULL, | |
45 WebDataServiceBase::ProfileErrorCallback()) { | |
46 } | |
47 | |
48 void AutofillWebDataService::AddFormFields( | |
49 const std::vector<FormFieldData>& fields) { | |
50 wdbs_->ScheduleDBTask(FROM_HERE, | |
51 Bind(&AutofillWebDataService::AddFormElementsImpl, this, fields)); | |
52 } | |
53 | |
54 WebDataServiceBase::Handle AutofillWebDataService::GetFormValuesForElementName( | |
55 const string16& name, const string16& prefix, int limit, | |
56 WebDataServiceConsumer* consumer) { | |
57 return wdbs_->ScheduleDBTaskWithResult(FROM_HERE, | |
58 Bind(&AutofillWebDataService::GetFormValuesForElementNameImpl, | |
59 this, name, prefix, limit), consumer); | |
60 } | |
61 | |
62 void AutofillWebDataService::RemoveFormElementsAddedBetween( | |
63 const Time& delete_begin, const Time& delete_end) { | |
64 wdbs_->ScheduleDBTask(FROM_HERE, | |
65 Bind(&AutofillWebDataService::RemoveFormElementsAddedBetweenImpl, | |
66 this, delete_begin, delete_end)); | |
67 } | |
68 | |
69 void AutofillWebDataService::RemoveExpiredFormElements() { | |
70 wdbs_->ScheduleDBTask(FROM_HERE, | |
71 Bind(&AutofillWebDataService::RemoveExpiredFormElementsImpl, this)); | |
72 } | |
73 | |
74 void AutofillWebDataService::RemoveFormValueForElementName( | |
75 const string16& name, const string16& value) { | |
76 wdbs_->ScheduleDBTask(FROM_HERE, | |
77 Bind(&AutofillWebDataService::RemoveFormValueForElementNameImpl, | |
78 this, name, value)); | |
79 } | |
80 | |
81 void AutofillWebDataService::AddAutofillProfile( | |
82 const AutofillProfile& profile) { | |
83 wdbs_->ScheduleDBTask(FROM_HERE, | |
84 Bind(&AutofillWebDataService::AddAutofillProfileImpl, this, profile)); | |
85 } | |
86 | |
87 void AutofillWebDataService::UpdateAutofillProfile( | |
88 const AutofillProfile& profile) { | |
89 wdbs_->ScheduleDBTask(FROM_HERE, | |
90 Bind(&AutofillWebDataService::UpdateAutofillProfileImpl, | |
91 this, profile)); | |
92 } | |
93 | |
94 void AutofillWebDataService::RemoveAutofillProfile( | |
95 const std::string& guid) { | |
96 wdbs_->ScheduleDBTask(FROM_HERE, | |
97 Bind(&AutofillWebDataService::RemoveAutofillProfileImpl, this, guid)); | |
98 } | |
99 | |
100 WebDataServiceBase::Handle AutofillWebDataService::GetAutofillProfiles( | |
101 WebDataServiceConsumer* consumer) { | |
102 return wdbs_->ScheduleDBTaskWithResult(FROM_HERE, | |
103 Bind(&AutofillWebDataService::GetAutofillProfilesImpl, this), | |
104 consumer); | |
105 } | |
106 | |
107 void AutofillWebDataService::AddCreditCard(const CreditCard& credit_card) { | |
108 wdbs_->ScheduleDBTask( | |
109 FROM_HERE, | |
110 Bind(&AutofillWebDataService::AddCreditCardImpl, this, credit_card)); | |
111 } | |
112 | |
113 void AutofillWebDataService::UpdateCreditCard( | |
114 const CreditCard& credit_card) { | |
115 wdbs_->ScheduleDBTask( | |
116 FROM_HERE, | |
117 Bind(&AutofillWebDataService::UpdateCreditCardImpl, this, credit_card)); | |
118 } | |
119 | |
120 void AutofillWebDataService::RemoveCreditCard(const std::string& guid) { | |
121 wdbs_->ScheduleDBTask( | |
122 FROM_HERE, | |
123 Bind(&AutofillWebDataService::RemoveCreditCardImpl, this, guid)); | |
124 } | |
125 | |
126 WebDataServiceBase::Handle AutofillWebDataService::GetCreditCards( | |
127 WebDataServiceConsumer* consumer) { | |
128 return wdbs_->ScheduleDBTaskWithResult(FROM_HERE, | |
129 Bind(&AutofillWebDataService::GetCreditCardsImpl, this), consumer); | |
130 } | |
131 | |
132 void AutofillWebDataService::RemoveAutofillDataModifiedBetween( | |
133 const Time& delete_begin, | |
134 const Time& delete_end) { | |
135 wdbs_->ScheduleDBTask( | |
136 FROM_HERE, | |
137 Bind(&AutofillWebDataService::RemoveAutofillDataModifiedBetweenImpl, | |
138 this, delete_begin, delete_end)); | |
139 } | |
140 | |
141 void AutofillWebDataService::AddObserver( | |
142 AutofillWebDataServiceObserverOnDBThread* observer) { | |
143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
144 db_observer_list_.AddObserver(observer); | |
145 } | |
146 | |
147 void AutofillWebDataService::RemoveObserver( | |
148 AutofillWebDataServiceObserverOnDBThread* observer) { | |
149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
150 db_observer_list_.RemoveObserver(observer); | |
151 } | |
152 | |
153 void AutofillWebDataService::AddObserver( | |
154 AutofillWebDataServiceObserverOnUIThread* observer) { | |
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
156 ui_observer_list_.AddObserver(observer); | |
157 } | |
158 | |
159 void AutofillWebDataService::RemoveObserver( | |
160 AutofillWebDataServiceObserverOnUIThread* observer) { | |
161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
162 ui_observer_list_.RemoveObserver(observer); | |
163 } | |
164 | |
165 AutofillWebDataService::~AutofillWebDataService() {} | |
166 | |
167 void AutofillWebDataService::NotifyDatabaseLoadedOnUIThread() { | |
168 // Notify that the database has been initialized. | |
169 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnUIThread, | |
170 ui_observer_list_, | |
171 WebDatabaseLoaded()); | |
172 } | |
173 | |
174 //////////////////////////////////////////////////////////////////////////////// | |
175 // | |
176 // Autofill implementation. | |
177 // | |
178 //////////////////////////////////////////////////////////////////////////////// | |
179 | |
180 WebDatabase::State AutofillWebDataService::AddFormElementsImpl( | |
181 const std::vector<FormFieldData>& fields, WebDatabase* db) { | |
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
183 AutofillChangeList changes; | |
184 if (!AutofillTable::FromWebDatabase(db)->AddFormFieldValues( | |
185 fields, &changes)) { | |
186 NOTREACHED(); | |
187 return WebDatabase::COMMIT_NOT_NEEDED; | |
188 } | |
189 | |
190 // Post the notifications including the list of affected keys. | |
191 // This is sent here so that work resulting from this notification will be | |
192 // done on the DB thread, and not the UI thread. | |
193 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnDBThread, | |
194 db_observer_list_, | |
195 AutofillEntriesChanged(changes)); | |
196 | |
197 return WebDatabase::COMMIT_NEEDED; | |
198 } | |
199 | |
200 scoped_ptr<WDTypedResult> | |
201 AutofillWebDataService::GetFormValuesForElementNameImpl( | |
202 const string16& name, const string16& prefix, int limit, WebDatabase* db) { | |
203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
204 std::vector<string16> values; | |
205 AutofillTable::FromWebDatabase(db)->GetFormValuesForElementName( | |
206 name, prefix, &values, limit); | |
207 return scoped_ptr<WDTypedResult>( | |
208 new WDResult<std::vector<string16> >(AUTOFILL_VALUE_RESULT, values)); | |
209 } | |
210 | |
211 WebDatabase::State AutofillWebDataService::RemoveFormElementsAddedBetweenImpl( | |
212 const base::Time& delete_begin, const base::Time& delete_end, | |
213 WebDatabase* db) { | |
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
215 AutofillChangeList changes; | |
216 | |
217 if (AutofillTable::FromWebDatabase(db)->RemoveFormElementsAddedBetween( | |
218 delete_begin, delete_end, &changes)) { | |
219 if (!changes.empty()) { | |
220 // Post the notifications including the list of affected keys. | |
221 // This is sent here so that work resulting from this notification | |
222 // will be done on the DB thread, and not the UI thread. | |
223 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnDBThread, | |
224 db_observer_list_, | |
225 AutofillEntriesChanged(changes)); | |
226 } | |
227 return WebDatabase::COMMIT_NEEDED; | |
228 } | |
229 return WebDatabase::COMMIT_NOT_NEEDED; | |
230 } | |
231 | |
232 WebDatabase::State AutofillWebDataService::RemoveExpiredFormElementsImpl( | |
233 WebDatabase* db) { | |
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
235 AutofillChangeList changes; | |
236 | |
237 if (AutofillTable::FromWebDatabase(db)->RemoveExpiredFormElements(&changes)) { | |
238 if (!changes.empty()) { | |
239 // Post the notifications including the list of affected keys. | |
240 // This is sent here so that work resulting from this notification | |
241 // will be done on the DB thread, and not the UI thread. | |
242 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnDBThread, | |
243 db_observer_list_, | |
244 AutofillEntriesChanged(changes)); | |
245 } | |
246 return WebDatabase::COMMIT_NEEDED; | |
247 } | |
248 return WebDatabase::COMMIT_NOT_NEEDED; | |
249 } | |
250 | |
251 WebDatabase::State AutofillWebDataService::RemoveFormValueForElementNameImpl( | |
252 const string16& name, const string16& value, WebDatabase* db) { | |
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
254 | |
255 if (AutofillTable::FromWebDatabase(db)->RemoveFormElement(name, value)) { | |
256 AutofillChangeList changes; | |
257 changes.push_back( | |
258 AutofillChange(AutofillChange::REMOVE, AutofillKey(name, value))); | |
259 | |
260 // Post the notifications including the list of affected keys. | |
261 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnDBThread, | |
262 db_observer_list_, | |
263 AutofillEntriesChanged(changes)); | |
264 | |
265 return WebDatabase::COMMIT_NEEDED; | |
266 } | |
267 return WebDatabase::COMMIT_NOT_NEEDED; | |
268 } | |
269 | |
270 WebDatabase::State AutofillWebDataService::AddAutofillProfileImpl( | |
271 const AutofillProfile& profile, WebDatabase* db) { | |
272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
273 if (!AutofillTable::FromWebDatabase(db)->AddAutofillProfile(profile)) { | |
274 NOTREACHED(); | |
275 return WebDatabase::COMMIT_NOT_NEEDED; | |
276 } | |
277 | |
278 // Send GUID-based notification. | |
279 AutofillProfileChange change( | |
280 AutofillProfileChange::ADD, profile.guid(), &profile); | |
281 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnDBThread, | |
282 db_observer_list_, | |
283 AutofillProfileChanged(change)); | |
284 | |
285 return WebDatabase::COMMIT_NEEDED; | |
286 } | |
287 | |
288 WebDatabase::State AutofillWebDataService::UpdateAutofillProfileImpl( | |
289 const AutofillProfile& profile, WebDatabase* db) { | |
290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
291 // Only perform the update if the profile exists. It is currently | |
292 // valid to try to update a missing profile. We simply drop the write and | |
293 // the caller will detect this on the next refresh. | |
294 AutofillProfile* original_profile = NULL; | |
295 if (!AutofillTable::FromWebDatabase(db)->GetAutofillProfile(profile.guid(), | |
296 &original_profile)) { | |
297 return WebDatabase::COMMIT_NOT_NEEDED; | |
298 } | |
299 scoped_ptr<AutofillProfile> scoped_profile(original_profile); | |
300 | |
301 if (!AutofillTable::FromWebDatabase(db)->UpdateAutofillProfileMulti( | |
302 profile)) { | |
303 NOTREACHED(); | |
304 return WebDatabase::COMMIT_NEEDED; | |
305 } | |
306 | |
307 // Send GUID-based notification. | |
308 AutofillProfileChange change( | |
309 AutofillProfileChange::UPDATE, profile.guid(), &profile); | |
310 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnDBThread, | |
311 db_observer_list_, | |
312 AutofillProfileChanged(change)); | |
313 | |
314 return WebDatabase::COMMIT_NEEDED; | |
315 } | |
316 | |
317 WebDatabase::State AutofillWebDataService::RemoveAutofillProfileImpl( | |
318 const std::string& guid, WebDatabase* db) { | |
319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
320 AutofillProfile* profile = NULL; | |
321 if (!AutofillTable::FromWebDatabase(db)->GetAutofillProfile(guid, &profile)) { | |
322 NOTREACHED(); | |
323 return WebDatabase::COMMIT_NOT_NEEDED; | |
324 } | |
325 scoped_ptr<AutofillProfile> scoped_profile(profile); | |
326 | |
327 if (!AutofillTable::FromWebDatabase(db)->RemoveAutofillProfile(guid)) { | |
328 NOTREACHED(); | |
329 return WebDatabase::COMMIT_NOT_NEEDED; | |
330 } | |
331 | |
332 // Send GUID-based notification. | |
333 AutofillProfileChange change(AutofillProfileChange::REMOVE, guid, NULL); | |
334 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnDBThread, | |
335 db_observer_list_, | |
336 AutofillProfileChanged(change)); | |
337 | |
338 return WebDatabase::COMMIT_NEEDED; | |
339 } | |
340 | |
341 scoped_ptr<WDTypedResult> AutofillWebDataService::GetAutofillProfilesImpl( | |
342 WebDatabase* db) { | |
343 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
344 std::vector<AutofillProfile*> profiles; | |
345 AutofillTable::FromWebDatabase(db)->GetAutofillProfiles(&profiles); | |
346 return scoped_ptr<WDTypedResult>( | |
347 new WDDestroyableResult<std::vector<AutofillProfile*> >( | |
348 AUTOFILL_PROFILES_RESULT, | |
349 profiles, | |
350 base::Bind(&AutofillWebDataService::DestroyAutofillProfileResult, | |
351 base::Unretained(this)))); | |
352 } | |
353 | |
354 WebDatabase::State AutofillWebDataService::AddCreditCardImpl( | |
355 const CreditCard& credit_card, WebDatabase* db) { | |
356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
357 if (!AutofillTable::FromWebDatabase(db)->AddCreditCard(credit_card)) { | |
358 NOTREACHED(); | |
359 return WebDatabase::COMMIT_NOT_NEEDED; | |
360 } | |
361 | |
362 return WebDatabase::COMMIT_NEEDED; | |
363 } | |
364 | |
365 WebDatabase::State AutofillWebDataService::UpdateCreditCardImpl( | |
366 const CreditCard& credit_card, WebDatabase* db) { | |
367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
368 // It is currently valid to try to update a missing profile. We simply drop | |
369 // the write and the caller will detect this on the next refresh. | |
370 CreditCard* original_credit_card = NULL; | |
371 if (!AutofillTable::FromWebDatabase(db)->GetCreditCard(credit_card.guid(), | |
372 &original_credit_card)) { | |
373 return WebDatabase::COMMIT_NOT_NEEDED; | |
374 } | |
375 scoped_ptr<CreditCard> scoped_credit_card(original_credit_card); | |
376 | |
377 if (!AutofillTable::FromWebDatabase(db)->UpdateCreditCard(credit_card)) { | |
378 NOTREACHED(); | |
379 return WebDatabase::COMMIT_NOT_NEEDED; | |
380 } | |
381 return WebDatabase::COMMIT_NEEDED; | |
382 } | |
383 | |
384 WebDatabase::State AutofillWebDataService::RemoveCreditCardImpl( | |
385 const std::string& guid, WebDatabase* db) { | |
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
387 if (!AutofillTable::FromWebDatabase(db)->RemoveCreditCard(guid)) { | |
388 NOTREACHED(); | |
389 return WebDatabase::COMMIT_NOT_NEEDED; | |
390 } | |
391 return WebDatabase::COMMIT_NEEDED; | |
392 } | |
393 | |
394 scoped_ptr<WDTypedResult> AutofillWebDataService::GetCreditCardsImpl( | |
395 WebDatabase* db) { | |
396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
397 std::vector<CreditCard*> credit_cards; | |
398 AutofillTable::FromWebDatabase(db)->GetCreditCards(&credit_cards); | |
399 return scoped_ptr<WDTypedResult>( | |
400 new WDDestroyableResult<std::vector<CreditCard*> >( | |
401 AUTOFILL_CREDITCARDS_RESULT, | |
402 credit_cards, | |
403 base::Bind(&AutofillWebDataService::DestroyAutofillCreditCardResult, | |
404 base::Unretained(this)))); | |
405 } | |
406 | |
407 WebDatabase::State | |
408 AutofillWebDataService::RemoveAutofillDataModifiedBetweenImpl( | |
409 const base::Time& delete_begin, | |
410 const base::Time& delete_end, | |
411 WebDatabase* db) { | |
412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
413 std::vector<std::string> profile_guids; | |
414 std::vector<std::string> credit_card_guids; | |
415 if (AutofillTable::FromWebDatabase(db)->RemoveAutofillDataModifiedBetween( | |
416 delete_begin, | |
417 delete_end, | |
418 &profile_guids, | |
419 &credit_card_guids)) { | |
420 for (std::vector<std::string>::iterator iter = profile_guids.begin(); | |
421 iter != profile_guids.end(); ++iter) { | |
422 AutofillProfileChange change(AutofillProfileChange::REMOVE, *iter, NULL); | |
423 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnDBThread, | |
424 db_observer_list_, | |
425 AutofillProfileChanged(change)); | |
426 } | |
427 // Note: It is the caller's responsibility to post notifications for any | |
428 // changes, e.g. by calling the Refresh() method of PersonalDataManager. | |
429 return WebDatabase::COMMIT_NEEDED; | |
430 } | |
431 return WebDatabase::COMMIT_NOT_NEEDED; | |
432 } | |
433 | |
434 void AutofillWebDataService::DestroyAutofillProfileResult( | |
435 const WDTypedResult* result) { | |
436 DCHECK(result->GetType() == AUTOFILL_PROFILES_RESULT); | |
437 const WDResult<std::vector<AutofillProfile*> >* r = | |
438 static_cast<const WDResult<std::vector<AutofillProfile*> >*>(result); | |
439 std::vector<AutofillProfile*> profiles = r->GetValue(); | |
440 STLDeleteElements(&profiles); | |
441 } | |
442 | |
443 void AutofillWebDataService::DestroyAutofillCreditCardResult( | |
444 const WDTypedResult* result) { | |
445 DCHECK(result->GetType() == AUTOFILL_CREDITCARDS_RESULT); | |
446 const WDResult<std::vector<CreditCard*> >* r = | |
447 static_cast<const WDResult<std::vector<CreditCard*> >*>(result); | |
448 | |
449 std::vector<CreditCard*> credit_cards = r->GetValue(); | |
450 STLDeleteElements(&credit_cards); | |
451 } | |
452 | |
453 void AutofillWebDataService::NotifyAutofillMultipleChangedOnUIThread() { | |
454 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
455 FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnUIThread, | |
456 ui_observer_list_, | |
457 AutofillMultipleChanged()); | |
458 } | |
OLD | NEW |