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

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: patch uploaded to debug why try servers have problem applying this patch. 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"
21 #include "chrome/browser/webdata/web_database.h" 24 #include "chrome/browser/webdata/web_database.h"
25 #include "chrome/common/pref_names.h"
22 #include "net/base/escape.h" 26 #include "net/base/escape.h"
23 27
24 using base::TimeTicks; 28 using base::TimeTicks;
25 29
26 namespace browser_sync { 30 namespace browser_sync {
27 31
28 const char kAutofillTag[] = "google_chrome_autofill"; 32 const char kAutofillTag[] = "google_chrome_autofill";
29 const char kAutofillEntryNamespaceTag[] = "autofill_entry|"; 33 const char kAutofillEntryNamespaceTag[] = "autofill_entry|";
30 34
31 struct AutofillModelAssociator::DataBundle { 35 struct AutofillModelAssociator::DataBundle {
32 std::set<AutofillKey> current_entries; 36 std::set<AutofillKey> current_entries;
33 std::vector<AutofillEntry> new_entries; 37 std::vector<AutofillEntry> new_entries;
34 std::set<string16> current_profiles; 38 std::set<string16> current_profiles;
35 std::vector<AutoFillProfile*> updated_profiles; 39 std::vector<AutoFillProfile*> updated_profiles;
36 std::vector<AutoFillProfile*> new_profiles; // We own these pointers. 40 std::vector<AutoFillProfile*> new_profiles; // We own these pointers.
37 ~DataBundle() { STLDeleteElements(&new_profiles); } 41 ~DataBundle() { STLDeleteElements(&new_profiles); }
38 }; 42 };
39 43
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( 44 AutofillModelAssociator::AutofillModelAssociator(
51 ProfileSyncService* sync_service, 45 ProfileSyncService* sync_service,
52 WebDatabase* web_database, 46 WebDatabase* web_database,
53 PersonalDataManager* personal_data) 47 PersonalDataManager* personal_data)
54 : sync_service_(sync_service), 48 : sync_service_(sync_service),
55 web_database_(web_database), 49 web_database_(web_database),
56 personal_data_(personal_data), 50 personal_data_(personal_data),
57 autofill_node_id_(sync_api::kInvalidId), 51 autofill_node_id_(sync_api::kInvalidId),
58 abort_association_pending_(false) { 52 abort_association_pending_(false),
53 number_of_entries_created_(0) {
59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
60 DCHECK(sync_service_); 55 DCHECK(sync_service_);
61 DCHECK(web_database_); 56 DCHECK(web_database_);
62 DCHECK(personal_data_); 57 DCHECK(personal_data_);
63 } 58 }
64 59
65 AutofillModelAssociator::~AutofillModelAssociator() { 60 AutofillModelAssociator::~AutofillModelAssociator() {
66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
67 } 62 }
68 63
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } else { 102 } else {
108 sync_api::WriteNode node(write_trans); 103 sync_api::WriteNode node(write_trans);
109 if (!node.InitUniqueByCreation(syncable::AUTOFILL, 104 if (!node.InitUniqueByCreation(syncable::AUTOFILL,
110 autofill_root, tag)) { 105 autofill_root, tag)) {
111 LOG(ERROR) << "Failed to create autofill sync node."; 106 LOG(ERROR) << "Failed to create autofill sync node.";
112 return false; 107 return false;
113 } 108 }
114 node.SetTitle(UTF8ToWide(tag)); 109 node.SetTitle(UTF8ToWide(tag));
115 AutofillChangeProcessor::WriteAutofillEntry(*ix, &node); 110 AutofillChangeProcessor::WriteAutofillEntry(*ix, &node);
116 Associate(&tag, node.GetId()); 111 Associate(&tag, node.GetId());
112 number_of_entries_created_++;
117 } 113 }
118 114
119 current_entries->insert(ix->key()); 115 current_entries->insert(ix->key());
120 } 116 }
121 return true; 117 return true;
122 } 118 }
123 119
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( 120 bool AutofillModelAssociator::LoadAutofillData(
140 std::vector<AutofillEntry>* entries, 121 std::vector<AutofillEntry>* entries,
141 std::vector<AutoFillProfile*>* profiles) { 122 std::vector<AutoFillProfile*>* profiles) {
142 if (IsAbortPending()) 123 if (IsAbortPending())
143 return false; 124 return false;
144 if (!web_database_->GetAllAutofillEntries(entries)) 125 if (!web_database_->GetAllAutofillEntries(entries))
145 return false; 126 return false;
146 127
147 if (IsAbortPending()) 128 if (IsAbortPending())
148 return false; 129 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 179 // 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 180 // 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 181 // 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 182 // to worry about the sync model getting out of sync, because changes are
202 // propogated to the ChangeProcessor on this thread. 183 // propogated to the ChangeProcessor on this thread.
203 if (!SaveChangesToWebData(bundle)) { 184 if (!SaveChangesToWebData(bundle)) {
204 LOG(ERROR) << "Failed to update autofill entries."; 185 LOG(ERROR) << "Failed to update autofill entries.";
205 return false; 186 return false;
206 } 187 }
207 188
189 if (sync_service_->backend()->GetAutofillMigrationState() !=
190 syncable::MIGRATED) {
191 syncable::AutofillMigrationDebugInfo debug_info;
192 debug_info.autofill_entries_added_during_migration =
193 number_of_entries_created_;
194 sync_service_->backend()->SetAutofillMigrationDebugInfo(
195 syncable::AutofillMigrationDebugInfo::ENTRIES_ADDED,
196 debug_info);
197 }
198
208 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 199 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
209 new DoOptimisticRefreshTask(personal_data_)); 200 new DoOptimisticRefreshForAutofill(personal_data_));
210 return true; 201 return true;
211 } 202 }
212 203
213 bool AutofillModelAssociator::SaveChangesToWebData(const DataBundle& bundle) { 204 bool AutofillModelAssociator::SaveChangesToWebData(const DataBundle& bundle) {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
215 206
216 if (IsAbortPending()) 207 if (IsAbortPending())
217 return false; 208 return false;
218 209
219 if (bundle.new_entries.size() && 210 if (bundle.new_entries.size() &&
(...skipping 17 matching lines...) Expand all
237 return true; 228 return true;
238 } 229 }
239 230
240 bool AutofillModelAssociator::TraverseAndAssociateAllSyncNodes( 231 bool AutofillModelAssociator::TraverseAndAssociateAllSyncNodes(
241 sync_api::WriteTransaction* write_trans, 232 sync_api::WriteTransaction* write_trans,
242 const sync_api::ReadNode& autofill_root, 233 const sync_api::ReadNode& autofill_root,
243 DataBundle* bundle, 234 DataBundle* bundle,
244 const std::vector<AutoFillProfile*>& all_profiles_from_db) { 235 const std::vector<AutoFillProfile*>& all_profiles_from_db) {
245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
246 237
238 bool autofill_profile_not_migrated = HasNotMigratedYet(write_trans);
239
240 if (MigrationLoggingEnabled() &&
241 autofill_profile_not_migrated) {
242 VLOG(1) << "[AUTOFILL MIGRATION]"
243 << "Printing profiles from web db";
244
245 for (std::vector<AutoFillProfile*>::const_iterator ix =
246 all_profiles_from_db.begin(); ix != all_profiles_from_db.end(); ++ix) {
247 AutoFillProfile* p = *ix;
248 VLOG(1) << "[AUTOFILL MIGRATION] "
249 << p->GetFieldText(AutoFillType(NAME_FIRST))
250 << p->GetFieldText(AutoFillType(NAME_LAST));
251 }
252 }
253
254 if (MigrationLoggingEnabled() && autofill_profile_not_migrated) {
255 VLOG(1) << "[AUTOFILL MIGRATION]"
256 << "Iterating over sync db";
257 }
258
247 int64 sync_child_id = autofill_root.GetFirstChildId(); 259 int64 sync_child_id = autofill_root.GetFirstChildId();
248 while (sync_child_id != sync_api::kInvalidId) { 260 while (sync_child_id != sync_api::kInvalidId) {
249 sync_api::ReadNode sync_child(write_trans); 261 sync_api::ReadNode sync_child(write_trans);
250 if (!sync_child.InitByIdLookup(sync_child_id)) { 262 if (!sync_child.InitByIdLookup(sync_child_id)) {
251 LOG(ERROR) << "Failed to fetch child node."; 263 LOG(ERROR) << "Failed to fetch child node.";
252 return false; 264 return false;
253 } 265 }
254 const sync_pb::AutofillSpecifics& autofill( 266 const sync_pb::AutofillSpecifics& autofill(
255 sync_child.GetAutofillSpecifics()); 267 sync_child.GetAutofillSpecifics());
256 268
257 if (autofill.has_value()) { 269 if (autofill.has_value()) {
258 AddNativeEntryIfNeeded(autofill, bundle, sync_child); 270 AddNativeEntryIfNeeded(autofill, bundle, sync_child);
259 } else if (autofill.has_profile() && HasNotMigratedYet()) { 271 } else if (autofill.has_profile()) {
260 // Ignore autofill profiles if we are not upgrading. 272 // Ignore autofill profiles if we are not upgrading.
261 AddNativeProfileIfNeeded( 273 if (autofill_profile_not_migrated) {
262 autofill.profile(), 274 if (MigrationLoggingEnabled()) {
263 bundle, 275 VLOG(1) << "[AUTOFILL MIGRATION] Looking for "
264 sync_child, 276 << autofill.profile().name_first()
265 all_profiles_from_db); 277 << autofill.profile().name_last();
278 }
279 AddNativeProfileIfNeeded(
280 autofill.profile(),
281 bundle,
282 sync_child,
283 all_profiles_from_db);
284 }
266 } else { 285 } else {
267 NOTREACHED() << "AutofillSpecifics has no autofill data!"; 286 NOTREACHED() << "AutofillSpecifics has no autofill data!";
268 } 287 }
269 288
270 sync_child_id = sync_child.GetSuccessorId(); 289 sync_child_id = sync_child.GetSuccessorId();
271 } 290 }
272 return true; 291 return true;
273 } 292 }
274 293
275 // Define the functor to be used as the predicate in find_if call. 294 // 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 } 344 }
326 345
327 void AutofillModelAssociator::AddNativeProfileIfNeeded( 346 void AutofillModelAssociator::AddNativeProfileIfNeeded(
328 const sync_pb::AutofillProfileSpecifics& profile, 347 const sync_pb::AutofillProfileSpecifics& profile,
329 DataBundle* bundle, 348 DataBundle* bundle,
330 const sync_api::ReadNode& node, 349 const sync_api::ReadNode& node,
331 const std::vector<AutoFillProfile*>& all_profiles_from_db) { 350 const std::vector<AutoFillProfile*>& all_profiles_from_db) {
332 351
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 352 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
334 353
335 scoped_ptr<AutoFillProfile> profile_in_web_db(FindCorrespondingNodeFromWebDB( 354 AutoFillProfile* profile_in_web_db = FindCorrespondingNodeFromWebDB(
336 profile, all_profiles_from_db)); 355 profile, all_profiles_from_db);
337 356
338 if (profile_in_web_db.get() != NULL) { 357 if (profile_in_web_db != NULL) {
358 if (MigrationLoggingEnabled()) {
359 VLOG(1) << "[AUTOFILL MIGRATION]"
360 << "Node found in web db. So associating";
361 }
339 int64 sync_id = node.GetId(); 362 int64 sync_id = node.GetId();
340 std::string guid = profile_in_web_db->guid(); 363 std::string guid = profile_in_web_db->guid();
341 Associate(&guid, sync_id); 364 Associate(&guid, sync_id);
342 return; 365 return;
343 } else { // Create a new node. 366 } else { // Create a new node.
367 if (MigrationLoggingEnabled()) {
368 VLOG(1) << "[AUTOFILL MIGRATION]"
369 << "Node not found in web db so creating and associating";
370 }
344 std::string guid = guid::GenerateGUID(); 371 std::string guid = guid::GenerateGUID();
345 Associate(&guid, node.GetId()); 372 Associate(&guid, node.GetId());
346 AutoFillProfile* p = new AutoFillProfile(guid); 373 AutoFillProfile* p = new AutoFillProfile(guid);
347 FillProfileWithServerData(p, profile); 374 FillProfileWithServerData(p, profile);
348 bundle->new_profiles.push_back(p); 375 bundle->new_profiles.push_back(p);
349 } 376 }
350 } 377 }
351 378
352 bool AutofillModelAssociator::DisassociateModels() { 379 bool AutofillModelAssociator::DisassociateModels() {
353 id_map_.clear(); 380 id_map_.clear();
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 diff = MergeField(p, ADDRESS_HOME_ZIP, s.address_home_zip()) || diff; 529 diff = MergeField(p, ADDRESS_HOME_ZIP, s.address_home_zip()) || diff;
503 diff = MergeField(p, EMAIL_ADDRESS, s.email_address()) || diff; 530 diff = MergeField(p, EMAIL_ADDRESS, s.email_address()) || diff;
504 diff = MergeField(p, COMPANY_NAME, s.company_name()) || diff; 531 diff = MergeField(p, COMPANY_NAME, s.company_name()) || diff;
505 diff = MergeField(p, PHONE_FAX_WHOLE_NUMBER, s.phone_fax_whole_number()) 532 diff = MergeField(p, PHONE_FAX_WHOLE_NUMBER, s.phone_fax_whole_number())
506 || diff; 533 || diff;
507 diff = MergeField(p, PHONE_HOME_WHOLE_NUMBER, s.phone_home_whole_number()) 534 diff = MergeField(p, PHONE_HOME_WHOLE_NUMBER, s.phone_home_whole_number())
508 || diff; 535 || diff;
509 return diff; 536 return diff;
510 } 537 }
511 538
512 bool AutofillModelAssociator::HasNotMigratedYet() { 539 bool AutofillModelAssociator::HasNotMigratedYet(
513 return true; 540 const sync_api::BaseTransaction* trans) {
541
542 // Now read the current value from the directory.
543 syncable::AutofillMigrationState autofill_migration_state =
544 sync_service()->backend()->GetAutofillMigrationState();
545
546 DCHECK_NE(autofill_migration_state, syncable::NOT_DETERMINED);
547
548 if (autofill_migration_state== syncable::NOT_DETERMINED) {
549 VLOG(1) << "Autofill migration state is not determined inside "
550 << " model associator";
551 }
552
553 if (autofill_migration_state == syncable::NOT_MIGRATED) {
554 return true;
555 }
556
557 if (autofill_migration_state == syncable::INSUFFICIENT_INFO_TO_DETERMINE) {
558 if (MigrationLoggingEnabled()) {
559 VLOG(1) << "[AUTOFILL MIGRATION]"
560 << "current autofill migration state is insufficient info to"
561 << "determine.";
562 }
563 sync_api::ReadNode autofill_profile_root_node(trans);
564 if (!autofill_profile_root_node.InitByTagLookup(
565 browser_sync::kAutofillProfileTag) ||
566 autofill_profile_root_node.GetFirstChildId()==
567 static_cast<int64>(0)) {
568 sync_service()->backend()->SetAutofillMigrationState(
569 syncable::NOT_MIGRATED);
570
571 if (MigrationLoggingEnabled()) {
572 VLOG(1) << "[AUTOFILL MIGRATION]"
573 << "Current autofill migration state is NOT Migrated because"
574 << "legacy autofill root node is present whereas new "
575 << "Autofill profile root node is absent.";
576 }
577 return true;
578 }
579
580 sync_service()->backend()->SetAutofillMigrationState(syncable::MIGRATED);
581
582 if (MigrationLoggingEnabled()) {
583 VLOG(1) << "[AUTOFILL MIGRATION]"
584 << "Current autofill migration state is migrated.";
585 }
586 }
587
588 return false;
514 } 589 }
515 590
591 bool AutofillModelAssociator::MigrationLoggingEnabled() {
592 // [TODO] enable logging via a command line flag.
593 return false;
594 }
516 } // namespace browser_sync 595 } // namespace browser_sync
596
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/autofill_model_associator.h ('k') | chrome/browser/sync/glue/autofill_profile_change_processor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698