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.
5 #include "chrome/browser/ui/login/login_prompt.h"
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"
26 using autofill::PasswordForm
;
27 using content::BrowserThread
;
28 using content::WebContents
;
29 using web_modal::WebContentsModalDialogManager
;
30 using web_modal::WebContentsModalDialogManagerDelegate
;
32 // ----------------------------------------------------------------------------
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
39 class LoginHandlerViews
: public LoginHandler
,
40 public views::DialogDelegate
{
42 LoginHandlerViews(net::AuthChallengeInfo
* auth_info
, net::URLRequest
* request
)
43 : LoginHandler(auth_info
, request
),
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.
54 virtual void OnLoginModelDestroying() OVERRIDE
{}
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
);
64 virtual base::string16
GetWindowTitle() const OVERRIDE
{
65 return l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_TITLE
);
68 virtual void WindowClosing() OVERRIDE
{
69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
71 WebContents
* tab
= GetWebContentsForLogin();
73 tab
->GetRenderViewHost()->SetIgnoreInputEvents(false);
75 // Reference is no longer valid.
81 virtual void DeleteDelegate() OVERRIDE
{
82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
84 // The widget is going to delete itself; clear our pointer.
91 virtual ui::ModalType
GetModalType() const OVERRIDE
{
93 return ui::MODAL_TYPE_CHILD
;
95 return views::WidgetDelegate::GetModalType();
99 virtual bool Cancel() OVERRIDE
{
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
106 virtual bool Accept() OVERRIDE
{
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
109 SetAuth(login_view_
->GetUsername(), login_view_
->GetPassword());
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(
119 GetWebContentsForLogin()->GetBrowserContext());
122 virtual views::View
* GetInitiallyFocusedView() OVERRIDE
{
123 return login_view_
->GetInitiallyFocusedView();
126 virtual views::View
* GetContentsView() OVERRIDE
{
129 virtual views::Widget
* GetWidget() OVERRIDE
{
130 return login_view_
->GetWidget();
132 virtual const views::Widget
* GetWidget() const OVERRIDE
{
133 return login_view_
->GetWidget();
138 virtual void BuildViewForPasswordManager(
139 PasswordManager
* manager
,
140 const base::string16
& explanation
) OVERRIDE
{
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
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
148 login_view_
= new LoginView(explanation
, manager
);
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());
167 virtual void CloseDialog() OVERRIDE
{
168 // The hosting widget may have been freed.
174 friend class base::RefCountedThreadSafe
<LoginHandlerViews
>;
175 friend class LoginPrompt
;
177 virtual ~LoginHandlerViews() {}
179 // The LoginView that contains the user's login information
180 LoginView
* login_view_
;
182 views::Widget
* dialog_
;
184 DISALLOW_COPY_AND_ASSIGN(LoginHandlerViews
);
188 LoginHandler
* LoginHandler::Create(net::AuthChallengeInfo
* auth_info
,
189 net::URLRequest
* request
) {
190 return new LoginHandlerViews(auth_info
, request
);