diff options
author | rockot@chromium.org <rockot@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-01 17:29:13 +0000 |
---|---|---|
committer | rockot@chromium.org <rockot@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-01 17:29:13 +0000 |
commit | e6893672ec403d9dbf7fc5aab64ba6109ffd625a (patch) | |
tree | 25d46598e07af97d4f284663a3e3d53412e4eb2b | |
parent | 3dfb202d7b2cbdb92b1fe9d6274211d823efebe8 (diff) | |
download | chromium_src-e6893672ec403d9dbf7fc5aab64ba6109ffd625a.zip chromium_src-e6893672ec403d9dbf7fc5aab64ba6109ffd625a.tar.gz chromium_src-e6893672ec403d9dbf7fc5aab64ba6109ffd625a.tar.bz2 |
Pull chrome stuff out of (and move) extensions::Dispatcher.
This moves Dispatcher into //extensions along with
several of its remaining dependencies.
This also introduces a DispatcherDelegate interface along with implementations for chrome and app_shell.
BUG=359836
TBR=sky for CCRC and ChromeRenderViewTest
Review URL: https://codereview.chromium.org/260083006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267564 0039d316-1c4b-4281-b951-d872f2087c98
82 files changed, 2271 insertions, 1670 deletions
diff --git a/apps/shell/app_shell.gyp b/apps/shell/app_shell.gyp index 1324ea5..8aa552a 100644 --- a/apps/shell/app_shell.gyp +++ b/apps/shell/app_shell.gyp @@ -139,6 +139,8 @@ 'renderer/shell_custom_bindings.cc', 'renderer/shell_custom_bindings.h', 'renderer/shell_custom_bindings.js', + 'renderer/shell_dispatcher_delegate.cc', + 'renderer/shell_dispatcher_delegate.h', 'renderer/shell_extensions_renderer_client.cc', 'renderer/shell_extensions_renderer_client.h', ], diff --git a/apps/shell/renderer/shell_content_renderer_client.cc b/apps/shell/renderer/shell_content_renderer_client.cc index 8c4befd..c2a7984 100644 --- a/apps/shell/renderer/shell_content_renderer_client.cc +++ b/apps/shell/renderer/shell_content_renderer_client.cc @@ -5,14 +5,15 @@ #include "apps/shell/renderer/shell_content_renderer_client.h" #include "apps/shell/common/shell_extensions_client.h" +#include "apps/shell/renderer/shell_dispatcher_delegate.h" #include "apps/shell/renderer/shell_extensions_renderer_client.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "chrome/renderer/extensions/extension_helper.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_frame_observer_tracker.h" #include "content/public/renderer/render_thread.h" #include "extensions/common/extensions_client.h" +#include "extensions/renderer/dispatcher.h" using blink::WebFrame; using blink::WebString; @@ -70,8 +71,11 @@ void ShellContentRendererClient::RenderThreadStarted() { extensions_renderer_client_.reset(new ShellExtensionsRendererClient); extensions::ExtensionsRendererClient::Set(extensions_renderer_client_.get()); + extension_dispatcher_delegate_.reset(new ShellDispatcherDelegate()); + // Must be initialized after ExtensionsRendererClient. - extension_dispatcher_.reset(new extensions::Dispatcher()); + extension_dispatcher_.reset( + new extensions::Dispatcher(extension_dispatcher_delegate_.get())); thread->AddObserver(extension_dispatcher_.get()); // TODO(jamescook): Init WebSecurityPolicy for chrome-extension: schemes. diff --git a/apps/shell/renderer/shell_content_renderer_client.h b/apps/shell/renderer/shell_content_renderer_client.h index 4a34810..506704c 100644 --- a/apps/shell/renderer/shell_content_renderer_client.h +++ b/apps/shell/renderer/shell_content_renderer_client.h @@ -12,6 +12,7 @@ namespace extensions { class Dispatcher; +class DispatcherDelegate; } namespace apps { @@ -43,6 +44,7 @@ class ShellContentRendererClient : public content::ContentRendererClient { private: scoped_ptr<ShellExtensionsClient> extensions_client_; scoped_ptr<ShellExtensionsRendererClient> extensions_renderer_client_; + scoped_ptr<extensions::DispatcherDelegate> extension_dispatcher_delegate_; scoped_ptr<extensions::Dispatcher> extension_dispatcher_; DISALLOW_COPY_AND_ASSIGN(ShellContentRendererClient); diff --git a/apps/shell/renderer/shell_dispatcher_delegate.cc b/apps/shell/renderer/shell_dispatcher_delegate.cc new file mode 100644 index 0000000..7959a5c --- /dev/null +++ b/apps/shell/renderer/shell_dispatcher_delegate.cc @@ -0,0 +1,35 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "apps/shell/renderer/shell_dispatcher_delegate.h" + +#include "apps/shell/renderer/shell_custom_bindings.h" +#include "extensions/renderer/module_system.h" +#include "extensions/renderer/resource_bundle_source_map.h" +#include "extensions/renderer/script_context.h" +#include "grit/app_shell_resources.h" + +namespace apps { + +ShellDispatcherDelegate::ShellDispatcherDelegate() { +} + +ShellDispatcherDelegate::~ShellDispatcherDelegate() { +} + +void ShellDispatcherDelegate::RegisterNativeHandlers( + extensions::Dispatcher* dispatcher, + extensions::ModuleSystem* module_system, + extensions::ScriptContext* context) { + module_system->RegisterNativeHandler( + "shell_natives", + scoped_ptr<extensions::NativeHandler>(new ShellCustomBindings(context))); +} + +void ShellDispatcherDelegate::PopulateSourceMap( + extensions::ResourceBundleSourceMap* source_map) { + source_map->RegisterSource("shell", IDR_SHELL_CUSTOM_BINDINGS_JS); +} + +} // namespace apps diff --git a/apps/shell/renderer/shell_dispatcher_delegate.h b/apps/shell/renderer/shell_dispatcher_delegate.h new file mode 100644 index 0000000..0bbb8f3 --- /dev/null +++ b/apps/shell/renderer/shell_dispatcher_delegate.h @@ -0,0 +1,35 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef APPS_SHELL_RENDERER_SHELL_DISPATCHER_DELEGATE_H_ +#define APPS_SHELL_RENDERER_SHELL_DISPATCHER_DELEGATE_H_ + +#include "base/macros.h" +#include "extensions/renderer/default_dispatcher_delegate.h" + +namespace apps { + +// app_shell's implementation of DispatcherDelegate. This inherits the behavior +// of the default delegate while augmenting its own script resources and native +// native handlers. +class ShellDispatcherDelegate : public extensions::DefaultDispatcherDelegate { + public: + ShellDispatcherDelegate(); + virtual ~ShellDispatcherDelegate(); + + // DispatcherDelegate implementation. + virtual void RegisterNativeHandlers( + extensions::Dispatcher* dispatcher, + extensions::ModuleSystem* module_system, + extensions::ScriptContext* context) OVERRIDE; + virtual void PopulateSourceMap( + extensions::ResourceBundleSourceMap* source_map) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(ShellDispatcherDelegate); +}; + +} // namespace apps + +#endif // APPS_SHELL_RENDERER_SHELL_DISPATCHER_DELEGATE_H_ diff --git a/apps/shell/renderer/shell_extensions_renderer_client.cc b/apps/shell/renderer/shell_extensions_renderer_client.cc index 039a970..c5de265 100644 --- a/apps/shell/renderer/shell_extensions_renderer_client.cc +++ b/apps/shell/renderer/shell_extensions_renderer_client.cc @@ -4,12 +4,6 @@ #include "apps/shell/renderer/shell_extensions_renderer_client.h" -#include "apps/shell/renderer/shell_custom_bindings.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/renderer/resource_bundle_source_map.h" -#include "extensions/renderer/module_system.h" -#include "grit/app_shell_resources.h" - namespace apps { ShellExtensionsRendererClient::ShellExtensionsRendererClient() {} @@ -28,17 +22,4 @@ int ShellExtensionsRendererClient::GetLowestIsolatedWorldId() const { return 1; } -void ShellExtensionsRendererClient::RegisterNativeHandlers( - extensions::ModuleSystem* module_system, - extensions::ScriptContext* context) { - module_system->RegisterNativeHandler( - "shell_natives", - scoped_ptr<extensions::NativeHandler>(new ShellCustomBindings(context))); -} - -void ShellExtensionsRendererClient::PopulateSourceMap( - ResourceBundleSourceMap* source_map) { - source_map->RegisterSource("shell", IDR_SHELL_CUSTOM_BINDINGS_JS); -} - } // namespace apps diff --git a/apps/shell/renderer/shell_extensions_renderer_client.h b/apps/shell/renderer/shell_extensions_renderer_client.h index e67d875..7b32f90 100644 --- a/apps/shell/renderer/shell_extensions_renderer_client.h +++ b/apps/shell/renderer/shell_extensions_renderer_client.h @@ -19,10 +19,6 @@ class ShellExtensionsRendererClient // extensions::ExtensionsRendererClient implementation. virtual bool IsIncognitoProcess() const OVERRIDE; virtual int GetLowestIsolatedWorldId() const OVERRIDE; - virtual void RegisterNativeHandlers( - extensions::ModuleSystem* module_system, - extensions::ScriptContext* context) OVERRIDE; - virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(ShellExtensionsRendererClient); diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc index dbe469c..67abb74 100644 --- a/chrome/browser/extensions/api/messaging/message_service.cc +++ b/chrome/browser/extensions/api/messaging/message_service.cc @@ -22,7 +22,6 @@ #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_util.h" -#include "chrome/common/extensions/manifest_handlers/externally_connectable.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" @@ -39,6 +38,7 @@ #include "extensions/common/extension_messages.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/background_info.h" +#include "extensions/common/manifest_handlers/externally_connectable.h" #include "extensions/common/manifest_handlers/incognito_info.h" #include "net/base/completion_callback.h" #include "url/gurl.h" diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index dbccd6c..6072b60 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -181,8 +181,6 @@ 'common/extensions/manifest_handlers/app_launch_info.h', 'common/extensions/manifest_handlers/content_scripts_handler.cc', 'common/extensions/manifest_handlers/content_scripts_handler.h', - 'common/extensions/manifest_handlers/externally_connectable.cc', - 'common/extensions/manifest_handlers/externally_connectable.h', 'common/extensions/manifest_handlers/minimum_chrome_version_checker.cc', 'common/extensions/manifest_handlers/minimum_chrome_version_checker.h', 'common/extensions/manifest_handlers/nacl_modules_handler.cc', diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index a4e5aab..949a0a8 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -46,24 +46,20 @@ 'sources': [ 'renderer/benchmarking_extension.cc', 'renderer/benchmarking_extension.h', - 'renderer/extensions/api_activity_logger.cc', - 'renderer/extensions/api_activity_logger.h', 'renderer/extensions/app_bindings.cc', 'renderer/extensions/app_bindings.h', - 'renderer/extensions/app_runtime_custom_bindings.cc', - 'renderer/extensions/app_runtime_custom_bindings.h', 'renderer/extensions/app_window_custom_bindings.cc', 'renderer/extensions/app_window_custom_bindings.h', 'renderer/extensions/cast_streaming_native_handler.cc', 'renderer/extensions/cast_streaming_native_handler.h', + 'renderer/extensions/chrome_extensions_dispatcher_delegate.cc', + 'renderer/extensions/chrome_extensions_dispatcher_delegate.h', 'renderer/extensions/chrome_extensions_renderer_client.cc', 'renderer/extensions/chrome_extensions_renderer_client.h', 'renderer/extensions/chrome_v8_context.cc', 'renderer/extensions/chrome_v8_context.h', 'renderer/extensions/chrome_v8_extension_handler.cc', 'renderer/extensions/chrome_v8_extension_handler.h', - 'renderer/extensions/dispatcher.cc', - 'renderer/extensions/dispatcher.h', 'renderer/extensions/extension_frame_helper.cc', 'renderer/extensions/extension_frame_helper.h', 'renderer/extensions/extension_helper.cc', @@ -76,8 +72,6 @@ 'renderer/extensions/file_browser_private_custom_bindings.h', 'renderer/extensions/media_galleries_custom_bindings.cc', 'renderer/extensions/media_galleries_custom_bindings.h', - 'renderer/extensions/messaging_bindings.cc', - 'renderer/extensions/messaging_bindings.h', 'renderer/extensions/page_actions_custom_bindings.cc', 'renderer/extensions/page_actions_custom_bindings.h', 'renderer/extensions/page_capture_custom_bindings.cc', @@ -90,8 +84,6 @@ 'renderer/extensions/renderer_permissions_policy_delegate.h', 'renderer/extensions/resource_request_policy.cc', 'renderer/extensions/resource_request_policy.h', - 'renderer/extensions/runtime_custom_bindings.cc', - 'renderer/extensions/runtime_custom_bindings.h', 'renderer/extensions/sync_file_system_custom_bindings.cc', 'renderer/extensions/sync_file_system_custom_bindings.h', 'renderer/extensions/tab_finder.cc', @@ -100,8 +92,6 @@ 'renderer/extensions/tabs_custom_bindings.h', 'renderer/extensions/user_script_scheduler.cc', 'renderer/extensions/user_script_scheduler.h', - 'renderer/extensions/user_script_slave.cc', - 'renderer/extensions/user_script_slave.h', 'renderer/extensions/webstore_bindings.cc', 'renderer/extensions/webstore_bindings.h', 'renderer/isolated_world_ids.h', @@ -145,8 +135,6 @@ 'renderer/playback_extension.h', 'renderer/principals_extension_bindings.cc', 'renderer/principals_extension_bindings.h', - 'renderer/resource_bundle_source_map.cc', - 'renderer/resource_bundle_source_map.h', 'renderer/resources/extensions/app_custom_bindings.js', 'renderer/resources/extensions/app_window_custom_bindings.js', 'renderer/resources/extensions/automation_custom_bindings.js', @@ -297,8 +285,6 @@ 'renderer/spellchecker/spellcheck_worditerator.cc', 'renderer/spellchecker/spellcheck_worditerator.h', 'renderer/spellchecker/spelling_engine.h', - 'renderer/static_v8_external_string_resource.cc', - 'renderer/static_v8_external_string_resource.h', 'renderer/tts_dispatcher.cc', 'renderer/tts_dispatcher.h', 'renderer/translate/translate_helper.cc', @@ -372,14 +358,14 @@ }], ['OS=="android"', { 'sources!': [ - 'renderer/prerender/prerender_media_load_deferrer.cc', - 'renderer/prerender/prerender_media_load_deferrer.h', 'renderer/extensions/app_window_custom_bindings.cc', 'renderer/extensions/chrome_v8_extension_handler.cc', 'renderer/extensions/file_browser_handler_custom_bindings.cc', 'renderer/extensions/page_actions_custom_bindings.cc', 'renderer/extensions/tabs_custom_bindings.cc', 'renderer/extensions/tts_custom_bindings.cc', + 'renderer/prerender/prerender_media_load_deferrer.cc', + 'renderer/prerender/prerender_media_load_deferrer.h', ], }], ['OS=="win" and target_arch=="ia32"', { diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 118b8e6..3537c8b 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -569,6 +569,7 @@ '../extensions/common/file_util_unittest.cc', '../extensions/common/id_util_unittest.cc', '../extensions/common/manifest_handler_unittest.cc', + '../extensions/common/manifest_handlers/externally_connectable_unittest.cc', '../extensions/common/manifest_handlers/shared_module_manifest_unittest.cc', '../extensions/common/message_bundle_unittest.cc', '../extensions/common/one_shot_event_unittest.cc', @@ -1801,7 +1802,6 @@ 'common/extensions/feature_switch_unittest.cc', 'common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc', 'common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc', - 'common/extensions/manifest_handlers/externally_connectable_unittest.cc', 'common/extensions/manifest_handlers/settings_overrides_handler_unittest.cc', 'common/extensions/manifest_handlers/ui_overrides_handler_unittest.cc', 'common/extensions/manifest_tests/extension_manifest_test.cc', diff --git a/chrome/common/extensions/api/manifest_types.json b/chrome/common/extensions/api/manifest_types.json index 592ca65..03f6ab8 100644 --- a/chrome/common/extensions/api/manifest_types.json +++ b/chrome/common/extensions/api/manifest_types.json @@ -13,32 +13,6 @@ }, "types": [ { - "id": "ExternallyConnectable", - "type": "object", - // Note: description commented out because externally_connectable.html - // already describes it, and the repetition looks odd. - // "description": "The <code>externally_connectable</code> manifest property declares which extensions, apps, and web pages can connect to your extension via $(ref:runtime.connect) and $(ref:runtime.sendMessage).", - "properties": { - "ids": { - "description": "<p>The IDs of extensions or apps that are allowed to connect. If left empty or unspecified, no extensions or apps can connect.</p><p>The wildcard <code>\"*\"</code> will allow all extensions and apps to connect.</p>", - "optional": true, - "type": "array", - "items": {"type": "string"} - }, - "matches": { - "description": "<p>The URL patterns for <em>web pages</em> that are allowed to connect. <em>This does not affect content scripts.</em> If left empty or unspecified, no web pages can connect.</p><p>Patterns cannot include wildcard domains nor subdomains of <a href=\"http://publicsuffix.org/list/\">(effective) top level domains</a>; <code>*://google.com/*</code> and <code>http://*.chromium.org/*</code> are valid, while <code><all_urls></code>, <code>http://*/*</code>, <code>*://*.com/*</code>, and even <code>http://*.appspot.com/*</code> are not.</p>", - "optional": true, - "type": "array", - "items": {"type": "string"} - }, - "accepts_tls_channel_id": { - "description": "If <code>true</code>, messages sent via $(ref:runtime.connect) or $(ref:runtime.sendMessage) will set $(ref:runtime.MessageSender.tlsChannelId) if those methods request it to be. If <code>false</code>, $(ref:runtime.MessageSender.tlsChannelId) will never be set under any circumstance.", - "optional": true, - "type": "boolean" - } - } - }, - { "id": "ChromeSettingsOverrides", "type": "object", "description": "Chrome settings which can be overriden by an extension.", diff --git a/chrome/common/extensions/chrome_manifest_handlers.cc b/chrome/common/extensions/chrome_manifest_handlers.cc index 877756c..872fc03 100644 --- a/chrome/common/extensions/chrome_manifest_handlers.cc +++ b/chrome/common/extensions/chrome_manifest_handlers.cc @@ -27,7 +27,6 @@ #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" -#include "chrome/common/extensions/manifest_handlers/externally_connectable.h" #include "chrome/common/extensions/manifest_handlers/minimum_chrome_version_checker.h" #include "chrome/common/extensions/manifest_handlers/nacl_modules_handler.h" #include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h" @@ -36,6 +35,7 @@ #include "chrome/common/extensions/manifest_url_handler.h" #include "chrome/common/extensions/mime_types_handler.h" #include "extensions/common/api/sockets/sockets_manifest_handler.h" +#include "extensions/common/manifest_handlers/externally_connectable.h" #include "extensions/common/manifest_handlers/icons_handler.h" #include "extensions/common/manifest_handlers/requirements_info.h" diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index f246fd4..467248e 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -31,8 +31,8 @@ #include "chrome/renderer/chrome_render_process_observer.h" #include "chrome/renderer/chrome_render_view_observer.h" #include "chrome/renderer/content_settings_observer.h" +#include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h" #include "chrome/renderer/extensions/chrome_extensions_renderer_client.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "chrome/renderer/extensions/extension_frame_helper.h" #include "chrome/renderer/extensions/extension_helper.h" #include "chrome/renderer/extensions/renderer_permissions_policy_delegate.h" @@ -81,6 +81,7 @@ #include "extensions/common/extension_set.h" #include "extensions/common/extension_urls.h" #include "extensions/common/switches.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/script_context.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" @@ -242,10 +243,14 @@ void ChromeContentRendererClient::RenderThreadStarted() { chrome_observer_.reset(new ChromeRenderProcessObserver(this)); + extension_dispatcher_delegate_.reset( + new ChromeExtensionsDispatcherDelegate()); // ChromeRenderViewTest::SetUp() creates its own ExtensionDispatcher and - // injects it using SetExtensionDispatcherForTest(). Don't overwrite it. - if (!extension_dispatcher_) - extension_dispatcher_.reset(new extensions::Dispatcher()); + // injects it using SetExtensionDispatcher(). Don't overwrite it. + if (!extension_dispatcher_) { + extension_dispatcher_.reset( + new extensions::Dispatcher(extension_dispatcher_delegate_.get())); + } permissions_policy_delegate_.reset( new extensions::RendererPermissionsPolicyDelegate( extension_dispatcher_.get())); @@ -1324,18 +1329,18 @@ bool ChromeContentRendererClient::IsAdblockPlusInstalled() { } bool ChromeContentRendererClient::IsAdblockWithWebRequestInstalled() { - return g_current_client->extension_dispatcher_-> - IsAdblockWithWebRequestInstalled(); + return g_current_client->extension_dispatcher_delegate_ + ->IsAdblockWithWebRequestInstalled(); } bool ChromeContentRendererClient::IsAdblockPlusWithWebRequestInstalled() { - return g_current_client->extension_dispatcher_-> - IsAdblockPlusWithWebRequestInstalled(); + return g_current_client->extension_dispatcher_delegate_ + ->IsAdblockPlusWithWebRequestInstalled(); } bool ChromeContentRendererClient::IsOtherExtensionWithWebRequestInstalled() { - return g_current_client->extension_dispatcher_-> - IsOtherExtensionWithWebRequestInstalled(); + return g_current_client->extension_dispatcher_delegate_ + ->IsOtherExtensionWithWebRequestInstalled(); } const void* ChromeContentRendererClient::CreatePPAPIInterface( diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index ba227e3..7fe7a82 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h @@ -15,6 +15,7 @@ #include "content/public/renderer/content_renderer_client.h" #include "ipc/ipc_channel_proxy.h" +class ChromeExtensionsDispatcherDelegate; class ChromeRenderProcessObserver; class PrescientNetworkingDispatcher; class RendererNetPredictor; @@ -189,6 +190,7 @@ class ChromeContentRendererClient : public content::ContentRendererClient { blink::WebPluginParams* params); scoped_ptr<ChromeRenderProcessObserver> chrome_observer_; + scoped_ptr<ChromeExtensionsDispatcherDelegate> extension_dispatcher_delegate_; scoped_ptr<extensions::Dispatcher> extension_dispatcher_; scoped_ptr<extensions::RendererPermissionsPolicyDelegate> permissions_policy_delegate_; diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc index 46c2012..1bfc461 100644 --- a/chrome/renderer/content_settings_observer.cc +++ b/chrome/renderer/content_settings_observer.cc @@ -9,12 +9,12 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "content/public/renderer/document_state.h" #include "content/public/renderer/navigation_state.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" #include "extensions/common/constants.h" +#include "extensions/renderer/dispatcher.h" #include "third_party/WebKit/public/platform/WebURL.h" #include "third_party/WebKit/public/web/WebDataSource.h" #include "third_party/WebKit/public/web/WebDocument.h" diff --git a/chrome/renderer/extensions/api_activity_logger.h b/chrome/renderer/extensions/api_activity_logger.h deleted file mode 100644 index 7eb4565..0000000 --- a/chrome/renderer/extensions/api_activity_logger.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_RENDERER_EXTENSIONS_API_ACTIVITY_LOGGER_H_ -#define CHROME_RENDERER_EXTENSIONS_API_ACTIVITY_LOGGER_H_ - -#include <string> - -#include "extensions/common/features/feature.h" -#include "extensions/renderer/object_backed_native_handler.h" -#include "v8/include/v8.h" - -namespace extensions { - -// Used to log extension API calls and events that are implemented with custom -// bindings.The actions are sent via IPC to extensions::ActivityLog for -// recording and display. -class APIActivityLogger : public ObjectBackedNativeHandler { - public: - explicit APIActivityLogger(ScriptContext* context); - - private: - // Used to distinguish API calls & events from each other in LogInternal. - enum CallType { - APICALL, - EVENT - }; - - // This is ultimately invoked in bindings.js with JavaScript arguments. - // arg0 - extension ID as a string - // arg1 - API call name as a string - // arg2 - arguments to the API call - // arg3 - any extra logging info as a string (optional) - static void LogAPICall(const v8::FunctionCallbackInfo<v8::Value>& args); - - // This is ultimately invoked in bindings.js with JavaScript arguments. - // arg0 - extension ID as a string - // arg1 - Event name as a string - // arg2 - Event arguments - // arg3 - any extra logging info as a string (optional) - static void LogEvent(const v8::FunctionCallbackInfo<v8::Value>& args); - - // LogAPICall and LogEvent are really the same underneath except for - // how they are ultimately dispatched to the log. - static void LogInternal(const CallType call_type, - const v8::FunctionCallbackInfo<v8::Value>& args); - - DISALLOW_COPY_AND_ASSIGN(APIActivityLogger); -}; - -} // namespace extensions - -#endif // CHROME_RENDERER_EXTENSIONS_API_ACTIVITY_LOGGER_H_ diff --git a/chrome/renderer/extensions/app_bindings.cc b/chrome/renderer/extensions/app_bindings.cc index 6ec369c..6e12d12 100644 --- a/chrome/renderer/extensions/app_bindings.cc +++ b/chrome/renderer/extensions/app_bindings.cc @@ -11,7 +11,6 @@ #include "base/values.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_constants.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "chrome/renderer/extensions/extension_helper.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/v8_value_converter.h" @@ -19,6 +18,7 @@ #include "extensions/common/extension_set.h" #include "extensions/common/manifest.h" #include "extensions/renderer/console.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/script_context.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" diff --git a/chrome/renderer/extensions/app_window_custom_bindings.cc b/chrome/renderer/extensions/app_window_custom_bindings.cc index fe0ccac..d9df7b4 100644 --- a/chrome/renderer/extensions/app_window_custom_bindings.cc +++ b/chrome/renderer/extensions/app_window_custom_bindings.cc @@ -8,13 +8,13 @@ #include "base/command_line.h" #include "chrome/common/chrome_switches.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view_observer.h" #include "content/public/renderer/render_view_visitor.h" #include "content/public/renderer/v8_value_converter.h" #include "extensions/common/extension_messages.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/scoped_persistent.h" #include "extensions/renderer/script_context.h" #include "extensions/renderer/script_context_set.h" diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc new file mode 100644 index 0000000..a7ffbb2 --- /dev/null +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc @@ -0,0 +1,355 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h" + +#include "base/command_line.h" +#include "base/sha1.h" +#include "base/strings/string_number_conversions.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/chrome_version_info.h" +#include "chrome/common/crash_keys.h" +#include "chrome/common/extensions/features/feature_channel.h" +#include "chrome/common/url_constants.h" +#include "chrome/renderer/extensions/app_bindings.h" +#include "chrome/renderer/extensions/app_window_custom_bindings.h" +#include "chrome/renderer/extensions/chrome_v8_context.h" +#include "chrome/renderer/extensions/file_browser_handler_custom_bindings.h" +#include "chrome/renderer/extensions/file_browser_private_custom_bindings.h" +#include "chrome/renderer/extensions/media_galleries_custom_bindings.h" +#include "chrome/renderer/extensions/page_actions_custom_bindings.h" +#include "chrome/renderer/extensions/page_capture_custom_bindings.h" +#include "chrome/renderer/extensions/pepper_request_natives.h" +#include "chrome/renderer/extensions/sync_file_system_custom_bindings.h" +#include "chrome/renderer/extensions/tab_finder.h" +#include "chrome/renderer/extensions/tabs_custom_bindings.h" +#include "chrome/renderer/extensions/webstore_bindings.h" +#include "content/public/renderer/render_thread.h" +#include "content/public/renderer/render_view.h" +#include "extensions/common/extension.h" +#include "extensions/common/permissions/api_permission_set.h" +#include "extensions/common/permissions/manifest_permission_set.h" +#include "extensions/common/permissions/permission_set.h" +#include "extensions/common/permissions/permissions_data.h" +#include "extensions/common/url_pattern_set.h" +#include "extensions/renderer/dispatcher.h" +#include "extensions/renderer/native_handler.h" +#include "extensions/renderer/resource_bundle_source_map.h" +#include "extensions/renderer/script_context.h" +#include "grit/renderer_resources.h" +#include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/web/WebSecurityPolicy.h" + +#if defined(ENABLE_WEBRTC) +#include "chrome/renderer/extensions/cast_streaming_native_handler.h" +#endif + +using extensions::NativeHandler; + +ChromeExtensionsDispatcherDelegate::ChromeExtensionsDispatcherDelegate() + : webrequest_adblock_(false), + webrequest_adblock_plus_(false), + webrequest_other_(false) { +} + +ChromeExtensionsDispatcherDelegate::~ChromeExtensionsDispatcherDelegate() { +} + +scoped_ptr<extensions::ScriptContext> +ChromeExtensionsDispatcherDelegate::CreateScriptContext( + const v8::Handle<v8::Context>& v8_context, + blink::WebFrame* frame, + const extensions::Extension* extension, + extensions::Feature::Context context_type) { + return scoped_ptr<extensions::ScriptContext>(new extensions::ChromeV8Context( + v8_context, frame, extension, context_type)); +} + +void ChromeExtensionsDispatcherDelegate::InitOriginPermissions( + const extensions::Extension* extension, + extensions::Feature::Context context_type) { + // TODO(jstritar): We should try to remove this special case. Also, these + // whitelist entries need to be updated when the kManagement permission + // changes. + if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT && + extension->HasAPIPermission(extensions::APIPermission::kManagement)) { + blink::WebSecurityPolicy::addOriginAccessWhitelistEntry( + extension->url(), + blink::WebString::fromUTF8(content::kChromeUIScheme), + blink::WebString::fromUTF8(chrome::kChromeUIExtensionIconHost), + false); + } +} + +void ChromeExtensionsDispatcherDelegate::RegisterNativeHandlers( + extensions::Dispatcher* dispatcher, + extensions::ModuleSystem* module_system, + extensions::ScriptContext* context) { +#if !defined(ENABLE_EXTENSIONS) + return; +#endif + module_system->RegisterNativeHandler( + "app", + scoped_ptr<NativeHandler>( + new extensions::AppBindings(dispatcher, context))); + module_system->RegisterNativeHandler( + "app_window_natives", + scoped_ptr<NativeHandler>( + new extensions::AppWindowCustomBindings(dispatcher, context))); + module_system->RegisterNativeHandler( + "sync_file_system", + scoped_ptr<NativeHandler>( + new extensions::SyncFileSystemCustomBindings(context))); + module_system->RegisterNativeHandler( + "file_browser_handler", + scoped_ptr<NativeHandler>( + new extensions::FileBrowserHandlerCustomBindings(context))); + module_system->RegisterNativeHandler( + "file_browser_private", + scoped_ptr<NativeHandler>( + new extensions::FileBrowserPrivateCustomBindings(context))); + module_system->RegisterNativeHandler( + "mediaGalleries", + scoped_ptr<NativeHandler>( + new extensions::MediaGalleriesCustomBindings(context))); + module_system->RegisterNativeHandler( + "page_actions", + scoped_ptr<NativeHandler>( + new extensions::PageActionsCustomBindings(dispatcher, context))); + module_system->RegisterNativeHandler( + "page_capture", + scoped_ptr<NativeHandler>( + new extensions::PageCaptureCustomBindings(context))); + module_system->RegisterNativeHandler( + "pepper_request_natives", + scoped_ptr<NativeHandler>(new extensions::PepperRequestNatives(context))); + module_system->RegisterNativeHandler( + "tabs", + scoped_ptr<NativeHandler>(new extensions::TabsCustomBindings(context))); + module_system->RegisterNativeHandler( + "webstore", + scoped_ptr<NativeHandler>(new extensions::WebstoreBindings(context))); +#if defined(ENABLE_WEBRTC) + module_system->RegisterNativeHandler( + "cast_streaming_natives", + scoped_ptr<NativeHandler>( + new extensions::CastStreamingNativeHandler(context))); +#endif +} + +void ChromeExtensionsDispatcherDelegate::PopulateSourceMap( + extensions::ResourceBundleSourceMap* source_map) { + // Libraries. + source_map->RegisterSource("pepper_request", IDR_PEPPER_REQUEST_JS); + + // Custom bindings. + source_map->RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("automation", IDR_AUTOMATION_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("automationEvent", IDR_AUTOMATION_EVENT_JS); + source_map->RegisterSource("automationNode", IDR_AUTOMATION_NODE_JS); + source_map->RegisterSource("automationTree", IDR_AUTOMATION_TREE_JS); + source_map->RegisterSource("browserAction", + IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("declarativeContent", + IDR_DECLARATIVE_CONTENT_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("declarativeWebRequest", + IDR_DECLARATIVE_WEBREQUEST_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("desktopCapture", + IDR_DESKTOP_CAPTURE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("developerPrivate", + IDR_DEVELOPER_PRIVATE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("downloads", IDR_DOWNLOADS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("feedbackPrivate", + IDR_FEEDBACK_PRIVATE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("fileBrowserHandler", + IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("fileBrowserPrivate", + IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("fileSystem", IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("fileSystemProvider", + IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("gcm", IDR_GCM_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("imageWriterPrivate", + IDR_IMAGE_WRITER_PRIVATE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("mediaGalleries", + IDR_MEDIA_GALLERIES_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("notifications", + IDR_NOTIFICATIONS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("pageActions", + IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("pageCapture", + IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("syncFileSystem", + IDR_SYNC_FILE_SYSTEM_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("systemIndicator", + IDR_SYSTEM_INDICATOR_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("tabCapture", IDR_TAB_CAPTURE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("webRequest", IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("webRequestInternal", + IDR_WEB_REQUEST_INTERNAL_CUSTOM_BINDINGS_JS); +#if defined(ENABLE_WEBRTC) + source_map->RegisterSource("cast.streaming.rtpStream", + IDR_CAST_STREAMING_RTP_STREAM_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("cast.streaming.session", + IDR_CAST_STREAMING_SESSION_CUSTOM_BINDINGS_JS); + source_map->RegisterSource( + "cast.streaming.udpTransport", + IDR_CAST_STREAMING_UDP_TRANSPORT_CUSTOM_BINDINGS_JS); +#endif + source_map->RegisterSource("webstore", IDR_WEBSTORE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("windowControls", IDR_WINDOW_CONTROLS_JS); + + // Custom types sources. + source_map->RegisterSource("ChromeSetting", IDR_CHROME_SETTING_JS); + source_map->RegisterSource("ContentSetting", IDR_CONTENT_SETTING_JS); + source_map->RegisterSource("ChromeDirectSetting", + IDR_CHROME_DIRECT_SETTING_JS); + + // Platform app sources that are not API-specific.. + source_map->RegisterSource("tagWatcher", IDR_TAG_WATCHER_JS); + source_map->RegisterSource("webview", IDR_WEBVIEW_CUSTOM_BINDINGS_JS); + // Note: webView not webview so that this doesn't interfere with the + // chrome.webview API bindings. + source_map->RegisterSource("webView", IDR_WEB_VIEW_JS); + source_map->RegisterSource("webViewExperimental", + IDR_WEB_VIEW_EXPERIMENTAL_JS); + source_map->RegisterSource("webViewRequest", + IDR_WEB_VIEW_REQUEST_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("denyWebView", IDR_WEB_VIEW_DENY_JS); + source_map->RegisterSource("adView", IDR_AD_VIEW_JS); + source_map->RegisterSource("denyAdView", IDR_AD_VIEW_DENY_JS); + source_map->RegisterSource("injectAppTitlebar", IDR_INJECT_APP_TITLEBAR_JS); +} + +void ChromeExtensionsDispatcherDelegate::RequireAdditionalModules( + extensions::ModuleSystem* module_system, + const extensions::Extension* extension, + extensions::Feature::Context context_type, + bool is_within_platform_app) { + if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT && + is_within_platform_app && + extensions::GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV && + CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kEnableAppWindowControls)) { + module_system->Require("windowControls"); + } + + // We used to limit WebView to |BLESSED_EXTENSION_CONTEXT| within platform + // apps. An ext/app runs in a blessed extension context, if it is the active + // extension in the current process, in other words, if it is loaded in a top + // frame. To support webview in a non-frame extension, we have to allow + // unblessed extension context as well. + // Note: setting up the WebView class here, not the chrome.webview API. + // The API will be automatically set up when first used. + if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT || + context_type == extensions::Feature::UNBLESSED_EXTENSION_CONTEXT) { + if (extension->HasAPIPermission(extensions::APIPermission::kWebView)) { + module_system->Require("webView"); + if (extensions::GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV) { + module_system->Require("webViewExperimental"); + } else { + // TODO(asargent) We need a whitelist for webview experimental. + // crbug.com/264852 + std::string id_hash = base::SHA1HashString(extension->id()); + std::string hexencoded_id_hash = + base::HexEncode(id_hash.c_str(), id_hash.length()); + if (hexencoded_id_hash == "8C3741E3AF0B93B6E8E0DDD499BB0B74839EA578" || + hexencoded_id_hash == "E703483CEF33DEC18B4B6DD84B5C776FB9182BDB" || + hexencoded_id_hash == "1A26E32DE447A17CBE5E9750CDBA78F58539B39C" || + hexencoded_id_hash == "59048028102D7B4C681DBC7BC6CD980C3DC66DA3") { + module_system->Require("webViewExperimental"); + } + } + } else { + module_system->Require("denyWebView"); + } + } + + // Same comment as above for <adview> tag. + if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT && + is_within_platform_app) { + if (CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kEnableAdview)) { + if (extension->HasAPIPermission(extensions::APIPermission::kAdView)) { + module_system->Require("adView"); + } else { + module_system->Require("denyAdView"); + } + } + } +} + +void ChromeExtensionsDispatcherDelegate::OnActiveExtensionsUpdated( + const std::set<std::string>& extension_ids) { + // In single-process mode, the browser process reports the active extensions. + if (CommandLine::ForCurrentProcess()->HasSwitch(::switches::kSingleProcess)) + return; + crash_keys::SetActiveExtensions(extension_ids); +} + +void ChromeExtensionsDispatcherDelegate::SetChannel(int channel) { + extensions::SetCurrentChannel( + static_cast<chrome::VersionInfo::Channel>(channel)); +} + +void ChromeExtensionsDispatcherDelegate::ClearTabSpecificPermissions( + const extensions::Dispatcher* dispatcher, + int tab_id, + const std::vector<std::string>& extension_ids) { + for (std::vector<std::string>::const_iterator it = extension_ids.begin(); + it != extension_ids.end(); + ++it) { + const extensions::Extension* extension = + dispatcher->extensions()->GetByID(*it); + if (extension) + extensions::PermissionsData::ClearTabSpecificPermissions(extension, + tab_id); + } +} + +void ChromeExtensionsDispatcherDelegate::UpdateTabSpecificPermissions( + const extensions::Dispatcher* dispatcher, + int page_id, + int tab_id, + const std::string& extension_id, + const extensions::URLPatternSet& origin_set) { + content::RenderView* view = extensions::TabFinder::Find(tab_id); + + // For now, the message should only be sent to the render view that contains + // the target tab. This may change. Either way, if this is the target tab it + // gives us the chance to check against the page ID to avoid races. + DCHECK(view); + if (view && view->GetPageId() != page_id) + return; + + const extensions::Extension* extension = + dispatcher->extensions()->GetByID(extension_id); + if (!extension) + return; + + extensions::PermissionsData::UpdateTabSpecificPermissions( + extension, + tab_id, + new extensions::PermissionSet(extensions::APIPermissionSet(), + extensions::ManifestPermissionSet(), + origin_set, + extensions::URLPatternSet())); +} + +void ChromeExtensionsDispatcherDelegate::HandleWebRequestAPIUsage( + bool adblock, + bool adblock_plus, + bool other) { + webrequest_adblock_ = adblock; + webrequest_adblock_plus_ = adblock_plus; + webrequest_other_ = other; +} diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h new file mode 100644 index 0000000..5a24e2b4 --- /dev/null +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h @@ -0,0 +1,74 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_EXTENSIONS_CHROME_EXTENSIONS_DISPATCHER_DELEGATE_H_ +#define CHROME_RENDERER_EXTENSIONS_CHROME_EXTENSIONS_DISPATCHER_DELEGATE_H_ + +#include "extensions/renderer/dispatcher_delegate.h" + +class ChromeExtensionsDispatcherDelegate + : public extensions::DispatcherDelegate { + public: + ChromeExtensionsDispatcherDelegate(); + virtual ~ChromeExtensionsDispatcherDelegate(); + + // TODO(mpcomplete): remove. http://crbug.com/100411 + bool IsAdblockWithWebRequestInstalled() const { return webrequest_adblock_; } + + bool IsAdblockPlusWithWebRequestInstalled() const { + return webrequest_adblock_plus_; + } + + bool IsOtherExtensionWithWebRequestInstalled() const { + return webrequest_other_; + } + + private: + // extensions::DispatcherDelegate implementation. + virtual scoped_ptr<extensions::ScriptContext> CreateScriptContext( + const v8::Handle<v8::Context>& v8_context, + blink::WebFrame* frame, + const extensions::Extension* extension, + extensions::Feature::Context context_type) OVERRIDE; + virtual void InitOriginPermissions( + const extensions::Extension* extension, + extensions::Feature::Context context_type) OVERRIDE; + virtual void RegisterNativeHandlers( + extensions::Dispatcher* dispatcher, + extensions::ModuleSystem* module_system, + extensions::ScriptContext* context) OVERRIDE; + virtual void PopulateSourceMap( + extensions::ResourceBundleSourceMap* source_map) OVERRIDE; + virtual void RequireAdditionalModules( + extensions::ModuleSystem* module_system, + const extensions::Extension* extension, + extensions::Feature::Context context_type, + bool is_within_platform_app) OVERRIDE; + virtual void OnActiveExtensionsUpdated( + const std::set<std::string>& extensions_ids) OVERRIDE; + virtual void SetChannel(int channel) OVERRIDE; + virtual void ClearTabSpecificPermissions( + const extensions::Dispatcher* dispatcher, + int tab_id, + const std::vector<std::string>& extension_ids) OVERRIDE; + virtual void UpdateTabSpecificPermissions( + const extensions::Dispatcher* dispatcher, + int page_id, + int tab_id, + const std::string& extension_id, + const extensions::URLPatternSet& origin_set) OVERRIDE; + virtual void HandleWebRequestAPIUsage(bool adblock, + bool adblock_plus, + bool other_webrequest) OVERRIDE; + + // Status of webrequest usage for known extensions. + // TODO(mpcomplete): remove. http://crbug.com/100411 + bool webrequest_adblock_; + bool webrequest_adblock_plus_; + bool webrequest_other_; + + DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsDispatcherDelegate); +}; + +#endif // CHROME_RENDERER_EXTENSIONS_CHROME_EXTENSIONS_DISPATCHER_DELEGATE_H_ diff --git a/chrome/renderer/extensions/chrome_extensions_renderer_client.cc b/chrome/renderer/extensions/chrome_extensions_renderer_client.cc index cd0b732..c3ef38d 100644 --- a/chrome/renderer/extensions/chrome_extensions_renderer_client.cc +++ b/chrome/renderer/extensions/chrome_extensions_renderer_client.cc @@ -26,12 +26,3 @@ bool ChromeExtensionsRendererClient::IsIncognitoProcess() const { int ChromeExtensionsRendererClient::GetLowestIsolatedWorldId() const { return chrome::ISOLATED_WORLD_ID_EXTENSIONS; } - -void ChromeExtensionsRendererClient::RegisterNativeHandlers( - extensions::ModuleSystem* module_system, - extensions::ScriptContext* context) { -} - -void ChromeExtensionsRendererClient::PopulateSourceMap( - ResourceBundleSourceMap* source_map) { -} diff --git a/chrome/renderer/extensions/chrome_extensions_renderer_client.h b/chrome/renderer/extensions/chrome_extensions_renderer_client.h index 092e52f..801bc1aa 100644 --- a/chrome/renderer/extensions/chrome_extensions_renderer_client.h +++ b/chrome/renderer/extensions/chrome_extensions_renderer_client.h @@ -20,10 +20,6 @@ class ChromeExtensionsRendererClient // extensions::ExtensionsRendererClient implementation. virtual bool IsIncognitoProcess() const OVERRIDE; virtual int GetLowestIsolatedWorldId() const OVERRIDE; - virtual void RegisterNativeHandlers( - extensions::ModuleSystem* module_system, - extensions::ScriptContext* context) OVERRIDE; - virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsRendererClient); diff --git a/chrome/renderer/extensions/chrome_v8_context.cc b/chrome/renderer/extensions/chrome_v8_context.cc index 795d298..8d58f70 100644 --- a/chrome/renderer/extensions/chrome_v8_context.cc +++ b/chrome/renderer/extensions/chrome_v8_context.cc @@ -7,21 +7,22 @@ #include "base/memory/scoped_ptr.h" #include "base/strings/string_split.h" #include "base/values.h" -#include "chrome/renderer/extensions/user_script_slave.h" #include "extensions/common/extension_api.h" #include "extensions/common/extension_urls.h" #include "extensions/common/features/base_feature_provider.h" #include "extensions/renderer/module_system.h" +#include "extensions/renderer/user_script_slave.h" #include "third_party/WebKit/public/web/WebFrame.h" #include "v8/include/v8.h" namespace extensions { -ChromeV8Context::ChromeV8Context(v8::Handle<v8::Context> v8_context, +ChromeV8Context::ChromeV8Context(const v8::Handle<v8::Context>& v8_context, blink::WebFrame* web_frame, const Extension* extension, Feature::Context context_type) : ScriptContext(v8_context, web_frame, extension, context_type), - pepper_request_proxy_(this) {} + pepper_request_proxy_(this) { +} } // namespace extensions diff --git a/chrome/renderer/extensions/chrome_v8_context.h b/chrome/renderer/extensions/chrome_v8_context.h index 41c8403..d4779db 100644 --- a/chrome/renderer/extensions/chrome_v8_context.h +++ b/chrome/renderer/extensions/chrome_v8_context.h @@ -32,7 +32,7 @@ class Extension; // Chrome's wrapper for a v8 context. class ChromeV8Context : public ScriptContext { public: - ChromeV8Context(v8::Handle<v8::Context> context, + ChromeV8Context(const v8::Handle<v8::Context>& context, blink::WebFrame* frame, const Extension* extension, Feature::Context context_type); diff --git a/chrome/renderer/extensions/extension_frame_helper.cc b/chrome/renderer/extensions/extension_frame_helper.cc index f9b75e1..c88c4cd 100644 --- a/chrome/renderer/extensions/extension_frame_helper.cc +++ b/chrome/renderer/extensions/extension_frame_helper.cc @@ -4,10 +4,10 @@ #include "chrome/renderer/extensions/extension_frame_helper.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "content/public/renderer/render_frame.h" #include "extensions/common/extension_messages.h" #include "extensions/renderer/console.h" +#include "extensions/renderer/dispatcher.h" #include "third_party/WebKit/public/web/WebConsoleMessage.h" #include "third_party/WebKit/public/web/WebFrame.h" diff --git a/chrome/renderer/extensions/extension_helper.cc b/chrome/renderer/extensions/extension_helper.cc index 92108e7..885b107 100644 --- a/chrome/renderer/extensions/extension_helper.cc +++ b/chrome/renderer/extensions/extension_helper.cc @@ -16,10 +16,7 @@ #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" #include "chrome/renderer/extensions/chrome_v8_context.h" -#include "chrome/renderer/extensions/dispatcher.h" -#include "chrome/renderer/extensions/messaging_bindings.h" #include "chrome/renderer/extensions/user_script_scheduler.h" -#include "chrome/renderer/extensions/user_script_slave.h" #include "chrome/renderer/web_apps.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view_visitor.h" @@ -27,6 +24,9 @@ #include "extensions/common/constants.h" #include "extensions/common/extension_messages.h" #include "extensions/renderer/console.h" +#include "extensions/renderer/dispatcher.h" +#include "extensions/renderer/messaging_bindings.h" +#include "extensions/renderer/user_script_slave.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" #include "third_party/WebKit/public/web/WebConsoleMessage.h" #include "third_party/WebKit/public/web/WebDocument.h" diff --git a/chrome/renderer/extensions/page_actions_custom_bindings.cc b/chrome/renderer/extensions/page_actions_custom_bindings.cc index fa74cfb..32237a2 100644 --- a/chrome/renderer/extensions/page_actions_custom_bindings.cc +++ b/chrome/renderer/extensions/page_actions_custom_bindings.cc @@ -8,8 +8,8 @@ #include "base/bind.h" #include "chrome/common/extensions/api/extension_action/action_info.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "extensions/common/extension.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/script_context.h" #include "v8/include/v8.h" diff --git a/chrome/renderer/extensions/renderer_permissions_policy_delegate.cc b/chrome/renderer/extensions/renderer_permissions_policy_delegate.cc index 2774064..63744c2 100644 --- a/chrome/renderer/extensions/renderer_permissions_policy_delegate.cc +++ b/chrome/renderer/extensions/renderer_permissions_policy_delegate.cc @@ -7,10 +7,10 @@ #include "base/command_line.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_constants.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "extensions/common/extensions_client.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/switches.h" +#include "extensions/renderer/dispatcher.h" namespace extensions { diff --git a/chrome/renderer/extensions/renderer_permissions_policy_delegate_unittest.cc b/chrome/renderer/extensions/renderer_permissions_policy_delegate_unittest.cc index 4cd5d97..b17d76e 100644 --- a/chrome/renderer/extensions/renderer_permissions_policy_delegate_unittest.cc +++ b/chrome/renderer/extensions/renderer_permissions_policy_delegate_unittest.cc @@ -5,7 +5,7 @@ #include "base/command_line.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_constants.h" -#include "chrome/renderer/extensions/dispatcher.h" +#include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h" #include "chrome/renderer/extensions/renderer_permissions_policy_delegate.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/mock_render_thread.h" @@ -13,6 +13,7 @@ #include "extensions/common/extension_builder.h" #include "extensions/common/extension_messages.h" #include "extensions/common/permissions/permissions_data.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/test_extensions_renderer_client.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,7 +31,10 @@ class RendererPermissionsPolicyDelegateTest : public testing::Test { render_thread_.reset(new content::MockRenderThread()); renderer_client_.reset(new TestExtensionsRendererClient); ExtensionsRendererClient::Set(renderer_client_.get()); - extension_dispatcher_.reset(new Dispatcher()); + extension_dispatcher_delegate_.reset( + new ChromeExtensionsDispatcherDelegate()); + extension_dispatcher_.reset( + new Dispatcher(extension_dispatcher_delegate_.get())); policy_delegate_.reset( new RendererPermissionsPolicyDelegate(extension_dispatcher_.get())); } @@ -38,6 +42,7 @@ class RendererPermissionsPolicyDelegateTest : public testing::Test { protected: scoped_ptr<content::MockRenderThread> render_thread_; scoped_ptr<ExtensionsRendererClient> renderer_client_; + scoped_ptr<DispatcherDelegate> extension_dispatcher_delegate_; scoped_ptr<Dispatcher> extension_dispatcher_; scoped_ptr<RendererPermissionsPolicyDelegate> policy_delegate_; }; diff --git a/chrome/renderer/extensions/user_script_scheduler.cc b/chrome/renderer/extensions/user_script_scheduler.cc index e36ac59..1ff5445 100644 --- a/chrome/renderer/extensions/user_script_scheduler.cc +++ b/chrome/renderer/extensions/user_script_scheduler.cc @@ -9,18 +9,18 @@ #include "base/message_loop/message_loop.h" #include "chrome/renderer/chrome_render_process_observer.h" #include "chrome/renderer/extensions/chrome_v8_context.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "chrome/renderer/extensions/extension_helper.h" -#include "chrome/renderer/extensions/user_script_slave.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/v8_value_converter.h" #include "extensions/common/error_utils.h" #include "extensions/common/extension_messages.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/permissions/permissions_data.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/dom_activity_logger.h" #include "extensions/renderer/extension_groups.h" #include "extensions/renderer/script_context.h" +#include "extensions/renderer/user_script_slave.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebVector.h" #include "third_party/WebKit/public/web/WebDocument.h" diff --git a/chrome/renderer/pepper/pepper_extensions_common_host.cc b/chrome/renderer/pepper/pepper_extensions_common_host.cc index f48d6b4..2b8c76f 100644 --- a/chrome/renderer/pepper/pepper_extensions_common_host.cc +++ b/chrome/renderer/pepper/pepper_extensions_common_host.cc @@ -8,10 +8,10 @@ #include "base/memory/scoped_ptr.h" #include "base/values.h" #include "chrome/renderer/extensions/chrome_v8_context.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "chrome/renderer/extensions/extension_helper.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/renderer_ppapi_host.h" +#include "extensions/renderer/dispatcher.h" #include "ppapi/c/pp_errors.h" #include "ppapi/host/dispatch_host_message.h" #include "ppapi/host/host_message_context.h" diff --git a/chrome/renderer/resources/extensions/app_custom_bindings.js b/chrome/renderer/resources/extensions/app_custom_bindings.js index 2ba59e6..e757502 100644 --- a/chrome/renderer/resources/extensions/app_custom_bindings.js +++ b/chrome/renderer/resources/extensions/app_custom_bindings.js @@ -71,7 +71,5 @@ app.installState = function getInstallState(callback) { if (extensionId) app.installState = wrapForLogging(app.installState); -// This must match InstallAppBindings() in -// chrome/renderer/extensions/dispatcher.cc. -exports.chromeApp = app; +exports.binding = app; exports.onInstallStateResponse = onInstallStateResponse; diff --git a/chrome/renderer/resources/extensions/webstore_custom_bindings.js b/chrome/renderer/resources/extensions/webstore_custom_bindings.js index c31f40f..b720106 100644 --- a/chrome/renderer/resources/extensions/webstore_custom_bindings.js +++ b/chrome/renderer/resources/extensions/webstore_custom_bindings.js @@ -84,9 +84,7 @@ var chromeWebstore = { onDownloadProgress: installer.onDownloadProgress }; -// This must match the name in InstallWebstoreBindings in -// chrome/renderer/extensions/dispatcher.cc. -exports.chromeWebstore = chromeWebstore; +exports.binding = chromeWebstore; // Called by webstore_bindings.cc. exports.onInstallResponse = diff --git a/chrome/test/base/chrome_render_view_test.cc b/chrome/test/base/chrome_render_view_test.cc index a1ddd2f..92425b1 100644 --- a/chrome/test/base/chrome_render_view_test.cc +++ b/chrome/test/base/chrome_render_view_test.cc @@ -9,7 +9,7 @@ #include "chrome/common/chrome_content_client.h" #include "chrome/common/render_messages.h" #include "chrome/renderer/chrome_content_renderer_client.h" -#include "chrome/renderer/extensions/dispatcher.h" +#include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h" #include "chrome/renderer/spellchecker/spellcheck.h" #include "chrome/test/base/chrome_unit_test_suite.h" #include "components/autofill/content/renderer/autofill_agent.h" @@ -21,6 +21,7 @@ #include "content/public/renderer/render_view.h" #include "extensions/browser/extension_function_dispatcher.h" #include "extensions/common/extension.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/event_bindings.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" #include "third_party/WebKit/public/web/WebFrame.h" @@ -93,8 +94,11 @@ content::ContentBrowserClient* content::ContentRendererClient* ChromeRenderViewTest::CreateContentRendererClient() { + extension_dispatcher_delegate_.reset( + new ChromeExtensionsDispatcherDelegate()); ChromeContentRendererClient* client = new ChromeContentRendererClient(); - client->SetExtensionDispatcherForTest(new extensions::Dispatcher); + client->SetExtensionDispatcherForTest( + new extensions::Dispatcher(extension_dispatcher_delegate_.get())); #if defined(ENABLE_SPELLCHECK) client->SetSpellcheck(new SpellCheck()); #endif diff --git a/chrome/test/base/chrome_render_view_test.h b/chrome/test/base/chrome_render_view_test.h index 5c4824f..19ee8d2 100644 --- a/chrome/test/base/chrome_render_view_test.h +++ b/chrome/test/base/chrome_render_view_test.h @@ -7,6 +7,7 @@ #include <string> +#include "base/memory/scoped_ptr.h" #include "chrome/renderer/chrome_mock_render_thread.h" #include "content/public/test/render_view_test.h" @@ -16,6 +17,10 @@ class TestPasswordAutofillAgent; class TestPasswordGenerationAgent; } +namespace extensions { +class DispatcherDelegate; +} + class ChromeRenderViewTest : public content::RenderViewTest { public: ChromeRenderViewTest(); @@ -30,6 +35,8 @@ class ChromeRenderViewTest : public content::RenderViewTest { virtual content::ContentRendererClient* CreateContentRendererClient() OVERRIDE; + scoped_ptr<extensions::DispatcherDelegate> extension_dispatcher_delegate_; + autofill::TestPasswordAutofillAgent* password_autofill_; autofill::TestPasswordGenerationAgent* password_generation_; autofill::AutofillAgent* autofill_agent_; diff --git a/extensions/DEPS b/extensions/DEPS index 5d3a4d5..4dabc14 100644 --- a/extensions/DEPS +++ b/extensions/DEPS @@ -2,6 +2,7 @@ include_rules = [ "+components/url_matcher", "+content/public/common", "+crypto", + "+grit/extensions_resources.h", "+testing", "+ui", @@ -12,10 +13,12 @@ include_rules = [ # # TODO(jamescook): Remove these. http://crbug.com/162530 "!chrome/browser/chrome_notification_types.h", - "!chrome/renderer/extensions/dispatcher.h", "!chrome/renderer/extensions/extension_helper.h", "!grit/common_resources.h", - "!grit/extensions_api_resources.h", + '!grit/extensions_api_resources.h', + # This is needed for renderer JS sources which should eventually move to + # the extensions_resources target. + "!grit/renderer_resources.h", ] specific_include_rules = { @@ -28,12 +31,12 @@ specific_include_rules = { "+chrome/browser/extensions/extension_service_unittest.h", "+chrome/browser/extensions/test_extension_system.h", "+chrome/common/chrome_paths.h", + "+chrome/common/extensions/features/feature_channel.h", "+chrome/common/extensions/manifest_tests/extension_manifest_test.h", "+chrome/test/base/testing_profile.h", ], "(simple|complex)_feature_unittest\.cc|base_feature_provider_unittest\.cc": [ "+chrome/common/extensions/features/chrome_channel_feature_filter.h", - "+chrome/common/extensions/features/feature_channel.h", ], "permissions_data_unittest\.cc": [ "+chrome/common/chrome_version_info.h", diff --git a/extensions/common/api/extensions_manifest_types.json b/extensions/common/api/extensions_manifest_types.json index 24c2df5..00262692 100644 --- a/extensions/common/api/extensions_manifest_types.json +++ b/extensions/common/api/extensions_manifest_types.json @@ -13,6 +13,32 @@ }, "types": [ { + "id": "ExternallyConnectable", + "type": "object", + // Note: description commented out because externally_connectable.html + // already describes it, and the repetition looks odd. + // "description": "The <code>externally_connectable</code> manifest property declares which extensions, apps, and web pages can connect to your extension via $(ref:runtime.connect) and $(ref:runtime.sendMessage).", + "properties": { + "ids": { + "description": "<p>The IDs of extensions or apps that are allowed to connect. If left empty or unspecified, no extensions or apps can connect.</p><p>The wildcard <code>\"*\"</code> will allow all extensions and apps to connect.</p>", + "optional": true, + "type": "array", + "items": {"type": "string"} + }, + "matches": { + "description": "<p>The URL patterns for <em>web pages</em> that are allowed to connect. <em>This does not affect content scripts.</em> If left empty or unspecified, no web pages can connect.</p><p>Patterns cannot include wildcard domains nor subdomains of <a href=\"http://publicsuffix.org/list/\">(effective) top level domains</a>; <code>*://google.com/*</code> and <code>http://*.chromium.org/*</code> are valid, while <code><all_urls></code>, <code>http://*/*</code>, <code>*://*.com/*</code>, and even <code>http://*.appspot.com/*</code> are not.</p>", + "optional": true, + "type": "array", + "items": {"type": "string"} + }, + "accepts_tls_channel_id": { + "description": "If <code>true</code>, messages sent via $(ref:runtime.connect) or $(ref:runtime.sendMessage) will set $(ref:runtime.MessageSender.tlsChannelId) if those methods request it to be. If <code>false</code>, $(ref:runtime.MessageSender.tlsChannelId) will never be set under any circumstance.", + "optional": true, + "type": "boolean" + } + } + }, + { "id": "SocketHostPatterns", "description": "<p>A single string or a list of strings representing host:port patterns.</p>", "choices": [ diff --git a/chrome/common/extensions/manifest_handlers/externally_connectable.cc b/extensions/common/manifest_handlers/externally_connectable.cc index cacb13a..1261ad8 100644 --- a/chrome/common/extensions/manifest_handlers/externally_connectable.cc +++ b/extensions/common/manifest_handlers/externally_connectable.cc @@ -1,14 +1,14 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/common/extensions/manifest_handlers/externally_connectable.h" +#include "extensions/common/manifest_handlers/externally_connectable.h" #include <algorithm> #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/common/extensions/api/manifest_types.h" +#include "extensions/common/api/extensions_manifest_types.h" #include "extensions/common/error_utils.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/permissions/api_permission_set.h" @@ -36,7 +36,7 @@ const char kErrorWildcardHostsNotAllowed[] = namespace keys = extensions::manifest_keys; namespace errors = externally_connectable_errors; -using api::manifest_types::ExternallyConnectable; +using core_api::extensions_manifest_types::ExternallyConnectable; namespace { @@ -49,11 +49,13 @@ std::vector<T> Sorted(const std::vector<T>& in) { return out; } -} // namespace +} // namespace -ExternallyConnectableHandler::ExternallyConnectableHandler() {} +ExternallyConnectableHandler::ExternallyConnectableHandler() { +} -ExternallyConnectableHandler::~ExternallyConnectableHandler() {} +ExternallyConnectableHandler::~ExternallyConnectableHandler() { +} bool ExternallyConnectableHandler::Parse(Extension* extension, base::string16* error) { @@ -62,14 +64,13 @@ bool ExternallyConnectableHandler::Parse(Extension* extension, &externally_connectable)); std::vector<InstallWarning> install_warnings; scoped_ptr<ExternallyConnectableInfo> info = - ExternallyConnectableInfo::FromValue(*externally_connectable, - &install_warnings, - error); + ExternallyConnectableInfo::FromValue( + *externally_connectable, &install_warnings, error); if (!info) return false; if (!info->matches.is_empty()) { - PermissionsData::GetInitialAPIPermissions(extension)->insert( - APIPermission::kWebConnectable); + PermissionsData::GetInitialAPIPermissions(extension) + ->insert(APIPermission::kWebConnectable); } extension->AddInstallWarnings(install_warnings); extension->SetManifestData(keys::kExternallyConnectable, info.release()); @@ -102,7 +103,8 @@ scoped_ptr<ExternallyConnectableInfo> ExternallyConnectableInfo::FromValue( if (externally_connectable->matches) { for (std::vector<std::string>::iterator it = externally_connectable->matches->begin(); - it != externally_connectable->matches->end(); ++it) { + it != externally_connectable->matches->end(); + ++it) { // Safe to use SCHEME_ALL here; externally_connectable gives a page -> // extension communication path, not the other way. URLPattern pattern(URLPattern::SCHEME_ALL); @@ -115,11 +117,11 @@ scoped_ptr<ExternallyConnectableInfo> ExternallyConnectableInfo::FromValue( // Wildcard hosts are not allowed. if (pattern.host().empty()) { // Warning not error for forwards compatibility. - install_warnings->push_back(InstallWarning( - ErrorUtils::FormatErrorMessage( - errors::kErrorWildcardHostsNotAllowed, *it), - keys::kExternallyConnectable, - *it)); + install_warnings->push_back( + InstallWarning(ErrorUtils::FormatErrorMessage( + errors::kErrorWildcardHostsNotAllowed, *it), + keys::kExternallyConnectable, + *it)); continue; } @@ -145,13 +147,13 @@ scoped_ptr<ExternallyConnectableInfo> ExternallyConnectableInfo::FromValue( // are not allowed. However just "appspot.com" is ok. if (registry_length == 0 && pattern.match_subdomains()) { // Warning not error for forwards compatibility. - install_warnings->push_back(InstallWarning( - ErrorUtils::FormatErrorMessage( - errors::kErrorTopLevelDomainsNotAllowed, - pattern.host().c_str(), - *it), - keys::kExternallyConnectable, - *it)); + install_warnings->push_back( + InstallWarning(ErrorUtils::FormatErrorMessage( + errors::kErrorTopLevelDomainsNotAllowed, + pattern.host().c_str(), + *it), + keys::kExternallyConnectable, + *it)); continue; } @@ -165,43 +167,45 @@ scoped_ptr<ExternallyConnectableInfo> ExternallyConnectableInfo::FromValue( if (externally_connectable->ids) { for (std::vector<std::string>::iterator it = externally_connectable->ids->begin(); - it != externally_connectable->ids->end(); ++it) { + it != externally_connectable->ids->end(); + ++it) { if (*it == kAllIds) { all_ids = true; } else if (Extension::IdIsValid(*it)) { ids.push_back(*it); } else { - *error = ErrorUtils::FormatErrorMessageUTF16( - errors::kErrorInvalidId, *it); + *error = + ErrorUtils::FormatErrorMessageUTF16(errors::kErrorInvalidId, *it); return scoped_ptr<ExternallyConnectableInfo>(); } } } - if (!externally_connectable->matches && - !externally_connectable->ids) { - install_warnings->push_back(InstallWarning( - errors::kErrorNothingSpecified, - keys::kExternallyConnectable)); + if (!externally_connectable->matches && !externally_connectable->ids) { + install_warnings->push_back(InstallWarning(errors::kErrorNothingSpecified, + keys::kExternallyConnectable)); } bool accepts_tls_channel_id = externally_connectable->accepts_tls_channel_id.get() && *externally_connectable->accepts_tls_channel_id; - return make_scoped_ptr( - new ExternallyConnectableInfo(matches, ids, all_ids, - accepts_tls_channel_id)); + return make_scoped_ptr(new ExternallyConnectableInfo( + matches, ids, all_ids, accepts_tls_channel_id)); } -ExternallyConnectableInfo::~ExternallyConnectableInfo() {} +ExternallyConnectableInfo::~ExternallyConnectableInfo() { +} ExternallyConnectableInfo::ExternallyConnectableInfo( const URLPatternSet& matches, const std::vector<std::string>& ids, bool all_ids, bool accepts_tls_channel_id) - : matches(matches), ids(Sorted(ids)), all_ids(all_ids), - accepts_tls_channel_id(accepts_tls_channel_id) {} + : matches(matches), + ids(Sorted(ids)), + all_ids(all_ids), + accepts_tls_channel_id(accepts_tls_channel_id) { +} bool ExternallyConnectableInfo::IdCanConnect(const std::string& id) { if (all_ids) @@ -210,4 +214,4 @@ bool ExternallyConnectableInfo::IdCanConnect(const std::string& id) { return std::binary_search(ids.begin(), ids.end(), id); } -} // namespace extensions +} // namespace extensions diff --git a/chrome/common/extensions/manifest_handlers/externally_connectable.h b/extensions/common/manifest_handlers/externally_connectable.h index db4b97a..960904e 100644 --- a/chrome/common/extensions/manifest_handlers/externally_connectable.h +++ b/extensions/common/manifest_handlers/externally_connectable.h @@ -1,9 +1,9 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_ -#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_ +#ifndef EXTENSIONS_COMMON_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_ +#define EXTENSIONS_COMMON_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_ #include <string> #include <vector> @@ -94,4 +94,4 @@ struct ExternallyConnectableInfo : public Extension::ManifestData { } // namespace extensions -#endif // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_ +#endif // EXTENSIONS_COMMON_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_ diff --git a/chrome/common/extensions/manifest_handlers/externally_connectable_unittest.cc b/extensions/common/manifest_handlers/externally_connectable_unittest.cc index 2e5d993..41b2d32 100644 --- a/chrome/common/extensions/manifest_handlers/externally_connectable_unittest.cc +++ b/extensions/common/manifest_handlers/externally_connectable_unittest.cc @@ -1,14 +1,14 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <algorithm> #include "chrome/common/extensions/features/feature_channel.h" -#include "chrome/common/extensions/manifest_handlers/externally_connectable.h" #include "chrome/common/extensions/manifest_tests/extension_manifest_test.h" #include "extensions/common/error_utils.h" #include "extensions/common/manifest_constants.h" +#include "extensions/common/manifest_handlers/externally_connectable.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,8 +25,8 @@ class ExternallyConnectableTest : public ExtensionManifestTest { protected: ExternallyConnectableInfo* GetExternallyConnectableInfo( scoped_refptr<Extension> extension) { - return static_cast<ExternallyConnectableInfo*>(extension->GetManifestData( - manifest_keys::kExternallyConnectable)); + return static_cast<ExternallyConnectableInfo*>( + extension->GetManifestData(manifest_keys::kExternallyConnectable)); } private: @@ -44,8 +44,9 @@ TEST_F(ExternallyConnectableTest, IDsAndMatches) { ExternallyConnectableInfo::Get(extension.get()); ASSERT_TRUE(info); - EXPECT_THAT(info->ids, ElementsAre("abcdefghijklmnopabcdefghijklmnop", - "ponmlkjihgfedcbaponmlkjihgfedcba")); + EXPECT_THAT(info->ids, + ElementsAre("abcdefghijklmnopabcdefghijklmnop", + "ponmlkjihgfedcbaponmlkjihgfedcba")); EXPECT_FALSE(info->all_ids); @@ -89,8 +90,8 @@ TEST_F(ExternallyConnectableTest, IDsAndMatches) { // ignore the trailing slash. This is kind of a corner case, so let's test it. EXPECT_TRUE(info->matches.MatchesURL(GURL("http://no.wildcard.path"))); EXPECT_TRUE(info->matches.MatchesURL(GURL("http://no.wildcard.path/"))); - EXPECT_FALSE(info->matches.MatchesURL( - GURL("http://no.wildcard.path/index.html"))); + EXPECT_FALSE( + info->matches.MatchesURL(GURL("http://no.wildcard.path/index.html"))); } TEST_F(ExternallyConnectableTest, IDs) { @@ -104,8 +105,9 @@ TEST_F(ExternallyConnectableTest, IDs) { ExternallyConnectableInfo::Get(extension.get()); ASSERT_TRUE(info); - EXPECT_THAT(info->ids, ElementsAre("abcdefghijklmnopabcdefghijklmnop", - "ponmlkjihgfedcbaponmlkjihgfedcba")); + EXPECT_THAT(info->ids, + ElementsAre("abcdefghijklmnopabcdefghijklmnop", + "ponmlkjihgfedcbaponmlkjihgfedcba")); EXPECT_FALSE(info->all_ids); @@ -155,9 +157,8 @@ TEST_F(ExternallyConnectableTest, Matches) { } TEST_F(ExternallyConnectableTest, MatchesWithTlsChannelId) { - scoped_refptr<Extension> extension = - LoadAndExpectSuccess( - "externally_connectable_matches_tls_channel_id.json"); + scoped_refptr<Extension> extension = LoadAndExpectSuccess( + "externally_connectable_matches_tls_channel_id.json"); ASSERT_TRUE(extension.get()); EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kWebConnectable)); @@ -190,8 +191,9 @@ TEST_F(ExternallyConnectableTest, AllIDs) { ExternallyConnectableInfo::Get(extension.get()); ASSERT_TRUE(info); - EXPECT_THAT(info->ids, ElementsAre("abcdefghijklmnopabcdefghijklmnop", - "ponmlkjihgfedcbaponmlkjihgfedcba")); + EXPECT_THAT(info->ids, + ElementsAre("abcdefghijklmnopabcdefghijklmnop", + "ponmlkjihgfedcbaponmlkjihgfedcba")); EXPECT_TRUE(info->all_ids); @@ -200,11 +202,11 @@ TEST_F(ExternallyConnectableTest, AllIDs) { TEST_F(ExternallyConnectableTest, IdCanConnect) { // Not in order to test that ExternallyConnectableInfo sorts it. - std::string matches_ids_array[] = { "g", "h", "c", "i", "a", "z", "b" }; + std::string matches_ids_array[] = {"g", "h", "c", "i", "a", "z", "b"}; std::vector<std::string> matches_ids( matches_ids_array, matches_ids_array + arraysize(matches_ids_array)); - std::string nomatches_ids_array[] = { "2", "3", "1" }; + std::string nomatches_ids_array[] = {"2", "3", "1"}; // all_ids = false. { @@ -237,10 +239,9 @@ TEST_F(ExternallyConnectableTest, ErrorBadID) { } TEST_F(ExternallyConnectableTest, ErrorBadMatches) { - LoadAndExpectError( - "externally_connectable_error_bad_matches.json", - ErrorUtils::FormatErrorMessage(errors::kErrorInvalidMatchPattern, - "www.yahoo.com")); + LoadAndExpectError("externally_connectable_error_bad_matches.json", + ErrorUtils::FormatErrorMessage( + errors::kErrorInvalidMatchPattern, "www.yahoo.com")); } TEST_F(ExternallyConnectableTest, WarningNoAllURLs) { @@ -270,10 +271,9 @@ TEST_F(ExternallyConnectableTest, WarningWildcardHost) { TEST_F(ExternallyConnectableTest, WarningNoTLD) { scoped_refptr<Extension> extension = LoadAndExpectWarning( "externally_connectable_error_tld.json", - ErrorUtils::FormatErrorMessage( - errors::kErrorTopLevelDomainsNotAllowed, - "co.uk", - "http://*.co.uk/*")); + ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed, + "co.uk", + "http://*.co.uk/*")); ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension); EXPECT_FALSE(info->matches.ContainsPattern( URLPattern(URLPattern::SCHEME_ALL, "http://*.co.uk/*"))); @@ -284,10 +284,9 @@ TEST_F(ExternallyConnectableTest, WarningNoTLD) { TEST_F(ExternallyConnectableTest, WarningNoEffectiveTLD) { scoped_refptr<Extension> extension = LoadAndExpectWarning( "externally_connectable_error_effective_tld.json", - ErrorUtils::FormatErrorMessage( - errors::kErrorTopLevelDomainsNotAllowed, - "appspot.com", - "http://*.appspot.com/*")); + ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed, + "appspot.com", + "http://*.appspot.com/*")); ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension); EXPECT_FALSE(info->matches.ContainsPattern( URLPattern(URLPattern::SCHEME_ALL, "http://*.appspot.com/*"))); @@ -298,10 +297,9 @@ TEST_F(ExternallyConnectableTest, WarningNoEffectiveTLD) { TEST_F(ExternallyConnectableTest, WarningUnknownTLD) { scoped_refptr<Extension> extension = LoadAndExpectWarning( "externally_connectable_error_unknown_tld.json", - ErrorUtils::FormatErrorMessage( - errors::kErrorTopLevelDomainsNotAllowed, - "notatld", - "http://*.notatld/*")); + ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed, + "notatld", + "http://*.notatld/*")); ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension); EXPECT_FALSE(info->matches.ContainsPattern( URLPattern(URLPattern::SCHEME_ALL, "http://*.notatld/*"))); diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp index 1664e87..faa7790 100644 --- a/extensions/extensions.gyp +++ b/extensions/extensions.gyp @@ -124,6 +124,8 @@ 'common/manifest_handlers/background_info.h', 'common/manifest_handlers/csp_info.cc', 'common/manifest_handlers/csp_info.h', + 'common/manifest_handlers/externally_connectable.cc', + 'common/manifest_handlers/externally_connectable.h', 'common/manifest_handlers/icons_handler.cc', 'common/manifest_handlers/icons_handler.h', 'common/manifest_handlers/incognito_info.cc', @@ -417,8 +419,12 @@ 'sources': [ 'renderer/activity_log_converter_strategy.cc', 'renderer/activity_log_converter_strategy.h', + 'renderer/api_activity_logger.cc', + 'renderer/api_activity_logger.h', 'renderer/api_definitions_natives.cc', 'renderer/api_definitions_natives.h', + 'renderer/app_runtime_custom_bindings.cc', + 'renderer/app_runtime_custom_bindings.h', 'renderer/binding_generating_native_handler.cc', 'renderer/binding_generating_native_handler.h', 'renderer/blob_native_handler.cc', @@ -431,6 +437,11 @@ 'renderer/context_menus_custom_bindings.h', 'renderer/css_native_handler.cc', 'renderer/css_native_handler.h', + 'renderer/default_dispatcher_delegate.cc', + 'renderer/default_dispatcher_delegate.h', + 'renderer/dispatcher.cc', + 'renderer/dispatcher.h', + 'renderer/dispatcher_delegate.h', 'renderer/document_custom_bindings.cc', 'renderer/document_custom_bindings.h', 'renderer/dom_activity_logger.cc', @@ -446,18 +457,30 @@ 'renderer/i18n_custom_bindings.h', 'renderer/id_generator_custom_bindings.cc', 'renderer/id_generator_custom_bindings.h', + 'renderer/lazy_background_page_native_handler.cc', + 'renderer/lazy_background_page_native_handler.h', 'renderer/logging_native_handler.cc', 'renderer/logging_native_handler.h', + 'renderer/messaging_bindings.cc', + 'renderer/messaging_bindings.h', 'renderer/module_system.cc', 'renderer/module_system.h', 'renderer/native_handler.cc', 'renderer/native_handler.h', 'renderer/object_backed_native_handler.cc', 'renderer/object_backed_native_handler.h', + 'renderer/print_native_handler.cc', + 'renderer/print_native_handler.h', + 'renderer/process_info_native_handler.cc', + 'renderer/process_info_native_handler.h', 'renderer/render_view_observer_natives.cc', 'renderer/render_view_observer_natives.h', 'renderer/request_sender.cc', 'renderer/request_sender.h', + 'renderer/resource_bundle_source_map.cc', + 'renderer/resource_bundle_source_map.h', + 'renderer/runtime_custom_bindings.cc', + 'renderer/runtime_custom_bindings.h', 'renderer/safe_builtins.cc', 'renderer/safe_builtins.h', 'renderer/send_request_natives.cc', @@ -469,12 +492,24 @@ 'renderer/script_context.h', 'renderer/script_context_set.cc', 'renderer/script_context_set.h', + 'renderer/static_v8_external_ascii_string_resource.cc', + 'renderer/static_v8_external_ascii_string_resource.h', + 'renderer/test_features_native_handler.cc', + 'renderer/test_features_native_handler.h', + 'renderer/user_gestures_native_handler.cc', + 'renderer/user_gestures_native_handler.h', + 'renderer/user_script_slave.cc', + 'renderer/user_script_slave.h', 'renderer/utils_native_handler.cc', 'renderer/utils_native_handler.h', + 'renderer/v8_context_native_handler.cc', + 'renderer/v8_context_native_handler.h', 'renderer/v8_schema_registry.cc', 'renderer/v8_schema_registry.h', ], 'dependencies': [ + 'extensions_resources.gyp:extensions_resources', + '../chrome/chrome_resources.gyp:chrome_resources', '../third_party/WebKit/public/blink.gyp:blink', ], # Disable c4267 warnings until we fix size_t to int truncations. diff --git a/chrome/renderer/extensions/api_activity_logger.cc b/extensions/renderer/api_activity_logger.cc index d29bd9b..c1c5aef 100644 --- a/chrome/renderer/extensions/api_activity_logger.cc +++ b/extensions/renderer/api_activity_logger.cc @@ -1,15 +1,15 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <string> #include "base/bind.h" -#include "chrome/renderer/extensions/api_activity_logger.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/v8_value_converter.h" #include "extensions/common/extension_messages.h" #include "extensions/renderer/activity_log_converter_strategy.h" +#include "extensions/renderer/api_activity_logger.h" #include "extensions/renderer/script_context.h" using content::V8ValueConverter; @@ -60,9 +60,10 @@ void APIActivityLogger::LogInternal( converter->SetStrategy(&strategy); scoped_ptr<base::ListValue> arg_list(new base::ListValue()); for (size_t i = 0; i < arg_array->Length(); ++i) { - arg_list->Set(i, - converter->FromV8Value(arg_array->Get(i), - args.GetIsolate()->GetCurrentContext())); + arg_list->Set( + i, + converter->FromV8Value(arg_array->Get(i), + args.GetIsolate()->GetCurrentContext())); } params.arguments.Swap(arg_list.get()); } diff --git a/extensions/renderer/api_activity_logger.h b/extensions/renderer/api_activity_logger.h new file mode 100644 index 0000000..13f23f9 --- /dev/null +++ b/extensions/renderer/api_activity_logger.h @@ -0,0 +1,51 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_API_ACTIVITY_LOGGER_H_ +#define EXTENSIONS_RENDERER_API_ACTIVITY_LOGGER_H_ + +#include <string> + +#include "extensions/common/features/feature.h" +#include "extensions/renderer/object_backed_native_handler.h" +#include "v8/include/v8.h" + +namespace extensions { + +// Used to log extension API calls and events that are implemented with custom +// bindings.The actions are sent via IPC to extensions::ActivityLog for +// recording and display. +class APIActivityLogger : public ObjectBackedNativeHandler { + public: + explicit APIActivityLogger(ScriptContext* context); + + private: + // Used to distinguish API calls & events from each other in LogInternal. + enum CallType { APICALL, EVENT }; + + // This is ultimately invoked in bindings.js with JavaScript arguments. + // arg0 - extension ID as a string + // arg1 - API call name as a string + // arg2 - arguments to the API call + // arg3 - any extra logging info as a string (optional) + static void LogAPICall(const v8::FunctionCallbackInfo<v8::Value>& args); + + // This is ultimately invoked in bindings.js with JavaScript arguments. + // arg0 - extension ID as a string + // arg1 - Event name as a string + // arg2 - Event arguments + // arg3 - any extra logging info as a string (optional) + static void LogEvent(const v8::FunctionCallbackInfo<v8::Value>& args); + + // LogAPICall and LogEvent are really the same underneath except for + // how they are ultimately dispatched to the log. + static void LogInternal(const CallType call_type, + const v8::FunctionCallbackInfo<v8::Value>& args); + + DISALLOW_COPY_AND_ASSIGN(APIActivityLogger); +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_API_ACTIVITY_LOGGER_H_ diff --git a/extensions/renderer/api_definitions_natives.cc b/extensions/renderer/api_definitions_natives.cc index a7970b2..c0dc699 100644 --- a/extensions/renderer/api_definitions_natives.cc +++ b/extensions/renderer/api_definitions_natives.cc @@ -4,9 +4,9 @@ #include "extensions/renderer/api_definitions_natives.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "extensions/common/features/feature.h" #include "extensions/common/features/feature_provider.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/script_context.h" namespace extensions { diff --git a/chrome/renderer/extensions/app_runtime_custom_bindings.cc b/extensions/renderer/app_runtime_custom_bindings.cc index 3d1016aa..3a1f169 100644 --- a/chrome/renderer/extensions/app_runtime_custom_bindings.cc +++ b/extensions/renderer/app_runtime_custom_bindings.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/extensions/app_runtime_custom_bindings.h" +#include "extensions/renderer/app_runtime_custom_bindings.h" #include "base/bind.h" #include "base/strings/string_number_conversions.h" @@ -17,7 +17,7 @@ using blink::WebString; namespace { -void DeserializeString(const v8::FunctionCallbackInfo<v8::Value> &args) { +void DeserializeString(const v8::FunctionCallbackInfo<v8::Value>& args) { DCHECK(args.Length() == 1); DCHECK(args[0]->IsString()); @@ -28,18 +28,17 @@ void DeserializeString(const v8::FunctionCallbackInfo<v8::Value> &args) { args.GetReturnValue().Set(serialized.deserialize()); } -void SerializeToString(const v8::FunctionCallbackInfo<v8::Value> &args) { +void SerializeToString(const v8::FunctionCallbackInfo<v8::Value>& args) { DCHECK(args.Length() == 1); - WebSerializedScriptValue data = - WebSerializedScriptValue::serialize(args[0]); + WebSerializedScriptValue data = WebSerializedScriptValue::serialize(args[0]); WebString data_webstring = data.toString(); std::string v = std::string(data_webstring.utf8()); - args.GetReturnValue() - .Set(v8::String::NewFromUtf8(args.GetIsolate(), v.c_str())); + args.GetReturnValue().Set( + v8::String::NewFromUtf8(args.GetIsolate(), v.c_str())); } -void CreateBlob(const v8::FunctionCallbackInfo<v8::Value> &args) { +void CreateBlob(const v8::FunctionCallbackInfo<v8::Value>& args) { DCHECK(args.Length() == 2); DCHECK(args[0]->IsString()); DCHECK(args[1]->IsNumber()); @@ -48,8 +47,8 @@ void CreateBlob(const v8::FunctionCallbackInfo<v8::Value> &args) { std::string blob_length_string(*v8::String::Utf8Value(args[1])); int64 blob_length = 0; DCHECK(base::StringToInt64(blob_length_string, &blob_length)); - blink::WebBlob web_blob = WebBlob::createFromFile( - WebString::fromUTF8(blob_file_path), blob_length); + blink::WebBlob web_blob = + WebBlob::createFromFile(WebString::fromUTF8(blob_file_path), blob_length); args.GetReturnValue().Set(web_blob.toV8Value()); } diff --git a/chrome/renderer/extensions/app_runtime_custom_bindings.h b/extensions/renderer/app_runtime_custom_bindings.h index f83c0f7..f4ff906 100644 --- a/chrome/renderer/extensions/app_runtime_custom_bindings.h +++ b/extensions/renderer/app_runtime_custom_bindings.h @@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_EXTENSIONS_APP_RUNTIME_CUSTOM_BINDINGS_H_ -#define CHROME_RENDERER_EXTENSIONS_APP_RUNTIME_CUSTOM_BINDINGS_H_ +#ifndef EXTENSIONS_RENDERER_APP_RUNTIME_CUSTOM_BINDINGS_H_ +#define EXTENSIONS_RENDERER_APP_RUNTIME_CUSTOM_BINDINGS_H_ #include "extensions/renderer/object_backed_native_handler.h" @@ -20,4 +20,4 @@ class AppRuntimeCustomBindings : public ObjectBackedNativeHandler { } // namespace extensions -#endif // CHROME_RENDERER_EXTENSIONS_APP_RUNTIME_CUSTOM_BINDINGS_H_ +#endif // EXTENSIONS_RENDERER_APP_RUNTIME_CUSTOM_BINDINGS_H_ diff --git a/extensions/renderer/console.cc b/extensions/renderer/console.cc index 303de44..f7ae995 100644 --- a/extensions/renderer/console.cc +++ b/extensions/renderer/console.cc @@ -10,10 +10,10 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "chrome/renderer/extensions/extension_helper.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view_visitor.h" +#include "extensions/renderer/dispatcher.h" #include "third_party/WebKit/public/web/WebConsoleMessage.h" #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebView.h" diff --git a/extensions/renderer/default_dispatcher_delegate.cc b/extensions/renderer/default_dispatcher_delegate.cc new file mode 100644 index 0000000..326ee70 --- /dev/null +++ b/extensions/renderer/default_dispatcher_delegate.cc @@ -0,0 +1,27 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/renderer/default_dispatcher_delegate.h" + +#include "extensions/renderer/script_context.h" + +namespace extensions { + +DefaultDispatcherDelegate::DefaultDispatcherDelegate() { +} + +DefaultDispatcherDelegate::~DefaultDispatcherDelegate() { +} + +// DispatcherDelegate implementation. +scoped_ptr<ScriptContext> DefaultDispatcherDelegate::CreateScriptContext( + const v8::Handle<v8::Context>& v8_context, + blink::WebFrame* frame, + const Extension* extension, + Feature::Context context_type) { + return make_scoped_ptr( + new ScriptContext(v8_context, frame, extension, context_type)); +} + +} // namespace extensions diff --git a/extensions/renderer/default_dispatcher_delegate.h b/extensions/renderer/default_dispatcher_delegate.h new file mode 100644 index 0000000..1ee92ab --- /dev/null +++ b/extensions/renderer/default_dispatcher_delegate.h @@ -0,0 +1,27 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_DEFAULT_DISPATCHER_DELEGATE_H +#define EXTENSIONS_RENDERER_DEFAULT_DISPATCHER_DELEGATE_H + +#include "extensions/renderer/dispatcher_delegate.h" + +namespace extensions { + +class DefaultDispatcherDelegate : public DispatcherDelegate { + public: + DefaultDispatcherDelegate(); + virtual ~DefaultDispatcherDelegate(); + + // DispatcherDelegate implementation. + virtual scoped_ptr<ScriptContext> CreateScriptContext( + const v8::Handle<v8::Context>& v8_context, + blink::WebFrame* frame, + const Extension* extension, + Feature::Context context_type) OVERRIDE; +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_DEFAULT_DISPATCHER_DELEGATE_H diff --git a/chrome/renderer/extensions/dispatcher.cc b/extensions/renderer/dispatcher.cc index 28254f6..93fa434 100644 --- a/chrome/renderer/extensions/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc @@ -1,46 +1,21 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/extensions/dispatcher.h" +#include "extensions/renderer/dispatcher.h" #include "base/callback.h" #include "base/command_line.h" #include "base/debug/alias.h" #include "base/memory/scoped_ptr.h" #include "base/metrics/user_metrics_action.h" -#include "base/sha1.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/values.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/chrome_version_info.h" -#include "chrome/common/crash_keys.h" -#include "chrome/common/extensions/features/feature_channel.h" -#include "chrome/common/extensions/manifest_handlers/externally_connectable.h" -#include "chrome/common/url_constants.h" -#include "chrome/renderer/chrome_render_process_observer.h" -#include "chrome/renderer/extensions/api_activity_logger.h" -#include "chrome/renderer/extensions/app_bindings.h" -#include "chrome/renderer/extensions/app_runtime_custom_bindings.h" -#include "chrome/renderer/extensions/app_window_custom_bindings.h" -#include "chrome/renderer/extensions/chrome_v8_context.h" #include "chrome/renderer/extensions/extension_helper.h" -#include "chrome/renderer/extensions/file_browser_handler_custom_bindings.h" -#include "chrome/renderer/extensions/file_browser_private_custom_bindings.h" -#include "chrome/renderer/extensions/media_galleries_custom_bindings.h" -#include "chrome/renderer/extensions/messaging_bindings.h" -#include "chrome/renderer/extensions/page_actions_custom_bindings.h" -#include "chrome/renderer/extensions/page_capture_custom_bindings.h" -#include "chrome/renderer/extensions/pepper_request_natives.h" -#include "chrome/renderer/extensions/runtime_custom_bindings.h" -#include "chrome/renderer/extensions/sync_file_system_custom_bindings.h" -#include "chrome/renderer/extensions/tab_finder.h" -#include "chrome/renderer/extensions/tabs_custom_bindings.h" -#include "chrome/renderer/extensions/user_script_slave.h" -#include "chrome/renderer/extensions/webstore_bindings.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/url_constants.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/v8_value_converter.h" @@ -52,22 +27,25 @@ #include "extensions/common/extension_urls.h" #include "extensions/common/features/feature.h" #include "extensions/common/features/feature_provider.h" -#include "extensions/common/features/json_feature_provider_source.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/background_info.h" +#include "extensions/common/manifest_handlers/externally_connectable.h" #include "extensions/common/manifest_handlers/sandboxed_page_info.h" #include "extensions/common/message_bundle.h" #include "extensions/common/permissions/permission_set.h" #include "extensions/common/permissions/permissions_data.h" #include "extensions/common/switches.h" #include "extensions/common/view_type.h" +#include "extensions/renderer/api_activity_logger.h" #include "extensions/renderer/api_definitions_natives.h" +#include "extensions/renderer/app_runtime_custom_bindings.h" #include "extensions/renderer/binding_generating_native_handler.h" #include "extensions/renderer/blob_native_handler.h" #include "extensions/renderer/content_watcher.h" #include "extensions/renderer/context_menus_custom_bindings.h" #include "extensions/renderer/css_native_handler.h" +#include "extensions/renderer/dispatcher_delegate.h" #include "extensions/renderer/document_custom_bindings.h" #include "extensions/renderer/dom_activity_logger.h" #include "extensions/renderer/event_bindings.h" @@ -76,19 +54,26 @@ #include "extensions/renderer/file_system_natives.h" #include "extensions/renderer/i18n_custom_bindings.h" #include "extensions/renderer/id_generator_custom_bindings.h" +#include "extensions/renderer/lazy_background_page_native_handler.h" #include "extensions/renderer/logging_native_handler.h" +#include "extensions/renderer/messaging_bindings.h" #include "extensions/renderer/module_system.h" -#include "extensions/renderer/object_backed_native_handler.h" +#include "extensions/renderer/print_native_handler.h" +#include "extensions/renderer/process_info_native_handler.h" #include "extensions/renderer/render_view_observer_natives.h" #include "extensions/renderer/request_sender.h" +#include "extensions/renderer/runtime_custom_bindings.h" #include "extensions/renderer/safe_builtins.h" #include "extensions/renderer/script_context.h" #include "extensions/renderer/script_context_set.h" #include "extensions/renderer/send_request_natives.h" #include "extensions/renderer/set_icon_natives.h" +#include "extensions/renderer/test_features_native_handler.h" +#include "extensions/renderer/user_gestures_native_handler.h" +#include "extensions/renderer/user_script_slave.h" #include "extensions/renderer/utils_native_handler.h" +#include "extensions/renderer/v8_context_native_handler.h" #include "grit/common_resources.h" -#include "grit/extensions_resources.h" #include "grit/renderer_resources.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" @@ -99,16 +84,11 @@ #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" #include "third_party/WebKit/public/web/WebScopedUserGesture.h" #include "third_party/WebKit/public/web/WebSecurityPolicy.h" -#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/base/layout.h" #include "ui/base/resource/resource_bundle.h" #include "v8/include/v8.h" -#if defined(ENABLE_WEBRTC) -#include "chrome/renderer/extensions/cast_streaming_native_handler.h" -#endif - using base::UserMetricsAction; using blink::WebDataSource; using blink::WebDocument; @@ -125,8 +105,8 @@ namespace extensions { namespace { -static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000; -static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000; +static const int64 kInitialExtensionIdleHandlerDelayMs = 5 * 1000; +static const int64 kMaxExtensionIdleHandlerDelayMs = 5 * 60 * 1000; static const char kEventDispatchFunction[] = "dispatchEvent"; static const char kOnSuspendEvent[] = "runtime.onSuspend"; static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled"; @@ -153,121 +133,36 @@ v8::Handle<v8::Object> AsObjectOrEmpty(v8::Handle<v8::Value> value) { return value->IsObject() ? value.As<v8::Object>() : v8::Handle<v8::Object>(); } -class TestFeaturesNativeHandler : public ObjectBackedNativeHandler { - public: - explicit TestFeaturesNativeHandler(ScriptContext* context) - : ObjectBackedNativeHandler(context) { - RouteFunction("GetAPIFeatures", - base::Bind(&TestFeaturesNativeHandler::GetAPIFeatures, - base::Unretained(this))); - } - - private: - void GetAPIFeatures(const v8::FunctionCallbackInfo<v8::Value>& args) { - JSONFeatureProviderSource source("api"); - source.LoadJSON(IDR_CHROME_EXTENSION_API_FEATURES); - source.LoadJSON(IDR_EXTENSION_API_FEATURES); - scoped_ptr<content::V8ValueConverter> converter( - content::V8ValueConverter::create()); - args.GetReturnValue().Set( - converter->ToV8Value(&source.dictionary(), context()->v8_context())); - } -}; - -class UserGesturesNativeHandler : public ObjectBackedNativeHandler { - public: - explicit UserGesturesNativeHandler(ScriptContext* context) - : ObjectBackedNativeHandler(context) { - RouteFunction("IsProcessingUserGesture", - base::Bind(&UserGesturesNativeHandler::IsProcessingUserGesture, - base::Unretained(this))); - RouteFunction("RunWithUserGesture", - base::Bind(&UserGesturesNativeHandler::RunWithUserGesture, - base::Unretained(this))); - RouteFunction("RunWithoutUserGesture", - base::Bind(&UserGesturesNativeHandler::RunWithoutUserGesture, - base::Unretained(this))); - } - - private: - void IsProcessingUserGesture( - const v8::FunctionCallbackInfo<v8::Value>& args) { - args.GetReturnValue().Set(v8::Boolean::New( - args.GetIsolate(), - blink::WebUserGestureIndicator::isProcessingUserGesture())); - } - - void RunWithUserGesture( - const v8::FunctionCallbackInfo<v8::Value>& args) { - blink::WebScopedUserGesture user_gesture; - CHECK_EQ(args.Length(), 1); - CHECK(args[0]->IsFunction()); - v8::Handle<v8::Value> no_args; - context()->CallFunction(v8::Handle<v8::Function>::Cast(args[0]), - 0, &no_args); - } - - void RunWithoutUserGesture( - const v8::FunctionCallbackInfo<v8::Value>& args) { - blink::WebUserGestureIndicator::consumeUserGesture(); - CHECK_EQ(args.Length(), 1); - CHECK(args[0]->IsFunction()); - v8::Handle<v8::Value> no_args; - context()->CallFunction(v8::Handle<v8::Function>::Cast(args[0]), - 0, &no_args); - } -}; - -class V8ContextNativeHandler : public ObjectBackedNativeHandler { - public: - V8ContextNativeHandler(ScriptContext* context, Dispatcher* dispatcher) - : ObjectBackedNativeHandler(context), - context_(context), - dispatcher_(dispatcher) { - RouteFunction("GetAvailability", - base::Bind(&V8ContextNativeHandler::GetAvailability, - base::Unretained(this))); - RouteFunction("GetModuleSystem", - base::Bind(&V8ContextNativeHandler::GetModuleSystem, - base::Unretained(this))); - } +// Calls a method |method_name| in a module |module_name| belonging to the +// module system from |context|. Intended as a callback target from +// ScriptContextSet::ForEach. +void CallModuleMethod(const std::string& module_name, + const std::string& method_name, + const base::ListValue* args, + ScriptContext* context) { + v8::HandleScope handle_scope(context->isolate()); + v8::Context::Scope context_scope(context->v8_context()); - private: - void GetAvailability(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK_EQ(args.Length(), 1); - v8::Isolate* isolate = args.GetIsolate(); - std::string api_name = *v8::String::Utf8Value(args[0]->ToString()); - Feature::Availability availability = context_->GetAvailability(api_name); - - v8::Handle<v8::Object> ret = v8::Object::New(isolate); - ret->Set(v8::String::NewFromUtf8(isolate, "is_available"), - v8::Boolean::New(isolate, availability.is_available())); - ret->Set(v8::String::NewFromUtf8(isolate, "message"), - v8::String::NewFromUtf8(isolate, availability.message().c_str())); - ret->Set(v8::String::NewFromUtf8(isolate, "result"), - v8::Integer::New(isolate, availability.result())); - args.GetReturnValue().Set(ret); - } + scoped_ptr<content::V8ValueConverter> converter( + content::V8ValueConverter::create()); - void GetModuleSystem(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK_EQ(args.Length(), 1); - CHECK(args[0]->IsObject()); - v8::Handle<v8::Context> v8_context = - v8::Handle<v8::Object>::Cast(args[0])->CreationContext(); - ScriptContext* context = - dispatcher_->script_context_set().GetByV8Context(v8_context); - args.GetReturnValue().Set(context->module_system()->NewInstance()); + std::vector<v8::Handle<v8::Value> > arguments; + for (base::ListValue::const_iterator it = args->begin(); it != args->end(); + ++it) { + arguments.push_back(converter->ToV8Value(*it, context->v8_context())); } - ScriptContext* context_; - Dispatcher* dispatcher_; -}; + context->module_system()->CallModuleMethod( + module_name, method_name, &arguments); +} +// This handles the "chrome." root API object in script contexts. class ChromeNativeHandler : public ObjectBackedNativeHandler { public: explicit ChromeNativeHandler(ScriptContext* context) : ObjectBackedNativeHandler(context) { - RouteFunction("GetChrome", + RouteFunction( + "GetChrome", base::Bind(&ChromeNativeHandler::GetChrome, base::Unretained(this))); } @@ -276,243 +171,307 @@ class ChromeNativeHandler : public ObjectBackedNativeHandler { } }; -class PrintNativeHandler : public ObjectBackedNativeHandler { - public: - explicit PrintNativeHandler(ScriptContext* context) - : ObjectBackedNativeHandler(context) { - RouteFunction("Print", - base::Bind(&PrintNativeHandler::Print, - base::Unretained(this))); +} // namespace + +Dispatcher::Dispatcher(DispatcherDelegate* delegate) + : delegate_(delegate), + content_watcher_(new ContentWatcher()), + source_map_(&ResourceBundle::GetSharedInstance()), + v8_schema_registry_(new V8SchemaRegistry), + is_webkit_initialized_(false) { + const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); + is_extension_process_ = + command_line.HasSwitch(extensions::switches::kExtensionProcess) || + command_line.HasSwitch(::switches::kSingleProcess); + + if (is_extension_process_) { + RenderThread::Get()->SetIdleNotificationDelayInMs( + kInitialExtensionIdleHandlerDelayMs); } - void Print(const v8::FunctionCallbackInfo<v8::Value>& args) { - if (args.Length() < 1) - return; + RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); - std::vector<std::string> components; - for (int i = 0; i < args.Length(); ++i) - components.push_back(*v8::String::Utf8Value(args[i]->ToString())); + user_script_slave_.reset(new UserScriptSlave(&extensions_)); + request_sender_.reset(new RequestSender(this)); + PopulateSourceMap(); +} - LOG(ERROR) << JoinString(components, ','); - } -}; +Dispatcher::~Dispatcher() { +} -class LazyBackgroundPageNativeHandler : public ObjectBackedNativeHandler { - public: - explicit LazyBackgroundPageNativeHandler(ScriptContext* context) - : ObjectBackedNativeHandler(context) { - RouteFunction("IncrementKeepaliveCount", - base::Bind(&LazyBackgroundPageNativeHandler::IncrementKeepaliveCount, - base::Unretained(this))); - RouteFunction("DecrementKeepaliveCount", - base::Bind(&LazyBackgroundPageNativeHandler::DecrementKeepaliveCount, - base::Unretained(this))); - } +bool Dispatcher::IsExtensionActive(const std::string& extension_id) const { + bool is_active = + active_extension_ids_.find(extension_id) != active_extension_ids_.end(); + if (is_active) + CHECK(extensions_.Contains(extension_id)); + return is_active; +} - void IncrementKeepaliveCount( - const v8::FunctionCallbackInfo<v8::Value>& args) { - if (!context()) - return; - RenderView* render_view = context()->GetRenderView(); - if (IsContextLazyBackgroundPage(render_view, context()->extension())) { - render_view->Send(new ExtensionHostMsg_IncrementLazyKeepaliveCount( - render_view->GetRoutingID())); - } +std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) { + if (world_id != 0) { + // Isolated worlds (content script). + return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id); } - void DecrementKeepaliveCount( - const v8::FunctionCallbackInfo<v8::Value>& args) { - if (!context()) - return; - RenderView* render_view = context()->GetRenderView(); - if (IsContextLazyBackgroundPage(render_view, context()->extension())) { - render_view->Send(new ExtensionHostMsg_DecrementLazyKeepaliveCount( - render_view->GetRoutingID())); + // TODO(kalman): Delete this check. + if (frame->document().securityOrigin().isUnique()) + return std::string(); + + // Extension pages (chrome-extension:// URLs). + GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame); + return extensions_.GetExtensionOrAppIDByURL(frame_url); +} + +void Dispatcher::DidCreateScriptContext( + WebFrame* frame, + const v8::Handle<v8::Context>& v8_context, + int extension_group, + int world_id) { +#if !defined(ENABLE_EXTENSIONS) + return; +#endif + + std::string extension_id = GetExtensionID(frame, world_id); + + const Extension* extension = extensions_.GetByID(extension_id); + if (!extension && !extension_id.empty()) { + // There are conditions where despite a context being associated with an + // extension, no extension actually gets found. Ignore "invalid" because + // CSP blocks extension page loading by switching the extension ID to + // "invalid". This isn't interesting. + if (extension_id != "invalid") { + LOG(ERROR) << "Extension \"" << extension_id << "\" not found"; + RenderThread::Get()->RecordAction( + UserMetricsAction("ExtensionNotFound_ED")); } + + extension_id = ""; } - private: - bool IsContextLazyBackgroundPage(RenderView* render_view, - const Extension* extension) { - if (!render_view) - return false; + Feature::Context context_type = + ClassifyJavaScriptContext(extension, + extension_group, + ScriptContext::GetDataSourceURLForFrame(frame), + frame->document().securityOrigin()); - ExtensionHelper* helper = ExtensionHelper::Get(render_view); - return (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && - helper->view_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); - } -}; + ScriptContext* context = + delegate_->CreateScriptContext(v8_context, frame, extension, context_type) + .release(); + script_context_set_.Add(context); -class ProcessInfoNativeHandler : public ObjectBackedNativeHandler { - public: - ProcessInfoNativeHandler(ScriptContext* context, - const std::string& extension_id, - const std::string& context_type, - bool is_incognito_context, - int manifest_version, - bool send_request_disabled) - : ObjectBackedNativeHandler(context), - extension_id_(extension_id), - context_type_(context_type), - is_incognito_context_(is_incognito_context), - manifest_version_(manifest_version), - send_request_disabled_(send_request_disabled) { - RouteFunction("GetExtensionId", - base::Bind(&ProcessInfoNativeHandler::GetExtensionId, - base::Unretained(this))); - RouteFunction("GetContextType", - base::Bind(&ProcessInfoNativeHandler::GetContextType, - base::Unretained(this))); - RouteFunction("InIncognitoContext", - base::Bind(&ProcessInfoNativeHandler::InIncognitoContext, - base::Unretained(this))); - RouteFunction("GetManifestVersion", - base::Bind(&ProcessInfoNativeHandler::GetManifestVersion, - base::Unretained(this))); - RouteFunction("IsSendRequestDisabled", - base::Bind(&ProcessInfoNativeHandler::IsSendRequestDisabled, - base::Unretained(this))); - RouteFunction("HasSwitch", - base::Bind(&ProcessInfoNativeHandler::HasSwitch, - base::Unretained(this))); + if (extension) { + InitOriginPermissions(extension, context_type); } - private: - void GetExtensionId(const v8::FunctionCallbackInfo<v8::Value>& args) { - args.GetReturnValue() - .Set(v8::String::NewFromUtf8(args.GetIsolate(), extension_id_.c_str())); + { + scoped_ptr<ModuleSystem> module_system( + new ModuleSystem(context, &source_map_)); + context->set_module_system(module_system.Pass()); } + ModuleSystem* module_system = context->module_system(); - void GetContextType(const v8::FunctionCallbackInfo<v8::Value>& args) { - args.GetReturnValue() - .Set(v8::String::NewFromUtf8(args.GetIsolate(), context_type_.c_str())); - } + // Enable natives in startup. + ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); - void InIncognitoContext(const v8::FunctionCallbackInfo<v8::Value>& args) { - args.GetReturnValue().Set(is_incognito_context_); - } + RegisterNativeHandlers(module_system, context); - void GetManifestVersion(const v8::FunctionCallbackInfo<v8::Value>& args) { - args.GetReturnValue().Set(static_cast<int32_t>(manifest_version_)); + // chrome.Event is part of the public API (although undocumented). Make it + // lazily evalulate to Event from event_bindings.js. For extensions only + // though, not all webpages! + if (context->extension()) { + v8::Handle<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context)); + if (!chrome.IsEmpty()) + module_system->SetLazyField(chrome, "Event", kEventBindings, "Event"); } - void IsSendRequestDisabled(const v8::FunctionCallbackInfo<v8::Value>& args) { - if (send_request_disabled_) { - args.GetReturnValue().Set(v8::String::NewFromUtf8(args.GetIsolate(), - "sendRequest and onRequest are obsolete." - " Please use sendMessage and onMessage instead.")); - } + UpdateBindingsForContext(context); + + bool is_within_platform_app = IsWithinPlatformApp(); + // Inject custom JS into the platform app context. + if (is_within_platform_app) { + module_system->Require("platformApp"); } - void HasSwitch(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(args.Length() == 1 && args[0]->IsString()); - bool has_switch = CommandLine::ForCurrentProcess()->HasSwitch( - *v8::String::Utf8Value(args[0])); - args.GetReturnValue().Set(v8::Boolean::New(args.GetIsolate(), has_switch)); + delegate_->RequireAdditionalModules( + module_system, extension, context_type, is_within_platform_app); + + VLOG(1) << "Num tracked contexts: " << script_context_set_.size(); +} + +void Dispatcher::WillReleaseScriptContext( + WebFrame* frame, + const v8::Handle<v8::Context>& v8_context, + int world_id) { + ScriptContext* context = script_context_set_.GetByV8Context(v8_context); + if (!context) + return; + + context->DispatchOnUnloadEvent(); + // TODO(kalman): add an invalidation observer interface to ScriptContext. + request_sender_->InvalidateSource(context); + + script_context_set_.Remove(context); + VLOG(1) << "Num tracked contexts: " << script_context_set_.size(); +} + +void Dispatcher::DidCreateDocumentElement(blink::WebFrame* frame) { + if (IsWithinPlatformApp()) { + // WebKit doesn't let us define an additional user agent stylesheet, so we + // insert the default platform app stylesheet into all documents that are + // loaded in each app. + std::string stylesheet = ResourceBundle::GetSharedInstance() + .GetRawDataResource(IDR_PLATFORM_APP_CSS) + .as_string(); + ReplaceFirstSubstringAfterOffset( + &stylesheet, 0, "$FONTFAMILY", system_font_family_); + ReplaceFirstSubstringAfterOffset( + &stylesheet, 0, "$FONTSIZE", system_font_size_); + frame->document().insertStyleSheet(WebString::fromUTF8(stylesheet)); } - std::string extension_id_; - std::string context_type_; - bool is_incognito_context_; - int manifest_version_; - bool send_request_disabled_; -}; + content_watcher_->DidCreateDocumentElement(frame); +} -void InstallAppBindings(ModuleSystem* module_system, - v8::Handle<v8::Object> chrome) { - module_system->SetLazyField(chrome, "app", "app", "chromeApp"); +void Dispatcher::DidMatchCSS( + blink::WebFrame* frame, + const blink::WebVector<blink::WebString>& newly_matching_selectors, + const blink::WebVector<blink::WebString>& stopped_matching_selectors) { + content_watcher_->DidMatchCSS( + frame, newly_matching_selectors, stopped_matching_selectors); } -void InstallWebstoreBindings(ModuleSystem* module_system, - v8::Handle<v8::Object> chrome) { - module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore"); +void Dispatcher::OnExtensionResponse(int request_id, + bool success, + const base::ListValue& response, + const std::string& error) { + request_sender_->HandleResponse(request_id, success, response, error); } -// Calls a method |method_name| in a module |module_name| belonging to the -// module system from |context|. Intended as a callback target from -// ScriptContextSet::ForEach. -void CallModuleMethod(const std::string& module_name, - const std::string& method_name, - const base::ListValue* args, - ScriptContext* context) { - v8::HandleScope handle_scope(context->isolate()); - v8::Context::Scope context_scope(context->v8_context()); +bool Dispatcher::CheckContextAccessToExtensionAPI( + const std::string& function_name, + ScriptContext* context) const { + if (!context) { + DLOG(ERROR) << "Not in a v8::Context"; + return false; + } - scoped_ptr<content::V8ValueConverter> converter( - content::V8ValueConverter::create()); + if (!context->extension()) { + context->isolate()->ThrowException(v8::Exception::Error( + v8::String::NewFromUtf8(context->isolate(), "Not in an extension."))); + return false; + } - std::vector<v8::Handle<v8::Value> > arguments; - for (base::ListValue::const_iterator it = args->begin(); it != args->end(); - ++it) { - arguments.push_back(converter->ToV8Value(*it, context->v8_context())); + // Theoretically we could end up with bindings being injected into sandboxed + // frames, for example content scripts. Don't let them execute API functions. + blink::WebFrame* frame = context->web_frame(); + if (IsSandboxedPage(ScriptContext::GetDataSourceURLForFrame(frame))) { + static const char kMessage[] = + "%s cannot be used within a sandboxed frame."; + std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); + context->isolate()->ThrowException(v8::Exception::Error( + v8::String::NewFromUtf8(context->isolate(), error_msg.c_str()))); + return false; } - context->module_system()->CallModuleMethod( - module_name, method_name, &arguments); + Feature::Availability availability = context->GetAvailability(function_name); + if (!availability.is_available()) { + context->isolate()->ThrowException( + v8::Exception::Error(v8::String::NewFromUtf8( + context->isolate(), availability.message().c_str()))); + } + + return availability.is_available(); } -} // namespace +void Dispatcher::DispatchEvent(const std::string& extension_id, + const std::string& event_name) const { + base::ListValue args; + args.Set(0, new base::StringValue(event_name)); + args.Set(1, new base::ListValue()); -Dispatcher::Dispatcher() - : content_watcher_(new ContentWatcher()), - is_webkit_initialized_(false), - webrequest_adblock_(false), - webrequest_adblock_plus_(false), - webrequest_other_(false), - source_map_(&ResourceBundle::GetSharedInstance()), - v8_schema_registry_(new V8SchemaRegistry) { - const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); - is_extension_process_ = - command_line.HasSwitch(extensions::switches::kExtensionProcess) || - command_line.HasSwitch(::switches::kSingleProcess); + // Needed for Windows compilation, since kEventBindings is declared extern. + const char* local_event_bindings = kEventBindings; + script_context_set_.ForEach(extension_id, + NULL, // all render views + base::Bind(&CallModuleMethod, + local_event_bindings, + kEventDispatchFunction, + &args)); +} + +void Dispatcher::InvokeModuleSystemMethod(content::RenderView* render_view, + const std::string& extension_id, + const std::string& module_name, + const std::string& function_name, + const base::ListValue& args, + bool user_gesture) { + scoped_ptr<WebScopedUserGesture> web_user_gesture; + if (user_gesture) + web_user_gesture.reset(new WebScopedUserGesture); + + script_context_set_.ForEach( + extension_id, + render_view, + base::Bind(&CallModuleMethod, module_name, function_name, &args)); + // Reset the idle handler each time there's any activity like event or message + // dispatch, for which Invoke is the chokepoint. if (is_extension_process_) { - RenderThread::Get()->SetIdleNotificationDelayInMs( + RenderThread::Get()->ScheduleIdleHandler( kInitialExtensionIdleHandlerDelayMs); } - RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); - - user_script_slave_.reset(new UserScriptSlave(&extensions_)); - request_sender_.reset(new RequestSender(this)); - PopulateSourceMap(); - // Register JS sources from the extensions module embedder. - ExtensionsRendererClient::Get()->PopulateSourceMap(&source_map_); - PopulateLazyBindingsMap(); + // Tell the browser process when an event has been dispatched with a lazy + // background page active. + const Extension* extension = extensions_.GetByID(extension_id); + if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && + module_name == kEventBindings && + function_name == kEventDispatchFunction) { + RenderView* background_view = + ExtensionHelper::GetBackgroundPage(extension_id); + if (background_view) { + background_view->Send( + new ExtensionHostMsg_EventAck(background_view->GetRoutingID())); + } + } } -Dispatcher::~Dispatcher() { +void Dispatcher::ClearPortData(int port_id) { + // Only the target port side has entries in |port_to_tab_id_map_|. If + // |port_id| is a source port, std::map::erase() will just silently fail + // here as a no-op. + port_to_tab_id_map_.erase(port_id); } bool Dispatcher::OnControlMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(Dispatcher, message) - IPC_MESSAGE_HANDLER(ExtensionMsg_SetChannel, OnSetChannel) - IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) - IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, OnDispatchOnConnect) - IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage) - IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect, - OnDispatchOnDisconnect) - IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames, OnSetFunctionNames) - IPC_MESSAGE_HANDLER(ExtensionMsg_SetSystemFont, OnSetSystemFont) - IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) - IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded) - IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist, - OnSetScriptingWhitelist) - IPC_MESSAGE_HANDLER(ExtensionMsg_ActivateExtension, OnActivateExtension) - IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePermissions, OnUpdatePermissions) - IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateTabSpecificPermissions, - OnUpdateTabSpecificPermissions) - IPC_MESSAGE_HANDLER(ExtensionMsg_ClearTabSpecificPermissions, - OnClearTabSpecificPermissions) - IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts) - IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI) - IPC_MESSAGE_HANDLER(ExtensionMsg_ShouldSuspend, OnShouldSuspend) - IPC_MESSAGE_HANDLER(ExtensionMsg_Suspend, OnSuspend) - IPC_MESSAGE_HANDLER(ExtensionMsg_CancelSuspend, OnCancelSuspend) - IPC_MESSAGE_FORWARD(ExtensionMsg_WatchPages, - content_watcher_.get(), ContentWatcher::OnWatchPages) - IPC_MESSAGE_UNHANDLED(handled = false) + IPC_MESSAGE_HANDLER(ExtensionMsg_ActivateExtension, OnActivateExtension) + IPC_MESSAGE_HANDLER(ExtensionMsg_CancelSuspend, OnCancelSuspend) + IPC_MESSAGE_HANDLER(ExtensionMsg_ClearTabSpecificPermissions, + OnClearTabSpecificPermissions) + IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage) + IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, OnDispatchOnConnect) + IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect, OnDispatchOnDisconnect) + IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) + IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) + IPC_MESSAGE_HANDLER(ExtensionMsg_SetChannel, OnSetChannel) + IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames, OnSetFunctionNames) + IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist, + OnSetScriptingWhitelist) + IPC_MESSAGE_HANDLER(ExtensionMsg_SetSystemFont, OnSetSystemFont) + IPC_MESSAGE_HANDLER(ExtensionMsg_ShouldSuspend, OnShouldSuspend) + IPC_MESSAGE_HANDLER(ExtensionMsg_Suspend, OnSuspend) + IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded) + IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePermissions, OnUpdatePermissions) + IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateTabSpecificPermissions, + OnUpdateTabSpecificPermissions) + IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts) + IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI) + IPC_MESSAGE_FORWARD(ExtensionMsg_WatchPages, + content_watcher_.get(), + ContentWatcher::OnWatchPages) + IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -523,15 +482,18 @@ void Dispatcher::WebKitInitialized() { // even if the extension keeps up activity. if (is_extension_process_) { forced_idle_timer_.reset(new base::RepeatingTimer<content::RenderThread>); - forced_idle_timer_->Start(FROM_HERE, + forced_idle_timer_->Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs), - RenderThread::Get(), &RenderThread::IdleHandler); + RenderThread::Get(), + &RenderThread::IdleHandler); } // Initialize host permissions for any extensions that were activated before // WebKit was initialized. for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); - iter != active_extension_ids_.end(); ++iter) { + iter != active_extension_ids_.end(); + ++iter) { const Extension* extension = extensions_.GetByID(*iter); CHECK(extension); } @@ -545,13 +507,15 @@ void Dispatcher::IdleNotification() { if (is_extension_process_) { // Dampen the forced delay as well if the extension stays idle for long // periods of time. - int64 forced_delay_ms = std::max( - RenderThread::Get()->GetIdleNotificationDelayInMs(), - kMaxExtensionIdleHandlerDelayMs); + int64 forced_delay_ms = + std::max(RenderThread::Get()->GetIdleNotificationDelayInMs(), + kMaxExtensionIdleHandlerDelayMs); forced_idle_timer_->Stop(); - forced_idle_timer_->Start(FROM_HERE, + forced_idle_timer_->Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(forced_delay_ms), - RenderThread::Get(), &RenderThread::IdleHandler); + RenderThread::Get(), + &RenderThread::IdleHandler); } } @@ -560,30 +524,62 @@ void Dispatcher::OnRenderProcessShutdown() { forced_idle_timer_.reset(); } -void Dispatcher::OnSetFunctionNames( - const std::vector<std::string>& names) { - function_names_.clear(); - for (size_t i = 0; i < names.size(); ++i) - function_names_.insert(names[i]); +void Dispatcher::OnActivateExtension(const std::string& extension_id) { + const Extension* extension = extensions_.GetByID(extension_id); + if (!extension) { + // Extension was activated but was never loaded. This probably means that + // the renderer failed to load it (or the browser failed to tell us when it + // did). Failures shouldn't happen, but instead of crashing there (which + // executes on all renderers) be conservative and only crash in the renderer + // of the extension which failed to load; this one. + std::string& error = extension_load_errors_[extension_id]; + char minidump[256]; + base::debug::Alias(&minidump); + base::snprintf(minidump, + arraysize(minidump), + "e::dispatcher:%s:%s", + extension_id.c_str(), + error.c_str()); + CHECK(extension) << extension_id << " was never loaded: " << error; + } + + active_extension_ids_.insert(extension_id); + + // This is called when starting a new extension page, so start the idle + // handler ticking. + RenderThread::Get()->ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayMs); + + if (is_webkit_initialized_) { + extensions::DOMActivityLogger::AttachToWorld( + extensions::DOMActivityLogger::kMainWorldId, extension_id); + } + + UpdateActiveExtensions(); } -void Dispatcher::OnSetSystemFont(const std::string& font_family, - const std::string& font_size) { - system_font_family_ = font_family; - system_font_size_ = font_size; +void Dispatcher::OnCancelSuspend(const std::string& extension_id) { + DispatchEvent(extension_id, kOnSuspendCanceledEvent); } -void Dispatcher::OnSetChannel(int channel) { - SetCurrentChannel(static_cast<chrome::VersionInfo::Channel>(channel)); +void Dispatcher::OnClearTabSpecificPermissions( + int tab_id, + const std::vector<std::string>& extension_ids) { + delegate_->ClearTabSpecificPermissions(this, tab_id, extension_ids); } -void Dispatcher::OnMessageInvoke(const std::string& extension_id, - const std::string& module_name, - const std::string& function_name, - const base::ListValue& args, - bool user_gesture) { - InvokeModuleSystemMethod( - NULL, extension_id, module_name, function_name, args, user_gesture); +void Dispatcher::OnDeliverMessage(int target_port_id, const Message& message) { + scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id; + std::map<int, int>::const_iterator it = + port_to_tab_id_map_.find(target_port_id); + if (it != port_to_tab_id_map_.end()) { + scoped_tab_id.reset( + new RequestSender::ScopedTabID(request_sender(), it->second)); + } + + MessagingBindings::DeliverMessage(script_context_set_.GetAll(), + target_port_id, + message, + NULL); // All render views. } void Dispatcher::OnDispatchOnConnect( @@ -609,22 +605,6 @@ void Dispatcher::OnDispatchOnConnect( NULL); // All render views. } -void Dispatcher::OnDeliverMessage(int target_port_id, - const Message& message) { - scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id; - std::map<int, int>::const_iterator it = - port_to_tab_id_map_.find(target_port_id); - if (it != port_to_tab_id_map_.end()) { - scoped_tab_id.reset(new RequestSender::ScopedTabID(request_sender(), - it->second)); - } - - MessagingBindings::DeliverMessage(script_context_set_.GetAll(), - target_port_id, - message, - NULL); // All render views. -} - void Dispatcher::OnDispatchOnDisconnect(int port_id, const std::string& error_message) { MessagingBindings::DispatchOnDisconnect(script_context_set_.GetAll(), @@ -648,13 +628,59 @@ void Dispatcher::OnLoaded( // Update the available bindings for all contexts. These may have changed if // an externally_connectable extension was loaded that can connect to an // open webpage. - AddOrRemoveBindings(""); + UpdateBindings(""); } void Dispatcher::OnLoadedInternal(scoped_refptr<const Extension> extension) { extensions_.Insert(extension); } +void Dispatcher::OnMessageInvoke(const std::string& extension_id, + const std::string& module_name, + const std::string& function_name, + const base::ListValue& args, + bool user_gesture) { + InvokeModuleSystemMethod( + NULL, extension_id, module_name, function_name, args, user_gesture); +} + +void Dispatcher::OnSetChannel(int channel) { + delegate_->SetChannel(channel); +} + +void Dispatcher::OnSetFunctionNames(const std::vector<std::string>& names) { + function_names_.clear(); + for (size_t i = 0; i < names.size(); ++i) + function_names_.insert(names[i]); +} + +void Dispatcher::OnSetScriptingWhitelist( + const ExtensionsClient::ScriptingWhitelist& extension_ids) { + ExtensionsClient::Get()->SetScriptingWhitelist(extension_ids); +} + +void Dispatcher::OnSetSystemFont(const std::string& font_family, + const std::string& font_size) { + system_font_family_ = font_family; + system_font_size_ = font_size; +} + +void Dispatcher::OnShouldSuspend(const std::string& extension_id, + int sequence_id) { + RenderThread::Get()->Send( + new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id)); +} + +void Dispatcher::OnSuspend(const std::string& extension_id) { + // Dispatch the suspend event. This doesn't go through the standard event + // dispatch machinery because it requires special handling. We need to let + // the browser know when we are starting and stopping the event dispatch, so + // that it still considers the extension idle despite any activity the suspend + // event creates. + DispatchEvent(extension_id, kOnSuspendEvent); + RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); +} + void Dispatcher::OnUnloaded(const std::string& id) { extensions_.Remove(id); active_extension_ids_.erase(id); @@ -677,7 +703,7 @@ void Dispatcher::OnUnloaded(const std::string& id) { // Update the available bindings for the remaining contexts. These may have // changed if an externally_connectable extension is unloaded and a webpage // is no longer accessible. - AddOrRemoveBindings(""); + UpdateBindings(""); // Invalidates the messages map for the extension in case the extension is // reloaded with a new messages map. @@ -688,42 +714,118 @@ void Dispatcher::OnUnloaded(const std::string& id) { // extension's URL just won't match anything anymore. } -void Dispatcher::OnSetScriptingWhitelist( - const ExtensionsClient::ScriptingWhitelist& extension_ids) { - ExtensionsClient::Get()->SetScriptingWhitelist(extension_ids); +void Dispatcher::OnUpdatePermissions( + const ExtensionMsg_UpdatePermissions_Params& params) { + int reason_id = params.reason_id; + const std::string& extension_id = params.extension_id; + const APIPermissionSet& apis = params.apis; + const ManifestPermissionSet& manifest_permissions = + params.manifest_permissions; + const URLPatternSet& explicit_hosts = params.explicit_hosts; + const URLPatternSet& scriptable_hosts = params.scriptable_hosts; + + const Extension* extension = extensions_.GetByID(extension_id); + if (!extension) + return; + + scoped_refptr<const PermissionSet> delta = new PermissionSet( + apis, manifest_permissions, explicit_hosts, scriptable_hosts); + scoped_refptr<const PermissionSet> old_active = + extension->GetActivePermissions(); + UpdatedExtensionPermissionsInfo::Reason reason = + static_cast<UpdatedExtensionPermissionsInfo::Reason>(reason_id); + + const PermissionSet* new_active = NULL; + switch (reason) { + case UpdatedExtensionPermissionsInfo::ADDED: + new_active = PermissionSet::CreateUnion(old_active.get(), delta.get()); + break; + case UpdatedExtensionPermissionsInfo::REMOVED: + new_active = + PermissionSet::CreateDifference(old_active.get(), delta.get()); + break; + } + + PermissionsData::SetActivePermissions(extension, new_active); + UpdateOriginPermissions(reason, extension, explicit_hosts); + UpdateBindings(extension->id()); } -bool Dispatcher::IsExtensionActive( - const std::string& extension_id) const { - bool is_active = - active_extension_ids_.find(extension_id) != active_extension_ids_.end(); - if (is_active) - CHECK(extensions_.Contains(extension_id)); - return is_active; +void Dispatcher::OnUpdateTabSpecificPermissions( + int page_id, + int tab_id, + const std::string& extension_id, + const URLPatternSet& origin_set) { + delegate_->UpdateTabSpecificPermissions( + this, page_id, tab_id, extension_id, origin_set); } -v8::Handle<v8::Object> Dispatcher::GetOrCreateObject( - v8::Handle<v8::Object> object, - const std::string& field, - v8::Isolate* isolate) { - v8::Handle<v8::String> key = v8::String::NewFromUtf8(isolate, field.c_str()); - // If the object has a callback property, it is assumed it is an unavailable - // API, so it is safe to delete. This is checked before GetOrCreateObject is - // called. - if (object->HasRealNamedCallbackProperty(key)) { - object->Delete(key); - } else if (object->HasRealNamedProperty(key)) { - v8::Handle<v8::Value> value = object->Get(key); - CHECK(value->IsObject()); - return v8::Handle<v8::Object>::Cast(value); +void Dispatcher::OnUpdateUserScripts(base::SharedMemoryHandle scripts) { + DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle"; + user_script_slave_->UpdateScripts(scripts); + UpdateActiveExtensions(); +} + +void Dispatcher::OnUsingWebRequestAPI(bool adblock, + bool adblock_plus, + bool other_webrequest) { + delegate_->HandleWebRequestAPIUsage(adblock, adblock_plus, other_webrequest); +} + +void Dispatcher::UpdateActiveExtensions() { + std::set<std::string> active_extensions = active_extension_ids_; + user_script_slave_->GetActiveExtensions(&active_extensions); + delegate_->OnActiveExtensionsUpdated(active_extensions); +} + +void Dispatcher::InitOriginPermissions(const Extension* extension, + Feature::Context context_type) { + delegate_->InitOriginPermissions(extension, context_type); + UpdateOriginPermissions( + UpdatedExtensionPermissionsInfo::ADDED, + extension, + PermissionsData::GetEffectiveHostPermissions(extension)); +} + +void Dispatcher::UpdateOriginPermissions( + UpdatedExtensionPermissionsInfo::Reason reason, + const Extension* extension, + const URLPatternSet& origins) { + for (URLPatternSet::const_iterator i = origins.begin(); i != origins.end(); + ++i) { + const char* schemes[] = { + content::kHttpScheme, content::kHttpsScheme, content::kFileScheme, + content::kChromeUIScheme, content::kFtpScheme, + }; + for (size_t j = 0; j < arraysize(schemes); ++j) { + if (i->MatchesScheme(schemes[j])) { + ((reason == UpdatedExtensionPermissionsInfo::REMOVED) + ? WebSecurityPolicy::removeOriginAccessWhitelistEntry + : WebSecurityPolicy::addOriginAccessWhitelistEntry)( + extension->url(), + WebString::fromUTF8(schemes[j]), + WebString::fromUTF8(i->host()), + i->match_subdomains()); + } + } } +} - v8::Handle<v8::Object> new_object = v8::Object::New(isolate); - object->Set(key, new_object); - return new_object; +void Dispatcher::EnableCustomElementWhiteList() { + blink::WebCustomElement::addEmbedderCustomElementName("webview"); + // TODO(fsamuel): Add <adview> to the whitelist once it has been converted + // into a custom element. + blink::WebCustomElement::addEmbedderCustomElementName("browser-plugin"); +} + +void Dispatcher::UpdateBindings(const std::string& extension_id) { + script_context_set().ForEach(extension_id, + NULL, // all render views + base::Bind(&Dispatcher::UpdateBindingsForContext, + base::Unretained(this))); } -void Dispatcher::AddOrRemoveBindingsForContext(ScriptContext* context) { +void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { v8::HandleScope handle_scope(context->isolate()); v8::Context::Scope context_scope(context->v8_context()); @@ -742,10 +844,11 @@ void Dispatcher::AddOrRemoveBindingsForContext(ScriptContext* context) { // connect to it. bool runtime_is_available = false; for (ExtensionSet::const_iterator it = extensions_.begin(); - it != extensions_.end(); ++it) { + it != extensions_.end(); + ++it) { ExternallyConnectableInfo* info = - static_cast<ExternallyConnectableInfo*>((*it)->GetManifestData( - manifest_keys::kExternallyConnectable)); + static_cast<ExternallyConnectableInfo*>( + (*it)->GetManifestData(manifest_keys::kExternallyConnectable)); if (info && info->matches.MatchesURL(context->GetURL())) { runtime_is_available = true; break; @@ -765,7 +868,8 @@ void Dispatcher::AddOrRemoveBindingsForContext(ScriptContext* context) { const std::vector<std::string>& apis = api_feature_provider->GetAllFeatureNames(); for (std::vector<std::string>::const_iterator it = apis.begin(); - it != apis.end(); ++it) { + it != apis.end(); + ++it) { const std::string& api_name = *it; Feature* feature = api_feature_provider->GetFeature(api_name); DCHECK(feature); @@ -791,56 +895,6 @@ void Dispatcher::AddOrRemoveBindingsForContext(ScriptContext* context) { } } -v8::Handle<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable( - const std::string& api_name, - std::string* bind_name, - ScriptContext* context) { - std::vector<std::string> split; - base::SplitString(api_name, '.', &split); - - v8::Handle<v8::Object> bind_object; - - // Check if this API has an ancestor. If the API's ancestor is available and - // the API is not available, don't install the bindings for this API. If - // the API is available and its ancestor is not, delete the ancestor and - // install the bindings for the API. This is to prevent loading the ancestor - // API schema if it will not be needed. - // - // For example: - // If app is available and app.window is not, just install app. - // If app.window is available and app is not, delete app and install - // app.window on a new object so app does not have to be loaded. - FeatureProvider* api_feature_provider = FeatureProvider::GetAPIFeatures(); - std::string ancestor_name; - bool only_ancestor_available = false; - - for (size_t i = 0; i < split.size() - 1; ++i) { - ancestor_name += (i ? ".": "") + split[i]; - if (api_feature_provider->GetFeature(ancestor_name) && - context->GetAvailability(ancestor_name).is_available() && - !context->GetAvailability(api_name).is_available()) { - only_ancestor_available = true; - break; - } - - if (bind_object.IsEmpty()) { - bind_object = AsObjectOrEmpty(GetOrCreateChrome(context)); - if (bind_object.IsEmpty()) - return v8::Handle<v8::Object>(); - } - bind_object = GetOrCreateObject(bind_object, split[i], context->isolate()); - } - - if (only_ancestor_available) - return v8::Handle<v8::Object>(); - - if (bind_name) - *bind_name = split.back(); - - return bind_object.IsEmpty() ? - AsObjectOrEmpty(GetOrCreateChrome(context)) : bind_object; -} - void Dispatcher::RegisterBinding(const std::string& api_name, ScriptContext* context) { std::string bind_name; @@ -871,24 +925,15 @@ void Dispatcher::RegisterBinding(const std::string& api_name, } ModuleSystem* module_system = context->module_system(); - if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) { - InstallBindings(module_system, context->v8_context(), api_name); - } else if (!source_map_.Contains(api_name)) { + if (!source_map_.Contains(api_name)) { module_system->RegisterNativeHandler( api_name, scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler( - module_system, - api_name, - "binding"))); - module_system->SetNativeLazyField(bind_object, - bind_name, - api_name, - "binding"); + module_system, api_name, "binding"))); + module_system->SetNativeLazyField( + bind_object, bind_name, api_name, "binding"); } else { - module_system->SetLazyField(bind_object, - bind_name, - api_name, - "binding"); + module_system->SetLazyField(bind_object, bind_name, api_name, "binding"); } } @@ -896,11 +941,51 @@ void Dispatcher::RegisterBinding(const std::string& api_name, void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, ScriptContext* context) { module_system->RegisterNativeHandler( + "chrome", scoped_ptr<NativeHandler>(new ChromeNativeHandler(context))); + module_system->RegisterNativeHandler( + "lazy_background_page", + scoped_ptr<NativeHandler>(new LazyBackgroundPageNativeHandler(context))); + module_system->RegisterNativeHandler( + "logging", scoped_ptr<NativeHandler>(new LoggingNativeHandler(context))); + module_system->RegisterNativeHandler("schema_registry", + v8_schema_registry_->AsNativeHandler()); + module_system->RegisterNativeHandler( + "print", scoped_ptr<NativeHandler>(new PrintNativeHandler(context))); + module_system->RegisterNativeHandler( + "test_features", + scoped_ptr<NativeHandler>(new TestFeaturesNativeHandler(context))); + module_system->RegisterNativeHandler( + "user_gestures", + scoped_ptr<NativeHandler>(new UserGesturesNativeHandler(context))); + module_system->RegisterNativeHandler( + "utils", scoped_ptr<NativeHandler>(new UtilsNativeHandler(context))); + module_system->RegisterNativeHandler( + "v8_context", + scoped_ptr<NativeHandler>(new V8ContextNativeHandler(context, this))); + + const Extension* extension = context->extension(); + int manifest_version = extension ? extension->manifest_version() : 1; + bool send_request_disabled = + (extension && Manifest::IsUnpackedLocation(extension->location()) && + BackgroundInfo::HasLazyBackgroundPage(extension)); + module_system->RegisterNativeHandler( + "process", + scoped_ptr<NativeHandler>(new ProcessInfoNativeHandler( + context, + context->GetExtensionID(), + context->GetContextTypeDescription(), + ExtensionsRendererClient::Get()->IsIncognitoProcess(), + manifest_version, + send_request_disabled))); + + module_system->RegisterNativeHandler( "event_natives", scoped_ptr<NativeHandler>(new EventBindings(this, context))); - module_system->RegisterNativeHandler("messaging_natives", + module_system->RegisterNativeHandler( + "messaging_natives", scoped_ptr<NativeHandler>(MessagingBindings::Get(this, context))); - module_system->RegisterNativeHandler("apiDefinitions", + module_system->RegisterNativeHandler( + "apiDefinitions", scoped_ptr<NativeHandler>(new ApiDefinitionsNatives(this, context))); module_system->RegisterNativeHandler( "sendRequest", @@ -918,19 +1003,16 @@ void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, scoped_ptr<NativeHandler>(new RenderViewObserverNatives(context))); // Natives used by multiple APIs. - module_system->RegisterNativeHandler("file_system_natives", + module_system->RegisterNativeHandler( + "file_system_natives", scoped_ptr<NativeHandler>(new FileSystemNatives(context))); // Custom bindings. - module_system->RegisterNativeHandler("app", - scoped_ptr<NativeHandler>(new AppBindings(this, context))); module_system->RegisterNativeHandler( "app_runtime", scoped_ptr<NativeHandler>(new AppRuntimeCustomBindings(context))); - module_system->RegisterNativeHandler("app_window_natives", - scoped_ptr<NativeHandler>( - new AppWindowCustomBindings(this, context))); - module_system->RegisterNativeHandler("blob_natives", + module_system->RegisterNativeHandler( + "blob_natives", scoped_ptr<NativeHandler>(new BlobNativeHandler(context))); module_system->RegisterNativeHandler( "context_menus", @@ -941,41 +1023,14 @@ void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, "document_natives", scoped_ptr<NativeHandler>(new DocumentCustomBindings(context))); module_system->RegisterNativeHandler( - "sync_file_system", - scoped_ptr<NativeHandler>(new SyncFileSystemCustomBindings(context))); - module_system->RegisterNativeHandler( - "file_browser_handler", - scoped_ptr<NativeHandler>(new FileBrowserHandlerCustomBindings(context))); - module_system->RegisterNativeHandler( - "file_browser_private", - scoped_ptr<NativeHandler>(new FileBrowserPrivateCustomBindings(context))); - module_system->RegisterNativeHandler( "i18n", scoped_ptr<NativeHandler>(new I18NCustomBindings(context))); module_system->RegisterNativeHandler( "id_generator", scoped_ptr<NativeHandler>(new IdGeneratorCustomBindings(context))); module_system->RegisterNativeHandler( - "mediaGalleries", - scoped_ptr<NativeHandler>(new MediaGalleriesCustomBindings(context))); - module_system->RegisterNativeHandler( - "page_actions", - scoped_ptr<NativeHandler>(new PageActionsCustomBindings(this, context))); - module_system->RegisterNativeHandler( - "page_capture", - scoped_ptr<NativeHandler>(new PageCaptureCustomBindings(context))); - module_system->RegisterNativeHandler( - "pepper_request_natives", - scoped_ptr<NativeHandler>(new PepperRequestNatives(context))); - module_system->RegisterNativeHandler( "runtime", scoped_ptr<NativeHandler>(new RuntimeCustomBindings(context))); - module_system->RegisterNativeHandler( - "tabs", scoped_ptr<NativeHandler>(new TabsCustomBindings(context))); - module_system->RegisterNativeHandler( - "webstore", scoped_ptr<NativeHandler>(new WebstoreBindings(context))); -#if defined(ENABLE_WEBRTC) - module_system->RegisterNativeHandler("cast_streaming_natives", - scoped_ptr<NativeHandler>(new CastStreamingNativeHandler(context))); -#endif + + delegate_->RegisterNativeHandlers(this, module_system, context); } void Dispatcher::PopulateSourceMap() { @@ -987,7 +1042,6 @@ void Dispatcher::PopulateSourceMap() { source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS); source_map_.RegisterSource("messaging", IDR_MESSAGING_JS); source_map_.RegisterSource("messaging_utils", IDR_MESSAGING_UTILS_JS); - source_map_.RegisterSource("pepper_request", IDR_PEPPER_REQUEST_JS); source_map_.RegisterSource(kSchemaUtils, IDR_SCHEMA_UTILS_JS); source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS); source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS); @@ -996,305 +1050,28 @@ void Dispatcher::PopulateSourceMap() { source_map_.RegisterSource("utils", IDR_UTILS_JS); // Custom bindings. - source_map_.RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("app.runtime", IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("automation", IDR_AUTOMATION_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("automationEvent", IDR_AUTOMATION_EVENT_JS); - source_map_.RegisterSource("automationNode", IDR_AUTOMATION_NODE_JS); - source_map_.RegisterSource("automationTree", IDR_AUTOMATION_TREE_JS); - source_map_.RegisterSource("browserAction", - IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("contextMenus", IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("declarativeContent", - IDR_DECLARATIVE_CONTENT_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("declarativeWebRequest", - IDR_DECLARATIVE_WEBREQUEST_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("desktopCapture", - IDR_DESKTOP_CAPTURE_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("developerPrivate", - IDR_DEVELOPER_PRIVATE_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("downloads", - IDR_DOWNLOADS_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("extension", IDR_EXTENSION_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("feedbackPrivate", - IDR_FEEDBACK_PRIVATE_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("fileBrowserHandler", - IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("fileBrowserPrivate", - IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("fileSystem", - IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("fileSystemProvider", - IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("gcm", - IDR_GCM_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("i18n", IDR_I18N_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("imageWriterPrivate", - IDR_IMAGE_WRITER_PRIVATE_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("mediaGalleries", - IDR_MEDIA_GALLERIES_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("notifications", - IDR_NOTIFICATIONS_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("pageActions", - IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("pageCapture", - IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("permissions", IDR_PERMISSIONS_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("runtime", IDR_RUNTIME_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("syncFileSystem", - IDR_SYNC_FILE_SYSTEM_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("systemIndicator", - IDR_SYSTEM_INDICATOR_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("tabCapture", IDR_TAB_CAPTURE_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("webRequest", IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("webRequestInternal", - IDR_WEB_REQUEST_INTERNAL_CUSTOM_BINDINGS_JS); -#if defined(ENABLE_WEBRTC) - source_map_.RegisterSource("cast.streaming.rtpStream", - IDR_CAST_STREAMING_RTP_STREAM_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("cast.streaming.session", - IDR_CAST_STREAMING_SESSION_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource( - "cast.streaming.udpTransport", - IDR_CAST_STREAMING_UDP_TRANSPORT_CUSTOM_BINDINGS_JS); -#endif - source_map_.RegisterSource("webstore", IDR_WEBSTORE_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("windowControls", IDR_WINDOW_CONTROLS_JS); source_map_.RegisterSource("binding", IDR_BINDING_JS); // Custom types sources. - source_map_.RegisterSource("ChromeSetting", IDR_CHROME_SETTING_JS); source_map_.RegisterSource("StorageArea", IDR_STORAGE_AREA_JS); - source_map_.RegisterSource("ContentSetting", IDR_CONTENT_SETTING_JS); - source_map_.RegisterSource("ChromeDirectSetting", - IDR_CHROME_DIRECT_SETTING_JS); // Platform app sources that are not API-specific.. - source_map_.RegisterSource("tagWatcher", IDR_TAG_WATCHER_JS); - source_map_.RegisterSource("webview", IDR_WEBVIEW_CUSTOM_BINDINGS_JS); - // Note: webView not webview so that this doesn't interfere with the - // chrome.webview API bindings. - source_map_.RegisterSource("webView", IDR_WEB_VIEW_JS); - source_map_.RegisterSource("webViewExperimental", - IDR_WEB_VIEW_EXPERIMENTAL_JS); - source_map_.RegisterSource("webViewRequest", - IDR_WEB_VIEW_REQUEST_CUSTOM_BINDINGS_JS); - source_map_.RegisterSource("denyWebView", IDR_WEB_VIEW_DENY_JS); - source_map_.RegisterSource("adView", IDR_AD_VIEW_JS); - source_map_.RegisterSource("denyAdView", IDR_AD_VIEW_DENY_JS); source_map_.RegisterSource("platformApp", IDR_PLATFORM_APP_JS); - source_map_.RegisterSource("injectAppTitlebar", IDR_INJECT_APP_TITLEBAR_JS); -} -void Dispatcher::PopulateLazyBindingsMap() { - lazy_bindings_map_["app"] = InstallAppBindings; - lazy_bindings_map_["webstore"] = InstallWebstoreBindings; -} - -void Dispatcher::InstallBindings(ModuleSystem* module_system, - v8::Handle<v8::Context> v8_context, - const std::string& api) { - std::map<std::string, BindingInstaller>::const_iterator lazy_binding = - lazy_bindings_map_.find(api); - if (lazy_binding != lazy_bindings_map_.end()) { - v8::Handle<v8::Object> global(v8_context->Global()); - v8::Handle<v8::Object> chrome = - global->Get(v8::String::NewFromUtf8(v8_context->GetIsolate(), "chrome")) - ->ToObject(); - (*lazy_binding->second)(module_system, chrome); - } else { - module_system->Require(api); - } -} - -void Dispatcher::DidCreateScriptContext( - WebFrame* frame, v8::Handle<v8::Context> v8_context, int extension_group, - int world_id) { -#if !defined(ENABLE_EXTENSIONS) - return; -#endif - - std::string extension_id = GetExtensionID(frame, world_id); - - const Extension* extension = extensions_.GetByID(extension_id); - if (!extension && !extension_id.empty()) { - // There are conditions where despite a context being associated with an - // extension, no extension actually gets found. Ignore "invalid" because - // CSP blocks extension page loading by switching the extension ID to - // "invalid". This isn't interesting. - if (extension_id != "invalid") { - LOG(ERROR) << "Extension \"" << extension_id << "\" not found"; - RenderThread::Get()->RecordAction( - UserMetricsAction("ExtensionNotFound_ED")); - } - - extension_id = ""; - } - - Feature::Context context_type = - ClassifyJavaScriptContext(extension, - extension_group, - ScriptContext::GetDataSourceURLForFrame(frame), - frame->document().securityOrigin()); - - ScriptContext* context = - new ChromeV8Context(v8_context, frame, extension, context_type); - script_context_set_.Add(context); - - if (extension) - InitOriginPermissions(extension, context_type); - - { - scoped_ptr<ModuleSystem> module_system(new ModuleSystem(context, - &source_map_)); - context->set_module_system(module_system.Pass()); - } - ModuleSystem* module_system = context->module_system(); - - // Enable natives in startup. - ModuleSystem::NativesEnabledScope natives_enabled_scope( - module_system); - - // Register the core extensions native handlers. - RegisterNativeHandlers(module_system, context); - - // Register native handlers from the extensions embedder. - ExtensionsRendererClient::Get()->RegisterNativeHandlers(module_system, - context); - - module_system->RegisterNativeHandler("chrome", - scoped_ptr<NativeHandler>(new ChromeNativeHandler(context))); - module_system->RegisterNativeHandler("print", - scoped_ptr<NativeHandler>(new PrintNativeHandler(context))); - module_system->RegisterNativeHandler( - "lazy_background_page", - scoped_ptr<NativeHandler>(new LazyBackgroundPageNativeHandler(context))); - module_system->RegisterNativeHandler("logging", - scoped_ptr<NativeHandler>(new LoggingNativeHandler(context))); - module_system->RegisterNativeHandler("schema_registry", - v8_schema_registry_->AsNativeHandler()); - module_system->RegisterNativeHandler("v8_context", - scoped_ptr<NativeHandler>(new V8ContextNativeHandler(context, this))); - module_system->RegisterNativeHandler("test_features", - scoped_ptr<NativeHandler>(new TestFeaturesNativeHandler(context))); - module_system->RegisterNativeHandler("user_gestures", - scoped_ptr<NativeHandler>(new UserGesturesNativeHandler(context))); - module_system->RegisterNativeHandler("utils", - scoped_ptr<NativeHandler>(new UtilsNativeHandler(context))); - - int manifest_version = extension ? extension->manifest_version() : 1; - bool send_request_disabled = - (extension && Manifest::IsUnpackedLocation(extension->location()) && - BackgroundInfo::HasLazyBackgroundPage(extension)); - module_system->RegisterNativeHandler( - "process", - scoped_ptr<NativeHandler>(new ProcessInfoNativeHandler( - context, - context->GetExtensionID(), - context->GetContextTypeDescription(), - ChromeRenderProcessObserver::is_incognito_process(), - manifest_version, - send_request_disabled))); - - // chrome.Event is part of the public API (although undocumented). Make it - // lazily evalulate to Event from event_bindings.js. For extensions only - // though, not all webpages! - if (context->extension()) { - v8::Handle<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context)); - if (!chrome.IsEmpty()) - module_system->SetLazyField(chrome, "Event", kEventBindings, "Event"); - } - - AddOrRemoveBindingsForContext(context); - - bool is_within_platform_app = IsWithinPlatformApp(); - // Inject custom JS into the platform app context. - if (is_within_platform_app) { - module_system->Require("platformApp"); - } - - if (context_type == Feature::BLESSED_EXTENSION_CONTEXT && - is_within_platform_app && - GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV && - CommandLine::ForCurrentProcess()->HasSwitch( - ::switches::kEnableAppWindowControls)) { - module_system->Require("windowControls"); - } - - // We used to limit WebView to |BLESSED_EXTENSION_CONTEXT| within platform - // apps. An ext/app runs in a blessed extension context, if it is the active - // extension in the current process, in other words, if it is loaded in a top - // frame. To support webview in a non-frame extension, we have to allow - // unblessed extension context as well. - // Note: setting up the WebView class here, not the chrome.webview API. - // The API will be automatically set up when first used. - if (context_type == Feature::BLESSED_EXTENSION_CONTEXT || - context_type == Feature::UNBLESSED_EXTENSION_CONTEXT) { - if (extension->HasAPIPermission(APIPermission::kWebView)) { - module_system->Require("webView"); - if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV) { - module_system->Require("webViewExperimental"); - } else { - // TODO(asargent) We need a whitelist for webview experimental. - // crbug.com/264852 - std::string id_hash = base::SHA1HashString(extension->id()); - std::string hexencoded_id_hash = base::HexEncode(id_hash.c_str(), - id_hash.length()); - if (hexencoded_id_hash == "8C3741E3AF0B93B6E8E0DDD499BB0B74839EA578" || - hexencoded_id_hash == "E703483CEF33DEC18B4B6DD84B5C776FB9182BDB" || - hexencoded_id_hash == "1A26E32DE447A17CBE5E9750CDBA78F58539B39C" || - hexencoded_id_hash == "59048028102D7B4C681DBC7BC6CD980C3DC66DA3") { - module_system->Require("webViewExperimental"); - } - } - } else { - module_system->Require("denyWebView"); - } - } - - // Same comment as above for <adview> tag. - if (context_type == Feature::BLESSED_EXTENSION_CONTEXT && - is_within_platform_app) { - if (CommandLine::ForCurrentProcess()->HasSwitch( - ::switches::kEnableAdview)) { - if (extension->HasAPIPermission(APIPermission::kAdView)) { - module_system->Require("adView"); - } else { - module_system->Require("denyAdView"); - } - } - } - - VLOG(1) << "Num tracked contexts: " << script_context_set_.size(); -} - -std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) { - if (world_id != 0) { - // Isolated worlds (content script). - return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id); - } - - // TODO(kalman): Delete this check. - if (frame->document().securityOrigin().isUnique()) - return std::string(); - - // Extension pages (chrome-extension:// URLs). - GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame); - return extensions_.GetExtensionOrAppIDByURL(frame_url); + delegate_->PopulateSourceMap(&source_map_); } bool Dispatcher::IsWithinPlatformApp() { for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); - iter != active_extension_ids_.end(); ++iter) { + iter != active_extension_ids_.end(); + ++iter) { const Extension* extension = extensions_.GetByID(*iter); if (extension && extension->is_platform_app()) return true; @@ -1302,257 +1079,6 @@ bool Dispatcher::IsWithinPlatformApp() { return false; } -void Dispatcher::WillReleaseScriptContext( - WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { - ScriptContext* context = script_context_set_.GetByV8Context(v8_context); - if (!context) - return; - - context->DispatchOnUnloadEvent(); - // TODO(kalman): add an invalidation observer interface to ScriptContext. - request_sender_->InvalidateSource(context); - - script_context_set_.Remove(context); - VLOG(1) << "Num tracked contexts: " << script_context_set_.size(); -} - -void Dispatcher::DidCreateDocumentElement(blink::WebFrame* frame) { - if (IsWithinPlatformApp()) { - // WebKit doesn't let us define an additional user agent stylesheet, so we - // insert the default platform app stylesheet into all documents that are - // loaded in each app. - std::string stylesheet = - ResourceBundle::GetSharedInstance(). - GetRawDataResource(IDR_PLATFORM_APP_CSS).as_string(); - ReplaceFirstSubstringAfterOffset(&stylesheet, 0, - "$FONTFAMILY", system_font_family_); - ReplaceFirstSubstringAfterOffset(&stylesheet, 0, - "$FONTSIZE", system_font_size_); - frame->document().insertStyleSheet(WebString::fromUTF8(stylesheet)); - } - - content_watcher_->DidCreateDocumentElement(frame); -} - -void Dispatcher::DidMatchCSS( - blink::WebFrame* frame, - const blink::WebVector<blink::WebString>& newly_matching_selectors, - const blink::WebVector<blink::WebString>& stopped_matching_selectors) { - content_watcher_->DidMatchCSS( - frame, newly_matching_selectors, stopped_matching_selectors); -} - - -void Dispatcher::OnActivateExtension(const std::string& extension_id) { - const Extension* extension = extensions_.GetByID(extension_id); - if (!extension) { - // Extension was activated but was never loaded. This probably means that - // the renderer failed to load it (or the browser failed to tell us when it - // did). Failures shouldn't happen, but instead of crashing there (which - // executes on all renderers) be conservative and only crash in the renderer - // of the extension which failed to load; this one. - std::string& error = extension_load_errors_[extension_id]; - char minidump[256]; - base::debug::Alias(&minidump); - base::snprintf(minidump, arraysize(minidump), - "e::dispatcher:%s:%s", extension_id.c_str(), error.c_str()); - CHECK(extension) << extension_id << " was never loaded: " << error; - } - - active_extension_ids_.insert(extension_id); - - // This is called when starting a new extension page, so start the idle - // handler ticking. - RenderThread::Get()->ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayMs); - - UpdateActiveExtensions(); - - if (is_webkit_initialized_) { - DOMActivityLogger::AttachToWorld(DOMActivityLogger::kMainWorldId, - extension_id); - } -} - -void Dispatcher::InitOriginPermissions(const Extension* extension, - Feature::Context context_type) { - // TODO(jstritar): We should try to remove this special case. Also, these - // whitelist entries need to be updated when the kManagement permission - // changes. - if (context_type == Feature::BLESSED_EXTENSION_CONTEXT && - extension->HasAPIPermission(APIPermission::kManagement)) { - WebSecurityPolicy::addOriginAccessWhitelistEntry( - extension->url(), - WebString::fromUTF8(content::kChromeUIScheme), - WebString::fromUTF8(chrome::kChromeUIExtensionIconHost), - false); - } - - AddOrRemoveOriginPermissions( - UpdatedExtensionPermissionsInfo::ADDED, - extension, - PermissionsData::GetEffectiveHostPermissions(extension)); -} - -void Dispatcher::AddOrRemoveOriginPermissions( - UpdatedExtensionPermissionsInfo::Reason reason, - const Extension* extension, - const URLPatternSet& origins) { - for (URLPatternSet::const_iterator i = origins.begin(); - i != origins.end(); ++i) { - const char* schemes[] = { - content::kHttpScheme, - content::kHttpsScheme, - content::kFileScheme, - content::kChromeUIScheme, - content::kFtpScheme, - }; - for (size_t j = 0; j < arraysize(schemes); ++j) { - if (i->MatchesScheme(schemes[j])) { - ((reason == UpdatedExtensionPermissionsInfo::REMOVED) ? - WebSecurityPolicy::removeOriginAccessWhitelistEntry : - WebSecurityPolicy::addOriginAccessWhitelistEntry)( - extension->url(), - WebString::fromUTF8(schemes[j]), - WebString::fromUTF8(i->host()), - i->match_subdomains()); - } - } - } -} - -void Dispatcher::EnableCustomElementWhiteList() { - blink::WebCustomElement::addEmbedderCustomElementName("webview"); - // TODO(fsamuel): Add <adview> to the whitelist once it has been converted - // into a custom element. - blink::WebCustomElement::addEmbedderCustomElementName("browser-plugin"); -} - -void Dispatcher::AddOrRemoveBindings(const std::string& extension_id) { - script_context_set().ForEach( - extension_id, - NULL, // all render views - base::Bind(&Dispatcher::AddOrRemoveBindingsForContext, - base::Unretained(this))); -} - -void Dispatcher::OnUpdatePermissions( - const ExtensionMsg_UpdatePermissions_Params& params) { - int reason_id = params.reason_id; - const std::string& extension_id = params.extension_id; - const APIPermissionSet& apis = params.apis; - const ManifestPermissionSet& manifest_permissions = - params.manifest_permissions; - const URLPatternSet& explicit_hosts = params.explicit_hosts; - const URLPatternSet& scriptable_hosts = params.scriptable_hosts; - - const Extension* extension = extensions_.GetByID(extension_id); - if (!extension) - return; - - scoped_refptr<const PermissionSet> delta = - new PermissionSet(apis, manifest_permissions, - explicit_hosts, scriptable_hosts); - scoped_refptr<const PermissionSet> old_active = - extension->GetActivePermissions(); - UpdatedExtensionPermissionsInfo::Reason reason = - static_cast<UpdatedExtensionPermissionsInfo::Reason>(reason_id); - - const PermissionSet* new_active = NULL; - switch (reason) { - case UpdatedExtensionPermissionsInfo::ADDED: - new_active = PermissionSet::CreateUnion(old_active.get(), delta.get()); - break; - case UpdatedExtensionPermissionsInfo::REMOVED: - new_active = - PermissionSet::CreateDifference(old_active.get(), delta.get()); - break; - } - - PermissionsData::SetActivePermissions(extension, new_active); - AddOrRemoveOriginPermissions(reason, extension, explicit_hosts); - AddOrRemoveBindings(extension->id()); -} - -void Dispatcher::OnUpdateTabSpecificPermissions( - int page_id, - int tab_id, - const std::string& extension_id, - const URLPatternSet& origin_set) { - RenderView* view = TabFinder::Find(tab_id); - - // For now, the message should only be sent to the render view that contains - // the target tab. This may change. Either way, if this is the target tab it - // gives us the chance to check against the page ID to avoid races. - DCHECK(view); - if (view && view->GetPageId() != page_id) - return; - - const Extension* extension = extensions_.GetByID(extension_id); - if (!extension) - return; - - PermissionsData::UpdateTabSpecificPermissions( - extension, - tab_id, - new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), - origin_set, URLPatternSet())); -} - -void Dispatcher::OnClearTabSpecificPermissions( - int tab_id, - const std::vector<std::string>& extension_ids) { - for (std::vector<std::string>::const_iterator it = extension_ids.begin(); - it != extension_ids.end(); ++it) { - const Extension* extension = extensions_.GetByID(*it); - if (extension) - PermissionsData::ClearTabSpecificPermissions(extension, tab_id); - } -} - -void Dispatcher::OnUpdateUserScripts( - base::SharedMemoryHandle scripts) { - DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle"; - user_script_slave_->UpdateScripts(scripts); - UpdateActiveExtensions(); -} - -void Dispatcher::UpdateActiveExtensions() { - // In single-process mode, the browser process reports the active extensions. - if (CommandLine::ForCurrentProcess()->HasSwitch(::switches::kSingleProcess)) - return; - - std::set<std::string> active_extensions = active_extension_ids_; - user_script_slave_->GetActiveExtensions(&active_extensions); - crash_keys::SetActiveExtensions(active_extensions); -} - -void Dispatcher::OnUsingWebRequestAPI( - bool adblock, bool adblock_plus, bool other) { - webrequest_adblock_ = adblock; - webrequest_adblock_plus_ = adblock_plus; - webrequest_other_ = other; -} - -void Dispatcher::OnShouldSuspend(const std::string& extension_id, - int sequence_id) { - RenderThread::Get()->Send( - new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id)); -} - -void Dispatcher::OnSuspend(const std::string& extension_id) { - // Dispatch the suspend event. This doesn't go through the standard event - // dispatch machinery because it requires special handling. We need to let - // the browser know when we are starting and stopping the event dispatch, so - // that it still considers the extension idle despite any activity the suspend - // event creates. - DispatchEvent(extension_id, kOnSuspendEvent); - RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); -} - -void Dispatcher::OnCancelSuspend(const std::string& extension_id) { - DispatchEvent(extension_id, kOnSuspendCanceledEvent); -} - // TODO(kalman): This is checking for the wrong thing, it should be checking if // the frame's security origin is unique. The extension sandbox directive is // checked for in extensions/common/manifest_handlers/csp_info.cc. @@ -1574,7 +1100,8 @@ Feature::Context Dispatcher::ClassifyJavaScriptContext( DCHECK_GE(extension_group, 0); if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { return extension ? // TODO(kalman): when does this happen? - Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT; + Feature::CONTENT_SCRIPT_CONTEXT + : Feature::UNSPECIFIED_CONTEXT; } // We have an explicit check for sandboxed pages before checking whether the @@ -1595,8 +1122,9 @@ Feature::Context Dispatcher::ClassifyJavaScriptContext( // unless the extension in question is a component extension, in which case // we cheat and call it blessed. return (extension->is_hosted_app() && - extension->location() != Manifest::COMPONENT) ? - Feature::BLESSED_WEB_PAGE_CONTEXT : Feature::BLESSED_EXTENSION_CONTEXT; + extension->location() != Manifest::COMPONENT) + ? Feature::BLESSED_WEB_PAGE_CONTEXT + : Feature::BLESSED_EXTENSION_CONTEXT; } // TODO(kalman): This isUnique() check is wrong, it should be performed as @@ -1604,9 +1132,8 @@ Feature::Context Dispatcher::ClassifyJavaScriptContext( if (!origin.isUnique() && extensions_.ExtensionBindingsAllowed(url)) { if (!extension) // TODO(kalman): when does this happen? return Feature::UNSPECIFIED_CONTEXT; - return extension->is_hosted_app() ? - Feature::BLESSED_WEB_PAGE_CONTEXT : - Feature::UNBLESSED_EXTENSION_CONTEXT; + return extension->is_hosted_app() ? Feature::BLESSED_WEB_PAGE_CONTEXT + : Feature::UNBLESSED_EXTENSION_CONTEXT; } if (url.is_valid()) @@ -1615,108 +1142,75 @@ Feature::Context Dispatcher::ClassifyJavaScriptContext( return Feature::UNSPECIFIED_CONTEXT; } -void Dispatcher::OnExtensionResponse(int request_id, - bool success, - const base::ListValue& response, - const std::string& error) { - request_sender_->HandleResponse(request_id, success, response, error); -} - -bool Dispatcher::CheckContextAccessToExtensionAPI( - const std::string& function_name, - ScriptContext* context) const { - if (!context) { - DLOG(ERROR) << "Not in a v8::Context"; - return false; - } - - if (!context->extension()) { - context->isolate()->ThrowException(v8::Exception::Error( - v8::String::NewFromUtf8(context->isolate(), "Not in an extension."))); - return false; - } - - // Theoretically we could end up with bindings being injected into sandboxed - // frames, for example content scripts. Don't let them execute API functions. - blink::WebFrame* frame = context->web_frame(); - if (IsSandboxedPage(ScriptContext::GetDataSourceURLForFrame(frame))) { - static const char kMessage[] = - "%s cannot be used within a sandboxed frame."; - std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); - context->isolate()->ThrowException(v8::Exception::Error( - v8::String::NewFromUtf8(context->isolate(), error_msg.c_str()))); - return false; - } - - Feature::Availability availability = context->GetAvailability(function_name); - if (!availability.is_available()) { - context->isolate()->ThrowException( - v8::Exception::Error(v8::String::NewFromUtf8( - context->isolate(), availability.message().c_str()))); +v8::Handle<v8::Object> Dispatcher::GetOrCreateObject( + const v8::Handle<v8::Object>& object, + const std::string& field, + v8::Isolate* isolate) { + v8::Handle<v8::String> key = v8::String::NewFromUtf8(isolate, field.c_str()); + // If the object has a callback property, it is assumed it is an unavailable + // API, so it is safe to delete. This is checked before GetOrCreateObject is + // called. + if (object->HasRealNamedCallbackProperty(key)) { + object->Delete(key); + } else if (object->HasRealNamedProperty(key)) { + v8::Handle<v8::Value> value = object->Get(key); + CHECK(value->IsObject()); + return v8::Handle<v8::Object>::Cast(value); } - return availability.is_available(); + v8::Handle<v8::Object> new_object = v8::Object::New(isolate); + object->Set(key, new_object); + return new_object; } -void Dispatcher::DispatchEvent(const std::string& extension_id, - const std::string& event_name) const { - base::ListValue args; - args.Set(0, new base::StringValue(event_name)); - args.Set(1, new base::ListValue()); - - // Needed for Windows compilation, since kEventBindings is declared extern. - const char* local_event_bindings = kEventBindings; - script_context_set_.ForEach(extension_id, - NULL, // all render views - base::Bind(&CallModuleMethod, - local_event_bindings, - kEventDispatchFunction, - &args)); -} +v8::Handle<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable( + const std::string& api_name, + std::string* bind_name, + ScriptContext* context) { + std::vector<std::string> split; + base::SplitString(api_name, '.', &split); -void Dispatcher::InvokeModuleSystemMethod( - content::RenderView* render_view, - const std::string& extension_id, - const std::string& module_name, - const std::string& function_name, - const base::ListValue& args, - bool user_gesture) { - scoped_ptr<WebScopedUserGesture> web_user_gesture; - if (user_gesture) - web_user_gesture.reset(new WebScopedUserGesture); + v8::Handle<v8::Object> bind_object; - script_context_set_.ForEach( - extension_id, - render_view, - base::Bind(&CallModuleMethod, module_name, function_name, &args)); + // Check if this API has an ancestor. If the API's ancestor is available and + // the API is not available, don't install the bindings for this API. If + // the API is available and its ancestor is not, delete the ancestor and + // install the bindings for the API. This is to prevent loading the ancestor + // API schema if it will not be needed. + // + // For example: + // If app is available and app.window is not, just install app. + // If app.window is available and app is not, delete app and install + // app.window on a new object so app does not have to be loaded. + FeatureProvider* api_feature_provider = FeatureProvider::GetAPIFeatures(); + std::string ancestor_name; + bool only_ancestor_available = false; - // Reset the idle handler each time there's any activity like event or message - // dispatch, for which Invoke is the chokepoint. - if (is_extension_process_) { - RenderThread::Get()->ScheduleIdleHandler( - kInitialExtensionIdleHandlerDelayMs); - } + for (size_t i = 0; i < split.size() - 1; ++i) { + ancestor_name += (i ? "." : "") + split[i]; + if (api_feature_provider->GetFeature(ancestor_name) && + context->GetAvailability(ancestor_name).is_available() && + !context->GetAvailability(api_name).is_available()) { + only_ancestor_available = true; + break; + } - // Tell the browser process when an event has been dispatched with a lazy - // background page active. - const Extension* extension = extensions_.GetByID(extension_id); - if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && - module_name == kEventBindings && - function_name == kEventDispatchFunction) { - RenderView* background_view = - ExtensionHelper::GetBackgroundPage(extension_id); - if (background_view) { - background_view->Send(new ExtensionHostMsg_EventAck( - background_view->GetRoutingID())); + if (bind_object.IsEmpty()) { + bind_object = AsObjectOrEmpty(GetOrCreateChrome(context)); + if (bind_object.IsEmpty()) + return v8::Handle<v8::Object>(); } + bind_object = GetOrCreateObject(bind_object, split[i], context->isolate()); } -} -void Dispatcher::ClearPortData(int port_id) { - // Only the target port side has entries in |port_to_tab_id_map_|. If - // |port_id| is a source port, std::map::erase() will just silently fail - // here as a no-op. - port_to_tab_id_map_.erase(port_id); + if (only_ancestor_available) + return v8::Handle<v8::Object>(); + + if (bind_name) + *bind_name = split.back(); + + return bind_object.IsEmpty() ? AsObjectOrEmpty(GetOrCreateChrome(context)) + : bind_object; } } // namespace extensions diff --git a/chrome/renderer/extensions/dispatcher.h b/extensions/renderer/dispatcher.h index a04b0f1..e4d7aed 100644 --- a/chrome/renderer/extensions/dispatcher.h +++ b/extensions/renderer/dispatcher.h @@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_EXTENSIONS_DISPATCHER_H_ -#define CHROME_RENDERER_EXTENSIONS_DISPATCHER_H_ +#ifndef EXTENSIONS_RENDERER_DISPATCHER_H_ +#define EXTENSIONS_RENDERER_DISPATCHER_H_ #include <map> #include <set> @@ -12,12 +12,12 @@ #include "base/memory/shared_memory.h" #include "base/timer/timer.h" -#include "chrome/renderer/resource_bundle_source_map.h" #include "content/public/renderer/render_process_observer.h" #include "extensions/common/event_filter.h" #include "extensions/common/extension_set.h" #include "extensions/common/extensions_client.h" #include "extensions/common/features/feature.h" +#include "extensions/renderer/resource_bundle_source_map.h" #include "extensions/renderer/script_context.h" #include "extensions/renderer/script_context_set.h" #include "extensions/renderer/v8_schema_registry.h" @@ -49,6 +49,7 @@ class RenderThread; namespace extensions { class ContentWatcher; +class DispatcherDelegate; class Extension; class FilteredEventRouter; class ManifestPermissionSet; @@ -61,7 +62,7 @@ struct Message; // renderer extension related state. class Dispatcher : public content::RenderProcessObserver { public: - Dispatcher(); + explicit Dispatcher(DispatcherDelegate* delegate); virtual ~Dispatcher(); const std::set<std::string>& function_names() const { @@ -69,22 +70,20 @@ class Dispatcher : public content::RenderProcessObserver { } bool is_extension_process() const { return is_extension_process_; } + const ExtensionSet* extensions() const { return &extensions_; } + const ScriptContextSet& script_context_set() const { return script_context_set_; } - UserScriptSlave* user_script_slave() { - return user_script_slave_.get(); - } - V8SchemaRegistry* v8_schema_registry() { - return v8_schema_registry_.get(); - } - ContentWatcher* content_watcher() { - return content_watcher_.get(); - } - RequestSender* request_sender() { - return request_sender_.get(); - } + + V8SchemaRegistry* v8_schema_registry() { return v8_schema_registry_.get(); } + + ContentWatcher* content_watcher() { return content_watcher_.get(); } + + UserScriptSlave* user_script_slave() { return user_script_slave_.get(); } + + RequestSender* request_sender() { return request_sender_.get(); } bool IsExtensionActive(const std::string& extension_id) const; @@ -95,11 +94,12 @@ class Dispatcher : public content::RenderProcessObserver { std::string GetExtensionID(const blink::WebFrame* frame, int world_id); void DidCreateScriptContext(blink::WebFrame* frame, - v8::Handle<v8::Context> context, + const v8::Handle<v8::Context>& context, int extension_group, int world_id); + void WillReleaseScriptContext(blink::WebFrame* frame, - v8::Handle<v8::Context> context, + const v8::Handle<v8::Context>& context, int world_id); void DidCreateDocumentElement(blink::WebFrame* frame); @@ -109,17 +109,6 @@ class Dispatcher : public content::RenderProcessObserver { const blink::WebVector<blink::WebString>& newly_matching_selectors, const blink::WebVector<blink::WebString>& stopped_matching_selectors); - // TODO(mpcomplete): remove. http://crbug.com/100411 - bool IsAdblockWithWebRequestInstalled() const { - return webrequest_adblock_; - } - bool IsAdblockPlusWithWebRequestInstalled() const { - return webrequest_adblock_plus_; - } - bool IsOtherExtensionWithWebRequestInstalled() const { - return webrequest_other_; - } - void OnExtensionResponse(int request_id, bool success, const base::ListValue& response, @@ -136,13 +125,12 @@ class Dispatcher : public content::RenderProcessObserver { const std::string& event_name) const; // Shared implementation of the various MessageInvoke IPCs. - void InvokeModuleSystemMethod( - content::RenderView* render_view, - const std::string& extension_id, - const std::string& module_name, - const std::string& function_name, - const base::ListValue& args, - bool user_gesture); + void InvokeModuleSystemMethod(content::RenderView* render_view, + const std::string& extension_id, + const std::string& module_name, + const std::string& function_name, + const base::ListValue& args, + bool user_gesture); void ClearPortData(int port_id); @@ -150,8 +138,6 @@ class Dispatcher : public content::RenderProcessObserver { friend class ::ChromeRenderViewTest; FRIEND_TEST_ALL_PREFIXES(RendererPermissionsPolicyDelegateTest, CannotScriptWebstore); - typedef void (*BindingInstaller)(ModuleSystem* module_system, - v8::Handle<v8::Object> chrome); // RenderProcessObserver implementation: virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE; @@ -159,86 +145,71 @@ class Dispatcher : public content::RenderProcessObserver { virtual void IdleNotification() OVERRIDE; virtual void OnRenderProcessShutdown() OVERRIDE; - void OnSetChannel(int channel); - void OnMessageInvoke(const std::string& extension_id, - const std::string& module_name, - const std::string& function_name, - const base::ListValue& args, - bool user_gesture); + void OnActivateExtension(const std::string& extension_id); + void OnCancelSuspend(const std::string& extension_id); + void OnClearTabSpecificPermissions( + int tab_id, + const std::vector<std::string>& extension_ids); + void OnDeliverMessage(int target_port_id, const Message& message); void OnDispatchOnConnect(int target_port_id, const std::string& channel_name, const base::DictionaryValue& source_tab, const ExtensionMsg_ExternalConnectionInfo& info, const std::string& tls_channel_id); - void OnDeliverMessage(int target_port_id, const Message& message); void OnDispatchOnDisconnect(int port_id, const std::string& error_message); - void OnSetFunctionNames(const std::vector<std::string>& names); - void OnSetSystemFont(const std::string& font_family, - const std::string& font_size); void OnLoaded( const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions); void OnLoadedInternal(scoped_refptr<const Extension> extension); - void OnUnloaded(const std::string& id); + void OnMessageInvoke(const std::string& extension_id, + const std::string& module_name, + const std::string& function_name, + const base::ListValue& args, + bool user_gesture); + void OnSetChannel(int channel); + void OnSetFunctionNames(const std::vector<std::string>& names); void OnSetScriptingWhitelist( const ExtensionsClient::ScriptingWhitelist& extension_ids); - void OnPageActionsUpdated(const std::string& extension_id, - const std::vector<std::string>& page_actions); - void OnActivateExtension(const std::string& extension_id); + void OnSetSystemFont(const std::string& font_family, + const std::string& font_size); + void OnShouldSuspend(const std::string& extension_id, int sequence_id); + void OnSuspend(const std::string& extension_id); + void OnUnloaded(const std::string& id); void OnUpdatePermissions(const ExtensionMsg_UpdatePermissions_Params& params); void OnUpdateTabSpecificPermissions(int page_id, int tab_id, const std::string& extension_id, const URLPatternSet& origin_set); - void OnClearTabSpecificPermissions( - int tab_id, - const std::vector<std::string>& extension_ids); - void OnUpdateUserScripts(base::SharedMemoryHandle table); - void OnUsingWebRequestAPI( - bool adblock, - bool adblock_plus, - bool other_webrequest); - void OnShouldSuspend(const std::string& extension_id, int sequence_id); - void OnSuspend(const std::string& extension_id); - void OnCancelSuspend(const std::string& extension_id); + void OnUpdateUserScripts(base::SharedMemoryHandle scripts); + void OnUsingWebRequestAPI(bool adblock, + bool adblock_plus, + bool other_webrequest); - // Update the list of active extensions that will be reported when we crash. void UpdateActiveExtensions(); // Sets up the host permissions for |extension|. void InitOriginPermissions(const Extension* extension, Feature::Context context_type); - void AddOrRemoveOriginPermissions( - UpdatedExtensionPermissionsInfo::Reason reason, - const Extension* extension, - const URLPatternSet& origins); + void UpdateOriginPermissions(UpdatedExtensionPermissionsInfo::Reason reason, + const Extension* extension, + const URLPatternSet& origins); // Enable custom element whitelist in Apps. void EnableCustomElementWhiteList(); // Adds or removes bindings for every context belonging to |extension_id|, or // or all contexts if |extension_id| is empty. - void AddOrRemoveBindings(const std::string& extension_id); + void UpdateBindings(const std::string& extension_id); + + void UpdateBindingsForContext(ScriptContext* context); + + void RegisterBinding(const std::string& api_name, ScriptContext* context); void RegisterNativeHandlers(ModuleSystem* module_system, ScriptContext* context); - void AddOrRemoveBindingsForContext(ScriptContext* context); - void RegisterBinding(const std::string& api_name, ScriptContext* context); - v8::Handle<v8::Object> GetOrCreateBindObjectIfAvailable( - const std::string& api_name, - std::string* bind_name, - ScriptContext* context); // Inserts static source code into |source_map_|. void PopulateSourceMap(); - // Inserts BindingInstallers into |lazy_bindings_map_|. - void PopulateLazyBindingsMap(); - - // Sets up the bindings for the given api. - void InstallBindings(ModuleSystem* module_system, - v8::Handle<v8::Context> v8_context, - const std::string& api); - // Returns whether the current renderer hosts a platform app. bool IsWithinPlatformApp(); @@ -253,10 +224,19 @@ class Dispatcher : public content::RenderProcessObserver { // Gets |field| from |object| or creates it as an empty object if it doesn't // exist. - v8::Handle<v8::Object> GetOrCreateObject(v8::Handle<v8::Object> object, + v8::Handle<v8::Object> GetOrCreateObject(const v8::Handle<v8::Object>& object, const std::string& field, v8::Isolate* isolate); + v8::Handle<v8::Object> GetOrCreateBindObjectIfAvailable( + const std::string& api_name, + std::string* bind_name, + ScriptContext* context); + + // The delegate for this dispatcher. Not owned, but must extend beyond the + // Dispatcher's own lifetime. + DispatcherDelegate* delegate_; + // True if this renderer is running extensions. bool is_extension_process_; @@ -273,10 +253,10 @@ class Dispatcher : public content::RenderProcessObserver { // There is zero or one for each v8 context. ScriptContextSet script_context_set_; - scoped_ptr<UserScriptSlave> user_script_slave_; - scoped_ptr<ContentWatcher> content_watcher_; + scoped_ptr<UserScriptSlave> user_script_slave_; + // Same as above, but on a longer timer and will run even if the process is // not idle, to ensure that IdleHandle gets called eventually. scoped_ptr<base::RepeatingTimer<content::RenderThread> > forced_idle_timer_; @@ -287,24 +267,11 @@ class Dispatcher : public content::RenderProcessObserver { // The extensions and apps that are active in this process. std::set<std::string> active_extension_ids_; - // True once WebKit has been initialized (and it is therefore safe to poke). - bool is_webkit_initialized_; - - // Status of webrequest usage for known extensions. - // TODO(mpcomplete): remove. http://crbug.com/100411 - bool webrequest_adblock_; - bool webrequest_adblock_plus_; - bool webrequest_other_; - ResourceBundleSourceMap source_map_; // Cache for the v8 representation of extension API schemas. scoped_ptr<V8SchemaRegistry> v8_schema_registry_; - // Bindings that are defined lazily and have BindingInstallers to install - // them. - std::map<std::string, BindingInstaller> lazy_bindings_map_; - // Sends API requests to the extension host. scoped_ptr<RequestSender> request_sender_; @@ -315,9 +282,12 @@ class Dispatcher : public content::RenderProcessObserver { // Mapping of port IDs to tabs. If there is no tab, the value would be -1. std::map<int, int> port_to_tab_id_map_; + // True once WebKit has been initialized (and it is therefore safe to poke). + bool is_webkit_initialized_; + DISALLOW_COPY_AND_ASSIGN(Dispatcher); }; } // namespace extensions -#endif // CHROME_RENDERER_EXTENSIONS_DISPATCHER_H_ +#endif // EXTENSIONS_RENDERER_DISPATCHER_H_ diff --git a/extensions/renderer/dispatcher_delegate.h b/extensions/renderer/dispatcher_delegate.h new file mode 100644 index 0000000..13d557f --- /dev/null +++ b/extensions/renderer/dispatcher_delegate.h @@ -0,0 +1,96 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_DISPATCHER_DELEGATE_H +#define EXTENSIONS_RENDERER_DISPATCHER_DELEGATE_H + +#include <set> +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "extensions/common/features/feature.h" +#include "v8/include/v8.h" + +namespace blink { +class WebFrame; +} + +namespace extensions { +class Dispatcher; +class Extension; +class ModuleSystem; +class ResourceBundleSourceMap; +class ScriptContext; +class URLPatternSet; + +// Base class and default implementation for an extensions::Dispacher delegate. +// DispatcherDelegate can be used to override and extend the behavior of the +// extensions system's renderer side. +class DispatcherDelegate { + public: + virtual ~DispatcherDelegate() {} + + // Creates a new ScriptContext for a given v8 context. + virtual scoped_ptr<ScriptContext> CreateScriptContext( + const v8::Handle<v8::Context>& v8_context, + blink::WebFrame* frame, + const Extension* extension, + Feature::Context context_type) = 0; + + // Initializes origin permissions for a newly created extension context. + virtual void InitOriginPermissions(const Extension* extension, + Feature::Context context_type) {} + + // Includes additional native handlers in a given ModuleSystem. + virtual void RegisterNativeHandlers(Dispatcher* dispatcher, + ModuleSystem* module_system, + ScriptContext* context) {} + + // Includes additional source resources into the resource map. + virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) {} + + // Requires additional modules within an extension context's module system. + virtual void RequireAdditionalModules(ModuleSystem* module_system, + const Extension* extension, + Feature::Context context_type, + bool is_within_platform_app) {} + + // Allows the delegate to respond to an updated set of active extensions in + // the Dispatcher. + virtual void OnActiveExtensionsUpdated( + const std::set<std::string>& extension_ids) {} + + // Sets the current Chrome channel. + // TODO(rockot): This doesn't belong in a generic extensions system interface. + // See http://crbug.com/368431. + virtual void SetChannel(int channel) {} + + // Clears extension permissions specific to a given tab. + // TODO(rockot): This doesn't belong in a generic extensions system interface. + // See http://crbug.com/368431. + virtual void ClearTabSpecificPermissions( + const extensions::Dispatcher* dispatcher, + int tab_id, + const std::vector<std::string>& extension_ids) {} + + // Updates extension permissions specific to a given tab. + // TODO(rockot): This doesn't belong in a generic extensions system interface. + // See http://crbug.com/368431. + virtual void UpdateTabSpecificPermissions( + const extensions::Dispatcher* dispatcher, + int page_id, + int tab_id, + const std::string& extension_id, + const extensions::URLPatternSet& origin_set) {} + + // Allows the delegate to respond to reports from the browser about WebRequest + // API usage from within this process. + virtual void HandleWebRequestAPIUsage(bool adblock, + bool adblock_plus, + bool other_webrequest) {} +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_DISPATCHER_DELEGATE_H diff --git a/extensions/renderer/event_bindings.cc b/extensions/renderer/event_bindings.cc index 9446595..0ebd08e 100644 --- a/extensions/renderer/event_bindings.cc +++ b/extensions/renderer/event_bindings.cc @@ -13,7 +13,6 @@ #include "base/bind.h" #include "base/lazy_instance.h" #include "base/memory/scoped_ptr.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "chrome/renderer/extensions/extension_helper.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" @@ -23,6 +22,7 @@ #include "extensions/common/extension_messages.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/value_counter.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/object_backed_native_handler.h" #include "url/gurl.h" #include "v8/include/v8.h" diff --git a/extensions/renderer/extensions_renderer_client.h b/extensions/renderer/extensions_renderer_client.h index 6b06b6c..ae4a31b 100644 --- a/extensions/renderer/extensions_renderer_client.h +++ b/extensions/renderer/extensions_renderer_client.h @@ -9,9 +9,6 @@ class ResourceBundleSourceMap; namespace extensions { -class ModuleSystem; -class ScriptContext; - // Interface to allow the extensions module to make render-process-specific // queries of the embedder. Should be Set() once in the render process. // @@ -30,13 +27,6 @@ class ExtensionsRendererClient { // (third_party/WebKit/public/web/WebFrame.h) for additional context. virtual int GetLowestIsolatedWorldId() const = 0; - // Registers additional native C++ code handlers for JS API functions. - virtual void RegisterNativeHandlers(ModuleSystem* module_system, - ScriptContext* context) = 0; - - // Registers additional JS source code resources for API implementations. - virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) = 0; - // Returns the single instance of |this|. static ExtensionsRendererClient* Get(); diff --git a/extensions/renderer/lazy_background_page_native_handler.cc b/extensions/renderer/lazy_background_page_native_handler.cc new file mode 100644 index 0000000..b7c72cd --- /dev/null +++ b/extensions/renderer/lazy_background_page_native_handler.cc @@ -0,0 +1,62 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/renderer/lazy_background_page_native_handler.h" + +#include "base/bind.h" +#include "chrome/renderer/extensions/extension_helper.h" +#include "content/public/renderer/render_view.h" +#include "extensions/common/extension_messages.h" +#include "extensions/common/manifest_handlers/background_info.h" +#include "extensions/renderer/script_context.h" + +namespace extensions { + +LazyBackgroundPageNativeHandler::LazyBackgroundPageNativeHandler( + ScriptContext* context) + : ObjectBackedNativeHandler(context) { + RouteFunction( + "IncrementKeepaliveCount", + base::Bind(&LazyBackgroundPageNativeHandler::IncrementKeepaliveCount, + base::Unretained(this))); + RouteFunction( + "DecrementKeepaliveCount", + base::Bind(&LazyBackgroundPageNativeHandler::DecrementKeepaliveCount, + base::Unretained(this))); +} + +void LazyBackgroundPageNativeHandler::IncrementKeepaliveCount( + const v8::FunctionCallbackInfo<v8::Value>& args) { + if (!context()) + return; + content::RenderView* render_view = context()->GetRenderView(); + if (IsContextLazyBackgroundPage(render_view, context()->extension())) { + render_view->Send(new ExtensionHostMsg_IncrementLazyKeepaliveCount( + render_view->GetRoutingID())); + } +} + +void LazyBackgroundPageNativeHandler::DecrementKeepaliveCount( + const v8::FunctionCallbackInfo<v8::Value>& args) { + if (!context()) + return; + content::RenderView* render_view = context()->GetRenderView(); + if (IsContextLazyBackgroundPage(render_view, context()->extension())) { + render_view->Send(new ExtensionHostMsg_DecrementLazyKeepaliveCount( + render_view->GetRoutingID())); + } +} + +bool LazyBackgroundPageNativeHandler::IsContextLazyBackgroundPage( + content::RenderView* render_view, + const Extension* extension) { + if (!render_view) + return false; + + ExtensionHelper* helper = ExtensionHelper::Get(render_view); + return (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && + helper->view_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); +} + +} // namespace extensions diff --git a/extensions/renderer/lazy_background_page_native_handler.h b/extensions/renderer/lazy_background_page_native_handler.h new file mode 100644 index 0000000..5ee43b2 --- /dev/null +++ b/extensions/renderer/lazy_background_page_native_handler.h @@ -0,0 +1,31 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_LAZY_BACKGROUND_PAGE_NATIVE_HANDLER_H_ +#define EXTENSIONS_RENDERER_LAZY_BACKGROUND_PAGE_NATIVE_HANDLER_H_ + +#include "extensions/renderer/object_backed_native_handler.h" + +namespace content { +class RenderView; +} + +namespace extensions { + +class Extension; + +class LazyBackgroundPageNativeHandler : public ObjectBackedNativeHandler { + public: + explicit LazyBackgroundPageNativeHandler(ScriptContext* context); + void IncrementKeepaliveCount(const v8::FunctionCallbackInfo<v8::Value>& args); + void DecrementKeepaliveCount(const v8::FunctionCallbackInfo<v8::Value>& args); + + private: + bool IsContextLazyBackgroundPage(content::RenderView* render_view, + const Extension* extension); +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_LAZY_BACKGROUND_PAGE_NATIVE_HANDLER_H_ diff --git a/chrome/renderer/extensions/messaging_bindings.cc b/extensions/renderer/messaging_bindings.cc index 1590724..281f276 100644 --- a/chrome/renderer/extensions/messaging_bindings.cc +++ b/extensions/renderer/messaging_bindings.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/extensions/messaging_bindings.h" +#include "extensions/renderer/messaging_bindings.h" #include <map> #include <string> @@ -13,14 +13,13 @@ #include "base/lazy_instance.h" #include "base/message_loop/message_loop.h" #include "base/values.h" -#include "chrome/common/extensions/manifest_handlers/externally_connectable.h" -#include "chrome/common/url_constants.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/v8_value_converter.h" #include "extensions/common/api/messaging/message.h" #include "extensions/common/extension_messages.h" +#include "extensions/common/manifest_handlers/externally_connectable.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/event_bindings.h" #include "extensions/renderer/object_backed_native_handler.h" #include "extensions/renderer/scoped_persistent.h" @@ -58,12 +57,11 @@ struct ExtensionData { std::map<int, PortData> ports; // port ID -> data }; -base::LazyInstance<ExtensionData> g_extension_data = - LAZY_INSTANCE_INITIALIZER; +base::LazyInstance<ExtensionData> g_extension_data = LAZY_INSTANCE_INITIALIZER; bool HasPortData(int port_id) { return g_extension_data.Get().ports.find(port_id) != - g_extension_data.Get().ports.end(); + g_extension_data.Get().ports.end(); } ExtensionData::PortData& GetPortData(int port_id) { @@ -82,17 +80,21 @@ class ExtensionImpl : public ObjectBackedNativeHandler { public: ExtensionImpl(Dispatcher* dispatcher, ScriptContext* context) : ObjectBackedNativeHandler(context), dispatcher_(dispatcher) { - RouteFunction("CloseChannel", + RouteFunction( + "CloseChannel", base::Bind(&ExtensionImpl::CloseChannel, base::Unretained(this))); - RouteFunction("PortAddRef", + RouteFunction( + "PortAddRef", base::Bind(&ExtensionImpl::PortAddRef, base::Unretained(this))); - RouteFunction("PortRelease", + RouteFunction( + "PortRelease", base::Bind(&ExtensionImpl::PortRelease, base::Unretained(this))); - RouteFunction("PostMessage", + RouteFunction( + "PostMessage", base::Bind(&ExtensionImpl::PostMessage, base::Unretained(this))); // TODO(fsamuel, kalman): Move BindToGC out of messaging natives. RouteFunction("BindToGC", - base::Bind(&ExtensionImpl::BindToGC, base::Unretained(this))); + base::Bind(&ExtensionImpl::BindToGC, base::Unretained(this))); } virtual ~ExtensionImpl() {} @@ -116,9 +118,7 @@ class ExtensionImpl : public ObjectBackedNativeHandler { return; // Arguments are (int32 port_id, string message). - CHECK(args.Length() == 2 && - args[0]->IsInt32() && - args[1]->IsString()); + CHECK(args.Length() == 2 && args[0]->IsInt32() && args[1]->IsString()); int port_id = args[0]->Int32Value(); if (!HasPortData(port_id)) { @@ -303,38 +303,36 @@ void MessagingBindings::DispatchOnConnect( } v8::Handle<v8::Value> arguments[] = { - // portId - v8::Integer::New(isolate, target_port_id), - // channelName - v8::String::NewFromUtf8(isolate, - channel_name.c_str(), - v8::String::kNormalString, - channel_name.size()), - // sourceTab - tab, - // sourceExtensionId - v8::String::NewFromUtf8(isolate, - source_extension_id.c_str(), - v8::String::kNormalString, - source_extension_id.size()), - // targetExtensionId - v8::String::NewFromUtf8(isolate, - target_extension_id.c_str(), - v8::String::kNormalString, - target_extension_id.size()), - // sourceUrl - v8::String::NewFromUtf8(isolate, - source_url_spec.c_str(), - v8::String::kNormalString, - source_url_spec.size()), - // tlsChannelId - tls_channel_id_value, + // portId + v8::Integer::New(isolate, target_port_id), + // channelName + v8::String::NewFromUtf8(isolate, + channel_name.c_str(), + v8::String::kNormalString, + channel_name.size()), + // sourceTab + tab, + // sourceExtensionId + v8::String::NewFromUtf8(isolate, + source_extension_id.c_str(), + v8::String::kNormalString, + source_extension_id.size()), + // targetExtensionId + v8::String::NewFromUtf8(isolate, + target_extension_id.c_str(), + v8::String::kNormalString, + target_extension_id.size()), + // sourceUrl + v8::String::NewFromUtf8(isolate, + source_url_spec.c_str(), + v8::String::kNormalString, + source_url_spec.size()), + // tlsChannelId + tls_channel_id_value, }; v8::Handle<v8::Value> retval = (*it)->module_system()->CallModuleMethod( - "messaging", - "dispatchOnConnect", - arraysize(arguments), arguments); + "messaging", "dispatchOnConnect", arraysize(arguments), arguments); if (retval.IsEmpty()) { LOG(ERROR) << "Empty return value from dispatchOnConnect."; @@ -348,9 +346,8 @@ void MessagingBindings::DispatchOnConnect( // If we didn't create a port, notify the other end of the channel (treat it // as a disconnect). if (!port_created) { - content::RenderThread::Get()->Send( - new ExtensionHostMsg_CloseChannel( - target_port_id, kReceivingEndDoesntExistError)); + content::RenderThread::Get()->Send(new ExtensionHostMsg_CloseChannel( + target_port_id, kReceivingEndDoesntExistError)); } } @@ -389,9 +386,7 @@ void MessagingBindings::DeliverMessage( v8::Handle<v8::Value> port_id_handle = v8::Integer::New(isolate, target_port_id); v8::Handle<v8::Value> has_port = (*it)->module_system()->CallModuleMethod( - "messaging", - "hasPort", - 1, &port_id_handle); + "messaging", "hasPort", 1, &port_id_handle); CHECK(!has_port.IsEmpty()); if (!has_port->BooleanValue()) @@ -403,9 +398,8 @@ void MessagingBindings::DeliverMessage( v8::String::kNormalString, message.data.size())); arguments.push_back(port_id_handle); - (*it)->module_system()->CallModuleMethod("messaging", - "dispatchOnMessage", - &arguments); + (*it)->module_system()->CallModuleMethod( + "messaging", "dispatchOnMessage", &arguments); } } @@ -439,9 +433,8 @@ void MessagingBindings::DispatchOnDisconnect( } else { arguments.push_back(v8::Null(isolate)); } - (*it)->module_system()->CallModuleMethod("messaging", - "dispatchOnDisconnect", - &arguments); + (*it)->module_system()->CallModuleMethod( + "messaging", "dispatchOnDisconnect", &arguments); } } diff --git a/chrome/renderer/extensions/messaging_bindings.h b/extensions/renderer/messaging_bindings.h index ab3c093..721b434 100644 --- a/chrome/renderer/extensions/messaging_bindings.h +++ b/extensions/renderer/messaging_bindings.h @@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_EXTENSIONS_MESSAGING_BINDINGS_H_ -#define CHROME_RENDERER_EXTENSIONS_MESSAGING_BINDINGS_H_ +#ifndef EXTENSIONS_RENDERER_MESSAGING_BINDINGS_H_ +#define EXTENSIONS_RENDERER_MESSAGING_BINDINGS_H_ #include <string> @@ -68,4 +68,4 @@ class MessagingBindings { } // namespace extensions -#endif // CHROME_RENDERER_EXTENSIONS_MESSAGING_BINDINGS_H_ +#endif // EXTENSIONS_RENDERER_MESSAGING_BINDINGS_H_ diff --git a/extensions/renderer/print_native_handler.cc b/extensions/renderer/print_native_handler.cc new file mode 100644 index 0000000..1e83b0e --- /dev/null +++ b/extensions/renderer/print_native_handler.cc @@ -0,0 +1,32 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/renderer/print_native_handler.h" + +#include <string> + +#include "base/bind.h" +#include "base/strings/string_util.h" + +namespace extensions { + +PrintNativeHandler::PrintNativeHandler(ScriptContext* context) + : ObjectBackedNativeHandler(context) { + RouteFunction("Print", + base::Bind(&PrintNativeHandler::Print, base::Unretained(this))); +} + +void PrintNativeHandler::Print( + const v8::FunctionCallbackInfo<v8::Value>& args) { + if (args.Length() < 1) + return; + + std::vector<std::string> components; + for (int i = 0; i < args.Length(); ++i) + components.push_back(*v8::String::Utf8Value(args[i]->ToString())); + + LOG(ERROR) << JoinString(components, ','); +} + +} // namespace extensions diff --git a/extensions/renderer/print_native_handler.h b/extensions/renderer/print_native_handler.h new file mode 100644 index 0000000..b2e5d37 --- /dev/null +++ b/extensions/renderer/print_native_handler.h @@ -0,0 +1,21 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_PRINT_NATIVE_HANDLER_H_ +#define EXTENSIONS_RENDERER_PRINT_NATIVE_HANDLER_H_ + +#include "extensions/renderer/object_backed_native_handler.h" + +namespace extensions { + +class PrintNativeHandler : public ObjectBackedNativeHandler { + public: + explicit PrintNativeHandler(ScriptContext* context); + + void Print(const v8::FunctionCallbackInfo<v8::Value>& args); +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_PRINT_NATIVE_HANDLER_H_ diff --git a/extensions/renderer/process_info_native_handler.cc b/extensions/renderer/process_info_native_handler.cc new file mode 100644 index 0000000..3c7ba78 --- /dev/null +++ b/extensions/renderer/process_info_native_handler.cc @@ -0,0 +1,86 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/renderer/process_info_native_handler.h" + +#include "base/bind.h" +#include "base/command_line.h" +#include "extensions/renderer/script_context.h" + +namespace extensions { + +ProcessInfoNativeHandler::ProcessInfoNativeHandler( + ScriptContext* context, + const std::string& extension_id, + const std::string& context_type, + bool is_incognito_context, + int manifest_version, + bool send_request_disabled) + : ObjectBackedNativeHandler(context), + extension_id_(extension_id), + context_type_(context_type), + is_incognito_context_(is_incognito_context), + manifest_version_(manifest_version), + send_request_disabled_(send_request_disabled) { + RouteFunction("GetExtensionId", + base::Bind(&ProcessInfoNativeHandler::GetExtensionId, + base::Unretained(this))); + RouteFunction("GetContextType", + base::Bind(&ProcessInfoNativeHandler::GetContextType, + base::Unretained(this))); + RouteFunction("InIncognitoContext", + base::Bind(&ProcessInfoNativeHandler::InIncognitoContext, + base::Unretained(this))); + RouteFunction("GetManifestVersion", + base::Bind(&ProcessInfoNativeHandler::GetManifestVersion, + base::Unretained(this))); + RouteFunction("IsSendRequestDisabled", + base::Bind(&ProcessInfoNativeHandler::IsSendRequestDisabled, + base::Unretained(this))); + RouteFunction( + "HasSwitch", + base::Bind(&ProcessInfoNativeHandler::HasSwitch, base::Unretained(this))); +} + +void ProcessInfoNativeHandler::GetExtensionId( + const v8::FunctionCallbackInfo<v8::Value>& args) { + args.GetReturnValue().Set( + v8::String::NewFromUtf8(args.GetIsolate(), extension_id_.c_str())); +} + +void ProcessInfoNativeHandler::GetContextType( + const v8::FunctionCallbackInfo<v8::Value>& args) { + args.GetReturnValue().Set( + v8::String::NewFromUtf8(args.GetIsolate(), context_type_.c_str())); +} + +void ProcessInfoNativeHandler::InIncognitoContext( + const v8::FunctionCallbackInfo<v8::Value>& args) { + args.GetReturnValue().Set(is_incognito_context_); +} + +void ProcessInfoNativeHandler::GetManifestVersion( + const v8::FunctionCallbackInfo<v8::Value>& args) { + args.GetReturnValue().Set(static_cast<int32_t>(manifest_version_)); +} + +void ProcessInfoNativeHandler::IsSendRequestDisabled( + const v8::FunctionCallbackInfo<v8::Value>& args) { + if (send_request_disabled_) { + args.GetReturnValue().Set(v8::String::NewFromUtf8( + args.GetIsolate(), + "sendRequest and onRequest are obsolete." + " Please use sendMessage and onMessage instead.")); + } +} + +void ProcessInfoNativeHandler::HasSwitch( + const v8::FunctionCallbackInfo<v8::Value>& args) { + CHECK(args.Length() == 1 && args[0]->IsString()); + bool has_switch = CommandLine::ForCurrentProcess()->HasSwitch( + *v8::String::Utf8Value(args[0])); + args.GetReturnValue().Set(v8::Boolean::New(args.GetIsolate(), has_switch)); +} + +} // namespace extensions diff --git a/extensions/renderer/process_info_native_handler.h b/extensions/renderer/process_info_native_handler.h new file mode 100644 index 0000000..1f25269 --- /dev/null +++ b/extensions/renderer/process_info_native_handler.h @@ -0,0 +1,40 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_PROCESS_INFO_NATIVE_HANDLER_H_ +#define EXTENSIONS_RENDERER_PROCESS_INFO_NATIVE_HANDLER_H_ + +#include <string> + +#include "extensions/renderer/object_backed_native_handler.h" + +namespace extensions { + +class ProcessInfoNativeHandler : public ObjectBackedNativeHandler { + public: + ProcessInfoNativeHandler(ScriptContext* context, + const std::string& extension_id, + const std::string& context_type, + bool is_incognito_context, + int manifest_version, + bool send_request_disabled); + + private: + void GetExtensionId(const v8::FunctionCallbackInfo<v8::Value>& args); + void GetContextType(const v8::FunctionCallbackInfo<v8::Value>& args); + void InIncognitoContext(const v8::FunctionCallbackInfo<v8::Value>& args); + void GetManifestVersion(const v8::FunctionCallbackInfo<v8::Value>& args); + void IsSendRequestDisabled(const v8::FunctionCallbackInfo<v8::Value>& args); + void HasSwitch(const v8::FunctionCallbackInfo<v8::Value>& args); + + std::string extension_id_; + std::string context_type_; + bool is_incognito_context_; + int manifest_version_; + bool send_request_disabled_; +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_PROCESS_INFO_NATIVE_HANDLER_H_ diff --git a/extensions/renderer/request_sender.cc b/extensions/renderer/request_sender.cc index 09ffa8f..60c77c6 100644 --- a/extensions/renderer/request_sender.cc +++ b/extensions/renderer/request_sender.cc @@ -5,9 +5,9 @@ #include "extensions/renderer/request_sender.h" #include "base/values.h" -#include "chrome/renderer/extensions/dispatcher.h" #include "content/public/renderer/render_view.h" #include "extensions/common/extension_messages.h" +#include "extensions/renderer/dispatcher.h" #include "extensions/renderer/script_context.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrame.h" diff --git a/chrome/renderer/resource_bundle_source_map.cc b/extensions/renderer/resource_bundle_source_map.cc index 6a7ff02..954a6d7 100644 --- a/chrome/renderer/resource_bundle_source_map.cc +++ b/extensions/renderer/resource_bundle_source_map.cc @@ -1,11 +1,13 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/resource_bundle_source_map.h" +#include "extensions/renderer/resource_bundle_source_map.h" #include "ui/base/resource/resource_bundle.h" +namespace extensions { + ResourceBundleSourceMap::ResourceBundleSourceMap( const ui::ResourceBundle* resource_bundle) : resource_bundle_(resource_bundle) { @@ -41,3 +43,5 @@ v8::Handle<v8::String> ResourceBundleSourceMap::ConvertString( return v8::String::NewExternal( isolate, new StaticV8ExternalAsciiStringResource(string)); } + +} // namespace extensions diff --git a/chrome/renderer/resource_bundle_source_map.h b/extensions/renderer/resource_bundle_source_map.h index fddea7c..89e8b1d 100644 --- a/chrome/renderer/resource_bundle_source_map.h +++ b/extensions/renderer/resource_bundle_source_map.h @@ -1,24 +1,26 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_ -#define CHROME_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_ +#ifndef EXTENSIONS_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_ +#define EXTENSIONS_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_ + +#include <map> +#include <string> #include "base/compiler_specific.h" #include "base/memory/linked_ptr.h" #include "base/strings/string_piece.h" -#include "chrome/renderer/static_v8_external_string_resource.h" #include "extensions/renderer/module_system.h" +#include "extensions/renderer/static_v8_external_ascii_string_resource.h" #include "v8/include/v8.h" -#include <map> -#include <string> - namespace ui { - class ResourceBundle; +class ResourceBundle; } +namespace extensions { + class ResourceBundleSourceMap : public extensions::ModuleSystem::SourceMap { public: explicit ResourceBundleSourceMap(const ui::ResourceBundle* resource_bundle); @@ -38,4 +40,6 @@ class ResourceBundleSourceMap : public extensions::ModuleSystem::SourceMap { std::map<std::string, int> resource_id_map_; }; -#endif // CHROME_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_ +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_ diff --git a/chrome/renderer/extensions/runtime_custom_bindings.cc b/extensions/renderer/runtime_custom_bindings.cc index bc36d78..7ed2ad2 100644 --- a/chrome/renderer/extensions/runtime_custom_bindings.cc +++ b/extensions/renderer/runtime_custom_bindings.cc @@ -1,13 +1,12 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/extensions/runtime_custom_bindings.h" +#include "extensions/renderer/runtime_custom_bindings.h" #include "base/bind.h" #include "base/memory/scoped_ptr.h" #include "base/values.h" -#include "chrome/renderer/extensions/api_activity_logger.h" #include "chrome/renderer/extensions/extension_helper.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/v8_value_converter.h" @@ -16,6 +15,7 @@ #include "extensions/common/features/feature.h" #include "extensions/common/features/feature_provider.h" #include "extensions/common/manifest.h" +#include "extensions/renderer/api_activity_logger.h" #include "extensions/renderer/script_context.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrame.h" @@ -27,9 +27,9 @@ namespace extensions { RuntimeCustomBindings::RuntimeCustomBindings(ScriptContext* context) : ObjectBackedNativeHandler(context) { - RouteFunction("GetManifest", - base::Bind(&RuntimeCustomBindings::GetManifest, - base::Unretained(this))); + RouteFunction( + "GetManifest", + base::Bind(&RuntimeCustomBindings::GetManifest, base::Unretained(this))); RouteFunction("OpenChannelToExtension", base::Bind(&RuntimeCustomBindings::OpenChannelToExtension, base::Unretained(this))); @@ -41,7 +41,8 @@ RuntimeCustomBindings::RuntimeCustomBindings(ScriptContext* context) base::Unretained(this))); } -RuntimeCustomBindings::~RuntimeCustomBindings() {} +RuntimeCustomBindings::~RuntimeCustomBindings() { +} void RuntimeCustomBindings::OpenChannelToExtension( const v8::FunctionCallbackInfo<v8::Value>& args) { @@ -69,9 +70,12 @@ void RuntimeCustomBindings::OpenChannelToExtension( bool include_tls_channel_id = args.Length() > 2 ? args[2]->BooleanValue() : false; int port_id = -1; - renderview->Send(new ExtensionHostMsg_OpenChannelToExtension( - renderview->GetRoutingID(), info, channel_name, include_tls_channel_id, - &port_id)); + renderview->Send( + new ExtensionHostMsg_OpenChannelToExtension(renderview->GetRoutingID(), + info, + channel_name, + include_tls_channel_id, + &port_id)); args.GetReturnValue().Set(static_cast<int32_t>(port_id)); } @@ -94,19 +98,14 @@ void RuntimeCustomBindings::OpenChannelToNativeApp( return; // The Javascript code should validate/fill the arguments. - CHECK(args.Length() >= 2 && - args[0]->IsString() && - args[1]->IsString()); + CHECK(args.Length() >= 2 && args[0]->IsString() && args[1]->IsString()); std::string extension_id = *v8::String::Utf8Value(args[0]->ToString()); std::string native_app_name = *v8::String::Utf8Value(args[1]->ToString()); int port_id = -1; renderview->Send(new ExtensionHostMsg_OpenChannelToNativeApp( - renderview->GetRoutingID(), - extension_id, - native_app_name, - &port_id)); + renderview->GetRoutingID(), extension_id, native_app_name, &port_id)); args.GetReturnValue().Set(static_cast<int32_t>(port_id)); } @@ -115,9 +114,8 @@ void RuntimeCustomBindings::GetManifest( CHECK(context()->extension()); scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); - args.GetReturnValue().Set( - converter->ToV8Value(context()->extension()->manifest()->value(), - context()->v8_context())); + args.GetReturnValue().Set(converter->ToV8Value( + context()->extension()->manifest()->value(), context()->v8_context())); } void RuntimeCustomBindings::GetExtensionViews( diff --git a/chrome/renderer/extensions/runtime_custom_bindings.h b/extensions/renderer/runtime_custom_bindings.h index ce2ba03..70f4d03 100644 --- a/chrome/renderer/extensions/runtime_custom_bindings.h +++ b/extensions/renderer/runtime_custom_bindings.h @@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_EXTENSIONS_RUNTIME_CUSTOM_BINDINGS_H_ -#define CHROME_RENDERER_EXTENSIONS_RUNTIME_CUSTOM_BINDINGS_H_ +#ifndef EXTENSIONS_RENDERER_RUNTIME_CUSTOM_BINDINGS_H_ +#define EXTENSIONS_RENDERER_RUNTIME_CUSTOM_BINDINGS_H_ #include "base/compiler_specific.h" #include "extensions/renderer/object_backed_native_handler.h" @@ -31,4 +31,4 @@ class RuntimeCustomBindings : public ObjectBackedNativeHandler { } // namespace extensions -#endif // CHROME_RENDERER_EXTENSIONS_RUNTIME_CUSTOM_BINDINGS_H_ +#endif // EXTENSIONS_RENDERER_RUNTIME_CUSTOM_BINDINGS_H_ diff --git a/extensions/renderer/script_context.cc b/extensions/renderer/script_context.cc index 77f72aa..33a9413 100644 --- a/extensions/renderer/script_context.cc +++ b/extensions/renderer/script_context.cc @@ -24,7 +24,7 @@ using content::V8ValueConverter; namespace extensions { -ScriptContext::ScriptContext(v8::Handle<v8::Context> v8_context, +ScriptContext::ScriptContext(const v8::Handle<v8::Context>& v8_context, blink::WebFrame* web_frame, const Extension* extension, Feature::Context context_type) diff --git a/extensions/renderer/script_context.h b/extensions/renderer/script_context.h index c2cbb04..5cc137e 100644 --- a/extensions/renderer/script_context.h +++ b/extensions/renderer/script_context.h @@ -30,7 +30,7 @@ class Extension; // Extensions wrapper for a v8 context. class ScriptContext : public RequestSender::Source { public: - ScriptContext(v8::Handle<v8::Context> context, + ScriptContext(const v8::Handle<v8::Context>& context, blink::WebFrame* frame, const Extension* extension, Feature::Context context_type); diff --git a/chrome/renderer/static_v8_external_string_resource.cc b/extensions/renderer/static_v8_external_ascii_string_resource.cc index 4395ffc..5d64d2e 100644 --- a/chrome/renderer/static_v8_external_string_resource.cc +++ b/extensions/renderer/static_v8_external_ascii_string_resource.cc @@ -1,8 +1,10 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/static_v8_external_string_resource.h" +#include "extensions/renderer/static_v8_external_ascii_string_resource.h" + +namespace extensions { StaticV8ExternalAsciiStringResource::StaticV8ExternalAsciiStringResource( const base::StringPiece& buffer) @@ -19,3 +21,5 @@ const char* StaticV8ExternalAsciiStringResource::data() const { size_t StaticV8ExternalAsciiStringResource::length() const { return buffer_.length(); } + +} // namespace extensions diff --git a/chrome/renderer/static_v8_external_string_resource.h b/extensions/renderer/static_v8_external_ascii_string_resource.h index 6459622..da02650 100644 --- a/chrome/renderer/static_v8_external_string_resource.h +++ b/extensions/renderer/static_v8_external_ascii_string_resource.h @@ -1,14 +1,16 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_EXTENSIONS_STATIC_V8_EXTERNAL_STRING_RESOURCE_H_ -#define CHROME_RENDERER_EXTENSIONS_STATIC_V8_EXTERNAL_STRING_RESOURCE_H_ +#ifndef EXTENSIONS_RENDERER_STATIC_V8_EXTERNAL_ASCII_STRING_RESOURCE_H_ +#define EXTENSIONS_RENDERER_STATIC_V8_EXTERNAL_ASCII_STRING_RESOURCE_H_ #include "base/compiler_specific.h" #include "base/strings/string_piece.h" #include "v8/include/v8.h" +namespace extensions { + // A very simple implementation of v8::ExternalAsciiStringResource that just // wraps a buffer. The buffer must outlive the v8 runtime instance this resource // is used in. @@ -25,4 +27,6 @@ class StaticV8ExternalAsciiStringResource base::StringPiece buffer_; }; -#endif // CHROME_RENDERER_EXTENSIONS_STATIC_V8_EXTERNAL_STRING_RESOURCE_H_ +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_STATIC_V8_EXTERNAL_ASCII_STRING_RESOURCE_H_ diff --git a/extensions/renderer/test_extensions_renderer_client.cc b/extensions/renderer/test_extensions_renderer_client.cc index 4d1c021..5299878 100644 --- a/extensions/renderer/test_extensions_renderer_client.cc +++ b/extensions/renderer/test_extensions_renderer_client.cc @@ -19,13 +19,4 @@ int TestExtensionsRendererClient::GetLowestIsolatedWorldId() const { return 1; } -void TestExtensionsRendererClient::RegisterNativeHandlers( - extensions::ModuleSystem* module_system, - extensions::ScriptContext* context) { -} - -void TestExtensionsRendererClient::PopulateSourceMap( - ResourceBundleSourceMap* source_map) { -} - } // namespace extensions diff --git a/extensions/renderer/test_extensions_renderer_client.h b/extensions/renderer/test_extensions_renderer_client.h index a71d1bb..72550a9 100644 --- a/extensions/renderer/test_extensions_renderer_client.h +++ b/extensions/renderer/test_extensions_renderer_client.h @@ -18,9 +18,6 @@ class TestExtensionsRendererClient : public ExtensionsRendererClient { // ExtensionsRendererClient implementation. virtual bool IsIncognitoProcess() const OVERRIDE; virtual int GetLowestIsolatedWorldId() const OVERRIDE; - virtual void RegisterNativeHandlers(ModuleSystem* module_system, - ScriptContext* context) OVERRIDE; - virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(TestExtensionsRendererClient); diff --git a/extensions/renderer/test_features_native_handler.cc b/extensions/renderer/test_features_native_handler.cc new file mode 100644 index 0000000..6e0423d --- /dev/null +++ b/extensions/renderer/test_features_native_handler.cc @@ -0,0 +1,36 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/renderer/test_features_native_handler.h" + +#include "base/bind.h" +#include "content/public/renderer/v8_value_converter.h" +#include "extensions/common/features/json_feature_provider_source.h" +#include "extensions/renderer/script_context.h" +#include "grit/common_resources.h" +#include "grit/extensions_resources.h" + +namespace extensions { + +TestFeaturesNativeHandler::TestFeaturesNativeHandler(ScriptContext* context) + : ObjectBackedNativeHandler(context) { + RouteFunction("GetAPIFeatures", + base::Bind(&TestFeaturesNativeHandler::GetAPIFeatures, + base::Unretained(this))); +} + +void TestFeaturesNativeHandler::GetAPIFeatures( + const v8::FunctionCallbackInfo<v8::Value>& args) { + JSONFeatureProviderSource source("api"); + // TODO(rockot): Only inlcude extensions features here. Chrome should add + // its own native handler for Chrome features. + source.LoadJSON(IDR_CHROME_EXTENSION_API_FEATURES); + source.LoadJSON(IDR_EXTENSION_API_FEATURES); + scoped_ptr<content::V8ValueConverter> converter( + content::V8ValueConverter::create()); + args.GetReturnValue().Set( + converter->ToV8Value(&source.dictionary(), context()->v8_context())); +} + +} // namespace extensions diff --git a/extensions/renderer/test_features_native_handler.h b/extensions/renderer/test_features_native_handler.h new file mode 100644 index 0000000..2422178 --- /dev/null +++ b/extensions/renderer/test_features_native_handler.h @@ -0,0 +1,22 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_TEST_FEATURES_NATIVE_HANDLER_H_ +#define EXTENSIONS_RENDERER_TEST_FEATURES_NATIVE_HANDLER_H_ + +#include "extensions/renderer/object_backed_native_handler.h" + +namespace extensions { + +class TestFeaturesNativeHandler : public ObjectBackedNativeHandler { + public: + explicit TestFeaturesNativeHandler(ScriptContext* context); + + private: + void GetAPIFeatures(const v8::FunctionCallbackInfo<v8::Value>& args); +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_TEST_FEATURES_NATIVE_HANDLER_H_ diff --git a/extensions/renderer/user_gestures_native_handler.cc b/extensions/renderer/user_gestures_native_handler.cc new file mode 100644 index 0000000..9875ac0 --- /dev/null +++ b/extensions/renderer/user_gestures_native_handler.cc @@ -0,0 +1,52 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/renderer/user_gestures_native_handler.h" + +#include "base/bind.h" +#include "extensions/renderer/script_context.h" +#include "third_party/WebKit/public/web/WebScopedUserGesture.h" +#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" + +namespace extensions { + +UserGesturesNativeHandler::UserGesturesNativeHandler(ScriptContext* context) + : ObjectBackedNativeHandler(context) { + RouteFunction("IsProcessingUserGesture", + base::Bind(&UserGesturesNativeHandler::IsProcessingUserGesture, + base::Unretained(this))); + RouteFunction("RunWithUserGesture", + base::Bind(&UserGesturesNativeHandler::RunWithUserGesture, + base::Unretained(this))); + RouteFunction("RunWithoutUserGesture", + base::Bind(&UserGesturesNativeHandler::RunWithoutUserGesture, + base::Unretained(this))); +} + +void UserGesturesNativeHandler::IsProcessingUserGesture( + const v8::FunctionCallbackInfo<v8::Value>& args) { + args.GetReturnValue().Set(v8::Boolean::New( + args.GetIsolate(), + blink::WebUserGestureIndicator::isProcessingUserGesture())); +} + +void UserGesturesNativeHandler::RunWithUserGesture( + const v8::FunctionCallbackInfo<v8::Value>& args) { + blink::WebScopedUserGesture user_gesture; + CHECK_EQ(args.Length(), 1); + CHECK(args[0]->IsFunction()); + v8::Handle<v8::Value> no_args; + context()->CallFunction(v8::Handle<v8::Function>::Cast(args[0]), 0, &no_args); +} + +void UserGesturesNativeHandler::RunWithoutUserGesture( + const v8::FunctionCallbackInfo<v8::Value>& args) { + blink::WebUserGestureIndicator::consumeUserGesture(); + CHECK_EQ(args.Length(), 1); + CHECK(args[0]->IsFunction()); + v8::Handle<v8::Value> no_args; + context()->CallFunction(v8::Handle<v8::Function>::Cast(args[0]), 0, &no_args); +} + +} // namespace extensions diff --git a/extensions/renderer/user_gestures_native_handler.h b/extensions/renderer/user_gestures_native_handler.h new file mode 100644 index 0000000..fbe15fb --- /dev/null +++ b/extensions/renderer/user_gestures_native_handler.h @@ -0,0 +1,24 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_USER_GESTURES_NATIVE_HANDLER_H_ +#define EXTENSIONS_RENDERER_USER_GESTURES_NATIVE_HANDLER_H_ + +#include "extensions/renderer/object_backed_native_handler.h" + +namespace extensions { + +class UserGesturesNativeHandler : public ObjectBackedNativeHandler { + public: + explicit UserGesturesNativeHandler(ScriptContext* context); + + private: + void IsProcessingUserGesture(const v8::FunctionCallbackInfo<v8::Value>& args); + void RunWithUserGesture(const v8::FunctionCallbackInfo<v8::Value>& args); + void RunWithoutUserGesture(const v8::FunctionCallbackInfo<v8::Value>& args); +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_USER_GESTURES_NATIVE_HANDLER_H_ diff --git a/chrome/renderer/extensions/user_script_slave.cc b/extensions/renderer/user_script_slave.cc index f4fcd40..64cd3f6 100644 --- a/chrome/renderer/extensions/user_script_slave.cc +++ b/extensions/renderer/user_script_slave.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/extensions/user_script_slave.h" +#include "extensions/renderer/user_script_slave.h" #include <map> @@ -13,8 +13,7 @@ #include "base/pickle.h" #include "base/strings/stringprintf.h" #include "base/timer/elapsed_timer.h" -#include "chrome/common/url_constants.h" -#include "chrome/renderer/isolated_world_ids.h" +#include "content/public/common/url_constants.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "extensions/common/extension.h" @@ -63,8 +62,7 @@ int UserScriptSlave::GetIsolatedWorldIdForExtension(const Extension* extension, // world since these are stored per frame, and we might not have used this // isolated world in this frame before. frame->setIsolatedWorldSecurityOrigin( - iter->second, - WebSecurityOrigin::create(extension->url())); + iter->second, WebSecurityOrigin::create(extension->url())); frame->setIsolatedWorldContentSecurityPolicy( iter->second, WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(extension))); @@ -78,8 +76,7 @@ int UserScriptSlave::GetIsolatedWorldIdForExtension(const Extension* extension, // going to have enough extensions for it to matter. isolated_world_ids_[extension->id()] = new_id; frame->setIsolatedWorldSecurityOrigin( - new_id, - WebSecurityOrigin::create(extension->url())); + new_id, WebSecurityOrigin::create(extension->url())); frame->setIsolatedWorldContentSecurityPolicy( new_id, WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(extension))); @@ -89,7 +86,8 @@ int UserScriptSlave::GetIsolatedWorldIdForExtension(const Extension* extension, std::string UserScriptSlave::GetExtensionIdForIsolatedWorld( int isolated_world_id) { for (IsolatedWorldMap::iterator iter = isolated_world_ids_.begin(); - iter != isolated_world_ids_.end(); ++iter) { + iter != isolated_world_ids_.end(); + ++iter) { if (iter->second == isolated_world_id) return iter->first; } @@ -106,7 +104,8 @@ UserScriptSlave::UserScriptSlave(const ExtensionSet* extensions) IDR_GREASEMONKEY_API_JS); } -UserScriptSlave::~UserScriptSlave() {} +UserScriptSlave::~UserScriptSlave() { +} void UserScriptSlave::GetActiveExtensions( std::set<std::string>* extension_ids) { @@ -141,8 +140,7 @@ bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) { // Unpickle scripts. uint64 num_scripts = 0; - Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()), - pickle_size); + Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()), pickle_size); PickleIterator iter(pickle); CHECK(pickle.ReadUInt64(&iter, &num_scripts)); @@ -238,7 +236,7 @@ void UserScriptSlave::InjectScripts(WebFrame* frame, if (script->run_location() == location) { num_scripts += script->js_scripts().size(); for (size_t j = 0; j < script->js_scripts().size(); ++j) { - UserScript::File &file = script->js_scripts()[j]; + UserScript::File& file = script->js_scripts()[j]; std::string content = file.GetContent().as_string(); // We add this dumb function wrapper for standalone user script to @@ -258,7 +256,8 @@ void UserScriptSlave::InjectScripts(WebFrame* frame, // Emulate Greasemonkey API for scripts that were converted to extensions // and "standalone" user scripts. if (script->is_standalone() || script->emulate_greasemonkey()) { - sources.insert(sources.begin(), + sources.insert( + sources.begin(), WebScriptSource(WebString::fromUTF8(api_js_.as_string()))); } @@ -266,13 +265,15 @@ void UserScriptSlave::InjectScripts(WebFrame* frame, base::ElapsedTimer exec_timer; DOMActivityLogger::AttachToWorld(isolated_world_id, extension->id()); - frame->executeScriptInIsolatedWorld( - isolated_world_id, &sources.front(), sources.size(), - EXTENSION_GROUP_CONTENT_SCRIPTS); + frame->executeScriptInIsolatedWorld(isolated_world_id, + &sources.front(), + sources.size(), + EXTENSION_GROUP_CONTENT_SCRIPTS); UMA_HISTOGRAM_TIMES("Extensions.InjectScriptTime", exec_timer.Elapsed()); for (std::vector<WebScriptSource>::const_iterator iter = sources.begin(); - iter != sources.end(); ++iter) { + iter != sources.end(); + ++iter) { extensions_executing_scripts[extension->id()].insert( GURL(iter->url).path()); } diff --git a/chrome/renderer/extensions/user_script_slave.h b/extensions/renderer/user_script_slave.h index 2c7211b..fc3da79 100644 --- a/chrome/renderer/extensions/user_script_slave.h +++ b/extensions/renderer/user_script_slave.h @@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SLAVE_H_ -#define CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SLAVE_H_ +#ifndef EXTENSIONS_RENDERER_USER_SCRIPT_SLAVE_H_ +#define EXTENSIONS_RENDERER_USER_SCRIPT_SLAVE_H_ #include <map> #include <set> @@ -81,4 +81,4 @@ class UserScriptSlave { } // namespace extensions -#endif // CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SLAVE_H_ +#endif // EXTENSIONS_RENDERER_USER_SCRIPT_SLAVE_H_ diff --git a/extensions/renderer/v8_context_native_handler.cc b/extensions/renderer/v8_context_native_handler.cc new file mode 100644 index 0000000..56cd973 --- /dev/null +++ b/extensions/renderer/v8_context_native_handler.cc @@ -0,0 +1,55 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/renderer/v8_context_native_handler.h" + +#include "base/bind.h" +#include "extensions/common/features/feature.h" +#include "extensions/renderer/dispatcher.h" +#include "extensions/renderer/script_context.h" + +namespace extensions { + +V8ContextNativeHandler::V8ContextNativeHandler(ScriptContext* context, + Dispatcher* dispatcher) + : ObjectBackedNativeHandler(context), + context_(context), + dispatcher_(dispatcher) { + RouteFunction("GetAvailability", + base::Bind(&V8ContextNativeHandler::GetAvailability, + base::Unretained(this))); + RouteFunction("GetModuleSystem", + base::Bind(&V8ContextNativeHandler::GetModuleSystem, + base::Unretained(this))); +} + +void V8ContextNativeHandler::GetAvailability( + const v8::FunctionCallbackInfo<v8::Value>& args) { + CHECK_EQ(args.Length(), 1); + v8::Isolate* isolate = args.GetIsolate(); + std::string api_name = *v8::String::Utf8Value(args[0]->ToString()); + Feature::Availability availability = context_->GetAvailability(api_name); + + v8::Handle<v8::Object> ret = v8::Object::New(isolate); + ret->Set(v8::String::NewFromUtf8(isolate, "is_available"), + v8::Boolean::New(isolate, availability.is_available())); + ret->Set(v8::String::NewFromUtf8(isolate, "message"), + v8::String::NewFromUtf8(isolate, availability.message().c_str())); + ret->Set(v8::String::NewFromUtf8(isolate, "result"), + v8::Integer::New(isolate, availability.result())); + args.GetReturnValue().Set(ret); +} + +void V8ContextNativeHandler::GetModuleSystem( + const v8::FunctionCallbackInfo<v8::Value>& args) { + CHECK_EQ(args.Length(), 1); + CHECK(args[0]->IsObject()); + v8::Handle<v8::Context> v8_context = + v8::Handle<v8::Object>::Cast(args[0])->CreationContext(); + ScriptContext* context = + dispatcher_->script_context_set().GetByV8Context(v8_context); + args.GetReturnValue().Set(context->module_system()->NewInstance()); +} + +} // namespace extensions diff --git a/extensions/renderer/v8_context_native_handler.h b/extensions/renderer/v8_context_native_handler.h new file mode 100644 index 0000000..a3a6163 --- /dev/null +++ b/extensions/renderer/v8_context_native_handler.h @@ -0,0 +1,28 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_V8_CONTEXT_NATIVE_HANDLER_H_ +#define EXTENSIONS_RENDERER_V8_CONTEXT_NATIVE_HANDLER_H_ + +#include "extensions/renderer/object_backed_native_handler.h" + +namespace extensions { + +class Dispatcher; + +class V8ContextNativeHandler : public ObjectBackedNativeHandler { + public: + V8ContextNativeHandler(ScriptContext* context, Dispatcher* dispatcher); + + private: + void GetAvailability(const v8::FunctionCallbackInfo<v8::Value>& args); + void GetModuleSystem(const v8::FunctionCallbackInfo<v8::Value>& args); + + ScriptContext* context_; + Dispatcher* dispatcher_; +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_V8_CONTEXT_NATIVE_HANDLER_H_ |