summaryrefslogtreecommitdiffstats
path: root/chrome/browser/external_tab_container.cc
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-30 00:47:06 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-30 00:47:06 +0000
commit18290eb6249c95069b20c3bdfc8163900d2a17a8 (patch)
tree8862c66a30c07241a9c31a0fba185e3c845613c1 /chrome/browser/external_tab_container.cc
parent94a3fbfa2fb5da363960d538938e4887e52d1345 (diff)
downloadchromium_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.cc54
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();
+}
+