summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeremya@chromium.org <jeremya@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-26 00:29:28 +0000
committerjeremya@chromium.org <jeremya@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-26 00:29:28 +0000
commit50b6601e6fbe1862226c072952d52eae1556a6ae (patch)
treeca498a3a4cf302947283673b3f65d4fa466667ac
parent5eff57ede25d7fe51c3bb964aaba2745e3fb1896 (diff)
downloadchromium_src-50b6601e6fbe1862226c072952d52eae1556a6ae.zip
chromium_src-50b6601e6fbe1862226c072952d52eae1556a6ae.tar.gz
chromium_src-50b6601e6fbe1862226c072952d52eae1556a6ae.tar.bz2
Make chrome.appWindow.create() provide access to the child window at a predictable time.
When you first create a window with chrome.appWindow.create(), it won't have loaded any resources. So, at create time, you are guaranteed that: child_window.location.href == 'about:blank' child_window.document.documentElement.outerHTML == '<html><head></head><body></body></html>' This is in line with the behaviour of window.open(). BUG=131735 TEST=browser_tests:PlatformAppBrowserTest.WindowsApi Review URL: https://chromiumcodereview.appspot.com/10644006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144072 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/platform_app_browsertest.cc2
-rw-r--r--chrome/browser/renderer_host/chrome_render_message_filter.cc8
-rw-r--r--chrome/browser/renderer_host/chrome_render_message_filter.h1
-rw-r--r--chrome/browser/ui/extensions/shell_window.cc45
-rw-r--r--chrome/common/extensions/extension_messages.h3
-rw-r--r--chrome/renderer/extensions/app_window_custom_bindings.cc9
-rw-r--r--chrome/renderer/resources/extensions/app_window_custom_bindings.js6
-rw-r--r--chrome/test/data/extensions/platform_apps/windows_api/test.js3
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host_impl.cc1
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host_impl.h12
-rw-r--r--content/public/browser/resource_dispatcher_host.h8
11 files changed, 79 insertions, 19 deletions
diff --git a/chrome/browser/extensions/platform_app_browsertest.cc b/chrome/browser/extensions/platform_app_browsertest.cc
index 11982ae..2343181 100644
--- a/chrome/browser/extensions/platform_app_browsertest.cc
+++ b/chrome/browser/extensions/platform_app_browsertest.cc
@@ -110,7 +110,7 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, Restrictions) {
ASSERT_TRUE(RunPlatformAppTest("platform_apps/restrictions")) << message_;
}
-// Tests that platform apps can use the chrome.windows.* API.
+// Tests that platform apps can use the chrome.appWindow.* API.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, WindowsApi) {
ASSERT_TRUE(RunPlatformAppTest("platform_apps/windows_api")) << message_;
}
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc
index 722fb1b..ffc0223 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.cc
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -35,6 +35,7 @@
#include "chrome/common/url_constants.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/common/process_type.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
@@ -101,6 +102,8 @@ bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message,
IPC_MESSAGE_HANDLER(ExtensionHostMsg_GenerateUniqueID,
OnExtensionGenerateUniqueID)
IPC_MESSAGE_HANDLER(ExtensionHostMsg_UnloadAck, OnExtensionUnloadAck)
+ IPC_MESSAGE_HANDLER(ExtensionHostMsg_ResumeRequests,
+ OnExtensionResumeRequests);
#if defined(USE_TCMALLOC)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_WriteTcmallocHeapProfile_ACK,
OnWriteTcmallocHeapProfile)
@@ -417,6 +420,11 @@ void ChromeRenderMessageFilter::OnExtensionGenerateUniqueID(int* unique_id) {
*unique_id = next_unique_id++;
}
+void ChromeRenderMessageFilter::OnExtensionResumeRequests(int route_id) {
+ content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute(
+ render_process_id_, route_id);
+}
+
#if defined(USE_TCMALLOC)
void ChromeRenderMessageFilter::OnWriteTcmallocHeapProfile(
const FilePath::StringType& filepath,
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.h b/chrome/browser/renderer_host/chrome_render_message_filter.h
index af0b82b..45efb40 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.h
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.h
@@ -125,6 +125,7 @@ class ChromeRenderMessageFilter : public content::BrowserMessageFilter {
int sequence_id);
void OnExtensionUnloadAck(const std::string& extension_id);
void OnExtensionGenerateUniqueID(int* unique_id);
+ void OnExtensionResumeRequests(int route_id);
#if defined(USE_TCMALLOC)
void OnRendererTcmalloc(const std::string& output);
void OnWriteTcmallocHeapProfile(const FilePath::StringType& filename,
diff --git a/chrome/browser/ui/extensions/shell_window.cc b/chrome/browser/ui/extensions/shell_window.cc
index af6aa86..d447596 100644
--- a/chrome/browser/ui/extensions/shell_window.cc
+++ b/chrome/browser/ui/extensions/shell_window.cc
@@ -8,8 +8,8 @@
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/file_select_helper.h"
-#include "chrome/browser/intents/web_intents_util.h"
#include "chrome/browser/infobars/infobar_tab_helper.h"
+#include "chrome/browser/intents/web_intents_util.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_id.h"
@@ -22,25 +22,39 @@
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_messages.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_entry.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_dispatcher_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_intents_dispatcher.h"
#include "content/public/common/renderer_preferences.h"
+using content::BrowserThread;
using content::ConsoleMessageLevel;
+using content::RenderViewHost;
+using content::ResourceDispatcherHost;
using content::SiteInstance;
using content::WebContents;
namespace {
-static const int kDefaultWidth = 512;
-static const int kDefaultHeight = 384;
+const int kDefaultWidth = 512;
+const int kDefaultHeight = 384;
+
+void SuspendRenderViewHost(RenderViewHost* rvh) {
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&ResourceDispatcherHost::BlockRequestsForRoute,
+ base::Unretained(ResourceDispatcherHost::Get()),
+ rvh->GetProcess()->GetID(), rvh->GetRoutingID()));
+}
+
} // namespace
ShellWindow::CreateParams::CreateParams()
@@ -82,9 +96,25 @@ ShellWindow::ShellWindow(Profile* profile,
browser_handles_all_top_level_requests = true;
web_contents_->GetRenderViewHost()->SyncRendererPrefs();
+ // Block the created RVH from loading anything until the background page
+ // has had a chance to do any initialization it wants.
+ SuspendRenderViewHost(web_contents_->GetRenderViewHost());
+
+ // TODO(jeremya): there's a bug where navigating a web contents to an
+ // extension URL causes it to create a new RVH and discard the old (perfectly
+ // usable) one. To work around this, we watch for a RVH_CHANGED message from
+ // the web contents (which will be sent during LoadURL) and suspend resource
+ // requests on the new RVH to ensure that we block the new RVH from loading
+ // anything. It should be okay to remove the NOTIFICATION_RVH_CHANGED
+ // registration once http://crbug.com/123007 is fixed.
+ registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
+ content::Source<content::NavigationController>(
+ &web_contents_->GetController()));
web_contents_->GetController().LoadURL(
url, content::Referrer(), content::PAGE_TRANSITION_LINK,
std::string());
+ registrar_.RemoveAll();
+
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
content::Source<Profile>(profile_));
// Close when the browser is exiting.
@@ -284,6 +314,15 @@ void ShellWindow::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
+ case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: {
+ // TODO(jeremya): once http://crbug.com/123007 is fixed, we'll no longer
+ // need to suspend resource requests here (the call in the constructor
+ // should be enough).
+ content::Details<std::pair<RenderViewHost*, RenderViewHost*> >
+ host_details(details);
+ SuspendRenderViewHost(host_details->second);
+ break;
+ }
case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
const extensions::Extension* unloaded_extension =
content::Details<extensions::UnloadedExtensionInfo>(
diff --git a/chrome/common/extensions/extension_messages.h b/chrome/common/extensions/extension_messages.h
index dfc8df9..9745bf2 100644
--- a/chrome/common/extensions/extension_messages.h
+++ b/chrome/common/extensions/extension_messages.h
@@ -479,3 +479,6 @@ IPC_MESSAGE_ROUTED0(ExtensionHostMsg_DecrementLazyKeepaliveCount)
// browser process.
IPC_SYNC_MESSAGE_CONTROL0_1(ExtensionHostMsg_GenerateUniqueID,
int /* unique_id */)
+
+// Resumes resource requests for a newly created app window.
+IPC_MESSAGE_CONTROL1(ExtensionHostMsg_ResumeRequests, int /* route_id */)
diff --git a/chrome/renderer/extensions/app_window_custom_bindings.cc b/chrome/renderer/extensions/app_window_custom_bindings.cc
index 48027a1..4a93595 100644
--- a/chrome/renderer/extensions/app_window_custom_bindings.cc
+++ b/chrome/renderer/extensions/app_window_custom_bindings.cc
@@ -12,15 +12,16 @@
#include "chrome/common/url_constants.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_helper.h"
+#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "grit/renderer_resources.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebNavigationPolicy.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebWindowFeatures.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebNavigationPolicy.h"
-#include "webkit/glue/webkit_glue.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h"
#include "v8/include/v8.h"
+#include "webkit/glue/webkit_glue.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_visitor.h"
@@ -92,6 +93,8 @@ v8::Handle<v8::Value> AppWindowCustomBindings::GetView(
WebKit::WebFrame* opener = render_view->GetWebView()->mainFrame();
WebKit::WebFrame* frame = view->GetWebView()->mainFrame();
frame->setOpener(opener);
+ content::RenderThread::Get()->Send(
+ new ExtensionHostMsg_ResumeRequests(view->GetRoutingID()));
v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global();
return window;
diff --git a/chrome/renderer/resources/extensions/app_window_custom_bindings.js b/chrome/renderer/resources/extensions/app_window_custom_bindings.js
index e3d71c1..23e7073 100644
--- a/chrome/renderer/resources/extensions/app_window_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/app_window_custom_bindings.js
@@ -11,10 +11,10 @@ var GetView = appWindowNatives.GetView;
chromeHidden.registerCustomHook('appWindow', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
- apiFunctions.setCustomCallback('create', function(name, request, view_id) {
+ apiFunctions.setCustomCallback('create', function(name, request, viewId) {
var view = null;
- if (view_id)
- view = GetView(view_id);
+ if (viewId)
+ view = GetView(viewId);
if (request.callback) {
request.callback(view);
delete request.callback;
diff --git a/chrome/test/data/extensions/platform_apps/windows_api/test.js b/chrome/test/data/extensions/platform_apps/windows_api/test.js
index 0c4b51e..9b8163f 100644
--- a/chrome/test/data/extensions/platform_apps/windows_api/test.js
+++ b/chrome/test/data/extensions/platform_apps/windows_api/test.js
@@ -9,6 +9,9 @@ chrome.experimental.app.onLaunched.addListener(function() {
function testCreateWindow() {
chrome.appWindow.create('test.html', {}, callbackPass(function (win) {
chrome.test.assertTrue(typeof win.window === 'object');
+ chrome.test.assertEq('about:blank', win.location.href);
+ chrome.test.assertEq('<html><head></head><body></body></html>',
+ win.document.documentElement.outerHTML);
}))
},
diff --git a/content/browser/renderer_host/resource_dispatcher_host_impl.cc b/content/browser/renderer_host/resource_dispatcher_host_impl.cc
index 9514845..692f7f3 100644
--- a/content/browser/renderer_host/resource_dispatcher_host_impl.cc
+++ b/content/browser/renderer_host/resource_dispatcher_host_impl.cc
@@ -1631,6 +1631,7 @@ void ResourceDispatcherHostImpl::UpdateLoadStates() {
void ResourceDispatcherHostImpl::BlockRequestsForRoute(int child_id,
int route_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
ProcessRouteIDs key(child_id, route_id);
DCHECK(blocked_loaders_map_.find(key) == blocked_loaders_map_.end()) <<
"BlockRequestsForRoute called multiple time for the same RVH";
diff --git a/content/browser/renderer_host/resource_dispatcher_host_impl.h b/content/browser/renderer_host/resource_dispatcher_host_impl.h
index d8fece0..4e1b6aa 100644
--- a/content/browser/renderer_host/resource_dispatcher_host_impl.h
+++ b/content/browser/renderer_host/resource_dispatcher_host_impl.h
@@ -86,6 +86,9 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
const DownloadSaveInfo& save_info,
const DownloadStartedCallback& started_callback) OVERRIDE;
virtual void ClearLoginDelegateForRequest(net::URLRequest* request) OVERRIDE;
+ virtual void BlockRequestsForRoute(int child_id, int route_id) OVERRIDE;
+ virtual void ResumeBlockedRequestsForRoute(
+ int child_id, int route_id) OVERRIDE;
// Puts the resource dispatcher host in an inactive state (unable to begin
// new requests). Cancels all pending requests.
@@ -176,15 +179,6 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
void RemovePendingRequest(int child_id, int request_id);
- // Causes all new requests for the route identified by
- // |child_id| and |route_id| to be blocked (not being
- // started) until ResumeBlockedRequestsForRoute or
- // CancelBlockedRequestsForRoute is called.
- void BlockRequestsForRoute(int child_id, int route_id);
-
- // Resumes any blocked request for the specified route id.
- void ResumeBlockedRequestsForRoute(int child_id, int route_id);
-
// Cancels any blocked request for the specified route id.
void CancelBlockedRequestsForRoute(int child_id, int route_id);
diff --git a/content/public/browser/resource_dispatcher_host.h b/content/public/browser/resource_dispatcher_host.h
index d6f813b..d289366 100644
--- a/content/public/browser/resource_dispatcher_host.h
+++ b/content/public/browser/resource_dispatcher_host.h
@@ -53,6 +53,14 @@ class CONTENT_EXPORT ResourceDispatcherHost {
// Clears the ResourceDispatcherHostLoginDelegate associated with the request.
virtual void ClearLoginDelegateForRequest(net::URLRequest* request) = 0;
+ // Causes all new requests for the route identified by |child_id| and
+ // |route_id| to be blocked (not being started) until
+ // ResumeBlockedRequestsForRoute is called.
+ virtual void BlockRequestsForRoute(int child_id, int route_id) = 0;
+
+ // Resumes any blocked request for the specified route id.
+ virtual void ResumeBlockedRequestsForRoute(int child_id, int route_id) = 0;
+
protected:
virtual ~ResourceDispatcherHost() {}
};