login_prompt_views.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/login/login_prompt.h" 6 7#include "base/strings/string16.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/browser/ui/views/constrained_window_views.h" 10#include "chrome/browser/ui/views/login_view.h" 11#include "components/password_manager/core/browser/password_manager.h" 12#include "content/public/browser/browser_thread.h" 13#include "content/public/browser/render_view_host.h" 14#include "content/public/browser/web_contents.h" 15#include "grit/generated_resources.h" 16#include "net/url_request/url_request.h" 17#include "ui/base/l10n/l10n_util.h" 18#include "ui/views/widget/widget.h" 19#include "ui/views/window/dialog_delegate.h" 20 21// ---------------------------------------------------------------------------- 22// LoginHandlerViews 23 24// This class simply forwards the authentication from the LoginView (on 25// the UI thread) to the net::URLRequest (on the I/O thread). 26// This class uses ref counting to ensure that it lives until all InvokeLaters 27// have been called. 28class LoginHandlerViews : public LoginHandler, public views::DialogDelegate { 29 public: 30 LoginHandlerViews(net::AuthChallengeInfo* auth_info, net::URLRequest* request) 31 : LoginHandler(auth_info, request), 32 login_view_(NULL), 33 dialog_(NULL) { 34 } 35 36 // LoginModelObserver: 37 virtual void OnAutofillDataAvailable( 38 const base::string16& username, 39 const base::string16& password) OVERRIDE { 40 // Nothing to do here since LoginView takes care of autofill for win. 41 } 42 virtual void OnLoginModelDestroying() OVERRIDE {} 43 44 // views::DialogDelegate: 45 virtual base::string16 GetDialogButtonLabel( 46 ui::DialogButton button) const OVERRIDE { 47 if (button == ui::DIALOG_BUTTON_OK) 48 return l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL); 49 return DialogDelegate::GetDialogButtonLabel(button); 50 } 51 52 virtual base::string16 GetWindowTitle() const OVERRIDE { 53 return l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_TITLE); 54 } 55 56 virtual void WindowClosing() OVERRIDE { 57 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 58 content::WebContents* web_contents = GetWebContentsForLogin(); 59 if (web_contents) 60 web_contents->GetRenderViewHost()->SetIgnoreInputEvents(false); 61 62 // Reference is no longer valid. 63 dialog_ = NULL; 64 CancelAuth(); 65 } 66 67 virtual void DeleteDelegate() OVERRIDE { 68 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 69 70 // The widget is going to delete itself; clear our pointer. 71 dialog_ = NULL; 72 SetModel(NULL); 73 74 ReleaseSoon(); 75 } 76 77 virtual ui::ModalType GetModalType() const OVERRIDE { 78 return ui::MODAL_TYPE_CHILD; 79 } 80 81 virtual bool Cancel() OVERRIDE { 82 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 83 CancelAuth(); 84 return true; 85 } 86 87 virtual bool Accept() OVERRIDE { 88 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 89 SetAuth(login_view_->GetUsername(), login_view_->GetPassword()); 90 return true; 91 } 92 93 virtual views::View* GetInitiallyFocusedView() OVERRIDE { 94 return login_view_->GetInitiallyFocusedView(); 95 } 96 97 virtual views::View* GetContentsView() OVERRIDE { 98 return login_view_; 99 } 100 virtual views::Widget* GetWidget() OVERRIDE { 101 return login_view_->GetWidget(); 102 } 103 virtual const views::Widget* GetWidget() const OVERRIDE { 104 return login_view_->GetWidget(); 105 } 106 107 // LoginHandler: 108 virtual void BuildViewForPasswordManager( 109 password_manager::PasswordManager* manager, 110 const base::string16& explanation) OVERRIDE { 111 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 112 113 // Create a new LoginView and set the model for it. The model (password 114 // manager) is owned by the WebContents, but the view is parented to the 115 // browser window, so the view may be destroyed after the password 116 // manager. The view listens for model destruction and unobserves 117 // accordingly. 118 login_view_ = new LoginView(explanation, manager); 119 120 // Scary thread safety note: This can potentially be called *after* SetAuth 121 // or CancelAuth (say, if the request was cancelled before the UI thread got 122 // control). However, that's OK since any UI interaction in those functions 123 // will occur via an InvokeLater on the UI thread, which is guaranteed 124 // to happen after this is called (since this was InvokeLater'd first). 125 dialog_ = ShowWebModalDialogViews(this, GetWebContentsForLogin()); 126 NotifyAuthNeeded(); 127 } 128 129 virtual void CloseDialog() OVERRIDE { 130 // The hosting widget may have been freed. 131 if (dialog_) 132 dialog_->Close(); 133 } 134 135 private: 136 friend class base::RefCountedThreadSafe<LoginHandlerViews>; 137 friend class LoginPrompt; 138 139 virtual ~LoginHandlerViews() {} 140 141 // The LoginView that contains the user's login information. 142 LoginView* login_view_; 143 144 views::Widget* dialog_; 145 146 DISALLOW_COPY_AND_ASSIGN(LoginHandlerViews); 147}; 148 149// static 150LoginHandler* LoginHandler::Create(net::AuthChallengeInfo* auth_info, 151 net::URLRequest* request) { 152 return new LoginHandlerViews(auth_info, request); 153} 154