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

Unified Diff: chrome/browser/ui/login/login_prompt.cc

Issue 5814005: Minimize login prompts (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Add const and fix braces Created 9 years, 12 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/login/login_prompt.h ('k') | chrome/browser/ui/login/login_prompt_browsertest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/login/login_prompt.cc
diff --git a/chrome/browser/ui/login/login_prompt.cc b/chrome/browser/ui/login/login_prompt.cc
index 40cc66a1475a651e98c76d1b5241f0f4abbc7f3a..e58d53a677b77ce891d553fbd1910917ed37299b 100644
--- a/chrome/browser/ui/login/login_prompt.cc
+++ b/chrome/browser/ui/login/login_prompt.cc
@@ -116,7 +116,9 @@ TabContents* LoginHandler::GetTabContentsForLogin() const {
void LoginHandler::SetAuth(const std::wstring& username,
const std::wstring& password) {
- if (WasAuthHandled(true))
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (TestAndSetAuthHandled())
return;
// Tell the password manager the credentials were submitted / accepted.
@@ -126,30 +128,40 @@ void LoginHandler::SetAuth(const std::wstring& username,
password_manager_->ProvisionallySavePassword(password_form_);
}
+ // Calling NotifyAuthSupplied() directly instead of posting a task
+ // allows other LoginHandler instances to queue their
+ // CloseContentsDeferred() before ours. Closing dialogs in the
+ // opposite order as they were created avoids races where remaining
+ // dialogs in the same tab may be briefly displayed to the user
+ // before they are removed.
+ NotifyAuthSupplied(username, password);
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(this, &LoginHandler::CloseContentsDeferred));
BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- this, &LoginHandler::NotifyAuthSupplied, username, password));
- BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(
this, &LoginHandler::SetAuthDeferred, username, password));
}
void LoginHandler::CancelAuth() {
- if (WasAuthHandled(true))
+ if (TestAndSetAuthHandled())
return;
+ // Similar to how we deal with notifications above in SetAuth()
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ NotifyAuthCancelled();
+ } else {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &LoginHandler::NotifyAuthCancelled));
+ }
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(this, &LoginHandler::CloseContentsDeferred));
BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this, &LoginHandler::NotifyAuthCancelled));
- BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(this, &LoginHandler::CancelAuthDeferred));
}
@@ -196,17 +208,17 @@ void LoginHandler::Observe(NotificationType type,
if (!requesting_contents)
return;
- NavigationController* this_controller = &requesting_contents->controller();
- NavigationController* that_controller =
- Source<NavigationController>(source).ptr();
-
- // Only handle notifications from other handlers.
- if (this_controller == that_controller)
+ // Break out early if we aren't interested in the notification.
+ if (WasAuthHandled())
return;
LoginNotificationDetails* login_details =
Details<LoginNotificationDetails>(details).ptr();
+ // WasAuthHandled() should always test positive before we publish
+ // AUTH_SUPPLIED or AUTH_CANCELLED notifications.
+ DCHECK(login_details->handler() != this);
+
// Only handle notification for the identical auth info.
if (*login_details->handler()->auth_info() != *auth_info())
return;
@@ -236,7 +248,7 @@ void LoginHandler::SetDialog(ConstrainedWindow* dialog) {
void LoginHandler::NotifyAuthNeeded() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (WasAuthHandled(false))
+ if (WasAuthHandled())
return;
TabContents* requesting_contents = GetTabContentsForLogin();
@@ -254,7 +266,7 @@ void LoginHandler::NotifyAuthNeeded() {
void LoginHandler::NotifyAuthCancelled() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(WasAuthHandled(false));
+ DCHECK(WasAuthHandled());
TabContents* requesting_contents = GetTabContentsForLogin();
if (!requesting_contents)
@@ -272,7 +284,7 @@ void LoginHandler::NotifyAuthCancelled() {
void LoginHandler::NotifyAuthSupplied(const std::wstring& username,
const std::wstring& password) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(WasAuthHandled(false));
+ DCHECK(WasAuthHandled());
TabContents* requesting_contents = GetTabContentsForLogin();
if (!requesting_contents)
@@ -288,7 +300,7 @@ void LoginHandler::NotifyAuthSupplied(const std::wstring& username,
}
void LoginHandler::ReleaseSoon() {
- if (!WasAuthHandled(true)) {
+ if (!TestAndSetAuthHandled()) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(this, &LoginHandler::CancelAuthDeferred));
@@ -306,12 +318,17 @@ void LoginHandler::ReleaseSoon() {
}
// Returns whether authentication had been handled (SetAuth or CancelAuth).
-// If |set_handled| is true, it will mark authentication as handled.
-bool LoginHandler::WasAuthHandled(bool set_handled) {
+bool LoginHandler::WasAuthHandled() const {
+ AutoLock lock(handled_auth_lock_);
+ bool was_handled = handled_auth_;
+ return was_handled;
+}
+
+// Marks authentication as handled and returns the previous handled state.
+bool LoginHandler::TestAndSetAuthHandled() {
AutoLock lock(handled_auth_lock_);
bool was_handled = handled_auth_;
- if (set_handled)
- handled_auth_ = true;
+ handled_auth_ = true;
return was_handled;
}
@@ -365,7 +382,7 @@ class LoginDialogTask : public Task {
void Run() {
TabContents* parent_contents = handler_->GetTabContentsForLogin();
- if (!parent_contents) {
+ if (!parent_contents || handler_->WasAuthHandled()) {
// The request may have been cancelled, or it may be for a renderer
// not hosted by a tab (e.g. an extension). Cancel just in case
// (cancelling twice is a no-op).
« no previous file with comments | « chrome/browser/ui/login/login_prompt.h ('k') | chrome/browser/ui/login/login_prompt_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698