password_store.cc revision 3dff810fe0cc4962a5fa554318e9bf8bc45f5274
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
15using std::vector;
16using webkit_glue::PasswordForm;
17
18PasswordStore::GetLoginsRequest::GetLoginsRequest(GetLoginsCallback* callback)
19    : CancelableRequest1<GetLoginsCallback,
20                         std::vector<webkit_glue::PasswordForm*> >(callback) {
21}
22
23PasswordStore::GetLoginsRequest::~GetLoginsRequest() {
24  if (canceled()) {
25    STLDeleteElements(&value);
26  }
27}
28
29PasswordStore::PasswordStore() {
30}
31
32bool PasswordStore::Init() {
33  ReportMetrics();
34  return true;
35}
36
37void PasswordStore::Shutdown() {
38}
39
40void PasswordStore::AddLogin(const PasswordForm& form) {
41  Task* task = NewRunnableMethod(this, &PasswordStore::AddLoginImpl, form);
42  ScheduleTask(
43      NewRunnableMethod(this, &PasswordStore::WrapModificationTask, task));
44}
45
46void PasswordStore::UpdateLogin(const PasswordForm& form) {
47  Task* task = NewRunnableMethod(this, &PasswordStore::UpdateLoginImpl, form);
48  ScheduleTask(
49      NewRunnableMethod(this, &PasswordStore::WrapModificationTask, task));
50}
51
52void PasswordStore::RemoveLogin(const PasswordForm& form) {
53  Task* task = NewRunnableMethod(this, &PasswordStore::RemoveLoginImpl, form);
54  ScheduleTask(
55      NewRunnableMethod(this, &PasswordStore::WrapModificationTask, task));
56}
57
58void 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
67CancelableRequestProvider::Handle PasswordStore::GetLogins(
68    const PasswordForm& form, PasswordStoreConsumer* consumer) {
69  return Schedule(&PasswordStore::GetLoginsImpl, consumer, form);
70}
71
72CancelableRequestProvider::Handle PasswordStore::GetAutofillableLogins(
73    PasswordStoreConsumer* consumer) {
74  return Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer);
75}
76
77CancelableRequestProvider::Handle PasswordStore::GetBlacklistLogins(
78    PasswordStoreConsumer* consumer) {
79  return Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer);
80}
81
82void PasswordStore::ReportMetrics() {
83  ScheduleTask(NewRunnableMethod(this, &PasswordStore::ReportMetricsImpl));
84}
85
86void PasswordStore::AddObserver(Observer* observer) {
87  observers_.AddObserver(observer);
88}
89
90void PasswordStore::RemoveObserver(Observer* observer) {
91  observers_.RemoveObserver(observer);
92}
93
94PasswordStore::~PasswordStore() {}
95
96PasswordStore::GetLoginsRequest* PasswordStore::NewGetLoginsRequest(
97    GetLoginsCallback* callback) {
98  return new GetLoginsRequest(callback);
99}
100
101void PasswordStore::ScheduleTask(Task* task) {
102  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task);
103}
104
105void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) {
106  request->ForwardResult(GetLoginsRequest::TupleType(request->handle(),
107                                                     request->value));
108}
109
110template<typename BackendFunc>
111CancelableRequestProvider::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
121template<typename BackendFunc, typename ArgA>
122CancelableRequestProvider::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
132void 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
144void 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
154void PasswordStore::NotifyLoginsChanged() {
155  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
156  FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged());
157}
158