defining-xpcom-components.rst (11225B)
1 .. _defining_xpcom_components: 2 3 ========================= 4 Defining XPCOM Components 5 ========================= 6 7 This document explains how to write a :code:`components.conf` file. For 8 documentation on the idl format see :ref:`XPIDL`. For a tutorial on writing 9 a new XPCOM interface, see 10 :ref:`writing_xpcom_interface`. 11 12 Native XPCOM components are registered at build time, and compiled into static 13 data structures which allow them to be accessed with little runtime overhead. 14 Each module which wishes to register components must provide a manifest 15 describing each component it implements, its type, and how it should be 16 constructed. 17 18 Manifest files are Python data files registered in ``moz.build`` files in a 19 ``XPCOM_MANIFESTS`` file list: 20 21 .. code-block:: python 22 23 XPCOM_MANIFESTS += [ 24 'components.conf', 25 ] 26 27 The files may define any of the following special variables: 28 29 .. code-block:: python 30 31 # Optional: A function to be called once, the first time any component 32 # listed in this manifest is instantiated. 33 InitFunc = 'nsInitFooModule' 34 # Optional: A function to be called at shutdown if any component listed in 35 # this manifest has been instantiated. 36 UnloadFunc = 'nsUnloadFooModule' 37 38 # Optional: A processing priority, to determine how early or late the 39 # manifest is processed. Defaults to 50. In practice, this mainly affects 40 # the order in which unload functions are called at shutdown, with higher 41 # priority numbers being called later. 42 Priority = 10 43 44 # Optional: A list of header files to include before calling init or 45 # unload functions, or any legacy constructor functions. 46 # 47 # Any header path beginning with a `/` is loaded relative to the root of 48 # the source tree, and must not rely on any local includes. 49 # 50 # Any relative header path must be exported. 51 Headers = [ 52 '/foo/nsFooModule.h', 53 'nsFoo.h', 54 ] 55 56 # A list of component classes provided by this module. 57 Classes = [ 58 { 59 # ... 60 }, 61 # ... 62 ] 63 64 # A list of category registrations 65 Categories = { 66 'category': { 67 'name': 'value', 68 'other-name': ('value', ProcessSelector.MAIN_PROCESS_ONLY), 69 # ... 70 }, 71 # ... 72 } 73 74 Class definitions may have the following properties: 75 76 ``name`` (optional) 77 If present, this component will generate an entry with the given name in the 78 ``mozilla::components`` namespace in ``mozilla/Components.h``, which gives 79 easy access to its CID, service, and instance constructors as (e.g.,) 80 ``components::Foo::CID()``, ``components::Foo::Service()``, and 81 ``components::Foo::Create()``, respectively. 82 83 ``cid`` 84 A UUID string containing this component's CID, in the form 85 ``'{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'``. 86 87 ``contract_ids`` (optional) 88 A list of contract IDs to register for this class. 89 90 ``categories`` (optional) 91 A dict of category entries to register for this component's contract ID. 92 Each key in the dict is the name of the category. Each value is either a 93 string containing a single entry, or a list of entries. Each entry is either 94 a string name, or a dictionary of the form ``{'name': 'value', 'backgroundtasks': 95 BackgroundTasksSelector.ALL_TASKS}``. By default, category entries are registered 96 for **no background tasks**: they have 97 ``'backgroundtasks': BackgroundTasksSelector.NO_TASKS``. 98 99 ``type`` (optional, default=``nsISupports``) 100 The fully-qualified type of the class implementing this component. Defaults 101 to ``nsISupports``, but **must** be provided if the ``init_method`` property 102 is specified, or if neither the ``constructor`` nor ``legacy_constructor`` 103 properties are provided. 104 105 ``headers`` (optional) 106 A list of headers to include in order to call this component's constructor, 107 in the same format as the global ``Headers`` property. 108 109 ``init_method`` (optional) 110 The name of a method to call on newly-created instances of this class before 111 returning them. The method must take no arguments, and must return a 112 ``nsresult``. If it returns failure, that failure is propagated to the 113 ``getService`` or ``createInstance`` caller. 114 115 ``constructor`` (optional) 116 The fully-qualified name of a constructor function to call in order to 117 create instances of this class. This function must be declared in one of the 118 headers listed in the ``headers`` property, must take no arguments, and must 119 return ``already_AddRefed<iface>`` where ``iface`` is the interface provided 120 in the ``type`` property. 121 122 This property is incompatible with ``legacy_constructor``. 123 124 ``esModule`` (optional) 125 If provided, must be the URL of a 126 `JavaScript module <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules>`_ 127 which contains a JavaScript implementation of the component. 128 The ``constructor`` property must contain the name of an exported 129 function which can be constructed to create a new instance of the component. 130 131 132 ``jsm`` (deprecated, optional) 133 Do not use. Use ``esModule`` instead. 134 135 ``legacy_constructor`` (optional) 136 This property is deprecated, and should not be used in new code. 137 138 The fully-qualified name of a constructor function to call in order to 139 create instances of this class. This function must be declared in one of the 140 headers listed in the ``headers`` property, and must have the signature 141 ``nsresult(const nsID& aIID, void** aResult)``, and behave equivalently to 142 ``nsIFactory::CreateInstance``. 143 144 This property is incompatible with ``constructor``. 145 146 ``singleton`` (optional, default=``False``) 147 If true, this component's constructor is expected to return the same 148 singleton for every call, and no ``mozilla::components::<name>::Create()`` 149 method will be generated for it. 150 151 ``overridable`` (optional, default=``False``) 152 If true, this component's contract ID is expected to be overridden by some 153 tests, and its ``mozilla::components::<name>::Service()`` getter will 154 therefore look it up by contract ID for every call. This component must, 155 therefore, provide at least one contract ID in its ``contract_ids`` array. 156 157 If false, the ``Service()`` getter will always retrieve the service based on 158 its static data, and it cannot be overridden. 159 160 Note: Enabling this option is expensive, and should not be done when it can 161 be avoided, or when the getter is used by any hot code. 162 163 ``external`` (optional, default=``False`` if any ``headers`` are provided, ``True`` otherwise) 164 If true, a constructor for this component's ``type`` must be defined in 165 another translation unit, using ``NS_IMPL_COMPONENT_FACTORY(type)``. The 166 constructor must return an ``already_AddRefed<nsISupports>``, and will be 167 used to construct instances of this type. 168 169 This option should only be used in cases where the headers which define the 170 component's concrete type cannot be easily included without local includes. 171 172 Note: External constructors may not specify an ``init_method``, since the 173 generated code will not have the necessary type information required to call 174 it. This option is also incompatible with ``constructor`` and 175 ``legacy_constructor``. 176 177 ``processes`` (optional, default=``ProcessSelector.ANY_PROCESS``) 178 An optional specifier restricting which types of process this component may 179 be loaded in. This must be a property of ``ProcessSelector`` with the same 180 name as one of the values in the ``Module::ProcessSelector`` enum. 181 182 183 Conditional Compilation 184 ======================= 185 186 This manifest may run any appropriate Python code to customize the values of 187 the ``Classes`` array based on build configuration. To simplify this process, 188 the following globals are available: 189 190 ``defined`` 191 A function which returns true if the given build config setting is defined 192 and true. 193 194 ``buildconfig`` 195 The ``buildconfig`` python module, with a ``substs`` property containing a 196 dict of all available build substitutions. 197 198 199 Component Constructors 200 ====================== 201 202 There are several ways to define component constructors, which vary mostly 203 depending on how old the code that uses them is: 204 205 Class Constructors 206 ------------------ 207 208 This simplest way to define a component is to include a header defining a 209 concrete type, and let the component manager call that class's constructor: 210 211 .. rstcheck: ignore-languages=python 212 .. code-block:: python 213 214 'type': 'mozilla::foo::Foo', 215 'headers': ['mozilla/Foo.h'], 216 217 This is generally the preferred method of defining non-singleton constructors, 218 but may not be practicable for classes which rely on local includes for their 219 definitions. 220 221 Singleton Constructors 222 ---------------------- 223 224 Singleton classes are generally expected to provide their own constructor 225 function which caches a singleton instance the first time it is called, and 226 returns the same instance on subsequent calls. This requires declaring the 227 constructor in an included header, and implementing it in a separate source 228 file: 229 230 .. rstcheck: ignore-languages=python 231 .. code-block:: python 232 233 'type': 'mozilla::foo::Foo', 234 'headers': ['mozilla/Foo.h'], 235 'constructor': 'mozilla::Foo::GetSingleton', 236 237 ``Foo.h`` 238 239 .. code-block:: cpp 240 241 class Foo final : public nsISupports { 242 public: 243 static already_AddRefed<Foo> GetSingleton(); 244 }; 245 246 ``Foo.cpp`` 247 248 .. code-block:: cpp 249 250 already_AddRefed<Foo> Foo::GetSingleton() { 251 // ... 252 } 253 254 External Constructors 255 --------------------- 256 257 For types whose headers can't easily be included, constructors can be defined 258 using a template specialization on an incomplete type: 259 260 .. rstcheck: ignore-languages=python 261 .. code-block:: python 262 263 'type': 'mozilla::foo::Foo', 264 'external: True,' 265 266 ``Foo.cpp`` 267 268 .. code-block:: cpp 269 270 NS_IMPL_COMPONENT_FACTORY(Foo) { 271 return do_AddRef(new Foo()).downcast<nsISupports>(); 272 } 273 274 Legacy Constructors 275 ------------------- 276 277 These should not be used in new code, and are left as an exercise for the 278 reader. 279 280 281 Registering Categories 282 ====================== 283 284 Classes which need define category entries with the same value as their 285 contract ID may do so using the following: 286 287 .. rstcheck: ignore-languages=python 288 .. code-block:: python 289 290 'contract_ids': ['@mozilla.org/foo;1'], 291 'categories': { 292 'content-policy': 'm-foo', 293 'Gecko-Content-Viewers': ['image/jpeg', 'image/png'], 294 }, 295 296 This will define each of the following category entries: 297 298 * ``"content-policy"`` ``"m-foo",`` ``"@mozilla.org/foo;1"`` 299 * ``"Gecko-Content-Viewers"`` ``"image/jpeg"`` ``"@mozilla.org/foo;1"`` 300 * ``"Gecko-Content-Viewers"`` ``"image/png"`` ``"@mozilla.org/foo;1"`` 301 302 Some category entries do not have a contract ID as a value. These entries can 303 be specified by adding to a global ``Categories`` dictionary: 304 305 .. code-block:: python 306 307 Categories = { 308 'update-timer': { 309 'nsUpdateService': '@mozilla.org/updates/update-service;1,getService,background-update-timer,app.update.interval,43200,86400', 310 } 311 } 312 313 It is possible to limit these on a per-process basis by using a tuple as the 314 value: 315 316 .. code-block:: python 317 318 Categories = { 319 '@mozilla.org/streamconv;1': { 320 '?from=gzip&to=uncompressed': ('', ProcessSelector.ALLOW_IN_SOCKET_PROCESS), 321 } 322 }