Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Side by Side Diff: chrome/browser/login_prompt_win.cc

Issue 995004: Factoring duplicate code from platform-specific LoginHandlers into a base ... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/login_prompt_mac.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/login_prompt.h" 5 #include "chrome/browser/login_prompt.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "chrome/browser/chrome_thread.h" 8 #include "chrome/browser/chrome_thread.h"
9 #include "chrome/browser/password_manager/password_manager.h" 9 #include "chrome/browser/password_manager/password_manager.h"
10 #include "chrome/browser/renderer_host/render_process_host.h" 10 #include "chrome/browser/renderer_host/render_process_host.h"
(...skipping 11 matching lines...) Expand all
22 using webkit_glue::PasswordForm; 22 using webkit_glue::PasswordForm;
23 23
24 // ---------------------------------------------------------------------------- 24 // ----------------------------------------------------------------------------
25 // LoginHandlerWin 25 // LoginHandlerWin
26 26
27 // This class simply forwards the authentication from the LoginView (on 27 // This class simply forwards the authentication from the LoginView (on
28 // the UI thread) to the URLRequest (on the I/O thread). 28 // the UI thread) to the URLRequest (on the I/O thread).
29 // This class uses ref counting to ensure that it lives until all InvokeLaters 29 // This class uses ref counting to ensure that it lives until all InvokeLaters
30 // have been called. 30 // have been called.
31 class LoginHandlerWin : public LoginHandler, 31 class LoginHandlerWin : public LoginHandler,
32 public base::RefCountedThreadSafe<LoginHandlerWin>,
33 public views::DialogDelegate { 32 public views::DialogDelegate {
34 public: 33 public:
35 explicit LoginHandlerWin(URLRequest* request) 34 explicit LoginHandlerWin(URLRequest* request) : LoginHandler(request) {
36 : dialog_(NULL), 35 }
37 handled_auth_(false),
38 request_(request),
39 password_manager_(NULL) {
40 DCHECK(request_) << "LoginHandler constructed with NULL request";
41 36
42 AddRef(); // matched by ReleaseLater. 37 // LoginModelObserver implementation.
43 if (!ResourceDispatcherHost::RenderViewForRequest(request_, 38 virtual void OnAutofillDataAvailable(const std::wstring& username,
44 &render_process_host_id_, 39 const std::wstring& password) {
45 &tab_contents_id_)) { 40 // Nothing to do here since LoginView takes care of autofil for win.
46 NOTREACHED();
47 }
48 } 41 }
49 42
50 void set_login_view(LoginView* login_view) { 43 void set_login_view(LoginView* login_view) {
51 login_view_ = login_view; 44 login_view_ = login_view;
52 } 45 }
53 46
54 // views::DialogDelegate methods: 47 // views::DialogDelegate methods:
55 virtual std::wstring GetDialogButtonLabel( 48 virtual std::wstring GetDialogButtonLabel(
56 MessageBoxFlags::DialogButton button) const { 49 MessageBoxFlags::DialogButton button) const {
57 if (button == MessageBoxFlags::DIALOGBUTTON_OK) 50 if (button == MessageBoxFlags::DIALOGBUTTON_OK)
58 return l10n_util::GetString(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL); 51 return l10n_util::GetString(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL);
59 return DialogDelegate::GetDialogButtonLabel(button); 52 return DialogDelegate::GetDialogButtonLabel(button);
60 } 53 }
54
61 virtual std::wstring GetWindowTitle() const { 55 virtual std::wstring GetWindowTitle() const {
62 return l10n_util::GetString(IDS_LOGIN_DIALOG_TITLE); 56 return l10n_util::GetString(IDS_LOGIN_DIALOG_TITLE);
63 } 57 }
58
64 virtual void WindowClosing() { 59 virtual void WindowClosing() {
65 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 60 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
66 61
67 TabContents* tab = GetTabContentsForLogin(); 62 TabContents* tab = GetTabContentsForLogin();
68 if (tab) 63 if (tab)
69 tab->render_view_host()->set_ignore_input_events(false); 64 tab->render_view_host()->set_ignore_input_events(false);
70 65
71 // Reference is no longer valid. 66 // Reference is no longer valid.
72 dialog_ = NULL; 67 SetDialog(NULL);
73 68
74 if (!WasAuthHandled(true)) { 69 CancelAuth();
75 ChromeThread::PostTask(
76 ChromeThread::IO, FROM_HERE,
77 NewRunnableMethod(this, &LoginHandlerWin::CancelAuthDeferred));
78 SendNotifications();
79 }
80 } 70 }
71
81 virtual void DeleteDelegate() { 72 virtual void DeleteDelegate() {
82 // Delete this object once all InvokeLaters have been called. 73 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
83 ChromeThread::ReleaseSoon(ChromeThread::IO, FROM_HERE, this); 74
75 // The constrained window is going to delete itself; clear our pointer.
76 SetDialog(NULL);
77 SetModel(NULL);
78
79 ReleaseSoon();
84 } 80 }
81
85 virtual bool Cancel() { 82 virtual bool Cancel() {
86 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 83 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
87 DCHECK(dialog_) << "LoginHandler invoked without being attached"; 84
88 CancelAuth(); 85 CancelAuth();
89 return true; 86 return true;
90 } 87 }
88
91 virtual bool Accept() { 89 virtual bool Accept() {
92 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 90 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
93 DCHECK(dialog_) << "LoginHandler invoked without being attached"; 91
94 SetAuth(login_view_->GetUsername(), login_view_->GetPassword()); 92 SetAuth(login_view_->GetUsername(), login_view_->GetPassword());
95 return true; 93 return true;
96 } 94 }
95
97 virtual views::View* GetContentsView() { 96 virtual views::View* GetContentsView() {
98 return login_view_; 97 return login_view_;
99 } 98 }
100 99
101 // LoginHandler: 100 // LoginHandler:
102 101
103 virtual void BuildViewForPasswordManager(PasswordManager* manager, 102 virtual void BuildViewForPasswordManager(PasswordManager* manager,
104 std::wstring explanation) { 103 std::wstring explanation) {
105 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 104 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
106 105
107 LoginView* view = new LoginView(explanation); 106 LoginView* view = new LoginView(explanation);
108 107
109 // Set the model for the login view. The model (password manager) is owned 108 // Set the model for the login view. The model (password manager) is owned
110 // by the view's parent TabContents, so natural destruction order means we 109 // by the view's parent TabContents, so natural destruction order means we
111 // don't have to worry about calling SetModel(NULL), because the view will 110 // don't have to worry about calling SetModel(NULL), because the view will
112 // be deleted before the password manager. 111 // be deleted before the password manager.
113 view->SetModel(manager); 112 view->SetModel(manager);
114 113
115 set_login_view(view); 114 set_login_view(view);
116 115
117 // Scary thread safety note: This can potentially be called *after* SetAuth 116 // Scary thread safety note: This can potentially be called *after* SetAuth
118 // or CancelAuth (say, if the request was cancelled before the UI thread got 117 // or CancelAuth (say, if the request was cancelled before the UI thread got
119 // control). However, that's OK since any UI interaction in those functions 118 // control). However, that's OK since any UI interaction in those functions
120 // will occur via an InvokeLater on the UI thread, which is guaranteed 119 // will occur via an InvokeLater on the UI thread, which is guaranteed
121 // to happen after this is called (since this was InvokeLater'd first). 120 // to happen after this is called (since this was InvokeLater'd first).
122 dialog_ = GetTabContentsForLogin()->CreateConstrainedDialog(this); 121 SetDialog(GetTabContentsForLogin()->CreateConstrainedDialog(this));
123 SendNotifications(); 122 SendNotifications();
124 } 123 }
125 124
126 virtual void SetPasswordForm(const webkit_glue::PasswordForm& form) {
127 password_form_ = form;
128 }
129
130 virtual void SetPasswordManager(PasswordManager* password_manager) {
131 password_manager_ = password_manager;
132 }
133
134 virtual TabContents* GetTabContentsForLogin() {
135 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
136
137 return tab_util::GetTabContentsByID(render_process_host_id_,
138 tab_contents_id_);
139 }
140
141 virtual void SetAuth(const std::wstring& username,
142 const std::wstring& password) {
143 if (WasAuthHandled(true))
144 return;
145
146 // Tell the password manager the credentials were submitted / accepted.
147 if (password_manager_) {
148 password_form_.username_value = username;
149 password_form_.password_value = password;
150 password_manager_->ProvisionallySavePassword(password_form_);
151 }
152
153 ChromeThread::PostTask(
154 ChromeThread::UI, FROM_HERE,
155 NewRunnableMethod(this, &LoginHandlerWin::CloseContentsDeferred));
156 ChromeThread::PostTask(
157 ChromeThread::UI, FROM_HERE,
158 NewRunnableMethod(this, &LoginHandlerWin::SendNotifications));
159 ChromeThread::PostTask(
160 ChromeThread::IO, FROM_HERE,
161 NewRunnableMethod(
162 this, &LoginHandlerWin::SetAuthDeferred, username, password));
163 }
164
165 virtual void CancelAuth() {
166 if (WasAuthHandled(true))
167 return;
168
169 ChromeThread::PostTask(
170 ChromeThread::UI, FROM_HERE,
171 NewRunnableMethod(this, &LoginHandlerWin::CloseContentsDeferred));
172 ChromeThread::PostTask(
173 ChromeThread::UI, FROM_HERE,
174 NewRunnableMethod(this, &LoginHandlerWin::SendNotifications));
175 ChromeThread::PostTask(
176 ChromeThread::IO, FROM_HERE,
177 NewRunnableMethod(this, &LoginHandlerWin::CancelAuthDeferred));
178 }
179
180 virtual void OnRequestCancelled() {
181 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)) <<
182 "Why is OnRequestCancelled called from the UI thread?";
183
184 // Reference is no longer valid.
185 request_ = NULL;
186
187 // Give up on auth if the request was cancelled.
188 CancelAuth();
189 }
190
191 private: 125 private:
192 friend class base::RefCountedThreadSafe<LoginHandlerWin>; 126 friend class base::RefCountedThreadSafe<LoginHandlerWin>;
193 friend class LoginPrompt; 127 friend class LoginPrompt;
194 128
195 ~LoginHandlerWin() {} 129 ~LoginHandlerWin() {}
196 130
197 // Calls SetAuth from the IO loop.
198 void SetAuthDeferred(const std::wstring& username,
199 const std::wstring& password) {
200 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
201
202 if (request_) {
203 request_->SetAuth(username, password);
204 ResetLoginHandlerForRequest(request_);
205 }
206 }
207
208 // Calls CancelAuth from the IO loop.
209 void CancelAuthDeferred() {
210 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
211
212 if (request_) {
213 request_->CancelAuth();
214 // Verify that CancelAuth does destroy the request via our delegate.
215 DCHECK(request_ != NULL);
216 ResetLoginHandlerForRequest(request_);
217 }
218 }
219
220 // Closes the view_contents from the UI loop.
221 void CloseContentsDeferred() {
222 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
223
224 // The hosting ConstrainedWindow may have been freed.
225 if (dialog_)
226 dialog_->CloseConstrainedWindow();
227 }
228
229 // Returns whether authentication had been handled (SetAuth or CancelAuth).
230 // If |set_handled| is true, it will mark authentication as handled.
231 bool WasAuthHandled(bool set_handled) {
232 AutoLock lock(handled_auth_lock_);
233 bool was_handled = handled_auth_;
234 if (set_handled)
235 handled_auth_ = true;
236 return was_handled;
237 }
238
239 // Notify observers that authentication is needed or received. The automation
240 // proxy uses this for testing.
241 void SendNotifications() {
242 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
243
244 NotificationService* service = NotificationService::current();
245 TabContents* requesting_contents = GetTabContentsForLogin();
246 if (!requesting_contents)
247 return;
248
249 NavigationController* controller = &requesting_contents->controller();
250
251 if (!WasAuthHandled(false)) {
252 LoginNotificationDetails details(this);
253 service->Notify(NotificationType::AUTH_NEEDED,
254 Source<NavigationController>(controller),
255 Details<LoginNotificationDetails>(&details));
256 } else {
257 service->Notify(NotificationType::AUTH_SUPPLIED,
258 Source<NavigationController>(controller),
259 NotificationService::NoDetails());
260 }
261 }
262
263 // True if we've handled auth (SetAuth or CancelAuth has been called).
264 bool handled_auth_;
265 Lock handled_auth_lock_;
266
267 // The ConstrainedWindow that is hosting our LoginView.
268 // This should only be accessed on the UI loop.
269 ConstrainedWindow* dialog_;
270
271 // The request that wants login data.
272 // This should only be accessed on the IO loop.
273 URLRequest* request_;
274
275 // The LoginView that contains the user's login information 131 // The LoginView that contains the user's login information
276 LoginView* login_view_; 132 LoginView* login_view_;
277 133
278 // The PasswordForm sent to the PasswordManager. This is so we can refer to it
279 // when later notifying the password manager if the credentials were accepted
280 // or rejected.
281 // This should only be accessed on the UI loop.
282 PasswordForm password_form_;
283
284 // Points to the password manager owned by the TabContents requesting auth.
285 // Can be null if the TabContents is not a TabContents.
286 // This should only be accessed on the UI loop.
287 PasswordManager* password_manager_;
288
289 // Cached from the URLRequest, in case it goes NULL on us.
290 int render_process_host_id_;
291 int tab_contents_id_;
292
293 DISALLOW_COPY_AND_ASSIGN(LoginHandlerWin); 134 DISALLOW_COPY_AND_ASSIGN(LoginHandlerWin);
294 }; 135 };
295 136
296 // static 137 // static
297 LoginHandler* LoginHandler::Create(URLRequest* request) { 138 LoginHandler* LoginHandler::Create(URLRequest* request) {
298 return new LoginHandlerWin(request); 139 return new LoginHandlerWin(request);
299 } 140 }
OLDNEW
« no previous file with comments | « chrome/browser/login_prompt_mac.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698