1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h"
7 #include "base/command_line.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "chrome/common/chrome_switches.h"
11 #include "chrome/common/chrome_version_info.h"
12 #include "chrome/common/crash_keys.h"
13 #include "chrome/common/extensions/features/feature_channel.h"
14 #include "chrome/common/url_constants.h"
15 #include "chrome/grit/renderer_resources.h"
16 #include "chrome/renderer/extensions/app_bindings.h"
17 #include "chrome/renderer/extensions/automation_internal_custom_bindings.h"
18 #include "chrome/renderer/extensions/chrome_v8_context.h"
19 #include "chrome/renderer/extensions/enterprise_platform_keys_natives.h"
20 #include "chrome/renderer/extensions/file_browser_handler_custom_bindings.h"
21 #include "chrome/renderer/extensions/file_manager_private_custom_bindings.h"
22 #include "chrome/renderer/extensions/media_galleries_custom_bindings.h"
23 #include "chrome/renderer/extensions/notifications_native_handler.h"
24 #include "chrome/renderer/extensions/page_capture_custom_bindings.h"
25 #include "chrome/renderer/extensions/sync_file_system_custom_bindings.h"
26 #include "chrome/renderer/extensions/tab_finder.h"
27 #include "chrome/renderer/extensions/tabs_custom_bindings.h"
28 #include "chrome/renderer/extensions/webstore_bindings.h"
29 #include "content/public/renderer/render_thread.h"
30 #include "content/public/renderer/render_view.h"
31 #include "extensions/common/extension.h"
32 #include "extensions/common/feature_switch.h"
33 #include "extensions/common/permissions/manifest_permission_set.h"
34 #include "extensions/common/permissions/permission_set.h"
35 #include "extensions/common/permissions/permissions_data.h"
36 #include "extensions/common/switches.h"
37 #include "extensions/renderer/dispatcher.h"
38 #include "extensions/renderer/native_handler.h"
39 #include "extensions/renderer/resource_bundle_source_map.h"
40 #include "extensions/renderer/script_context.h"
41 #include "third_party/WebKit/public/platform/WebString.h"
42 #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
44 #if defined(ENABLE_WEBRTC)
45 #include "chrome/renderer/extensions/cast_streaming_native_handler.h"
48 using extensions::NativeHandler
;
50 ChromeExtensionsDispatcherDelegate::ChromeExtensionsDispatcherDelegate() {
53 ChromeExtensionsDispatcherDelegate::~ChromeExtensionsDispatcherDelegate() {
56 scoped_ptr
<extensions::ScriptContext
>
57 ChromeExtensionsDispatcherDelegate::CreateScriptContext(
58 const v8::Handle
<v8::Context
>& v8_context
,
59 blink::WebFrame
* frame
,
60 const extensions::Extension
* extension
,
61 extensions::Feature::Context context_type
,
62 const extensions::Extension
* effective_extension
,
63 extensions::Feature::Context effective_context_type
) {
64 return scoped_ptr
<extensions::ScriptContext
>(
65 new extensions::ChromeV8Context(v8_context
,
70 effective_context_type
));
73 void ChromeExtensionsDispatcherDelegate::InitOriginPermissions(
74 const extensions::Extension
* extension
,
75 bool is_extension_active
) {
76 // TODO(jstritar): We should try to remove this special case. Also, these
77 // whitelist entries need to be updated when the kManagement permission
79 if (is_extension_active
&&
80 extension
->permissions_data()->HasAPIPermission(
81 extensions::APIPermission::kManagement
)) {
82 blink::WebSecurityPolicy::addOriginAccessWhitelistEntry(
84 blink::WebString::fromUTF8(content::kChromeUIScheme
),
85 blink::WebString::fromUTF8(chrome::kChromeUIExtensionIconHost
),
90 void ChromeExtensionsDispatcherDelegate::RegisterNativeHandlers(
91 extensions::Dispatcher
* dispatcher
,
92 extensions::ModuleSystem
* module_system
,
93 extensions::ScriptContext
* context
) {
94 module_system
->RegisterNativeHandler(
96 scoped_ptr
<NativeHandler
>(
97 new extensions::AppBindings(dispatcher
, context
)));
98 module_system
->RegisterNativeHandler(
100 scoped_ptr
<NativeHandler
>(
101 new extensions::SyncFileSystemCustomBindings(context
)));
102 module_system
->RegisterNativeHandler(
103 "enterprise_platform_keys_natives",
104 scoped_ptr
<NativeHandler
>(
105 new extensions::EnterprisePlatformKeysNatives(context
)));
106 module_system
->RegisterNativeHandler(
107 "file_browser_handler",
108 scoped_ptr
<NativeHandler
>(
109 new extensions::FileBrowserHandlerCustomBindings(context
)));
110 module_system
->RegisterNativeHandler(
111 "file_manager_private",
112 scoped_ptr
<NativeHandler
>(
113 new extensions::FileManagerPrivateCustomBindings(context
)));
114 module_system
->RegisterNativeHandler(
115 "notifications_private",
116 scoped_ptr
<NativeHandler
>(
117 new extensions::NotificationsNativeHandler(context
)));
118 module_system
->RegisterNativeHandler(
120 scoped_ptr
<NativeHandler
>(
121 new extensions::MediaGalleriesCustomBindings(context
)));
122 module_system
->RegisterNativeHandler(
124 scoped_ptr
<NativeHandler
>(
125 new extensions::PageCaptureCustomBindings(context
)));
126 module_system
->RegisterNativeHandler(
128 scoped_ptr
<NativeHandler
>(new extensions::TabsCustomBindings(context
)));
129 module_system
->RegisterNativeHandler(
131 scoped_ptr
<NativeHandler
>(new extensions::WebstoreBindings(context
)));
132 #if defined(ENABLE_WEBRTC)
133 module_system
->RegisterNativeHandler(
134 "cast_streaming_natives",
135 scoped_ptr
<NativeHandler
>(
136 new extensions::CastStreamingNativeHandler(context
)));
138 module_system
->RegisterNativeHandler(
139 "automationInternal",
140 scoped_ptr
<NativeHandler
>(
141 new extensions::AutomationInternalCustomBindings(context
)));
144 void ChromeExtensionsDispatcherDelegate::PopulateSourceMap(
145 extensions::ResourceBundleSourceMap
* source_map
) {
147 source_map
->RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS
);
148 source_map
->RegisterSource("automation", IDR_AUTOMATION_CUSTOM_BINDINGS_JS
);
149 source_map
->RegisterSource("automationEvent", IDR_AUTOMATION_EVENT_JS
);
150 source_map
->RegisterSource("automationNode", IDR_AUTOMATION_NODE_JS
);
151 source_map
->RegisterSource("browserAction",
152 IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS
);
153 source_map
->RegisterSource("declarativeContent",
154 IDR_DECLARATIVE_CONTENT_CUSTOM_BINDINGS_JS
);
155 source_map
->RegisterSource("desktopCapture",
156 IDR_DESKTOP_CAPTURE_CUSTOM_BINDINGS_JS
);
157 source_map
->RegisterSource("developerPrivate",
158 IDR_DEVELOPER_PRIVATE_CUSTOM_BINDINGS_JS
);
159 source_map
->RegisterSource("downloads", IDR_DOWNLOADS_CUSTOM_BINDINGS_JS
);
160 source_map
->RegisterSource("enterprise.platformKeys",
161 IDR_ENTERPRISE_PLATFORM_KEYS_CUSTOM_BINDINGS_JS
);
162 source_map
->RegisterSource("enterprise.platformKeys.internalAPI",
163 IDR_ENTERPRISE_PLATFORM_KEYS_INTERNAL_API_JS
);
164 source_map
->RegisterSource("enterprise.platformKeys.Key",
165 IDR_ENTERPRISE_PLATFORM_KEYS_KEY_JS
);
166 source_map
->RegisterSource("enterprise.platformKeys.KeyPair",
167 IDR_ENTERPRISE_PLATFORM_KEYS_KEY_PAIR_JS
);
168 source_map
->RegisterSource("enterprise.platformKeys.SubtleCrypto",
169 IDR_ENTERPRISE_PLATFORM_KEYS_SUBTLE_CRYPTO_JS
);
170 source_map
->RegisterSource("enterprise.platformKeys.Token",
171 IDR_ENTERPRISE_PLATFORM_KEYS_TOKEN_JS
);
172 source_map
->RegisterSource("enterprise.platformKeys.utils",
173 IDR_ENTERPRISE_PLATFORM_KEYS_UTILS_JS
);
174 source_map
->RegisterSource("feedbackPrivate",
175 IDR_FEEDBACK_PRIVATE_CUSTOM_BINDINGS_JS
);
176 source_map
->RegisterSource("fileBrowserHandler",
177 IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS
);
178 source_map
->RegisterSource("fileManagerPrivate",
179 IDR_FILE_MANAGER_PRIVATE_CUSTOM_BINDINGS_JS
);
180 source_map
->RegisterSource("fileSystem", IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS
);
181 source_map
->RegisterSource("fileSystemProvider",
182 IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS
);
183 source_map
->RegisterSource("gcm", IDR_GCM_CUSTOM_BINDINGS_JS
);
184 source_map
->RegisterSource("identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS
);
185 source_map
->RegisterSource("imageWriterPrivate",
186 IDR_IMAGE_WRITER_PRIVATE_CUSTOM_BINDINGS_JS
);
187 source_map
->RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS
);
188 source_map
->RegisterSource("logPrivate", IDR_LOG_PRIVATE_CUSTOM_BINDINGS_JS
);
189 source_map
->RegisterSource("mediaGalleries",
190 IDR_MEDIA_GALLERIES_CUSTOM_BINDINGS_JS
);
191 source_map
->RegisterSource("notifications",
192 IDR_NOTIFICATIONS_CUSTOM_BINDINGS_JS
);
193 source_map
->RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS
);
194 source_map
->RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS
);
195 source_map
->RegisterSource("pageCapture",
196 IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS
);
197 source_map
->RegisterSource("syncFileSystem",
198 IDR_SYNC_FILE_SYSTEM_CUSTOM_BINDINGS_JS
);
199 source_map
->RegisterSource("systemIndicator",
200 IDR_SYSTEM_INDICATOR_CUSTOM_BINDINGS_JS
);
201 source_map
->RegisterSource("tabCapture", IDR_TAB_CAPTURE_CUSTOM_BINDINGS_JS
);
202 source_map
->RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS
);
203 source_map
->RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS
);
204 source_map
->RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS
);
205 #if defined(ENABLE_WEBRTC)
206 source_map
->RegisterSource("cast.streaming.rtpStream",
207 IDR_CAST_STREAMING_RTP_STREAM_CUSTOM_BINDINGS_JS
);
208 source_map
->RegisterSource("cast.streaming.session",
209 IDR_CAST_STREAMING_SESSION_CUSTOM_BINDINGS_JS
);
210 source_map
->RegisterSource(
211 "cast.streaming.udpTransport",
212 IDR_CAST_STREAMING_UDP_TRANSPORT_CUSTOM_BINDINGS_JS
);
214 source_map
->RegisterSource("webstore", IDR_WEBSTORE_CUSTOM_BINDINGS_JS
);
216 // Custom types sources.
217 source_map
->RegisterSource("ChromeSetting", IDR_CHROME_SETTING_JS
);
218 source_map
->RegisterSource("ContentSetting", IDR_CONTENT_SETTING_JS
);
219 source_map
->RegisterSource("ChromeDirectSetting",
220 IDR_CHROME_DIRECT_SETTING_JS
);
222 // Platform app sources that are not API-specific..
223 source_map
->RegisterSource("fileEntryBindingUtil",
224 IDR_FILE_ENTRY_BINDING_UTIL_JS
);
225 source_map
->RegisterSource("extensionOptions", IDR_EXTENSION_OPTIONS_JS
);
226 source_map
->RegisterSource("extensionOptionsEvents",
227 IDR_EXTENSION_OPTIONS_EVENTS_JS
);
228 source_map
->RegisterSource("tagWatcher", IDR_TAG_WATCHER_JS
);
229 source_map
->RegisterSource("chromeWebViewInternal",
230 IDR_CHROME_WEB_VIEW_INTERNAL_CUSTOM_BINDINGS_JS
);
231 source_map
->RegisterSource("chromeWebView", IDR_CHROME_WEB_VIEW_JS
);
232 source_map
->RegisterSource("chromeWebViewExperimental",
233 IDR_CHROME_WEB_VIEW_EXPERIMENTAL_JS
);
234 source_map
->RegisterSource("injectAppTitlebar", IDR_INJECT_APP_TITLEBAR_JS
);
237 void ChromeExtensionsDispatcherDelegate::RequireAdditionalModules(
238 extensions::ScriptContext
* context
,
239 bool is_within_platform_app
) {
240 extensions::ModuleSystem
* module_system
= context
->module_system();
241 extensions::Feature::Context context_type
= context
->context_type();
243 // TODO(kalman, fsamuel): Eagerly calling Require on context startup is
244 // expensive. It would be better if there were a light way of detecting when
245 // a webview or appview is created and only then set up the infrastructure.
246 if (context_type
== extensions::Feature::BLESSED_EXTENSION_CONTEXT
&&
247 is_within_platform_app
&&
248 extensions::GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV
&&
249 base::CommandLine::ForCurrentProcess()->HasSwitch(
250 extensions::switches::kEnableAppWindowControls
)) {
251 module_system
->Require("windowControls");
254 // Note: setting up the WebView class here, not the chrome.webview API.
255 // The API will be automatically set up when first used.
256 if (context
->GetAvailability("webViewInternal").is_available()) {
257 module_system
->Require("chromeWebView");
258 if (context
->GetAvailability("webViewExperimentalInternal")
260 module_system
->Require("chromeWebViewExperimental");
264 if (context
->GetAvailability("extensionOptionsInternal").is_available()) {
265 module_system
->Require("extensionOptions");
269 void ChromeExtensionsDispatcherDelegate::OnActiveExtensionsUpdated(
270 const std::set
<std::string
>& extension_ids
) {
271 // In single-process mode, the browser process reports the active extensions.
272 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
273 ::switches::kSingleProcess
))
275 crash_keys::SetActiveExtensions(extension_ids
);
278 void ChromeExtensionsDispatcherDelegate::SetChannel(int channel
) {
279 extensions::SetCurrentChannel(
280 static_cast<chrome::VersionInfo::Channel
>(channel
));