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

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

Issue 345037: Fifth patch in getting rid of caching MessageLoop pointers. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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
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 <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include "app/l10n_util.h" 9 #include "app/l10n_util.h"
10 #include "base/message_loop.h" 10 #include "chrome/browser/chrome_thread.h"
11 #include "chrome/browser/gtk/constrained_window_gtk.h" 11 #include "chrome/browser/gtk/constrained_window_gtk.h"
12 #include "chrome/browser/login_model.h" 12 #include "chrome/browser/login_model.h"
13 #include "chrome/browser/password_manager/password_manager.h" 13 #include "chrome/browser/password_manager/password_manager.h"
14 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" 14 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
15 #include "chrome/browser/tab_contents/navigation_controller.h" 15 #include "chrome/browser/tab_contents/navigation_controller.h"
16 #include "chrome/browser/tab_contents/tab_contents.h" 16 #include "chrome/browser/tab_contents/tab_contents.h"
17 #include "chrome/browser/tab_contents/tab_util.h" 17 #include "chrome/browser/tab_contents/tab_util.h"
18 #include "chrome/common/gtk_util.h" 18 #include "chrome/common/gtk_util.h"
19 #include "chrome/common/notification_service.h" 19 #include "chrome/common/notification_service.h"
20 #include "grit/generated_resources.h" 20 #include "grit/generated_resources.h"
21 #include "net/url_request/url_request.h" 21 #include "net/url_request/url_request.h"
22 22
23 using webkit_glue::PasswordForm; 23 using webkit_glue::PasswordForm;
24 24
25 // ---------------------------------------------------------------------------- 25 // ----------------------------------------------------------------------------
26 // LoginHandlerGtk 26 // LoginHandlerGtk
27 27
28 // This class simply forwards the authentication from the LoginView (on 28 // This class simply forwards the authentication from the LoginView (on
29 // the UI thread) to the URLRequest (on the I/O thread). 29 // the UI thread) to the URLRequest (on the I/O thread).
30 // This class uses ref counting to ensure that it lives until all InvokeLaters 30 // This class uses ref counting to ensure that it lives until all InvokeLaters
31 // have been called. 31 // have been called.
32 class LoginHandlerGtk : public LoginHandler, 32 class LoginHandlerGtk : public LoginHandler,
33 public base::RefCountedThreadSafe<LoginHandlerGtk>, 33 public base::RefCountedThreadSafe<LoginHandlerGtk>,
34 public ConstrainedWindowGtkDelegate, 34 public ConstrainedWindowGtkDelegate,
35 public LoginModelObserver { 35 public LoginModelObserver {
36 public: 36 public:
37 LoginHandlerGtk(URLRequest* request, MessageLoop* ui_loop) 37 LoginHandlerGtk(URLRequest* request)
38 : handled_auth_(false), 38 : handled_auth_(false),
39 dialog_(NULL), 39 dialog_(NULL),
40 ui_loop_(ui_loop),
41 request_(request), 40 request_(request),
42 request_loop_(MessageLoop::current()),
43 password_manager_(NULL), 41 password_manager_(NULL),
44 login_model_(NULL) { 42 login_model_(NULL) {
45 DCHECK(request_) << "LoginHandlerGtk constructed with NULL request"; 43 DCHECK(request_) << "LoginHandlerGtk constructed with NULL request";
46 44
47 AddRef(); // matched by ReleaseLater. 45 AddRef(); // matched by ReleaseLater.
48 if (!ResourceDispatcherHost::RenderViewForRequest(request_, 46 if (!ResourceDispatcherHost::RenderViewForRequest(request_,
49 &render_process_host_id_, 47 &render_process_host_id_,
50 &tab_contents_id_)) { 48 &tab_contents_id_)) {
51 NOTREACHED(); 49 NOTREACHED();
52 } 50 }
(...skipping 23 matching lines...) Expand all
76 WideToUTF8(username).c_str()); 74 WideToUTF8(username).c_str());
77 gtk_entry_set_text(GTK_ENTRY(password_entry_), 75 gtk_entry_set_text(GTK_ENTRY(password_entry_),
78 WideToUTF8(password).c_str()); 76 WideToUTF8(password).c_str());
79 gtk_editable_select_region(GTK_EDITABLE(username_entry_), 0, -1); 77 gtk_editable_select_region(GTK_EDITABLE(username_entry_), 0, -1);
80 } 78 }
81 } 79 }
82 80
83 // LoginHandler: 81 // LoginHandler:
84 virtual void BuildViewForPasswordManager(PasswordManager* manager, 82 virtual void BuildViewForPasswordManager(PasswordManager* manager,
85 std::wstring explanation) { 83 std::wstring explanation) {
86 DCHECK(MessageLoop::current() == ui_loop_); 84 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
87 85
88 root_.Own(gtk_vbox_new(NULL, gtk_util::kContentAreaBorder)); 86 root_.Own(gtk_vbox_new(NULL, gtk_util::kContentAreaBorder));
89 GtkWidget* label = gtk_label_new(WideToUTF8(explanation).c_str()); 87 GtkWidget* label = gtk_label_new(WideToUTF8(explanation).c_str());
90 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); 88 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
91 gtk_box_pack_start(GTK_BOX(root_.get()), label, FALSE, FALSE, 0); 89 gtk_box_pack_start(GTK_BOX(root_.get()), label, FALSE, FALSE, 0);
92 90
93 username_entry_ = gtk_entry_new(); 91 username_entry_ = gtk_entry_new();
94 gtk_entry_set_activates_default(GTK_ENTRY(username_entry_), TRUE); 92 gtk_entry_set_activates_default(GTK_ENTRY(username_entry_), TRUE);
95 93
96 password_entry_ = gtk_entry_new(); 94 password_entry_ = gtk_entry_new();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 137
140 virtual void SetPasswordForm(const webkit_glue::PasswordForm& form) { 138 virtual void SetPasswordForm(const webkit_glue::PasswordForm& form) {
141 password_form_ = form; 139 password_form_ = form;
142 } 140 }
143 141
144 virtual void SetPasswordManager(PasswordManager* password_manager) { 142 virtual void SetPasswordManager(PasswordManager* password_manager) {
145 password_manager_ = password_manager; 143 password_manager_ = password_manager;
146 } 144 }
147 145
148 virtual TabContents* GetTabContentsForLogin() { 146 virtual TabContents* GetTabContentsForLogin() {
149 DCHECK(MessageLoop::current() == ui_loop_); 147 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
150 148
151 return tab_util::GetTabContentsByID(render_process_host_id_, 149 return tab_util::GetTabContentsByID(render_process_host_id_,
152 tab_contents_id_); 150 tab_contents_id_);
153 } 151 }
154 152
155 virtual void SetAuth(const std::wstring& username, 153 virtual void SetAuth(const std::wstring& username,
156 const std::wstring& password) { 154 const std::wstring& password) {
157 if (WasAuthHandled(true)) 155 if (WasAuthHandled(true))
158 return; 156 return;
159 157
160 // Tell the password manager the credentials were submitted / accepted. 158 // Tell the password manager the credentials were submitted / accepted.
161 if (password_manager_) { 159 if (password_manager_) {
162 password_form_.username_value = WideToUTF16Hack(username); 160 password_form_.username_value = WideToUTF16Hack(username);
163 password_form_.password_value = WideToUTF16Hack(password); 161 password_form_.password_value = WideToUTF16Hack(password);
164 password_manager_->ProvisionallySavePassword(password_form_); 162 password_manager_->ProvisionallySavePassword(password_form_);
165 } 163 }
166 164
167 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 165 ChromeThread::PostTask(
168 this, &LoginHandlerGtk::CloseContentsDeferred)); 166 ChromeThread::UI, FROM_HERE,
169 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 167 NewRunnableMethod(this, &LoginHandlerGtk::CloseContentsDeferred));
170 this, &LoginHandlerGtk::SendNotifications)); 168 ChromeThread::PostTask(
171 request_loop_->PostTask(FROM_HERE, NewRunnableMethod( 169 ChromeThread::UI, FROM_HERE,
172 this, &LoginHandlerGtk::SetAuthDeferred, username, password)); 170 NewRunnableMethod(this, &LoginHandlerGtk::SendNotifications));
171 ChromeThread::PostTask(
172 ChromeThread::IO, FROM_HERE,
173 NewRunnableMethod(this, &LoginHandlerGtk::SetAuthDeferred, username,
174 password));
173 } 175 }
174 176
175 virtual void CancelAuth() { 177 virtual void CancelAuth() {
176 if (WasAuthHandled(true)) 178 if (WasAuthHandled(true))
177 return; 179 return;
178 180
179 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 181 ChromeThread::PostTask(
180 this, &LoginHandlerGtk::CloseContentsDeferred)); 182 ChromeThread::UI, FROM_HERE,
181 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 183 NewRunnableMethod(this, &LoginHandlerGtk::CloseContentsDeferred));
182 this, &LoginHandlerGtk::SendNotifications)); 184 ChromeThread::PostTask(
183 request_loop_->PostTask(FROM_HERE, NewRunnableMethod( 185 ChromeThread::UI, FROM_HERE,
184 this, &LoginHandlerGtk::CancelAuthDeferred)); 186 NewRunnableMethod(this, &LoginHandlerGtk::SendNotifications));
187 ChromeThread::PostTask(
188 ChromeThread::IO, FROM_HERE,
189 NewRunnableMethod(this, &LoginHandlerGtk::CancelAuthDeferred));
185 } 190 }
186 191
187 virtual void OnRequestCancelled() { 192 virtual void OnRequestCancelled() {
188 DCHECK(MessageLoop::current() == request_loop_) << 193 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)) <<
189 "Why is OnRequestCancelled called from the UI thread?"; 194 "Why is OnRequestCancelled called from the UI thread?";
190 195
191 // Reference is no longer valid. 196 // Reference is no longer valid.
192 request_ = NULL; 197 request_ = NULL;
193 198
194 // Give up on auth if the request was cancelled. 199 // Give up on auth if the request was cancelled.
195 CancelAuth(); 200 CancelAuth();
196 } 201 }
197 202
198 // Overridden from ConstrainedWindowGtkDelegate: 203 // Overridden from ConstrainedWindowGtkDelegate:
199 virtual GtkWidget* GetWidgetRoot() { 204 virtual GtkWidget* GetWidgetRoot() {
200 return root_.get(); 205 return root_.get();
201 } 206 }
202 207
203 virtual void DeleteDelegate() { 208 virtual void DeleteDelegate() {
204 if (!WasAuthHandled(true)) { 209 if (!WasAuthHandled(true)) {
205 request_loop_->PostTask(FROM_HERE, NewRunnableMethod( 210 ChromeThread::PostTask(
206 this, &LoginHandlerGtk::CancelAuthDeferred)); 211 ChromeThread::IO, FROM_HERE,
207 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 212 NewRunnableMethod(this, &LoginHandlerGtk::CancelAuthDeferred));
208 this, &LoginHandlerGtk::SendNotifications)); 213 ChromeThread::PostTask(
214 ChromeThread::UI, FROM_HERE,
215 NewRunnableMethod(this, &LoginHandlerGtk::SendNotifications));
209 } 216 }
210 217
211 SetModel(NULL); 218 SetModel(NULL);
212 219
213 // Delete this object once all InvokeLaters have been called. 220 // Delete this object once all InvokeLaters have been called.
214 request_loop_->ReleaseSoon(FROM_HERE, this); 221 ChromeThread::ReleaseSoon(ChromeThread::IO, FROM_HERE, this);
215 } 222 }
216 223
217 private: 224 private:
218 friend class LoginPrompt; 225 friend class LoginPrompt;
219 226
220 // Calls SetAuth from the request_loop. 227 // Calls SetAuth from the IO loop.
221 void SetAuthDeferred(const std::wstring& username, 228 void SetAuthDeferred(const std::wstring& username,
222 const std::wstring& password) { 229 const std::wstring& password) {
223 DCHECK(MessageLoop::current() == request_loop_); 230 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
224 231
225 if (request_) { 232 if (request_) {
226 request_->SetAuth(username, password); 233 request_->SetAuth(username, password);
227 ResetLoginHandlerForRequest(request_); 234 ResetLoginHandlerForRequest(request_);
228 } 235 }
229 } 236 }
230 237
231 // Calls CancelAuth from the request_loop. 238 // Calls CancelAuth from the IO loop.
232 void CancelAuthDeferred() { 239 void CancelAuthDeferred() {
233 DCHECK(MessageLoop::current() == request_loop_); 240 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
234 241
235 if (request_) { 242 if (request_) {
236 request_->CancelAuth(); 243 request_->CancelAuth();
237 // Verify that CancelAuth does destroy the request via our delegate. 244 // Verify that CancelAuth does destroy the request via our delegate.
238 DCHECK(request_ != NULL); 245 DCHECK(request_ != NULL);
239 ResetLoginHandlerForRequest(request_); 246 ResetLoginHandlerForRequest(request_);
240 } 247 }
241 } 248 }
242 249
243 // Closes the view_contents from the UI loop. 250 // Closes the view_contents from the UI loop.
244 void CloseContentsDeferred() { 251 void CloseContentsDeferred() {
245 DCHECK(MessageLoop::current() == ui_loop_); 252 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
246 253
247 // The hosting ConstrainedWindow may have been freed. 254 // The hosting ConstrainedWindow may have been freed.
248 if (dialog_) 255 if (dialog_)
249 dialog_->CloseConstrainedWindow(); 256 dialog_->CloseConstrainedWindow();
250 } 257 }
251 258
252 // Returns whether authentication had been handled (SetAuth or CancelAuth). 259 // Returns whether authentication had been handled (SetAuth or CancelAuth).
253 // If |set_handled| is true, it will mark authentication as handled. 260 // If |set_handled| is true, it will mark authentication as handled.
254 bool WasAuthHandled(bool set_handled) { 261 bool WasAuthHandled(bool set_handled) {
255 AutoLock lock(handled_auth_lock_); 262 AutoLock lock(handled_auth_lock_);
256 bool was_handled = handled_auth_; 263 bool was_handled = handled_auth_;
257 if (set_handled) 264 if (set_handled)
258 handled_auth_ = true; 265 handled_auth_ = true;
259 return was_handled; 266 return was_handled;
260 } 267 }
261 268
262 // Notify observers that authentication is needed or received. The automation 269 // Notify observers that authentication is needed or received. The automation
263 // proxy uses this for testing. 270 // proxy uses this for testing.
264 void SendNotifications() { 271 void SendNotifications() {
265 DCHECK(MessageLoop::current() == ui_loop_); 272 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
266 273
267 NotificationService* service = NotificationService::current(); 274 NotificationService* service = NotificationService::current();
268 TabContents* requesting_contents = GetTabContentsForLogin(); 275 TabContents* requesting_contents = GetTabContentsForLogin();
269 if (!requesting_contents) 276 if (!requesting_contents)
270 return; 277 return;
271 278
272 NavigationController* controller = &requesting_contents->controller(); 279 NavigationController* controller = &requesting_contents->controller();
273 280
274 if (!WasAuthHandled(false)) { 281 if (!WasAuthHandled(false)) {
275 LoginNotificationDetails details(this); 282 LoginNotificationDetails details(this);
276 service->Notify(NotificationType::AUTH_NEEDED, 283 service->Notify(NotificationType::AUTH_NEEDED,
277 Source<NavigationController>(controller), 284 Source<NavigationController>(controller),
278 Details<LoginNotificationDetails>(&details)); 285 Details<LoginNotificationDetails>(&details));
279 } else { 286 } else {
280 service->Notify(NotificationType::AUTH_SUPPLIED, 287 service->Notify(NotificationType::AUTH_SUPPLIED,
281 Source<NavigationController>(controller), 288 Source<NavigationController>(controller),
282 NotificationService::NoDetails()); 289 NotificationService::NoDetails());
283 } 290 }
284 } 291 }
285 292
286 static void OnOKClicked(GtkButton *button, LoginHandlerGtk* handler) { 293 static void OnOKClicked(GtkButton *button, LoginHandlerGtk* handler) {
287 DCHECK(MessageLoop::current() == handler->ui_loop_); 294 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
288 295
289 handler->SetAuth( 296 handler->SetAuth(
290 UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(handler->username_entry_))), 297 UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(handler->username_entry_))),
291 UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(handler->password_entry_)))); 298 UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(handler->password_entry_))));
292 } 299 }
293 300
294 static void OnCancelClicked(GtkButton *button, LoginHandlerGtk* handler) { 301 static void OnCancelClicked(GtkButton *button, LoginHandlerGtk* handler) {
295 DCHECK(MessageLoop::current() == handler->ui_loop_); 302 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
296 handler->CancelAuth(); 303 handler->CancelAuth();
297 } 304 }
298 305
299 // True if we've handled auth (SetAuth or CancelAuth has been called). 306 // True if we've handled auth (SetAuth or CancelAuth has been called).
300 bool handled_auth_; 307 bool handled_auth_;
301 Lock handled_auth_lock_; 308 Lock handled_auth_lock_;
302 309
303 // The ConstrainedWindow that is hosting our LoginView. 310 // The ConstrainedWindow that is hosting our LoginView.
304 // This should only be accessed on the ui_loop_. 311 // This should only be accessed on the UI loop.
305 ConstrainedWindow* dialog_; 312 ConstrainedWindow* dialog_;
306 313
307 // The MessageLoop of the thread that the ChromeViewContents lives in.
308 MessageLoop* ui_loop_;
309
310 // The request that wants login data. 314 // The request that wants login data.
311 // This should only be accessed on the request_loop_. 315 // This should only be accessed on the IO loop.
312 URLRequest* request_; 316 URLRequest* request_;
313 317
314 // The MessageLoop of the thread that the URLRequest lives in.
315 MessageLoop* request_loop_;
316
317 // The PasswordForm sent to the PasswordManager. This is so we can refer to it 318 // The PasswordForm sent to the PasswordManager. This is so we can refer to it
318 // when later notifying the password manager if the credentials were accepted 319 // when later notifying the password manager if the credentials were accepted
319 // or rejected. 320 // or rejected.
320 // This should only be accessed on the ui_loop_. 321 // This should only be accessed on the UI loop.
321 PasswordForm password_form_; 322 PasswordForm password_form_;
322 323
323 // Points to the password manager owned by the TabContents requesting auth. 324 // Points to the password manager owned by the TabContents requesting auth.
324 // Can be null if the TabContents is not a TabContents. 325 // Can be null if the TabContents is not a TabContents.
325 // This should only be accessed on the ui_loop_. 326 // This should only be accessed on the UI loop.
326 PasswordManager* password_manager_; 327 PasswordManager* password_manager_;
327 328
328 // Cached from the URLRequest, in case it goes NULL on us. 329 // Cached from the URLRequest, in case it goes NULL on us.
329 int render_process_host_id_; 330 int render_process_host_id_;
330 int tab_contents_id_; 331 int tab_contents_id_;
331 332
332 // The GtkWidgets that form our visual hierarchy: 333 // The GtkWidgets that form our visual hierarchy:
333 // The root container we pass to our parent. 334 // The root container we pass to our parent.
334 OwnedWidgetGtk root_; 335 OwnedWidgetGtk root_;
335 336
336 // GtkEntry widgets that the user types into. 337 // GtkEntry widgets that the user types into.
337 GtkWidget* username_entry_; 338 GtkWidget* username_entry_;
338 GtkWidget* password_entry_; 339 GtkWidget* password_entry_;
339 340
340 // If not null, points to a model we need to notify of our own destruction 341 // If not null, points to a model we need to notify of our own destruction
341 // so it doesn't try and access this when its too late. 342 // so it doesn't try and access this when its too late.
342 LoginModel* login_model_; 343 LoginModel* login_model_;
343 344
344 DISALLOW_COPY_AND_ASSIGN(LoginHandlerGtk); 345 DISALLOW_COPY_AND_ASSIGN(LoginHandlerGtk);
345 }; 346 };
346 347
347 // static 348 // static
348 LoginHandler* LoginHandler::Create(URLRequest* request, MessageLoop* ui_loop) { 349 LoginHandler* LoginHandler::Create(URLRequest* request) {
349 return new LoginHandlerGtk(request, ui_loop); 350 return new LoginHandlerGtk(request);
350 } 351 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698