#include "extensions/browser/event_router.h"
#include <stddef.h>
#include <optional>
#include <string_view>
#include <utility>
#include "base/atomic_sequence_num.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/observer_list.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_util.h"
#include "components/crx_file/id_util.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
#include "extensions/browser/api_activity_monitor.h"
#include "extensions/browser/bad_message.h"
#include "extensions/browser/browser_process_context_data.h"
#include "extensions/browser/event_router_factory.h"
#include "extensions/browser/events/lazy_event_dispatcher.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_util.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/process_map.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_api.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/extension_urls.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/manifest_handlers/incognito_info.h"
#include "extensions/common/mojom/context_type.mojom.h"
#include "extensions/common/mojom/event_dispatcher.mojom.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/utils/extension_utils.h"
#include "ipc/ipc_channel_proxy.h"
#include "url/origin.h"
BrowserContext;
BrowserThread;
RenderProcessHost;
namespace extensions {
namespace {
constexpr char kFilteredEvents[] = …;
constexpr char kFilteredServiceWorkerEvents[] = …;
constexpr char kAddEventListenerWithInvalidParam[] = …;
constexpr char kAddEventListenerWithInvalidWorkerScopeURL[] = …;
constexpr char kAddEventListenerWithInvalidExtensionID[] = …;
constexpr char kRemoveEventListenerWithInvalidParam[] = …;
constexpr char kRemoveEventListenerWithInvalidWorkerScopeURL[] = …;
constexpr char kRemoveEventListenerWithInvalidExtensionID[] = …;
void NotifyEventDispatched(content::BrowserContext* browser_context,
const ExtensionId& extension_id,
const std::string& event_name,
const base::Value::List& args) { … }
LazyContextId LazyContextIdForListener(const EventListener* listener,
BrowserContext* browser_context) { … }
base::AtomicSequenceNumber g_extension_event_id;
bool CrossesIncognito(BrowserContext* context, const Event& event) { … }
}
const char EventRouter::kRegisteredLazyEvents[] = …;
const char EventRouter::kRegisteredServiceWorkerEvents[] = …;
void EventRouter::DispatchExtensionMessage(
content::RenderProcessHost* rph,
int worker_thread_id,
content::BrowserContext* browser_context,
const mojom::HostID& host_id,
int event_id,
const std::string& event_name,
base::Value::List event_args,
UserGestureState user_gesture,
mojom::EventFilteringInfoPtr info,
mojom::EventDispatcher::DispatchEventCallback callback) { … }
void EventRouter::RouteDispatchEvent(
content::RenderProcessHost* rph,
mojom::DispatchEventParamsPtr params,
base::Value::List event_args,
mojom::EventDispatcher::DispatchEventCallback callback) { … }
EventRouter* EventRouter::Get(content::BrowserContext* browser_context) { … }
std::string EventRouter::GetBaseEventName(const std::string& full_event_name) { … }
void EventRouter::DispatchEventToSender(
content::RenderProcessHost* rph,
content::BrowserContext* browser_context,
const mojom::HostID& host_id,
events::HistogramValue histogram_value,
const std::string& event_name,
int worker_thread_id,
int64_t service_worker_version_id,
base::Value::List event_args,
mojom::EventFilteringInfoPtr info) { … }
bool EventRouter::CanDispatchEventToBrowserContext(BrowserContext* context,
const Extension* extension,
const Event& event) { … }
void EventRouter::BindForRenderer(
int render_process_id,
mojo::PendingAssociatedReceiver<mojom::EventRouter> receiver) { … }
EventRouter::EventRouter(BrowserContext* browser_context,
ExtensionPrefs* extension_prefs)
: … { … }
EventRouter::~EventRouter() { … }
content::RenderProcessHost*
EventRouter::GetRenderProcessHostForCurrentReceiver() { … }
BrowserContext* EventRouter::GetIncognitoContextIfAccessible(
const ExtensionId& extension_id) { … }
BrowserContext* EventRouter::GetIncognitoContext() { … }
void EventRouter::AddListenerForMainThread(
mojom::EventListenerPtr event_listener) { … }
void EventRouter::AddListenerForServiceWorker(
mojom::EventListenerPtr event_listener) { … }
void EventRouter::AddLazyListenerForMainThread(const ExtensionId& extension_id,
const std::string& event_name) { … }
void EventRouter::AddLazyListenerForServiceWorker(
const ExtensionId& extension_id,
const GURL& worker_scope_url,
const std::string& event_name) { … }
void EventRouter::AddFilteredListenerForMainThread(
mojom::EventListenerOwnerPtr listener_owner,
const std::string& event_name,
base::Value::Dict filter,
bool add_lazy_listener) { … }
void EventRouter::AddFilteredListenerForServiceWorker(
const ExtensionId& extension_id,
const std::string& event_name,
mojom::ServiceWorkerContextPtr service_worker_context,
base::Value::Dict filter,
bool add_lazy_listener) { … }
void EventRouter::RemoveListenerForMainThread(
mojom::EventListenerPtr event_listener) { … }
void EventRouter::RemoveListenerForServiceWorker(
mojom::EventListenerPtr event_listener) { … }
void EventRouter::RemoveLazyListenerForMainThread(
const ExtensionId& extension_id,
const std::string& event_name) { … }
void EventRouter::RemoveLazyListenerForServiceWorker(
const ExtensionId& extension_id,
const GURL& worker_scope_url,
const std::string& event_name) { … }
void EventRouter::RemoveFilteredListenerForMainThread(
mojom::EventListenerOwnerPtr listener_owner,
const std::string& event_name,
base::Value::Dict filter,
bool remove_lazy_listener) { … }
void EventRouter::RemoveFilteredListenerForServiceWorker(
const ExtensionId& extension_id,
const std::string& event_name,
mojom::ServiceWorkerContextPtr service_worker_context,
base::Value::Dict filter,
bool remove_lazy_listener) { … }
void EventRouter::AddEventListener(const std::string& event_name,
RenderProcessHost* process,
const ExtensionId& extension_id) { … }
void EventRouter::AddServiceWorkerEventListener(
mojom::EventListenerPtr event_listener,
RenderProcessHost* process) { … }
void EventRouter::RemoveEventListener(const std::string& event_name,
RenderProcessHost* process,
const ExtensionId& extension_id) { … }
void EventRouter::RemoveServiceWorkerEventListener(
mojom::EventListenerPtr event_listener,
RenderProcessHost* process) { … }
void EventRouter::AddEventListenerForURL(const std::string& event_name,
RenderProcessHost* process,
const GURL& listener_url) { … }
void EventRouter::RemoveEventListenerForURL(const std::string& event_name,
RenderProcessHost* process,
const GURL& listener_url) { … }
void EventRouter::RegisterObserver(Observer* observer,
const std::string& event_name) { … }
void EventRouter::UnregisterObserver(Observer* observer) { … }
void EventRouter::AddObserverForTesting(TestObserver* observer) { … }
void EventRouter::RemoveObserverForTesting(TestObserver* observer) { … }
void EventRouter::OnListenerAdded(const EventListener* listener) { … }
void EventRouter::OnListenerRemoved(const EventListener* listener) { … }
void EventRouter::ObserveProcess(RenderProcessHost* process) { … }
void EventRouter::RenderProcessExited(
RenderProcessHost* host,
const content::ChildProcessTerminationInfo& info) { … }
void EventRouter::RenderProcessHostDestroyed(RenderProcessHost* host) { … }
void EventRouter::AddFilteredEventListener(
const std::string& event_name,
RenderProcessHost* process,
mojom::EventListenerOwnerPtr listener_owner,
mojom::ServiceWorkerContext* service_worker_context,
const base::Value::Dict& filter,
bool add_lazy_listener) { … }
void EventRouter::RemoveFilteredEventListener(
const std::string& event_name,
RenderProcessHost* process,
mojom::EventListenerOwnerPtr listener_owner,
mojom::ServiceWorkerContext* service_worker_context,
const base::Value::Dict& filter,
bool remove_lazy_listener) { … }
bool EventRouter::HasEventListener(const std::string& event_name) const { … }
bool EventRouter::ExtensionHasEventListener(
const ExtensionId& extension_id,
const std::string& event_name) const { … }
bool EventRouter::URLHasEventListener(const GURL& url,
const std::string& event_name) const { … }
std::set<std::string> EventRouter::GetRegisteredEvents(
const ExtensionId& extension_id,
RegisteredEventType type) const { … }
void EventRouter::ClearRegisteredEventsForTest(
const ExtensionId& extension_id) { … }
bool EventRouter::HasLazyEventListenerForTesting(
const std::string& event_name) { … }
bool EventRouter::HasNonLazyEventListenerForTesting(
const std::string& event_name) { … }
void EventRouter::RemoveFilterFromEvent(const std::string& event_name,
const ExtensionId& extension_id,
bool is_for_service_worker,
const base::Value::Dict& filter) { … }
const base::Value::Dict* EventRouter::GetFilteredEvents(
const ExtensionId& extension_id,
RegisteredEventType type) { … }
void EventRouter::BroadcastEvent(std::unique_ptr<Event> event) { … }
void EventRouter::DispatchEventToExtension(const ExtensionId& extension_id,
std::unique_ptr<Event> event) { … }
void EventRouter::DispatchEventToURL(const GURL& url,
std::unique_ptr<Event> event) { … }
void EventRouter::DispatchEventWithLazyListener(const ExtensionId& extension_id,
std::unique_ptr<Event> event) { … }
void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id,
const GURL& restrict_to_url,
std::unique_ptr<Event> event) { … }
void EventRouter::DispatchEventToProcess(
const ExtensionId& extension_id,
const GURL& listener_url,
RenderProcessHost* process,
int64_t service_worker_version_id,
int worker_thread_id,
const Event& event,
const base::Value::Dict* listener_filter,
bool did_enqueue) { … }
void EventRouter::DecrementInFlightEventsForServiceWorker(
const WorkerId& worker_id,
int event_id,
bool event_will_run_in_lazy_background_page_script) { … }
void EventRouter::DecrementInFlightEventsForRenderFrameHost(
int render_process_host,
const ExtensionId& extension_id,
int event_id,
bool event_will_run_in_background_page_script) { … }
void EventRouter::IncrementInFlightEvents(
BrowserContext* context,
RenderProcessHost* process,
const Extension* extension,
int event_id,
const std::string& event_name,
base::TimeTicks dispatch_start_time,
int64_t service_worker_version_id,
EventDispatchSource dispatch_source,
bool lazy_background_active_on_dispatch,
events::HistogramValue histogram_value) { … }
void EventRouter::OnEventAck(BrowserContext* context,
const ExtensionId& extension_id,
const std::string& event_name) { … }
bool EventRouter::HasRegisteredEvents(const ExtensionId& extension_id) const { … }
void EventRouter::ReportEvent(events::HistogramValue histogram_value,
const Extension* extension,
bool did_enqueue) { … }
void EventRouter::DispatchPendingEvent(
std::unique_ptr<Event> event,
std::unique_ptr<LazyContextTaskQueue::ContextInfo> params) { … }
void EventRouter::SetRegisteredEvents(const ExtensionId& extension_id,
const std::set<std::string>& events,
RegisteredEventType type) { … }
void EventRouter::AddFilterToEvent(const std::string& event_name,
const ExtensionId& extension_id,
bool is_for_service_worker,
const base::Value::Dict& filter) { … }
void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) { … }
void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionReason reason) { … }
void EventRouter::AddLazyEventListenerImpl(
std::unique_ptr<EventListener> listener,
RegisteredEventType type) { … }
void EventRouter::RemoveLazyEventListenerImpl(
std::unique_ptr<EventListener> listener,
RegisteredEventType type) { … }
void EventRouter::BindServiceWorkerEventDispatcher(
int render_process_id,
int worker_thread_id,
mojo::PendingAssociatedRemote<mojom::EventDispatcher> event_dispatcher) { … }
void EventRouter::UnbindServiceWorkerEventDispatcher(RenderProcessHost* host,
int worker_thread_id) { … }
Event::Event(events::HistogramValue histogram_value,
std::string_view event_name,
base::Value::List event_args)
: … { … }
Event::Event(events::HistogramValue histogram_value,
std::string_view event_name,
base::Value::List event_args,
content::BrowserContext* restrict_to_browser_context,
std::optional<mojom::ContextType> restrict_to_context_type)
: … { … }
Event::Event(events::HistogramValue histogram_value,
std::string_view event_name,
base::Value::List event_args,
content::BrowserContext* restrict_to_browser_context,
std::optional<mojom::ContextType> restrict_to_context_type,
const GURL& event_url,
EventRouter::UserGestureState user_gesture,
mojom::EventFilteringInfoPtr info,
bool lazy_background_active_on_dispatch,
base::TimeTicks dispatch_start_time)
: … { … }
Event::~Event() = default;
std::unique_ptr<Event> Event::DeepCopy() const { … }
EventListenerInfo::EventListenerInfo(const std::string& event_name,
const ExtensionId& extension_id,
const GURL& listener_url,
content::BrowserContext* browser_context)
: … { … }
EventListenerInfo::EventListenerInfo(const std::string& event_name,
const ExtensionId& extension_id,
const GURL& listener_url,
content::BrowserContext* browser_context,
int worker_thread_id,
int64_t service_worker_version_id,
bool is_lazy)
: … { … }
}