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

Side by Side Diff: chrome/browser/login_prompt_mac.mm

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 #import "chrome/browser/login_prompt_mac.h" 6 #import "chrome/browser/login_prompt_mac.h"
7 7
8 #include "app/l10n_util.h" 8 #include "app/l10n_util.h"
9 #include "base/mac_util.h" 9 #include "base/mac_util.h"
10 #include "base/message_loop.h"
11 #include "base/sys_string_conversions.h" 10 #include "base/sys_string_conversions.h"
11 #include "chrome/browser/chrome_thread.h"
12 #include "chrome/browser/cocoa/constrained_window_mac.h" 12 #include "chrome/browser/cocoa/constrained_window_mac.h"
13 #include "chrome/browser/login_model.h" 13 #include "chrome/browser/login_model.h"
14 #include "chrome/browser/password_manager/password_manager.h" 14 #include "chrome/browser/password_manager/password_manager.h"
15 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" 15 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
16 #include "chrome/browser/tab_contents/navigation_controller.h" 16 #include "chrome/browser/tab_contents/navigation_controller.h"
17 #include "chrome/browser/tab_contents/tab_contents.h" 17 #include "chrome/browser/tab_contents/tab_contents.h"
18 #include "chrome/browser/tab_contents/tab_util.h" 18 #include "chrome/browser/tab_contents/tab_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 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" 22 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
23 23
24 using webkit_glue::PasswordForm; 24 using webkit_glue::PasswordForm;
25 25
26 // ---------------------------------------------------------------------------- 26 // ----------------------------------------------------------------------------
27 // LoginHandlerMac 27 // LoginHandlerMac
28 28
29 // This class simply forwards the authentication from the LoginView (on 29 // This class simply forwards the authentication from the LoginView (on
30 // the UI thread) to the URLRequest (on the I/O thread). 30 // the UI thread) to the URLRequest (on the I/O thread).
31 // This class uses ref counting to ensure that it lives until all InvokeLaters 31 // This class uses ref counting to ensure that it lives until all InvokeLaters
32 // have been called. 32 // have been called.
33 class LoginHandlerMac : public LoginHandler, 33 class LoginHandlerMac : public LoginHandler,
34 public base::RefCountedThreadSafe<LoginHandlerMac>, 34 public base::RefCountedThreadSafe<LoginHandlerMac>,
35 public ConstrainedWindowMacDelegateCustomSheet, 35 public ConstrainedWindowMacDelegateCustomSheet,
36 public LoginModelObserver { 36 public LoginModelObserver {
37 public: 37 public:
38 LoginHandlerMac(URLRequest* request, MessageLoop* ui_loop) 38 LoginHandlerMac(URLRequest* request)
39 : handled_auth_(false), 39 : handled_auth_(false),
40 dialog_(NULL), 40 dialog_(NULL),
41 ui_loop_(ui_loop),
42 request_(request), 41 request_(request),
43 request_loop_(MessageLoop::current()),
44 password_manager_(NULL), 42 password_manager_(NULL),
45 sheet_controller_(nil), 43 sheet_controller_(nil),
46 login_model_(NULL) { 44 login_model_(NULL) {
47 // This constructor is called on the I/O thread, so we cannot load the nib 45 // This constructor is called on the I/O thread, so we cannot load the nib
48 // here. BuildViewForPasswordManager() will be invoked on the UI thread 46 // here. BuildViewForPasswordManager() will be invoked on the UI thread
49 // later, so wait with loading the nib until then. 47 // later, so wait with loading the nib until then.
50 DCHECK(request_) << "LoginHandlerMac constructed with NULL request"; 48 DCHECK(request_) << "LoginHandlerMac constructed with NULL request";
51 49
52 AddRef(); // matched by ReleaseLater. 50 AddRef(); // matched by ReleaseLater.
53 if (!ResourceDispatcherHost::RenderViewForRequest(request_, 51 if (!ResourceDispatcherHost::RenderViewForRequest(request_,
(...skipping 19 matching lines...) Expand all
73 // LoginModelObserver implementation. 71 // LoginModelObserver implementation.
74 virtual void OnAutofillDataAvailable(const std::wstring& username, 72 virtual void OnAutofillDataAvailable(const std::wstring& username,
75 const std::wstring& password) { 73 const std::wstring& password) {
76 [sheet_controller_ autofillLogin:base::SysWideToNSString(username) 74 [sheet_controller_ autofillLogin:base::SysWideToNSString(username)
77 password:base::SysWideToNSString(password)]; 75 password:base::SysWideToNSString(password)];
78 } 76 }
79 77
80 // LoginHandler: 78 // LoginHandler:
81 virtual void BuildViewForPasswordManager(PasswordManager* manager, 79 virtual void BuildViewForPasswordManager(PasswordManager* manager,
82 std::wstring explanation) { 80 std::wstring explanation) {
83 DCHECK(MessageLoop::current() == ui_loop_); 81 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
84 82
85 // Load nib here instead of in constructor. 83 // Load nib here instead of in constructor.
86 sheet_controller_ = [[[LoginHandlerSheet alloc] 84 sheet_controller_ = [[[LoginHandlerSheet alloc]
87 initWithLoginHandler:this] autorelease]; 85 initWithLoginHandler:this] autorelease];
88 init([sheet_controller_ window], sheet_controller_, 86 init([sheet_controller_ window], sheet_controller_,
89 @selector(sheetDidEnd:returnCode:contextInfo:)); 87 @selector(sheetDidEnd:returnCode:contextInfo:));
90 88
91 SetModel(manager); 89 SetModel(manager);
92 90
93 [sheet_controller_ setExplanation:base::SysWideToNSString(explanation)]; 91 [sheet_controller_ setExplanation:base::SysWideToNSString(explanation)];
(...skipping 10 matching lines...) Expand all
104 102
105 virtual void SetPasswordForm(const webkit_glue::PasswordForm& form) { 103 virtual void SetPasswordForm(const webkit_glue::PasswordForm& form) {
106 password_form_ = form; 104 password_form_ = form;
107 } 105 }
108 106
109 virtual void SetPasswordManager(PasswordManager* password_manager) { 107 virtual void SetPasswordManager(PasswordManager* password_manager) {
110 password_manager_ = password_manager; 108 password_manager_ = password_manager;
111 } 109 }
112 110
113 virtual TabContents* GetTabContentsForLogin() { 111 virtual TabContents* GetTabContentsForLogin() {
114 DCHECK(MessageLoop::current() == ui_loop_); 112 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
115 113
116 return tab_util::GetTabContentsByID(render_process_host_id_, 114 return tab_util::GetTabContentsByID(render_process_host_id_,
117 tab_contents_id_); 115 tab_contents_id_);
118 } 116 }
119 117
120 virtual void SetAuth(const std::wstring& username, 118 virtual void SetAuth(const std::wstring& username,
121 const std::wstring& password) { 119 const std::wstring& password) {
122 if (WasAuthHandled(true)) 120 if (WasAuthHandled(true))
123 return; 121 return;
124 122
125 // Tell the password manager the credentials were submitted / accepted. 123 // Tell the password manager the credentials were submitted / accepted.
126 if (password_manager_) { 124 if (password_manager_) {
127 password_form_.username_value = WideToUTF16Hack(username); 125 password_form_.username_value = WideToUTF16Hack(username);
128 password_form_.password_value = WideToUTF16Hack(password); 126 password_form_.password_value = WideToUTF16Hack(password);
129 password_manager_->ProvisionallySavePassword(password_form_); 127 password_manager_->ProvisionallySavePassword(password_form_);
130 } 128 }
131 129
132 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 130 ChromeThread::PostTask(
133 this, &LoginHandlerMac::CloseContentsDeferred)); 131 ChromeThread::UI, FROM_HERE,
134 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 132 NewRunnableMethod(this, &LoginHandlerMac::CloseContentsDeferred));
135 this, &LoginHandlerMac::SendNotifications)); 133 ChromeThread::PostTask(
136 request_loop_->PostTask(FROM_HERE, NewRunnableMethod( 134 ChromeThread::UI, FROM_HERE,
137 this, &LoginHandlerMac::SetAuthDeferred, username, password)); 135 NewRunnableMethod(this, &LoginHandlerMac::SendNotifications));
136 ChromeThread::PostTask(
137 ChromeThread::IO, FROM_HERE,
138 NewRunnableMethod(
139 this, &LoginHandlerMac::SetAuthDeferred, username, password));
138 } 140 }
139 141
140 virtual void CancelAuth() { 142 virtual void CancelAuth() {
141 if (WasAuthHandled(true)) 143 if (WasAuthHandled(true))
142 return; 144 return;
143 145
144 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 146 ChromeThread::PostTask(
145 this, &LoginHandlerMac::CloseContentsDeferred)); 147 ChromeThread::UI, FROM_HERE,
146 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 148 NewRunnableMethod(this, &LoginHandlerMac::CloseContentsDeferred));
147 this, &LoginHandlerMac::SendNotifications)); 149 ChromeThread::PostTask(
148 request_loop_->PostTask(FROM_HERE, NewRunnableMethod( 150 ChromeThread::UI, FROM_HERE,
149 this, &LoginHandlerMac::CancelAuthDeferred)); 151 NewRunnableMethod(this, &LoginHandlerMac::SendNotifications));
152 ChromeThread::PostTask(
153 ChromeThread::IO, FROM_HERE,
154 NewRunnableMethod(this, &LoginHandlerMac::CancelAuthDeferred));
150 } 155 }
151 156
152 virtual void OnRequestCancelled() { 157 virtual void OnRequestCancelled() {
153 DCHECK(MessageLoop::current() == request_loop_) << 158 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)) <<
154 "Why is OnRequestCancelled called from the UI thread?"; 159 "Why is OnRequestCancelled called from the UI thread?";
155 160
156 // Reference is no longer valid. 161 // Reference is no longer valid.
157 request_ = NULL; 162 request_ = NULL;
158 163
159 // Give up on auth if the request was cancelled. 164 // Give up on auth if the request was cancelled.
160 CancelAuth(); 165 CancelAuth();
161 } 166 }
162 167
163 // Overridden from ConstrainedWindowMacDelegate: 168 // Overridden from ConstrainedWindowMacDelegate:
164 virtual void DeleteDelegate() { 169 virtual void DeleteDelegate() {
165 if (!WasAuthHandled(true)) { 170 if (!WasAuthHandled(true)) {
166 request_loop_->PostTask(FROM_HERE, NewRunnableMethod( 171 ChromeThread::PostTask(
167 this, &LoginHandlerMac::CancelAuthDeferred)); 172 ChromeThread::IO, FROM_HERE,
168 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod( 173 NewRunnableMethod(this, &LoginHandlerMac::CancelAuthDeferred));
169 this, &LoginHandlerMac::SendNotifications)); 174 ChromeThread::PostTask(
175 ChromeThread::UI, FROM_HERE,
176 NewRunnableMethod(this, &LoginHandlerMac::SendNotifications));
170 } 177 }
171 178
172 // Close sheet if it's still open, as required by 179 // Close sheet if it's still open, as required by
173 // ConstrainedWindowMacDelegate. 180 // ConstrainedWindowMacDelegate.
174 DCHECK(MessageLoop::current() == ui_loop_); 181 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
175 if (is_sheet_open()) 182 if (is_sheet_open())
176 [NSApp endSheet:sheet()]; 183 [NSApp endSheet:sheet()];
177 184
178 SetModel(NULL); 185 SetModel(NULL);
179 186
180 // Delete this object once all InvokeLaters have been called. 187 // Delete this object once all InvokeLaters have been called.
181 request_loop_->ReleaseSoon(FROM_HERE, this); 188 ChromeThread::ReleaseSoon(ChromeThread::IO, FROM_HERE, this);
182 } 189 }
183 190
184 void OnLoginPressed(const std::wstring& username, 191 void OnLoginPressed(const std::wstring& username,
185 const std::wstring& password) { 192 const std::wstring& password) {
186 DCHECK(MessageLoop::current() == ui_loop_); 193 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
187 SetAuth(username, password); 194 SetAuth(username, password);
188 } 195 }
189 196
190 void OnCancelPressed() { 197 void OnCancelPressed() {
191 DCHECK(MessageLoop::current() == ui_loop_); 198 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
192 CancelAuth(); 199 CancelAuth();
193 } 200 }
194 201
195 private: 202 private:
196 friend class LoginPrompt; 203 friend class LoginPrompt;
197 204
198 // Calls SetAuth from the request_loop. 205 // Calls SetAuth from the IO loop.
199 void SetAuthDeferred(const std::wstring& username, 206 void SetAuthDeferred(const std::wstring& username,
200 const std::wstring& password) { 207 const std::wstring& password) {
201 DCHECK(MessageLoop::current() == request_loop_); 208 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
202 209
203 if (request_) { 210 if (request_) {
204 request_->SetAuth(username, password); 211 request_->SetAuth(username, password);
205 ResetLoginHandlerForRequest(request_); 212 ResetLoginHandlerForRequest(request_);
206 } 213 }
207 } 214 }
208 215
209 // Calls CancelAuth from the request_loop. 216 // Calls CancelAuth from the IO loop.
210 void CancelAuthDeferred() { 217 void CancelAuthDeferred() {
211 DCHECK(MessageLoop::current() == request_loop_); 218 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
212 219
213 if (request_) { 220 if (request_) {
214 request_->CancelAuth(); 221 request_->CancelAuth();
215 // Verify that CancelAuth does destroy the request via our delegate. 222 // Verify that CancelAuth does destroy the request via our delegate.
216 DCHECK(request_ != NULL); 223 DCHECK(request_ != NULL);
217 ResetLoginHandlerForRequest(request_); 224 ResetLoginHandlerForRequest(request_);
218 } 225 }
219 } 226 }
220 227
221 // Closes the view_contents from the UI loop. 228 // Closes the view_contents from the UI loop.
222 void CloseContentsDeferred() { 229 void CloseContentsDeferred() {
223 DCHECK(MessageLoop::current() == ui_loop_); 230 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
224 231
225 // The hosting ConstrainedWindow may have been freed. 232 // The hosting ConstrainedWindow may have been freed.
226 if (dialog_) 233 if (dialog_)
227 dialog_->CloseConstrainedWindow(); 234 dialog_->CloseConstrainedWindow();
228 } 235 }
229 236
230 // Returns whether authentication had been handled (SetAuth or CancelAuth). 237 // Returns whether authentication had been handled (SetAuth or CancelAuth).
231 // If |set_handled| is true, it will mark authentication as handled. 238 // If |set_handled| is true, it will mark authentication as handled.
232 bool WasAuthHandled(bool set_handled) { 239 bool WasAuthHandled(bool set_handled) {
233 AutoLock lock(handled_auth_lock_); 240 AutoLock lock(handled_auth_lock_);
234 bool was_handled = handled_auth_; 241 bool was_handled = handled_auth_;
235 if (set_handled) 242 if (set_handled)
236 handled_auth_ = true; 243 handled_auth_ = true;
237 return was_handled; 244 return was_handled;
238 } 245 }
239 246
240 // Notify observers that authentication is needed or received. The automation 247 // Notify observers that authentication is needed or received. The automation
241 // proxy uses this for testing. 248 // proxy uses this for testing.
242 void SendNotifications() { 249 void SendNotifications() {
243 DCHECK(MessageLoop::current() == ui_loop_); 250 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
244 251
245 NotificationService* service = NotificationService::current(); 252 NotificationService* service = NotificationService::current();
246 TabContents* requesting_contents = GetTabContentsForLogin(); 253 TabContents* requesting_contents = GetTabContentsForLogin();
247 if (!requesting_contents) 254 if (!requesting_contents)
248 return; 255 return;
249 256
250 NavigationController* controller = &requesting_contents->controller(); 257 NavigationController* controller = &requesting_contents->controller();
251 258
252 if (!WasAuthHandled(false)) { 259 if (!WasAuthHandled(false)) {
253 LoginNotificationDetails details(this); 260 LoginNotificationDetails details(this);
254 service->Notify(NotificationType::AUTH_NEEDED, 261 service->Notify(NotificationType::AUTH_NEEDED,
255 Source<NavigationController>(controller), 262 Source<NavigationController>(controller),
256 Details<LoginNotificationDetails>(&details)); 263 Details<LoginNotificationDetails>(&details));
257 } else { 264 } else {
258 service->Notify(NotificationType::AUTH_SUPPLIED, 265 service->Notify(NotificationType::AUTH_SUPPLIED,
259 Source<NavigationController>(controller), 266 Source<NavigationController>(controller),
260 NotificationService::NoDetails()); 267 NotificationService::NoDetails());
261 } 268 }
262 } 269 }
263 270
264 // True if we've handled auth (SetAuth or CancelAuth has been called). 271 // True if we've handled auth (SetAuth or CancelAuth has been called).
265 bool handled_auth_; 272 bool handled_auth_;
266 Lock handled_auth_lock_; 273 Lock handled_auth_lock_;
267 274
268 // The ConstrainedWindow that is hosting our LoginView. 275 // The ConstrainedWindow that is hosting our LoginView.
269 // This should only be accessed on the ui_loop_. 276 // This should only be accessed on the UI loop.
270 ConstrainedWindow* dialog_; 277 ConstrainedWindow* dialog_;
271 278
272 // The MessageLoop of the thread that the ChromeViewContents lives in.
273 MessageLoop* ui_loop_;
274
275 // The request that wants login data. 279 // The request that wants login data.
276 // This should only be accessed on the request_loop_. 280 // This should only be accessed on the IO loop.
277 URLRequest* request_; 281 URLRequest* request_;
278 282
279 // The MessageLoop of the thread that the URLRequest lives in.
280 MessageLoop* request_loop_;
281
282 // The PasswordForm sent to the PasswordManager. This is so we can refer to it 283 // The PasswordForm sent to the PasswordManager. This is so we can refer to it
283 // when later notifying the password manager if the credentials were accepted 284 // when later notifying the password manager if the credentials were accepted
284 // or rejected. 285 // or rejected.
285 // This should only be accessed on the ui_loop_. 286 // This should only be accessed on the UI loop.
286 PasswordForm password_form_; 287 PasswordForm password_form_;
287 288
288 // Points to the password manager owned by the TabContents requesting auth. 289 // Points to the password manager owned by the TabContents requesting auth.
289 // Can be null if the TabContents is not a TabContents. 290 // Can be null if the TabContents is not a TabContents.
290 // This should only be accessed on the ui_loop_. 291 // This should only be accessed on the UI loop.
291 PasswordManager* password_manager_; 292 PasswordManager* password_manager_;
292 293
293 // Cached from the URLRequest, in case it goes NULL on us. 294 // Cached from the URLRequest, in case it goes NULL on us.
294 int render_process_host_id_; 295 int render_process_host_id_;
295 int tab_contents_id_; 296 int tab_contents_id_;
296 297
297 // The Cocoa controller of the GUI. 298 // The Cocoa controller of the GUI.
298 LoginHandlerSheet* sheet_controller_; 299 LoginHandlerSheet* sheet_controller_;
299 300
300 // If not null, points to a model we need to notify of our own destruction 301 // If not null, points to a model we need to notify of our own destruction
301 // so it doesn't try and access this when its too late. 302 // so it doesn't try and access this when its too late.
302 LoginModel* login_model_; 303 LoginModel* login_model_;
303 304
304 DISALLOW_COPY_AND_ASSIGN(LoginHandlerMac); 305 DISALLOW_COPY_AND_ASSIGN(LoginHandlerMac);
305 }; 306 };
306 307
307 // static 308 // static
308 LoginHandler* LoginHandler::Create(URLRequest* request, MessageLoop* ui_loop) { 309 LoginHandler* LoginHandler::Create(URLRequest* request) {
309 return new LoginHandlerMac(request, ui_loop); 310 return new LoginHandlerMac(request);
310 } 311 }
311 312
312 // ---------------------------------------------------------------------------- 313 // ----------------------------------------------------------------------------
313 // LoginHandlerSheet 314 // LoginHandlerSheet
314 315
315 @implementation LoginHandlerSheet 316 @implementation LoginHandlerSheet
316 317
317 - (id)initWithLoginHandler:(LoginHandlerMac*)handler { 318 - (id)initWithLoginHandler:(LoginHandlerMac*)handler {
318 NSString* nibPath = 319 NSString* nibPath =
319 [mac_util::MainAppBundle() pathForResource:@"HttpAuthLoginSheet" 320 [mac_util::MainAppBundle() pathForResource:@"HttpAuthLoginSheet"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 sizeToFitFixedWidthTextField:explanationField_]; 363 sizeToFitFixedWidthTextField:explanationField_];
363 364
364 // Resize the window (no shifting needed due to window layout). 365 // Resize the window (no shifting needed due to window layout).
365 NSSize windowDelta = NSMakeSize(0, explanationShift); 366 NSSize windowDelta = NSMakeSize(0, explanationShift);
366 [GTMUILocalizerAndLayoutTweaker 367 [GTMUILocalizerAndLayoutTweaker
367 resizeWindowWithoutAutoResizingSubViews:[self window] 368 resizeWindowWithoutAutoResizingSubViews:[self window]
368 delta:windowDelta]; 369 delta:windowDelta];
369 } 370 }
370 371
371 @end 372 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698