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

Side by Side Diff: components/password_manager/core/browser/password_store.cc

Issue 866983003: GetLoginsRequest: Use ScopedVector to express ownership of forms (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@324291_scopedvector
Patch Set: Fix Mac unittest Created 5 years, 10 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/password_manager/core/browser/password_store.h" 5 #include "components/password_manager/core/browser/password_store.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/dump_without_crashing.h" 8 #include "base/debug/dump_without_crashing.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 10 matching lines...) Expand all
21 21
22 using autofill::PasswordForm; 22 using autofill::PasswordForm;
23 23
24 namespace password_manager { 24 namespace password_manager {
25 25
26 namespace { 26 namespace {
27 27
28 // Calls |consumer| back with the request result, if |consumer| is still alive. 28 // Calls |consumer| back with the request result, if |consumer| is still alive.
29 // Takes ownership of the elements in |result|, passing ownership to |consumer| 29 // Takes ownership of the elements in |result|, passing ownership to |consumer|
30 // if it is still alive. 30 // if it is still alive.
31 void MaybeCallConsumerCallback(base::WeakPtr<PasswordStoreConsumer> consumer, 31 void MaybeCallConsumerCallback(base::WeakPtr<PasswordStoreConsumer> consumer,
vasilii 2015/02/05 19:23:27 Shouldn't Bind be smart enough to do what you are
vabr (Chromium) 2015/02/06 14:16:05 Good call. WeakPtr should indeed just safely give
32 scoped_ptr<std::vector<PasswordForm*>> result) { 32 ScopedVector<autofill::PasswordForm> result) {
33 if (consumer.get()) 33 if (consumer)
34 consumer->OnGetPasswordStoreResults(*result); 34 consumer->OnGetPasswordStoreResults(result.Pass());
35 else
36 STLDeleteElements(result.get());
37 } 35 }
38 36
39 // http://crbug.com/404012. Let's see where the empty fields come from. 37 // http://crbug.com/404012. Let's see where the empty fields come from.
40 void CheckForEmptyUsernameAndPassword(const PasswordForm& form) { 38 void CheckForEmptyUsernameAndPassword(const PasswordForm& form) {
41 if (form.username_value.empty() && 39 if (form.username_value.empty() &&
42 form.password_value.empty() && 40 form.password_value.empty() &&
43 !form.blacklisted_by_user) 41 !form.blacklisted_by_user)
44 base::debug::DumpWithoutCrashing(); 42 base::debug::DumpWithoutCrashing();
45 } 43 }
46 44
47 } // namespace 45 } // namespace
48 46
49 PasswordStore::GetLoginsRequest::GetLoginsRequest( 47 PasswordStore::GetLoginsRequest::GetLoginsRequest(
50 PasswordStoreConsumer* consumer) 48 PasswordStoreConsumer* consumer)
51 : consumer_weak_(consumer->GetWeakPtr()), 49 : consumer_weak_(consumer->GetWeakPtr()) {
52 result_(new std::vector<PasswordForm*>()) { 50 // TODO(vabr): As long as |thread_checker_| gets constructed without failures,
51 // this DCHECK is always trivially true. It looks like we could get rid of the
52 // |thread_checker_| unless it was meant to make sure that threads are
53 // actually present in relevant tests. But in that case, we should do better
54 // than to hog production code because of tests.
53 DCHECK(thread_checker_.CalledOnValidThread()); 55 DCHECK(thread_checker_.CalledOnValidThread());
vasilii 2015/02/05 19:23:27 After discussing I still think that |thread_checke
vabr (Chromium) 2015/02/06 14:16:05 Done.
54 origin_loop_ = base::MessageLoopProxy::current(); 56 origin_loop_ = base::MessageLoopProxy::current();
55 } 57 }
56 58
57 PasswordStore::GetLoginsRequest::~GetLoginsRequest() { 59 PasswordStore::GetLoginsRequest::~GetLoginsRequest() {
58 } 60 }
59 61
60 void PasswordStore::GetLoginsRequest::ApplyIgnoreLoginsCutoff() { 62 void PasswordStore::GetLoginsRequest::ApplyIgnoreLoginsCutoff() {
61 if (!ignore_logins_cutoff_.is_null()) { 63 if (!ignore_logins_cutoff_.is_null()) {
62 // Count down rather than up since we may be deleting elements. 64 ScopedVector<autofill::PasswordForm> remaining_logins;
63 // Note that in principle it could be more efficient to copy the whole array 65 remaining_logins.reserve(result_.size());
64 // since that's worst-case linear time, but we expect that elements will be 66 for (auto& login : result_) {
65 // deleted rarely and lists will be small, so this avoids the copies. 67 if (login->date_created >= ignore_logins_cutoff_) {
66 for (size_t i = result_->size(); i > 0; --i) { 68 remaining_logins.push_back(login);
67 if ((*result_)[i - 1]->date_created < ignore_logins_cutoff_) { 69 login = nullptr;
68 delete (*result_)[i - 1];
69 result_->erase(result_->begin() + (i - 1));
70 } 70 }
71 } 71 }
72 remaining_logins.swap(result_);
72 } 73 }
73 } 74 }
74 75
75 void PasswordStore::GetLoginsRequest::ForwardResult() { 76 void PasswordStore::GetLoginsRequest::ForwardResult() {
76 origin_loop_->PostTask(FROM_HERE, 77 origin_loop_->PostTask(FROM_HERE,
77 base::Bind(&MaybeCallConsumerCallback, 78 base::Bind(&MaybeCallConsumerCallback, consumer_weak_,
78 consumer_weak_, 79 base::Passed(&result_)));
79 base::Passed(result_.Pass())));
80 } 80 }
81 81
82 PasswordStore::PasswordStore( 82 PasswordStore::PasswordStore(
83 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, 83 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
84 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner) 84 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner)
85 : main_thread_runner_(main_thread_runner), 85 : main_thread_runner_(main_thread_runner),
86 db_thread_runner_(db_thread_runner), 86 db_thread_runner_(db_thread_runner),
87 observers_(new ObserverListThreadSafe<Observer>()), 87 observers_(new ObserverListThreadSafe<Observer>()),
88 shutdown_called_(false) { 88 shutdown_called_(false) {
89 } 89 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 base::Time ignore_logins_cutoff; // the null time 134 base::Time ignore_logins_cutoff; // the null time
135 if (form.scheme == PasswordForm::SCHEME_HTML && 135 if (form.scheme == PasswordForm::SCHEME_HTML &&
136 (form.signon_realm == "http://www.google.com" || 136 (form.signon_realm == "http://www.google.com" ||
137 form.signon_realm == "http://www.google.com/" || 137 form.signon_realm == "http://www.google.com/" ||
138 form.signon_realm == "https://www.google.com" || 138 form.signon_realm == "https://www.google.com" ||
139 form.signon_realm == "https://www.google.com/")) { 139 form.signon_realm == "https://www.google.com/")) {
140 static const base::Time::Exploded exploded_cutoff = 140 static const base::Time::Exploded exploded_cutoff =
141 { 2012, 1, 0, 1, 0, 0, 0, 0 }; // 00:00 Jan 1 2012 141 { 2012, 1, 0, 1, 0, 0, 0, 0 }; // 00:00 Jan 1 2012
142 ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff); 142 ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff);
143 } 143 }
144 GetLoginsRequest* request = new GetLoginsRequest(consumer); 144 scoped_ptr<GetLoginsRequest> request(new GetLoginsRequest(consumer));
145 request->set_ignore_logins_cutoff(ignore_logins_cutoff); 145 request->set_ignore_logins_cutoff(ignore_logins_cutoff);
146 146
147 ConsumerCallbackRunner callback_runner = base::Bind( 147 ConsumerCallbackRunner callback_runner =
148 &PasswordStore::CopyAndForwardLoginsResult, base::Owned(request)); 148 base::Bind(&CopyAndForwardLoginsResult, base::Passed(&request));
149 ScheduleTask(base::Bind(&PasswordStore::GetLoginsImpl, this, form, 149 ScheduleTask(base::Bind(&PasswordStore::GetLoginsImpl, this, form,
150 prompt_policy, callback_runner)); 150 prompt_policy, callback_runner));
151 } 151 }
152 152
153 void PasswordStore::GetAutofillableLogins(PasswordStoreConsumer* consumer) { 153 void PasswordStore::GetAutofillableLogins(PasswordStoreConsumer* consumer) {
154 Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); 154 Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer);
155 } 155 }
156 156
157 void PasswordStore::GetBlacklistLogins(PasswordStoreConsumer* consumer) { 157 void PasswordStore::GetBlacklistLogins(PasswordStoreConsumer* consumer) {
158 Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); 158 Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 PasswordStore::~PasswordStore() { 206 PasswordStore::~PasswordStore() {
207 DCHECK(shutdown_called_); 207 DCHECK(shutdown_called_);
208 } 208 }
209 209
210 scoped_refptr<base::SingleThreadTaskRunner> 210 scoped_refptr<base::SingleThreadTaskRunner>
211 PasswordStore::GetBackgroundTaskRunner() { 211 PasswordStore::GetBackgroundTaskRunner() {
212 return db_thread_runner_; 212 return db_thread_runner_;
213 } 213 }
214 214
215 // static 215 // static
216 void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) { 216 void PasswordStore::ForwardLoginsResult(scoped_ptr<GetLoginsRequest> request) {
217 request->ApplyIgnoreLoginsCutoff(); 217 request->ApplyIgnoreLoginsCutoff();
218 request->ForwardResult(); 218 request->ForwardResult();
219 } 219 }
220 220
221 // static 221 // static
222 void PasswordStore::CopyAndForwardLoginsResult( 222 void PasswordStore::CopyAndForwardLoginsResult(
223 PasswordStore::GetLoginsRequest* request, 223 scoped_ptr<PasswordStore::GetLoginsRequest> request,
224 ScopedVector<autofill::PasswordForm> matched_forms) { 224 ScopedVector<autofill::PasswordForm> matched_forms) {
225 // Move the contents of |matched_forms| into the request. 225 DCHECK(request->result()->empty());
226 request->result()->swap(matched_forms.get()); 226 request->result()->swap(matched_forms);
227 ForwardLoginsResult(request); 227 ForwardLoginsResult(request.Pass());
228 } 228 }
229 229
230 void PasswordStore::LogStatsForBulkDeletion(int num_deletions) { 230 void PasswordStore::LogStatsForBulkDeletion(int num_deletions) {
231 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedByBulkDelete", 231 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedByBulkDelete",
232 num_deletions); 232 num_deletions);
233 } 233 }
234 234
235 void PasswordStore::LogStatsForBulkDeletionDuringRollback(int num_deletions) { 235 void PasswordStore::LogStatsForBulkDeletionDuringRollback(int num_deletions) {
236 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedDuringRollback", 236 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedDuringRollback",
237 num_deletions); 237 num_deletions);
238 } 238 }
239 239
240 void PasswordStore::NotifyLoginsChanged( 240 void PasswordStore::NotifyLoginsChanged(
241 const PasswordStoreChangeList& changes) { 241 const PasswordStoreChangeList& changes) {
242 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); 242 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
243 if (!changes.empty()) { 243 if (!changes.empty()) {
244 observers_->Notify(&Observer::OnLoginsChanged, changes); 244 observers_->Notify(&Observer::OnLoginsChanged, changes);
245 #if defined(PASSWORD_MANAGER_ENABLE_SYNC) 245 #if defined(PASSWORD_MANAGER_ENABLE_SYNC)
246 if (syncable_service_) 246 if (syncable_service_)
247 syncable_service_->ActOnPasswordStoreChanges(changes); 247 syncable_service_->ActOnPasswordStoreChanges(changes);
248 #endif 248 #endif
249 } 249 }
250 } 250 }
251 251
252 template <typename BackendFunc> 252 void PasswordStore::Schedule(
253 void PasswordStore::Schedule(BackendFunc func, 253 void (PasswordStore::*func)(scoped_ptr<GetLoginsRequest>),
254 PasswordStoreConsumer* consumer) { 254 PasswordStoreConsumer* consumer) {
255 GetLoginsRequest* request = new GetLoginsRequest(consumer); 255 scoped_ptr<GetLoginsRequest> request(new GetLoginsRequest(consumer));
256 consumer->cancelable_task_tracker()->PostTask( 256 consumer->cancelable_task_tracker()->PostTask(
257 GetBackgroundTaskRunner().get(), 257 GetBackgroundTaskRunner().get(), FROM_HERE,
258 FROM_HERE, 258 base::Bind(func, this, base::Passed(&request)));
259 base::Bind(func, this, base::Owned(request)));
260 } 259 }
261 260
262 void PasswordStore::WrapModificationTask(ModificationTask task) { 261 void PasswordStore::WrapModificationTask(ModificationTask task) {
263 PasswordStoreChangeList changes = task.Run(); 262 PasswordStoreChangeList changes = task.Run();
264 NotifyLoginsChanged(changes); 263 NotifyLoginsChanged(changes);
265 } 264 }
266 265
267 void PasswordStore::AddLoginInternal(const PasswordForm& form) { 266 void PasswordStore::AddLoginInternal(const PasswordForm& form) {
268 PasswordStoreChangeList changes = AddLoginImpl(form); 267 PasswordStoreChangeList changes = AddLoginImpl(form);
269 NotifyLoginsChanged(changes); 268 NotifyLoginsChanged(changes);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 syncable_service_->InjectStartSyncFlare(flare); 301 syncable_service_->InjectStartSyncFlare(flare);
303 } 302 }
304 303
305 void PasswordStore::DestroySyncableService() { 304 void PasswordStore::DestroySyncableService() {
306 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); 305 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
307 syncable_service_.reset(); 306 syncable_service_.reset();
308 } 307 }
309 #endif 308 #endif
310 309
311 } // namespace password_manager 310 } // namespace password_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698