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

Side by Side Diff: chrome/browser/login_prompt_win.cc

Issue 345037: Fifth patch in getting rid of caching MessageLoop pointers. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/login_prompt.h" 5 #include "chrome/browser/login_prompt.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "base/message_loop.h" 8 #include "chrome/browser/chrome_thread.h"
9 #include "chrome/browser/password_manager/password_manager.h" 9 #include "chrome/browser/password_manager/password_manager.h"
10 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" 10 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
11 #include "chrome/browser/tab_contents/navigation_controller.h" 11 #include "chrome/browser/tab_contents/navigation_controller.h"
12 #include "chrome/browser/tab_contents/tab_contents.h" 12 #include "chrome/browser/tab_contents/tab_contents.h"
13 #include "chrome/browser/tab_contents/tab_util.h" 13 #include "chrome/browser/tab_contents/tab_util.h"
14 #include "chrome/browser/views/login_view.h" 14 #include "chrome/browser/views/login_view.h"
15 #include "chrome/common/notification_service.h" 15 #include "chrome/common/notification_service.h"
16 #include "grit/generated_resources.h" 16 #include "grit/generated_resources.h"
17 #include "net/url_request/url_request.h" 17 #include "net/url_request/url_request.h"
18 #include "views/window/dialog_delegate.h" 18 #include "views/window/dialog_delegate.h"
19 19
20 using webkit_glue::PasswordForm; 20 using webkit_glue::PasswordForm;
21 21
22 // ---------------------------------------------------------------------------- 22 // ----------------------------------------------------------------------------
23 // LoginHandlerWin 23 // LoginHandlerWin
24 24
25 // This class simply forwards the authentication from the LoginView (on 25 // This class simply forwards the authentication from the LoginView (on
26 // the UI thread) to the URLRequest (on the I/O thread). 26 // the UI thread) to the URLRequest (on the I/O thread).
27 // This class uses ref counting to ensure that it lives until all InvokeLaters 27 // This class uses ref counting to ensure that it lives until all InvokeLaters
28 // have been called. 28 // have been called.
29 class LoginHandlerWin : public LoginHandler, 29 class LoginHandlerWin : public LoginHandler,
30 public base::RefCountedThreadSafe<LoginHandlerWin>, 30 public base::RefCountedThreadSafe<LoginHandlerWin>,
31 public views::DialogDelegate { 31 public views::DialogDelegate {
32 public: 32 public:
33 LoginHandlerWin(URLRequest* request, MessageLoop* ui_loop) 33 LoginHandlerWin(URLRequest* request)
34 : dialog_(NULL), 34 : dialog_(NULL),
35 handled_auth_(false), 35 handled_auth_(false),
36 request_(request), 36 request_(request),
37 request_loop_(MessageLoop::current()),
38 ui_loop_(ui_loop),
39 password_manager_(NULL) { 37 password_manager_(NULL) {
40 DCHECK(request_) << "LoginHandler constructed with NULL request"; 38 DCHECK(request_) << "LoginHandler constructed with NULL request";
41 39
42 AddRef(); // matched by ReleaseLater. 40 AddRef(); // matched by ReleaseLater.
43 if (!ResourceDispatcherHost::RenderViewForRequest(request_, 41 if (!ResourceDispatcherHost::RenderViewForRequest(request_,
44 &render_process_host_id_, 42 &render_process_host_id_,
45 &tab_contents_id_)) { 43 &tab_contents_id_)) {
46 NOTREACHED(); 44 NOTREACHED();
47 } 45 }
48 } 46 }
49 47
50 ~LoginHandlerWin() { 48 ~LoginHandlerWin() {
51 } 49 }
52 50
53 void set_login_view(LoginView* login_view) { 51 void set_login_view(LoginView* login_view) {
54 login_view_ = login_view; 52 login_view_ = login_view;
55 } 53 }
56 54
57 // views::DialogDelegate methods: 55 // views::DialogDelegate methods:
58 virtual std::wstring GetDialogButtonLabel( 56 virtual std::wstring GetDialogButtonLabel(
59 MessageBoxFlags::DialogButton button) const { 57 MessageBoxFlags::DialogButton button) const {
60 if (button == MessageBoxFlags::DIALOGBUTTON_OK) 58 if (button == MessageBoxFlags::DIALOGBUTTON_OK)
61 return l10n_util::GetString(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL); 59 return l10n_util::GetString(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL);
62 return DialogDelegate::GetDialogButtonLabel(button); 60 return DialogDelegate::GetDialogButtonLabel(button);
63 } 61 }
64 virtual std::wstring GetWindowTitle() const { 62 virtual std::wstring GetWindowTitle() const {
65 return l10n_util::GetString(IDS_LOGIN_DIALOG_TITLE); 63 return l10n_util::GetString(IDS_LOGIN_DIALOG_TITLE);
66 } 64 }
67 virtual void WindowClosing() { 65 virtual void WindowClosing() {
68 DCHECK(MessageLoop::current() == ui_loop_); 66 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
69 67
70 // Reference is no longer valid. 68 // Reference is no longer valid.
71 dialog_ = NULL; 69 dialog_ = NULL;
72 70
73 if (!WasAuthHandled(true)) { 71 if (!WasAuthHandled(true)) {
74 request_loop_->PostTask(FROM_HERE, NewRunnableMethod( 72 ChromeThread::PostTask(
75 this, &LoginHandlerWin::CancelAuthDeferred)); 73 ChromeThread::IO, FROM_HERE,
74 NewRunnableMethod(this, &LoginHandlerWin::CancelAuthDeferred));
76 SendNotifications(); 75 SendNotifications();
77 } 76 }
78 } 77 }
79 virtual void DeleteDelegate() { 78 virtual void DeleteDelegate() {
80 // Delete this object once all InvokeLaters have been called. 79 // Delete this object once all InvokeLaters have been called.
81 request_loop_->ReleaseSoon(FROM_HERE, this); 80 ChromeThread::ReleaseSoon(ChromeThread::IO, FROM_HERE, this);
82 } 81 }
83 virtual bool Cancel() { 82 virtual bool Cancel() {
84 DCHECK(MessageLoop::current() == ui_loop_); 83 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
85 DCHECK(dialog_) << "LoginHandler invoked without being attached"; 84 DCHECK(dialog_) << "LoginHandler invoked without being attached";
86 CancelAuth(); 85 CancelAuth();
87 return true; 86 return true;
88 } 87 }
89 virtual bool Accept() { 88 virtual bool Accept() {
90 DCHECK(MessageLoop::current() == ui_loop_); 89 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
91 DCHECK(dialog_) << "LoginHandler invoked without being attached"; 90 DCHECK(dialog_) << "LoginHandler invoked without being attached";
92 SetAuth(login_view_->GetUsername(), login_view_->GetPassword()); 91 SetAuth(login_view_->GetUsername(), login_view_->GetPassword());
93 return true; 92 return true;
94 } 93 }
95 virtual views::View* GetContentsView() { 94 virtual views::View* GetContentsView() {
96 return login_view_; 95 return login_view_;
97 } 96 }
98 97
99 // LoginHandler: 98 // LoginHandler:
100 99
101 virtual void BuildViewForPasswordManager(PasswordManager* manager, 100 virtual void BuildViewForPasswordManager(PasswordManager* manager,
102 std::wstring explanation) { 101 std::wstring explanation) {
103 DCHECK(MessageLoop::current() == ui_loop_); 102 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
104 103
105 LoginView* view = new LoginView(explanation); 104 LoginView* view = new LoginView(explanation);
106 105
107 // Set the model for the login view. The model (password manager) is owned 106 // Set the model for the login view. The model (password manager) is owned
108 // by the view's parent TabContents, so natural destruction order means we 107 // by the view's parent TabContents, so natural destruction order means we
109 // don't have to worry about calling SetModel(NULL), because the view will 108 // don't have to worry about calling SetModel(NULL), because the view will
110 // be deleted before the password manager. 109 // be deleted before the password manager.
111 view->SetModel(manager); 110 view->SetModel(manager);
112 111
113 set_login_view(view); 112 set_login_view(view);
114 113
115 // Scary thread safety note: This can potentially be called *after* SetAuth 114 // Scary thread safety note: This can potentially be called *after* SetAuth
116 // or CancelAuth (say, if the request was cancelled before the UI thread got 115 // or CancelAuth (say, if the request was cancelled before the UI thread got
117 // control). However, that's OK since any UI interaction in those functions 116 // control). However, that's OK since any UI interaction in those functions
118 // will occur via an InvokeLater on the UI thread, which is guaranteed 117 // will occur via an InvokeLater on the UI thread, which is guaranteed
119 // to happen after this is called (since this was InvokeLater'd first). 118 // to happen after this is called (since this was InvokeLater'd first).
120 dialog_ = GetTabContentsForLogin()->CreateConstrainedDialog(this); 119 dialog_ = GetTabContentsForLogin()->CreateConstrainedDialog(this);
121 SendNotifications(); 120 SendNotifications();
122 } 121 }
123 122
124 virtual void SetPasswordForm(const webkit_glue::PasswordForm& form) { 123 virtual void SetPasswordForm(const webkit_glue::PasswordForm& form) {
125 password_form_ = form; 124 password_form_ = form;
126 } 125 }
127 126
128 virtual void SetPasswordManager(PasswordManager* password_manager) { 127 virtual void SetPasswordManager(PasswordManager* password_manager) {
129 password_manager_ = password_manager; 128 password_manager_ = password_manager;
130 } 129 }
131 130
132 virtual TabContents* GetTabContentsForLogin() { 131 virtual TabContents* GetTabContentsForLogin() {
133 DCHECK(MessageLoop::current() == ui_loop_); 132 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
134 133
135 return tab_util::GetTabContentsByID(render_process_host_id_, 134 return tab_util::GetTabContentsByID(render_process_host_id_,
136 tab_contents_id_); 135 tab_contents_id_);
137 } 136 }
138 137
139 virtual void SetAuth(const std::wstring& username, 138 virtual void SetAuth(const std::wstring& username,
140 const std::wstring& password) { 139 const std::wstring& password) {
141 if (WasAuthHandled(true)) 140 if (WasAuthHandled(true))
142 return; 141 return;
143 142
144 // Tell the password manager the credentials were submitted / accepted. 143 // Tell the password manager the credentials were submitted / accepted.
145 if (password_manager_) { 144 if (password_manager_) {
146 password_form_.username_value = username; 145 password_form_.username_value = username;
147 password_form_.password_value = password; 146 password_form_.password_value = password;
148 password_manager_->ProvisionallySavePassword(password_form_); 147 password_manager_->ProvisionallySavePassword(password_form_);
149 } 148 }
150 149
151 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 150 ChromeThread::PostTask(
152 this, &LoginHandlerWin::CloseContentsDeferred)); 151 ChromeThread::UI, FROM_HERE,
153 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 152 NewRunnableMethod(this, &LoginHandlerWin::CloseContentsDeferred));
154 this, &LoginHandlerWin::SendNotifications)); 153 ChromeThread::PostTask(
155 request_loop_->PostTask(FROM_HERE, NewRunnableMethod( 154 ChromeThread::UI, FROM_HERE,
156 this, &LoginHandlerWin::SetAuthDeferred, username, password)); 155 NewRunnableMethod(this, &LoginHandlerWin::SendNotifications));
156 ChromeThread::PostTask(
157 ChromeThread::IO, FROM_HERE,
158 NewRunnableMethod(
159 this, &LoginHandlerWin::SetAuthDeferred, username, password));
157 } 160 }
158 161
159 virtual void CancelAuth() { 162 virtual void CancelAuth() {
160 if (WasAuthHandled(true)) 163 if (WasAuthHandled(true))
161 return; 164 return;
162 165
163 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 166 ChromeThread::PostTask(
164 this, &LoginHandlerWin::CloseContentsDeferred)); 167 ChromeThread::UI, FROM_HERE,
165 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 168 NewRunnableMethod(this, &LoginHandlerWin::CloseContentsDeferred));
166 this, &LoginHandlerWin::SendNotifications)); 169 ChromeThread::PostTask(
167 request_loop_->PostTask(FROM_HERE, NewRunnableMethod( 170 ChromeThread::UI, FROM_HERE,
168 this, &LoginHandlerWin::CancelAuthDeferred)); 171 NewRunnableMethod(this, &LoginHandlerWin::SendNotifications));
172 ChromeThread::PostTask(
173 ChromeThread::IO, FROM_HERE,
174 NewRunnableMethod(this, &LoginHandlerWin::CancelAuthDeferred));
169 } 175 }
170 176
171 virtual void OnRequestCancelled() { 177 virtual void OnRequestCancelled() {
172 DCHECK(MessageLoop::current() == request_loop_) << 178 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)) <<
173 "Why is OnRequestCancelled called from the UI thread?"; 179 "Why is OnRequestCancelled called from the UI thread?";
174 180
175 // Reference is no longer valid. 181 // Reference is no longer valid.
176 request_ = NULL; 182 request_ = NULL;
177 183
178 // Give up on auth if the request was cancelled. 184 // Give up on auth if the request was cancelled.
179 CancelAuth(); 185 CancelAuth();
180 } 186 }
181 187
182 private: 188 private:
183 friend class LoginPrompt; 189 friend class LoginPrompt;
184 190
185 // Calls SetAuth from the request_loop. 191 // Calls SetAuth from the IO loop.
186 void SetAuthDeferred(const std::wstring& username, 192 void SetAuthDeferred(const std::wstring& username,
187 const std::wstring& password) { 193 const std::wstring& password) {
188 DCHECK(MessageLoop::current() == request_loop_); 194 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
189 195
190 if (request_) { 196 if (request_) {
191 request_->SetAuth(username, password); 197 request_->SetAuth(username, password);
192 ResetLoginHandlerForRequest(request_); 198 ResetLoginHandlerForRequest(request_);
193 } 199 }
194 } 200 }
195 201
196 // Calls CancelAuth from the request_loop. 202 // Calls CancelAuth from the IO loop.
197 void CancelAuthDeferred() { 203 void CancelAuthDeferred() {
198 DCHECK(MessageLoop::current() == request_loop_); 204 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
199 205
200 if (request_) { 206 if (request_) {
201 request_->CancelAuth(); 207 request_->CancelAuth();
202 // Verify that CancelAuth does destroy the request via our delegate. 208 // Verify that CancelAuth does destroy the request via our delegate.
203 DCHECK(request_ != NULL); 209 DCHECK(request_ != NULL);
204 ResetLoginHandlerForRequest(request_); 210 ResetLoginHandlerForRequest(request_);
205 } 211 }
206 } 212 }
207 213
208 // Closes the view_contents from the UI loop. 214 // Closes the view_contents from the UI loop.
209 void CloseContentsDeferred() { 215 void CloseContentsDeferred() {
210 DCHECK(MessageLoop::current() == ui_loop_); 216 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
211 217
212 // The hosting ConstrainedWindow may have been freed. 218 // The hosting ConstrainedWindow may have been freed.
213 if (dialog_) 219 if (dialog_)
214 dialog_->CloseConstrainedWindow(); 220 dialog_->CloseConstrainedWindow();
215 } 221 }
216 222
217 // Returns whether authentication had been handled (SetAuth or CancelAuth). 223 // Returns whether authentication had been handled (SetAuth or CancelAuth).
218 // If |set_handled| is true, it will mark authentication as handled. 224 // If |set_handled| is true, it will mark authentication as handled.
219 bool WasAuthHandled(bool set_handled) { 225 bool WasAuthHandled(bool set_handled) {
220 AutoLock lock(handled_auth_lock_); 226 AutoLock lock(handled_auth_lock_);
221 bool was_handled = handled_auth_; 227 bool was_handled = handled_auth_;
222 if (set_handled) 228 if (set_handled)
223 handled_auth_ = true; 229 handled_auth_ = true;
224 return was_handled; 230 return was_handled;
225 } 231 }
226 232
227 // Notify observers that authentication is needed or received. The automation 233 // Notify observers that authentication is needed or received. The automation
228 // proxy uses this for testing. 234 // proxy uses this for testing.
229 void SendNotifications() { 235 void SendNotifications() {
230 DCHECK(MessageLoop::current() == ui_loop_); 236 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
231 237
232 NotificationService* service = NotificationService::current(); 238 NotificationService* service = NotificationService::current();
233 TabContents* requesting_contents = GetTabContentsForLogin(); 239 TabContents* requesting_contents = GetTabContentsForLogin();
234 if (!requesting_contents) 240 if (!requesting_contents)
235 return; 241 return;
236 242
237 NavigationController* controller = &requesting_contents->controller(); 243 NavigationController* controller = &requesting_contents->controller();
238 244
239 if (!WasAuthHandled(false)) { 245 if (!WasAuthHandled(false)) {
240 LoginNotificationDetails details(this); 246 LoginNotificationDetails details(this);
241 service->Notify(NotificationType::AUTH_NEEDED, 247 service->Notify(NotificationType::AUTH_NEEDED,
242 Source<NavigationController>(controller), 248 Source<NavigationController>(controller),
243 Details<LoginNotificationDetails>(&details)); 249 Details<LoginNotificationDetails>(&details));
244 } else { 250 } else {
245 service->Notify(NotificationType::AUTH_SUPPLIED, 251 service->Notify(NotificationType::AUTH_SUPPLIED,
246 Source<NavigationController>(controller), 252 Source<NavigationController>(controller),
247 NotificationService::NoDetails()); 253 NotificationService::NoDetails());
248 } 254 }
249 } 255 }
250 256
251 // True if we've handled auth (SetAuth or CancelAuth has been called). 257 // True if we've handled auth (SetAuth or CancelAuth has been called).
252 bool handled_auth_; 258 bool handled_auth_;
253 Lock handled_auth_lock_; 259 Lock handled_auth_lock_;
254 260
255 // The ConstrainedWindow that is hosting our LoginView. 261 // The ConstrainedWindow that is hosting our LoginView.
256 // This should only be accessed on the ui_loop_. 262 // This should only be accessed on the UI loop.
257 ConstrainedWindow* dialog_; 263 ConstrainedWindow* dialog_;
258 264
259 // The MessageLoop of the thread that the ChromeViewContents lives in.
260 MessageLoop* ui_loop_;
261
262 // The request that wants login data. 265 // The request that wants login data.
263 // This should only be accessed on the request_loop_. 266 // This should only be accessed on the IO loop.
264 URLRequest* request_; 267 URLRequest* request_;
265 268
266 // The MessageLoop of the thread that the URLRequest lives in.
267 MessageLoop* request_loop_;
268
269 // The LoginView that contains the user's login information 269 // The LoginView that contains the user's login information
270 LoginView* login_view_; 270 LoginView* login_view_;
271 271
272 // The PasswordForm sent to the PasswordManager. This is so we can refer to it 272 // The PasswordForm sent to the PasswordManager. This is so we can refer to it
273 // when later notifying the password manager if the credentials were accepted 273 // when later notifying the password manager if the credentials were accepted
274 // or rejected. 274 // or rejected.
275 // This should only be accessed on the ui_loop_. 275 // This should only be accessed on the UI loop.
276 PasswordForm password_form_; 276 PasswordForm password_form_;
277 277
278 // Points to the password manager owned by the TabContents requesting auth. 278 // Points to the password manager owned by the TabContents requesting auth.
279 // Can be null if the TabContents is not a TabContents. 279 // Can be null if the TabContents is not a TabContents.
280 // This should only be accessed on the ui_loop_. 280 // This should only be accessed on the UI loop.
281 PasswordManager* password_manager_; 281 PasswordManager* password_manager_;
282 282
283 // Cached from the URLRequest, in case it goes NULL on us. 283 // Cached from the URLRequest, in case it goes NULL on us.
284 int render_process_host_id_; 284 int render_process_host_id_;
285 int tab_contents_id_; 285 int tab_contents_id_;
286 286
287 DISALLOW_COPY_AND_ASSIGN(LoginHandlerWin); 287 DISALLOW_COPY_AND_ASSIGN(LoginHandlerWin);
288 }; 288 };
289 289
290 // static 290 // static
291 LoginHandler* LoginHandler::Create(URLRequest* request, MessageLoop* ui_loop) { 291 LoginHandler* LoginHandler::Create(URLRequest* request) {
292 return new LoginHandlerWin(request, ui_loop); 292 return new LoginHandlerWin(request);
293 } 293 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698