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. |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 20 | - While we don't allow old-style Chrome IPC `_messages.h` files in |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame^] | 21 | `//content/public`, we do allow `.mojom` files (see |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 22 | [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^] | 23 | If a mojom is only used inside content, it should be in |
| 24 | `//content/common`. If it's an interface that is implemented or called by |
| 25 | content's embedder, then it belongs in `//content/public/common`. |
| 26 | - In general, if there is a struct or enum which is only used by an interface, |
| 27 | they are put in the same file, but when the struct/enum is used in other |
| 28 | places or if it's pretty big, then it should be in its own file. |
| 29 | - All code under `//content` should be in the `"content"` namespace. |
| 30 | - Interfaces that content implements usually should be pure abstract, because |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 31 | usually there's only one implementation. These should not be implemented |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame^] | 32 | outside of content. (i.e., content will freely assume that it can cast to |
| 33 | its implementation(s)). |
| 34 | - Interfaces that embedders implement, especially ones which are used in tests |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 35 | or are observer-style and have many implementations, should have default |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame^] | 36 | (empty) implementations. |
| 37 | - Prefer enum classes over enum types. For enum types, the value should start |
| 38 | with the name of the type, i.e., `PAGE_TRANSITION_LINK` in the |
| 39 | `content::PageTransition` enum. |
| 40 | - content implementation code should use other implementations directly and |
| 41 | not go through the interface (i.e., code in `//content/renderer` should use |
| 42 | `RenderViewImpl` instead of `content::RenderView`). |
| 43 | - It's acceptable to put implementation files that hold constructors/destructors |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 44 | of interfaces/structs which might have member variables. For structs, this |
| 45 | covers initializing member variables. For interfaces (i.e. |
| 46 | `RenderViewObserver`) this might cover things like automatic |
| 47 | registration/unregistration. Normally we would put this small code in headers, |
| 48 | but because of the clang checks against putting code in headers, we're forced |
| 49 | to put it in .cc files (we don't want to make a clang exception for the |
| 50 | `content/public` directory since that would lead to confusion). |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame^] | 51 | - When code in chrome implements an interface from content, usually the |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 52 | convention is to prefix the implementation with "Chrome" (i.e. |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame^] | 53 | `ChromeContentBrowserClient` derives from `content::ContentBrowserClient`). |
| 54 | - Only expose methods in the public API that embedders need. If a method is only |
| 55 | used by other code in content, it belongs in `foo_impl.h` and not `foo.h`. |
| 56 | - 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] | 57 | its embedder, or the embedder is calling to content. There shouldn't be any |
| 58 | methods which are used to call from the embedder to the embedder. |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame^] | 59 | - 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] | 60 | 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^] | 61 | it, it doesn't belong in `//content/public` but instead some module that's |
| 62 | higher level. |
| 63 | - We avoid single-method delegate interfaces, and in those case we use |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 64 | callbacks. |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame^] | 65 | - Don't add the `const` identifier to interfaces. For interfaces implemented by |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 66 | the embedder, we can't make assumptions about what the embedder needs to |
| 67 | implement it. For interfaces implemented by content, the implementation |
| 68 | details doesn't have to be exposed. |
Matt Falkenhagen | 973af9d | 2019-10-03 00:35:38 | [diff] [blame^] | 69 | - Observer interfaces (i.e. `WebContentsObserver`, `RenderFrameObserver`, |
| 70 | `RenderViewObserver`) should only have void methods. This is because otherwise |
Matt Falkenhagen | ad915cb | 2019-09-22 13:49:16 | [diff] [blame] | 71 | 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^] | 72 | The only exception is `OnMessageReceived()`, which is fine since only one |
| 73 | observer class handles each particular IPC, so ordering doesn't make a |
| 74 | difference. |