| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/login/login_prompt.h" |
| |
| #include "base/strings/string16.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/ui/views/login_view.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "components/constrained_window/constrained_window_views.h" |
| #include "components/password_manager/core/browser/password_manager.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/render_widget_host.h" |
| #include "content/public/browser/web_contents.h" |
| #include "net/url_request/url_request.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/views/widget/widget.h" |
| #include "ui/views/window/dialog_delegate.h" |
| |
| // ---------------------------------------------------------------------------- |
| // LoginHandlerViews |
| |
| // This class simply forwards the authentication from the LoginView (on |
| // the UI thread) to the net::URLRequest (on the I/O thread). |
| // This class uses ref counting to ensure that it lives until all InvokeLaters |
| // have been called. |
| class LoginHandlerViews : public LoginHandler, public views::DialogDelegate { |
| public: |
| LoginHandlerViews(net::AuthChallengeInfo* auth_info, net::URLRequest* request) |
| : LoginHandler(auth_info, request), |
| login_view_(NULL), |
| dialog_(NULL) { |
| } |
| |
| // LoginModelObserver: |
| void OnAutofillDataAvailableInternal( |
| const base::string16& username, |
| const base::string16& password) override { |
| // Nothing to do here since LoginView takes care of autofill for win. |
| } |
| void OnLoginModelDestroying() override {} |
| |
| // views::DialogDelegate: |
| base::string16 GetDialogButtonLabel(ui::DialogButton button) const override { |
| if (button == ui::DIALOG_BUTTON_OK) |
| return l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL); |
| return DialogDelegate::GetDialogButtonLabel(button); |
| } |
| |
| base::string16 GetWindowTitle() const override { |
| return l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_TITLE); |
| } |
| |
| void WindowClosing() override { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| content::WebContents* web_contents = GetWebContentsForLogin(); |
| if (web_contents) |
| web_contents->GetRenderViewHost()->GetWidget()->SetIgnoreInputEvents( |
| false); |
| |
| // Reference is no longer valid. |
| dialog_ = NULL; |
| CancelAuth(); |
| } |
| |
| void DeleteDelegate() override { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| |
| // The widget is going to delete itself; clear our pointer. |
| dialog_ = NULL; |
| ResetModel(); |
| |
| ReleaseSoon(); |
| } |
| |
| ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; } |
| |
| bool Cancel() override { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| CancelAuth(); |
| return true; |
| } |
| |
| bool Accept() override { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| SetAuth(login_view_->GetUsername(), login_view_->GetPassword()); |
| return true; |
| } |
| |
| views::View* GetInitiallyFocusedView() override { |
| return login_view_->GetInitiallyFocusedView(); |
| } |
| |
| views::View* GetContentsView() override { return login_view_; } |
| views::Widget* GetWidget() override { return login_view_->GetWidget(); } |
| const views::Widget* GetWidget() const override { |
| return login_view_->GetWidget(); |
| } |
| |
| // LoginHandler: |
| void BuildViewImpl(const base::string16& authority, |
| const base::string16& explanation, |
| LoginModelData* login_model_data) override { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| |
| // Create a new LoginView and set the model for it. The model (password |
| // manager) is owned by the WebContents, but the view is parented to the |
| // browser window, so the view may be destroyed after the password |
| // manager. The view listens for model destruction and unobserves |
| // accordingly. |
| login_view_ = new LoginView(authority, explanation, login_model_data); |
| |
| // Scary thread safety note: This can potentially be called *after* SetAuth |
| // or CancelAuth (say, if the request was cancelled before the UI thread got |
| // control). However, that's OK since any UI interaction in those functions |
| // will occur via an InvokeLater on the UI thread, which is guaranteed |
| // to happen after this is called (since this was InvokeLater'd first). |
| dialog_ = constrained_window::ShowWebModalDialogViews( |
| this, GetWebContentsForLogin()); |
| NotifyAuthNeeded(); |
| } |
| |
| void CloseDialog() override { |
| // The hosting widget may have been freed. |
| if (dialog_) |
| dialog_->Close(); |
| } |
| |
| private: |
| friend class base::RefCountedThreadSafe<LoginHandlerViews>; |
| friend class LoginPrompt; |
| |
| ~LoginHandlerViews() override {} |
| |
| // The LoginView that contains the user's login information. |
| LoginView* login_view_; |
| |
| views::Widget* dialog_; |
| |
| DISALLOW_COPY_AND_ASSIGN(LoginHandlerViews); |
| }; |
| |
| namespace chrome { |
| |
| LoginHandler* CreateLoginHandlerViews(net::AuthChallengeInfo* auth_info, |
| net::URLRequest* request) { |
| return new LoginHandlerViews(auth_info, request); |
| } |
| |
| } // namespace chrome |