Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 1 | # Content API |
| 2 | |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 3 | `//content/public` is the API exposed to embedders of the [content |
| 4 | module](/content/README.md). |
| 5 | |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 6 | ## Motivation |
| 7 | - isolate developers working on Chrome from inner workings of content |
| 8 | - make the boundary between content and chrome clear to developers and other |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 9 | embedders |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 10 | |
| 11 | ## Design |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 12 | In general, we follow the design of the [Blink Public |
| 13 | API](/third_party/blink/public/README.md). This makes it easier for people |
| 14 | who're already familiar with it, and also keeps things consistent. |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 15 | |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 16 | - `//content/public` should contain only interfaces, enums, structs and (rarely) |
| 17 | static functions. |
| 18 | - An exception is `//content/public/test`. We allow concrete classes that |
| 19 | chrome test classes derive from or use in here. |
John Abd-El-Malek | 59eacd67 | 2021-03-26 07:26:16 | [diff] [blame] | 20 | - Tests for files in `//content/public` should be inside implementation directories, |
| 21 | e.g. `//content/browser`, `//content/renderer` etc... |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 22 | - While we don't allow old-style Chrome IPC `_messages.h` files in |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 23 | `//content/public`, we do allow `.mojom` files (see |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 24 | [discussion](https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-mojo/cross-module/chromium-mojo/ZR2YlRV7Uxs/Ce-h_AaWCgAJ)). |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 25 | If a mojom is only used inside content, it should be in |
| 26 | `//content/common`. If it's an interface that is implemented or called by |
| 27 | content's embedder, then it belongs in `//content/public/common`. |
| 28 | - In general, if there is a struct or enum which is only used by an interface, |
| 29 | they are put in the same file, but when the struct/enum is used in other |
| 30 | places or if it's pretty big, then it should be in its own file. |
| 31 | - All code under `//content` should be in the `"content"` namespace. |
| 32 | - Interfaces that content implements usually should be pure abstract, because |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 33 | usually there's only one implementation. These should not be implemented |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 34 | outside of content. (i.e., content will freely assume that it can cast to |
| 35 | its implementation(s)). |
| 36 | - Interfaces that embedders implement, especially ones which are used in tests |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 37 | or are observer-style and have many implementations, should have default |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 38 | (empty) implementations. |
| 39 | - Prefer enum classes over enum types. For enum types, the value should start |
| 40 | with the name of the type, i.e., `PAGE_TRANSITION_LINK` in the |
| 41 | `content::PageTransition` enum. |
| 42 | - content implementation code should use other implementations directly and |
| 43 | not go through the interface (i.e., code in `//content/renderer` should use |
| 44 | `RenderViewImpl` instead of `content::RenderView`). |
| 45 | - It's acceptable to put implementation files that hold constructors/destructors |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 46 | of interfaces/structs which might have member variables. For structs, this |
| 47 | covers initializing member variables. For interfaces (i.e. |
| 48 | `RenderViewObserver`) this might cover things like automatic |
| 49 | registration/unregistration. Normally we would put this small code in headers, |
| 50 | but because of the clang checks against putting code in headers, we're forced |
| 51 | to put it in .cc files (we don't want to make a clang exception for the |
| 52 | `content/public` directory since that would lead to confusion). |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 53 | - When code in chrome implements an interface from content, usually the |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 54 | convention is to prefix the implementation with "Chrome" (i.e. |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 55 | `ChromeContentBrowserClient` derives from `content::ContentBrowserClient`). |
| 56 | - Only expose methods in the public API that embedders need. If a method is only |
| 57 | used by other code in content, it belongs in `foo_impl.h` and not `foo.h`. |
| 58 | - Methods in the API should be there because either content is calling out to |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 59 | its embedder, or the embedder is calling to content. There shouldn't be any |
| 60 | methods which are used to call from the embedder to the embedder. |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 61 | - All classes/structs/enums in the public API must be used by embedders and |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 62 | content. i.e. if the chrome layer uses a struct but content doesn't know about |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 63 | it, it doesn't belong in `//content/public` but instead some module that's |
| 64 | higher level. |
| 65 | - We avoid single-method delegate interfaces, and in those case we use |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 66 | callbacks. |
Dave Tapuska | 74bcc37 | 2021-05-19 19:36:04 | [diff] [blame^] | 67 | - The `const` identifier can be added to simple getter APIs implemented by |
| 68 | content. Don't add `const` to interfaces implemented by the embedder, where |
| 69 | we can't make assumptions about what the embedder needs to implement it. |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 70 | - Observer interfaces (i.e. `WebContentsObserver`, `RenderFrameObserver`, |
| 71 | `RenderViewObserver`) should only have void methods. This is because otherwise |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 72 | the order that observers are registered would matter, and we don't want that. |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame] | 73 | The only exception is `OnMessageReceived()`, which is fine since only one |
| 74 | observer class handles each particular IPC, so ordering doesn't make a |
| 75 | difference. |