1 .. _defining_xpcom_components:
3 =========================================
4 Defining XPCOM C++-implemented Components
5 =========================================
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`.
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
18 Manifest files are Python data files registered in ``moz.build`` files in a
19 ``XPCOM_MANIFESTS`` file list:
21 .. code-block:: python
27 The files may define any of the following special variables:
29 .. code-block:: python
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'
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.
44 # Optional: A list of header files to include before calling init or
45 # unload functions, or any legacy constructor functions.
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.
50 # Any relative header path must be exported.
56 # A list of component classes provided by this module.
64 # A list of category registrations
68 'other-name': ('value', ProcessSelector.MAIN_PROCESS_ONLY),
74 Class definitions may have the following properties:
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.
84 A UUID string containing this component's CID, in the form
85 ``'{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'``.
87 ``contract_ids`` (optional)
88 A list of contract IDs to register for this class.
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``.
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.
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.
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.
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.
122 This property is incompatible with ``legacy_constructor``.
125 If provided, must be the URL of a JavaScript module which contains a
126 JavaScript implementation of the component. The ``constructor`` property
127 must contain the name of an exported function which can be constructed to
128 create a new instance of the component.
130 ``legacy_constructor`` (optional)
131 This property is deprecated, and should not be used in new code.
133 The fully-qualified name of a constructor function to call in order to
134 create instances of this class. This function must be declared in one of the
135 headers listed in the ``headers`` property, and must have the signature
136 ``nsresult(nsISupports* aOuter, const nsID& aIID, void** aResult)``, and
137 behave equivalently to ``nsIFactory::CreateInstance``.
139 This property is incompatible with ``constructor``.
141 ``singleton`` (optional, default=``False``)
142 If true, this component's constructor is expected to return the same
143 singleton for every call, and no ``mozilla::components::<name>::Create()``
144 method will be generated for it.
146 ``overridable`` (optional, default=``False``)
147 If true, this component's contract ID is expected to be overridden by some
148 tests, and its ``mozilla::components::<name>::Service()`` getter will
149 therefore look it up by contract ID for every call. This component must,
150 therefore, provide at least one contract ID in its ``contract_ids`` array.
152 If false, the ``Service()`` getter will always retrieve the service based on
153 its static data, and it cannot be overridden.
155 Note: Enabling this option is expensive, and should not be done when it can
156 be avoided, or when the getter is used by any hot code.
158 ``external`` (optional, default=``False`` if any ``headers`` are provided, ``True`` otherwise)
159 If true, a constructor for this component's ``type`` must be defined in
160 another translation unit, using ``NS_IMPL_COMPONENT_FACTORY(type)``. The
161 constructor must return an ``already_AddRefed<nsISupports>``, and will be
162 used to construct instances of this type.
164 This option should only be used in cases where the headers which define the
165 component's concrete type cannot be easily included without local includes.
167 Note: External constructors may not specify an ``init_method``, since the
168 generated code will not have the necessary type information required to call
169 it. This option is also incompatible with ``constructor`` and
170 ``legacy_constructor``.
172 ``processes`` (optional, default=``ProcessSelector.ANY_PROCESS``)
173 An optional specifier restricting which types of process this component may
174 be loaded in. This must be a property of ``ProcessSelector`` with the same
175 name as one of the values in the ``Module::ProcessSelector`` enum.
178 Conditional Compilation
179 =======================
181 This manifest may run any appropriate Python code to customize the values of
182 the ``Classes`` array based on build configuration. To simplify this process,
183 the following globals are available:
186 A function which returns true if the given build config setting is defined
190 The ``buildconfig`` python module, with a ``substs`` property containing a
191 dict of all available build substitutions.
194 Component Constructors
195 ======================
197 There are several ways to define component constructors, which vary mostly
198 depending on how old the code that uses them is:
203 This simplest way to define a component is to include a header defining a
204 concrete type, and let the component manager call that class's constructor:
206 .. code-block:: python
208 'type': 'mozilla::foo::Foo',
209 'headers': ['mozilla/Foo.h'],
211 This is generally the preferred method of defining non-singleton constructors,
212 but may not be practicable for classes which rely on local includes for their
215 Singleton Constructors
216 ----------------------
218 Singleton classes are generally expected to provide their own constructor
219 function which caches a singleton instance the first time it is called, and
220 returns the same instance on subsequent calls. This requires declaring the
221 constructor in an included header, and implementing it in a separate source
224 .. code-block:: python
226 'type': 'mozilla::foo::Foo',
227 'headers': ['mozilla/Foo.h'],
228 'constructor': 'mozilla::Foo::GetSingleton',
234 class Foo final : public nsISupports {
236 static already_AddRefed<Foo> GetSingleton();
243 already_AddRefed<Foo> Foo::GetSingleton() {
247 External Constructors
248 ---------------------
250 For types whose headers can't easily be included, constructors can be defined
251 using a template specialization on an incomplete type:
253 .. code-block:: python
255 'type': 'mozilla::foo::Foo',
262 NS_IMPL_COMPONENT_FACTORY(Foo) {
263 return do_AddRef(new Foo()).downcast<nsISupports>();
269 These should not be used in new code, and are left as an exercise for the
273 Registering Categories
274 ======================
276 Classes which need define category entries with the same value as their
277 contract ID may do so using the following:
279 .. code-block:: python
281 'contract_ids': ['@mozilla.org/foo;1'],
283 'content-policy': 'm-foo',
284 'Gecko-Content-Viewers': ['image/jpeg', 'image/png'],
287 This will define each of the following category entries:
289 * ``"content-policy"`` ``"m-foo",`` ``"@mozilla.org/foo;1"``
290 * ``"Gecko-Content-Viewers"`` ``"image/jpeg"`` ``"@mozilla.org/foo;1"``
291 * ``"Gecko-Content-Viewers"`` ``"image/png"`` ``"@mozilla.org/foo;1"``
293 Some category entries do not have a contract ID as a value. These entries can
294 be specified by adding to a global ``Categories`` dictionary:
296 .. code-block:: python
300 'Mapi Support': 'service,@mozilla.org/mapisupport;1',
304 It is possible to limit these on a per-process basis by using a tuple as the
307 .. code-block:: python
311 'MainProcessSingleton': ('service,@mozilla.org/main-process-singleton;1', ProcessSelector.MAIN_PROCESS_ONLY),