Chromium Code Reviews| 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" | 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |