Home | History | Annotate | Download | only in password_manager
      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 
     18 PasswordStore::GetLoginsRequest::GetLoginsRequest(GetLoginsCallback* callback)
     19     : CancelableRequest1<GetLoginsCallback,
     20                          std::vector<webkit_glue::PasswordForm*> >(callback) {
     21 }
     22 
     23 PasswordStore::GetLoginsRequest::~GetLoginsRequest() {
     24   if (canceled()) {
     25     STLDeleteElements(&value);
     26   }
     27 }
     28 
     29 PasswordStore::PasswordStore() {
     30 }
     31 
     32 bool PasswordStore::Init() {
     33   ReportMetrics();
     34   return true;
     35 }
     36 
     37 void PasswordStore::Shutdown() {
     38 }
     39 
     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 
     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 
     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 
     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 
     67 CancelableRequestProvider::Handle PasswordStore::GetLogins(
     68     const PasswordForm& form, PasswordStoreConsumer* consumer) {
     69   return Schedule(&PasswordStore::GetLoginsImpl, consumer, form);
     70 }
     71 
     72 CancelableRequestProvider::Handle PasswordStore::GetAutofillableLogins(
     73     PasswordStoreConsumer* consumer) {
     74   return Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer);
     75 }
     76 
     77 CancelableRequestProvider::Handle PasswordStore::GetBlacklistLogins(
     78     PasswordStoreConsumer* consumer) {
     79   return Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer);
     80 }
     81 
     82 void PasswordStore::ReportMetrics() {
     83   ScheduleTask(NewRunnableMethod(this, &PasswordStore::ReportMetricsImpl));
     84 }
     85 
     86 void PasswordStore::AddObserver(Observer* observer) {
     87   observers_.AddObserver(observer);
     88 }
     89 
     90 void PasswordStore::RemoveObserver(Observer* observer) {
     91   observers_.RemoveObserver(observer);
     92 }
     93 
     94 PasswordStore::~PasswordStore() {}
     95 
     96 PasswordStore::GetLoginsRequest* PasswordStore::NewGetLoginsRequest(
     97     GetLoginsCallback* callback) {
     98   return new GetLoginsRequest(callback);
     99 }
    100 
    101 void PasswordStore::ScheduleTask(Task* task) {
    102   BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task);
    103 }
    104 
    105 void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) {
    106   request->ForwardResult(GetLoginsRequest::TupleType(request->handle(),
    107                                                      request->value));
    108 }
    109 
    110 template<typename BackendFunc>
    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>
    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 
    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 
    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 
    154 void PasswordStore::NotifyLoginsChanged() {
    155   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    156   FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged());
    157 }
    158