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