chromium/extensions/browser/event_router.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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 {

// A dictionary of event names to lists of filters that this extension has
// registered from its lazy background page.
constexpr char kFilteredEvents[] =;

// Similar to |kFilteredEvents|, but applies to extension service worker events.
constexpr char kFilteredServiceWorkerEvents[] =;

// A message when mojom::EventRouter::AddListenerForMainThread() is called with
// an invalid param.
constexpr char kAddEventListenerWithInvalidParam[] =;

// A message when mojom::EventRouter::AddListenerForServiceWorker() is called
// with an invalid worker scope URL.
constexpr char kAddEventListenerWithInvalidWorkerScopeURL[] =;

// A message when mojom::EventRouter::AddListenerForServiceWorker() is called
// with an invalid extension ID.
constexpr char kAddEventListenerWithInvalidExtensionID[] =;

// A message when mojom::EventRouter::RemoveListenerForMainThread() is called
// with an invalid param.
constexpr char kRemoveEventListenerWithInvalidParam[] =;

// A message when mojom::EventRouter::RemoveListenerForServiceWorker() is called
// with an invalid worker scope URL.
constexpr char kRemoveEventListenerWithInvalidWorkerScopeURL[] =;

// A message when mojom::EventRouter::RemoveListenerForServiceWorker() is called
// with an invalid extension ID.
constexpr char kRemoveEventListenerWithInvalidExtensionID[] =;

// Sends a notification about an event to the API activity monitor and the
// ExtensionHost for |extension_id| on the UI thread. Can be called from any
// thread.
void NotifyEventDispatched(content::BrowserContext* browser_context,
                           const ExtensionId& extension_id,
                           const std::string& event_name,
                           const base::Value::List& args) {}

// Browser context is required for lazy context id. Before adding browser
// context member to EventListener, callers must pass in the browser context as
// a parameter.
// TODO(richardzh): Once browser context is added as a member to EventListener,
//                  update this method to get browser_context from listener
//                  instead of parameter.
LazyContextId LazyContextIdForListener(const EventListener* listener,
                                       BrowserContext* browser_context) {}

// A global identifier used to distinguish extension events.
base::AtomicSequenceNumber g_extension_event_id;

// Returns whether an event would cross the incognito boundary. e.g.
// incognito->regular or regular->incognito. This is allowed for some extensions
// that enable spanning-mode but is always disallowed for webUI.
// |context| refers to the BrowserContext of the receiver of the event.
bool CrossesIncognito(BrowserContext* context, const Event& event) {}

}  // namespace

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) {}

// static
EventRouter* EventRouter::Get(content::BrowserContext* browser_context) {}

// static
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) {}

// static.
bool EventRouter::CanDispatchEventToBrowserContext(BrowserContext* context,
                                                   const Extension* extension,
                                                   const Event& event) {}

// static
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 {}

// This constructor is only used by tests, for non-ServiceWorker context
// (background page, popup, tab, etc).
// is_lazy flag default to false.
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)
    :{}

}  // namespace extensions