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