OLD | NEW |
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" | |
10 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
11 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
12 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
13 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
14 #include "components/autofill/core/common/password_form.h" | 13 #include "components/autofill/core/common/password_form.h" |
15 #include "components/password_manager/core/browser/password_store_consumer.h" | 14 #include "components/password_manager/core/browser/password_store_consumer.h" |
16 #include "components/password_manager/core/browser/password_syncable_service.h" | 15 #include "components/password_manager/core/browser/password_syncable_service.h" |
17 | 16 |
18 #if defined(PASSWORD_MANAGER_ENABLE_SYNC) | 17 #if defined(PASSWORD_MANAGER_ENABLE_SYNC) |
19 #include "components/password_manager/core/browser/password_syncable_service.h" | 18 #include "components/password_manager/core/browser/password_syncable_service.h" |
20 #endif | 19 #endif |
21 | 20 |
22 using autofill::PasswordForm; | 21 using autofill::PasswordForm; |
23 | 22 |
24 namespace password_manager { | 23 namespace password_manager { |
25 | 24 |
26 namespace { | 25 namespace { |
27 | 26 |
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| | |
30 // if it is still alive. | |
31 void MaybeCallConsumerCallback(base::WeakPtr<PasswordStoreConsumer> consumer, | |
32 scoped_ptr<std::vector<PasswordForm*>> result) { | |
33 if (consumer.get()) | |
34 consumer->OnGetPasswordStoreResults(*result); | |
35 else | |
36 STLDeleteElements(result.get()); | |
37 } | |
38 | |
39 // http://crbug.com/404012. Let's see where the empty fields come from. | 27 // http://crbug.com/404012. Let's see where the empty fields come from. |
40 void CheckForEmptyUsernameAndPassword(const PasswordForm& form) { | 28 void CheckForEmptyUsernameAndPassword(const PasswordForm& form) { |
41 if (form.username_value.empty() && | 29 if (form.username_value.empty() && |
42 form.password_value.empty() && | 30 form.password_value.empty() && |
43 !form.blacklisted_by_user) | 31 !form.blacklisted_by_user) |
44 base::debug::DumpWithoutCrashing(); | 32 base::debug::DumpWithoutCrashing(); |
45 } | 33 } |
46 | 34 |
47 } // namespace | 35 } // namespace |
48 | 36 |
49 PasswordStore::GetLoginsRequest::GetLoginsRequest( | 37 PasswordStore::GetLoginsRequest::GetLoginsRequest( |
50 PasswordStoreConsumer* consumer) | 38 PasswordStoreConsumer* consumer) |
51 : consumer_weak_(consumer->GetWeakPtr()), | 39 : consumer_weak_(consumer->GetWeakPtr()) { |
52 result_(new std::vector<PasswordForm*>()) { | |
53 DCHECK(thread_checker_.CalledOnValidThread()); | |
54 origin_loop_ = base::MessageLoopProxy::current(); | 40 origin_loop_ = base::MessageLoopProxy::current(); |
55 } | 41 } |
56 | 42 |
57 PasswordStore::GetLoginsRequest::~GetLoginsRequest() { | 43 PasswordStore::GetLoginsRequest::~GetLoginsRequest() { |
58 } | 44 } |
59 | 45 |
60 void PasswordStore::GetLoginsRequest::ApplyIgnoreLoginsCutoff() { | 46 void PasswordStore::GetLoginsRequest::ApplyIgnoreLoginsCutoff() { |
61 if (!ignore_logins_cutoff_.is_null()) { | 47 if (!ignore_logins_cutoff_.is_null()) { |
62 // Count down rather than up since we may be deleting elements. | 48 ScopedVector<autofill::PasswordForm> remaining_logins; |
63 // Note that in principle it could be more efficient to copy the whole array | 49 remaining_logins.reserve(result_.size()); |
64 // since that's worst-case linear time, but we expect that elements will be | 50 for (auto& login : result_) { |
65 // deleted rarely and lists will be small, so this avoids the copies. | 51 if (login->date_created >= ignore_logins_cutoff_) { |
66 for (size_t i = result_->size(); i > 0; --i) { | 52 remaining_logins.push_back(login); |
67 if ((*result_)[i - 1]->date_created < ignore_logins_cutoff_) { | 53 login = nullptr; |
68 delete (*result_)[i - 1]; | |
69 result_->erase(result_->begin() + (i - 1)); | |
70 } | 54 } |
71 } | 55 } |
| 56 remaining_logins.swap(result_); |
72 } | 57 } |
73 } | 58 } |
74 | 59 |
75 void PasswordStore::GetLoginsRequest::ForwardResult() { | 60 void PasswordStore::GetLoginsRequest::ForwardResult() { |
76 origin_loop_->PostTask(FROM_HERE, | 61 origin_loop_->PostTask( |
77 base::Bind(&MaybeCallConsumerCallback, | 62 FROM_HERE, base::Bind(&PasswordStoreConsumer::OnGetPasswordStoreResults, |
78 consumer_weak_, | 63 consumer_weak_, base::Passed(&result_))); |
79 base::Passed(result_.Pass()))); | |
80 } | 64 } |
81 | 65 |
82 PasswordStore::PasswordStore( | 66 PasswordStore::PasswordStore( |
83 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, | 67 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, |
84 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner) | 68 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner) |
85 : main_thread_runner_(main_thread_runner), | 69 : main_thread_runner_(main_thread_runner), |
86 db_thread_runner_(db_thread_runner), | 70 db_thread_runner_(db_thread_runner), |
87 observers_(new ObserverListThreadSafe<Observer>()), | 71 observers_(new ObserverListThreadSafe<Observer>()), |
88 shutdown_called_(false) { | 72 shutdown_called_(false) { |
89 } | 73 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 base::Time ignore_logins_cutoff; // the null time | 118 base::Time ignore_logins_cutoff; // the null time |
135 if (form.scheme == PasswordForm::SCHEME_HTML && | 119 if (form.scheme == PasswordForm::SCHEME_HTML && |
136 (form.signon_realm == "http://www.google.com" || | 120 (form.signon_realm == "http://www.google.com" || |
137 form.signon_realm == "http://www.google.com/" || | 121 form.signon_realm == "http://www.google.com/" || |
138 form.signon_realm == "https://www.google.com" || | 122 form.signon_realm == "https://www.google.com" || |
139 form.signon_realm == "https://www.google.com/")) { | 123 form.signon_realm == "https://www.google.com/")) { |
140 static const base::Time::Exploded exploded_cutoff = | 124 static const base::Time::Exploded exploded_cutoff = |
141 { 2012, 1, 0, 1, 0, 0, 0, 0 }; // 00:00 Jan 1 2012 | 125 { 2012, 1, 0, 1, 0, 0, 0, 0 }; // 00:00 Jan 1 2012 |
142 ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff); | 126 ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff); |
143 } | 127 } |
144 GetLoginsRequest* request = new GetLoginsRequest(consumer); | 128 scoped_ptr<GetLoginsRequest> request(new GetLoginsRequest(consumer)); |
145 request->set_ignore_logins_cutoff(ignore_logins_cutoff); | 129 request->set_ignore_logins_cutoff(ignore_logins_cutoff); |
146 | 130 |
147 ConsumerCallbackRunner callback_runner = base::Bind( | 131 ConsumerCallbackRunner callback_runner = |
148 &PasswordStore::CopyAndForwardLoginsResult, base::Owned(request)); | 132 base::Bind(&MoveAndForwardLoginsResult, base::Passed(&request)); |
149 ScheduleTask(base::Bind(&PasswordStore::GetLoginsImpl, this, form, | 133 ScheduleTask(base::Bind(&PasswordStore::GetLoginsImpl, this, form, |
150 prompt_policy, callback_runner)); | 134 prompt_policy, callback_runner)); |
151 } | 135 } |
152 | 136 |
153 void PasswordStore::GetAutofillableLogins(PasswordStoreConsumer* consumer) { | 137 void PasswordStore::GetAutofillableLogins(PasswordStoreConsumer* consumer) { |
154 Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); | 138 Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); |
155 } | 139 } |
156 | 140 |
157 void PasswordStore::GetBlacklistLogins(PasswordStoreConsumer* consumer) { | 141 void PasswordStore::GetBlacklistLogins(PasswordStoreConsumer* consumer) { |
158 Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); | 142 Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 PasswordStore::~PasswordStore() { | 190 PasswordStore::~PasswordStore() { |
207 DCHECK(shutdown_called_); | 191 DCHECK(shutdown_called_); |
208 } | 192 } |
209 | 193 |
210 scoped_refptr<base::SingleThreadTaskRunner> | 194 scoped_refptr<base::SingleThreadTaskRunner> |
211 PasswordStore::GetBackgroundTaskRunner() { | 195 PasswordStore::GetBackgroundTaskRunner() { |
212 return db_thread_runner_; | 196 return db_thread_runner_; |
213 } | 197 } |
214 | 198 |
215 // static | 199 // static |
216 void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) { | 200 void PasswordStore::ForwardLoginsResult(scoped_ptr<GetLoginsRequest> request) { |
217 request->ApplyIgnoreLoginsCutoff(); | 201 request->ApplyIgnoreLoginsCutoff(); |
218 request->ForwardResult(); | 202 request->ForwardResult(); |
219 } | 203 } |
220 | 204 |
221 // static | 205 // static |
222 void PasswordStore::CopyAndForwardLoginsResult( | 206 void PasswordStore::MoveAndForwardLoginsResult( |
223 PasswordStore::GetLoginsRequest* request, | 207 scoped_ptr<PasswordStore::GetLoginsRequest> request, |
224 ScopedVector<autofill::PasswordForm> matched_forms) { | 208 ScopedVector<autofill::PasswordForm> matched_forms) { |
225 // Move the contents of |matched_forms| into the request. | 209 DCHECK(request->result()->empty()); |
226 request->result()->swap(matched_forms.get()); | 210 request->result()->swap(matched_forms); |
227 ForwardLoginsResult(request); | 211 ForwardLoginsResult(request.Pass()); |
228 } | 212 } |
229 | 213 |
230 void PasswordStore::LogStatsForBulkDeletion(int num_deletions) { | 214 void PasswordStore::LogStatsForBulkDeletion(int num_deletions) { |
231 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedByBulkDelete", | 215 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedByBulkDelete", |
232 num_deletions); | 216 num_deletions); |
233 } | 217 } |
234 | 218 |
235 void PasswordStore::LogStatsForBulkDeletionDuringRollback(int num_deletions) { | 219 void PasswordStore::LogStatsForBulkDeletionDuringRollback(int num_deletions) { |
236 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedDuringRollback", | 220 UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedDuringRollback", |
237 num_deletions); | 221 num_deletions); |
238 } | 222 } |
239 | 223 |
240 void PasswordStore::NotifyLoginsChanged( | 224 void PasswordStore::NotifyLoginsChanged( |
241 const PasswordStoreChangeList& changes) { | 225 const PasswordStoreChangeList& changes) { |
242 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 226 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
243 if (!changes.empty()) { | 227 if (!changes.empty()) { |
244 observers_->Notify(&Observer::OnLoginsChanged, changes); | 228 observers_->Notify(&Observer::OnLoginsChanged, changes); |
245 #if defined(PASSWORD_MANAGER_ENABLE_SYNC) | 229 #if defined(PASSWORD_MANAGER_ENABLE_SYNC) |
246 if (syncable_service_) | 230 if (syncable_service_) |
247 syncable_service_->ActOnPasswordStoreChanges(changes); | 231 syncable_service_->ActOnPasswordStoreChanges(changes); |
248 #endif | 232 #endif |
249 } | 233 } |
250 } | 234 } |
251 | 235 |
252 template <typename BackendFunc> | 236 void PasswordStore::Schedule( |
253 void PasswordStore::Schedule(BackendFunc func, | 237 void (PasswordStore::*func)(scoped_ptr<GetLoginsRequest>), |
254 PasswordStoreConsumer* consumer) { | 238 PasswordStoreConsumer* consumer) { |
255 GetLoginsRequest* request = new GetLoginsRequest(consumer); | 239 scoped_ptr<GetLoginsRequest> request(new GetLoginsRequest(consumer)); |
256 consumer->cancelable_task_tracker()->PostTask( | 240 consumer->cancelable_task_tracker()->PostTask( |
257 GetBackgroundTaskRunner().get(), | 241 GetBackgroundTaskRunner().get(), FROM_HERE, |
258 FROM_HERE, | 242 base::Bind(func, this, base::Passed(&request))); |
259 base::Bind(func, this, base::Owned(request))); | |
260 } | 243 } |
261 | 244 |
262 void PasswordStore::WrapModificationTask(ModificationTask task) { | 245 void PasswordStore::WrapModificationTask(ModificationTask task) { |
263 PasswordStoreChangeList changes = task.Run(); | 246 PasswordStoreChangeList changes = task.Run(); |
264 NotifyLoginsChanged(changes); | 247 NotifyLoginsChanged(changes); |
265 } | 248 } |
266 | 249 |
267 void PasswordStore::AddLoginInternal(const PasswordForm& form) { | 250 void PasswordStore::AddLoginInternal(const PasswordForm& form) { |
268 PasswordStoreChangeList changes = AddLoginImpl(form); | 251 PasswordStoreChangeList changes = AddLoginImpl(form); |
269 NotifyLoginsChanged(changes); | 252 NotifyLoginsChanged(changes); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 syncable_service_->InjectStartSyncFlare(flare); | 285 syncable_service_->InjectStartSyncFlare(flare); |
303 } | 286 } |
304 | 287 |
305 void PasswordStore::DestroySyncableService() { | 288 void PasswordStore::DestroySyncableService() { |
306 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); | 289 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); |
307 syncable_service_.reset(); | 290 syncable_service_.reset(); |
308 } | 291 } |
309 #endif | 292 #endif |
310 | 293 |
311 } // namespace password_manager | 294 } // namespace password_manager |
OLD | NEW |