Danil Somsikov | 4054d1e | 2023-04-13 08:22:06 | [diff] [blame] | 1 | # Chrome DevTools Protocol |
| 2 | |
| 3 | ## Definitions |
| 4 | ### Domain |
| 5 | A group of CDP methods and events, which can usually be individually enabled or |
| 6 | disabled and individually supported by different types of targets. |
| 7 | |
| 8 | *Source: [Chrome DevTools Walkthrough](https://docs.google.com/document/d/1QG7P18wDIhB_twNbkvEAbgJfNoTkyTRXf-6Nk2TTYPI/edit#)* |
| 9 | |
| 10 | ### Agent (in blink) or Handler (in browser) |
| 11 | TLDR: Backend implementation of a domain that syncs with the frontend. |
| 12 | |
| 13 | Agents and Handlers are backend classes that implement individual protocol |
| 14 | domains. Some domains are implemented as agents in the renderer process (either |
| 15 | in Blink or v8; no agents are currently present in the content/renderer so far) |
| 16 | and some as handlers in the browser process (implemented either by the content |
| 17 | layer or by the embedder). A domain may be implemented by multiple agents or |
| 18 | handlers spanning several layers and processes, e.g. have instances in |
| 19 | `chrome/`, `content/` and `blink/renderer/` . A single command may be handled by |
| 20 | multiple layers in the following sequence: |
| 21 | embedder, content browser, blink, V8. An agent may indicate that it has |
| 22 | completed handling the command or let the command fall-through to the |
| 23 | next layer. |
| 24 | |
| 25 | |
| 26 | *Source: |
| 27 | - [Chrome DevTools Contribution Guide](https://docs.google.com/document/d/1WNF-KqRSzPLUUfZqQG5AFeU_Ll8TfWYcJasa_XGf7ro/edit#) |
| 28 | - [third_party/blink/public/devtools_protocol - chromium/src - Git at Google](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/public/devtools_protocol/) |
| 29 | |
| 30 | |
| 31 | ## Background |
| 32 | |
| 33 | ### browser_protocol.pdl |
| 34 | |
| 35 | The `browser_protocol.pdl` file is the source of truth that is used to generate |
| 36 | the `browser_protocol.json` file and the `.ts`, `.h` and `.cc` files. |
| 37 | |
| 38 | However, there are multiple `browser_protocol.pdl` files across the codebase. |
| 39 | The main one is located at (in your chromium repo): |
| 40 | |
| 41 | `third_party/blink/public/devtools_protocol/browser_protocol.pdl` |
| 42 | |
| 43 | This is the one you should modify and the other ones will be synced using |
| 44 | different commands explained later. |
| 45 | |
| 46 | There’s also a separate `js_protocol.pdl` that has only V8-specific domains. |
| 47 | |
| 48 | ## Create a new Protocol |
| 49 | |
| 50 | ### 1- Create your domain on the Chromium repository |
| 51 | |
| 52 | #### 1.1- Add your domain to the main browser_protocol.pdl file in your |
| 53 | |
| 54 | chromium repository To create a new domain, you should add your new domain to |
| 55 | `third_party/blink/public/devtools_protocol/browser_protocol.pdl` |
| 56 | |
| 57 | #### 1.2- Modify headless/BUILD.gn |
| 58 | Open the file `headless/BUILD.gn` in your chromium repository and the name of |
| 59 | your new domain under the devtools_domain section. |
| 60 | |
| 61 | #### 1.3- Modify third_party/blink/renderer/core/inspector/BUILD.gn |
| 62 | Open the file `third_party/blink/renderer/core/inspector/BUILD.gn` in your |
| 63 | chromium repository and add the new protocol files to be generated under the |
| 64 | outputs section. The convention is to use the domain name converting it from |
| 65 | camel case to snake case. |
| 66 | |
| 67 | The protocol files generated will list the methods that your Agent will need to |
| 68 | implement to enable the communication between the Chrome DevTools and Chromium. |
| 69 | |
| 70 | #### 1.4- Modify inspector_protocol_config.json |
| 71 | |
| 72 | Open the file |
| 73 | `third_party/blink/renderer/core/inspector/inspector_protocol_config.json` and |
| 74 | under `protocol.options`, add your new domain: |
| 75 | |
| 76 | ``` |
| 77 | { |
| 78 | "domain": "YourNewDomain" |
| 79 | } |
| 80 | ``` |
| 81 | |
| 82 | #### 1.5- Build chromium |
| 83 | Build chromium as you normally would. |
| 84 | |
| 85 | #### 1.6- See the newly generated protocol C++ files |
| 86 | Your new domain files should be generated in this folder: |
| 87 | |
| 88 | ``` |
Etienne Noel | 0d4ffb3 | 2023-06-16 18:31:51 | [diff] [blame] | 89 | src/out/Default/gen/third_party/blink/renderer/core/inspector/protocol/your_new_domain.cc |
| 90 | src/out/Default/gen/third_party/blink/renderer/core/inspector/protocol/your_new_domain.h |
Danil Somsikov | 4054d1e | 2023-04-13 08:22:06 | [diff] [blame] | 91 | ``` |
| 92 | |
Etienne Noel | 0d4ffb3 | 2023-06-16 18:31:51 | [diff] [blame] | 93 | #### 1.7- Add the agent to the devtools-frontend/front_end/core/protocol_client/InspectorBackend.ts |
| 94 | |
| 95 | Open the file `devtools-frontend/front_end/core/protocol_client/InspectorBackend.ts` and add a new method to expose your Agent. |
| 96 | |
| 97 | ``` |
| 98 | youNewDomainAgent(): ProtocolProxyApi.YourNewAgentApi { |
| 99 | return this.getAgent('YourNewAgent'); |
| 100 | } |
| 101 | ``` |
| 102 | |
| 103 | #### 1.8- Add the newly generated protocol files to the BUILD.gn |
| 104 | |
| 105 | In your chromium repository, open the file |
| 106 | `third_party/blink/renderer/core/inspector/BUILD.gn` and add the newly generated |
| 107 | protocol files. This will make them available to be used later in the Agent |
| 108 | class. |
| 109 | |
| 110 | ``` |
| 111 | outputs = [ |
| 112 | ... |
| 113 | "inspector/protocol/your_new_domain.cc", |
| 114 | "inspector/protocol/your_new_domain.h", |
| 115 | ``` |
Danil Somsikov | 4054d1e | 2023-04-13 08:22:06 | [diff] [blame] | 116 | |
Ergun Erdogmus | 97a5ea3 | 2024-01-30 13:55:28 | [diff] [blame] | 117 | ### 2- Sync the browser_protocol files and generate the protocol resources |
Danil Somsikov | 4054d1e | 2023-04-13 08:22:06 | [diff] [blame] | 118 | As mentioned before, there are many browser_protocol files. To synchronize the |
| 119 | modifications, run this command from your Chrome DevTools repository: |
| 120 | |
| 121 | ``` |
| 122 | scripts/deps/roll_deps.py ~/chromium/src . |
| 123 | ``` |
| 124 | |
| 125 | The first parameter is the path from your Chrome DevTools repository to the |
| 126 | chromium repository. The second parameter is the root of the |
| 127 | Chrome DevTools repository. |
| 128 | |
Danil Somsikov | 4054d1e | 2023-04-13 08:22:06 | [diff] [blame] | 129 | ### 3- Create the Agent on the Chromium repository |
| 130 | |
| 131 | #### 3.1- Create the Agent class |
| 132 | The Agent class should inherit the newly created protocol |
| 133 | `protocol::YourNewDomainAgent::Metainfo` |
| 134 | |
| 135 | ``` |
| 136 | class MODULES_EXPORT YourNewDomainAgent final : public InspectorBaseAgent<protocol::YourNewDomainAgent::Metainfo> { |
| 137 | ``` |
| 138 | |
| 139 | #### 3.2- Register the Agent |
| 140 | The Agent must be registered with the Session. To do so, go to the file |
| 141 | `third_party/blink/renderer/modules/modules_initializer.cc` and append it to the |
| 142 | session in this method: |
| 143 | |
| 144 | ``` |
| 145 | void ModulesInitializer::InitInspectorAgentSession { |
| 146 | … |
| 147 | session->CreateAndAppend<YourNewAgent>... |
| 148 | ``` |
| 149 | |
| 150 | ### 4- Setup the communication from the Chrome DevTools repository |
| 151 | In the TypeScript class, your agent can now be accessible directly from the |
| 152 | target. With the target, you can simply access your agent like this: |
| 153 | |
| 154 | ``` |
| 155 | initialize(target: SDK.Target.Target) { |
| 156 | target.yourNewDomainAgent(); |
| 157 | } |
| 158 | ``` |