Home | History | Annotate | Download | only in views
      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.
     28 class 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
    150 LoginHandler* LoginHandler::Create(net::AuthChallengeInfo* auth_info,
    151                                    net::URLRequest* request) {
    152   return new LoginHandlerViews(auth_info, request);
    153 }
    154