diff options
author | guohui@chromium.org <guohui@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-24 17:01:44 +0000 |
---|---|---|
committer | guohui@chromium.org <guohui@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-24 17:01:44 +0000 |
commit | 22aa4f87dafd3b5071c74ec8666ab90696cc4811 (patch) | |
tree | 1c4976a830bcee881cc2f07f50208c72d1803f7f | |
parent | 616965f6faf9d4c2c18f5efd5a118d8511ccc929 (diff) | |
download | chromium_src-22aa4f87dafd3b5071c74ec8666ab90696cc4811.zip chromium_src-22aa4f87dafd3b5071c74ec8666ab90696cc4811.tar.gz chromium_src-22aa4f87dafd3b5071c74ec8666ab90696cc4811.tar.bz2 |
Support webview tag when the container ext/app is embedded in a webUI
Design doc at https://docs.google.com/a/google.com/document/d/1LcriMmLY76IUhFO5rWh3Tz6xDFkGPNnL4MYSIBD4Jbc/edit#
BUG=285151
R=cdn@chromium.org, creis@chromium.org, fsamuel@chromium.org, jochen@chromium.org
Review URL: https://codereview.chromium.org/23530029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225014 0039d316-1c4b-4281-b951-d872f2087c98
11 files changed, 50 insertions, 25 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index d4e15d9..367878b 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -126,6 +126,7 @@ #include "content/public/browser/web_contents_view.h" #include "content/public/common/child_process_host.h" #include "content/public/common/content_descriptors.h" +#include "content/public/common/url_utils.h" #include "extensions/browser/view_type_utils.h" #include "extensions/common/constants.h" #include "extensions/common/switches.h" @@ -790,6 +791,7 @@ void ChromeContentBrowserClient::GuestWebContentsCreated( void ChromeContentBrowserClient::GuestWebContentsAttached( WebContents* guest_web_contents, WebContents* embedder_web_contents, + const GURL& embedder_frame_url, const base::DictionaryValue& extra_params) { Profile* profile = Profile::FromBrowserContext( embedder_web_contents->GetBrowserContext()); @@ -799,9 +801,16 @@ void ChromeContentBrowserClient::GuestWebContentsAttached( NOTREACHED(); return; } - const GURL& url = embedder_web_contents->GetSiteInstance()->GetSiteURL(); - const Extension* extension = - service->extensions()->GetExtensionOrAppByURL(url); + + // We usually require BrowserPlugins to be hosted by a storage isolated
+ // extension. We treat WebUI pages as a special case if they host the
+ // BrowserPlugin in a component extension iframe. In that case, we use the
+ // iframe's URL to determine the extension. + const GURL& embedder_site_url = + embedder_web_contents->GetSiteInstance()->GetSiteURL(); + const Extension* extension = service->extensions()->GetExtensionOrAppByURL( + content::HasWebUIScheme(embedder_site_url) ? + embedder_frame_url : embedder_site_url); if (!extension) { // It's ok to return here, since we could be running a browser plugin // outside an extension, and don't need to attach a @@ -2332,6 +2341,9 @@ bool ChromeContentBrowserClient::SupportsBrowserPlugin( switches::kEnableBrowserPluginForAllViewTypes)) return true; + if (content::HasWebUIScheme(site_url)) + return true; + Profile* profile = Profile::FromBrowserContext(browser_context); ExtensionService* service = extensions::ExtensionSystem::Get(profile)->extension_service(); diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index f912682..86ca435 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -67,6 +67,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { virtual void GuestWebContentsAttached( content::WebContents* guest_web_contents, content::WebContents* embedder_web_contents, + const GURL& embedder_frame_url, const base::DictionaryValue& extra_params) OVERRIDE; virtual void RenderProcessHostCreated( content::RenderProcessHost* host) OVERRIDE; diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 83bb858..e4b718b 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -411,15 +411,12 @@ std::string ChromeContentRendererClient::GetDefaultEncoding() { return l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING); } -const Extension* ChromeContentRendererClient::GetExtension( +const Extension* ChromeContentRendererClient::GetExtensionByOrigin( const WebSecurityOrigin& origin) const { if (!EqualsASCII(origin.protocol(), extensions::kExtensionScheme)) return NULL; const std::string extension_id = origin.host().utf8().data(); - if (!extension_dispatcher_->IsExtensionActive(extension_id)) - return NULL; - return extension_dispatcher_->extensions()->GetByID(extension_id); } @@ -435,7 +432,7 @@ bool ChromeContentRendererClient::OverrideCreatePlugin( return false; WebDocument document = frame->document(); const Extension* extension = - GetExtension(document.securityOrigin()); + GetExtensionByOrigin(document.securityOrigin()); if (extension) { const extensions::APIPermission::ID perms[] = { extensions::APIPermission::kWebView, diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index 1885c57..599c5e8 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h @@ -173,7 +173,9 @@ class ChromeContentRendererClient : public content::ContentRendererClient { private: FRIEND_TEST_ALL_PREFIXES(ChromeContentRendererClientTest, NaClRestriction); - const extensions::Extension* GetExtension( + // Gets extension by the given origin, regardless of whether the extension + // is active in the current process. + const extensions::Extension* GetExtensionByOrigin( const WebKit::WebSecurityOrigin& origin) const; // Returns true if the frame is navigating to an URL either into or out of an diff --git a/chrome/renderer/extensions/document_custom_bindings.cc b/chrome/renderer/extensions/document_custom_bindings.cc index 36406c2..253b612 100644 --- a/chrome/renderer/extensions/document_custom_bindings.cc +++ b/chrome/renderer/extensions/document_custom_bindings.cc @@ -7,10 +7,9 @@ #include <string> #include "base/bind.h" -#include "content/public/renderer/render_view.h" +#include "chrome/renderer/extensions/chrome_v8_context.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrame.h" -#include "third_party/WebKit/public/web/WebView.h" #include "v8/include/v8.h" namespace extensions { @@ -26,16 +25,6 @@ DocumentCustomBindings::DocumentCustomBindings( // Attach an event name to an object. void DocumentCustomBindings::RegisterElement( const v8::FunctionCallbackInfo<v8::Value>& args) { - content::RenderView* render_view = GetRenderView(); - if (!render_view) { - return; - } - - WebKit::WebView* web_view = render_view->GetWebView(); - if (!web_view) { - return; - } - if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsObject()) { NOTREACHED(); return; @@ -45,7 +34,7 @@ void DocumentCustomBindings::RegisterElement( v8::Local<v8::Object> options = args[1]->ToObject(); WebKit::WebExceptionCode ec = 0; - WebKit::WebDocument document = web_view->mainFrame()->document(); + WebKit::WebDocument document = context()->web_frame()->document(); v8::Handle<v8::Value> constructor = document.registerEmbedderCustomElement( WebKit::WebString::fromUTF8(element_name), options, ec); diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc index 1f673ba..ad4279c 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.cc +++ b/content/browser/browser_plugin/browser_plugin_embedder.cc @@ -16,6 +16,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/native_web_keyboard_event.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/user_metrics.h" #include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" @@ -176,7 +177,11 @@ void BrowserPluginEmbedder::OnAttach( BrowserPluginGuest* guest = GetBrowserPluginGuestManager()->GetGuestByInstanceID( instance_id, web_contents()->GetRenderProcessHost()->GetID()); - +
+ RenderProcessHost* render_process_host =
+ web_contents()->GetRenderProcessHost();
+ GURL validated_frame_url(params.embedder_frame_url);
+ RenderViewHost::FilterURL(render_process_host, false, &validated_frame_url); if (guest) { // There is an implicit order expectation here: @@ -187,6 +192,7 @@ void BrowserPluginEmbedder::OnAttach( GetContentClient()->browser()->GuestWebContentsAttached( guest->GetWebContents(), web_contents(), + validated_frame_url, extra_params); guest->Attach( static_cast<WebContentsImpl*>(web_contents()), params, extra_params); @@ -202,6 +208,7 @@ void BrowserPluginEmbedder::OnAttach( GetContentClient()->browser()->GuestWebContentsAttached( guest->GetWebContents(), web_contents(), + validated_frame_url, extra_params); guest->Initialize(static_cast<WebContentsImpl*>(web_contents()), params); } diff --git a/content/browser/browser_plugin/browser_plugin_guest_manager.cc b/content/browser/browser_plugin/browser_plugin_guest_manager.cc index 6c86331b..3dceb63 100644 --- a/content/browser/browser_plugin/browser_plugin_guest_manager.cc +++ b/content/browser/browser_plugin/browser_plugin_guest_manager.cc @@ -16,6 +16,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" #include "content/public/common/url_constants.h" +#include "content/public/common/url_utils.h" #include "net/base/escape.h" #include "ui/events/keycodes/keyboard_codes.h" @@ -44,6 +45,8 @@ BrowserPluginGuest* BrowserPluginGuestManager::CreateGuest( const BrowserPluginHostMsg_Attach_Params& params, scoped_ptr<base::DictionaryValue> extra_params) { SiteInstance* guest_site_instance = NULL; + RenderProcessHost* embedder_process_host = + embedder_site_instance->GetProcess(); // Validate that the partition id coming from the renderer is valid UTF-8, // since we depend on this in other parts of the code, such as FilePath // creation. If the validation fails, treat it as a bad message and kill the @@ -51,7 +54,7 @@ BrowserPluginGuest* BrowserPluginGuestManager::CreateGuest( if (!IsStringUTF8(params.storage_partition_id)) { content::RecordAction(UserMetricsAction("BadMessageTerminate_BPGM")); base::KillProcess( - embedder_site_instance->GetProcess()->GetHandle(), + embedder_process_host->GetHandle(), content::RESULT_CODE_KILLED_BAD_MESSAGE, false); return NULL; } @@ -70,7 +73,13 @@ BrowserPluginGuest* BrowserPluginGuestManager::CreateGuest( guest_site_instance = embedder_site_instance->GetRelatedSiteInstance(GURL(params.src)); } else { - const std::string& host = embedder_site_instance->GetSiteURL().host(); + // Only trust |embedder_frame_url| reported by a WebUI renderer. + const GURL& embedder_site_url = embedder_site_instance->GetSiteURL(); + GURL validated_frame_url(params.embedder_frame_url);
+ RenderViewHost::FilterURL(
+ embedder_process_host, false, &validated_frame_url); + const std::string& host = content::HasWebUIScheme(embedder_site_url) ? + validated_frame_url.host() : embedder_site_url.host(); std::string url_encoded_partition = net::EscapeQueryParamValue( params.storage_partition_id, false); diff --git a/content/common/browser_plugin/browser_plugin_messages.h b/content/common/browser_plugin/browser_plugin_messages.h index b4345c6..7aaf07f 100644 --- a/content/common/browser_plugin/browser_plugin_messages.h +++ b/content/common/browser_plugin/browser_plugin_messages.h @@ -26,6 +26,7 @@ #include "ui/gfx/point.h" #include "ui/gfx/rect.h" #include "ui/gfx/size.h" +#include "url/gurl.h" #include "webkit/common/cursors/webcursor.h" #undef IPC_MESSAGE_EXPORT @@ -69,6 +70,7 @@ IPC_STRUCT_BEGIN(BrowserPluginHostMsg_Attach_Params) IPC_STRUCT_MEMBER(bool, visible) IPC_STRUCT_MEMBER(std::string, name) IPC_STRUCT_MEMBER(std::string, src) + IPC_STRUCT_MEMBER(GURL, embedder_frame_url) IPC_STRUCT_MEMBER(BrowserPluginHostMsg_AutoSize_Params, auto_size_params) IPC_STRUCT_MEMBER(BrowserPluginHostMsg_ResizeGuest_Params, resize_guest_params) diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index cc664c6..dcf487f 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -163,6 +163,7 @@ class CONTENT_EXPORT ContentBrowserClient { virtual void GuestWebContentsAttached( WebContents* guest_web_contents, WebContents* embedder_web_contents, + const GURL& embedder_frame_url, const base::DictionaryValue& extra_params) {} // Notifies that a RenderProcessHost has been created. This is called before diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 71aac85..77af957 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc @@ -90,6 +90,7 @@ BrowserPlugin::BrowserPlugin( mouse_locked_(false), browser_plugin_manager_(render_view->GetBrowserPluginManager()), compositing_enabled_(false), + embedder_frame_url_(frame->document().url()), weak_ptr_factory_(this) { } @@ -374,6 +375,7 @@ void BrowserPlugin::Attach(scoped_ptr<base::DictionaryValue> extra_params) { attach_params.storage_partition_id = storage_partition_id_; attach_params.persist_storage = persist_storage_; attach_params.src = GetSrcAttribute(); + attach_params.embedder_frame_url = embedder_frame_url_; GetDamageBufferWithSizeParams(&attach_params.auto_size_params, &attach_params.resize_guest_params, false); diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index ba30ac9..9e0b60c 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h @@ -354,6 +354,9 @@ class CONTENT_EXPORT BrowserPlugin : // Used to identify the plugin to WebBindings. scoped_ptr<struct _NPP> npp_; + // URL for the embedder frame. + GURL embedder_frame_url_; + // Weak factory used in v8 |MakeWeak| callback, since the v8 callback might // get called after BrowserPlugin has been destroyed. base::WeakPtrFactory<BrowserPlugin> weak_ptr_factory_; |