diff options
author | lfg <lfg@chromium.org> | 2014-09-12 15:58:28 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-12 23:02:10 +0000 |
commit | 0330a7e9fc13f03380f86916b0b2cf718f36b1f8 (patch) | |
tree | 6af1c962b32253b78ddaa3a7de39d5c59e742c78 | |
parent | 311ecdf7e9ba01b0a8ccbd1488e312e13cf398c5 (diff) | |
download | chromium_src-0330a7e9fc13f03380f86916b0b2cf718f36b1f8.zip chromium_src-0330a7e9fc13f03380f86916b0b2cf718f36b1f8.tar.gz chromium_src-0330a7e9fc13f03380f86916b0b2cf718f36b1f8.tar.bz2 |
Enabling webview in app_shell.
This CL registers the webview tag in extensions, allowing it to be used inside app_shell. The webview browser sample should be working with this patch.
For now, not all the webview APIs are supported, the APIs that are not supported are: contextMenus, webrequest, declarativeWebRequest and permissions (videoCapture, pointerLock, geolocation).
BUG=352293
Review URL: https://codereview.chromium.org/566863004
Cr-Commit-Position: refs/heads/master@{#294689}
-rw-r--r-- | athena/resources/athena_resources.gyp | 1 | ||||
-rw-r--r-- | chrome/common/extensions/api/_api_features.json | 16 | ||||
-rw-r--r-- | chrome/common/extensions/api/_permission_features.json | 16 | ||||
-rw-r--r-- | chrome/common/extensions/permissions/chrome_api_permissions.cc | 2 | ||||
-rw-r--r-- | chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc | 2 | ||||
-rw-r--r-- | chrome/renderer/resources/extensions/chrome_web_view.js | 91 | ||||
-rw-r--r-- | extensions/BUILD.gn | 1 | ||||
-rw-r--r-- | extensions/browser/api/extensions_api_client.cc | 3 | ||||
-rw-r--r-- | extensions/common/api/_api_features.json | 18 | ||||
-rw-r--r-- | extensions/common/api/_permission_features.json | 17 | ||||
-rw-r--r-- | extensions/common/permissions/extensions_api_permissions.cc | 2 | ||||
-rw-r--r-- | extensions/extensions.gyp | 1 | ||||
-rw-r--r-- | extensions/renderer/dispatcher.cc | 12 | ||||
-rw-r--r-- | extensions/renderer/resources/web_view.js | 6 | ||||
-rw-r--r-- | extensions/renderer/resources/web_view_events.js | 92 | ||||
-rw-r--r-- | extensions/shell/browser/shell_browser_context.cc | 6 | ||||
-rw-r--r-- | extensions/shell/browser/shell_browser_context.h | 1 |
17 files changed, 159 insertions, 128 deletions
diff --git a/athena/resources/athena_resources.gyp b/athena/resources/athena_resources.gyp index 08a59e1..4a9f953 100644 --- a/athena/resources/athena_resources.gyp +++ b/athena/resources/athena_resources.gyp @@ -49,7 +49,6 @@ '<(SHARED_INTERMEDIATE_DIR)/components/component_resources.pak', '<(SHARED_INTERMEDIATE_DIR)/components/strings/components_strings_en-US.pak', '<(SHARED_INTERMEDIATE_DIR)/content/app/resources/content_resources_100_percent.pak', - '<(SHARED_INTERMEDIATE_DIR)/content/app/strings/content_strings_en-US.pak', '<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_browser_resources_100_percent.pak', '<(SHARED_INTERMEDIATE_DIR)/ui/chromeos/resources/ui_chromeos_resources_100_percent.pak', '<(SHARED_INTERMEDIATE_DIR)/ui/chromeos/strings/ui_chromeos_strings_en-US.pak', diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 1fb304f..ddee4fc 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -437,22 +437,6 @@ "dependencies": ["permission:gcm"], "contexts": ["blessed_extension"] }, - "guestViewInternal": [{ - "internal": true, - "channel": "stable", - "contexts": ["blessed_extension"] - }, { - // Component extensions can use the guestViewInternal API from iframes. - "location": "component", - "internal": true, - "dependencies": ["permission:webview"], - "contexts": ["unblessed_extension"] - }, { - "internal": true, - "channel": "trunk", - "contexts": ["webui"], - "matches": ["chrome://extensions-frame/*", "chrome://extensions/*"] - }], "hangoutsPrivate": { "channel": "stable", "contexts": ["blessed_extension"], diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index 5c92e87..83719e2 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json @@ -1042,19 +1042,5 @@ "webRequestBlocking": { "channel": "stable", "extension_types": ["extension", "legacy_packaged_app"] - }, - "webview": [{ - "channel": "stable", - "extension_types": ["platform_app"] - }, { - // General support for webview in component extensions still in progress. - // Only allowed for whitelisted extensions until all the caveats are - // addressed. Tracked in crbug/285151. - "channel": "stable", - "extension_types": ["extension"], - "location": "component", - "whitelist": [ - "D519188F86D9ACCEE0412007B227D9936EB9676B" // GAIA Component Extension - ] - }] + } } diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index 02e34e3..e4c6ccb 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc @@ -161,8 +161,6 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions() PermissionMessage::kTabs}, {APIPermission::kWebRequest, "webRequest"}, {APIPermission::kWebRequestBlocking, "webRequestBlocking"}, - {APIPermission::kWebView, "webview", - APIPermissionInfo::kFlagCannotBeOptional}, // Register private permissions. {APIPermission::kScreenlockPrivate, "screenlockPrivate", diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc index 5778452..9ec8246 100644 --- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc @@ -276,8 +276,6 @@ void ChromeExtensionsDispatcherDelegate::RequireAdditionalModules( .is_available()) { module_system->Require("chromeWebViewExperimental"); } - } else if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT) { - module_system->Require("denyWebView"); } if (extensions::FeatureSwitch::app_view()->IsEnabled() && diff --git a/chrome/renderer/resources/extensions/chrome_web_view.js b/chrome/renderer/resources/extensions/chrome_web_view.js index badbf62..8028ff0 100644 --- a/chrome/renderer/resources/extensions/chrome_web_view.js +++ b/chrome/renderer/resources/extensions/chrome_web_view.js @@ -6,9 +6,17 @@ var ChromeWebView = require('chromeWebViewInternal').ChromeWebView; var CreateEvent = require('webViewEvents').CreateEvent; +var DeclarativeWebRequestSchema = + requireNative('schema_registry').GetSchema('declarativeWebRequest'); var EventBindings = require('event_bindings'); +var IdGenerator = requireNative('id_generator'); +var WebRequestEvent = require('webRequestInternal').WebRequestEvent; +var WebRequestSchema = + requireNative('schema_registry').GetSchema('webRequest'); var WebViewInternal = require('webView').WebViewInternal +var WebRequestMessageEvent = CreateEvent('webViewInternal.onMessage'); + var CHROME_WEB_VIEW_EVENTS = { 'contextmenu': { evt: CreateEvent('chromeWebViewInternal.contextmenu'), @@ -20,6 +28,25 @@ var CHROME_WEB_VIEW_EVENTS = { } }; +function DeclarativeWebRequestEvent(opt_eventName, + opt_argSchemas, + opt_eventOptions, + opt_webViewInstanceId) { + var subEventName = opt_eventName + '/' + IdGenerator.GetNextId(); + EventBindings.Event.call(this, subEventName, opt_argSchemas, opt_eventOptions, + opt_webViewInstanceId); + + // TODO(lazyboy): When do we dispose this listener? + WebRequestMessageEvent.addListener(function() { + // Re-dispatch to subEvent's listeners. + $Function.apply(this.dispatch, this, $Array.slice(arguments)); + }.bind(this), {instanceId: opt_webViewInstanceId || 0}); +} + +DeclarativeWebRequestEvent.prototype = { + __proto__: EventBindings.Event.prototype +}; + /** * Implemented when the ChromeWebView API is available. * @private @@ -41,3 +68,67 @@ WebViewInternal.prototype.maybeHandleContextMenu = function(e, webViewEvent) { var params = undefined; ChromeWebView.showContextMenu(this.guestInstanceId, requestId, params); }; + +WebViewInternal.prototype.maybeSetupChromeWebViewEvents = function() { + var request = {}; + var createWebRequestEvent = function(webRequestEvent) { + return function() { + if (!this[webRequestEvent.name]) { + this[webRequestEvent.name] = + new WebRequestEvent( + 'webViewInternal.' + webRequestEvent.name, + webRequestEvent.parameters, + webRequestEvent.extraParameters, webRequestEvent.options, + this.viewInstanceId); + } + return this[webRequestEvent.name]; + }.bind(this); + }.bind(this); + + var createDeclarativeWebRequestEvent = function(webRequestEvent) { + return function() { + if (!this[webRequestEvent.name]) { + // The onMessage event gets a special event type because we want + // the listener to fire only for messages targeted for this particular + // <webview>. + var EventClass = webRequestEvent.name === 'onMessage' ? + DeclarativeWebRequestEvent : EventBindings.Event; + this[webRequestEvent.name] = + new EventClass( + 'webViewInternal.' + webRequestEvent.name, + webRequestEvent.parameters, + webRequestEvent.options, + this.viewInstanceId); + } + return this[webRequestEvent.name]; + }.bind(this); + }.bind(this); + + for (var i = 0; i < DeclarativeWebRequestSchema.events.length; ++i) { + var eventSchema = DeclarativeWebRequestSchema.events[i]; + var webRequestEvent = createDeclarativeWebRequestEvent(eventSchema); + Object.defineProperty( + request, + eventSchema.name, + { + get: webRequestEvent, + enumerable: true + } + ); + } + + // Populate the WebRequest events from the API definition. + for (var i = 0; i < WebRequestSchema.events.length; ++i) { + var webRequestEvent = createWebRequestEvent(WebRequestSchema.events[i]); + Object.defineProperty( + request, + WebRequestSchema.events[i].name, + { + get: webRequestEvent, + enumerable: true + } + ); + } + + this.setRequestPropertyOnWebViewNode(request); +}; diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn index 2769bdb..80f3f44 100644 --- a/extensions/BUILD.gn +++ b/extensions/BUILD.gn @@ -118,6 +118,7 @@ repack("shell_and_test_pak") { # from generated_resources_en-US.pak. http://crbug.com/397250 "$root_gen_dir/chrome/generated_resources_en-US.pak", "$root_gen_dir/chrome/renderer_resources_100_percent.pak", + "$root_gen_dir/content/app/strings/content_strings_en-US.pak", "$root_gen_dir/content/content_resources.pak", "$root_gen_dir/content/shell/shell_resources.pak", "$root_gen_dir/extensions/extensions_renderer_resources.pak", diff --git a/extensions/browser/api/extensions_api_client.cc b/extensions/browser/api/extensions_api_client.cc index d0bc081..3f5ccbd 100644 --- a/extensions/browser/api/extensions_api_client.cc +++ b/extensions/browser/api/extensions_api_client.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h" +#include "extensions/browser/guest_view/web_view/web_view_permission_helper_delegate.h" namespace extensions { class AppViewGuestDelegate; @@ -51,7 +52,7 @@ WebViewGuestDelegate* ExtensionsAPIClient::CreateWebViewGuestDelegate( WebViewPermissionHelperDelegate* ExtensionsAPIClient:: CreateWebViewPermissionHelperDelegate( WebViewPermissionHelper* web_view_permission_helper) const { - return NULL; + return new WebViewPermissionHelperDelegate(web_view_permission_helper); } scoped_refptr<RulesRegistry> ExtensionsAPIClient::GetRulesRegistry( diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 929ea42..dd5b3a7 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json @@ -67,6 +67,24 @@ "extension_types": ["extension", "legacy_packaged_app", "platform_app"], "contexts": ["blessed_extension"] }, + "guestViewInternal": [ + { + "internal": true, + "channel": "stable", + "contexts": ["blessed_extension"] + }, { + // Component extensions can use the guestViewInternal API from iframes. + "location": "component", + "internal": true, + "dependencies": ["permission:webview"], + "contexts": ["unblessed_extension"] + }, { + "internal": true, + "channel": "trunk", + "contexts": ["webui"], + "matches": ["chrome://extensions-frame/*", "chrome://extensions/*"] + } + ], "hid": { "dependencies": ["permission:hid"], "contexts": ["blessed_extension"] diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json index 8cddf76..40a4726 100644 --- a/extensions/common/api/_permission_features.json +++ b/extensions/common/api/_permission_features.json @@ -309,5 +309,22 @@ "A434B90223C3C52F2B69DB494736B63C612C774D" ] } + ], + "webview": [ + { + "channel": "stable", + "extension_types": ["platform_app"] + }, + { + // General support for webview in component extensions still in progress. + // Only allowed for whitelisted extensions until all the caveats are + // addressed. Tracked in crbug/285151. + "channel": "stable", + "extension_types": ["extension"], + "location": "component", + "whitelist": [ + "D519188F86D9ACCEE0412007B227D9936EB9676B" // GAIA Component Extension + ] + } ] } diff --git a/extensions/common/permissions/extensions_api_permissions.cc b/extensions/common/permissions/extensions_api_permissions.cc index 679136e..b4b2ddf 100644 --- a/extensions/common/permissions/extensions_api_permissions.cc +++ b/extensions/common/permissions/extensions_api_permissions.cc @@ -65,6 +65,8 @@ std::vector<APIPermissionInfo*> ExtensionsAPIPermissions::GetAllPermissions() {APIPermission::kVideoCapture, "videoCapture", APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_VIDEO_CAPTURE, PermissionMessage::kVideoCapture}, + {APIPermission::kWebView, "webview", + APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kWindowShape, "app.window.shape"}, }; diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp index acb5bf1..b286936 100644 --- a/extensions/extensions.gyp +++ b/extensions/extensions.gyp @@ -994,6 +994,7 @@ # from generated_resources_en-US.pak. http://crbug.com/397250 '<(SHARED_INTERMEDIATE_DIR)/chrome/generated_resources_en-US.pak', '<(SHARED_INTERMEDIATE_DIR)/chrome/renderer_resources_100_percent.pak', + '<(SHARED_INTERMEDIATE_DIR)/content/app/strings/content_strings_en-US.pak', '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.pak', '<(SHARED_INTERMEDIATE_DIR)/content/shell_resources.pak', '<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_renderer_resources.pak', diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 163218c..80ee4ec 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc @@ -323,6 +323,18 @@ void Dispatcher::DidCreateScriptContext( module_system->Require("platformApp"); } + // Note: setting up the WebView class here, not the chrome.webview API. + // The API will be automatically set up when first used. + if (context->GetAvailability("webViewInternal").is_available()) { + module_system->Require("webView"); + if (context->GetAvailability("webViewExperimentalInternal") + .is_available()) { + module_system->Require("webViewExperimental"); + } + } else if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT) { + module_system->Require("denyWebView"); + } + delegate_->RequireAdditionalModules(context, is_within_platform_app); VLOG(1) << "Num tracked contexts: " << script_context_set_.size(); diff --git a/extensions/renderer/resources/web_view.js b/extensions/renderer/resources/web_view.js index 610c65f..85c588c 100644 --- a/extensions/renderer/resources/web_view.js +++ b/extensions/renderer/resources/web_view.js @@ -1017,6 +1017,12 @@ window.addEventListener('readystatechange', function listener(event) { WebViewInternal.prototype.maybeGetChromeWebViewEvents = function() {}; /** + * Implemented when the ChromeWebView API is available. + * @private + */ +WebViewInternal.prototype.maybeSetupChromeWebViewEvents = function() {}; + +/** * Implemented when the experimental API is available. * @private */ diff --git a/extensions/renderer/resources/web_view_events.js b/extensions/renderer/resources/web_view_events.js index 32b500c..137baa2e 100644 --- a/extensions/renderer/resources/web_view_events.js +++ b/extensions/renderer/resources/web_view_events.js @@ -4,14 +4,8 @@ // Event management for WebViewInternal. -var DeclarativeWebRequestSchema = - requireNative('schema_registry').GetSchema('declarativeWebRequest'); var EventBindings = require('event_bindings'); -var IdGenerator = requireNative('id_generator'); var MessagingNatives = requireNative('messaging_natives'); -var WebRequestEvent = require('webRequestInternal').WebRequestEvent; -var WebRequestSchema = - requireNative('schema_registry').GetSchema('webRequest'); var WebView = require('webViewInternal').WebView; var CreateEvent = function(name) { @@ -21,7 +15,6 @@ var CreateEvent = function(name) { var FrameNameChangedEvent = CreateEvent('webViewInternal.onFrameNameChanged'); var PluginDestroyedEvent = CreateEvent('webViewInternal.onPluginDestroyed'); -var WebRequestMessageEvent = CreateEvent('webViewInternal.onMessage'); // WEB_VIEW_EVENTS is a map of stable <webview> DOM event names to their // associated extension event descriptor objects. @@ -155,25 +148,6 @@ var WEB_VIEW_EVENTS = { } }; -function DeclarativeWebRequestEvent(opt_eventName, - opt_argSchemas, - opt_eventOptions, - opt_webViewInstanceId) { - var subEventName = opt_eventName + '/' + IdGenerator.GetNextId(); - EventBindings.Event.call(this, subEventName, opt_argSchemas, opt_eventOptions, - opt_webViewInstanceId); - - // TODO(lazyboy): When do we dispose this listener? - WebRequestMessageEvent.addListener(function() { - // Re-dispatch to subEvent's listeners. - $Function.apply(this.dispatch, this, $Array.slice(arguments)); - }.bind(this), {instanceId: opt_webViewInstanceId || 0}); -} - -DeclarativeWebRequestEvent.prototype = { - __proto__: EventBindings.Event.prototype -}; - // Constructor. function WebViewEvents(webViewInternal, viewInstanceId) { this.webViewInternal = webViewInternal; @@ -185,7 +159,7 @@ function WebViewEvents(webViewInternal, viewInstanceId) { WebViewEvents.prototype.setup = function() { this.setupFrameNameChangedEvent(); this.setupPluginDestroyedEvent(); - this.setupWebRequestEvents(); + this.webViewInternal.maybeSetupChromeWebViewEvents(); this.webViewInternal.setupExperimentalContextMenus(); var events = this.getEvents(); @@ -206,70 +180,6 @@ WebViewEvents.prototype.setupPluginDestroyedEvent = function() { }.bind(this), {instanceId: this.viewInstanceId}); }; -WebViewEvents.prototype.setupWebRequestEvents = function() { - var request = {}; - var createWebRequestEvent = function(webRequestEvent) { - return function() { - if (!this[webRequestEvent.name]) { - this[webRequestEvent.name] = - new WebRequestEvent( - 'webViewInternal.' + webRequestEvent.name, - webRequestEvent.parameters, - webRequestEvent.extraParameters, webRequestEvent.options, - this.viewInstanceId); - } - return this[webRequestEvent.name]; - }.bind(this); - }.bind(this); - - var createDeclarativeWebRequestEvent = function(webRequestEvent) { - return function() { - if (!this[webRequestEvent.name]) { - // The onMessage event gets a special event type because we want - // the listener to fire only for messages targeted for this particular - // <webview>. - var EventClass = webRequestEvent.name === 'onMessage' ? - DeclarativeWebRequestEvent : EventBindings.Event; - this[webRequestEvent.name] = - new EventClass( - 'webViewInternal.' + webRequestEvent.name, - webRequestEvent.parameters, - webRequestEvent.options, - this.viewInstanceId); - } - return this[webRequestEvent.name]; - }.bind(this); - }.bind(this); - - for (var i = 0; i < DeclarativeWebRequestSchema.events.length; ++i) { - var eventSchema = DeclarativeWebRequestSchema.events[i]; - var webRequestEvent = createDeclarativeWebRequestEvent(eventSchema); - Object.defineProperty( - request, - eventSchema.name, - { - get: webRequestEvent, - enumerable: true - } - ); - } - - // Populate the WebRequest events from the API definition. - for (var i = 0; i < WebRequestSchema.events.length; ++i) { - var webRequestEvent = createWebRequestEvent(WebRequestSchema.events[i]); - Object.defineProperty( - request, - WebRequestSchema.events[i].name, - { - get: webRequestEvent, - enumerable: true - } - ); - } - - this.webViewInternal.setRequestPropertyOnWebViewNode(request); -}; - WebViewEvents.prototype.getEvents = function() { var experimentalEvents = this.webViewInternal.maybeGetExperimentalEvents(); for (var eventName in experimentalEvents) { diff --git a/extensions/shell/browser/shell_browser_context.cc b/extensions/shell/browser/shell_browser_context.cc index ed18aa2..33a08e3 100644 --- a/extensions/shell/browser/shell_browser_context.cc +++ b/extensions/shell/browser/shell_browser_context.cc @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "extensions/shell/browser/shell_browser_context.h" + +#include "extensions/browser/guest_view/guest_view_manager.h" #include "extensions/shell/browser/shell_special_storage_policy.h" namespace extensions { @@ -17,6 +19,10 @@ ShellBrowserContext::ShellBrowserContext() ShellBrowserContext::~ShellBrowserContext() { } +content::BrowserPluginGuestManager* ShellBrowserContext::GetGuestManager() { + return GuestViewManager::FromBrowserContext(this); +} + storage::SpecialStoragePolicy* ShellBrowserContext::GetSpecialStoragePolicy() { return storage_policy_.get(); } diff --git a/extensions/shell/browser/shell_browser_context.h b/extensions/shell/browser/shell_browser_context.h index d65fca4..305ab2b7 100644 --- a/extensions/shell/browser/shell_browser_context.h +++ b/extensions/shell/browser/shell_browser_context.h @@ -22,6 +22,7 @@ class ShellBrowserContext : public content::ShellBrowserContext { virtual ~ShellBrowserContext(); // content::BrowserContext implementation. + virtual content::BrowserPluginGuestManager* GetGuestManager() OVERRIDE; virtual storage::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE; // HACK: Pad the virtual function table so we trip an assertion if someone |