blob: e861d2e140ea9242fdbe3cee74d5a9ff82e309fa [file] [log] [blame] [view]
rdevlin.cronin8a23c0c2016-08-19 21:44:241# Extension Features Files
2
3[TOC]
4
5## Summary
6
7The Extension features files specify the different requirements for extension
8feature availability.
9
10An **extension feature** can be any component of extension capabilities. Most
11notably, this includes extension APIs, but there are also more structural or
12behavioral features, such as web accessible resources or event pages.
13
14## Files
15
16There are four different feature files used:
17* [\_api\_features](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/_api_features.json):
18Specifies the requirements for API availability. If an extension doesn't satisfy
19the requirements, the API will not be accessible in the extension's code.
20* [\_permission\_features](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/_permission_features.json):
21Specifies the requirements for permission availability. If an extension doesn't
22satisfy the requirements, the permission will not be granted and the extension
23will have an install warning.
24* [\_manifest\_features](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/_manifest_features.json):
25Specifies the requirements for manifest entry availability. If an extension
26doesn't satisfy the requirements, the extension will fail to load with an error.
27* [\_behavior\_features](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/_behavior_features.json):
28Specifies the requirements for miscellaneous extension behaviors. This should
29typically not be used.
30
31Note that these files may be present under chrome/common/extensions/api, as well
32as under extensions/common/api and extensions/shell/common/api.
33
34## Grammar
35
36The feature files are written in JSON. Each file contains a single JSON object
37with properties for each feature.
38
39```
40{
41 "feature1": <definition>,
42 "feature2": <definition>,
43 ...
44}
45```
46
47### Simple and Complex Features
48
49Most features are known as "simple" features. These are features whose
50definition is a single object that contains the properties describing the
51criteria for availability. A simple feature might look like this:
52```
53"feature1": {
54 "dependencies": ["permission:feature1"],
55 "contexts": ["blessed_extension"]
56}
57```
58`feature1` has a single definition, which says for it to be available, a
59permission must be present and it must be executed from a blessed context.
60(These concepts are covered more later in this document.)
61
62Features can also be "complex". A complex feature has a list of objects to
63specify multiple groups of possible properties. A complex feature could look
64like this:
65```
66"feature1": [{
67 "dependencies": ["permission:feature1"],
68 "contexts": ["blessed_extension"]
69}, {
70 "dependencies": ["permission:otherPermission"],
71 "contexts": ["blessed_extension", "unblessed_extension"]
72}]
73```
74
75With complex features, if either of the definitions are matched, the feature
76is available (in other words, the feature definitions are logically OR'd
77together). Complex features should frequently be avoided, as it makes the
78logic more involved and slower.
79
80### Inheritance
81
82By default, features inherit from parents. A feature's ancestry is specified by
83its name, where a child feature is the parent's name followed by a '.' and the
84child's name. That is, `feature1.child` is the child of `feature1`. Inheritance
85can carry for multiple levels (e.g. `feature1.child.child`), but this is rarely
86(if ever) useful.
87
88A child feature inherits all the properties of its parent, but can choose to
89override them or add additional properties. Take the example:
90```
91"feature1": {
92 "dependencies": ["permission:feature1"],
93 "contexts": ["blessed_extension"]
94},
95"feature1.child": {
96 "contexts": ["unblessed_extension"],
97 "extension_types": ["extension"]
98}
99```
100
101In this case, `feature1.child` will effectively have the properties
102```
103"dependencies": ["permission:feature1"], # inherited from feature1
104"contexts": ["unblessed_extension"], # inherited value overridden by child
105"extension_types": ["extension] # specified by child
106```
107
108If you don't want a child to inherit any features from the parent, add the
109property `"noparent": true`. This is useful if, for instance, you have a
110prefixed API name that isn't dependent on the prefix, such as app.window
111(which is fully separate from the app API).
112
113If the parent of a feature is a complex feature, the feature system needs to
114know which parent to inherit from. To do this, add the property
115`"default_parent": true` to one of the feature definitions in the parent
116feature.
117
118## Properties
119
120The following properties are supported in the feature system.
121
122### blacklist
123
124The `blacklist` property specifies a list of ID hashes for extensions that
rdevlin.cronin1d4585192016-08-22 22:34:28125cannot access a feature. See ID Hashes in this document for how to generate
126these hashes.
rdevlin.cronin8a23c0c2016-08-19 21:44:24127
128Accepted values are lists of id hashes.
129
130### channel
131
132The `channel` property specifies a maximum channel for the feature availability.
133That is, specifying `dev` means that the feature is available on `dev`,
134`canary`, and `trunk`.
135
136Accepted values are a single string from `trunk`, `canary`, `dev`, `beta`, and
137`stable`.
138
139### command\_line\_switch
140
141The `command_line_switch` property specifies a command line switch that must be
142present for the feature to be available.
143
144Accepted values are a single string for the command line switch (without the
145preceeding '--').
146
147### component\_extensions\_auto\_granted
148
149The `component_extensions_auto_granted` specifies whether or not component
150extensions should be automatically granted access to the feature. By default,
151this is `true`.
152
153The only accepted value is the bool `false` (since true is the default).
154
155### contexts
156
157The `contexts` property specifies which JavaScript contexts can access the
158feature. All API features must specify at least one context, and only API
159features can specify contexts.
160
161Accepted values are a list of strings from `blessed_extension`,
162`blessed_web_page`, `content_script`, `extension_service_worker`,
163`web_page`, `webui`, and `unblessed_extension`.
164
165### default\_parent
166
167The `default_parent` property specifies a feature definition from a complex
168feature to be used as the parent for any children. See also Inheritance.
169
170The only accepted value is the bool `true`.
171
172### dependencies
173
174The `dependencies` property specifies which other features must be present in
175order to access this feature. This is useful so that you don't have to
176re-specify all the same properties on an API feature and a permission feature.
177
178A common practice is to put as many restrictions as possible in the
179permission or manifest feature so that we warn at extension load, and put
180relatively limited properties in an API feature with a dependency on the
181manifest or permission feature.
182
183To specify a dependent feature, use the prefix the feature name with the type
184of feature it is, followed by a colon. For example, in order to specify a
185dependency on a permission feature `foo`, we would add the dependency entry
186`permission:foo`.
187
188Accepted values are lists of strings specifying the dependent features.
189
190### extension\_types
191
192The `extension_types` properties specifies the different classes of extensions
193that can use the feature. It is very common for certain features to only be
194allowed in certain extension classes, rather than available to all types.
195
196Accepted values are lists of strings from `extension`, `hosted_app`,
197`legacy_packaged_app`, `platform_app`, `shared_module`, and `theme`.
198
199### location
200
201The `location` property specifies the required install location of the
202extension.
203
204Accepted values are a single string from `component`, `external_component`, and
205`policy`.
206
207### internal
208
209The `internal` property specifies whether or not a feature is considered
210internal to Chromium. Internal features are not exposed to extensions, and can
211only be used from Chromium code.
212
213The only accepted value is the bool `true`.
214
215### matches
216
217The `matches` property specifies url patterns which should be allowed to access
218the feature. Only API features may specify `matches`, and `matches` only make
219sense with a context of either `webui` or `web_page`.
220
221Accepted values are a list of strings specifying the match patterns.
222
223### max\_manifest\_version
224
225The `max_manifest_version` property specifies the maximum manifest version to be
226allowed to access a feature. Extensions with a greater manifest version cannot
227access the feature.
228
229The only accepted value is `1`, as currently the highest possible manifest
230version is `2`.
231
232### min\_manifest\_version
233
234The `min_manifest_version` property specifies the minimum manifest version to be
235allowed to access a feature. Extensions with a lesser manifest version cannot
236access the feature.
237
238The only accepted value is `2`, as this is currently the highest possible
239manifest version.
240
241### noparent
242
243The `noparent` property specifies that a feature should not inherit any
244properties from a derived parent. See also Inheritance.
245
246The only accepted value is the bool `true`.
247
248### platforms
249
250The `platforms` property specifies the properties the feature should be
251available on.
252
253The accepted values are lists of strings from `chromeos`, `mac`, `linux`, and
254`win`.
255
256### whitelist
257
258The `whitelist` property specifies a list of ID hashes for extensions that
259are the only extensions allowed to access a feature.
260
261Accepted values are lists of id hashes.
262
rdevlin.cronin1d4585192016-08-22 22:34:28263## ID Hashes
264
265Instead of listing the ID directly in the whitelist or blacklist section, we
266use an uppercased SHA1 hash of the id.
267
268To generate a new whitelisted ID for an extension ID, do the following in bash:
269```
270$ echo -n "aaaabbbbccccddddeeeeffffgggghhhh" | \
271 sha1sum | tr '[:lower:]' '[:upper:]'
272```
273(Replacing `aaaabbbbccccddddeeeeffffgggghhhh` with your extension ID.)
274
275The output should be something like:
276```
2779A0417016F345C934A1A88F55CA17C05014EEEBA -
278```
279
280Add the ID to the whitelist or blacklist for the desired feature. It is also
281often useful to link the crbug next to the id hash, e.g.:
282```
283"whitelist": [
284 "9A0417016F345C934A1A88F55CA17C05014EEEBA" // crbug.com/<num>
285]
286```
287
288Google employees: please update http://go/chrome-api-whitelist to map hashes
289back to ids.
290
291## Compilation
292
293The feature files are compiled as part of the suite of tools in
294//tools/json\_schema\_compiler/. The output is a set of FeatureProviders that
295contain a mapping of all features.
296
297In addition to being significantly more performant than parsing the JSON files
298at runtime, this has the added benefit of allowing us to validate at compile
299time rather than needing a unittest (or allowing incorrect features).
300
301In theory, invalid features should result in a compilation failure; in practice,
302the compiler is probably missing some cases.
303
rdevlin.cronin8a23c0c2016-08-19 21:44:24304## Still to come
305
rdevlin.cronin1d4585192016-08-22 22:34:28306TODO(devlin): Possibly move documentation for feature contexts, add
307documentation for extension types. Probably also more on requirements for
308individual features.