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

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: Couple of lint errors sneaked into my previous patch. This is clean of 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"
tim (not reviewing) 2010/12/13 19:24:33 illegal include
lipalani 2010/12/14 21:05:57 Done.
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::NOT_DETERMINED),
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::MIGRATED) {
193 syncable::AutofillMigrationDebugInfo debug_info;
194 debug_info.autofill_entries_added_during_migration =
195 number_of_entries_created_;
196 sync_service_->backend()->SetAutofillMigrationDebugInfo(
197 syncable::AutofillMigrationDebugInfo::ENTRIES_ADDED,
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
242 if (MigrationLoggingEnabled() &&
243 autofill_profile_not_migrated) {
244 VLOG(1) << "[AUTOFILL MIGRATION]"
245 << "Printing profiles from web db";
246
247 for (std::vector<AutoFillProfile*>::const_iterator ix =
248 all_profiles_from_db.begin(); ix != all_profiles_from_db.end(); ++ix) {
249 AutoFillProfile* p = *ix;
250 VLOG(1) << "[AUTOFILL MIGRATION] "
251 << UTF16ToUTF8(p->GetFieldText(AutoFillType(NAME_FIRST)))
252 << UTF16ToUTF8(p->GetFieldText(AutoFillType(NAME_LAST)));
253 }
254 }
255
256 if (MigrationLoggingEnabled() && autofill_profile_not_migrated) {
257 VLOG(1) << "[AUTOFILL MIGRATION]"
258 << "Iterating over sync db";
259 }
260
247 int64 sync_child_id = autofill_root.GetFirstChildId(); 261 int64 sync_child_id = autofill_root.GetFirstChildId();
248 while (sync_child_id != sync_api::kInvalidId) { 262 while (sync_child_id != sync_api::kInvalidId) {
249 sync_api::ReadNode sync_child(write_trans); 263 sync_api::ReadNode sync_child(write_trans);
250 if (!sync_child.InitByIdLookup(sync_child_id)) { 264 if (!sync_child.InitByIdLookup(sync_child_id)) {
251 LOG(ERROR) << "Failed to fetch child node."; 265 LOG(ERROR) << "Failed to fetch child node.";
252 return false; 266 return false;
253 } 267 }
254 const sync_pb::AutofillSpecifics& autofill( 268 const sync_pb::AutofillSpecifics& autofill(
255 sync_child.GetAutofillSpecifics()); 269 sync_child.GetAutofillSpecifics());
256 270
257 if (autofill.has_value()) { 271 if (autofill.has_value()) {
258 AddNativeEntryIfNeeded(autofill, bundle, sync_child); 272 AddNativeEntryIfNeeded(autofill, bundle, sync_child);
259 } else if (autofill.has_profile() && HasNotMigratedYet()) { 273 } else if (autofill.has_profile()) {
260 // Ignore autofill profiles if we are not upgrading. 274 // Ignore autofill profiles if we are not upgrading.
261 AddNativeProfileIfNeeded( 275 if (autofill_profile_not_migrated) {
262 autofill.profile(), 276 if (MigrationLoggingEnabled()) {
263 bundle, 277 VLOG(1) << "[AUTOFILL MIGRATION] Looking for "
tim (not reviewing) 2010/12/13 19:24:33 it seems weird to combine vlog with another condit
lipalani 2010/12/14 21:05:57 Would it be OK if I dealt with logging on the next
264 sync_child, 278 << autofill.profile().name_first()
265 all_profiles_from_db); 279 << autofill.profile().name_last();
280 }
281 AddNativeProfileIfNeeded(
282 autofill.profile(),
283 bundle,
284 sync_child,
285 all_profiles_from_db);
286 }
266 } else { 287 } else {
267 NOTREACHED() << "AutofillSpecifics has no autofill data!"; 288 NOTREACHED() << "AutofillSpecifics has no autofill data!";
268 } 289 }
269 290
270 sync_child_id = sync_child.GetSuccessorId(); 291 sync_child_id = sync_child.GetSuccessorId();
271 } 292 }
272 return true; 293 return true;
273 } 294 }
274 295
275 // Define the functor to be used as the predicate in find_if call. 296 // 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 } 346 }
326 347
327 void AutofillModelAssociator::AddNativeProfileIfNeeded( 348 void AutofillModelAssociator::AddNativeProfileIfNeeded(
328 const sync_pb::AutofillProfileSpecifics& profile, 349 const sync_pb::AutofillProfileSpecifics& profile,
329 DataBundle* bundle, 350 DataBundle* bundle,
330 const sync_api::ReadNode& node, 351 const sync_api::ReadNode& node,
331 const std::vector<AutoFillProfile*>& all_profiles_from_db) { 352 const std::vector<AutoFillProfile*>& all_profiles_from_db) {
332 353
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
334 355
335 scoped_ptr<AutoFillProfile> profile_in_web_db(FindCorrespondingNodeFromWebDB( 356 AutoFillProfile* profile_in_web_db = FindCorrespondingNodeFromWebDB(
336 profile, all_profiles_from_db)); 357 profile, all_profiles_from_db);
337 358
338 if (profile_in_web_db.get() != NULL) { 359 if (profile_in_web_db != NULL) {
360 if (MigrationLoggingEnabled()) {
361 VLOG(1) << "[AUTOFILL MIGRATION]"
362 << "Node found in web db. So associating";
363 }
339 int64 sync_id = node.GetId(); 364 int64 sync_id = node.GetId();
340 std::string guid = profile_in_web_db->guid(); 365 std::string guid = profile_in_web_db->guid();
341 Associate(&guid, sync_id); 366 Associate(&guid, sync_id);
342 return; 367 return;
343 } else { // Create a new node. 368 } else { // Create a new node.
369 if (MigrationLoggingEnabled()) {
370 VLOG(1) << "[AUTOFILL MIGRATION]"
371 << "Node not found in web db so creating and associating";
372 }
344 std::string guid = guid::GenerateGUID(); 373 std::string guid = guid::GenerateGUID();
345 Associate(&guid, node.GetId()); 374 Associate(&guid, node.GetId());
346 AutoFillProfile* p = new AutoFillProfile(guid); 375 AutoFillProfile* p = new AutoFillProfile(guid);
347 FillProfileWithServerData(p, profile); 376 FillProfileWithServerData(p, profile);
348 bundle->new_profiles.push_back(p); 377 bundle->new_profiles.push_back(p);
349 } 378 }
350 } 379 }
351 380
352 bool AutofillModelAssociator::DisassociateModels() { 381 bool AutofillModelAssociator::DisassociateModels() {
353 id_map_.clear(); 382 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; 531 diff = MergeField(p, ADDRESS_HOME_ZIP, s.address_home_zip()) || diff;
503 diff = MergeField(p, EMAIL_ADDRESS, s.email_address()) || diff; 532 diff = MergeField(p, EMAIL_ADDRESS, s.email_address()) || diff;
504 diff = MergeField(p, COMPANY_NAME, s.company_name()) || diff; 533 diff = MergeField(p, COMPANY_NAME, s.company_name()) || diff;
505 diff = MergeField(p, PHONE_FAX_WHOLE_NUMBER, s.phone_fax_whole_number()) 534 diff = MergeField(p, PHONE_FAX_WHOLE_NUMBER, s.phone_fax_whole_number())
506 || diff; 535 || diff;
507 diff = MergeField(p, PHONE_HOME_WHOLE_NUMBER, s.phone_home_whole_number()) 536 diff = MergeField(p, PHONE_HOME_WHOLE_NUMBER, s.phone_home_whole_number())
508 || diff; 537 || diff;
509 return diff; 538 return diff;
510 } 539 }
511 540
512 bool AutofillModelAssociator::HasNotMigratedYet() { 541 bool AutofillModelAssociator::HasNotMigratedYet(
513 return true; 542 const sync_api::BaseTransaction* trans) {
543
544 // If state is migrated in our cached variable return true. We dont have
545 // to check against the directory as it will not change.
546 if (autofill_migration_state_ ==
tim (not reviewing) 2010/12/13 19:24:33 I thought we were getting rid of this cache?
lipalani 2010/12/14 21:05:57 Yeah I got rid of it! it is reflected in the curre
547 syncable::MIGRATED) {
tim (not reviewing) 2010/12/13 19:24:33 I think this fits on previous line, but it shouldn
lipalani 2010/12/14 21:05:57 I fixed the line indentation. Not sure I understan
548 return false;
549 }
550
551 // Now read the current value from the directory.
552 autofill_migration_state_ =
553 sync_service()->backend()->GetAutofillMigrationState();
554
555 DCHECK_NE(autofill_migration_state_, syncable::NOT_DETERMINED);
556
557 if (autofill_migration_state_== syncable::NOT_DETERMINED) {
558 VLOG(1) << "Autofill migration state is not determined inside "
559 << " model associator";
560 }
561 if (autofill_migration_state_ ==
562 syncable::NOT_MIGRATED) {
tim (not reviewing) 2010/12/13 19:24:33 same comment as above
lipalani 2010/12/14 21:05:57 Done.
563 return true;
564 }
565
566 if (autofill_migration_state_ ==
567 syncable::INSUFFICIENT_INFO_TO_DETERMINE) {
568 if (MigrationLoggingEnabled()) {
569 VLOG(1) << "[AUTOFILL MIGRATION]"
570 << "current autofill migration state is insufficient info to"
571 << "Determine";
572 }
573 sync_api::ReadNode autofill_profile_root_node(trans);
574 if (!autofill_profile_root_node.InitByTagLookup(
575 browser_sync::kAutofillProfileTag) ||
576 autofill_profile_root_node.GetFirstChildId()==
577 static_cast<int64>(0)) {
578 sync_service()->backend()->SetAutofillMigrationState(
579 syncable::NOT_MIGRATED);
580
581 if (MigrationLoggingEnabled()) {
582 VLOG(1) << "[AUTOFILL MIGRATION]"
583 << "Current autofill migration state is NOT Migrated becausse"
584 << "legacy autofil root node is preseent whereas new "
585 << "Autofill profile root node is not present";
586 }
587 return true;
588 }
589
590 sync_service()->backend()->SetAutofillMigrationState(
591 syncable::MIGRATED);
592
593 if (MigrationLoggingEnabled()) {
594 VLOG(1) << "[AUTOFILL MIGRATION]"
595 << "Current autofill migration state is migrated";
596 }
597 autofill_migration_state_ =
598 syncable::MIGRATED;
tim (not reviewing) 2010/12/13 19:24:33 prev line
lipalani 2010/12/14 21:05:57 Removed. On 2010/12/13 19:24:33, timsteele wrote:
599 }
600
601 return false;
514 } 602 }
515 603
604 bool AutofillModelAssociator::MigrationLoggingEnabled() {
605 // [TODO] enable logging via a command line flag.
tim (not reviewing) 2010/12/13 19:24:33 what's the plan here?
lipalani 2010/12/14 21:05:57 Logging part of the next cl? On 2010/12/13 19:24:3
606 return false;
607 }
516 } // namespace browser_sync 608 } // namespace browser_sync
609
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698