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

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

Issue 9978017: [Sync] - Upload the callstacks for errors so that the line number of error is in callstack. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: For review. Created 8 years, 8 months 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) 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/sync/glue/password_model_associator.h" 5 #include "chrome/browser/sync/glue/password_model_associator.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 10 matching lines...) Expand all
21 #include "webkit/forms/password_form.h" 21 #include "webkit/forms/password_form.h"
22 22
23 using content::BrowserThread; 23 using content::BrowserThread;
24 24
25 namespace browser_sync { 25 namespace browser_sync {
26 26
27 const char kPasswordTag[] = "google_chrome_passwords"; 27 const char kPasswordTag[] = "google_chrome_passwords";
28 28
29 PasswordModelAssociator::PasswordModelAssociator( 29 PasswordModelAssociator::PasswordModelAssociator(
30 ProfileSyncService* sync_service, 30 ProfileSyncService* sync_service,
31 PasswordStore* password_store) 31 PasswordStore* password_store,
32 DataTypeErrorHandler* error_handler)
32 : sync_service_(sync_service), 33 : sync_service_(sync_service),
33 password_store_(password_store), 34 password_store_(password_store),
34 password_node_id_(sync_api::kInvalidId), 35 password_node_id_(sync_api::kInvalidId),
35 abort_association_pending_(false), 36 abort_association_pending_(false),
36 expected_loop_(MessageLoop::current()) { 37 expected_loop_(MessageLoop::current()),
38 error_handler_(error_handler) {
37 DCHECK(sync_service_); 39 DCHECK(sync_service_);
38 DCHECK(password_store_); 40 DCHECK(password_store_);
39 #if defined(OS_MACOSX) 41 #if defined(OS_MACOSX)
40 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 42 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
41 #else 43 #else
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
43 #endif 45 #endif
44 } 46 }
45 47
46 PasswordModelAssociator::~PasswordModelAssociator() {} 48 PasswordModelAssociator::~PasswordModelAssociator() {}
47 49
48 bool PasswordModelAssociator::AssociateModels(SyncError* error) { 50 SyncError PasswordModelAssociator::AssociateModels() {
51 SyncError error;
49 DCHECK(expected_loop_ == MessageLoop::current()); 52 DCHECK(expected_loop_ == MessageLoop::current());
50 { 53 {
51 base::AutoLock lock(abort_association_pending_lock_); 54 base::AutoLock lock(abort_association_pending_lock_);
52 abort_association_pending_ = false; 55 abort_association_pending_ = false;
53 } 56 }
54 57
55 // We must not be holding a transaction when we interact with the password 58 // We must not be holding a transaction when we interact with the password
56 // store, as it can post tasks to the UI thread which can itself be blocked 59 // store, as it can post tasks to the UI thread which can itself be blocked
57 // on our transaction, resulting in deadlock. (http://crbug.com/70658) 60 // on our transaction, resulting in deadlock. (http://crbug.com/70658)
58 std::vector<webkit::forms::PasswordForm*> passwords; 61 std::vector<webkit::forms::PasswordForm*> passwords;
59 if (!password_store_->FillAutofillableLogins(&passwords) || 62 if (!password_store_->FillAutofillableLogins(&passwords) ||
60 !password_store_->FillBlacklistLogins(&passwords)) { 63 !password_store_->FillBlacklistLogins(&passwords)) {
61 STLDeleteElements(&passwords); 64 STLDeleteElements(&passwords);
62 error->Reset(FROM_HERE, 65 return error_handler_->CreateAndUploadError(
63 "Could not get the password entries.", 66 FROM_HERE,
64 model_type()); 67 "Could not get the password entries.",
65 return false; 68 model_type());
66 } 69 }
67 70
68 std::set<std::string> current_passwords; 71 std::set<std::string> current_passwords;
69 PasswordVector new_passwords; 72 PasswordVector new_passwords;
70 PasswordVector updated_passwords; 73 PasswordVector updated_passwords;
71 { 74 {
72 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 75 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
73 sync_api::ReadNode password_root(&trans); 76 sync_api::ReadNode password_root(&trans);
74 if (!password_root.InitByTagLookup(kPasswordTag)) { 77 if (!password_root.InitByTagLookup(kPasswordTag)) {
75 error->Reset(FROM_HERE, 78 return error_handler_->CreateAndUploadError(
76 "Server did not create the top-level password node. We " 79 FROM_HERE,
77 "might be running against an out-of-date server.", 80 "Server did not create the top-level password node. We "
78 model_type()); 81 "might be running against an out-of-date server.",
79 return false; 82 model_type());
80 } 83 }
81 84
82 for (std::vector<webkit::forms::PasswordForm*>::iterator ix = 85 for (std::vector<webkit::forms::PasswordForm*>::iterator ix =
83 passwords.begin(); 86 passwords.begin();
84 ix != passwords.end(); ++ix) { 87 ix != passwords.end(); ++ix) {
85 if (IsAbortPending()) { 88 if (IsAbortPending()) {
86 error->Reset(FROM_HERE, "Abort pending", model_type()); 89 return SyncError();
87 return false;
88 } 90 }
89 std::string tag = MakeTag(**ix); 91 std::string tag = MakeTag(**ix);
90 92
91 sync_api::ReadNode node(&trans); 93 sync_api::ReadNode node(&trans);
92 if (node.InitByClientTagLookup(syncable::PASSWORDS, tag)) { 94 if (node.InitByClientTagLookup(syncable::PASSWORDS, tag)) {
93 const sync_pb::PasswordSpecificsData& password = 95 const sync_pb::PasswordSpecificsData& password =
94 node.GetPasswordSpecifics(); 96 node.GetPasswordSpecifics();
95 DCHECK_EQ(tag, MakeTag(password)); 97 DCHECK_EQ(tag, MakeTag(password));
96 98
97 webkit::forms::PasswordForm new_password; 99 webkit::forms::PasswordForm new_password;
98 100
99 if (MergePasswords(password, **ix, &new_password)) { 101 if (MergePasswords(password, **ix, &new_password)) {
100 sync_api::WriteNode write_node(&trans); 102 sync_api::WriteNode write_node(&trans);
101 if (!write_node.InitByClientTagLookup(syncable::PASSWORDS, tag)) { 103 if (!write_node.InitByClientTagLookup(syncable::PASSWORDS, tag)) {
102 STLDeleteElements(&passwords); 104 STLDeleteElements(&passwords);
103 error->Reset(FROM_HERE, 105 return error_handler_->CreateAndUploadError(
104 "Failed to edit password sync node.", 106 FROM_HERE,
105 model_type()); 107 "Failed to edit password sync node.",
106 return false; 108 model_type());
107 } 109 }
108 WriteToSyncNode(new_password, &write_node); 110 WriteToSyncNode(new_password, &write_node);
109 updated_passwords.push_back(new_password); 111 updated_passwords.push_back(new_password);
110 } 112 }
111 113
112 Associate(&tag, node.GetId()); 114 Associate(&tag, node.GetId());
113 } else { 115 } else {
114 sync_api::WriteNode node(&trans); 116 sync_api::WriteNode node(&trans);
115 if (!node.InitUniqueByCreation(syncable::PASSWORDS, 117 if (!node.InitUniqueByCreation(syncable::PASSWORDS,
116 password_root, tag)) { 118 password_root, tag)) {
117 STLDeleteElements(&passwords); 119 STLDeleteElements(&passwords);
118 error->Reset(FROM_HERE, 120 return error_handler_->CreateAndUploadError(
119 "Failed to create password sync node.", 121 FROM_HERE,
120 model_type()); 122 "Failed to create password sync node.",
121 return false; 123 model_type());
122 } 124 }
123 125
124 WriteToSyncNode(**ix, &node); 126 WriteToSyncNode(**ix, &node);
125 127
126 Associate(&tag, node.GetId()); 128 Associate(&tag, node.GetId());
127 } 129 }
128 130
129 current_passwords.insert(tag); 131 current_passwords.insert(tag);
130 } 132 }
131 133
132 STLDeleteElements(&passwords); 134 STLDeleteElements(&passwords);
133 135
134 int64 sync_child_id = password_root.GetFirstChildId(); 136 int64 sync_child_id = password_root.GetFirstChildId();
135 while (sync_child_id != sync_api::kInvalidId) { 137 while (sync_child_id != sync_api::kInvalidId) {
136 sync_api::ReadNode sync_child_node(&trans); 138 sync_api::ReadNode sync_child_node(&trans);
137 if (!sync_child_node.InitByIdLookup(sync_child_id)) { 139 if (!sync_child_node.InitByIdLookup(sync_child_id)) {
138 error->Reset(FROM_HERE, "Failed to fetch child node.", model_type()); 140 return error_handler_->CreateAndUploadError(
139 return false; 141 FROM_HERE,
142 "Failed to fetch child node.",
143 model_type());
140 } 144 }
141 const sync_pb::PasswordSpecificsData& password = 145 const sync_pb::PasswordSpecificsData& password =
142 sync_child_node.GetPasswordSpecifics(); 146 sync_child_node.GetPasswordSpecifics();
143 std::string tag = MakeTag(password); 147 std::string tag = MakeTag(password);
144 148
145 // The password only exists on the server. Add it to the local 149 // The password only exists on the server. Add it to the local
146 // model. 150 // model.
147 if (current_passwords.find(tag) == current_passwords.end()) { 151 if (current_passwords.find(tag) == current_passwords.end()) {
148 webkit::forms::PasswordForm new_password; 152 webkit::forms::PasswordForm new_password;
149 153
150 CopyPassword(password, &new_password); 154 CopyPassword(password, &new_password);
151 Associate(&tag, sync_child_node.GetId()); 155 Associate(&tag, sync_child_node.GetId());
152 new_passwords.push_back(new_password); 156 new_passwords.push_back(new_password);
153 } 157 }
154 158
155 sync_child_id = sync_child_node.GetSuccessorId(); 159 sync_child_id = sync_child_node.GetSuccessorId();
156 } 160 }
157 } 161 }
158 162
159 // We must not be holding a transaction when we interact with the password 163 // We must not be holding a transaction when we interact with the password
160 // store, as it can post tasks to the UI thread which can itself be blocked 164 // store, as it can post tasks to the UI thread which can itself be blocked
161 // on our transaction, resulting in deadlock. (http://crbug.com/70658) 165 // on our transaction, resulting in deadlock. (http://crbug.com/70658)
162 if (!WriteToPasswordStore(&new_passwords, &updated_passwords, NULL)) { 166 error = WriteToPasswordStore(&new_passwords,
163 error->Reset(FROM_HERE, "Failed to write passwords.", model_type()); 167 &updated_passwords,
164 return false; 168 NULL);
169 if (error.IsSet()) {
170 return error;
165 } 171 }
166 172
167 return true; 173 return error;
168 } 174 }
169 175
170 bool PasswordModelAssociator::DeleteAllNodes( 176 bool PasswordModelAssociator::DeleteAllNodes(
171 sync_api::WriteTransaction* trans) { 177 sync_api::WriteTransaction* trans) {
172 DCHECK(expected_loop_ == MessageLoop::current()); 178 DCHECK(expected_loop_ == MessageLoop::current());
173 for (PasswordToSyncIdMap::iterator node_id = id_map_.begin(); 179 for (PasswordToSyncIdMap::iterator node_id = id_map_.begin();
174 node_id != id_map_.end(); ++node_id) { 180 node_id != id_map_.end(); ++node_id) {
175 sync_api::WriteNode sync_node(trans); 181 sync_api::WriteNode sync_node(trans);
176 if (!sync_node.InitByIdLookup(node_id->second)) { 182 if (!sync_node.InitByIdLookup(node_id->second)) {
177 LOG(ERROR) << "Typed url node lookup failed."; 183 LOG(ERROR) << "Typed url node lookup failed.";
178 return false; 184 return false;
179 } 185 }
180 sync_node.Remove(); 186 sync_node.Remove();
181 } 187 }
182 188
183 id_map_.clear(); 189 id_map_.clear();
184 id_map_inverse_.clear(); 190 id_map_inverse_.clear();
185 return true; 191 return true;
186 } 192 }
187 193
188 bool PasswordModelAssociator::DisassociateModels(SyncError* error) { 194 SyncError PasswordModelAssociator::DisassociateModels() {
189 id_map_.clear(); 195 id_map_.clear();
190 id_map_inverse_.clear(); 196 id_map_inverse_.clear();
191 return true; 197 return SyncError();
192 } 198 }
193 199
194 bool PasswordModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) { 200 bool PasswordModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) {
195 DCHECK(has_nodes); 201 DCHECK(has_nodes);
196 *has_nodes = false; 202 *has_nodes = false;
197 int64 password_sync_id; 203 int64 password_sync_id;
198 if (!GetSyncIdForTaggedNode(kPasswordTag, &password_sync_id)) { 204 if (!GetSyncIdForTaggedNode(kPasswordTag, &password_sync_id)) {
199 LOG(ERROR) << "Server did not create the top-level password node. We " 205 LOG(ERROR) << "Server did not create the top-level password node. We "
200 << "might be running against an out-of-date server."; 206 << "might be running against an out-of-date server.";
201 return false; 207 return false;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 bool PasswordModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, 278 bool PasswordModelAssociator::GetSyncIdForTaggedNode(const std::string& tag,
273 int64* sync_id) { 279 int64* sync_id) {
274 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 280 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
275 sync_api::ReadNode sync_node(&trans); 281 sync_api::ReadNode sync_node(&trans);
276 if (!sync_node.InitByTagLookup(tag.c_str())) 282 if (!sync_node.InitByTagLookup(tag.c_str()))
277 return false; 283 return false;
278 *sync_id = sync_node.GetId(); 284 *sync_id = sync_node.GetId();
279 return true; 285 return true;
280 } 286 }
281 287
282 bool PasswordModelAssociator::WriteToPasswordStore( 288 SyncError PasswordModelAssociator::WriteToPasswordStore(
283 const PasswordVector* new_passwords, 289 const PasswordVector* new_passwords,
284 const PasswordVector* updated_passwords, 290 const PasswordVector* updated_passwords,
285 const PasswordVector* deleted_passwords) { 291 const PasswordVector* deleted_passwords) {
286 if (new_passwords) { 292 if (new_passwords) {
287 for (PasswordVector::const_iterator password = new_passwords->begin(); 293 for (PasswordVector::const_iterator password = new_passwords->begin();
288 password != new_passwords->end(); ++password) { 294 password != new_passwords->end(); ++password) {
289 password_store_->AddLoginImpl(*password); 295 password_store_->AddLoginImpl(*password);
290 } 296 }
291 } 297 }
292 298
293 if (updated_passwords) { 299 if (updated_passwords) {
294 for (PasswordVector::const_iterator password = updated_passwords->begin(); 300 for (PasswordVector::const_iterator password = updated_passwords->begin();
295 password != updated_passwords->end(); ++password) { 301 password != updated_passwords->end(); ++password) {
296 password_store_->UpdateLoginImpl(*password); 302 password_store_->UpdateLoginImpl(*password);
297 } 303 }
298 } 304 }
299 305
300 if (deleted_passwords) { 306 if (deleted_passwords) {
301 for (PasswordVector::const_iterator password = deleted_passwords->begin(); 307 for (PasswordVector::const_iterator password = deleted_passwords->begin();
302 password != deleted_passwords->end(); ++password) { 308 password != deleted_passwords->end(); ++password) {
303 password_store_->RemoveLoginImpl(*password); 309 password_store_->RemoveLoginImpl(*password);
304 } 310 }
305 } 311 }
306 312
307 if (new_passwords || updated_passwords || deleted_passwords) { 313 if (new_passwords || updated_passwords || deleted_passwords) {
308 // We have to notify password store observers of the change by hand since 314 // We have to notify password store observers of the change by hand since
309 // we use internal password store interfaces to make changes synchronously. 315 // we use internal password store interfaces to make changes synchronously.
310 password_store_->PostNotifyLoginsChanged(); 316 password_store_->PostNotifyLoginsChanged();
311 } 317 }
312 return true; 318 return SyncError();
313 } 319 }
314 320
315 // static 321 // static
316 void PasswordModelAssociator::CopyPassword( 322 void PasswordModelAssociator::CopyPassword(
317 const sync_pb::PasswordSpecificsData& password, 323 const sync_pb::PasswordSpecificsData& password,
318 webkit::forms::PasswordForm* new_password) { 324 webkit::forms::PasswordForm* new_password) {
319 new_password->scheme = 325 new_password->scheme =
320 static_cast<webkit::forms::PasswordForm::Scheme>(password.scheme()); 326 static_cast<webkit::forms::PasswordForm::Scheme>(password.scheme());
321 new_password->signon_realm = password.signon_realm(); 327 new_password->signon_realm = password.signon_realm();
322 new_password->origin = GURL(password.origin()); 328 new_password->origin = GURL(password.origin());
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 const std::string& password_element, 429 const std::string& password_element,
424 const std::string& signon_realm) { 430 const std::string& signon_realm) {
425 return net::EscapePath(origin_url) + "|" + 431 return net::EscapePath(origin_url) + "|" +
426 net::EscapePath(username_element) + "|" + 432 net::EscapePath(username_element) + "|" +
427 net::EscapePath(username_value) + "|" + 433 net::EscapePath(username_value) + "|" +
428 net::EscapePath(password_element) + "|" + 434 net::EscapePath(password_element) + "|" +
429 net::EscapePath(signon_realm); 435 net::EscapePath(signon_realm);
430 } 436 }
431 437
432 } // namespace browser_sync 438 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698