A group of CDP methods and events, which can usually be individually enabled or disabled and individually supported by different types of targets.
Source: Chrome DevTools Walkthrough
TLDR: Backend implementation of a domain that syncs with the frontend.
Agents and Handlers are backend classes that implement individual protocol domains. Some domains are implemented as agents in the renderer process (either in Blink or v8; no agents are currently present in the content/renderer so far) and some as handlers in the browser process (implemented either by the content layer or by the embedder). A domain may be implemented by multiple agents or handlers spanning several layers and processes, e.g. have instances in chrome/
, content/
and blink/renderer/
. A single command may be handled by multiple layers in the following sequence: embedder, content browser, blink, V8. An agent may indicate that it has completed handling the command or let the command fall-through to the next layer.
*Source:
The browser_protocol.pdl
file is the source of truth that is used to generate the browser_protocol.json
file and the .ts
, .h
and .cc
files.
However, there are multiple browser_protocol.pdl
files across the codebase. The main one is located at (in your chromium repo):
third_party/blink/public/devtools_protocol/browser_protocol.pdl
This is the one you should modify and the other ones will be synced using different commands explained later.
There’s also a separate js_protocol.pdl
that has only V8-specific domains.
chromium repository To create a new domain, you should add your new domain to third_party/blink/public/devtools_protocol/browser_protocol.pdl
Open the file headless/BUILD.gn
in your chromium repository and the name of your new domain under the devtools_domain section.
Open the file third_party/blink/renderer/core/inspector/BUILD.gn
in your chromium repository and add the new protocol files to be generated under the outputs section. The convention is to use the domain name converting it from camel case to snake case.
The protocol files generated will list the methods that your Agent will need to implement to enable the communication between the Chrome DevTools and Chromium.
Open the file third_party/blink/renderer/core/inspector/inspector_protocol_config.json
and under protocol.options
, add your new domain:
{ "domain": "YourNewDomain" }
Build chromium as you normally would.
Your new domain files should be generated in this folder:
src/out/Default/gen/third_party/blink/renderer/core/inspector/protocol/your_new_domain.cc src/out/Default/gen/third_party/blink/renderer/core/inspector/protocol/your_new_domain.h
Open the file devtools-frontend/front_end/core/protocol_client/InspectorBackend.ts
and add a new method to expose your Agent.
youNewDomainAgent(): ProtocolProxyApi.YourNewAgentApi { return this.getAgent('YourNewAgent'); }
In your chromium repository, open the file third_party/blink/renderer/core/inspector/BUILD.gn
and add the newly generated protocol files. This will make them available to be used later in the Agent class.
outputs = [ ... "inspector/protocol/your_new_domain.cc", "inspector/protocol/your_new_domain.h",
As mentioned before, there are many browser_protocol files. To synchronize the modifications, run this command from your Chrome DevTools repository:
scripts/deps/roll_deps.py ~/chromium/src .
The first parameter is the path from your Chrome DevTools repository to the chromium repository. The second parameter is the root of the Chrome DevTools repository.
The Agent class should inherit the newly created protocol protocol::YourNewDomainAgent::Metainfo
class MODULES_EXPORT YourNewDomainAgent final : public InspectorBaseAgent<protocol::YourNewDomainAgent::Metainfo> {
The Agent must be registered with the Session. To do so, go to the file third_party/blink/renderer/modules/modules_initializer.cc
and append it to the session in this method:
void ModulesInitializer::InitInspectorAgentSession { … session->CreateAndAppend<YourNewAgent>...
In the TypeScript class, your agent can now be accessible directly from the target. With the target, you can simply access your agent like this:
initialize(target: SDK.Target.Target) { target.yourNewDomainAgent(); }