OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/login/login_prompt.h" | 5 #include "chrome/browser/ui/login/login_prompt.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 BrowserThread::PostTask( | 98 BrowserThread::PostTask( |
99 BrowserThread::UI, FROM_HERE, | 99 BrowserThread::UI, FROM_HERE, |
100 base::Bind(&LoginHandler::AddObservers, this)); | 100 base::Bind(&LoginHandler::AddObservers, this)); |
101 | 101 |
102 if (!ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderView( | 102 if (!ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderView( |
103 &render_process_host_id_, &tab_contents_id_)) { | 103 &render_process_host_id_, &tab_contents_id_)) { |
104 NOTREACHED(); | 104 NOTREACHED(); |
105 } | 105 } |
106 } | 106 } |
107 | 107 |
108 LoginHandler::~LoginHandler() { | 108 void LoginHandler::OnRequestCancelled() { |
109 SetModel(NULL); | 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << |
| 110 "Why is OnRequestCancelled called from the UI thread?"; |
| 111 |
| 112 // Reference is no longer valid. |
| 113 request_ = NULL; |
| 114 |
| 115 // Give up on auth if the request was cancelled. |
| 116 CancelAuth(); |
110 } | 117 } |
111 | 118 |
112 void LoginHandler::SetPasswordForm(const webkit::forms::PasswordForm& form) { | 119 void LoginHandler::SetPasswordForm(const webkit::forms::PasswordForm& form) { |
113 password_form_ = form; | 120 password_form_ = form; |
114 } | 121 } |
115 | 122 |
116 void LoginHandler::SetPasswordManager(PasswordManager* password_manager) { | 123 void LoginHandler::SetPasswordManager(PasswordManager* password_manager) { |
117 password_manager_ = password_manager; | 124 password_manager_ = password_manager; |
118 } | 125 } |
119 | 126 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 } | 184 } |
178 | 185 |
179 BrowserThread::PostTask( | 186 BrowserThread::PostTask( |
180 BrowserThread::UI, FROM_HERE, | 187 BrowserThread::UI, FROM_HERE, |
181 base::Bind(&LoginHandler::CloseContentsDeferred, this)); | 188 base::Bind(&LoginHandler::CloseContentsDeferred, this)); |
182 BrowserThread::PostTask( | 189 BrowserThread::PostTask( |
183 BrowserThread::IO, FROM_HERE, | 190 BrowserThread::IO, FROM_HERE, |
184 base::Bind(&LoginHandler::CancelAuthDeferred, this)); | 191 base::Bind(&LoginHandler::CancelAuthDeferred, this)); |
185 } | 192 } |
186 | 193 |
187 void LoginHandler::OnRequestCancelled() { | |
188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << | |
189 "Why is OnRequestCancelled called from the UI thread?"; | |
190 | |
191 // Reference is no longer valid. | |
192 request_ = NULL; | |
193 | |
194 // Give up on auth if the request was cancelled. | |
195 CancelAuth(); | |
196 } | |
197 | |
198 void LoginHandler::AddObservers() { | |
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
200 | |
201 // This is probably OK; we need to listen to everything and we break out of | |
202 // the Observe() if we aren't handling the same auth_info(). | |
203 registrar_.reset(new content::NotificationRegistrar); | |
204 registrar_->Add(this, chrome::NOTIFICATION_AUTH_SUPPLIED, | |
205 content::NotificationService::AllBrowserContextsAndSources()); | |
206 registrar_->Add(this, chrome::NOTIFICATION_AUTH_CANCELLED, | |
207 content::NotificationService::AllBrowserContextsAndSources()); | |
208 } | |
209 | |
210 void LoginHandler::RemoveObservers() { | |
211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
212 | |
213 registrar_.reset(); | |
214 } | |
215 | 194 |
216 void LoginHandler::Observe(int type, | 195 void LoginHandler::Observe(int type, |
217 const content::NotificationSource& source, | 196 const content::NotificationSource& source, |
218 const content::NotificationDetails& details) { | 197 const content::NotificationDetails& details) { |
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
220 DCHECK(type == chrome::NOTIFICATION_AUTH_SUPPLIED || | 199 DCHECK(type == chrome::NOTIFICATION_AUTH_SUPPLIED || |
221 type == chrome::NOTIFICATION_AUTH_CANCELLED); | 200 type == chrome::NOTIFICATION_AUTH_CANCELLED); |
222 | 201 |
223 WebContents* requesting_contents = GetWebContentsForLogin(); | 202 WebContents* requesting_contents = GetWebContentsForLogin(); |
224 if (!requesting_contents) | 203 if (!requesting_contents) |
(...skipping 23 matching lines...) Expand all Loading... |
248 if (type == chrome::NOTIFICATION_AUTH_SUPPLIED) { | 227 if (type == chrome::NOTIFICATION_AUTH_SUPPLIED) { |
249 AuthSuppliedLoginNotificationDetails* supplied_details = | 228 AuthSuppliedLoginNotificationDetails* supplied_details = |
250 content::Details<AuthSuppliedLoginNotificationDetails>(details).ptr(); | 229 content::Details<AuthSuppliedLoginNotificationDetails>(details).ptr(); |
251 SetAuth(supplied_details->username(), supplied_details->password()); | 230 SetAuth(supplied_details->username(), supplied_details->password()); |
252 } else { | 231 } else { |
253 DCHECK(type == chrome::NOTIFICATION_AUTH_CANCELLED); | 232 DCHECK(type == chrome::NOTIFICATION_AUTH_CANCELLED); |
254 CancelAuth(); | 233 CancelAuth(); |
255 } | 234 } |
256 } | 235 } |
257 | 236 |
| 237 // Returns whether authentication had been handled (SetAuth or CancelAuth). |
| 238 bool LoginHandler::WasAuthHandled() const { |
| 239 base::AutoLock lock(handled_auth_lock_); |
| 240 bool was_handled = handled_auth_; |
| 241 return was_handled; |
| 242 } |
| 243 |
| 244 LoginHandler::~LoginHandler() { |
| 245 SetModel(NULL); |
| 246 } |
| 247 |
258 void LoginHandler::SetModel(LoginModel* model) { | 248 void LoginHandler::SetModel(LoginModel* model) { |
259 if (login_model_) | 249 if (login_model_) |
260 login_model_->SetObserver(NULL); | 250 login_model_->SetObserver(NULL); |
261 login_model_ = model; | 251 login_model_ = model; |
262 if (login_model_) | 252 if (login_model_) |
263 login_model_->SetObserver(this); | 253 login_model_->SetObserver(this); |
264 } | 254 } |
265 | 255 |
266 void LoginHandler::SetDialog(ConstrainedWindow* dialog) { | 256 void LoginHandler::SetDialog(ConstrainedWindow* dialog) { |
267 dialog_ = dialog; | 257 dialog_ = dialog; |
(...skipping 12 matching lines...) Expand all Loading... |
280 if (requesting_contents) | 270 if (requesting_contents) |
281 controller = &requesting_contents->GetController(); | 271 controller = &requesting_contents->GetController(); |
282 | 272 |
283 LoginNotificationDetails details(this); | 273 LoginNotificationDetails details(this); |
284 | 274 |
285 service->Notify(chrome::NOTIFICATION_AUTH_NEEDED, | 275 service->Notify(chrome::NOTIFICATION_AUTH_NEEDED, |
286 content::Source<NavigationController>(controller), | 276 content::Source<NavigationController>(controller), |
287 content::Details<LoginNotificationDetails>(&details)); | 277 content::Details<LoginNotificationDetails>(&details)); |
288 } | 278 } |
289 | 279 |
290 void LoginHandler::NotifyAuthCancelled() { | 280 void LoginHandler::ReleaseSoon() { |
| 281 if (!TestAndSetAuthHandled()) { |
| 282 BrowserThread::PostTask( |
| 283 BrowserThread::IO, FROM_HERE, |
| 284 base::Bind(&LoginHandler::CancelAuthDeferred, this)); |
| 285 BrowserThread::PostTask( |
| 286 BrowserThread::UI, FROM_HERE, |
| 287 base::Bind(&LoginHandler::NotifyAuthCancelled, this)); |
| 288 } |
| 289 |
| 290 BrowserThread::PostTask( |
| 291 BrowserThread::UI, FROM_HERE, |
| 292 base::Bind(&LoginHandler::RemoveObservers, this)); |
| 293 |
| 294 // Delete this object once all InvokeLaters have been called. |
| 295 BrowserThread::ReleaseSoon(BrowserThread::IO, FROM_HERE, this); |
| 296 } |
| 297 |
| 298 void LoginHandler::AddObservers() { |
291 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
292 DCHECK(WasAuthHandled()); | |
293 | 300 |
294 content::NotificationService* service = | 301 // This is probably OK; we need to listen to everything and we break out of |
295 content::NotificationService::current(); | 302 // the Observe() if we aren't handling the same auth_info(). |
296 NavigationController* controller = NULL; | 303 registrar_.reset(new content::NotificationRegistrar); |
| 304 registrar_->Add(this, chrome::NOTIFICATION_AUTH_SUPPLIED, |
| 305 content::NotificationService::AllBrowserContextsAndSources()); |
| 306 registrar_->Add(this, chrome::NOTIFICATION_AUTH_CANCELLED, |
| 307 content::NotificationService::AllBrowserContextsAndSources()); |
| 308 } |
297 | 309 |
298 WebContents* requesting_contents = GetWebContentsForLogin(); | 310 void LoginHandler::RemoveObservers() { |
299 if (requesting_contents) | 311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
300 controller = &requesting_contents->GetController(); | |
301 | 312 |
302 LoginNotificationDetails details(this); | 313 registrar_.reset(); |
303 | |
304 service->Notify(chrome::NOTIFICATION_AUTH_CANCELLED, | |
305 content::Source<NavigationController>(controller), | |
306 content::Details<LoginNotificationDetails>(&details)); | |
307 } | 314 } |
308 | 315 |
309 void LoginHandler::NotifyAuthSupplied(const string16& username, | 316 void LoginHandler::NotifyAuthSupplied(const string16& username, |
310 const string16& password) { | 317 const string16& password) { |
311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
312 DCHECK(WasAuthHandled()); | 319 DCHECK(WasAuthHandled()); |
313 | 320 |
314 WebContents* requesting_contents = GetWebContentsForLogin(); | 321 WebContents* requesting_contents = GetWebContentsForLogin(); |
315 if (!requesting_contents) | 322 if (!requesting_contents) |
316 return; | 323 return; |
317 | 324 |
318 content::NotificationService* service = | 325 content::NotificationService* service = |
319 content::NotificationService::current(); | 326 content::NotificationService::current(); |
320 NavigationController* controller = | 327 NavigationController* controller = |
321 &requesting_contents->GetController(); | 328 &requesting_contents->GetController(); |
322 AuthSuppliedLoginNotificationDetails details(this, username, password); | 329 AuthSuppliedLoginNotificationDetails details(this, username, password); |
323 | 330 |
324 service->Notify( | 331 service->Notify( |
325 chrome::NOTIFICATION_AUTH_SUPPLIED, | 332 chrome::NOTIFICATION_AUTH_SUPPLIED, |
326 content::Source<NavigationController>(controller), | 333 content::Source<NavigationController>(controller), |
327 content::Details<AuthSuppliedLoginNotificationDetails>(&details)); | 334 content::Details<AuthSuppliedLoginNotificationDetails>(&details)); |
328 } | 335 } |
329 | 336 |
330 void LoginHandler::ReleaseSoon() { | 337 void LoginHandler::NotifyAuthCancelled() { |
331 if (!TestAndSetAuthHandled()) { | 338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
332 BrowserThread::PostTask( | 339 DCHECK(WasAuthHandled()); |
333 BrowserThread::IO, FROM_HERE, | |
334 base::Bind(&LoginHandler::CancelAuthDeferred, this)); | |
335 BrowserThread::PostTask( | |
336 BrowserThread::UI, FROM_HERE, | |
337 base::Bind(&LoginHandler::NotifyAuthCancelled, this)); | |
338 } | |
339 | 340 |
340 BrowserThread::PostTask( | 341 content::NotificationService* service = |
341 BrowserThread::UI, FROM_HERE, | 342 content::NotificationService::current(); |
342 base::Bind(&LoginHandler::RemoveObservers, this)); | 343 NavigationController* controller = NULL; |
343 | 344 |
344 // Delete this object once all InvokeLaters have been called. | 345 WebContents* requesting_contents = GetWebContentsForLogin(); |
345 BrowserThread::ReleaseSoon(BrowserThread::IO, FROM_HERE, this); | 346 if (requesting_contents) |
346 } | 347 controller = &requesting_contents->GetController(); |
347 | 348 |
348 // Returns whether authentication had been handled (SetAuth or CancelAuth). | 349 LoginNotificationDetails details(this); |
349 bool LoginHandler::WasAuthHandled() const { | 350 |
350 base::AutoLock lock(handled_auth_lock_); | 351 service->Notify(chrome::NOTIFICATION_AUTH_CANCELLED, |
351 bool was_handled = handled_auth_; | 352 content::Source<NavigationController>(controller), |
352 return was_handled; | 353 content::Details<LoginNotificationDetails>(&details)); |
353 } | 354 } |
354 | 355 |
355 // Marks authentication as handled and returns the previous handled state. | 356 // Marks authentication as handled and returns the previous handled state. |
356 bool LoginHandler::TestAndSetAuthHandled() { | 357 bool LoginHandler::TestAndSetAuthHandled() { |
357 base::AutoLock lock(handled_auth_lock_); | 358 base::AutoLock lock(handled_auth_lock_); |
358 bool was_handled = handled_auth_; | 359 bool was_handled = handled_auth_; |
359 handled_auth_ = true; | 360 handled_auth_ = true; |
360 return was_handled; | 361 return was_handled; |
361 } | 362 } |
362 | 363 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 | 478 |
478 LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info, | 479 LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info, |
479 net::URLRequest* request) { | 480 net::URLRequest* request) { |
480 LoginHandler* handler = LoginHandler::Create(auth_info, request); | 481 LoginHandler* handler = LoginHandler::Create(auth_info, request); |
481 BrowserThread::PostTask( | 482 BrowserThread::PostTask( |
482 BrowserThread::UI, FROM_HERE, | 483 BrowserThread::UI, FROM_HERE, |
483 base::Bind(&LoginDialogCallback, request->url(), | 484 base::Bind(&LoginDialogCallback, request->url(), |
484 make_scoped_refptr(auth_info), make_scoped_refptr(handler))); | 485 make_scoped_refptr(auth_info), make_scoped_refptr(handler))); |
485 return handler; | 486 return handler; |
486 } | 487 } |
OLD | NEW |