Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Extension Bindings | |
| 2 | |
| 3 [TOC] | |
| 4 | |
| 5 ## What Is It | |
| 6 | |
| 7 The Bindings System is responsible for creating the JS entry points for APIs. | |
| 8 It creates the `chrome` object (if it does not exist) and adds the API objects | |
| 9 (e.g. `tabs`) that should be accessible to the context. | |
| 10 | |
| 11 ## Initialization | |
| 12 | |
| 13 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,
| |
| 14 and stamping out copies of this template. This means that once an API is | |
| 15 instantiated once, further instantiations within that same process are | |
| 16 significantly faster. | |
| 17 | |
| 18 This is slightly complicated because APIs may have features (such as specific | |
| 19 methods or events) that are restricted in certain contexts, even if the rest of | |
| 20 the API is available. As a result, after object instantiation, there’s a chance | |
| 21 we may have to alter the object in order to remove these unavailable features. | |
| 22 | |
| 23 ## API Features | |
| 24 | |
| 25 A "feature" of an API is a property on the API object to expose some | |
| 26 functionality. There are three main types of features exposed on APIs. | |
| 27 | |
| 28 * __Functions__: | |
| 29 Functions are the main type of feature exposed on APIs. They allow callers to | |
| 30 interact with the browser and trigger behavior. | |
| 31 | |
| 32 * __Events__: | |
| 33 Most events are dispatched when something happens to inform an interested party | |
| 34 of the instance. Callers subscribe to the events they are interested in, and | |
| 35 are notified only for subscribed events. While most events do not influence | |
| 36 behavior change in the browser, declarative events may. | |
| 37 | |
| 38 * __Properties__: | |
| 39 Certain APIs have exposed properties that are accessed directly on the API | |
| 40 object. These are frequently constants (including enum definitions), but are | |
| 41 also sometimes properties relating to the state of the context. | |
| 42 | |
| 43 ## Restriction | |
| 44 | |
| 45 Not all APIs are available to all contexts; we restrict which capabilities are | |
| 46 exposed based on multiple factors. | |
| 47 | |
| 48 ### Scope | |
| 49 | |
| 50 Features may be restricted at multiple scopes. The most common is at the | |
| 51 API-scope - where none of the API will be made available if the requirements | |
| 52 aren’t met. In this case, the chrome.<apiName> property will simply be | |
| 53 undefined. However, we also have the ability to restrict features on a more | |
| 54 granular scope, such as at the method or event level. In this case, even though | |
| 55 most of an API may be available, a certain function might not be; or, | |
| 56 conversely, only a small subset of features may be available while the rest of | |
| 57 the API is restricted. | |
| 58 | |
| 59 ### Restricting | |
| 60 | |
| 61 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.
| |
| 62 contexts within the same frame may have different API availabilities (this is | |
| 63 significantly different than the web platform, where features are exposed at the | |
| 64 frame-level). The bindings system takes into account context type, associated | |
| 65 extensions, URL, and more when evaluating features; for more information, see | |
| 66 the feature documentation. | |
|
jbroman
2017/05/23 18:58:25
nit: link to "the feature documentation"?
Devlin
2017/05/23 20:40:37
Done.
| |
| 67 | |
| 68 ## Typical Function Flow | |
| 69 | |
| 70 The typical flow for all API methods is the same. A JS entry point (the method | |
| 71 on the API object) leads to a common native implementation. This implementation | |
| 72 has the following steps: | |
| 73 | |
| 74 * __Argument Parsing__: | |
| 75 Passed arguments are parsed against an expected signature defined in the API | |
| 76 specification. If the passed arguments match the signature, the arguments are | |
| 77 normalized and converted to a serialized format (base::Value). | |
| 78 * __Request Dispatch__: | |
| 79 A request is dispatched with the parsed arguments and other information about | |
| 80 the request (such as requesting context and user gesture status). If a callback | |
| 81 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.
| |
| 82 * __Request Response__: | |
| 83 A response is provided asynchronously, indicating success or failure, along with | |
| 84 any return values (to pass to a provided callback) or an error message. The | |
| 85 pending request is removed. | |
| 86 | |
| 87 ## Custom Function Hooks | |
| 88 | |
| 89 Certain APIs need to deviate from this typical flow in order to customize | |
| 90 behavior. We provide the following general custom hooks for APIs to modify the | |
| 91 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.
| |
| 92 | |
| 93 * __updateArgumentsPreValidate__: | |
| 94 Allows an API implementation to modify passed arguments before the argument | |
| 95 signature is validated. This can be useful in the case of undocumented | |
| 96 (internal) parameters or properties, such as a generated ID. | |
| 97 * __updateArgumentsPostValidate__: | |
| 98 Allows an API implementation to modify passed arguments after the argument | |
| 99 signature is validated, but before the request is handled. Note: this is | |
| 100 usually bad practice, as any modification means that the arguments no longer | |
| 101 match the expected signature. This can cause headaches when we attempt to | |
| 102 deserialize these values. | |
| 103 * __handleRequest__: | |
| 104 Allows an API implementation to internally handle a request. This is useful | |
| 105 when the request itself should not go through the normal flow, such as when the | |
| 106 logic requires a greater level of involvement on the renderer, or is entirely | |
| 107 handled without needing to message the browser. | |
| 108 * __customCallback__: | |
| 109 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.
| |
| 110 result of an API function call before the caller’s callback is invoked. It is | |
| 111 the responsibility of the custom callback to invoke the original callback, which | |
| 112 is passed as an argument. This is useful when the return results should be | |
| 113 mutated before returning to the caller (which can be necessary when the eventual | |
| 114 result could be a renderer-specific concept, such as a DOMWindow). | |
| 115 | |
| 116 An API implementation may use one or more of these hooks. | |
| 117 | |
| 118 ## Events | |
| 119 | |
| 120 Events are dispatched when the associated action occurs. | |
| 121 | |
| 122 ### Types | |
| 123 | |
| 124 There are three types of events. | |
| 125 | |
| 126 * __Regular__: | |
| 127 These events are dispatched to the subscriber when something happens, and merely | |
| 128 serve as a notification to allow the subscriber to react. | |
| 129 * __Declarative__: | |
| 130 Declarative events allow a subscriber to specify some action to be taken when an | |
| 131 event occurs. For instance, the declarativeContent API allows a subscriber to | |
| 132 indicate that an action should be shown whenever a certain URL pattern or CSS | |
| 133 rule is matched. For these events, the subscriber is not notified when the | |
| 134 event happens; rather, the browser takes immediately takes the specified action. | |
| 135 By virtue of not notifying the subscriber, we help preserve the user’s privacy; | |
| 136 if a subscriber says "do X when the user visits example.com", it does not know | |
| 137 whether the user visited example.com. (Note: subsequent actions, such as a user | |
| 138 interacting with the action on a given page, can expose this.) | |
| 139 * __Imperative__: | |
| 140 A few events are designed to be dispatched and to return a response from the | |
| 141 subscriber, indicating an action the browser should take. These are | |
| 142 predominantly used in the webRequest API, where a subscriber can register events | |
| 143 for navigations, receive notifications of those navigations, and return a result | |
| 144 of whether the navigation should continue, cancel, or redirect. These events | |
| 145 are generally discouraged for performance reasons, and declarative events are | |
| 146 preferred. | |
| 147 | |
| 148 ### Filters | |
| 149 | |
| 150 Certain events also allow the registration of filters, which allow subscribers | |
| 151 to only be notified of a subset of events. For example, the webNavigation and | |
| 152 webRequest APIs allow filtering by URL pattern, so that uninteresting | |
| 153 navigations are ignored. | |
| 154 | |
| 155 ## Legacy JavaScript Implementations | |
| 156 | |
| 157 The prior bindings system was implemented primarily in JavaScript, rather than | |
| 158 utilizing native code. There were many reasons for this, but they include ease | |
| 159 of coding and more limited interactions with Blink (WebKit at the time) and V8. | |
| 160 Unfortunately, this led to numerous security vulnerabilities (because untrusted | |
| 161 code can run in the same context) and performance issues (because bindings were | |
| 162 set up per context, and could not be cached in any way). | |
| 163 | |
| 164 While the native bindings system replaces the core functionality with a native | |
| 165 implementation, individual APIs may still be implemented in JavaScript custom | |
| 166 bindings, or hooks. These should eventually be replaced by native-only | |
| 167 implementations. | |
| 168 | |
| 169 ## Differences Between Web/Blink Bindings | |
| 170 | |
| 171 There are a number of differences between the Extensions Bindings System and | |
| 172 Blink Bindings. | |
| 173 | |
| 174 ### Common Implementation to Optimize Binary Size | |
| 175 | |
| 176 Most Extension APIs are implemented in the browser process after a common flow | |
| 177 in the renderer. This allows us to optimize the renderer implementation for | |
| 178 space and have the majority of APIs lead to a single entry point, which can | |
| 179 match an API against an expected schema. This is contrary to Blink Bindings, | |
| 180 which set up a distinct separate entry point for each API, and then individually | |
| 181 parses the expected results. | |
| 182 | |
| 183 The Blink implementation provides greater speed, but comes at a larger generated | |
| 184 code cost, since each API has its own generated parsing and handling code. | |
| 185 Since most Blink/open web APIs are implemented in the renderer, this cost is not | |
| 186 as severe - each API would already require specialized code in the renderer. | |
| 187 | |
| 188 Extension APIs, on the other hand, are predominantly implemented in the browser; | |
| 189 this means we can optimize space by having a single parsing/handling point. | |
| 190 This is also beneficial because many extension APIs are exposed on a more | |
| 191 limited basis, where only a handful of contexts need access to them, and thus | |
| 192 the binary size savings is more valuable, and the speed cost less harmful. | |
| 193 | |
| 194 ### Signature Matching | |
| 195 | |
| 196 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.
| |
| 197 Extension APIs. | |
| 198 | |
| 199 #### Optional Inner Parameters | |
| 200 | |
| 201 Unlike OWP APIs, Extension APIs allow for optional inner parameters. For | |
| 202 instance, if an API has the signature `(integer, optional string, optional | |
| 203 function)`, it may be invoked with `(integer, function)` - which would not be | |
| 204 valid in the OWP. This also allows for inner parameters to be optional with | |
| 205 subsequent required parameters, such as `(integer, optional string, function)` - | |
| 206 again, something which would be disallowed on the OWP. | |
| 207 | |
| 208 #### Unknown Properties | |
| 209 | |
| 210 Unknown properties on objects are, by default, unallowed. That is, if a | |
| 211 function accepts an object that has properties of `foo` and `bar`, passing | |
| 212 `{foo: <foo>, bar: <bar>, baz: <baz>}` is invalid. | |
| OLD | NEW |