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

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: sync 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 error page loads in a
cbentzel 2012/08/15 17:00:38 "Link Doctor pages act like error page loads in a
mmenke 2012/08/16 14:30:03 Correct. "two" added
+ // row. The second time, provisional_render_view_host_ will be NULL.
cbentzel 2012/08/15 17:00:38 Why will provisional_render_view_host_ be NULL? Wi
mmenke 2012/08/16 14:30:03 It's: - provisional load - provisional load fails
+ if (is_error_page && provisional_render_view_host_ == render_view_host)
+ return;
+ // Otherwise, abort the old load.
+ tab_reloader_->OnAbort();
+ }
- // 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.
+ tab_reloader_->OnAbort();
- tab_reloader_->OnLoadCommitted(pending_error_code_);
+ // Send information about the new load.
cbentzel 2012/08/15 17:00:38 Why do you need to do this? Just for stats?
mmenke 2012/08/16 14:30:03 To make TabReloader's interface a bit better defin
cbentzel 2012/08/16 19:15:04 I think this is fine.
+ tab_reloader_->OnLoadStart(url.SchemeIsSecure());
+ tab_reloader_->OnLoadCommitted(net::OK);
+ }
+
+ provisional_render_view_host_ = NULL;
pending_error_code_ = net::OK;
}
@@ -102,15 +119,15 @@
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) {
+ // 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;
@@ -133,33 +150,52 @@
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_) {
+ provisional_render_view_host_ = NULL;
cbentzel 2012/08/15 17:00:38 Should you share this logic with the error_code ==
mmenke 2012/08/16 14:30:03 Done. Went ahead and used the same function for t
+ pending_error_code_ = net::OK;
+ tab_reloader_->OnAbort();
+ }
+ 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 ||
cbentzel 2012/08/15 17:00:38 Would child_id ever be -1 here?
mmenke 2012/08/16 14:30:03 Since the id is actually used to lookup the Render
+ child_id != GetProvisionalChildID()) {
return;
}
@@ -214,4 +250,10 @@
tab_contents->captive_portal_tab_helper()->SetIsLoginTab();
}
+int CaptivePortalTabHelper::GetProvisionalChildID() const {
+ if (!provisional_render_view_host_)
+ return -1;
+ return provisional_render_view_host_->GetProcess()->GetID();
+}
+
} // namespace captive_portal

Powered by Google App Engine
This is Rietveld 408576698