diff options
author | kaiwang@chromium.org <kaiwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-14 04:01:56 +0000 |
---|---|---|
committer | kaiwang@chromium.org <kaiwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-14 04:01:56 +0000 |
commit | cef1a75de87b9ccc381f3d5f8e6d56cc2d58bcbc (patch) | |
tree | c82191bc5fd01f06af77791d788447776a550bda /chrome | |
parent | 5ea6fdb73760fc1c7a7929dcb4d5f5dd89230610 (diff) | |
download | chromium_src-cef1a75de87b9ccc381f3d5f8e6d56cc2d58bcbc.zip chromium_src-cef1a75de87b9ccc381f3d5f8e6d56cc2d58bcbc.tar.gz chromium_src-cef1a75de87b9ccc381f3d5f8e6d56cc2d58bcbc.tar.bz2 |
Convert PasswordStore::GetLogins to not depend on CancelableRequest
Please note, in order to reduce the CL size, I only converted GetLogins. There will be another CL to convert GetAutofillableLogins and GetBlackListLogins. As a result, there's a bunch of old code I can not get rid of now.
e.g.
PasswordStore::GetLoginRequest
PasswordStore::Schedule
PasswordStoreConsumer::OnPasswordStoreRequestDone
etc
Will clean them up in next CL
BUG=155883,162337
Review URL: https://chromiumcodereview.appspot.com/11415106
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173076 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
26 files changed, 331 insertions, 209 deletions
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc index 954e75f..d726ef0 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -1580,6 +1580,13 @@ void AutomationProviderGetPasswordsObserver::OnPasswordStoreRequestDone( delete this; } +void AutomationProviderGetPasswordsObserver::OnGetPasswordStoreResults( + const std::vector<content::PasswordForm*>& results) { + // TODO(kaiwang): Implement when I refactor + // PasswordManager::GetAutofillableLogins. + NOTIMPLEMENTED(); +} + PasswordStoreLoginsChangedObserver::PasswordStoreLoginsChangedObserver( AutomationProvider* automation, IPC::Message* reply_message, diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h index 29f5d27..ce8d536 100644 --- a/chrome/browser/automation/automation_provider_observers.h +++ b/chrome/browser/automation/automation_provider_observers.h @@ -1159,9 +1159,12 @@ class AutomationProviderGetPasswordsObserver : public PasswordStoreConsumer { IPC::Message* reply_message); virtual ~AutomationProviderGetPasswordsObserver(); + // PasswordStoreConsumer implementation. virtual void OnPasswordStoreRequestDone( CancelableRequestProvider::Handle handle, const std::vector<content::PasswordForm*>& result) OVERRIDE; + virtual void OnGetPasswordStoreResults( + const std::vector<content::PasswordForm*>& results) OVERRIDE; private: base::WeakPtr<AutomationProvider> provider_; diff --git a/chrome/browser/password_manager/mock_password_store.h b/chrome/browser/password_manager/mock_password_store.h index e7f91b4..5bc7720 100644 --- a/chrome/browser/password_manager/mock_password_store.h +++ b/chrome/browser/password_manager/mock_password_store.h @@ -18,8 +18,9 @@ class MockPasswordStore : public PasswordStore { static scoped_refptr<RefcountedProfileKeyedService> Build(Profile* profile); MOCK_METHOD1(RemoveLogin, void(const content::PasswordForm&)); - MOCK_METHOD2(GetLogins, int(const content::PasswordForm&, - PasswordStoreConsumer*)); + MOCK_METHOD2(GetLogins, + CancelableTaskTracker::TaskId(const content::PasswordForm&, + PasswordStoreConsumer*)); MOCK_METHOD1(AddLogin, void(const content::PasswordForm&)); MOCK_METHOD1(UpdateLogin, void(const content::PasswordForm&)); MOCK_METHOD0(ReportMetrics, void()); @@ -29,8 +30,9 @@ class MockPasswordStore : public PasswordStore { MOCK_METHOD1(RemoveLoginImpl, void(const content::PasswordForm&)); MOCK_METHOD2(RemoveLoginsCreatedBetweenImpl, void(const base::Time&, const base::Time&)); - MOCK_METHOD2(GetLoginsImpl, void(GetLoginsRequest*, - const content::PasswordForm&)); + MOCK_METHOD2(GetLoginsImpl, + void(const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner)); MOCK_METHOD1(GetAutofillableLoginsImpl, void(GetLoginsRequest*)); MOCK_METHOD1(GetBlacklistLoginsImpl, void(GetLoginsRequest*)); MOCK_METHOD1(FillAutofillableLogins, diff --git a/chrome/browser/password_manager/password_form_manager.cc b/chrome/browser/password_manager/password_form_manager.cc index 6aacd0c..4f1b910 100644 --- a/chrome/browser/password_manager/password_form_manager.cc +++ b/chrome/browser/password_manager/password_form_manager.cc @@ -32,7 +32,6 @@ PasswordFormManager::PasswordFormManager(Profile* profile, is_new_login_(true), has_generated_password_(false), password_manager_(password_manager), - pending_login_query_(0), preferred_match_(NULL), state_(PRE_MATCHING_PHASE), profile_(profile), @@ -225,7 +224,6 @@ void PasswordFormManager::Save() { void PasswordFormManager::FetchMatchingLoginsFromPasswordStore() { DCHECK_EQ(state_, PRE_MATCHING_PHASE); - DCHECK(!pending_login_query_); state_ = MATCHING_PHASE; PasswordStore* password_store = PasswordStoreFactory::GetForProfile( profile_, Profile::EXPLICIT_ACCESS); @@ -233,14 +231,14 @@ void PasswordFormManager::FetchMatchingLoginsFromPasswordStore() { NOTREACHED(); return; } - pending_login_query_ = password_store->GetLogins(observed_form_, this); + password_store->GetLogins(observed_form_, this); } bool PasswordFormManager::HasCompletedMatching() { return state_ == POST_MATCHING_PHASE; } -void PasswordFormManager::OnRequestDone(int handle, +void PasswordFormManager::OnRequestDone( const std::vector<PasswordForm*>& logins_result) { // Note that the result gets deleted after this call completes, but we own // the PasswordForm objects pointed to by the result vector, thus we keep @@ -340,12 +338,17 @@ void PasswordFormManager::OnRequestDone(int handle, } void PasswordFormManager::OnPasswordStoreRequestDone( - CancelableRequestProvider::Handle handle, - const std::vector<PasswordForm*>& result) { + CancelableRequestProvider::Handle handle, + const std::vector<content::PasswordForm*>& result) { + // TODO(kaiwang): Remove this function. + NOTREACHED(); +} + +void PasswordFormManager::OnGetPasswordStoreResults( + const std::vector<content::PasswordForm*>& results) { DCHECK_EQ(state_, MATCHING_PHASE); - DCHECK_EQ(pending_login_query_, handle); - if (result.empty()) { + if (results.empty()) { state_ = POST_MATCHING_PHASE; // No result means that we visit this site the first time so we don't need // to check whether this site is blacklisted or not. Just send a message @@ -353,9 +356,7 @@ void PasswordFormManager::OnPasswordStoreRequestDone( SendNotBlacklistedToRenderer(); return; } - - OnRequestDone(handle, result); - pending_login_query_ = 0; + OnRequestDone(results); } bool PasswordFormManager::IgnoreResult(const PasswordForm& form) const { diff --git a/chrome/browser/password_manager/password_form_manager.h b/chrome/browser/password_manager/password_form_manager.h index aa4bb1c..6dfda5f 100644 --- a/chrome/browser/password_manager/password_form_manager.h +++ b/chrome/browser/password_manager/password_form_manager.h @@ -84,13 +84,14 @@ class PasswordFormManager : public PasswordStoreConsumer { void SetHasGeneratedPassword(); // Determines if we need to autofill given the results of the query. - void OnRequestDone( - int handle, const std::vector<content::PasswordForm*>& result); + void OnRequestDone(const std::vector<content::PasswordForm*>& result); // PasswordStoreConsumer implementation. virtual void OnPasswordStoreRequestDone( CancelableRequestProvider::Handle handle, const std::vector<content::PasswordForm*>& result) OVERRIDE; + virtual void OnGetPasswordStoreResults( + const std::vector<content::PasswordForm*>& results) OVERRIDE; // A user opted to 'never remember' passwords for this form. // Blacklist it so that from now on when it is seen we ignore it. @@ -228,9 +229,6 @@ class PasswordFormManager : public PasswordStoreConsumer { // PasswordManager owning this. const PasswordManager* const password_manager_; - // Handle to any pending PasswordStore::GetLogins query. - CancelableRequestProvider::Handle pending_login_query_; - // Convenience pointer to entry in best_matches_ that is marked // as preferred. This is only allowed to be null if there are no best matches // at all, since there will always be one preferred login when there are diff --git a/chrome/browser/password_manager/password_form_manager_unittest.cc b/chrome/browser/password_manager/password_form_manager_unittest.cc index 43f1a02..939f621 100644 --- a/chrome/browser/password_manager/password_form_manager_unittest.cc +++ b/chrome/browser/password_manager/password_form_manager_unittest.cc @@ -106,20 +106,17 @@ class PasswordFormManagerTest : public testing::Test { } void SimulateFetchMatchingLoginsFromPasswordStore( - PasswordFormManager* manager, - int handle) { + PasswordFormManager* manager) { // Just need to update the internal states. manager->state_ = PasswordFormManager::MATCHING_PHASE; - manager->pending_login_query_ = handle; } void SimulateResponseFromPasswordStore( PasswordFormManager* manager, - int handle, const std::vector<PasswordForm*>& result) { // Simply call the callback method when request done. This will transfer // the ownership of the objects in |result| to the |manager|. - manager->OnPasswordStoreRequestDone(handle, result); + manager->OnGetPasswordStoreResults(result); } bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) { @@ -384,9 +381,9 @@ TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) { // We should send the not blacklisted message. scoped_ptr<TestPasswordFormManager> manager(new TestPasswordFormManager( profile(), &password_manager, *observed_form(), false)); - SimulateFetchMatchingLoginsFromPasswordStore(manager.get(), 1); + SimulateFetchMatchingLoginsFromPasswordStore(manager.get()); std::vector<PasswordForm*> result; - SimulateResponseFromPasswordStore(manager.get(), 1, result); + SimulateResponseFromPasswordStore(manager.get(), result); EXPECT_EQ(1u, manager->num_sent_messages()); // Sign up attempt to previously visited sites; Login result is found from @@ -394,10 +391,10 @@ TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) { // message. manager.reset(new TestPasswordFormManager( profile(), &password_manager, *observed_form(), false)); - SimulateFetchMatchingLoginsFromPasswordStore(manager.get(), 2); + SimulateFetchMatchingLoginsFromPasswordStore(manager.get()); // We need add heap allocated objects to result. result.push_back(CreateSavedMatch(false)); - SimulateResponseFromPasswordStore(manager.get(), 2, result); + SimulateResponseFromPasswordStore(manager.get(), result); EXPECT_EQ(1u, manager->num_sent_messages()); // Sign up attempt to previously visited sites; Login result is found from @@ -405,9 +402,9 @@ TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) { // message. manager.reset(new TestPasswordFormManager( profile(), &password_manager, *observed_form(), false)); - SimulateFetchMatchingLoginsFromPasswordStore(manager.get(), 3); + SimulateFetchMatchingLoginsFromPasswordStore(manager.get()); result.clear(); result.push_back(CreateSavedMatch(true)); - SimulateResponseFromPasswordStore(manager.get(), 3, result); + SimulateResponseFromPasswordStore(manager.get(), result); EXPECT_EQ(0u, manager->num_sent_messages()); } diff --git a/chrome/browser/password_manager/password_manager_unittest.cc b/chrome/browser/password_manager/password_manager_unittest.cc index 8884af1..e297d7c 100644 --- a/chrome/browser/password_manager/password_manager_unittest.cc +++ b/chrome/browser/password_manager/password_manager_unittest.cc @@ -40,8 +40,8 @@ class MockPasswordManagerDelegate : public PasswordManagerDelegate { MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool()); }; -ACTION_P2(InvokeConsumer, handle, forms) { - arg0->OnPasswordStoreRequestDone(handle, forms); +ACTION_P(InvokeConsumer, forms) { + arg0->OnGetPasswordStoreResults(forms); } ACTION_P(SaveToScopedPtr, scoped) { @@ -119,7 +119,7 @@ TEST_F(PasswordManagerTest, FormSubmitEmptyStore) { std::vector<PasswordForm*> result; // Empty password store. EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); observed.push_back(form); @@ -151,7 +151,7 @@ TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) { std::vector<PasswordForm*> result; // Empty password store. EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); observed.push_back(form); @@ -185,7 +185,7 @@ TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) { result.push_back(existing_different); EXPECT_CALL(delegate_, FillPasswordForm(_)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); @@ -215,7 +215,7 @@ TEST_F(PasswordManagerTest, FormSeenThenLeftPage) { std::vector<PasswordForm*> result; // Empty password store. EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); observed.push_back(form); @@ -243,7 +243,7 @@ TEST_F(PasswordManagerTest, FormSubmitAfterNavigateSubframe) { std::vector<PasswordForm*> result; // Empty password store. EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); observed.push_back(form); @@ -279,7 +279,7 @@ TEST_F(PasswordManagerTest, FormSubmitFailedLogin) { std::vector<PasswordForm*> result; // Empty password store. EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); observed.push_back(form); @@ -300,7 +300,7 @@ TEST_F(PasswordManagerTest, FormSubmitInvisibleLogin) { std::vector<PasswordForm*> result; // Empty password store. EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); observed.push_back(form); @@ -333,7 +333,7 @@ TEST_F(PasswordManagerTest, InitiallyInvisibleForm) { result.push_back(existing); EXPECT_CALL(delegate_, FillPasswordForm(_)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); observed.push_back(form); @@ -368,7 +368,7 @@ TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) { Value::CreateBooleanValue(false)); EXPECT_CALL(delegate_, FillPasswordForm(_)); EXPECT_CALL(*store_, GetLogins(_, _)) - .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); observed.push_back(form); @@ -381,7 +381,7 @@ TEST_F(PasswordManagerTest, FormNotSavedAutocompleteOff) { std::vector<PasswordForm*> result; // Empty password store. EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); form.password_autocomplete_set = false; @@ -409,7 +409,7 @@ TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) { std::vector<PasswordForm*> result; // Empty password store. EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); EXPECT_CALL(*store_, GetLogins(_,_)) - .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); + .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); std::vector<PasswordForm> observed; PasswordForm form(MakeSimpleForm()); form.password_autocomplete_set = false; diff --git a/chrome/browser/password_manager/password_store.cc b/chrome/browser/password_manager/password_store.cc index d4ef8e1..807dd31 100644 --- a/chrome/browser/password_manager/password_store.cc +++ b/chrome/browser/password_manager/password_store.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" +#include "base/message_loop_proxy.h" #include "base/stl_util.h" #include "chrome/browser/password_manager/password_store_consumer.h" #include "content/public/browser/browser_thread.h" @@ -16,10 +17,52 @@ using content::BrowserThread; using std::vector; using content::PasswordForm; +namespace { + +// PasswordStoreConsumer callback requires vector const reference. +void RunConsumerCallbackIfNotCanceled( + const CancelableTaskTracker::IsCanceledCallback& is_canceled_cb, + PasswordStoreConsumer* consumer, + const vector<PasswordForm*>* matched_forms) { + if (is_canceled_cb.Run()) { + STLDeleteContainerPointers(matched_forms->begin(), matched_forms->end()); + return; + } + + // OnGetPasswordStoreResults owns PasswordForms in the vector. + consumer->OnGetPasswordStoreResults(*matched_forms); +} + +void PostConsumerCallback( + base::TaskRunner* task_runner, + const CancelableTaskTracker::IsCanceledCallback& is_canceled_cb, + PasswordStoreConsumer* consumer, + const base::Time& ignore_logins_cutoff, + const vector<PasswordForm*>& matched_forms) { + vector<PasswordForm*>* matched_forms_copy = new vector<PasswordForm*>(); + if (ignore_logins_cutoff.is_null()) { + *matched_forms_copy = matched_forms; + } else { + // Apply |ignore_logins_cutoff| and delete old ones. + for (size_t i = 0; i < matched_forms.size(); i++) { + if (matched_forms[i]->date_created < ignore_logins_cutoff) + delete matched_forms[i]; + else + matched_forms_copy->push_back(matched_forms[i]); + } + } + + task_runner->PostTask( + FROM_HERE, + base::Bind(&RunConsumerCallbackIfNotCanceled, + is_canceled_cb, consumer, base::Owned(matched_forms_copy))); +} + +} // namespace + PasswordStore::GetLoginsRequest::GetLoginsRequest( const GetLoginsCallback& callback) - : CancelableRequest1<GetLoginsCallback, - std::vector<PasswordForm*> >(callback) { + : CancelableRequest1<GetLoginsCallback, vector<PasswordForm*> >(callback) { } void PasswordStore::GetLoginsRequest::ApplyIgnoreLoginsCutoff() { @@ -74,8 +117,9 @@ void PasswordStore::RemoveLoginsCreatedBetween(const base::Time& delete_begin, delete_begin, delete_end)))); } -CancelableRequestProvider::Handle PasswordStore::GetLogins( - const PasswordForm& form, PasswordStoreConsumer* consumer) { +CancelableTaskTracker::TaskId PasswordStore::GetLogins( + const PasswordForm& form, + PasswordStoreConsumer* consumer) { // Per http://crbug.com/121738, we deliberately ignore saved logins for // http*://www.google.com/ that were stored prior to 2012. (Google now uses // https://accounts.google.com/ for all login forms, so these should be @@ -93,8 +137,20 @@ CancelableRequestProvider::Handle PasswordStore::GetLogins( { 2012, 1, 0, 1, 0, 0, 0, 0 }; // 00:00 Jan 1 2012 ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff); } - return Schedule(&PasswordStore::GetLoginsImpl, consumer, form, - ignore_logins_cutoff); + + CancelableTaskTracker::IsCanceledCallback is_canceled_cb; + CancelableTaskTracker::TaskId id = + consumer->cancelable_task_tracker()->NewTrackedTaskId(&is_canceled_cb); + + ConsumerCallbackRunner callback_runner = + base::Bind(&PostConsumerCallback, + base::MessageLoopProxy::current(), + is_canceled_cb, + consumer, + ignore_logins_cutoff); + ScheduleTask( + base::Bind(&PasswordStore::GetLoginsImpl, this, form, callback_runner)); + return id; } CancelableRequestProvider::Handle PasswordStore::GetAutofillableLogins( @@ -137,10 +193,12 @@ void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) { template<typename BackendFunc> CancelableRequestProvider::Handle PasswordStore::Schedule( - BackendFunc func, PasswordStoreConsumer* consumer) { - scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( - base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, - base::Unretained(consumer)))); + BackendFunc func, + PasswordStoreConsumer* consumer) { + scoped_refptr<GetLoginsRequest> request( + NewGetLoginsRequest( + base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, + base::Unretained(consumer)))); AddRequest(request, consumer->cancelable_consumer()); ScheduleTask(base::Bind(func, this, request)); return request->handle(); @@ -148,11 +206,14 @@ CancelableRequestProvider::Handle PasswordStore::Schedule( template<typename BackendFunc> CancelableRequestProvider::Handle PasswordStore::Schedule( - BackendFunc func, PasswordStoreConsumer* consumer, - const PasswordForm& form, const base::Time& ignore_logins_cutoff) { - scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( - base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, - base::Unretained(consumer)))); + BackendFunc func, + PasswordStoreConsumer* consumer, + const PasswordForm& form, + const base::Time& ignore_logins_cutoff) { + scoped_refptr<GetLoginsRequest> request( + NewGetLoginsRequest( + base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, + base::Unretained(consumer)))); request->set_ignore_logins_cutoff(ignore_logins_cutoff); AddRequest(request, consumer->cancelable_consumer()); ScheduleTask(base::Bind(func, this, request, form)); diff --git a/chrome/browser/password_manager/password_store.h b/chrome/browser/password_manager/password_store.h index a15bd7a..8a684ca 100644 --- a/chrome/browser/password_manager/password_store.h +++ b/chrome/browser/password_manager/password_store.h @@ -14,6 +14,7 @@ #include "base/time.h" #include "chrome/browser/common/cancelable_request.h" #include "chrome/browser/profiles/refcounted_profile_keyed_service.h" +#include "chrome/common/cancelable_task_tracker.h" class PasswordStore; class PasswordStoreConsumer; @@ -102,11 +103,12 @@ class PasswordStore void RemoveLoginsCreatedBetween(const base::Time& delete_begin, const base::Time& delete_end); - // Searches for a matching PasswordForm and returns a handle so the async - // request can be tracked. Implement the PasswordStoreConsumer interface to be + // Searches for a matching PasswordForm and returns a ID so the async request + // can be tracked. Implement the PasswordStoreConsumer interface to be // notified on completion. - virtual Handle GetLogins(const content::PasswordForm& form, - PasswordStoreConsumer* consumer); + virtual CancelableTaskTracker::TaskId GetLogins( + const content::PasswordForm& form, + PasswordStoreConsumer* consumer); // Gets the complete list of PasswordForms that are not blacklist entries--and // are thus auto-fillable--and returns a handle so the async request can be @@ -147,7 +149,9 @@ class PasswordStore virtual GetLoginsRequest* NewGetLoginsRequest( const GetLoginsCallback& callback); - // Schedule the given |task| to be run in the PasswordStore's own thread. + // Schedule the given |task| to be run in the PasswordStore's task thread. By + // default it uses DB thread, but sub classes can override to use other + // threads. virtual bool ScheduleTask(const base::Closure& task); // These will be run in PasswordStore's own thread. @@ -162,11 +166,17 @@ class PasswordStore // Synchronous implementation to remove the given logins. virtual void RemoveLoginsCreatedBetweenImpl(const base::Time& delete_begin, const base::Time& delete_end) = 0; + + typedef base::Callback<void(const std::vector<content::PasswordForm*>&)> + ConsumerCallbackRunner; // Owns all PasswordForms in the vector. + // Should find all PasswordForms with the same signon_realm. The results // will then be scored by the PasswordFormManager. Once they are found // (or not), the consumer should be notified. - virtual void GetLoginsImpl(GetLoginsRequest* request, - const content::PasswordForm& form) = 0; + virtual void GetLoginsImpl( + const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner) = 0; + // Finds all non-blacklist PasswordForms, and notifies the consumer. virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) = 0; // Finds all blacklist PasswordForms, and notifies the consumer. @@ -193,7 +203,8 @@ class PasswordStore // form |form| and responses delivered to |consumer| on the current thread. // See GetLogins() for more information on |ignore_logins_cutoff|. template<typename BackendFunc> - Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer, + Handle Schedule(BackendFunc func, + PasswordStoreConsumer* consumer, const content::PasswordForm& form, const base::Time& ignore_logins_cutoff); diff --git a/chrome/browser/password_manager/password_store_consumer.h b/chrome/browser/password_manager/password_store_consumer.h index 87e7f43..5defe1e 100644 --- a/chrome/browser/password_manager/password_store_consumer.h +++ b/chrome/browser/password_manager/password_store_consumer.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_CONSUMER_H_ #include "chrome/browser/common/cancelable_request.h" +#include "chrome/common/cancelable_task_tracker.h" namespace content { struct PasswordForm; @@ -34,11 +35,23 @@ class PasswordStoreConsumer { return &cancelable_consumer_; } + // Called when the request is finished. If there are no results, it is called + // with an empty vector. + // Note: The implementation owns all PasswordForms in the vector. + virtual void OnGetPasswordStoreResults( + const std::vector<content::PasswordForm*>& results) = 0; + + // Cancels the task. + CancelableTaskTracker* cancelable_task_tracker() { + return &cancelable_task_tracker_; + } + protected: virtual ~PasswordStoreConsumer(); private: CancelableRequestConsumer cancelable_consumer_; + CancelableTaskTracker cancelable_task_tracker_; }; #endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_CONSUMER_H_ diff --git a/chrome/browser/password_manager/password_store_default.cc b/chrome/browser/password_manager/password_store_default.cc index a5c6db6..22ace74 100644 --- a/chrome/browser/password_manager/password_store_default.cc +++ b/chrome/browser/password_manager/password_store_default.cc @@ -94,9 +94,11 @@ void PasswordStoreDefault::RemoveLoginsCreatedBetweenImpl( } void PasswordStoreDefault::GetLoginsImpl( - GetLoginsRequest* request, const content::PasswordForm& form) { - login_db_->GetLogins(form, &request->value); - ForwardLoginsResult(request); + const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner) { + std::vector<PasswordForm*> matched_forms; + login_db_->GetLogins(form, &matched_forms); + callback_runner.Run(matched_forms); } void PasswordStoreDefault::GetAutofillableLoginsImpl( diff --git a/chrome/browser/password_manager/password_store_default.h b/chrome/browser/password_manager/password_store_default.h index ac624ca..6f23776 100644 --- a/chrome/browser/password_manager/password_store_default.h +++ b/chrome/browser/password_manager/password_store_default.h @@ -36,8 +36,9 @@ class PasswordStoreDefault : public PasswordStore { const content::PasswordForm& form) OVERRIDE; virtual void RemoveLoginsCreatedBetweenImpl( const base::Time& delete_begin, const base::Time& delete_end) OVERRIDE; - virtual void GetLoginsImpl(GetLoginsRequest* request, - const content::PasswordForm& form) OVERRIDE; + virtual void GetLoginsImpl( + const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner) OVERRIDE; virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) OVERRIDE; virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) OVERRIDE; virtual bool FillAutofillableLogins( diff --git a/chrome/browser/password_manager/password_store_default_unittest.cc b/chrome/browser/password_manager/password_store_default_unittest.cc index 32c6f43..2febab2b 100644 --- a/chrome/browser/password_manager/password_store_default_unittest.cc +++ b/chrome/browser/password_manager/password_store_default_unittest.cc @@ -43,6 +43,8 @@ class MockPasswordStoreConsumer : public PasswordStoreConsumer { MOCK_METHOD2(OnPasswordStoreRequestDone, void(CancelableRequestProvider::Handle, const std::vector<PasswordForm*>&)); + MOCK_METHOD1(OnGetPasswordStoreResults, + void(const std::vector<PasswordForm*>&)); }; // This class will add and remove a mock notification observer from diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc index 5c2bb25..33aec57 100644 --- a/chrome/browser/password_manager/password_store_mac.cc +++ b/chrome/browser/password_manager/password_store_mac.cc @@ -763,6 +763,9 @@ bool PasswordStoreMac::Init() { void PasswordStoreMac::ShutdownOnUIThread() { } +// Mac stores passwords in the system keychain, which can block for an +// arbitrarily long time (most notably, it can block on user confirmation +// from a dialog). Use a dedicated thread to avoid blocking DB thread. bool PasswordStoreMac::ScheduleTask(const base::Closure& task) { if (thread_.get()) { thread_->message_loop()->PostTask(FROM_HERE, task); @@ -888,8 +891,9 @@ void PasswordStoreMac::RemoveLoginsCreatedBetweenImpl( } } -void PasswordStoreMac::GetLoginsImpl(GetLoginsRequest* request, - const content::PasswordForm& form) { +void PasswordStoreMac::GetLoginsImpl( + const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner) { MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get()); std::vector<PasswordForm*> keychain_forms = keychain_adapter.PasswordsFillingForm(form); @@ -897,17 +901,18 @@ void PasswordStoreMac::GetLoginsImpl(GetLoginsRequest* request, std::vector<PasswordForm*> database_forms; login_metadata_db_->GetLogins(form, &database_forms); - std::vector<PasswordForm*>& merged_forms = request->value; + std::vector<PasswordForm*> matched_forms; internal_keychain_helpers::MergePasswordForms(&keychain_forms, &database_forms, - &merged_forms); + &matched_forms); // Strip any blacklist entries out of the unused Keychain array, then take // all the entries that are left (which we can use as imported passwords). std::vector<PasswordForm*> keychain_blacklist_forms = internal_keychain_helpers::ExtractBlacklistForms(&keychain_forms); - merged_forms.insert(merged_forms.end(), keychain_forms.begin(), - keychain_forms.end()); + matched_forms.insert(matched_forms.end(), + keychain_forms.begin(), + keychain_forms.end()); keychain_forms.clear(); STLDeleteElements(&keychain_blacklist_forms); @@ -915,7 +920,7 @@ void PasswordStoreMac::GetLoginsImpl(GetLoginsRequest* request, RemoveDatabaseForms(database_forms); STLDeleteElements(&database_forms); - ForwardLoginsResult(request); + callback_runner.Run(matched_forms); } void PasswordStoreMac::GetBlacklistLoginsImpl(GetLoginsRequest* request) { diff --git a/chrome/browser/password_manager/password_store_mac.h b/chrome/browser/password_manager/password_store_mac.h index 39cc572..519e71f 100644 --- a/chrome/browser/password_manager/password_store_mac.h +++ b/chrome/browser/password_manager/password_store_mac.h @@ -51,8 +51,9 @@ class PasswordStoreMac : public PasswordStore { const content::PasswordForm& form) OVERRIDE; virtual void RemoveLoginsCreatedBetweenImpl( const base::Time& delete_begin, const base::Time& delete_end) OVERRIDE; - virtual void GetLoginsImpl(GetLoginsRequest* request, - const content::PasswordForm& form) OVERRIDE; + virtual void GetLoginsImpl( + const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner) OVERRIDE; virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) OVERRIDE; virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) OVERRIDE; virtual bool FillAutofillableLogins( diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc index b413193..d48d9ef 100644 --- a/chrome/browser/password_manager/password_store_mac_unittest.cc +++ b/chrome/browser/password_manager/password_store_mac_unittest.cc @@ -33,6 +33,8 @@ public: MOCK_METHOD2(OnPasswordStoreRequestDone, void(CancelableRequestProvider::Handle, const std::vector<content::PasswordForm*>&)); + MOCK_METHOD1(OnGetPasswordStoreResults, + void(const std::vector<content::PasswordForm*>&)); }; ACTION(STLDeleteElements0) { @@ -996,10 +998,10 @@ TEST_F(PasswordStoreMacTest, TestStoreUpdate) { // Do a store-level query to wait for all the operations above to be done. MockPasswordStoreConsumer consumer; - ON_CALL(consumer, OnPasswordStoreRequestDone(_, _)).WillByDefault( + ON_CALL(consumer, OnGetPasswordStoreResults(_)).WillByDefault( QuitUIMessageLoop()); - EXPECT_CALL(consumer, OnPasswordStoreRequestDone(_, _)).WillOnce( - DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop())); + EXPECT_CALL(consumer, OnGetPasswordStoreResults(_)).WillOnce( + DoAll(WithArg<0>(STLDeleteElements0()), QuitUIMessageLoop())); store_->GetLogins(*joint_form, &consumer); MessageLoop::current()->Run(); diff --git a/chrome/browser/password_manager/password_store_unittest.cc b/chrome/browser/password_manager/password_store_unittest.cc index aec69d9..5b2e8d4 100644 --- a/chrome/browser/password_manager/password_store_unittest.cc +++ b/chrome/browser/password_manager/password_store_unittest.cc @@ -35,6 +35,8 @@ class MockPasswordStoreConsumer : public PasswordStoreConsumer { MOCK_METHOD2(OnPasswordStoreRequestDone, void(CancelableRequestProvider::Handle, const std::vector<PasswordForm*>&)); + MOCK_METHOD1(OnGetPasswordStoreResults, + void(const std::vector<PasswordForm*>&)); }; // This class will add and remove a mock notification observer from @@ -238,24 +240,23 @@ TEST_F(PasswordStoreTest, IgnoreOldWwwGoogleLogins) { MockPasswordStoreConsumer consumer; // Make sure we quit the MessageLoop even if the test fails. - ON_CALL(consumer, OnPasswordStoreRequestDone(_, _)) + ON_CALL(consumer, OnGetPasswordStoreResults(_)) .WillByDefault(QuitUIMessageLoop()); // Expect the appropriate replies, as above, in reverse order than we will // issue the queries. Each retires on saturation to avoid matcher spew, except // the last which quits the message loop. EXPECT_CALL(consumer, - OnPasswordStoreRequestDone(_, - ContainsAllPasswordForms(bar_example_expected))) - .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop())); + OnGetPasswordStoreResults(ContainsAllPasswordForms(bar_example_expected))) + .WillOnce(DoAll(WithArg<0>(STLDeleteElements0()), QuitUIMessageLoop())); EXPECT_CALL(consumer, - OnPasswordStoreRequestDone(_, + OnGetPasswordStoreResults( ContainsAllPasswordForms(accounts_google_expected))) - .WillOnce(WithArg<1>(STLDeleteElements0())).RetiresOnSaturation(); + .WillOnce(WithArg<0>(STLDeleteElements0())).RetiresOnSaturation(); EXPECT_CALL(consumer, - OnPasswordStoreRequestDone(_, + OnGetPasswordStoreResults( ContainsAllPasswordForms(www_google_expected))) - .WillOnce(WithArg<1>(STLDeleteElements0())).RetiresOnSaturation(); + .WillOnce(WithArg<0>(STLDeleteElements0())).RetiresOnSaturation(); store->GetLogins(www_google, &consumer); store->GetLogins(accounts_google, &consumer); diff --git a/chrome/browser/password_manager/password_store_win.cc b/chrome/browser/password_manager/password_store_win.cc index 3982ec4..3736e75 100644 --- a/chrome/browser/password_manager/password_store_win.cc +++ b/chrome/browser/password_manager/password_store_win.cc @@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "chrome/browser/password_manager/ie7_password.h" @@ -18,36 +19,6 @@ using content::BrowserThread; using content::PasswordForm; -namespace { -// Subclass GetLoginsRequest in order to hold a copy of the form information -// from the GetLogins request for the ForwardLoginsResult call. Note that the -// other calls such as GetBlacklistLogins and GetAutofillableLogins, the form is -// not set. -class FormGetLoginsRequest : public PasswordStore::GetLoginsRequest { - public: - explicit FormGetLoginsRequest( - const PasswordStore::GetLoginsCallback& callback) - : GetLoginsRequest(callback) {} - - // We hold a copy of the |form| used in GetLoginsImpl as a pointer. If the - // form is not set (is NULL), then we are not a GetLogins request. - void SetLoginsRequestForm(const PasswordForm& form) { - form_.reset(new PasswordForm(form)); - } - PasswordForm* form() const { - return form_.get(); - } - bool IsLoginsRequest() const { return !!form_.get(); } - - protected: - virtual ~FormGetLoginsRequest() {} - - private: - scoped_ptr<PasswordForm> form_; -}; - -} // namespace - // Handles requests to WebDataService. class PasswordStoreWin::DBHandler : public WebDataServiceConsumer { public: @@ -59,21 +30,34 @@ class PasswordStoreWin::DBHandler : public WebDataServiceConsumer { ~DBHandler(); - // Requests the IE7 login for |url| and |request|. This is async. The request - // is processed when complete. - void GetIE7Login(const GURL& url, GetLoginsRequest* request); + // Requests the IE7 login for |form|. This is async. |callback_runner| will be + // run when complete. + void GetIE7Login( + const PasswordForm& form, + const PasswordStoreWin::ConsumerCallbackRunner& callback_runner); private: - // Holds requests associated with in-flight GetLogin queries. - typedef std::map<WebDataService::Handle, - scoped_refptr<GetLoginsRequest> > PendingRequestMap; + struct RequestInfo { + RequestInfo() {} + + RequestInfo(PasswordForm* request_form, + const PasswordStoreWin::ConsumerCallbackRunner& runner) + : form(request_form), + callback_runner(runner) {} + + PasswordForm* form; + PasswordStoreWin::ConsumerCallbackRunner callback_runner; + }; + + // Holds info associated with in-flight GetIE7Login requests. + typedef std::map<WebDataService::Handle, RequestInfo> PendingRequestMap; // Gets logins from IE7 if no others are found. Also copies them into // Chrome's WebDatabase so we don't need to look next time. PasswordForm* GetIE7Result(const WDTypedResult* result, const PasswordForm& form); - // WebDataServiceConsumer. + // WebDataServiceConsumer implementation. virtual void OnWebDataServiceRequestDone( WebDataService::Handle handle, const WDTypedResult* result) OVERRIDE; @@ -84,7 +68,6 @@ class PasswordStoreWin::DBHandler : public WebDataServiceConsumer { // from PasswordStoreWin::Shutdown, which deletes us. scoped_refptr<PasswordStoreWin> password_store_; - // Holds requests associated with in-flight GetLogin queries. PendingRequestMap pending_requests_; DISALLOW_COPY_AND_ASSIGN(DBHandler); @@ -93,18 +76,22 @@ class PasswordStoreWin::DBHandler : public WebDataServiceConsumer { PasswordStoreWin::DBHandler::~DBHandler() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); for (PendingRequestMap::const_iterator i = pending_requests_.begin(); - i != pending_requests_.end(); ++i) { + i != pending_requests_.end(); + ++i) { web_data_service_->CancelRequest(i->first); + delete i->second.form; } } -void PasswordStoreWin::DBHandler::GetIE7Login(const GURL& url, - GetLoginsRequest* request) { +void PasswordStoreWin::DBHandler::GetIE7Login( + const PasswordForm& form, + const PasswordStoreWin::ConsumerCallbackRunner& callback_runner) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); IE7PasswordInfo info; - info.url_hash = ie7_password::GetUrlHash(UTF8ToWide(url.spec())); + info.url_hash = ie7_password::GetUrlHash(UTF8ToWide(form.origin.spec())); WebDataService::Handle handle = web_data_service_->GetIE7Login(info, this); - pending_requests_.insert(PendingRequestMap::value_type(handle, request)); + pending_requests_[handle] = + RequestInfo(new PasswordForm(form), callback_runner); } PasswordForm* PasswordStoreWin::DBHandler::GetIE7Result( @@ -148,28 +135,30 @@ void PasswordStoreWin::DBHandler::OnWebDataServiceRequestDone( const WDTypedResult* result) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - PendingRequestMap::iterator i(pending_requests_.find(handle)); + PendingRequestMap::iterator i = pending_requests_.find(handle); DCHECK(i != pending_requests_.end()); - scoped_refptr<GetLoginsRequest> request(i->second); + + scoped_ptr<PasswordForm> form(i->second.form); + PasswordStoreWin::ConsumerCallbackRunner callback_runner( + i->second.callback_runner); pending_requests_.erase(i); - if (!result) - return; // The WDS returns NULL if it is shutting down. + std::vector<content::PasswordForm*> matched_forms; + + if (!result) { + // The WDS returns NULL if it is shutting down. Run callback with empty + // result. + callback_runner.Run(matched_forms); + return; + } DCHECK_EQ(PASSWORD_IE7_RESULT, result->GetType()); - PasswordForm* form = - static_cast<FormGetLoginsRequest*>(request.get())->form(); - DCHECK(form); PasswordForm* ie7_form = GetIE7Result(result, *form); if (ie7_form) - request->value.push_back(ie7_form); + matched_forms.push_back(ie7_form); - // Since we aren't using ForwardLoginsResult(), we must call - // ApplyIgnoreLoginsCutoff() manually here as is done in - // PasswordStore::ForwardLoginsResult(). - request->ApplyIgnoreLoginsCutoff(); - request->ForwardResult(request->handle(), request->value); + callback_runner.Run(matched_forms); } PasswordStoreWin::PasswordStoreWin(LoginDatabase* login_database, @@ -187,11 +176,6 @@ void PasswordStoreWin::ShutdownOnDBThread() { db_handler_.reset(); } -PasswordStore::GetLoginsRequest* PasswordStoreWin::NewGetLoginsRequest( - const GetLoginsCallback& callback) { - return new FormGetLoginsRequest(callback); -} - void PasswordStoreWin::ShutdownOnUIThread() { BrowserThread::PostTask( BrowserThread::DB, FROM_HERE, @@ -199,21 +183,24 @@ void PasswordStoreWin::ShutdownOnUIThread() { PasswordStoreDefault::ShutdownOnUIThread(); } -void PasswordStoreWin::ForwardLoginsResult(GetLoginsRequest* request) { +void PasswordStoreWin::GetIE7LoginIfNecessary( + const PasswordForm& form, + const ConsumerCallbackRunner& callback_runner, + const std::vector<content::PasswordForm*>& matched_forms) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - if (static_cast<FormGetLoginsRequest*>(request)->IsLoginsRequest() && - request->value.empty() && db_handler_.get()) { - db_handler_->GetIE7Login( - static_cast<FormGetLoginsRequest*>(request)->form()->origin, - request); + if (matched_forms.empty() && db_handler_.get()) { + db_handler_->GetIE7Login(form, callback_runner); } else { - PasswordStore::ForwardLoginsResult(request); + // No need to get IE7 login. + callback_runner.Run(matched_forms); } } -void PasswordStoreWin::GetLoginsImpl(GetLoginsRequest* request, - const PasswordForm& form) { - static_cast<FormGetLoginsRequest*>(request)->SetLoginsRequestForm(form); - - PasswordStoreDefault::GetLoginsImpl(request, form); +void PasswordStoreWin::GetLoginsImpl( + const PasswordForm& form, + const ConsumerCallbackRunner& callback_runner) { + ConsumerCallbackRunner get_ie7_login = + base::Bind(&PasswordStoreWin::GetIE7LoginIfNecessary, + this, form, callback_runner); + PasswordStoreDefault::GetLoginsImpl(form, get_ie7_login); } diff --git a/chrome/browser/password_manager/password_store_win.h b/chrome/browser/password_manager/password_store_win.h index c4dae0c..8493265 100644 --- a/chrome/browser/password_manager/password_store_win.h +++ b/chrome/browser/password_manager/password_store_win.h @@ -36,15 +36,14 @@ class PasswordStoreWin : public PasswordStoreDefault { // Invoked from Shutdown, but run on the DB thread. void ShutdownOnDBThread(); - virtual GetLoginsRequest* NewGetLoginsRequest( - const GetLoginsCallback& callback) OVERRIDE; - - // See PasswordStoreDefault. - virtual void ForwardLoginsResult(GetLoginsRequest* request) OVERRIDE; - - // Overridden so that we can save the form for later use. - virtual void GetLoginsImpl(GetLoginsRequest* request, - const content::PasswordForm& form) OVERRIDE; + virtual void GetLoginsImpl( + const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner) OVERRIDE; + + void GetIE7LoginIfNecessary( + const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner, + const std::vector<content::PasswordForm*>& matched_forms); scoped_ptr<DBHandler> db_handler_; diff --git a/chrome/browser/password_manager/password_store_win_unittest.cc b/chrome/browser/password_manager/password_store_win_unittest.cc index 0d75255..142cb93 100644 --- a/chrome/browser/password_manager/password_store_win_unittest.cc +++ b/chrome/browser/password_manager/password_store_win_unittest.cc @@ -41,6 +41,8 @@ class MockPasswordStoreConsumer : public PasswordStoreConsumer { MOCK_METHOD2(OnPasswordStoreRequestDone, void(CancelableRequestProvider::Handle, const std::vector<content::PasswordForm*>&)); + MOCK_METHOD1(OnGetPasswordStoreResults, + void(const std::vector<content::PasswordForm*>&)); }; class MockWebDataServiceConsumer : public WebDataServiceConsumer { @@ -184,7 +186,7 @@ TEST_F(PasswordStoreWinTest, DISABLED_ConvertIE7Login) { MockPasswordStoreConsumer consumer; // Make sure we quit the MessageLoop even if the test fails. - ON_CALL(consumer, OnPasswordStoreRequestDone(_, _)) + ON_CALL(consumer, OnGetPasswordStoreResults(_)) .WillByDefault(QuitUIMessageLoop()); PasswordFormData form_data = { @@ -218,8 +220,7 @@ TEST_F(PasswordStoreWinTest, DISABLED_ConvertIE7Login) { // The IE7 password should be returned. EXPECT_CALL(consumer, - OnPasswordStoreRequestDone(_, - ContainsAllPasswordForms(forms))) + OnGetPasswordStoreResults(ContainsAllPasswordForms(forms))) .WillOnce(QuitUIMessageLoop()); store_->GetLogins(*form, &consumer); @@ -280,7 +281,7 @@ TEST_F(PasswordStoreWinTest, DISABLED_MultipleWDSQueriesOnDifferentThreads) { MockPasswordStoreConsumer password_consumer; // Make sure we quit the MessageLoop even if the test fails. - ON_CALL(password_consumer, OnPasswordStoreRequestDone(_, _)) + ON_CALL(password_consumer, OnGetPasswordStoreResults(_)) .WillByDefault(QuitUIMessageLoop()); PasswordFormData form_data = { @@ -314,8 +315,7 @@ TEST_F(PasswordStoreWinTest, DISABLED_MultipleWDSQueriesOnDifferentThreads) { // The IE7 password should be returned. EXPECT_CALL(password_consumer, - OnPasswordStoreRequestDone(_, - ContainsAllPasswordForms(forms))) + OnGetPasswordStoreResults(ContainsAllPasswordForms(forms))) .WillOnce(QuitUIMessageLoop()); store_->GetLogins(*form, &password_consumer); @@ -323,8 +323,8 @@ TEST_F(PasswordStoreWinTest, DISABLED_MultipleWDSQueriesOnDifferentThreads) { MockWebDataServiceConsumer wds_consumer; EXPECT_CALL(wds_consumer, - OnWebDataServiceRequestDone(_, _)) - .WillOnce(QuitUIMessageLoop()); + OnWebDataServiceRequestDone(_, _)) + .WillOnce(QuitUIMessageLoop()); wds_->GetIE7Login(password_info, &wds_consumer); @@ -359,14 +359,14 @@ TEST_F(PasswordStoreWinTest, EmptyLogins) { MockPasswordStoreConsumer consumer; // Make sure we quit the MessageLoop even if the test fails. - ON_CALL(consumer, OnPasswordStoreRequestDone(_, _)) + ON_CALL(consumer, OnGetPasswordStoreResults(_)) .WillByDefault(QuitUIMessageLoop()); VectorOfForms expect_none; // expect that we get no results; - EXPECT_CALL(consumer, OnPasswordStoreRequestDone( - _, ContainsAllPasswordForms(expect_none))) - .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop())); + EXPECT_CALL(consumer, + OnGetPasswordStoreResults(ContainsAllPasswordForms(expect_none))) + .WillOnce(DoAll(WithArg<0>(STLDeleteElements0()), QuitUIMessageLoop())); store_->GetLogins(*form, &consumer); MessageLoop::current()->Run(); @@ -385,8 +385,9 @@ TEST_F(PasswordStoreWinTest, EmptyBlacklistLogins) { VectorOfForms expect_none; // expect that we get no results; - EXPECT_CALL(consumer, OnPasswordStoreRequestDone( - _, ContainsAllPasswordForms(expect_none))) + EXPECT_CALL( + consumer, + OnPasswordStoreRequestDone(_, ContainsAllPasswordForms(expect_none))) .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop())); store_->GetBlacklistLogins(&consumer); @@ -406,8 +407,9 @@ TEST_F(PasswordStoreWinTest, EmptyAutofillableLogins) { VectorOfForms expect_none; // expect that we get no results; - EXPECT_CALL(consumer, OnPasswordStoreRequestDone( - _, ContainsAllPasswordForms(expect_none))) + EXPECT_CALL( + consumer, + OnPasswordStoreRequestDone(_, ContainsAllPasswordForms(expect_none))) .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop())); store_->GetAutofillableLogins(&consumer); diff --git a/chrome/browser/password_manager/password_store_x.cc b/chrome/browser/password_manager/password_store_x.cc index f1e29c3..eae3161 100644 --- a/chrome/browser/password_manager/password_store_x.cc +++ b/chrome/browser/password_manager/password_store_x.cc @@ -115,22 +115,25 @@ void PasswordStoreX::SortLoginsByOrigin(NativeBackend::PasswordFormList* list) { std::sort(list->begin(), list->end(), LoginLessThan()); } -void PasswordStoreX::GetLoginsImpl(GetLoginsRequest* request, - const PasswordForm& form) { +void PasswordStoreX::GetLoginsImpl( + const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner) { CheckMigration(); - if (use_native_backend() && backend_->GetLogins(form, &request->value)) { - SortLoginsByOrigin(&request->value); - ForwardLoginsResult(request); + std::vector<content::PasswordForm*> matched_forms; + if (use_native_backend() && backend_->GetLogins(form, &matched_forms)) { + SortLoginsByOrigin(&matched_forms); + callback_runner.Run(matched_forms); // The native backend may succeed and return no data even while locked, if // the query did not match anything stored. So we continue to allow fallback // until we perform a write operation, or until a read returns actual data. - if (request->value.size() > 0) + if (matched_forms.size() > 0) allow_fallback_ = false; } else if (allow_default_store()) { - PasswordStoreDefault::GetLoginsImpl(request, form); + DCHECK(matched_forms.empty()); + PasswordStoreDefault::GetLoginsImpl(form, callback_runner); } else { // The consumer will be left hanging unless we reply. - ForwardLoginsResult(request); + callback_runner.Run(matched_forms); } } diff --git a/chrome/browser/password_manager/password_store_x.h b/chrome/browser/password_manager/password_store_x.h index 5caad55..ab69ca7 100644 --- a/chrome/browser/password_manager/password_store_x.h +++ b/chrome/browser/password_manager/password_store_x.h @@ -80,8 +80,9 @@ class PasswordStoreX : public PasswordStoreDefault { const content::PasswordForm& form) OVERRIDE; virtual void RemoveLoginsCreatedBetweenImpl( const base::Time& delete_begin, const base::Time& delete_end) OVERRIDE; - virtual void GetLoginsImpl(GetLoginsRequest* request, - const content::PasswordForm& form) OVERRIDE; + virtual void GetLoginsImpl( + const content::PasswordForm& form, + const ConsumerCallbackRunner& callback_runner) OVERRIDE; virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) OVERRIDE; virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) OVERRIDE; virtual bool FillAutofillableLogins( diff --git a/chrome/browser/password_manager/password_store_x_unittest.cc b/chrome/browser/password_manager/password_store_x_unittest.cc index bbb9aa2..2387968 100644 --- a/chrome/browser/password_manager/password_store_x_unittest.cc +++ b/chrome/browser/password_manager/password_store_x_unittest.cc @@ -50,6 +50,8 @@ class MockPasswordStoreConsumer : public PasswordStoreConsumer { MOCK_METHOD2(OnPasswordStoreRequestDone, void(CancelableRequestProvider::Handle, const std::vector<PasswordForm*>&)); + MOCK_METHOD1(OnGetPasswordStoreResults, + void(const std::vector<PasswordForm*>&)); }; // This class will add and remove a mock notification observer from diff --git a/chrome/browser/sync/test/integration/passwords_helper.cc b/chrome/browser/sync/test/integration/passwords_helper.cc index e54d89d..fd8836b 100644 --- a/chrome/browser/sync/test/integration/passwords_helper.cc +++ b/chrome/browser/sync/test/integration/passwords_helper.cc @@ -4,6 +4,7 @@ #include "chrome/browser/sync/test/integration/passwords_helper.h" +#include "base/compiler_specific.h" #include "base/stringprintf.h" #include "base/synchronization/waitable_event.h" #include "base/time.h" @@ -43,13 +44,19 @@ class PasswordStoreConsumerHelper : public PasswordStoreConsumer { virtual void OnPasswordStoreRequestDone( CancelableRequestProvider::Handle handle, - const std::vector<PasswordForm*>& result) { + const std::vector<PasswordForm*>& result) OVERRIDE { + // TODO(kaiwang): Remove this function. + NOTREACHED(); + } + + virtual void OnGetPasswordStoreResults( + const std::vector<PasswordForm*>& result) OVERRIDE { result_->clear(); for (std::vector<PasswordForm*>::const_iterator it = result.begin(); - it != result.end(); ++it) { - // Make a copy of the form since it gets deallocated after the caller of - // this method returns. + it != result.end(); + ++it) { result_->push_back(**it); + delete *it; } // Quit the message loop to wake up passwords_helper::GetLogins. diff --git a/chrome/browser/ui/webui/options/password_manager_handler.cc b/chrome/browser/ui/webui/options/password_manager_handler.cc index a137a40..ca57a68 100644 --- a/chrome/browser/ui/webui/options/password_manager_handler.cc +++ b/chrome/browser/ui/webui/options/password_manager_handler.cc @@ -238,6 +238,13 @@ void PasswordManagerHandler::PasswordListPopulater:: page_->SetPasswordList(); } +void PasswordManagerHandler::PasswordListPopulater::OnGetPasswordStoreResults( + const std::vector<content::PasswordForm*>& results) { + // TODO(kaiwang): Implement when I refactor + // PasswordStore::GetAutofillableLogins and PasswordStore::GetBlacklistLogins. + NOTIMPLEMENTED(); +} + PasswordManagerHandler::PasswordExceptionListPopulater:: PasswordExceptionListPopulater(PasswordManagerHandler* page) : ListPopulater(page) { @@ -267,4 +274,12 @@ void PasswordManagerHandler::PasswordExceptionListPopulater:: page_->SetPasswordExceptionList(); } +void PasswordManagerHandler::PasswordExceptionListPopulater:: + OnGetPasswordStoreResults( + const std::vector<content::PasswordForm*>& results) { + // TODO(kaiwang): Implement when I refactor + // PasswordStore::GetAutofillableLogins and PasswordStore::GetBlacklistLogins. + NOTIMPLEMENTED(); +} + } // namespace options diff --git a/chrome/browser/ui/webui/options/password_manager_handler.h b/chrome/browser/ui/webui/options/password_manager_handler.h index c47058a..f261e0a 100644 --- a/chrome/browser/ui/webui/options/password_manager_handler.h +++ b/chrome/browser/ui/webui/options/password_manager_handler.h @@ -73,11 +73,6 @@ class PasswordManagerHandler : public OptionsPageUIHandler, // Send a query to the password store to populate a list. virtual void Populate() = 0; - // Send the password store's reply back to the handler. - virtual void OnPasswordStoreRequestDone( - CancelableRequestProvider::Handle handle, - const std::vector<content::PasswordForm*>& result) = 0; - protected: PasswordManagerHandler* page_; CancelableRequestProvider::Handle pending_login_query_; @@ -95,6 +90,8 @@ class PasswordManagerHandler : public OptionsPageUIHandler, virtual void OnPasswordStoreRequestDone( CancelableRequestProvider::Handle handle, const std::vector<content::PasswordForm*>& result) OVERRIDE; + virtual void OnGetPasswordStoreResults( + const std::vector<content::PasswordForm*>& results) OVERRIDE; }; // A short class to mediate requests to the password store for exceptions. @@ -109,6 +106,8 @@ class PasswordManagerHandler : public OptionsPageUIHandler, virtual void OnPasswordStoreRequestDone( CancelableRequestProvider::Handle handle, const std::vector<content::PasswordForm*>& result) OVERRIDE; + virtual void OnGetPasswordStoreResults( + const std::vector<content::PasswordForm*>& results) OVERRIDE; }; // Password store consumer for populating the password list and exceptions. |