Extension Manager:Bootstrapped Extensions
Bootstrapped add-ons exist as a means of restricting what is available to an add-on in order to allow it to be loaded and unloaded with restarting the application.
Rationale
Current XPI add-ons cannot be unloaded without restarting the application. This is because the features that we give them (XPCOM components, chrome registration and overlays etc.) cannot be removed in a managed fashion. Loading without a restart could possibly be implemented however that really only solves a small part of the problem as updates etc. would still require restarts.
The approach taken here is to simplify what it means to be an add-on. Instead of registering XPCOM components and chrome in bootstrapped add-ons we instead do nothing except execute a bootstrap script when the add-on is loaded and call some functions on it. The add-on can do whatever it likes at that point however it must undo anything it has done when we call the bootstrap script to tell it to unload.
Declaring an Add-on as Bootstrappable
Add-ons are declared as being bootstrappable using the special em:bootstrap="true" property in the install manifest. Although any type of add-on can include this, for now it only makes sense for add-ons with em:type="2" (the default extension type) to include it. They should also include a bootstrap.js file alongside the install.rdf.
Backwards Compatibility
Older versions of Firefox do not know about the em:bootstrap flag or bootstrap.js file but with care it is possible to make the same XPI usable in both cases. Older versions would just treat it as a normal add-on requiring a restart to install and uninstall and loading components and chrome from the normal places. Newer versions will ignore the components and chrome and just load the bootstrap.js.
Bootstrap Events
When an add-on is loaded the bootstrap.js file is executed in a privileged sandbox which is cached until the add-on is unloaded. The scripts should contain a number of functions that will be called to notify the add-on of certain events:
Startup
Whenever an add-on needs to be loaded the platform will call a function named startup
in the bootstrap script. It will be passed the following arguments:
- data
- A JS object containing basic information about the add-on,
id
,version
andinstallPath
. - reason
- A number representing the reason for loading the add-on. This may be APP_STARTUP or ADDON_ENABLE.
Shutdown
Whenever an add-on needs to be unloaded the platform will call a function named shutdown
in the bootstrap script. It will be passed the following arguments:
- data
- A JS object containing basic information about the add-on,
id
,version
andinstallPath
. - reason
- A number representing the reason for unloading the add-on. This may be APP_SHUTDOWN or ADDON_DISABLE.
Install
The bootstrap script may include an install
method and if so it will be called before the first call to startup
after a particular version of an add-on is installed. It will be passed the following arguments:
- data
- A JS object containing basic information about the add-on,
id
,version
andinstallPath
. - reason
- A number representing the reason for installing the add-on. This may be ADDON_INSTALLED, ADDON_UPGRADED or ADDON_DOWNGRADED.
Note that install
will never be called if the add-on is never loaded.
Uninstall
The bootstrap script may include an uninstall
method and if so it will be called after the last call to shutdown
before a particular version of an add-on is uninstalled. It will be passed the following arguments:
- data
- A JS object containing basic information about the add-on,
id
,version
andinstallPath
. - reason
- A number representing the reason for installing the add-on. This may be ADDON_UNINSTALLED, ADDON_UPGRADED or ADDON_DOWNGRADED.
Note that uninstall
may be called even when add-ons are disabled or incompatible with the current application. It is important that the uninstall
script be carefully written to handle APIs that may no longer be present in the application.
In some cases uninstall
may never be called for an add-on. This happens when a third-party application removes the add-on while Firefox is not running.