#ifndef EXTENSIONS_RENDERER_WORKER_THREAD_DISPATCHER_H_
#define EXTENSIONS_RENDERER_WORKER_THREAD_DISPATCHER_H_
#include <map>
#include <memory>
#include <string>
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
#include "base/values.h"
#include "content/public/renderer/render_thread_observer.h"
#include "content/public/renderer/worker_thread.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/mojom/event_dispatcher.mojom.h"
#include "extensions/common/mojom/event_router.mojom.h"
#include "extensions/common/mojom/service_worker_host.mojom.h"
#include "ipc/ipc_sync_message_filter.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
namespace base {
class SingleThreadTaskRunner;
class UnguessableToken;
}
namespace content {
class RenderThread;
}
class GURL;
struct ExtensionMsg_OnConnectData;
namespace extensions {
class NativeExtensionBindingsSystem;
class ScriptContext;
class ServiceWorkerData;
class V8SchemaRegistry;
struct Message;
struct PortId;
class WorkerThreadDispatcher : public content::RenderThreadObserver,
public IPC::Sender,
public mojom::EventDispatcher {
public:
WorkerThreadDispatcher();
WorkerThreadDispatcher(const WorkerThreadDispatcher&) = delete;
WorkerThreadDispatcher& operator=(const WorkerThreadDispatcher&) = delete;
~WorkerThreadDispatcher() override;
static WorkerThreadDispatcher* Get();
static NativeExtensionBindingsSystem* GetBindingsSystem();
static V8SchemaRegistry* GetV8SchemaRegistry();
static ScriptContext* GetScriptContext();
static ServiceWorkerData* GetServiceWorkerData();
void Init(content::RenderThread* render_thread);
bool Send(IPC::Message* message) override;
void AddWorkerData(
int64_t service_worker_version_id,
base::UnguessableToken activation_sequence,
ScriptContext* script_context,
std::unique_ptr<NativeExtensionBindingsSystem> bindings_system);
void RemoveWorkerData(int64_t service_worker_version_id);
void DidInitializeContext(int64_t service_worker_version_id);
void DidStartContext(const GURL& service_worker_scope,
int64_t service_worker_version_id);
void DidStopContext(const GURL& service_worker_scope,
int64_t service_worker_version_id);
void IncrementServiceWorkerActivity(int64_t service_worker_version_id,
const std::string& request_uuid);
void DecrementServiceWorkerActivity(int64_t service_worker_version_id,
const std::string& request_uuid);
void RequestWorker(mojom::RequestParamsPtr params);
void WorkerResponseAck(int request_id, int64_t service_worker_version_id);
bool OnControlMessageReceived(const IPC::Message& message) override;
bool UpdateBindingsForWorkers(const ExtensionId& extension_id);
void SendAddEventListener(const std::string& extension_id,
const GURL& scope,
const std::string& event_name,
int64_t service_worker_version_id,
int worker_thread_id);
void SendAddEventLazyListener(const std::string& extension_id,
const GURL& scope,
const std::string& event_name);
void SendAddEventFilteredListener(const std::string& extension_id,
const GURL& scope,
const std::string& event_name,
int64_t service_worker_version_id,
int worker_thread_id,
base::Value::Dict filter,
bool add_lazy_listener);
void SendRemoveEventListener(const std::string& extension_id,
const GURL& scope,
const std::string& event_name,
int64_t service_worker_version_id,
int worker_thread_id);
void SendRemoveEventLazyListener(const std::string& extension_id,
const GURL& scope,
const std::string& event_name);
void SendRemoveEventFilteredListener(const std::string& extension_id,
const GURL& scope,
const std::string& event_name,
int64_t service_worker_version_id,
int worker_thread_id,
base::Value::Dict filter,
bool remove_lazy_listener);
mojom::EventRouter* GetEventRouterOnIO();
mojom::ServiceWorkerHost* GetServiceWorkerHostOnIO();
void DispatchEvent(mojom::DispatchEventParamsPtr params,
base::Value::List event_args) override;
private:
static bool HandlesMessageOnWorkerThread(const IPC::Message& message);
static void ForwardIPC(int worker_thread_id, const IPC::Message& message);
static void UpdateBindingsOnWorkerThread(const ExtensionId& extension_id);
static void DispatchEventOnWorkerThread(mojom::DispatchEventParamsPtr params,
base::Value::List event_args);
void OnMessageReceivedOnWorkerThread(int worker_thread_id,
const IPC::Message& message);
bool PostTaskToWorkerThread(int worker_thread_id, base::OnceClosure task);
void PostTaskToIOThread(base::OnceClosure task);
void OnResponseWorker(int worker_thread_id,
int request_id,
bool succeeded,
ExtensionMsg_ResponseWorkerData response,
const std::string& error);
void OnValidateMessagePort(int worker_thread_id, const PortId& id);
void OnDispatchOnConnect(int worker_thread_id,
const ExtensionMsg_OnConnectData& connect_data);
void OnDeliverMessage(int worker_thread_id,
const PortId& target_port_id,
const Message& message);
void OnDispatchOnDisconnect(int worker_thread_id,
const PortId& port_id,
const std::string& error_message);
void DispatchEventHelper(mojom::DispatchEventParamsPtr params,
base::Value::List event_args);
scoped_refptr<IPC::SyncMessageFilter> message_filter_;
using IDToTaskRunnerMap = std::map<base::PlatformThreadId, base::TaskRunner*>;
IDToTaskRunnerMap task_runner_map_;
base::Lock task_runner_map_lock_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
mojo::AssociatedRemote<mojom::EventRouter> event_router_remote_;
mojo::AssociatedRemote<mojom::ServiceWorkerHost> service_worker_host_;
};
}
#endif