blob: 5269aadfe785a556f9c86a0184e203a83acc081f [file] [log] [blame] [view]
Francois Dorayf7d340722019-04-05 20:28:501# About //components
2
3This directory is meant to house features or subsystems that are used in more
4than one part of the Chromium codebase.
5
John Abd-El-Malekb0608b72022-08-12 19:38:226## Use cases:
Francois Dorayf7d340722019-04-05 20:28:507
8 * Features that are shared by Chrome on iOS (`//ios/chrome`) and Chrome on
9 other platforms (`//chrome`).
10 * Note: `//ios` doesn't depend on `//chrome`.
11 * Features that are shared between multiple embedders of content. For example,
12 `//chrome` and `//android_webview`.
13 * Features that are shared between Blink and the browser process.
14 * Note: It is also possible to place code shared between Blink and the
15 browser process into `//third_party/blink/common`. The distinction comes
16 down to (a) whether Blink is the owner of the code in question or a
17 consumer of it and (b) whether the code in question is shared by Chrome
18 on iOS as well. If the code is conceptually its own cross-process
19 feature with Blink as a consumer, then `//components` can make sense. If
20 it's conceptually Blink code, then `//third_party/blink/common` likely
21 makes more sense. (In the so-far hypothetical case where it's
22 conceptually Blink code that is shared by iOS, raise the question on
23 chromium-dev@, where the right folks will see it).
24
John Abd-El-Malekb0608b72022-08-12 19:38:2225Note that the above list is meant to be exhaustive. A component should not be
26added just to separate it from other code in the same layer that is the only
David Dorwin154becc2022-10-20 20:55:5827consumer; that can be done with strict `DEPS` or GN `visibility` rules.
John Abd-El-Malekb0608b72022-08-12 19:38:2228
Ted Choc422440e32023-04-06 22:48:0329## Before adding a new component
30
31 * Is there an existing component that you can leverage instead of introducing
32 a new component?
33 * Can you restructure an existing component to logically encompass the
34 proposed new code?
35 * As a general rule, we prefer fewer top level components. So, consider
36 whether adding sub-features within an existing component is more
37 appropriate for your use case.
38 * Historically, dependency issues were simply addressed by adding new
39 components. But, you can (and it is preferred to) solve that by
40 restructing an existing component and its dependencies where possible.
41
Francois Dorayf7d340722019-04-05 20:28:5042## Guidelines for adding a new component
43
David Dorwin154becc2022-10-20 20:55:5844 * You will be added to an `OWNERS` file under `//components/{your component}`
Francois Dorayf7d340722019-04-05 20:28:5045 and be responsible for maintaining your addition.
Ted Choc422440e32023-04-06 22:48:0346 * You must specify at least two OWNERS for any new component.
Francois Dorayf7d340722019-04-05 20:28:5047 * A `//components/OWNER` must approve of the location of your code.
Ted Choc422440e32023-04-06 22:48:0348 * The CL (either commit message or comment) must explicitly specify what [use
49 case(s)](#use-cases) justify the new component.
Francois Dorayf7d340722019-04-05 20:28:5050 * Code must be needed in at least 2 places in Chrome that don't have a "higher
51 layered" directory that could facilitate sharing (e.g. `//content/common`,
52 `//chrome/utility`, etc.).
Colin Blundell17af29b2022-08-31 07:25:3353 * The CL adding a new component should be substantial enough so that
54 //components/OWNERS can see its basic intended structure and usage before
55 approving the addition (e.g., it should not just be an empty shell).
Ted Choc422440e32023-04-06 22:48:0356 * You must add a [`DIR_METADATA`](https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md)
57 file under `//components/{your component}` with an appropriately specified
58 bug-component.
Francois Dorayf7d340722019-04-05 20:28:5059
60## Dependencies of a component
61
62Components **cannot** depend on the higher layers of the Chromium codebase:
63
64 * `//android_webview`
65 * `//chrome`
66 * `//chromecast`
67 * `//headless`
68 * `//ios/chrome`
69 * `//content/shell`
70
71Components **can** depend on the lower layers of the Chromium codebase:
72
73 * `//base`
74 * `//gpu`
75 * `//mojo`
76 * `//net`
Alan Screen1c7382702020-09-25 00:07:1577 * `//printing`
Francois Dorayf7d340722019-04-05 20:28:5078 * `//ui`
79
80Components **can** depend on each other. This must be made explicit in the
81`DEPS` file of the component.
82
Matt Falkenhagenf28d6d72021-05-27 13:43:4183Components **can** depend on `//content/public`, `//ipc`, and
84`//third_party/blink/public`. This must be made explicit in the `DEPS` file of
85the component. If such a component is used by Chrome for iOS (which does not
86use content or IPC), the component will have to be in the form of a [layered
Colin Blundell207520752024-01-02 21:21:3387component](https://www.chromium.org/developers/design-documents/layered-components-design).
88In particular, code that is shared with iOS *cannot* depend on any of the
89above modules; those dependencies must be injected into the shared code (either via
90a layered component structure or directly from the embedder for simple dependencies
91such as booleans that can be passed as constructor parameters). It is not
92an acceptable solution to conditionally depend on the above modules in code shared
93with iOS.
Francois Dorayf7d340722019-04-05 20:28:5094
95`//chrome`, `//ios/chrome`, `//content` and `//ios/web` **can** depend on
96individual components. The dependency might have to be made explicit in the
97`DEPS` file of the higher layer (e.g. in `//content/browser/DEPS`). Circular
98dependencies are not allowed: if `//content` depends on a component, then that
99component cannot depend on `//content/public`, directly or indirectly.
100
101## Structure of a component
102
Matt Falkenhagenf28d6d72021-05-27 13:43:41103As mentioned above, components that depend on `//content/public`, `//ipc`, or
104`third_party/blink/public` might have to be in the form of a [layered
Francois Dorayf7d340722019-04-05 20:28:50105component](http://www.chromium.org/developers/design-documents/layered-components-design).
106
107Components that have bits of code that need to live in different processes (e.g.
108some code in the browser process, some in the renderer process, etc.) should
109separate the code into different subdirectories. Hence for a component named
110'foo' you might end up with a structure like the following (assuming that foo is
111not used by iOS and thus does not need to be a layered component):
112
David Dorwin154becc2022-10-20 20:55:58113 * `components/foo` - `BUILD.gn`, `DEPS`, `DIR_METADATA`, `OWNERS`, `README.md`
Francois Dorayf7d340722019-04-05 20:28:50114 * `components/foo/browser` - code that needs the browser process
115 * `components/foo/common` - for e.g. Mojo interfaces and such
116 * `components/foo/renderer` - code that needs renderer process
117
David Dorwin154becc2022-10-20 20:55:58118These subdirectories should have `DEPS` files with the relevant restrictions in
Francois Dorayf7d340722019-04-05 20:28:50119place, i.e. only `components/foo/browser` should be allowed to #include from
Matt Falkenhagenf28d6d72021-05-27 13:43:41120`content/public/browser`. Note that `third_party/blink/public` is a
121renderer process directory except for `third_party/blink/public/common` which
122can be used by all processes.
Francois Dorayf7d340722019-04-05 20:28:50123
124Note that there may also be an `android` subdir, with a Java source code
125structure underneath it where the package name is org.chromium.components.foo,
126and with subdirs after 'foo' to illustrate process, e.g. 'browser' or
127'renderer':
128
David Dorwin154becc2022-10-20 20:55:58129 * `components/foo/android/`{`OWNERS`, `DEPS`}
Francois Dorayf7d340722019-04-05 20:28:50130 * `components/foo/android/java/src/org/chromium/components/foo/browser/`
131 * `components/foo/android/javatests/src/org/chromium/components/foo/browser/`
132
133Code in a component should be placed in a namespace corresponding to the name of
134the component; e.g. for a component living in `//components/foo`, code in that
135component should be in the `foo::` namespace.