summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorkaiwang@chromium.org <kaiwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-14 04:01:56 +0000
committerkaiwang@chromium.org <kaiwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-14 04:01:56 +0000
commitcef1a75de87b9ccc381f3d5f8e6d56cc2d58bcbc (patch)
treec82191bc5fd01f06af77791d788447776a550bda /chrome
parent5ea6fdb73760fc1c7a7929dcb4d5f5dd89230610 (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc7
-rw-r--r--chrome/browser/automation/automation_provider_observers.h3
-rw-r--r--chrome/browser/password_manager/mock_password_store.h10
-rw-r--r--chrome/browser/password_manager/password_form_manager.cc23
-rw-r--r--chrome/browser/password_manager/password_form_manager.h8
-rw-r--r--chrome/browser/password_manager/password_form_manager_unittest.cc19
-rw-r--r--chrome/browser/password_manager/password_manager_unittest.cc26
-rw-r--r--chrome/browser/password_manager/password_store.cc91
-rw-r--r--chrome/browser/password_manager/password_store.h27
-rw-r--r--chrome/browser/password_manager/password_store_consumer.h13
-rw-r--r--chrome/browser/password_manager/password_store_default.cc8
-rw-r--r--chrome/browser/password_manager/password_store_default.h5
-rw-r--r--chrome/browser/password_manager/password_store_default_unittest.cc2
-rw-r--r--chrome/browser/password_manager/password_store_mac.cc19
-rw-r--r--chrome/browser/password_manager/password_store_mac.h5
-rw-r--r--chrome/browser/password_manager/password_store_mac_unittest.cc8
-rw-r--r--chrome/browser/password_manager/password_store_unittest.cc17
-rw-r--r--chrome/browser/password_manager/password_store_win.cc133
-rw-r--r--chrome/browser/password_manager/password_store_win.h17
-rw-r--r--chrome/browser/password_manager/password_store_win_unittest.cc34
-rw-r--r--chrome/browser/password_manager/password_store_x.cc19
-rw-r--r--chrome/browser/password_manager/password_store_x.h5
-rw-r--r--chrome/browser/password_manager/password_store_x_unittest.cc2
-rw-r--r--chrome/browser/sync/test/integration/passwords_helper.cc15
-rw-r--r--chrome/browser/ui/webui/options/password_manager_handler.cc15
-rw-r--r--chrome/browser/ui/webui/options/password_manager_handler.h9
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.