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