diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-30 00:47:06 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-30 00:47:06 +0000 |
commit | 18290eb6249c95069b20c3bdfc8163900d2a17a8 (patch) | |
tree | 8862c66a30c07241a9c31a0fba185e3c845613c1 /chrome/browser/external_tab_container.cc | |
parent | 94a3fbfa2fb5da363960d538938e4887e52d1345 (diff) | |
download | chromium_src-18290eb6249c95069b20c3bdfc8163900d2a17a8.zip chromium_src-18290eb6249c95069b20c3bdfc8163900d2a17a8.tar.gz chromium_src-18290eb6249c95069b20c3bdfc8163900d2a17a8.tar.bz2 |
In IE8 new windows opened within ChromeFrame via window.open calls at times bypass the host network stack.
In this case we don't get control over the navigation as window.open calls expect to carry the opener
relationship over to the new window. This basically means that navigation occurs in Chrome and the
new tab/window created by the host attaches to the newly created ExternalTabContainer instance.
In IE8 the new tab opens in a new IE process, which basically uses a new automation channel to talk to
Chrome. The host network stack implementation routes network requests issued by registered render views
to the host browser over the automation channel. There is a timing window between the new window getting
created and issuing network requests and the channel being established with the new iexplore instance.
As a result network requests issued by the new window don't use the host network stack.
Fix is to register the render view and process as a pending view when we get notified about the new TabContents
in the original ExternalTabContainers implementation of TabContentsDelegate::AddNewContents. Any network requests
issued for this view would result in the corresponding URLRequestAutomationJob instances getting created as
pending as well. When the host browser connects to the new ExternalTabContainer instance, we pass over the new
automation channel and tab handle to the URLRequestAutomationJob instances and resume them.
This fixes bug http://code.google.com/p/chromium/issues/detail?id=33516
Bug=33516
Test=Login to gmail in IE8 in ChromeFrame. Open up a new conversation and click on New Window which opens up
a tear off window. This should not bring up the login prompt again.
Will think about a good approach to write a unit test for this behavior and send out a separate CL for that.
Review URL: http://codereview.chromium.org/554134
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37585 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/external_tab_container.cc')
-rw-r--r-- | chrome/browser/external_tab_container.cc | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc index bb3f603..e717490 100644 --- a/chrome/browser/external_tab_container.cc +++ b/chrome/browser/external_tab_container.cc @@ -48,7 +48,8 @@ ExternalTabContainer::ExternalTabContainer( handle_top_level_requests_(false), external_method_factory_(this), enabled_extension_automation_(false), - waiting_for_unload_event_(false) { + waiting_for_unload_event_(false), + pending_(false) { } ExternalTabContainer::~ExternalTabContainer() { @@ -207,7 +208,7 @@ bool ExternalTabContainer::Reinitialize( RenderViewHost* rvh = tab_contents_->render_view_host(); if (rvh) { - AutomationResourceMessageFilter::RegisterRenderView( + AutomationResourceMessageFilter::ResumePendingRenderView( rvh->process()->id(), rvh->routing_id(), tab_handle_, automation_resource_message_filter_); } @@ -218,7 +219,7 @@ bool ExternalTabContainer::Reinitialize( MessageLoop::current()->PostTask( FROM_HERE, external_method_factory_.NewRunnableMethod( - &ExternalTabContainer::NavigationStateChanged, tab_contents_, 0)); + &ExternalTabContainer::OnReinitialize)); return true; } @@ -276,6 +277,17 @@ void ExternalTabContainer::OpenURLFromTab(TabContents* source, const GURL& referrer, WindowOpenDisposition disposition, PageTransition::Type transition) { + if (pending()) { + PendingTopLevelNavigation url_request; + url_request.disposition = disposition; + url_request.transition = transition; + url_request.url = url; + url_request.referrer = referrer; + + pending_open_url_requests_.push_back(url_request); + return; + } + switch (disposition) { case CURRENT_TAB: case SINGLETON_TAB: @@ -333,6 +345,19 @@ void ExternalTabContainer::AddNewContents(TabContents* source, pending_tabs_[reinterpret_cast<intptr_t>(new_container.get())] = new_container; + new_container->set_pending(true); + + RenderViewHost* rvh = new_contents->render_view_host(); + DCHECK(rvh != NULL); + if (rvh) { + // Register this render view as a pending render view, i.e. any network + // requests initiated by this render view would be serviced when the + // external host connects to the new external tab instance. + AutomationResourceMessageFilter::RegisterRenderView( + rvh->process()->id(), rvh->routing_id(), + tab_handle_, automation_resource_message_filter_, + true); + } automation_->Send(new AutomationMsg_AttachExternalTab( 0, tab_handle_, @@ -573,7 +598,7 @@ void ExternalTabContainer::Observe(NotificationType type, if (rvh) { AutomationResourceMessageFilter::RegisterRenderView( rvh->process()->id(), rvh->routing_id(), - tab_handle_, automation_resource_message_filter_); + tab_handle_, automation_resource_message_filter_, false); } } break; @@ -818,3 +843,24 @@ void ExternalTabContainer::LoadAccelerators() { focus_manager->RegisterAccelerator(accelerator, this); } } + +void ExternalTabContainer::OnReinitialize() { + NavigationStateChanged(tab_contents_, 0); + ServicePendingOpenURLRequests(); +} + +void ExternalTabContainer::ServicePendingOpenURLRequests() { + DCHECK(pending()); + + set_pending(false); + + for (size_t index = 0; index < pending_open_url_requests_.size(); + index ++) { + const PendingTopLevelNavigation& url_request = + pending_open_url_requests_[index]; + OpenURLFromTab(tab_contents_, url_request.url, url_request.referrer, + url_request.disposition, url_request.transition); + } + pending_open_url_requests_.clear(); +} + |