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