Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: chrome/browser/password_manager/password_store.cc

Issue 6646051: Fix DCHECK, memory leak, and refactor PasswordStore to use CancelableRequest (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix ~ListPopulator ordering. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/password_manager/password_store.h" 5 #include "chrome/browser/password_manager/password_store.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/scoped_ptr.h" 8 #include "base/scoped_ptr.h"
9 #include "base/stl_util-inl.h"
9 #include "base/task.h" 10 #include "base/task.h"
10 #include "content/browser/browser_thread.h" 11 #include "content/browser/browser_thread.h"
11 12
12 using std::vector; 13 using std::vector;
13 using webkit_glue::PasswordForm; 14 using webkit_glue::PasswordForm;
14 15
15 PasswordStore::PasswordStore() : handle_(0) { 16 const PasswordStore::Handle PasswordStore::kInvalidHandle = 0;
James Hawkins 2011/03/21 17:53:11 Isn't Handle defined by CancelableRequest? It see
Sheridan Rawlins 2011/03/21 18:36:42 Yep, was thinking the same thing, but too tired to
17
18 PasswordStoreConsumer::~PasswordStoreConsumer() {
19 }
20
21 PasswordStore::GetLoginsRequest::GetLoginsRequest(GetLoginsCallback* callback)
22 : CancelableRequest1<GetLoginsCallback,
23 std::vector<webkit_glue::PasswordForm*> >(callback) {
24 }
25
26 PasswordStore::GetLoginsRequest::~GetLoginsRequest() {
27 if (canceled()) {
28 STLDeleteElements(&value);
29 }
30 }
31
32 PasswordStore::PasswordStore() {
16 } 33 }
17 34
18 bool PasswordStore::Init() { 35 bool PasswordStore::Init() {
19 ReportMetrics(); 36 ReportMetrics();
20 return true; 37 return true;
21 } 38 }
22 39
23 void PasswordStore::AddLogin(const PasswordForm& form) { 40 void PasswordStore::AddLogin(const PasswordForm& form) {
24 Task* task = NewRunnableMethod(this, &PasswordStore::AddLoginImpl, form); 41 Task* task = NewRunnableMethod(this, &PasswordStore::AddLoginImpl, form);
25 ScheduleTask( 42 ScheduleTask(
(...skipping 14 matching lines...) Expand all
40 57
41 void PasswordStore::RemoveLoginsCreatedBetween(const base::Time& delete_begin, 58 void PasswordStore::RemoveLoginsCreatedBetween(const base::Time& delete_begin,
42 const base::Time& delete_end) { 59 const base::Time& delete_end) {
43 Task* task = NewRunnableMethod(this, 60 Task* task = NewRunnableMethod(this,
44 &PasswordStore::RemoveLoginsCreatedBetweenImpl, 61 &PasswordStore::RemoveLoginsCreatedBetweenImpl,
45 delete_begin, delete_end); 62 delete_begin, delete_end);
46 ScheduleTask( 63 ScheduleTask(
47 NewRunnableMethod(this, &PasswordStore::WrapModificationTask, task)); 64 NewRunnableMethod(this, &PasswordStore::WrapModificationTask, task));
48 } 65 }
49 66
50 int PasswordStore::GetLogins(const PasswordForm& form, 67 PasswordStore::Handle PasswordStore::GetLogins(
51 PasswordStoreConsumer* consumer) { 68 const PasswordForm& form, PasswordStoreConsumer* consumer) {
52 int handle = GetNewRequestHandle(); 69 return Schedule(&PasswordStore::GetLoginsImpl, consumer, form);
53 GetLoginsRequest* request = new GetLoginsRequest(consumer, handle);
54 ScheduleTask(NewRunnableMethod(this, &PasswordStore::GetLoginsImpl, request,
55 form));
56 return handle;
57 } 70 }
58 71
59 int PasswordStore::GetAutofillableLogins(PasswordStoreConsumer* consumer) { 72 PasswordStore::Handle PasswordStore::GetAutofillableLogins(
60 int handle = GetNewRequestHandle(); 73 PasswordStoreConsumer* consumer) {
61 GetLoginsRequest* request = new GetLoginsRequest(consumer, handle); 74 return Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer);
62 ScheduleTask(NewRunnableMethod(this,
63 &PasswordStore::GetAutofillableLoginsImpl,
64 request));
65 return handle;
66 } 75 }
67 76
68 int PasswordStore::GetBlacklistLogins(PasswordStoreConsumer* consumer) { 77 PasswordStore::Handle PasswordStore::GetBlacklistLogins(
69 int handle = GetNewRequestHandle(); 78 PasswordStoreConsumer* consumer) {
70 GetLoginsRequest* request = new GetLoginsRequest(consumer, handle); 79 return Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer);
71 ScheduleTask(NewRunnableMethod(this,
72 &PasswordStore::GetBlacklistLoginsImpl,
73 request));
74 return handle;
75 }
76
77 void PasswordStore::CancelLoginsQuery(int handle) {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
79 pending_requests_.erase(handle);
80 } 80 }
81 81
82 void PasswordStore::ReportMetrics() { 82 void PasswordStore::ReportMetrics() {
83 ScheduleTask(NewRunnableMethod(this, &PasswordStore::ReportMetricsImpl)); 83 ScheduleTask(NewRunnableMethod(this, &PasswordStore::ReportMetricsImpl));
84 } 84 }
85 85
86 void PasswordStore::AddObserver(Observer* observer) { 86 void PasswordStore::AddObserver(Observer* observer) {
87 observers_.AddObserver(observer); 87 observers_.AddObserver(observer);
88 } 88 }
89 89
90 void PasswordStore::RemoveObserver(Observer* observer) { 90 void PasswordStore::RemoveObserver(Observer* observer) {
91 observers_.RemoveObserver(observer); 91 observers_.RemoveObserver(observer);
92 } 92 }
93 93
94 PasswordStore::~PasswordStore() {} 94 PasswordStore::~PasswordStore() {}
95 95
96 PasswordStore::GetLoginsRequest::GetLoginsRequest(
97 PasswordStoreConsumer* consumer, int handle)
98 : consumer(consumer), handle(handle), message_loop(MessageLoop::current()) {
99 }
100
101 void PasswordStore::ScheduleTask(Task* task) { 96 void PasswordStore::ScheduleTask(Task* task) {
102 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task); 97 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task);
103 } 98 }
104 99 void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) {
105 void PasswordStore::NotifyConsumer(GetLoginsRequest* request, 100 request->ForwardResult(GetLoginsRequest::TupleType(request->handle(),
106 const vector<PasswordForm*>& forms) { 101 request->value));
107 scoped_ptr<GetLoginsRequest> request_ptr(request);
108
109 #if !defined(OS_MACOSX)
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
111 #endif
112 request->message_loop->PostTask(
113 FROM_HERE,
114 NewRunnableMethod(this,
115 &PasswordStore::NotifyConsumerImpl,
116 request->consumer, request->handle, forms));
117 } 102 }
118 103
119 void PasswordStore::NotifyConsumerImpl(PasswordStoreConsumer* consumer, 104 template<typename BackendFunc>
120 int handle, 105 PasswordStore::Handle PasswordStore::Schedule(
121 const vector<PasswordForm*>& forms) { 106 BackendFunc func, PasswordStoreConsumer* consumer) {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 107 scoped_refptr<GetLoginsRequest> request(new GetLoginsRequest(
123 // Don't notify the consumer if the request was canceled. 108 NewCallback(consumer,
124 if (pending_requests_.find(handle) == pending_requests_.end()) { 109 &PasswordStoreConsumer::OnPasswordStoreRequestDone)));
125 // |forms| is const so we iterate rather than use STLDeleteElements(). 110 AddRequest(request, consumer->cancelable_consumer());
126 for (size_t i = 0; i < forms.size(); ++i) 111 ScheduleTask(NewRunnableMethod(this, func, request));
127 delete forms[i]; 112 return request->handle();
128 return;
129 }
130 pending_requests_.erase(handle);
131
132 consumer->OnPasswordStoreRequestDone(handle, forms);
133 } 113 }
134 114
135 int PasswordStore::GetNewRequestHandle() { 115 template<typename BackendFunc, typename ArgA>
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 116 PasswordStore::Handle PasswordStore::Schedule(
137 int handle = handle_++; 117 BackendFunc func, PasswordStoreConsumer* consumer, const ArgA& a) {
138 pending_requests_.insert(handle); 118 scoped_refptr<GetLoginsRequest> request(new GetLoginsRequest(
139 return handle; 119 NewCallback(consumer,
120 &PasswordStoreConsumer::OnPasswordStoreRequestDone)));
121 AddRequest(request, consumer->cancelable_consumer());
122 ScheduleTask(NewRunnableMethod(this, func, request, a));
123 return request->handle();
140 } 124 }
141 125
142 void PasswordStore::WrapModificationTask(Task* task) { 126 void PasswordStore::WrapModificationTask(Task* task) {
143 #if !defined(OS_MACOSX) 127 #if !defined(OS_MACOSX)
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
145 #endif // !defined(OS_MACOSX) 129 #endif // !defined(OS_MACOSX)
146 130
147 DCHECK(task); 131 DCHECK(task);
148 task->Run(); 132 task->Run();
149 delete task; 133 delete task;
150 134
151 BrowserThread::PostTask( 135 BrowserThread::PostTask(
152 BrowserThread::UI, FROM_HERE, 136 BrowserThread::UI, FROM_HERE,
153 NewRunnableMethod(this, &PasswordStore::NotifyLoginsChanged)); 137 NewRunnableMethod(this, &PasswordStore::NotifyLoginsChanged));
154 } 138 }
155 139
156 void PasswordStore::NotifyLoginsChanged() { 140 void PasswordStore::NotifyLoginsChanged() {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
158 FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged()); 142 FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged());
159 } 143 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698