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