Chromium Code Reviews| Index: extensions/renderer/bindings.md |
| diff --git a/extensions/renderer/bindings.md b/extensions/renderer/bindings.md |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1bd78e0b0cae2cdc1f0da63d27de59cd46bb7685 |
| --- /dev/null |
| +++ b/extensions/renderer/bindings.md |
| @@ -0,0 +1,212 @@ |
| +# Extension Bindings |
| + |
| +[TOC] |
| + |
| +## What Is It |
| + |
| +The Bindings System is responsible for creating the JS entry points for APIs. |
| +It creates the `chrome` object (if it does not exist) and adds the API objects |
| +(e.g. `tabs`) that should be accessible to the context. |
| + |
| +## Initialization |
| + |
| +Bindings are initialized by creating an ObjectTemplate from an API specification |
|
jbroman
2017/05/23 18:58:25
nit: Describe where I could find these specificati
Devlin
2017/05/23 20:40:37
Done. (We need to add documentation about those,
|
| +and stamping out copies of this template. This means that once an API is |
| +instantiated once, further instantiations within that same process are |
| +significantly faster. |
| + |
| +This is slightly complicated because APIs may have features (such as specific |
| +methods or events) that are restricted in certain contexts, even if the rest of |
| +the API is available. As a result, after object instantiation, there’s a chance |
| +we may have to alter the object in order to remove these unavailable features. |
| + |
| +## API Features |
| + |
| +A "feature" of an API is a property on the API object to expose some |
| +functionality. There are three main types of features exposed on APIs. |
| + |
| +* __Functions__: |
| +Functions are the main type of feature exposed on APIs. They allow callers to |
| +interact with the browser and trigger behavior. |
| + |
| +* __Events__: |
| +Most events are dispatched when something happens to inform an interested party |
| +of the instance. Callers subscribe to the events they are interested in, and |
| +are notified only for subscribed events. While most events do not influence |
| +behavior change in the browser, declarative events may. |
| + |
| +* __Properties__: |
| +Certain APIs have exposed properties that are accessed directly on the API |
| +object. These are frequently constants (including enum definitions), but are |
| +also sometimes properties relating to the state of the context. |
| + |
| +## Restriction |
| + |
| +Not all APIs are available to all contexts; we restrict which capabilities are |
| +exposed based on multiple factors. |
| + |
| +### Scope |
| + |
| +Features may be restricted at multiple scopes. The most common is at the |
| +API-scope - where none of the API will be made available if the requirements |
| +aren’t met. In this case, the chrome.<apiName> property will simply be |
| +undefined. However, we also have the ability to restrict features on a more |
| +granular scope, such as at the method or event level. In this case, even though |
| +most of an API may be available, a certain function might not be; or, |
| +conversely, only a small subset of features may be available while the rest of |
| +the API is restricted. |
| + |
| +### Restricting |
| + |
| +Properties Feature restrictions are based on a specific v8::Context. Different |
|
jbroman
2017/05/23 18:58:25
nit: Delete "Properties", or clarify if this was n
Devlin
2017/05/23 20:40:37
Whoops! Format fail. Fixed.
|
| +contexts within the same frame may have different API availabilities (this is |
| +significantly different than the web platform, where features are exposed at the |
| +frame-level). The bindings system takes into account context type, associated |
| +extensions, URL, and more when evaluating features; for more information, see |
| +the feature documentation. |
|
jbroman
2017/05/23 18:58:25
nit: link to "the feature documentation"?
Devlin
2017/05/23 20:40:37
Done.
|
| + |
| +## Typical Function Flow |
| + |
| +The typical flow for all API methods is the same. A JS entry point (the method |
| +on the API object) leads to a common native implementation. This implementation |
| +has the following steps: |
| + |
| +* __Argument Parsing__: |
| +Passed arguments are parsed against an expected signature defined in the API |
| +specification. If the passed arguments match the signature, the arguments are |
| +normalized and converted to a serialized format (base::Value). |
| +* __Request Dispatch__: |
| +A request is dispatched with the parsed arguments and other information about |
| +the request (such as requesting context and user gesture status). If a callback |
| +is included, a pending request is added. |
|
jbroman
2017/05/23 18:58:25
nit: What does it mean for "a pending request to b
Devlin
2017/05/23 20:40:37
Done.
|
| +* __Request Response__: |
| +A response is provided asynchronously, indicating success or failure, along with |
| +any return values (to pass to a provided callback) or an error message. The |
| +pending request is removed. |
| + |
| +## Custom Function Hooks |
| + |
| +Certain APIs need to deviate from this typical flow in order to customize |
| +behavior. We provide the following general custom hooks for APIs to modify the |
| +typical behavior. |
|
jbroman
2017/05/23 18:58:25
OK, so these hooks exist. Where would I look to at
Devlin
2017/05/23 20:40:37
Done.
|
| + |
| +* __updateArgumentsPreValidate__: |
| +Allows an API implementation to modify passed arguments before the argument |
| +signature is validated. This can be useful in the case of undocumented |
| +(internal) parameters or properties, such as a generated ID. |
| +* __updateArgumentsPostValidate__: |
| +Allows an API implementation to modify passed arguments after the argument |
| +signature is validated, but before the request is handled. Note: this is |
| +usually bad practice, as any modification means that the arguments no longer |
| +match the expected signature. This can cause headaches when we attempt to |
| +deserialize these values. |
| +* __handleRequest__: |
| +Allows an API implementation to internally handle a request. This is useful |
| +when the request itself should not go through the normal flow, such as when the |
| +logic requires a greater level of involvement on the renderer, or is entirely |
| +handled without needing to message the browser. |
| +* __customCallback__: |
| +Allows an AIP implementation to add a callback that should be called with the |
|
jbroman
2017/05/23 18:58:25
nit: s/AIP/API/?
Devlin
2017/05/23 20:40:37
Done.
|
| +result of an API function call before the caller’s callback is invoked. It is |
| +the responsibility of the custom callback to invoke the original callback, which |
| +is passed as an argument. This is useful when the return results should be |
| +mutated before returning to the caller (which can be necessary when the eventual |
| +result could be a renderer-specific concept, such as a DOMWindow). |
| + |
| +An API implementation may use one or more of these hooks. |
| + |
| +## Events |
| + |
| +Events are dispatched when the associated action occurs. |
| + |
| +### Types |
| + |
| +There are three types of events. |
| + |
| +* __Regular__: |
| +These events are dispatched to the subscriber when something happens, and merely |
| +serve as a notification to allow the subscriber to react. |
| +* __Declarative__: |
| +Declarative events allow a subscriber to specify some action to be taken when an |
| +event occurs. For instance, the declarativeContent API allows a subscriber to |
| +indicate that an action should be shown whenever a certain URL pattern or CSS |
| +rule is matched. For these events, the subscriber is not notified when the |
| +event happens; rather, the browser takes immediately takes the specified action. |
| +By virtue of not notifying the subscriber, we help preserve the user’s privacy; |
| +if a subscriber says "do X when the user visits example.com", it does not know |
| +whether the user visited example.com. (Note: subsequent actions, such as a user |
| +interacting with the action on a given page, can expose this.) |
| +* __Imperative__: |
| +A few events are designed to be dispatched and to return a response from the |
| +subscriber, indicating an action the browser should take. These are |
| +predominantly used in the webRequest API, where a subscriber can register events |
| +for navigations, receive notifications of those navigations, and return a result |
| +of whether the navigation should continue, cancel, or redirect. These events |
| +are generally discouraged for performance reasons, and declarative events are |
| +preferred. |
| + |
| +### Filters |
| + |
| +Certain events also allow the registration of filters, which allow subscribers |
| +to only be notified of a subset of events. For example, the webNavigation and |
| +webRequest APIs allow filtering by URL pattern, so that uninteresting |
| +navigations are ignored. |
| + |
| +## Legacy JavaScript Implementations |
| + |
| +The prior bindings system was implemented primarily in JavaScript, rather than |
| +utilizing native code. There were many reasons for this, but they include ease |
| +of coding and more limited interactions with Blink (WebKit at the time) and V8. |
| +Unfortunately, this led to numerous security vulnerabilities (because untrusted |
| +code can run in the same context) and performance issues (because bindings were |
| +set up per context, and could not be cached in any way). |
| + |
| +While the native bindings system replaces the core functionality with a native |
| +implementation, individual APIs may still be implemented in JavaScript custom |
| +bindings, or hooks. These should eventually be replaced by native-only |
| +implementations. |
| + |
| +## Differences Between Web/Blink Bindings |
| + |
| +There are a number of differences between the Extensions Bindings System and |
| +Blink Bindings. |
| + |
| +### Common Implementation to Optimize Binary Size |
| + |
| +Most Extension APIs are implemented in the browser process after a common flow |
| +in the renderer. This allows us to optimize the renderer implementation for |
| +space and have the majority of APIs lead to a single entry point, which can |
| +match an API against an expected schema. This is contrary to Blink Bindings, |
| +which set up a distinct separate entry point for each API, and then individually |
| +parses the expected results. |
| + |
| +The Blink implementation provides greater speed, but comes at a larger generated |
| +code cost, since each API has its own generated parsing and handling code. |
| +Since most Blink/open web APIs are implemented in the renderer, this cost is not |
| +as severe - each API would already require specialized code in the renderer. |
| + |
| +Extension APIs, on the other hand, are predominantly implemented in the browser; |
| +this means we can optimize space by having a single parsing/handling point. |
| +This is also beneficial because many extension APIs are exposed on a more |
| +limited basis, where only a handful of contexts need access to them, and thus |
| +the binary size savings is more valuable, and the speed cost less harmful. |
| + |
| +### Signature Matching |
| + |
| +Signature matching differs significantly between open web functions and |
|
jbroman
2017/05/23 18:58:25
"open web functions" == WebIDL?
Devlin
2017/05/23 20:40:37
Done.
|
| +Extension APIs. |
| + |
| +#### Optional Inner Parameters |
| + |
| +Unlike OWP APIs, Extension APIs allow for optional inner parameters. For |
| +instance, if an API has the signature `(integer, optional string, optional |
| +function)`, it may be invoked with `(integer, function)` - which would not be |
| +valid in the OWP. This also allows for inner parameters to be optional with |
| +subsequent required parameters, such as `(integer, optional string, function)` - |
| +again, something which would be disallowed on the OWP. |
| + |
| +#### Unknown Properties |
| + |
| +Unknown properties on objects are, by default, unallowed. That is, if a |
| +function accepts an object that has properties of `foo` and `bar`, passing |
| +`{foo: <foo>, bar: <bar>, baz: <baz>}` is invalid. |