Extension Manager:Install Hooks

From MozillaWiki
Jump to navigation Jump to search

One of the more common issues that add-on developers seem to be hitting is trying to run code when their add-on is installed or uninstalled. While there are currently ways to detect this they are not totally reliable and fail in many situations.

Overview

Add-on hooks are a proposed way that add-on developers can have JavaScript code executed whenever their add-on is acted on by the extension manager. The following operations would cause a hook to be executed:

  • Installation
  • Uninstallation
  • Enabling
  • Disabling (either by user choice or application incompatibilities)
  • Upgrading

Detailed specification

How to include hooks

From the add-on developer's perspective the process of including a hook is simple. Hooks exist as simple text files in the add-on xpi. The following file structure should exist:

  • install.rdf
  • hooks/
    • install.js
    • enable.js
    • disable.js
    • uninstall.js
    • upgrade.js

Only the hooks that the developer wishes to implement need to be included. A likely common case will be just the install hook in order to perform some kind of first run behaviour like creating databases in the profile etc.

Hook API

The hook file is expected to be JavaScript code. When the hook is triggered it will be executed once. It runs in its own scope so does not have to worry about any conflicts beyond the API defined here. It will run with full privileges and so can access all of XPCOM.

Included in the scope of the hook's execution will be the ADDON object. This contains details of the add-on the hook is running for providing easy access to data the hook may require:

ADDON = {
  id: <add-on ID>,
  version: <add-on version>,
  directory: <add-on installation directory>
};

The ADDON structure may not be protected from being altered by the hook, however no alterations to it will have any effect.

Protected operations

There are certain operations that need to be carefully protected from tampering with by hooks. In particular it should be close to impossible for a disable/uninstall hook to be able to cancel that action. Hooks are not designed to decide whether the operation should proceed, they should perform simple actions in response to the operation.

When hooks will run

It is important to note that aside from some exceptions listed later, this specification suggests that hooks will always be executed. This means that even if an add-on is disabled when it is uninstalled then the uninstall hook will still execute. Some consideration must be made whether to run hooks during safe mode or whether to potentially defer add-on changes until the next normal startup.

The specific moment when hooks are executed depends on the type of hook:

Install, enable and upgrade

These hooks will get executed in the early UI startup. Likely the final-ui-startup observer will be used to trigger them. This means that there will be no main application window yet.

Disable and uninstall

The hooks that are focused on stopping the extension from executing will run during early startup as the add-on is disabled/uninstalled. These hooks should not expect to be able to display any UI. Shortly after the hook's execution the application's process will be restarted

When hooks won't run

There are deliberately very few circumstances where hooks would not be executed.

The first is due to implementation details. If the directory for the extension in the install location is removed, or if the registry key for the extension in the registry install location is removed then no uninstall hook will be executed.

Secondly if the add-on is blocklisted then no hooks will be run for that add-on until it is no longer blocklisted. This is obviously important to stop a malicious add-on getting the ability to run code even after being blocked.

Potential problems

There are certain situations that hooks can cause which could cause problems:

  • Long running scripts will delay the startup of the browser. In particular a hook might try to start a web request to notify the server of add-on uninstallation.