1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/password_manager/password_store.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop.h"
9 #include "base/stl_util-inl.h"
10 #include "base/task.h"
11 #include "chrome/browser/password_manager/password_store_consumer.h"
12 #include "content/browser/browser_thread.h"
13 #include "webkit/glue/password_form.h"
14
15 using std::vector;
16 using webkit_glue::PasswordForm;
17
GetLoginsRequest(GetLoginsCallback * callback)18 PasswordStore::GetLoginsRequest::GetLoginsRequest(GetLoginsCallback* callback)
19 : CancelableRequest1<GetLoginsCallback,
20 std::vector<webkit_glue::PasswordForm*> >(callback) {
21 }
22
~GetLoginsRequest()23 PasswordStore::GetLoginsRequest::~GetLoginsRequest() {
24 if (canceled()) {
25 STLDeleteElements(&value);
26 }
27 }
28
PasswordStore()29 PasswordStore::PasswordStore() {
30 }
31
Init()32 bool PasswordStore::Init() {
33 ReportMetrics();
34 return true;
35 }
36
Shutdown()37 void PasswordStore::Shutdown() {
38 }
39
AddLogin(const PasswordForm & form)40 void PasswordStore::AddLogin(const PasswordForm& form) {
41 Task* task = NewRunnableMethod(this, &PasswordStore::AddLoginImpl, form);
42 ScheduleTask(
43 NewRunnableMethod(this, &PasswordStore::WrapModificationTask, task));
44 }
45
UpdateLogin(const PasswordForm & form)46 void PasswordStore::UpdateLogin(const PasswordForm& form) {
47 Task* task = NewRunnableMethod(this, &PasswordStore::UpdateLoginImpl, form);
48 ScheduleTask(
49 NewRunnableMethod(this, &PasswordStore::WrapModificationTask, task));
50 }
51
RemoveLogin(const PasswordForm & form)52 void PasswordStore::RemoveLogin(const PasswordForm& form) {
53 Task* task = NewRunnableMethod(this, &PasswordStore::RemoveLoginImpl, form);
54 ScheduleTask(
55 NewRunnableMethod(this, &PasswordStore::WrapModificationTask, task));
56 }
57
RemoveLoginsCreatedBetween(const base::Time & delete_begin,const base::Time & delete_end)58 void PasswordStore::RemoveLoginsCreatedBetween(const base::Time& delete_begin,
59 const base::Time& delete_end) {
60 Task* task = NewRunnableMethod(this,
61 &PasswordStore::RemoveLoginsCreatedBetweenImpl,
62 delete_begin, delete_end);
63 ScheduleTask(
64 NewRunnableMethod(this, &PasswordStore::WrapModificationTask, task));
65 }
66
GetLogins(const PasswordForm & form,PasswordStoreConsumer * consumer)67 CancelableRequestProvider::Handle PasswordStore::GetLogins(
68 const PasswordForm& form, PasswordStoreConsumer* consumer) {
69 return Schedule(&PasswordStore::GetLoginsImpl, consumer, form);
70 }
71
GetAutofillableLogins(PasswordStoreConsumer * consumer)72 CancelableRequestProvider::Handle PasswordStore::GetAutofillableLogins(
73 PasswordStoreConsumer* consumer) {
74 return Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer);
75 }
76
GetBlacklistLogins(PasswordStoreConsumer * consumer)77 CancelableRequestProvider::Handle PasswordStore::GetBlacklistLogins(
78 PasswordStoreConsumer* consumer) {
79 return Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer);
80 }
81
ReportMetrics()82 void PasswordStore::ReportMetrics() {
83 ScheduleTask(NewRunnableMethod(this, &PasswordStore::ReportMetricsImpl));
84 }
85
AddObserver(Observer * observer)86 void PasswordStore::AddObserver(Observer* observer) {
87 observers_.AddObserver(observer);
88 }
89
RemoveObserver(Observer * observer)90 void PasswordStore::RemoveObserver(Observer* observer) {
91 observers_.RemoveObserver(observer);
92 }
93
~PasswordStore()94 PasswordStore::~PasswordStore() {}
95
NewGetLoginsRequest(GetLoginsCallback * callback)96 PasswordStore::GetLoginsRequest* PasswordStore::NewGetLoginsRequest(
97 GetLoginsCallback* callback) {
98 return new GetLoginsRequest(callback);
99 }
100
ScheduleTask(Task * task)101 void PasswordStore::ScheduleTask(Task* task) {
102 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task);
103 }
104
ForwardLoginsResult(GetLoginsRequest * request)105 void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) {
106 request->ForwardResult(GetLoginsRequest::TupleType(request->handle(),
107 request->value));
108 }
109
110 template<typename BackendFunc>
Schedule(BackendFunc func,PasswordStoreConsumer * consumer)111 CancelableRequestProvider::Handle PasswordStore::Schedule(
112 BackendFunc func, PasswordStoreConsumer* consumer) {
113 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest(
114 NewCallback(consumer,
115 &PasswordStoreConsumer::OnPasswordStoreRequestDone)));
116 AddRequest(request, consumer->cancelable_consumer());
117 ScheduleTask(NewRunnableMethod(this, func, request));
118 return request->handle();
119 }
120
121 template<typename BackendFunc, typename ArgA>
Schedule(BackendFunc func,PasswordStoreConsumer * consumer,const ArgA & a)122 CancelableRequestProvider::Handle PasswordStore::Schedule(
123 BackendFunc func, PasswordStoreConsumer* consumer, const ArgA& a) {
124 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest(
125 NewCallback(consumer,
126 &PasswordStoreConsumer::OnPasswordStoreRequestDone)));
127 AddRequest(request, consumer->cancelable_consumer());
128 ScheduleTask(NewRunnableMethod(this, func, request, a));
129 return request->handle();
130 }
131
WrapModificationTask(Task * task)132 void PasswordStore::WrapModificationTask(Task* task) {
133 #if !defined(OS_MACOSX)
134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
135 #endif // !defined(OS_MACOSX)
136
137 DCHECK(task);
138 task->Run();
139 delete task;
140
141 PostNotifyLoginsChanged();
142 }
143
PostNotifyLoginsChanged()144 void PasswordStore::PostNotifyLoginsChanged() {
145 #if !defined(OS_MACOSX)
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
147 #endif // !defined(OS_MACOSX)
148
149 BrowserThread::PostTask(
150 BrowserThread::UI, FROM_HERE,
151 NewRunnableMethod(this, &PasswordStore::NotifyLoginsChanged));
152 }
153
NotifyLoginsChanged()154 void PasswordStore::NotifyLoginsChanged() {
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
156 FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged());
157 }
158