diff options
author | kalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-08 19:01:49 +0000 |
---|---|---|
committer | kalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-08 19:02:59 +0000 |
commit | 755211feabeb6e195b7c8486a8a154853d361b6c (patch) | |
tree | 1b55683521d8e163d7172ea2f5a40517fcb1fb43 | |
parent | 14522ce4160475e97b5b8dfe9ca952364079714b (diff) | |
download | chromium_src-755211feabeb6e195b7c8486a8a154853d361b6c.zip chromium_src-755211feabeb6e195b7c8486a8a154853d361b6c.tar.gz chromium_src-755211feabeb6e195b7c8486a8a154853d361b6c.tar.bz2 |
Refactor guest view availability to be API based not permission based.
This is a step towards allowing WebUI to directly embed guest views.
BUG=386838
R=fsamuel@chromium.org
Review URL: https://codereview.chromium.org/426593007
Cr-Commit-Position: refs/heads/master@{#288407}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288407 0039d316-1c4b-4281-b951-d872f2087c98
23 files changed, 127 insertions, 92 deletions
diff --git a/chrome/browser/extensions/api/guest_view/guest_view_internal_api.cc b/chrome/browser/extensions/api/guest_view/guest_view_internal_api.cc index 7765d9b..cc2ac3b 100644 --- a/chrome/browser/extensions/api/guest_view/guest_view_internal_api.cc +++ b/chrome/browser/extensions/api/guest_view/guest_view_internal_api.cc @@ -35,7 +35,7 @@ bool GuestViewInternalCreateGuestFunction::RunAsync() { this); guest_view_manager->CreateGuest(view_type, extension_id(), - render_view_host()->GetProcess()->GetID(), + GetAssociatedWebContents(), *create_params, callback); diff --git a/chrome/browser/guest_view/app_view/app_view_constants.cc b/chrome/browser/guest_view/app_view/app_view_constants.cc index 5316ce9..bdcd7ef 100644 --- a/chrome/browser/guest_view/app_view/app_view_constants.cc +++ b/chrome/browser/guest_view/app_view/app_view_constants.cc @@ -6,6 +6,10 @@ namespace appview { +// API namespace for the embedder. +const char kEmbedderAPINamespace[] = "appViewEmbedderInternal"; + +// Parameters/properties on events. const char kAppID[] = "appId"; const char kEmbedderID[] ="embedderId"; const char kGuestInstanceID[] = "guestInstanceId"; diff --git a/chrome/browser/guest_view/app_view/app_view_constants.h b/chrome/browser/guest_view/app_view/app_view_constants.h index a6f29cf..0222e6f 100644 --- a/chrome/browser/guest_view/app_view/app_view_constants.h +++ b/chrome/browser/guest_view/app_view/app_view_constants.h @@ -9,6 +9,9 @@ namespace appview { +// API namespace for the *embedder*. The embedder and guest use different APIs. +extern const char kEmbedderAPINamespace[]; + // Parameters/properties on events. extern const char kAppID[]; extern const char kEmbedderID[]; diff --git a/chrome/browser/guest_view/app_view/app_view_guest.cc b/chrome/browser/guest_view/app_view/app_view_guest.cc index 85e9d52d..6df3c5d 100644 --- a/chrome/browser/guest_view/app_view/app_view_guest.cc +++ b/chrome/browser/guest_view/app_view/app_view_guest.cc @@ -17,13 +17,11 @@ #include "extensions/browser/api/app_runtime/app_runtime_api.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_host.h" -#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/lazy_background_task_queue.h" #include "extensions/browser/view_type_utils.h" #include "extensions/common/api/app_runtime.h" #include "extensions/common/extension_messages.h" -#include "extensions/common/permissions/permissions_data.h" #include "ipc/ipc_message_macros.h" namespace app_runtime = extensions::core_api::app_runtime; @@ -137,16 +135,8 @@ bool AppViewGuest::HandleContextMenu(const content::ContextMenuParams& params) { return true; } -bool AppViewGuest::CanEmbedderUseGuestView( - const std::string& embedder_extension_id) { - const extensions::Extension* embedder_extension = - extensions::ExtensionRegistry::Get(browser_context()) - ->enabled_extensions() - .GetByID(embedder_extension_id); - if (!embedder_extension) - return false; - return embedder_extension->permissions_data()->HasAPIPermission( - extensions::APIPermission::kAppView); +const char* AppViewGuest::GetAPINamespace() { + return appview::kEmbedderAPINamespace; } void AppViewGuest::CreateWebContents( diff --git a/chrome/browser/guest_view/app_view/app_view_guest.h b/chrome/browser/guest_view/app_view/app_view_guest.h index 87aa89c..831941e 100644 --- a/chrome/browser/guest_view/app_view/app_view_guest.h +++ b/chrome/browser/guest_view/app_view/app_view_guest.h @@ -47,8 +47,7 @@ class AppViewGuest : public GuestView<AppViewGuest>, const content::ContextMenuParams& params) OVERRIDE; // GuestViewBase implementation. - virtual bool CanEmbedderUseGuestView( - const std::string& embedder_extension_id) OVERRIDE; + virtual const char* GetAPINamespace() OVERRIDE; virtual void CreateWebContents( const std::string& embedder_extension_id, int embedder_render_process_id, diff --git a/chrome/browser/guest_view/extension_options/extension_options_constants.cc b/chrome/browser/guest_view/extension_options/extension_options_constants.cc index ab431c9..e85c087 100644 --- a/chrome/browser/guest_view/extension_options/extension_options_constants.cc +++ b/chrome/browser/guest_view/extension_options/extension_options_constants.cc @@ -6,6 +6,9 @@ namespace extensionoptions { +// API namespace. +extern const char kAPINamespace[] = "extensionOptionsInternal"; + // Attributes. const char kAttributeAutoSize[] = "autosize"; const char kAttributeMaxHeight[] = "maxheight"; diff --git a/chrome/browser/guest_view/extension_options/extension_options_constants.h b/chrome/browser/guest_view/extension_options/extension_options_constants.h index 08efd57..f1a2f1b 100644 --- a/chrome/browser/guest_view/extension_options/extension_options_constants.h +++ b/chrome/browser/guest_view/extension_options/extension_options_constants.h @@ -7,6 +7,9 @@ namespace extensionoptions { +// API namespace. +extern const char kAPINamespace[]; + // Attributes. extern const char kAttributeAutoSize[]; extern const char kAttributeMaxHeight[]; diff --git a/chrome/browser/guest_view/extension_options/extension_options_guest.cc b/chrome/browser/guest_view/extension_options/extension_options_guest.cc index 8fd477a..3ca78ec 100644 --- a/chrome/browser/guest_view/extension_options/extension_options_guest.cc +++ b/chrome/browser/guest_view/extension_options/extension_options_guest.cc @@ -36,16 +36,8 @@ ExtensionOptionsGuest::ExtensionOptionsGuest( ExtensionOptionsGuest::~ExtensionOptionsGuest() { } -bool ExtensionOptionsGuest::CanEmbedderUseGuestView( - const std::string& embedder_extension_id) { - const extensions::Extension* embedder_extension = - extensions::ExtensionRegistry::Get(browser_context()) - ->enabled_extensions() - .GetByID(embedder_extension_id); - if (!embedder_extension) - return false; - return embedder_extension->permissions_data()->HasAPIPermission( - extensions::APIPermission::kEmbeddedExtensionOptions); +const char* ExtensionOptionsGuest::GetAPINamespace() { + return extensionoptions::kAPINamespace; } // static diff --git a/chrome/browser/guest_view/extension_options/extension_options_guest.h b/chrome/browser/guest_view/extension_options/extension_options_guest.h index 6373ae5..65e33fb 100644 --- a/chrome/browser/guest_view/extension_options/extension_options_guest.h +++ b/chrome/browser/guest_view/extension_options/extension_options_guest.h @@ -23,8 +23,7 @@ class ExtensionOptionsGuest int guest_instance_id); // GuestViewBase implementation. - virtual bool CanEmbedderUseGuestView( - const std::string& embedder_extension_id) OVERRIDE; + virtual const char* GetAPINamespace() OVERRIDE; virtual void CreateWebContents( const std::string& embedder_extension_id, int embedder_render_process_id, diff --git a/chrome/browser/guest_view/guest_view_base.cc b/chrome/browser/guest_view/guest_view_base.cc index 1300cfb..3a41e1d 100644 --- a/chrome/browser/guest_view/guest_view_base.cc +++ b/chrome/browser/guest_view/guest_view_base.cc @@ -18,6 +18,10 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" #include "extensions/browser/event_router.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/process_map.h" +#include "extensions/common/features/feature.h" +#include "extensions/common/features/feature_provider.h" #include "third_party/WebKit/public/web/WebInputEvent.h" using content::WebContents; @@ -97,27 +101,48 @@ GuestViewBase::GuestViewBase(content::BrowserContext* browser_context, weak_ptr_factory_(this) { } -void GuestViewBase::Init( - const std::string& embedder_extension_id, - int embedder_render_process_id, - const base::DictionaryValue& create_params, - const WebContentsCreatedCallback& callback) { +void GuestViewBase::Init(const std::string& embedder_extension_id, + content::WebContents* embedder_web_contents, + const base::DictionaryValue& create_params, + const WebContentsCreatedCallback& callback) { if (initialized_) return; initialized_ = true; - if (!CanEmbedderUseGuestView(embedder_extension_id)) { + extensions::Feature* feature = + extensions::FeatureProvider::GetAPIFeatures()->GetFeature( + GetAPINamespace()); + CHECK(feature); + + extensions::ProcessMap* process_map = + extensions::ProcessMap::Get(browser_context()); + CHECK(process_map); + + const extensions::Extension* embedder_extension = + extensions::ExtensionRegistry::Get(browser_context_) + ->enabled_extensions() + .GetByID(embedder_extension_id); + int embedder_process_id = + embedder_web_contents->GetRenderProcessHost()->GetID(); + + extensions::Feature::Availability availability = + feature->IsAvailableToContext( + embedder_extension, + process_map->GetMostLikelyContextType(embedder_extension, + embedder_process_id), + embedder_web_contents->GetLastCommittedURL()); + if (!availability.is_available()) { callback.Run(NULL); return; } CreateWebContents(embedder_extension_id, - embedder_render_process_id, + embedder_process_id, create_params, base::Bind(&GuestViewBase::CompleteInit, AsWeakPtr(), embedder_extension_id, - embedder_render_process_id, + embedder_process_id, callback)); } diff --git a/chrome/browser/guest_view/guest_view_base.h b/chrome/browser/guest_view/guest_view_base.h index e42b47c..0f1cd1c 100644 --- a/chrome/browser/guest_view/guest_view_base.h +++ b/chrome/browser/guest_view/guest_view_base.h @@ -141,11 +141,13 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate, // to destruction. virtual void WillDestroy() {} - // This method is to be implemented by the derived class. It determines - // whether the guest view type of the derived class can be used by the - // provided embedder extension ID. - virtual bool CanEmbedderUseGuestView( - const std::string& embedder_extension_id) = 0; + // This method is to be implemented by the derived class. Access to guest + // views are determined by the availability of the internal extension API + // used to implement the guest view. + // + // This should be the name of the API as it appears in the _api_features.json + // file. + virtual const char* GetAPINamespace() = 0; // This method is to be implemented by the derived class. Given a set of // initialization parameters, a concrete subclass of GuestViewBase can @@ -161,7 +163,7 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate, // This creates a WebContents and initializes |this| GuestViewBase to use the // newly created WebContents. void Init(const std::string& embedder_extension_id, - int embedder_render_process_id, + content::WebContents* embedder_web_contents, const base::DictionaryValue& create_params, const WebContentsCreatedCallback& callback); diff --git a/chrome/browser/guest_view/guest_view_manager.cc b/chrome/browser/guest_view/guest_view_manager.cc index 0493bcf..892d729 100644 --- a/chrome/browser/guest_view/guest_view_manager.cc +++ b/chrome/browser/guest_view/guest_view_manager.cc @@ -62,12 +62,11 @@ int GuestViewManager::GetNextInstanceID() { return ++current_instance_id_; } -void GuestViewManager::CreateGuest( - const std::string& view_type, - const std::string& embedder_extension_id, - int embedder_render_process_id, - const base::DictionaryValue& create_params, - const WebContentsCreatedCallback& callback) { +void GuestViewManager::CreateGuest(const std::string& view_type, + const std::string& embedder_extension_id, + content::WebContents* embedder_web_contents, + const base::DictionaryValue& create_params, + const WebContentsCreatedCallback& callback) { int guest_instance_id = GetNextInstanceID(); GuestViewBase* guest = GuestViewBase::Create(context_, guest_instance_id, view_type); @@ -75,10 +74,8 @@ void GuestViewManager::CreateGuest( callback.Run(NULL); return; } - guest->Init(embedder_extension_id, - embedder_render_process_id, - create_params, - callback); + guest->Init( + embedder_extension_id, embedder_web_contents, create_params, callback); } content::WebContents* GuestViewManager::CreateGuestWithWebContentsParams( diff --git a/chrome/browser/guest_view/guest_view_manager.h b/chrome/browser/guest_view/guest_view_manager.h index c908d44..8b32ed9c 100644 --- a/chrome/browser/guest_view/guest_view_manager.h +++ b/chrome/browser/guest_view/guest_view_manager.h @@ -20,6 +20,7 @@ class GURL; namespace content { class BrowserContext; +class WebContents; } // namespace content class GuestViewManager : public content::BrowserPluginGuestManager, @@ -48,12 +49,11 @@ class GuestViewManager : public content::BrowserPluginGuestManager, typedef base::Callback<void(content::WebContents*)> WebContentsCreatedCallback; - void CreateGuest( - const std::string& view_type, - const std::string& embedder_extension_id, - int embedder_render_process_id, - const base::DictionaryValue& create_params, - const WebContentsCreatedCallback& callback); + void CreateGuest(const std::string& view_type, + const std::string& embedder_extension_id, + content::WebContents* embedder_web_contents, + const base::DictionaryValue& create_params, + const WebContentsCreatedCallback& callback); content::WebContents* CreateGuestWithWebContentsParams( const std::string& view_type, diff --git a/chrome/browser/guest_view/web_view/web_view_constants.cc b/chrome/browser/guest_view/web_view/web_view_constants.cc index 10e1f2a..a93e363 100644 --- a/chrome/browser/guest_view/web_view/web_view_constants.cc +++ b/chrome/browser/guest_view/web_view/web_view_constants.cc @@ -13,6 +13,9 @@ const char kAttributeMaxWidth[] = "maxwidth"; const char kAttributeMinHeight[] = "minheight"; const char kAttributeMinWidth[] = "minwidth"; +// API namespace. +const char kAPINamespace[] = "webViewInternal"; + // Events. const char kEventClose[] = "webViewInternal.onClose"; const char kEventConsoleMessage[] = "webViewInternal.onConsoleMessage"; diff --git a/chrome/browser/guest_view/web_view/web_view_constants.h b/chrome/browser/guest_view/web_view/web_view_constants.h index 94aa97e..e28d59d 100644 --- a/chrome/browser/guest_view/web_view/web_view_constants.h +++ b/chrome/browser/guest_view/web_view/web_view_constants.h @@ -16,6 +16,10 @@ extern const char kAttributeMaxWidth[]; extern const char kAttributeMinHeight[]; extern const char kAttributeMinWidth[]; +// API namespace. +// TODO(kalman): Consolidate this with the other API constants. +extern const char kAPINamespace[]; + // Events. extern const char kEventClose[]; extern const char kEventConsoleMessage[]; diff --git a/chrome/browser/guest_view/web_view/web_view_guest.cc b/chrome/browser/guest_view/web_view/web_view_guest.cc index 68136ba..87ec282 100644 --- a/chrome/browser/guest_view/web_view/web_view_guest.cc +++ b/chrome/browser/guest_view/web_view/web_view_guest.cc @@ -48,10 +48,8 @@ #include "content/public/common/result_codes.h" #include "content/public/common/stop_find_action.h" #include "content/public/common/url_constants.h" -#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/common/constants.h" -#include "extensions/common/permissions/permissions_data.h" #include "ipc/ipc_message_macros.h" #include "net/base/escape.h" #include "net/base/net_errors.h" @@ -226,16 +224,8 @@ scoped_ptr<base::ListValue> WebViewGuest::MenuModelToValue( return items.Pass(); } -bool WebViewGuest::CanEmbedderUseGuestView( - const std::string& embedder_extension_id) { - const extensions::Extension* embedder_extension = - extensions::ExtensionRegistry::Get(browser_context()) - ->enabled_extensions() - .GetByID(embedder_extension_id); - if (!embedder_extension) - return false; - return embedder_extension->permissions_data()->HasAPIPermission( - extensions::APIPermission::kWebView); +const char* WebViewGuest::GetAPINamespace() { + return webview::kAPINamespace; } void WebViewGuest::CreateWebContents( @@ -570,13 +560,13 @@ void WebViewGuest::CreateNewGuestWebViewWindow( base::DictionaryValue create_params; create_params.SetString(webview::kStoragePartitionId, storage_partition_id); - guest_manager->CreateGuest( - WebViewGuest::Type, - embedder_extension_id(), - embedder_web_contents()->GetRenderProcessHost()->GetID(), - create_params, - base::Bind(&WebViewGuest::NewGuestWebViewCallback, - base::Unretained(this), params)); + guest_manager->CreateGuest(WebViewGuest::Type, + embedder_extension_id(), + embedder_web_contents(), + create_params, + base::Bind(&WebViewGuest::NewGuestWebViewCallback, + base::Unretained(this), + params)); } void WebViewGuest::NewGuestWebViewCallback( diff --git a/chrome/browser/guest_view/web_view/web_view_guest.h b/chrome/browser/guest_view/web_view/web_view_guest.h index c38a7ee..39e3c72 100644 --- a/chrome/browser/guest_view/web_view/web_view_guest.h +++ b/chrome/browser/guest_view/web_view/web_view_guest.h @@ -83,8 +83,7 @@ class WebViewGuest : public GuestView<WebViewGuest>, void SetZoom(double zoom_factor); // GuestViewBase implementation. - virtual bool CanEmbedderUseGuestView( - const std::string& embedder_extension_id) OVERRIDE; + virtual const char* GetAPINamespace() OVERRIDE; virtual void CreateWebContents( const std::string& embedder_extension_id, int embedder_render_process_id, diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 464efe2..7051eb5 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -56,6 +56,14 @@ // Any webpage can use the app API. "matches": ["<all_urls>"] }, + // The API for the *embedder* of appview. Appview has both an embedder and + // guest API, which are different. + "appViewEmbedderInternal": { + "internal": true, + "contexts": ["blessed_extension"], + "dependencies": ["permission:appview"] + }, + // TODO(fsamuel,kalman): Rename this appViewGuestInternal. "appViewInternal": { "internal": true, "channel": "dev", diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc index 1feb1ca..d006d1e 100644 --- a/extensions/browser/event_router.cc +++ b/extensions/browser/event_router.cc @@ -539,7 +539,8 @@ void EventRouter::DispatchEventToProcess(const std::string& extension_id, BrowserContext* listener_context = process->GetBrowserContext(); ProcessMap* process_map = ProcessMap::Get(listener_context); - // TODO(kalman): Convert this method to use ProcessMap::GuessContextType. + // TODO(kalman): Convert this method to use + // ProcessMap::GetMostLikelyContextType. const Extension* extension = ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( diff --git a/extensions/browser/extension_function_dispatcher.cc b/extensions/browser/extension_function_dispatcher.cc index b26ef2d..4dfb7fe 100644 --- a/extensions/browser/extension_function_dispatcher.cc +++ b/extensions/browser/extension_function_dispatcher.cc @@ -455,7 +455,7 @@ ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( function->set_response_callback(callback); function->set_source_tab_id(params.source_tab_id); function->set_source_context_type( - process_map.GuessContextType(extension, requesting_process_id)); + process_map.GetMostLikelyContextType(extension, requesting_process_id)); return function; } diff --git a/extensions/browser/process_map.cc b/extensions/browser/process_map.cc index 12fb538..0850bc6 100644 --- a/extensions/browser/process_map.cc +++ b/extensions/browser/process_map.cc @@ -123,8 +123,9 @@ std::set<std::string> ProcessMap::GetExtensionsInProcess(int process_id) const { return result; } -Feature::Context ProcessMap::GuessContextType(const Extension* extension, - int process_id) const { +Feature::Context ProcessMap::GetMostLikelyContextType( + const Extension* extension, + int process_id) const { // WARNING: This logic must match Dispatcher::ClassifyJavaScriptContext, as // much as possible. diff --git a/extensions/browser/process_map.h b/extensions/browser/process_map.h index d7ae8b3..731bf4f8 100644 --- a/extensions/browser/process_map.h +++ b/extensions/browser/process_map.h @@ -95,24 +95,36 @@ class ProcessMap : public KeyedService { std::set<std::string> GetExtensionsInProcess(int process_id) const; - // Guesses the most permissive context type for the process with ID - // |process_id|. Context types are renderer (JavaScript) concepts but the - // browser can do a decent job in guessing what the process hosts. + // Gets the most likely context type for the process with ID |process_id| + // which hosts Extension |extension|, if any (may be NULL). Context types are + // renderer (JavaScript) concepts but the browser can do a decent job in + // guessing what the process hosts. // + // |extension| is the funky part - unfortunately we need to trust the + // caller of this method to be correct that indeed the context does feature + // an extension. This matters for iframes, where an extension could be + // hosted in another extension's process (privilege level needs to be + // downgraded) or in a web page's process (privilege level needs to be + // upgraded). + // + // The latter of these is slightly problematic from a security perspective; + // if a web page renderer gets owned it could try to pretend it's an + // extension and get access to some unprivileged APIs. Luckly, when OOP + // iframes lauch, it won't be an issue. + // + // Anyhow, the expected behaviour is: // - For hosted app processes, this will be blessed_web_page. // - For other extension processes, this will be blessed_extension. // - For WebUI processes, this will be a webui. - // - For anything else we have the choice of unblessed_extension or + // - For any other extension we have the choice of unblessed_extension or // content_script. Since content scripts are more common, guess that. // We *could* in theory track which web processes have extension frames // in them, and those would be unblessed_extension, but we don't at the // moment, and once OOP iframes exist then there won't even be such a // thing as an unblessed_extension context. - // - // |extension| isn't used to upgrade the process trust level, but rather used - // as a tiebreaker if a process is found to contain multiple extensions. - Feature::Context GuessContextType(const Extension* extension, - int process_id) const; + // - For anything else, web_page. + Feature::Context GetMostLikelyContextType(const Extension* extension, + int process_id) const; private: struct Item; diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 130f585..f09d5fd 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc @@ -1174,7 +1174,7 @@ Feature::Context Dispatcher::ClassifyJavaScriptContext( int extension_group, const GURL& url, const blink::WebSecurityOrigin& origin) { - // WARNING: This logic must match ProcessMap::GuessContextType, as much as + // WARNING: This logic must match ProcessMap::GetContextType, as much as // possible. DCHECK_GE(extension_group, 0); |