tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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    }