| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/renderer/extensions/api/chrome_extensions_renderer_api_provider.h" |
| |
| #include <string_view> |
| |
| #include "chrome/grit/renderer_resources.h" |
| #include "chrome/renderer/extensions/api/extension_hooks_delegate.h" |
| #include "chrome/renderer/extensions/api/notifications_native_handler.h" |
| #include "chrome/renderer/extensions/api/page_capture_custom_bindings.h" |
| #include "chrome/renderer/extensions/api/tabs_hooks_delegate.h" |
| #include "components/guest_view/buildflags/buildflags.h" |
| #include "extensions/buildflags/buildflags.h" |
| #include "extensions/renderer/bindings/api_bindings_system.h" |
| #include "extensions/renderer/lazy_background_page_native_handler.h" |
| #include "extensions/renderer/module_system.h" |
| #include "extensions/renderer/native_extension_bindings_system.h" |
| #include "extensions/renderer/resource_bundle_source_map.h" |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| #include "build/chromeos_buildflags.h" |
| #include "chrome/renderer/extensions/api/app_hooks_delegate.h" |
| #include "chrome/renderer/extensions/api/identity_hooks_delegate.h" |
| #include "chrome/renderer/extensions/api/media_galleries_custom_bindings.h" |
| #include "chrome/renderer/extensions/api/sync_file_system_custom_bindings.h" |
| #include "extensions/renderer/dispatcher.h" |
| #include "extensions/renderer/native_handler.h" |
| #include "extensions/renderer/script_context.h" |
| #include "printing/buildflags/buildflags.h" |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| #include "chrome/renderer/extensions/api/accessibility_private_hooks_delegate.h" |
| #include "chrome/renderer/extensions/api/file_browser_handler_custom_bindings.h" |
| #include "chrome/renderer/extensions/api/file_manager_private_custom_bindings.h" |
| #include "chrome/renderer/extensions/api/platform_keys_natives.h" |
| #if BUILDFLAG(USE_CUPS) |
| #include "chrome/renderer/extensions/api/printing_hooks_delegate.h" |
| #endif // BUILDFLAG(USE_CUPS) |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| #endif // BUILDFLAG(ENABLE_EXTENSIONS) |
| |
| namespace extensions { |
| |
| void ChromeExtensionsRendererAPIProvider::RegisterNativeHandlers( |
| ModuleSystem* module_system, |
| NativeExtensionBindingsSystem* bindings_system, |
| V8SchemaRegistry* v8_schema_registry, |
| ScriptContext* context) const { |
| // TODO(crbug.com/356905053): Move handlers supported on desktop android here. |
| module_system->RegisterNativeHandler( |
| "notifications_private", |
| std::make_unique<NotificationsNativeHandler>(context)); |
| module_system->RegisterNativeHandler( |
| "page_capture", std::make_unique<PageCaptureCustomBindings>( |
| context, bindings_system->GetIPCMessageSender())); |
| |
| // The following are native handlers that are defined in //extensions, but |
| // are only used for APIs defined in Chrome. |
| // TODO(devlin): We should clean this up. If an API is defined in Chrome, |
| // there's no reason to have its native handlers residing and being compiled |
| // in //extensions. |
| module_system->RegisterNativeHandler( |
| "lazy_background_page", |
| std::make_unique<LazyBackgroundPageNativeHandler>(context)); |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| module_system->RegisterNativeHandler( |
| "sync_file_system", |
| std::make_unique<SyncFileSystemCustomBindings>(context)); |
| #if BUILDFLAG(IS_CHROMEOS) |
| module_system->RegisterNativeHandler( |
| "file_browser_handler", |
| std::make_unique<FileBrowserHandlerCustomBindings>(context)); |
| module_system->RegisterNativeHandler( |
| "platform_keys_natives", std::make_unique<PlatformKeysNatives>(context)); |
| module_system->RegisterNativeHandler( |
| "file_manager_private", |
| std::make_unique<FileManagerPrivateCustomBindings>(context)); |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| module_system->RegisterNativeHandler( |
| "mediaGalleries", |
| std::make_unique<MediaGalleriesCustomBindings>(context)); |
| #endif // BUILDFLAG(ENABLE_EXTENSIONS) |
| } |
| |
| void ChromeExtensionsRendererAPIProvider::AddBindingsSystemHooks( |
| Dispatcher* dispatcher, |
| NativeExtensionBindingsSystem* bindings_system) const { |
| // TODO(crbug.com/356905053): Move bindings supported on desktop android here. |
| APIBindingsSystem* bindings = bindings_system->api_system(); |
| bindings->RegisterHooksDelegate( |
| "extension", std::make_unique<extensions::ExtensionHooksDelegate>( |
| bindings_system->messaging_service())); |
| bindings->RegisterHooksDelegate( |
| "tabs", std::make_unique<extensions::TabsHooksDelegate>( |
| bindings_system->messaging_service())); |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| bindings->RegisterHooksDelegate( |
| "app", std::make_unique<extensions::AppHooksDelegate>( |
| dispatcher, bindings->request_handler(), |
| bindings_system->GetIPCMessageSender())); |
| bindings->RegisterHooksDelegate( |
| "identity", std::make_unique<extensions::IdentityHooksDelegate>()); |
| #if BUILDFLAG(IS_CHROMEOS) |
| bindings->RegisterHooksDelegate( |
| "accessibilityPrivate", |
| std::make_unique<extensions::AccessibilityPrivateHooksDelegate>()); |
| #if BUILDFLAG(USE_CUPS) |
| bindings->RegisterHooksDelegate( |
| "printing", std::make_unique<extensions::PrintingHooksDelegate>()); |
| #endif // BUILDFLAG(USE_CUPS) |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| #endif // BUILDFLAG(ENABLE_EXTENSIONS) |
| } |
| |
| void ChromeExtensionsRendererAPIProvider::PopulateSourceMap( |
| ResourceBundleSourceMap* source_map) const { |
| struct RegisterSourceData { |
| std::string_view name; |
| int resource_id; |
| }; |
| |
| static constexpr RegisterSourceData kSources[] = { |
| // Custom bindings. |
| {"action", IDR_ACTION_CUSTOM_BINDINGS_JS}, |
| {"browserAction", IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS}, |
| {"declarativeContent", IDR_DECLARATIVE_CONTENT_CUSTOM_BINDINGS_JS}, |
| {"desktopCapture", IDR_DESKTOP_CAPTURE_CUSTOM_BINDINGS_JS}, |
| {"developerPrivate", IDR_DEVELOPER_PRIVATE_CUSTOM_BINDINGS_JS}, |
| {"downloads", IDR_DOWNLOADS_CUSTOM_BINDINGS_JS}, |
| {"gcm", IDR_GCM_CUSTOM_BINDINGS_JS}, |
| {"identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS}, |
| {"imageWriterPrivate", IDR_IMAGE_WRITER_PRIVATE_CUSTOM_BINDINGS_JS}, |
| {"input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS}, |
| {"mediaGalleries", IDR_MEDIA_GALLERIES_CUSTOM_BINDINGS_JS}, |
| {"notifications", IDR_NOTIFICATIONS_CUSTOM_BINDINGS_JS}, |
| {"omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS}, |
| {"pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS}, |
| {"pageCapture", IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS}, |
| {"syncFileSystem", IDR_SYNC_FILE_SYSTEM_CUSTOM_BINDINGS_JS}, |
| {"tabCapture", IDR_TAB_CAPTURE_CUSTOM_BINDINGS_JS}, |
| {"tts", IDR_TTS_CUSTOM_BINDINGS_JS}, |
| {"ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS}, |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| {"certificateProvider", IDR_CERTIFICATE_PROVIDER_CUSTOM_BINDINGS_JS}, |
| {"enterprise.platformKeys", |
| IDR_ENTERPRISE_PLATFORM_KEYS_CUSTOM_BINDINGS_JS}, |
| {"enterprise.platformKeys.CryptoKey", |
| IDR_ENTERPRISE_PLATFORM_KEYS_CRYPTO_KEY_JS}, |
| {"enterprise.platformKeys.SubtleCrypto", |
| IDR_ENTERPRISE_PLATFORM_KEYS_SUBTLE_CRYPTO_JS}, |
| {"enterprise.platformKeys.Token", IDR_ENTERPRISE_PLATFORM_KEYS_TOKEN_JS}, |
| {"fileBrowserHandler", IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS}, |
| {"fileSystemProvider", IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS}, |
| {"platformKeys", IDR_PLATFORM_KEYS_CUSTOM_BINDINGS_JS}, |
| {"platformKeys.getCryptoKeyUtil", |
| IDR_PLATFORM_KEYS_GET_CRYPTO_KEY_UTIL_JS}, |
| {"platformKeys.Key", IDR_PLATFORM_KEYS_KEY_JS}, |
| {"platformKeys.SubtleCrypto", IDR_PLATFORM_KEYS_SUBTLE_CRYPTO_JS}, |
| {"platformKeys.utils", IDR_PLATFORM_KEYS_UTILS_JS}, |
| |
| // Remote Apps. |
| {"chromeos.remote_apps.mojom-lite", IDR_REMOTE_APPS_MOJOM_LITE_JS}, |
| {"chromeos.remote_apps", IDR_REMOTE_APPS_BINDINGS_JS}, |
| {"url/mojom/url.mojom-lite", IDR_MOJO_URL_MOJOM_LITE_JS}, |
| |
| {"fileManagerPrivate", IDR_FILE_MANAGER_PRIVATE_CUSTOM_BINDINGS_JS}, |
| {"terminalPrivate", IDR_TERMINAL_PRIVATE_CUSTOM_BINDINGS_JS}, |
| |
| // IME service on Chrome OS. |
| {"ash.ime.mojom.ime_service.mojom", IDR_IME_SERVICE_MOJOM_JS}, |
| {"ash.ime.mojom.input_engine.mojom", |
| IDR_IME_SERVICE_INPUT_ENGINE_MOJOM_JS}, |
| {"ash.ime.mojom.input_method.mojom", |
| IDR_IME_SERVICE_INPUT_METHOD_MOJOM_JS}, |
| {"ash.ime.mojom.input_method_host.mojom", |
| IDR_IME_SERVICE_INPUT_METHOD_HOST_MOJOM_JS}, |
| {"chromeos.ime.service", IDR_IME_SERVICE_BINDINGS_JS}, |
| |
| {"chromeos.tts.mojom.google_tts_stream.mojom", |
| IDR_GOOGLE_TTS_STREAM_MOJOM_JS}, |
| {"chromeos.tts.google_stream", IDR_GOOGLE_TTS_STREAM_BINDINGS_JS}, |
| |
| {"ash.enhanced_network_tts.mojom-lite", |
| IDR_ENHANCED_NETWORK_TTS_MOJOM_LITE_JS}, |
| {"ash.enhanced_network_tts", IDR_ENHANCED_NETWORK_TTS_BINDINGS_JS}, |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| |
| {"webrtcDesktopCapturePrivate", |
| IDR_WEBRTC_DESKTOP_CAPTURE_PRIVATE_CUSTOM_BINDINGS_JS}, |
| {"webrtcLoggingPrivate", IDR_WEBRTC_LOGGING_PRIVATE_CUSTOM_BINDINGS_JS}, |
| |
| // Platform app sources that are not API-specific.. |
| {"chromeWebViewContextMenusApiMethods", |
| IDR_CHROME_WEB_VIEW_CONTEXT_MENUS_API_METHODS_JS}, |
| {"chromeWebViewElement", IDR_CHROME_WEB_VIEW_ELEMENT_JS}, |
| {"chromeWebViewInternal", |
| IDR_CHROME_WEB_VIEW_INTERNAL_CUSTOM_BINDINGS_JS}, |
| {"chromeWebView", IDR_CHROME_WEB_VIEW_JS}, |
| }; |
| |
| for (const auto& source : kSources) { |
| source_map->RegisterSource(source.name, source.resource_id); |
| } |
| } |
| |
| void ChromeExtensionsRendererAPIProvider::EnableCustomElementAllowlist() const { |
| } |
| |
| void ChromeExtensionsRendererAPIProvider::RequireWebViewModules( |
| ScriptContext* context) const { |
| #if BUILDFLAG(ENABLE_GUEST_VIEW) |
| DCHECK(context->GetAvailability("webViewInternal").is_available()); |
| if (context->GetAvailability("chromeWebViewTag").is_available()) { |
| // CHECK that the Chrome WebView and Controlled Frame features aren't both |
| // enabled in the same context. This is here because Controlled Frame |
| // is based on WebView and modifies base classes in order to not ship some |
| // APIs. These modifications could harm a live WebView instance if we |
| // allowed both in a single instance, but these features aren't designed |
| // to be enabled in the same instance. This check confirms that is held. |
| CHECK(!context->GetAvailability("controlledFrameInternal").is_available()); |
| |
| context->module_system()->Require("chromeWebViewElement"); |
| } |
| #endif // BUILDFLAG(ENABLE_GUEST_VIEW) |
| } |
| |
| } // namespace extensions |