refactor: use new extensions Messaging API IPC (#40511)
* refactor: use new extensions Messaging API IPC Refs CRBUG:993189 Incorporates changes from: * Bind ServiceWorker associated interfaces on Worker Thread (CL:4929154) * [extensions] Move WakeEventPage to mojom::RendererHost (CL:4902564) * [extensions] Convert Extension Messaging APIs over to mojo (CL:4947890) * [extensions] Port GetMessageBundle over to mojom (CL:4956841) * 5008635: [extensions] Bind the mojo interfaces to the frame instance https://chromium-review.googlesource.com/c/chromium/src/+/5008635
This commit is contained in:
		
					parent
					
						
							
								088affd4a4
							
						
					
				
			
			
				commit
				
					
						371bca69b6
					
				
			
		
					 7 changed files with 25 additions and 259 deletions
				
			
		|  | @ -60,8 +60,3 @@ enable_dangling_raw_ptr_checks = false | |||
| # This flag speeds up the performance of fork/execve on linux systems. | ||||
| # Ref: https://chromium-review.googlesource.com/c/v8/v8/+/4602858 | ||||
| v8_enable_private_mapping_fork_optimization = true | ||||
| 
 | ||||
| # https://chromium-review.googlesource.com/c/chromium/src/+/4995136 | ||||
| # TODO(jkleinsc): convert legacy IPC calls in extensions to use mojo | ||||
| # https://github.com/electron/electron/issues/40439 | ||||
| enable_extensions_legacy_ipc = true | ||||
|  |  | |||
|  | @ -733,8 +733,6 @@ filenames = { | |||
|     "shell/browser/extensions/electron_extension_host_delegate.h", | ||||
|     "shell/browser/extensions/electron_extension_loader.cc", | ||||
|     "shell/browser/extensions/electron_extension_loader.h", | ||||
|     "shell/browser/extensions/electron_extension_message_filter.cc", | ||||
|     "shell/browser/extensions/electron_extension_message_filter.h", | ||||
|     "shell/browser/extensions/electron_extension_system_factory.cc", | ||||
|     "shell/browser/extensions/electron_extension_system_factory.h", | ||||
|     "shell/browser/extensions/electron_extension_system.cc", | ||||
|  |  | |||
|  | @ -151,13 +151,11 @@ | |||
| #include "content/public/browser/child_process_security_policy.h" | ||||
| #include "content/public/browser/file_url_loader.h" | ||||
| #include "content/public/browser/web_ui_url_loader_factory.h" | ||||
| #include "extensions/browser/api/messaging/messaging_api_message_filter.h" | ||||
| #include "extensions/browser/api/mime_handler_private/mime_handler_private.h" | ||||
| #include "extensions/browser/api/web_request/web_request_api.h" | ||||
| #include "extensions/browser/browser_context_keyed_api_factory.h" | ||||
| #include "extensions/browser/event_router.h" | ||||
| #include "extensions/browser/extension_host.h" | ||||
| #include "extensions/browser/extension_message_filter.h" | ||||
| #include "extensions/browser/extension_navigation_throttle.h" | ||||
| #include "extensions/browser/extension_prefs.h" | ||||
| #include "extensions/browser/extension_protocols.h" | ||||
|  | @ -177,7 +175,6 @@ | |||
| #include "extensions/common/mojom/guest_view.mojom.h" | ||||
| #include "extensions/common/mojom/renderer_host.mojom.h" | ||||
| #include "extensions/common/switches.h" | ||||
| #include "shell/browser/extensions/electron_extension_message_filter.h" | ||||
| #include "shell/browser/extensions/electron_extension_system.h" | ||||
| #include "shell/browser/extensions/electron_extension_web_contents_observer.h" | ||||
| #endif | ||||
|  | @ -385,20 +382,6 @@ bool ElectronBrowserClient::IsRendererSubFrame(int process_id) const { | |||
| 
 | ||||
| void ElectronBrowserClient::RenderProcessWillLaunch( | ||||
|     content::RenderProcessHost* host) { | ||||
|   // When a render process is crashed, it might be reused.
 | ||||
| #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) | ||||
|   int process_id = host->GetID(); | ||||
| 
 | ||||
|   auto* browser_context = host->GetBrowserContext(); | ||||
| 
 | ||||
|   host->AddFilter( | ||||
|       new extensions::ExtensionMessageFilter(process_id, browser_context)); | ||||
|   host->AddFilter( | ||||
|       new ElectronExtensionMessageFilter(process_id, browser_context)); | ||||
|   host->AddFilter( | ||||
|       new extensions::MessagingAPIMessageFilter(process_id, browser_context)); | ||||
| #endif | ||||
| 
 | ||||
|   // Remove in case the host is reused after a crash, otherwise noop.
 | ||||
|   host->RemoveObserver(this); | ||||
| 
 | ||||
|  | @ -1429,6 +1412,19 @@ void ElectronBrowserClient::OverrideURLLoaderFactoryParams( | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ElectronBrowserClient::RegisterAssociatedInterfaceBindersForServiceWorker( | ||||
|     const content::ServiceWorkerVersionBaseInfo& service_worker_version_info, | ||||
|     blink::AssociatedInterfaceRegistry& associated_registry) { | ||||
| #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) | ||||
|   associated_registry.AddInterface<extensions::mojom::RendererHost>( | ||||
|       base::BindRepeating(&extensions::RendererStartupHelper::BindForRenderer, | ||||
|                           service_worker_version_info.process_id)); | ||||
|   associated_registry.AddInterface<extensions::mojom::ServiceWorkerHost>( | ||||
|       base::BindRepeating(&extensions::ServiceWorkerHost::BindReceiver, | ||||
|                           service_worker_version_info.process_id)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ElectronBrowserClient:: | ||||
|     RegisterAssociatedInterfaceBindersForRenderFrameHost( | ||||
|         content::RenderFrameHost& | ||||
|  | @ -1485,6 +1481,13 @@ void ElectronBrowserClient:: | |||
|           &render_frame_host)); | ||||
| #endif | ||||
| #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) | ||||
|   int render_process_id = render_frame_host.GetProcess()->GetID(); | ||||
|   associated_registry.AddInterface<extensions::mojom::EventRouter>( | ||||
|       base::BindRepeating(&extensions::EventRouter::BindForRenderer, | ||||
|                           render_process_id)); | ||||
|   associated_registry.AddInterface<extensions::mojom::RendererHost>( | ||||
|       base::BindRepeating(&extensions::RendererStartupHelper::BindForRenderer, | ||||
|                           render_process_id)); | ||||
|   associated_registry.AddInterface<extensions::mojom::LocalFrameHost>( | ||||
|       base::BindRepeating( | ||||
|           [](content::RenderFrameHost* render_frame_host, | ||||
|  | @ -1572,15 +1575,9 @@ void ElectronBrowserClient::ExposeInterfacesToRenderer( | |||
|     blink::AssociatedInterfaceRegistry* associated_registry, | ||||
|     content::RenderProcessHost* render_process_host) { | ||||
| #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) | ||||
|   associated_registry->AddInterface<extensions::mojom::EventRouter>( | ||||
|       base::BindRepeating(&extensions::EventRouter::BindForRenderer, | ||||
|                           render_process_host->GetID())); | ||||
|   associated_registry->AddInterface<extensions::mojom::RendererHost>( | ||||
|       base::BindRepeating(&extensions::RendererStartupHelper::BindForRenderer, | ||||
|                           render_process_host->GetID())); | ||||
|   associated_registry->AddInterface<extensions::mojom::ServiceWorkerHost>( | ||||
|       base::BindRepeating(&extensions::ServiceWorkerHost::BindReceiver, | ||||
|                           render_process_host->GetID())); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -250,6 +250,9 @@ class ElectronBrowserClient : public content::ContentBrowserClient, | |||
|   void RegisterAssociatedInterfaceBindersForRenderFrameHost( | ||||
|       content::RenderFrameHost& render_frame_host, | ||||
|       blink::AssociatedInterfaceRegistry& associated_registry) override; | ||||
|   void RegisterAssociatedInterfaceBindersForServiceWorker( | ||||
|       const content::ServiceWorkerVersionBaseInfo& service_worker_version_info, | ||||
|       blink::AssociatedInterfaceRegistry& associated_registry) override; | ||||
| 
 | ||||
|   bool HandleExternalProtocol( | ||||
|       const GURL& url, | ||||
|  |  | |||
|  | @ -64,6 +64,7 @@ | |||
| #include "extensions/browser/extension_pref_store.h" | ||||
| #include "extensions/browser/extension_pref_value_map_factory.h" | ||||
| #include "extensions/browser/extension_prefs.h" | ||||
| #include "extensions/browser/permissions_manager.h" | ||||
| #include "extensions/browser/pref_names.h" | ||||
| #include "extensions/common/extension_api.h" | ||||
| #include "shell/browser/extensions/electron_browser_context_keyed_service_factories.h" | ||||
|  | @ -313,6 +314,7 @@ void ElectronBrowserContext::InitPrefs() { | |||
| #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) | ||||
|   if (!in_memory_) | ||||
|     extensions::ExtensionPrefs::RegisterProfilePrefs(registry.get()); | ||||
|   extensions::PermissionsManager::RegisterProfilePrefs(registry.get()); | ||||
| #endif | ||||
| 
 | ||||
| #if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER) | ||||
|  |  | |||
|  | @ -1,157 +0,0 @@ | |||
| // Copyright (c) 2020 Samuel Maddock <sam@samuelmaddock.com>.
 | ||||
| // Use of this source code is governed by the MIT license that can be
 | ||||
| // found in the LICENSE file.
 | ||||
| 
 | ||||
| #include "shell/browser/extensions/electron_extension_message_filter.h" | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <memory> | ||||
| 
 | ||||
| #include "base/files/file_path.h" | ||||
| #include "base/functional/bind.h" | ||||
| #include "base/functional/callback_helpers.h" | ||||
| #include "base/logging.h" | ||||
| #include "base/memory/ptr_util.h" | ||||
| #include "base/stl_util.h" | ||||
| #include "base/strings/utf_string_conversions.h" | ||||
| #include "base/task/thread_pool.h" | ||||
| #include "content/public/browser/browser_context.h" | ||||
| #include "content/public/browser/browser_task_traits.h" | ||||
| #include "content/public/browser/render_process_host.h" | ||||
| #include "extensions/browser/extension_registry.h" | ||||
| #include "extensions/browser/extension_system.h" | ||||
| #include "extensions/browser/l10n_file_util.h" | ||||
| #include "extensions/common/extension_messages.h" | ||||
| #include "extensions/common/extension_set.h" | ||||
| #include "extensions/common/manifest_handlers/default_locale_handler.h" | ||||
| #include "extensions/common/manifest_handlers/shared_module_info.h" | ||||
| #include "extensions/common/message_bundle.h" | ||||
| 
 | ||||
| using content::BrowserThread; | ||||
| 
 | ||||
| namespace electron { | ||||
| 
 | ||||
| const uint32_t kExtensionFilteredMessageClasses[] = { | ||||
|     ExtensionMsgStart, | ||||
| }; | ||||
| 
 | ||||
| ElectronExtensionMessageFilter::ElectronExtensionMessageFilter( | ||||
|     int render_process_id, | ||||
|     content::BrowserContext* browser_context) | ||||
|     : BrowserMessageFilter(kExtensionFilteredMessageClasses, | ||||
|                            std::size(kExtensionFilteredMessageClasses)), | ||||
|       render_process_id_(render_process_id), | ||||
|       browser_context_(browser_context) { | ||||
|   DCHECK_CURRENTLY_ON(BrowserThread::UI); | ||||
| } | ||||
| 
 | ||||
| ElectronExtensionMessageFilter::~ElectronExtensionMessageFilter() { | ||||
|   DCHECK_CURRENTLY_ON(BrowserThread::UI); | ||||
| } | ||||
| 
 | ||||
| bool ElectronExtensionMessageFilter::OnMessageReceived( | ||||
|     const IPC::Message& message) { | ||||
|   bool handled = true; | ||||
|   IPC_BEGIN_MESSAGE_MAP(ElectronExtensionMessageFilter, message) | ||||
|     IPC_MESSAGE_HANDLER_DELAY_REPLY(ExtensionHostMsg_GetMessageBundle, | ||||
|                                     OnGetExtMessageBundle) | ||||
|     IPC_MESSAGE_UNHANDLED(handled = false) | ||||
|   IPC_END_MESSAGE_MAP() | ||||
| 
 | ||||
|   return handled; | ||||
| } | ||||
| 
 | ||||
| void ElectronExtensionMessageFilter::OverrideThreadForMessage( | ||||
|     const IPC::Message& message, | ||||
|     BrowserThread::ID* thread) { | ||||
|   switch (message.type()) { | ||||
|     case ExtensionHostMsg_GetMessageBundle::ID: | ||||
|       *thread = BrowserThread::UI; | ||||
|       break; | ||||
|     default: | ||||
|       break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void ElectronExtensionMessageFilter::OnDestruct() const { | ||||
|   if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | ||||
|     delete this; | ||||
|   } else { | ||||
|     content::GetUIThreadTaskRunner({})->DeleteSoon(FROM_HERE, this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void ElectronExtensionMessageFilter::OnGetExtMessageBundle( | ||||
|     const std::string& extension_id, | ||||
|     IPC::Message* reply_msg) { | ||||
|   DCHECK_CURRENTLY_ON(BrowserThread::UI); | ||||
| 
 | ||||
|   const extensions::ExtensionSet& extension_set = | ||||
|       extensions::ExtensionRegistry::Get(browser_context_) | ||||
|           ->enabled_extensions(); | ||||
|   const extensions::Extension* extension = extension_set.GetByID(extension_id); | ||||
| 
 | ||||
|   if (!extension) {  // The extension has gone.
 | ||||
|     ExtensionHostMsg_GetMessageBundle::WriteReplyParams( | ||||
|         reply_msg, extensions::MessageBundle::SubstitutionMap()); | ||||
|     Send(reply_msg); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   const std::string& default_locale = | ||||
|       extensions::LocaleInfo::GetDefaultLocale(extension); | ||||
|   if (default_locale.empty()) { | ||||
|     // A little optimization: send the answer here to avoid an extra thread hop.
 | ||||
|     std::unique_ptr<extensions::MessageBundle::SubstitutionMap> dictionary_map( | ||||
|         extensions::l10n_file_util:: | ||||
|             LoadNonLocalizedMessageBundleSubstitutionMap(extension_id)); | ||||
|     ExtensionHostMsg_GetMessageBundle::WriteReplyParams(reply_msg, | ||||
|                                                         *dictionary_map); | ||||
|     Send(reply_msg); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   std::vector<base::FilePath> paths_to_load; | ||||
|   paths_to_load.push_back(extension->path()); | ||||
| 
 | ||||
|   auto imports = extensions::SharedModuleInfo::GetImports(extension); | ||||
|   // Iterate through the imports in reverse.  This will allow later imported
 | ||||
|   // modules to override earlier imported modules, as the list order is
 | ||||
|   // maintained from the definition in manifest.json of the imports.
 | ||||
|   for (auto it = imports.rbegin(); it != imports.rend(); ++it) { | ||||
|     const extensions::Extension* imported_extension = | ||||
|         extension_set.GetByID(it->extension_id); | ||||
|     if (!imported_extension) { | ||||
|       NOTREACHED() << "Missing shared module " << it->extension_id; | ||||
|       continue; | ||||
|     } | ||||
|     paths_to_load.push_back(imported_extension->path()); | ||||
|   } | ||||
| 
 | ||||
|   // This blocks tab loading. Priority is inherited from the calling context.
 | ||||
|   base::ThreadPool::PostTask( | ||||
|       FROM_HERE, {base::MayBlock()}, | ||||
|       base::BindOnce( | ||||
|           &ElectronExtensionMessageFilter::OnGetExtMessageBundleAsync, this, | ||||
|           paths_to_load, extension_id, default_locale, | ||||
|           extension_l10n_util::GetGzippedMessagesPermissionForExtension( | ||||
|               extension), | ||||
|           reply_msg)); | ||||
| } | ||||
| 
 | ||||
| void ElectronExtensionMessageFilter::OnGetExtMessageBundleAsync( | ||||
|     const std::vector<base::FilePath>& extension_paths, | ||||
|     const std::string& main_extension_id, | ||||
|     const std::string& default_locale, | ||||
|     extension_l10n_util::GzippedMessagesPermission gzip_permission, | ||||
|     IPC::Message* reply_msg) { | ||||
|   std::unique_ptr<extensions::MessageBundle::SubstitutionMap> dictionary_map( | ||||
|       extensions::l10n_file_util::LoadMessageBundleSubstitutionMapFromPaths( | ||||
|           extension_paths, main_extension_id, default_locale, gzip_permission)); | ||||
| 
 | ||||
|   ExtensionHostMsg_GetMessageBundle::WriteReplyParams(reply_msg, | ||||
|                                                       *dictionary_map); | ||||
|   Send(reply_msg); | ||||
| } | ||||
| 
 | ||||
| }  // namespace electron
 | ||||
|  | @ -1,72 +0,0 @@ | |||
| // Copyright (c) 2020 Samuel Maddock <sam@samuelmaddock.com>.
 | ||||
| // Use of this source code is governed by the MIT license that can be
 | ||||
| // found in the LICENSE file.
 | ||||
| 
 | ||||
| #ifndef ELECTRON_SHELL_BROWSER_EXTENSIONS_ELECTRON_EXTENSION_MESSAGE_FILTER_H_ | ||||
| #define ELECTRON_SHELL_BROWSER_EXTENSIONS_ELECTRON_EXTENSION_MESSAGE_FILTER_H_ | ||||
| 
 | ||||
| #include <string> | ||||
| #include <vector> | ||||
| 
 | ||||
| #include "base/memory/raw_ptr.h" | ||||
| #include "base/task/sequenced_task_runner_helpers.h" | ||||
| #include "content/public/browser/browser_message_filter.h" | ||||
| #include "content/public/browser/browser_thread.h" | ||||
| #include "extensions/common/extension_l10n_util.h" | ||||
| 
 | ||||
| namespace content { | ||||
| class BrowserContext; | ||||
| } | ||||
| 
 | ||||
| namespace extensions { | ||||
| struct Message; | ||||
| } | ||||
| 
 | ||||
| namespace electron { | ||||
| 
 | ||||
| // This class filters out incoming Electron-specific IPC messages from the
 | ||||
| // extension process on the IPC thread.
 | ||||
| class ElectronExtensionMessageFilter : public content::BrowserMessageFilter { | ||||
|  public: | ||||
|   ElectronExtensionMessageFilter(int render_process_id, | ||||
|                                  content::BrowserContext* browser_context); | ||||
| 
 | ||||
|   // disable copy
 | ||||
|   ElectronExtensionMessageFilter(const ElectronExtensionMessageFilter&) = | ||||
|       delete; | ||||
|   ElectronExtensionMessageFilter& operator=( | ||||
|       const ElectronExtensionMessageFilter&) = delete; | ||||
| 
 | ||||
|   // content::BrowserMessageFilter methods:
 | ||||
|   bool OnMessageReceived(const IPC::Message& message) override; | ||||
|   void OverrideThreadForMessage(const IPC::Message& message, | ||||
|                                 content::BrowserThread::ID* thread) override; | ||||
|   void OnDestruct() const override; | ||||
| 
 | ||||
|  private: | ||||
|   friend class content::BrowserThread; | ||||
|   friend class base::DeleteHelper<ElectronExtensionMessageFilter>; | ||||
| 
 | ||||
|   ~ElectronExtensionMessageFilter() override; | ||||
| 
 | ||||
|   void OnGetExtMessageBundle(const std::string& extension_id, | ||||
|                              IPC::Message* reply_msg); | ||||
|   void OnGetExtMessageBundleAsync( | ||||
|       const std::vector<base::FilePath>& extension_paths, | ||||
|       const std::string& main_extension_id, | ||||
|       const std::string& default_locale, | ||||
|       extension_l10n_util::GzippedMessagesPermission gzip_permission, | ||||
|       IPC::Message* reply_msg); | ||||
| 
 | ||||
|   const int render_process_id_; | ||||
| 
 | ||||
|   // The BrowserContext associated with our renderer process.  This should only
 | ||||
|   // be accessed on the UI thread! Furthermore since this class is refcounted it
 | ||||
|   // may outlive |browser_context_|, so make sure to nullptr check if in doubt;
 | ||||
|   // async calls and the like.
 | ||||
|   raw_ptr<content::BrowserContext> browser_context_; | ||||
| }; | ||||
| 
 | ||||
| }  // namespace electron
 | ||||
| 
 | ||||
| #endif  // ELECTRON_SHELL_BROWSER_EXTENSIONS_ELECTRON_EXTENSION_MESSAGE_FILTER_H_
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Shelley Vohr
				Shelley Vohr