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

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

Issue 6646051: Fix DCHECK, memory leak, and refactor PasswordStore to use CancelableRequest (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Responding to review comments. 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 #ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_ 5 #ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_
6 #define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_ 6 #define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_
7 #pragma once 7 #pragma once
8 8
9 #include <set>
10 #include <vector> 9 #include <vector>
11 10
11 #include "base/callback.h"
12 #include "base/observer_list.h" 12 #include "base/observer_list.h"
13 #include "base/ref_counted.h" 13 #include "base/ref_counted.h"
14 #include "base/threading/thread.h" 14 #include "base/threading/thread.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "content/browser/cancelable_request.h"
16 #include "webkit/glue/password_form.h" 17 #include "webkit/glue/password_form.h"
17 18
18 class Profile;
James Hawkins 2011/03/21 01:45:06 Nice catch.
19 class Task; 19 class Task;
20 20
21 namespace browser_sync { 21 namespace browser_sync {
22 class PasswordDataTypeController; 22 class PasswordDataTypeController;
23 class PasswordModelAssociator; 23 class PasswordModelAssociator;
24 class PasswordModelWorker; 24 class PasswordModelWorker;
25 }; 25 };
26 26
27 // This abstract base class for consumers of PasswordStore calls that need
James Hawkins 2011/03/21 01:45:06 nit: This is quite a long sentence. Consider break
Sheridan Rawlins 2011/03/21 05:20:17 Done.
28 // asynchronous responses provides the CancelableRequestConsumer object which
29 // takes care of canceling any outstanding requests, should the consumer be
30 // destroyed before the response calls back.
27 class PasswordStoreConsumer { 31 class PasswordStoreConsumer {
James Hawkins 2011/03/21 01:45:06 Move this class to its own header.
Sheridan Rawlins 2011/03/21 05:20:17 This is fairly tricky, due to PasswordStore provid
28 public: 32 public:
29 virtual ~PasswordStoreConsumer() {} 33 virtual ~PasswordStoreConsumer() {}
James Hawkins 2011/03/21 01:45:06 Make the destructor protected.
Sheridan Rawlins 2011/03/21 05:20:17 Done.
30 // Call this when the request is finished. If there are no results, call it 34 // Call this when the request is finished. If there are no results, call it
31 // anyway with an empty vector. 35 // anyway with an empty vector.
32 virtual void OnPasswordStoreRequestDone( 36 virtual void OnPasswordStoreRequestDone(
33 int handle, const std::vector<webkit_glue::PasswordForm*>& result) = 0; 37 CancelableRequestProvider::Handle handle,
38 const std::vector<webkit_glue::PasswordForm*>& result) = 0;
39
40 // The CancelableRequest framework needs both a callback (the
41 // PasswordStoreConsumer::OnPasswordStoreRequestDone) as well as a
42 // CancelableRequestConsumer. This accessor makes the API simpler for callers
43 // as PasswordStore can get both from the PasswordStoreConsumer.
44 CancelableRequestConsumerBase* cancelable_consumer() {
45 return &cancelable_consumer_;
46 }
47
48 private:
49 CancelableRequestConsumer cancelable_consumer_;
34 }; 50 };
35 51
36 // Interface for storing form passwords in a platform-specific secure way. 52 // Interface for storing form passwords in a platform-specific secure way.
37 // The login request/manipulation API is not threadsafe and must be used 53 // The login request/manipulation API is not threadsafe and must be used
38 // from the UI thread. 54 // from the UI thread.
39 class PasswordStore : public base::RefCountedThreadSafe<PasswordStore> { 55 class PasswordStore
56 : public base::RefCountedThreadSafe<PasswordStore>,
57 public CancelableRequestProvider {
40 public: 58 public:
59 typedef Callback2<Handle,
60 const std::vector<webkit_glue::PasswordForm*>&>::Type
61 GetLoginsCallback;
62
63 // PasswordForm vector elements are meant to be owned (i.e. deleted) by the
James Hawkins 2011/03/21 01:45:06 nit: You don't need to clarify this: "i.e. deleted
Sheridan Rawlins 2011/03/21 05:20:17 Done.
64 // PasswordStoreConsumer. However, if the request is canceled after the
James Hawkins 2011/03/21 01:45:06 nit: Single space between sentences.
Sheridan Rawlins 2011/03/21 05:20:17 Done.
65 // allocation, then the request must take care of the deletion.
66 // TODO(scr) If we can convert vector<PasswordForm*> to
67 // ScopedVector<PasswordForm>, then we can move the following class to merely
68 // a typedef. At the moment, a subclass of CancelableRequest1 is required to
69 // provide a destructor, which cleans up after canceled requests by deleting
70 // vector elements.
71 class GetLoginsRequest : public CancelableRequest1<
72 GetLoginsCallback, std::vector<webkit_glue::PasswordForm*> > {
73 public:
74 explicit GetLoginsRequest(GetLoginsCallback* callback);
75 virtual ~GetLoginsRequest();
76
77 private:
78 DISALLOW_COPY_AND_ASSIGN(GetLoginsRequest);
79 };
80
41 // An interface used to notify clients (observers) of this object that data in 81 // An interface used to notify clients (observers) of this object that data in
42 // the password store has changed. Register the observer via 82 // the password store has changed. Register the observer via
43 // PasswordStore::SetObserver. 83 // PasswordStore::SetObserver.
44 class Observer { 84 class Observer {
45 public: 85 public:
46 // Notifies the observer that password data changed in some way. 86 // Notifies the observer that password data changed in some way.
47 virtual void OnLoginsChanged() = 0; 87 virtual void OnLoginsChanged() = 0;
48 88
49 protected: 89 protected:
50 virtual ~Observer() {} 90 virtual ~Observer() {}
(...skipping 11 matching lines...) Expand all
62 void UpdateLogin(const webkit_glue::PasswordForm& form); 102 void UpdateLogin(const webkit_glue::PasswordForm& form);
63 103
64 // Removes the matching PasswordForm from the secure password store (async). 104 // Removes the matching PasswordForm from the secure password store (async).
65 void RemoveLogin(const webkit_glue::PasswordForm& form); 105 void RemoveLogin(const webkit_glue::PasswordForm& form);
66 106
67 // Removes all logins created in the given date range. 107 // Removes all logins created in the given date range.
68 void RemoveLoginsCreatedBetween(const base::Time& delete_begin, 108 void RemoveLoginsCreatedBetween(const base::Time& delete_begin,
69 const base::Time& delete_end); 109 const base::Time& delete_end);
70 110
71 // Searches for a matching PasswordForm and returns a handle so the async 111 // Searches for a matching PasswordForm and returns a handle so the async
72 // request can be tracked. Implement the PasswordStoreConsumer interface to 112 // request can be tracked. Implement the Consumer interface to be
James Hawkins 2011/03/21 01:45:06 Why have you made this ambiguous? Isn't it actuall
Sheridan Rawlins 2011/03/21 05:20:17 Nice catch - that was a search/replace artifact -
73 // be notified on completion. 113 // notified on completion.
74 virtual int GetLogins(const webkit_glue::PasswordForm& form, 114 virtual Handle GetLogins(const webkit_glue::PasswordForm& form,
75 PasswordStoreConsumer* consumer); 115 PasswordStoreConsumer* consumer);
76 116
77 // Gets the complete list of PasswordForms that are not blacklist entries--and 117 // Gets the complete list of PasswordForms that are not blacklist entries--and
78 // are thus auto-fillable--and returns a handle so the async request can be 118 // are thus auto-fillable--and returns a handle so the async request can be
79 // tracked. Implement the PasswordStoreConsumer interface to be notified 119 // tracked. Implement the PasswordStoreConsumer interface to be notified on
80 // on completion. 120 // completion.
81 int GetAutofillableLogins(PasswordStoreConsumer* consumer); 121 Handle GetAutofillableLogins(PasswordStoreConsumer* consumer);
82 122
83 // Gets the complete list of PasswordForms that are blacklist entries, and 123 // Gets the complete list of PasswordForms that are blacklist entries, and
84 // returns a handle so the async request can be tracked. Implement the 124 // returns a handle so the async request can be tracked. Implement the
85 // PasswordStoreConsumer interface to be notified on completion. 125 // PasswordStoreConsumer interface to be notified on completion.
86 int GetBlacklistLogins(PasswordStoreConsumer* consumer); 126 Handle GetBlacklistLogins(PasswordStoreConsumer* consumer);
87
88 // Cancels a previous Get*Logins query (async)
89 void CancelLoginsQuery(int handle);
90 127
91 // Reports usage metrics for the database. 128 // Reports usage metrics for the database.
92 void ReportMetrics(); 129 void ReportMetrics();
93 130
94 // Adds an observer to be notified when the password store data changes. 131 // Adds an observer to be notified when the password store data changes.
95 void AddObserver(Observer* observer); 132 void AddObserver(Observer* observer);
96 133
97 // Removes |observer| from the observer list. 134 // Removes |observer| from the observer list.
98 void RemoveObserver(Observer* observer); 135 void RemoveObserver(Observer* observer);
99 136
100 protected: 137 protected:
101 friend class base::RefCountedThreadSafe<PasswordStore>; 138 friend class base::RefCountedThreadSafe<PasswordStore>;
102 friend class browser_sync::PasswordDataTypeController; 139 friend class browser_sync::PasswordDataTypeController;
103 friend class browser_sync::PasswordModelAssociator; 140 friend class browser_sync::PasswordModelAssociator;
104 friend class browser_sync::PasswordModelWorker; 141 friend class browser_sync::PasswordModelWorker;
105 friend class LivePasswordsSyncTest; 142 friend class LivePasswordsSyncTest;
106 143
107 virtual ~PasswordStore(); 144 virtual ~PasswordStore();
108 145
109 // Simple container class that represents a login lookup request. 146 // Schedule the given |task| to be run in the PasswordStore's own thread.
110 class GetLoginsRequest {
111 public:
112 GetLoginsRequest(PasswordStoreConsumer* c,
113 int handle);
114
115 // The consumer to notify when this request is complete.
116 PasswordStoreConsumer* consumer;
117 // A unique handle for the request
118 int handle;
119 // The message loop that the request was made from. We send the result
120 // back to the consumer in this same message loop.
121 MessageLoop* message_loop;
122
123 private:
124 DISALLOW_COPY_AND_ASSIGN(GetLoginsRequest);
125 };
126
127 // Schedule the given task to be run in the PasswordStore's own thread.
128 virtual void ScheduleTask(Task* task); 147 virtual void ScheduleTask(Task* task);
129 148
130 // These will be run in PasswordStore's own thread. 149 // These will be run in PasswordStore's own thread.
131 // Synchronous implementation that reports usage metrics. 150 // Synchronous implementation that reports usage metrics.
132 virtual void ReportMetricsImpl() = 0; 151 virtual void ReportMetricsImpl() = 0;
133 // Synchronous implementation to add the given login. 152 // Synchronous implementation to add the given login.
134 virtual void AddLoginImpl(const webkit_glue::PasswordForm& form) = 0; 153 virtual void AddLoginImpl(const webkit_glue::PasswordForm& form) = 0;
135 // Synchronous implementation to update the given login. 154 // Synchronous implementation to update the given login.
136 virtual void UpdateLoginImpl(const webkit_glue::PasswordForm& form) = 0; 155 virtual void UpdateLoginImpl(const webkit_glue::PasswordForm& form) = 0;
137 // Synchronous implementation to remove the given login. 156 // Synchronous implementation to remove the given login.
(...skipping 11 matching lines...) Expand all
149 // Finds all blacklist PasswordForms, and notifies the consumer. 168 // Finds all blacklist PasswordForms, and notifies the consumer.
150 virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0; 169 virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0;
151 170
152 // Finds all non-blacklist PasswordForms, and fills the vector. 171 // Finds all non-blacklist PasswordForms, and fills the vector.
153 virtual bool FillAutofillableLogins( 172 virtual bool FillAutofillableLogins(
154 std::vector<webkit_glue::PasswordForm*>* forms) = 0; 173 std::vector<webkit_glue::PasswordForm*>* forms) = 0;
155 // Finds all blacklist PasswordForms, and fills the vector. 174 // Finds all blacklist PasswordForms, and fills the vector.
156 virtual bool FillBlacklistLogins( 175 virtual bool FillBlacklistLogins(
157 std::vector<webkit_glue::PasswordForm*>* forms) = 0; 176 std::vector<webkit_glue::PasswordForm*>* forms) = 0;
158 177
159 // Notifies the consumer that a Get*Logins() request is complete. 178 // Dispatches the result to the PasswordStoreConsumer on the correct thread so
James Hawkins 2011/03/21 01:45:06 Which thread is the correct thread?
Sheridan Rawlins 2011/03/21 05:20:17 The original caller's thread (UI, in our case).
160 virtual void NotifyConsumer( 179 // the callback can be executed there using
161 GetLoginsRequest* request, 180 // CancelableRequestProvider::ForwardResult.
162 const std::vector<webkit_glue::PasswordForm*>& forms); 181 virtual void ForwardLoginsResult(GetLoginsRequest* request);
182
183 // Schedule the given |func| to be run in the PasswordStore's own thread with
184 // responses delivered to |consumer| on the current thread.
185 template<typename BackendFunc>
186 Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer);
187
188 // Schedule the given |func| to be run in the PasswordStore's own thread with
189 // argument |a| and responses delivered to |consumer| on the current thread.
190 template<typename BackendFunc, typename ArgA>
191 Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer,
192 const ArgA& a);
163 193
164 private: 194 private:
165 // Called by NotifyConsumer, but runs in the consumer's thread. Will not
166 // call the consumer if the request was canceled. This extra layer is here so
167 // that PasswordStoreConsumer doesn't have to be reference counted (we assume
168 // consumers will cancel their requests before they are destroyed).
169 void NotifyConsumerImpl(PasswordStoreConsumer* consumer, int handle,
170 const std::vector<webkit_glue::PasswordForm*>& forms);
171
172 // Returns a new request handle tracked in pending_requests_.
173 int GetNewRequestHandle();
174
175 // Wrapper method called on the destination thread (DB for non-mac) that calls 195 // Wrapper method called on the destination thread (DB for non-mac) that calls
176 // the method specified in |task| and then calls back into the source thread 196 // the method specified in |task| and then calls back into the source thread
177 // to notify observers that the password store may have been modified via 197 // to notify observers that the password store may have been modified via
178 // NotifyLoginsChanged(). Note that there is no guarantee that the called 198 // NotifyLoginsChanged(). Note that there is no guarantee that the called
179 // method will actually modify the password store data. |task| may not be 199 // method will actually modify the password store data. |task| may not be
180 // NULL. This method owns and will delete |task|. 200 // NULL. This method owns and will delete |task|.
181 void WrapModificationTask(Task* task); 201 void WrapModificationTask(Task* task);
182 202
183 // Called by WrapModificationTask() once the underlying data-modifying 203 // Called by WrapModificationTask() once the underlying data-modifying
184 // operation has been performed. Notifies observers that password store data 204 // operation has been performed. Notifies observers that password store data
185 // may have been changed. 205 // may have been changed.
186 void NotifyLoginsChanged(); 206 void NotifyLoginsChanged();
187 207
188 // Next handle to return from Get*Logins() to allow callers to track
189 // their request.
190 int handle_;
191
192 // List of pending request handles. Handles are removed from the set when
193 // they finish or are canceled.
194 std::set<int> pending_requests_;
195
196 // The observers. 208 // The observers.
197 ObserverList<Observer> observers_; 209 ObserverList<Observer> observers_;
198 210
199 DISALLOW_COPY_AND_ASSIGN(PasswordStore); 211 DISALLOW_COPY_AND_ASSIGN(PasswordStore);
200 }; 212 };
201 213
202 #endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_ 214 #endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698