123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- // 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_H_
- #define EXTENSIONS_RENDERER_DISPATCHER_H_
- #include <stdint.h>
- #include <map>
- #include <memory>
- #include <set>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/gtest_prod_util.h"
- #include "base/scoped_observation.h"
- #include "base/timer/timer.h"
- #include "components/version_info/version_info.h"
- #include "content/public/renderer/render_thread_observer.h"
- #include "extensions/common/event_filter.h"
- #include "extensions/common/extension_id.h"
- #include "extensions/common/extensions_client.h"
- #include "extensions/common/features/feature.h"
- #include "extensions/common/mojom/event_dispatcher.mojom.h"
- #include "extensions/common/mojom/feature_session_type.mojom.h"
- #include "extensions/common/mojom/frame.mojom.h"
- #include "extensions/common/mojom/host_id.mojom-forward.h"
- #include "extensions/common/mojom/renderer.mojom.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/user_script_set_manager.h"
- #include "extensions/renderer/v8_schema_registry.h"
- #include "mojo/public/cpp/bindings/associated_receiver.h"
- #include "third_party/blink/public/platform/web_string.h"
- #include "v8/include/v8-forward.h"
- class ChromeRenderViewTest;
- class GURL;
- class ModuleSystem;
- struct ExtensionMsg_ExternalConnectionInfo;
- struct ExtensionMsg_TabConnectionInfo;
- namespace blink {
- class WebLocalFrame;
- class WebServiceWorkerContextProxy;
- }
- namespace base {
- class SingleThreadTaskRunner;
- }
- namespace content {
- class RenderThread;
- } // namespace content
- namespace extensions {
- // Constant to define the default profile id for the renderer to 0.
- // Since each renderer is associated with a single context, we don't need
- // separate ids for the profile.
- const int kRendererProfileId = 0;
- class ContentWatcher;
- class DispatcherDelegate;
- class Extension;
- class NativeExtensionBindingsSystem;
- class IPCMessageSender;
- class ScriptContext;
- class ScriptContextSetIterable;
- class ScriptInjectionManager;
- class WorkerScriptContextSet;
- struct Message;
- struct PortId;
- // Dispatches extension control messages sent to the renderer and stores
- // renderer extension related state.
- class Dispatcher : public content::RenderThreadObserver,
- public UserScriptSetManager::Observer,
- public mojom::Renderer,
- public mojom::EventDispatcher {
- public:
- explicit Dispatcher(std::unique_ptr<DispatcherDelegate> delegate);
- Dispatcher(const Dispatcher&) = delete;
- Dispatcher& operator=(const Dispatcher&) = delete;
- ~Dispatcher() override;
- // Returns Service Worker ScriptContexts belonging to current worker thread.
- static WorkerScriptContextSet* GetWorkerScriptContextSet();
- const ScriptContextSet& script_context_set() const {
- return *script_context_set_;
- }
- // Returns iterator to iterate over all main thread ScriptContexts.
- ScriptContextSetIterable* script_context_set_iterator() {
- return script_context_set_.get();
- }
- V8SchemaRegistry* v8_schema_registry() { return v8_schema_registry_.get(); }
- const std::string& webview_partition_id() { return webview_partition_id_; }
- bool activity_logging_enabled() const { return activity_logging_enabled_; }
- void OnRenderThreadStarted(content::RenderThread* render_thread);
- void OnRenderFrameCreated(content::RenderFrame* render_frame);
- bool IsExtensionActive(const std::string& extension_id) const;
- void DidCreateScriptContext(blink::WebLocalFrame* frame,
- const v8::Local<v8::Context>& context,
- int32_t world_id);
- // This is called when a service worker is ready to evaluate the toplevel
- // script. This method suspends the service worker if:
- // * the service worker is background of a service worker based extension,
- // and
- // * the extension isn't loaded yet.
- // Suspending background service worker is required because we need to
- // install extension API bindings before executing the service worker.
- // TODO(crbug.com/1000890): Figure out better way to coalesce them.
- //
- // Runs on the service worker thread and should only use thread-safe member
- // variables.
- void DidInitializeServiceWorkerContextOnWorkerThread(
- blink::WebServiceWorkerContextProxy* context_proxy,
- const GURL& service_worker_scope,
- const GURL& script_url);
- // This is called immediately before a service worker evaluates the
- // toplevel script. This method installs extension API bindings.
- //
- // Runs on a different thread and should only use thread-safe member
- // variables.
- void WillEvaluateServiceWorkerOnWorkerThread(
- blink::WebServiceWorkerContextProxy* context_proxy,
- v8::Local<v8::Context> v8_context,
- int64_t service_worker_version_id,
- const GURL& service_worker_scope,
- const GURL& script_url);
- void WillReleaseScriptContext(blink::WebLocalFrame* frame,
- const v8::Local<v8::Context>& context,
- int32_t world_id);
- // Runs on worker thread and should not use any member variables.
- void DidStartServiceWorkerContextOnWorkerThread(
- int64_t service_worker_version_id,
- const GURL& service_worker_scope,
- const GURL& script_url);
- // Runs on a different thread and should not use any member variables.
- void WillDestroyServiceWorkerContextOnWorkerThread(
- v8::Local<v8::Context> v8_context,
- int64_t service_worker_version_id,
- const GURL& service_worker_scope,
- const GURL& script_url);
- // This method is not allowed to run JavaScript code in the frame.
- void DidCreateDocumentElement(blink::WebLocalFrame* frame);
- // These methods may run (untrusted) JavaScript code in the frame, and
- // cause |render_frame| to become invalid.
- void RunScriptsAtDocumentStart(content::RenderFrame* render_frame);
- void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame);
- void RunScriptsAtDocumentIdle(content::RenderFrame* render_frame);
- // Dispatches the event named |event_name| to all render views.
- void DispatchEventHelper(const std::string& extension_id,
- const std::string& event_name,
- const base::Value::List& event_args,
- mojom::EventFilteringInfoPtr filtering_info) const;
- // Shared implementation of the various MessageInvoke IPCs.
- void InvokeModuleSystemMethod(content::RenderFrame* render_frame,
- const std::string& extension_id,
- const std::string& module_name,
- const std::string& function_name,
- const base::Value::List& args);
- void ExecuteDeclarativeScript(content::RenderFrame* render_frame,
- int tab_id,
- const ExtensionId& extension_id,
- const std::string& script_id,
- const GURL& url);
- // Executes the code described in |param| and calls |callback| if it's done.
- void ExecuteCode(mojom::ExecuteCodeParamsPtr param,
- mojom::LocalFrame::ExecuteCodeCallback callback,
- content::RenderFrame* render_frame);
- struct JsResourceInfo {
- const char* name = nullptr;
- int id = 0;
- };
- // Returns a list of resources for the JS modules to add to the source map.
- static std::vector<JsResourceInfo> GetJsResources();
- static void RegisterNativeHandlers(
- ModuleSystem* module_system,
- ScriptContext* context,
- Dispatcher* dispatcher,
- NativeExtensionBindingsSystem* bindings_system,
- V8SchemaRegistry* v8_schema_registry);
- NativeExtensionBindingsSystem* bindings_system() {
- return bindings_system_.get();
- }
- private:
- // The RendererPermissionsPolicyDelegateTest.CannotScriptWebstore test needs
- // to call the ActivateExtension IPCs.
- friend class ::ChromeRenderViewTest;
- FRIEND_TEST_ALL_PREFIXES(RendererPermissionsPolicyDelegateTest,
- CannotScriptWebstore);
- // RenderThreadObserver implementation:
- bool OnControlMessageReceived(const IPC::Message& message) override;
- void RegisterMojoInterfaces(
- blink::AssociatedInterfaceRegistry* associated_interfaces) override;
- void UnregisterMojoInterfaces(
- blink::AssociatedInterfaceRegistry* associated_interfaces) override;
- // mojom::Renderer implementation:
- void ActivateExtension(const std::string& extension_id) override;
- void SetActivityLoggingEnabled(bool enabled) override;
- void LoadExtensions(
- std::vector<mojom::ExtensionLoadedParamsPtr> loaded_extensions) override;
- void UnloadExtension(const std::string& extension_id) override;
- void SuspendExtension(
- const std::string& extension_id,
- mojom::Renderer::SuspendExtensionCallback callback) override;
- void CancelSuspendExtension(const std::string& extension_id) override;
- void SetDeveloperMode(bool current_developer_mode) override;
- void SetSessionInfo(version_info::Channel channel,
- mojom::FeatureSessionType session_type,
- bool lock_screen_context) override;
- void SetSystemFont(const std::string& font_family,
- const std::string& font_size) override;
- void SetWebViewPartitionID(const std::string& partition_id) override;
- void SetScriptingAllowlist(
- const std::vector<std::string>& extension_ids) override;
- void ShouldSuspend(ShouldSuspendCallback callback) override;
- void TransferBlobs(TransferBlobsCallback callback) override;
- void UpdatePermissions(const std::string& extension_id,
- PermissionSet active_permissions,
- PermissionSet withheld_permissions,
- URLPatternSet policy_blocked_hosts,
- URLPatternSet policy_allowed_hosts,
- bool uses_default_policy_host_restrictions) override;
- void UpdateDefaultPolicyHostRestrictions(
- URLPatternSet default_policy_blocked_hosts,
- URLPatternSet default_policy_allowed_hosts) override;
- void UpdateUserHostRestrictions(URLPatternSet user_blocked_hosts,
- URLPatternSet user_allowed_hosts) override;
- void UpdateTabSpecificPermissions(const std::string& extension_id,
- URLPatternSet new_hosts,
- int tab_id,
- bool update_origin_allowlist) override;
- void UpdateUserScripts(base::ReadOnlySharedMemoryRegion shared_memory,
- mojom::HostIDPtr host_id) override;
- void ClearTabSpecificPermissions(
- const std::vector<std::string>& extension_ids,
- int tab_id,
- bool update_origin_allowlist) override;
- void WatchPages(const std::vector<std::string>& css_selectors) override;
- void OnRendererAssociatedRequest(
- mojo::PendingAssociatedReceiver<mojom::Renderer> receiver);
- void OnEventDispatcherRequest(
- mojo::PendingAssociatedReceiver<mojom::EventDispatcher> receiver);
- void OnDeliverMessage(int worker_thread_id,
- const PortId& target_port_id,
- const Message& message);
- void OnDispatchOnConnect(int worker_thread_id,
- const PortId& target_port_id,
- const std::string& channel_name,
- const ExtensionMsg_TabConnectionInfo& source,
- const ExtensionMsg_ExternalConnectionInfo& info);
- void OnDispatchOnDisconnect(int worker_thread_id,
- const PortId& port_id,
- const std::string& error_message);
- // mojom::EventDispatcher implementation.
- void DispatchEvent(mojom::DispatchEventParamsPtr params,
- base::Value::List event_args) override;
- // UserScriptSetManager::Observer implementation.
- void OnUserScriptsUpdated(const mojom::HostID& changed_host) override;
- void UpdateActiveExtensions();
- // Sets up the host permissions for |extension|.
- void InitOriginPermissions(const Extension* extension);
- // Updates the host permissions for the extension url to include only those
- // the extension currently has, removing any old entries.
- void UpdateOriginPermissions(const Extension& extension);
- // Enable custom element allowlist in Apps.
- void EnableCustomElementAllowlist();
- // Adds or removes bindings for all contexts.
- void UpdateAllBindings();
- // Adds or removes bindings for every context belonging to |extension|, due to
- // permissions change in the extension.
- void UpdateBindingsForExtension(const Extension& extension);
- void RegisterNativeHandlers(ModuleSystem* module_system,
- ScriptContext* context,
- NativeExtensionBindingsSystem* bindings_system,
- V8SchemaRegistry* v8_schema_registry);
- // Inserts static source code into |source_map_|.
- void PopulateSourceMap();
- // Returns whether the current renderer hosts a platform app.
- bool IsWithinPlatformApp();
- // Requires the GuestView modules in the module system of the ScriptContext
- // |context|.
- void RequireGuestViewModules(ScriptContext* context);
- // Creates the NativeExtensionBindingsSystem. Note: this may be called on any
- // thread, and thus cannot mutate any state or rely on state which can be
- // mutated in Dispatcher.
- std::unique_ptr<NativeExtensionBindingsSystem> CreateBindingsSystem(
- std::unique_ptr<IPCMessageSender> ipc_sender);
- void ResumeEvaluationOnWorkerThread(const ExtensionId& extension_id);
- // The delegate for this dispatcher to handle embedder-specific logic.
- std::unique_ptr<DispatcherDelegate> delegate_;
- // The IDs of extensions that failed to load, mapped to the error message
- // generated on failure.
- std::map<std::string, std::string> extension_load_errors_;
- // All the bindings contexts that are currently loaded for this renderer.
- // There is zero or one for each v8 context.
- std::unique_ptr<ScriptContextSet> script_context_set_;
- std::unique_ptr<ContentWatcher> content_watcher_;
- std::unique_ptr<UserScriptSetManager> user_script_set_manager_;
- std::unique_ptr<ScriptInjectionManager> script_injection_manager_;
- // The extensions and apps that are active in this process.
- ExtensionIdSet active_extension_ids_;
- ResourceBundleSourceMap source_map_;
- // Cache for the v8 representation of extension API schemas.
- std::unique_ptr<V8SchemaRegistry> v8_schema_registry_;
- // The bindings system associated with the main thread.
- std::unique_ptr<NativeExtensionBindingsSystem> bindings_system_;
- // The platforms system font family and size;
- std::string system_font_family_;
- std::string system_font_size_;
- // It is important for this to come after the ScriptInjectionManager, so that
- // the observer is destroyed before the UserScriptSet.
- base::ScopedObservation<UserScriptSetManager, UserScriptSetManager::Observer>
- user_script_set_manager_observation_{this};
- // Whether or not extension activity is enabled.
- bool activity_logging_enabled_;
- // The WebView partition ID associated with this process's storage partition,
- // if this renderer is a WebView guest render process. Otherwise, this will be
- // empty.
- std::string webview_partition_id_;
- // Extensions renderer receiver. This is an associated receiver because
- // it is dependent on other messages sent on other associated channels.
- mojo::AssociatedReceiver<mojom::Renderer> receiver_;
- // Extensions mojom::EventDispatcher receiver. This is an associated receiver
- // because it is dependent on other messages sent on other associated
- // channels.
- mojo::AssociatedReceiver<mojom::EventDispatcher> dispatcher_;
- // Used to hold a service worker information which is ready to execute but the
- // onloaded message haven't been received yet. We need to defer service worker
- // execution until the ExtensionMsg_Loaded message is received because we can
- // install extension bindings only after the onload message is received.
- // TODO(bashi): Consider to have a separate class to put this logic?
- struct PendingServiceWorker {
- scoped_refptr<base::SingleThreadTaskRunner> task_runner;
- blink::WebServiceWorkerContextProxy* context_proxy;
- PendingServiceWorker(blink::WebServiceWorkerContextProxy* context_proxy);
- ~PendingServiceWorker();
- };
- // This will be accessed both from the main thread and worker threads.
- std::map<ExtensionId, std::unique_ptr<PendingServiceWorker>>
- service_workers_paused_for_on_loaded_message_;
- base::Lock service_workers_paused_for_on_loaded_message_lock_;
- };
- } // namespace extensions
- #endif // EXTENSIONS_RENDERER_DISPATCHER_H_
|