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

Unified Diff: chrome/browser/captive_portal/captive_portal_tab_helper.cc

Issue 10837146: Fix how captive portals track which page is loading. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Inline GetProcessID, get rid of TestCaptivePortalTabHelper Created 8 years, 4 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
Index: chrome/browser/captive_portal/captive_portal_tab_helper.cc
===================================================================
--- chrome/browser/captive_portal/captive_portal_tab_helper.cc (revision 151564)
+++ chrome/browser/captive_portal/captive_portal_tab_helper.cc (working copy)
@@ -14,9 +14,13 @@
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_request_details.h"
+#include "content/public/browser/web_contents.h"
#include "net/base/net_errors.h"
namespace captive_portal {
@@ -34,13 +38,16 @@
login_detector_(new CaptivePortalLoginDetector(profile)),
profile_(profile),
pending_error_code_(net::OK),
- provisional_main_frame_id_(-1) {
+ provisional_render_view_host_(NULL) {
registrar_.Add(this,
chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
content::Source<Profile>(profile_));
registrar_.Add(this,
content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
content::Source<content::WebContents>(web_contents));
+ registrar_.Add(this,
+ content::NOTIFICATION_RENDER_VIEW_HOST_DELETED,
+ content::NotificationService::AllSources());
}
CaptivePortalTabHelper::~CaptivePortalTabHelper() {
@@ -58,18 +65,17 @@
if (!is_main_frame)
return;
- provisional_main_frame_id_ = frame_id;
+ if (provisional_render_view_host_) {
+ // If loading an error page for a previous failure, treat this as part of
+ // the previous load. Link Doctor pages act like two error page loads in a
+ // row. The second time, provisional_render_view_host_ will be NULL.
+ if (is_error_page && provisional_render_view_host_ == render_view_host)
+ return;
+ // Otherwise, abort the old load.
+ OnLoadAborted();
+ }
- // If loading an error page for a previous failure, treat this as part of
- // the previous load. The second check is needed because Link Doctor pages
- // result in two error page provisional loads in a row. Currently, the
- // second load is treated as a normal load, rather than reusing old error
- // codes.
- if (is_error_page && pending_error_code_ != net::OK)
- return;
-
- // Makes the second load for Link Doctor pages act as a normal load.
- // TODO(mmenke): Figure out if this affects any other cases.
+ provisional_render_view_host_ = render_view_host;
pending_error_code_ = net::OK;
tab_reloader_->OnLoadStart(validated_url.SchemeIsSecure());
@@ -87,9 +93,20 @@
if (!is_main_frame)
return;
- provisional_main_frame_id_ = -1;
+ if (provisional_render_view_host_ == render_view_host) {
+ tab_reloader_->OnLoadCommitted(pending_error_code_);
+ } else {
+ // This may happen if the active RenderView commits a page before a cross
+ // process navigation cancels the old load. In this case, the commit of the
+ // old navigation will cancel the newer one.
+ OnLoadAborted();
- tab_reloader_->OnLoadCommitted(pending_error_code_);
+ // Send information about the new load.
+ tab_reloader_->OnLoadStart(url.SchemeIsSecure());
+ tab_reloader_->OnLoadCommitted(net::OK);
+ }
+
+ provisional_render_view_host_ = NULL;
pending_error_code_ = net::OK;
}
@@ -102,19 +119,14 @@
content::RenderViewHost* render_view_host) {
DCHECK(CalledOnValidThread());
- // Ignore subframes.
- if (!is_main_frame)
+ // Ignore subframes and unexpected RenderViewHosts.
+ if (!is_main_frame || render_view_host != provisional_render_view_host_)
return;
- provisional_main_frame_id_ = -1;
-
// Aborts generally aren't followed by loading an error page, so go ahead and
// reset the state now, to prevent any captive portal checks from triggering.
if (error_code == net::ERR_ABORTED) {
- // May have been aborting the load of an error page.
- pending_error_code_ = net::OK;
-
- tab_reloader_->OnAbort();
+ OnLoadAborted();
return;
}
@@ -133,33 +145,50 @@
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK(CalledOnValidThread());
- if (type == content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT) {
- DCHECK_EQ(web_contents(),
- content::Source<content::WebContents>(source).ptr());
+ switch (type) {
+ case content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: {
+ DCHECK_EQ(web_contents(),
+ content::Source<content::WebContents>(source).ptr());
- const content::ResourceRedirectDetails* redirect_details =
- content::Details<content::ResourceRedirectDetails>(details).ptr();
+ const content::ResourceRedirectDetails* redirect_details =
+ content::Details<content::ResourceRedirectDetails>(details).ptr();
- if (redirect_details->resource_type == ResourceType::MAIN_FRAME)
- OnRedirect(redirect_details->frame_id, redirect_details->new_url);
- } else if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
- DCHECK_EQ(profile_, content::Source<Profile>(source).ptr());
+ OnRedirect(redirect_details->origin_child_id,
+ redirect_details->resource_type,
+ redirect_details->new_url);
+ break;
+ }
+ case chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT: {
+ DCHECK_EQ(profile_, content::Source<Profile>(source).ptr());
- const CaptivePortalService::Results* results =
- content::Details<CaptivePortalService::Results>(details).ptr();
+ const CaptivePortalService::Results* results =
+ content::Details<CaptivePortalService::Results>(details).ptr();
- OnCaptivePortalResults(results->previous_result, results->result);
- } else {
- NOTREACHED();
+ OnCaptivePortalResults(results->previous_result, results->result);
+ break;
+ }
+ case content::NOTIFICATION_RENDER_VIEW_HOST_DELETED: {
+ content::RenderViewHost* render_view_host =
+ content::Source<content::RenderViewHost>(source).ptr();
+ // This can happen when a cross-process navigation is aborted, either by
+ // pressing stop or by starting a new cross-process navigation that can't
+ // re-use |provisional_render_view_host_|. May also happen on a crash.
+ if (render_view_host == provisional_render_view_host_)
+ OnLoadAborted();
+ break;
+ }
+ default:
+ NOTREACHED();
}
}
-void CaptivePortalTabHelper::OnRedirect(int64 frame_id, const GURL& new_url) {
- // If the main frame's not currently loading, or the redirect is for some
- // other frame, ignore the redirect. It's unclear if |frame_id| can ever be
- // -1 ("invalid/unknown"), but best to be careful.
- if (provisional_main_frame_id_ == -1 ||
- provisional_main_frame_id_ != frame_id) {
+void CaptivePortalTabHelper::OnRedirect(int child_id,
+ ResourceType::Type resource_type,
+ const GURL& new_url) {
+ // Only main frame redirects for the provisional RenderViewHost matter.
+ if (resource_type != ResourceType::MAIN_FRAME ||
+ !provisional_render_view_host_ ||
+ provisional_render_view_host_->GetProcess()->GetID() != child_id) {
return;
}
@@ -172,6 +201,15 @@
login_detector_->OnCaptivePortalResults(previous_result, result);
}
+void CaptivePortalTabHelper::OnLoadAborted() {
+ // No further messages for the cancelled navigation will occur.
+ provisional_render_view_host_ = NULL;
+ // May have been aborting the load of an error page.
+ pending_error_code_ = net::OK;
+
+ tab_reloader_->OnAbort();
+}
+
bool CaptivePortalTabHelper::IsLoginTab() const {
cbentzel 2012/08/16 19:15:05 Nit: This doesn't match ordering in header.
mmenke 2012/08/16 19:18:34 Done.
return login_detector_->is_login_tab();
}

Powered by Google App Engine
This is Rietveld 408576698