Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(392)

Side by Side Diff: chrome/browser/sync/glue/autofill_model_associator.cc

Issue 5159001: Rest of the autofill work. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Autofill code after fixing the lint errors. Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/sync/glue/autofill_model_associator.h" 5 #include "chrome/browser/sync/glue/autofill_model_associator.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/task.h" 9 #include "base/task.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/autofill/autofill_profile.h" 13 #include "chrome/browser/autofill/autofill_profile.h"
14 #include "chrome/browser/browser_thread.h" 14 #include "chrome/browser/browser_thread.h"
15 #include "chrome/browser/guid.h" 15 #include "chrome/browser/guid.h"
16 #include "chrome/browser/prefs/pref_service.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/sync/engine/syncapi.h" 18 #include "chrome/browser/sync/engine/syncapi.h"
18 #include "chrome/browser/sync/glue/autofill_change_processor.h" 19 #include "chrome/browser/sync/glue/autofill_change_processor.h"
20 #include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
21 #include "chrome/browser/sync/glue/do_optimistic_refresh_Task.h"
19 #include "chrome/browser/sync/profile_sync_service.h" 22 #include "chrome/browser/sync/profile_sync_service.h"
20 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h" 23 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
24 #include "chrome/browser/sync/syncable/syncable.h"
21 #include "chrome/browser/webdata/web_database.h" 25 #include "chrome/browser/webdata/web_database.h"
26 #include "chrome/common/pref_names.h"
22 #include "net/base/escape.h" 27 #include "net/base/escape.h"
23 28
24 using base::TimeTicks; 29 using base::TimeTicks;
25 30
26 namespace browser_sync { 31 namespace browser_sync {
27 32
28 const char kAutofillTag[] = "google_chrome_autofill"; 33 const char kAutofillTag[] = "google_chrome_autofill";
29 const char kAutofillEntryNamespaceTag[] = "autofill_entry|"; 34 const char kAutofillEntryNamespaceTag[] = "autofill_entry|";
30 35
31 struct AutofillModelAssociator::DataBundle { 36 struct AutofillModelAssociator::DataBundle {
32 std::set<AutofillKey> current_entries; 37 std::set<AutofillKey> current_entries;
33 std::vector<AutofillEntry> new_entries; 38 std::vector<AutofillEntry> new_entries;
34 std::set<string16> current_profiles; 39 std::set<string16> current_profiles;
35 std::vector<AutoFillProfile*> updated_profiles; 40 std::vector<AutoFillProfile*> updated_profiles;
36 std::vector<AutoFillProfile*> new_profiles; // We own these pointers. 41 std::vector<AutoFillProfile*> new_profiles; // We own these pointers.
37 ~DataBundle() { STLDeleteElements(&new_profiles); } 42 ~DataBundle() { STLDeleteElements(&new_profiles); }
38 }; 43 };
39 44
40 AutofillModelAssociator::DoOptimisticRefreshTask::DoOptimisticRefreshTask(
41 PersonalDataManager* pdm) : pdm_(pdm) {}
42
43 AutofillModelAssociator::DoOptimisticRefreshTask::~DoOptimisticRefreshTask() {}
44
45 void AutofillModelAssociator::DoOptimisticRefreshTask::Run() {
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
47 pdm_->Refresh();
48 }
49
50 AutofillModelAssociator::AutofillModelAssociator( 45 AutofillModelAssociator::AutofillModelAssociator(
51 ProfileSyncService* sync_service, 46 ProfileSyncService* sync_service,
52 WebDatabase* web_database, 47 WebDatabase* web_database,
53 PersonalDataManager* personal_data) 48 PersonalDataManager* personal_data)
54 : sync_service_(sync_service), 49 : sync_service_(sync_service),
55 web_database_(web_database), 50 web_database_(web_database),
56 personal_data_(personal_data), 51 personal_data_(personal_data),
57 autofill_node_id_(sync_api::kInvalidId), 52 autofill_node_id_(sync_api::kInvalidId),
58 abort_association_pending_(false) { 53 autofill_migration_state_(syncable::Directory::PersistedKernelInfo::NOT_DE TERMINED),
54 abort_association_pending_(false),
55 number_of_entries_created_(0) {
59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
60 DCHECK(sync_service_); 57 DCHECK(sync_service_);
61 DCHECK(web_database_); 58 DCHECK(web_database_);
62 DCHECK(personal_data_); 59 DCHECK(personal_data_);
63 } 60 }
64 61
65 AutofillModelAssociator::~AutofillModelAssociator() { 62 AutofillModelAssociator::~AutofillModelAssociator() {
66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
67 } 64 }
68 65
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } else { 104 } else {
108 sync_api::WriteNode node(write_trans); 105 sync_api::WriteNode node(write_trans);
109 if (!node.InitUniqueByCreation(syncable::AUTOFILL, 106 if (!node.InitUniqueByCreation(syncable::AUTOFILL,
110 autofill_root, tag)) { 107 autofill_root, tag)) {
111 LOG(ERROR) << "Failed to create autofill sync node."; 108 LOG(ERROR) << "Failed to create autofill sync node.";
112 return false; 109 return false;
113 } 110 }
114 node.SetTitle(UTF8ToWide(tag)); 111 node.SetTitle(UTF8ToWide(tag));
115 AutofillChangeProcessor::WriteAutofillEntry(*ix, &node); 112 AutofillChangeProcessor::WriteAutofillEntry(*ix, &node);
116 Associate(&tag, node.GetId()); 113 Associate(&tag, node.GetId());
114 number_of_entries_created_++;
117 } 115 }
118 116
119 current_entries->insert(ix->key()); 117 current_entries->insert(ix->key());
120 } 118 }
121 return true; 119 return true;
122 } 120 }
123 121
124 bool AutofillModelAssociator::MakeNewAutofillProfileSyncNode(
125 sync_api::WriteTransaction* trans, const sync_api::BaseNode& autofill_root,
126 const std::string& tag, const AutoFillProfile& profile, int64* sync_id) {
127 sync_api::WriteNode node(trans);
128 if (!node.InitUniqueByCreation(syncable::AUTOFILL, autofill_root, tag)) {
129 LOG(ERROR) << "Failed to create autofill sync node.";
130 return false;
131 }
132 node.SetTitle(UTF8ToWide(tag));
133 AutofillChangeProcessor::WriteAutofillProfile(profile, &node);
134 *sync_id = node.GetId();
135 return true;
136 }
137
138
139 bool AutofillModelAssociator::LoadAutofillData( 122 bool AutofillModelAssociator::LoadAutofillData(
140 std::vector<AutofillEntry>* entries, 123 std::vector<AutofillEntry>* entries,
141 std::vector<AutoFillProfile*>* profiles) { 124 std::vector<AutoFillProfile*>* profiles) {
142 if (IsAbortPending()) 125 if (IsAbortPending())
143 return false; 126 return false;
144 if (!web_database_->GetAllAutofillEntries(entries)) 127 if (!web_database_->GetAllAutofillEntries(entries))
145 return false; 128 return false;
146 129
147 if (IsAbortPending()) 130 if (IsAbortPending())
148 return false; 131 return false;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 // Since we're on the DB thread, we don't have to worry about updating 181 // Since we're on the DB thread, we don't have to worry about updating
199 // the autofill database after closing the write transaction, since 182 // the autofill database after closing the write transaction, since
200 // this is the only thread that writes to the database. We also don't have 183 // this is the only thread that writes to the database. We also don't have
201 // to worry about the sync model getting out of sync, because changes are 184 // to worry about the sync model getting out of sync, because changes are
202 // propogated to the ChangeProcessor on this thread. 185 // propogated to the ChangeProcessor on this thread.
203 if (!SaveChangesToWebData(bundle)) { 186 if (!SaveChangesToWebData(bundle)) {
204 LOG(ERROR) << "Failed to update autofill entries."; 187 LOG(ERROR) << "Failed to update autofill entries.";
205 return false; 188 return false;
206 } 189 }
207 190
191 if (sync_service_->backend()->GetAutofillMigrationState() !=
192 syncable::Directory::PersistedKernelInfo::MIGRATED) {
193 syncable::AutofillMigrationDebugInfo debug_info;
tim (not reviewing) 2010/12/10 22:16:02 indent here or line above looks off
lipalani 2010/12/11 00:12:36 Done.
194 debug_info.autofill_entries_added_during_migration =
195 number_of_entries_created_;
tim (not reviewing) 2010/12/10 22:16:02 4 spaces indent
lipalani 2010/12/11 00:12:36 Done.
196 sync_service_->backend()->SetAutofillMigrationDebugInfo(
197 syncable::AutofillMigrationDebugInfo::ENTRIES_ADDED,
tim (not reviewing) 2010/12/10 22:16:02 4 spaces indent
lipalani 2010/12/11 00:12:36 Done.
198 debug_info);
199 }
200
208 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 201 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
209 new DoOptimisticRefreshTask(personal_data_)); 202 new DoOptimisticRefreshForAutofill(personal_data_));
210 return true; 203 return true;
211 } 204 }
212 205
213 bool AutofillModelAssociator::SaveChangesToWebData(const DataBundle& bundle) { 206 bool AutofillModelAssociator::SaveChangesToWebData(const DataBundle& bundle) {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
215 208
216 if (IsAbortPending()) 209 if (IsAbortPending())
217 return false; 210 return false;
218 211
219 if (bundle.new_entries.size() && 212 if (bundle.new_entries.size() &&
(...skipping 17 matching lines...) Expand all
237 return true; 230 return true;
238 } 231 }
239 232
240 bool AutofillModelAssociator::TraverseAndAssociateAllSyncNodes( 233 bool AutofillModelAssociator::TraverseAndAssociateAllSyncNodes(
241 sync_api::WriteTransaction* write_trans, 234 sync_api::WriteTransaction* write_trans,
242 const sync_api::ReadNode& autofill_root, 235 const sync_api::ReadNode& autofill_root,
243 DataBundle* bundle, 236 DataBundle* bundle,
244 const std::vector<AutoFillProfile*>& all_profiles_from_db) { 237 const std::vector<AutoFillProfile*>& all_profiles_from_db) {
245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
246 239
240 bool autofill_profile_not_migrated = HasNotMigratedYet(write_trans);
241
247 int64 sync_child_id = autofill_root.GetFirstChildId(); 242 int64 sync_child_id = autofill_root.GetFirstChildId();
248 while (sync_child_id != sync_api::kInvalidId) { 243 while (sync_child_id != sync_api::kInvalidId) {
249 sync_api::ReadNode sync_child(write_trans); 244 sync_api::ReadNode sync_child(write_trans);
250 if (!sync_child.InitByIdLookup(sync_child_id)) { 245 if (!sync_child.InitByIdLookup(sync_child_id)) {
251 LOG(ERROR) << "Failed to fetch child node."; 246 LOG(ERROR) << "Failed to fetch child node.";
252 return false; 247 return false;
253 } 248 }
254 const sync_pb::AutofillSpecifics& autofill( 249 const sync_pb::AutofillSpecifics& autofill(
255 sync_child.GetAutofillSpecifics()); 250 sync_child.GetAutofillSpecifics());
256 251
257 if (autofill.has_value()) { 252 if (autofill.has_value()) {
258 AddNativeEntryIfNeeded(autofill, bundle, sync_child); 253 AddNativeEntryIfNeeded(autofill, bundle, sync_child);
259 } else if (autofill.has_profile() && HasNotMigratedYet()) { 254 } else if (autofill.has_profile()) {
260 // Ignore autofill profiles if we are not upgrading. 255 // Ignore autofill profiles if we are not upgrading.
261 AddNativeProfileIfNeeded( 256 if (autofill_profile_not_migrated) {
262 autofill.profile(), 257 AddNativeProfileIfNeeded(
263 bundle, 258 autofill.profile(),
264 sync_child, 259 bundle,
265 all_profiles_from_db); 260 sync_child,
261 all_profiles_from_db);
262 }
266 } else { 263 } else {
267 NOTREACHED() << "AutofillSpecifics has no autofill data!"; 264 NOTREACHED() << "AutofillSpecifics has no autofill data!";
268 } 265 }
269 266
270 sync_child_id = sync_child.GetSuccessorId(); 267 sync_child_id = sync_child.GetSuccessorId();
271 } 268 }
272 return true; 269 return true;
273 } 270 }
274 271
275 // Define the functor to be used as the predicate in find_if call. 272 // Define the functor to be used as the predicate in find_if call.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 } 322 }
326 323
327 void AutofillModelAssociator::AddNativeProfileIfNeeded( 324 void AutofillModelAssociator::AddNativeProfileIfNeeded(
328 const sync_pb::AutofillProfileSpecifics& profile, 325 const sync_pb::AutofillProfileSpecifics& profile,
329 DataBundle* bundle, 326 DataBundle* bundle,
330 const sync_api::ReadNode& node, 327 const sync_api::ReadNode& node,
331 const std::vector<AutoFillProfile*>& all_profiles_from_db) { 328 const std::vector<AutoFillProfile*>& all_profiles_from_db) {
332 329
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
334 331
335 scoped_ptr<AutoFillProfile> profile_in_web_db(FindCorrespondingNodeFromWebDB( 332 AutoFillProfile* profile_in_web_db = FindCorrespondingNodeFromWebDB(
tim (not reviewing) 2010/12/10 22:16:02 why no scoped_ptr?
lipalani 2010/12/11 00:12:36 The pointer we are getting is part of the vector a
336 profile, all_profiles_from_db)); 333 profile, all_profiles_from_db);
337 334
338 if (profile_in_web_db.get() != NULL) { 335 if (profile_in_web_db != NULL) {
339 int64 sync_id = node.GetId(); 336 int64 sync_id = node.GetId();
340 std::string guid = profile_in_web_db->guid(); 337 std::string guid = profile_in_web_db->guid();
341 Associate(&guid, sync_id); 338 Associate(&guid, sync_id);
342 return; 339 return;
343 } else { // Create a new node. 340 } else { // Create a new node.
344 std::string guid = guid::GenerateGUID(); 341 std::string guid = guid::GenerateGUID();
345 Associate(&guid, node.GetId()); 342 Associate(&guid, node.GetId());
346 AutoFillProfile* p = new AutoFillProfile(guid); 343 AutoFillProfile* p = new AutoFillProfile(guid);
347 FillProfileWithServerData(p, profile); 344 FillProfileWithServerData(p, profile);
348 bundle->new_profiles.push_back(p); 345 bundle->new_profiles.push_back(p);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 diff = MergeField(p, ADDRESS_HOME_ZIP, s.address_home_zip()) || diff; 499 diff = MergeField(p, ADDRESS_HOME_ZIP, s.address_home_zip()) || diff;
503 diff = MergeField(p, EMAIL_ADDRESS, s.email_address()) || diff; 500 diff = MergeField(p, EMAIL_ADDRESS, s.email_address()) || diff;
504 diff = MergeField(p, COMPANY_NAME, s.company_name()) || diff; 501 diff = MergeField(p, COMPANY_NAME, s.company_name()) || diff;
505 diff = MergeField(p, PHONE_FAX_WHOLE_NUMBER, s.phone_fax_whole_number()) 502 diff = MergeField(p, PHONE_FAX_WHOLE_NUMBER, s.phone_fax_whole_number())
506 || diff; 503 || diff;
507 diff = MergeField(p, PHONE_HOME_WHOLE_NUMBER, s.phone_home_whole_number()) 504 diff = MergeField(p, PHONE_HOME_WHOLE_NUMBER, s.phone_home_whole_number())
508 || diff; 505 || diff;
509 return diff; 506 return diff;
510 } 507 }
511 508
512 bool AutofillModelAssociator::HasNotMigratedYet() { 509 bool AutofillModelAssociator::HasNotMigratedYet(
513 return true; 510 const sync_api::BaseTransaction* trans) {
511
lipalani 2010/12/09 19:45:25 get rid of the variable.
lipalani 2010/12/11 00:12:36 we need the transaction variable. this comment was
512 // If state is migrated in our cached variable return true. We dont have
513 // to check against the directory as it will not change.
514 if (autofill_migration_state_ ==
515 syncable::Directory::PersistedKernelInfo::MIGRATED) {
516 return false;
517 }
518
519 // Now read the current value from the directory.
520 autofill_migration_state_ =
521 sync_service()->backend()->GetAutofillMigrationState();
522
lipalani 2010/12/09 19:45:25 add a redirect comment.
lipalani 2010/12/11 00:12:36 Done.
523 DCHECK_NE(autofill_migration_state_,
524 syncable::Directory::PersistedKernelInfo::NOT_DETERMINED);
525 if (autofill_migration_state_ ==
526 syncable::Directory::PersistedKernelInfo::NOT_MIGRATED) {
527 return true;
528 }
529
530 if (autofill_migration_state_ ==
531 syncable::Directory::PersistedKernelInfo::INSUFFICIENT_INFO_TO_DETERMINE) {
532 sync_api::ReadNode autofill_profile_root_node(trans);
533 if (!autofill_profile_root_node.InitByTagLookup(
534 browser_sync::kAutofillProfileTag) ||
535 autofill_profile_root_node.GetFirstChildId()==
536 static_cast<int64>(0)) {
537 sync_service()->backend()->SetAutofillMigrationState(
538 syncable::Directory::PersistedKernelInfo::NOT_MIGRATED);
539 return true;
540 }
541
542 sync_service()->backend()->SetAutofillMigrationState(
543 syncable::Directory::PersistedKernelInfo::MIGRATED);
544
545 autofill_migration_state_ =
546 syncable::Directory::PersistedKernelInfo::MIGRATED;
547 }
548
549 return false;
550
514 } 551 }
552 } // namespace browser_sync
515 553
516 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698