Extension Manager:Install Hooks

From MozillaWiki
Jump to: navigation, 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 activated or deactivated, both to show a give a good user experience and to clean up after themselves. 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. There are two types of actions that add-on authors can request:

  • Resource cleanup after uninstall
  • Scripted hooks

Automatic resource removals

The extension manager will support automatically cleaning up certain resources when an add-on is uninstalled.

Identifying resources

The resources will be included in the install.rdf manifest using the following format:

<em:resources>
  <Description>
    <em:preference>extensions.foo.bar</em:preference>
    <em:preference>extensions.bar.*</em:preference>
    <em:file>foo/bar</em:file>
  </Description>
</em:resources>

The preference elements may either specify a specific preference or an entire preference branch. The preferences included will be reset to their default values.

The file elements specify files to be deleted from the profile directory using "/" as a separator on all platforms. Only exact files and directories may be named. When a directory is named, it and all files and directories in it will be deleted.

When resources are removed

Resources for an add-on will be removed after the add-on has been completely uninstalled, whether it be by the user's actions, or directory removal or anything else.

Scripted hooks

The following operations would cause a scripted hook to be executed:

  • Enabling (also runs during add-on installation)
  • Disabling (also runs if an enabled add-on is uninstalled)
  • Upgrading

How to include hooks

Scripted hooks are included simple JavaScript files in the add-on xpi. The following file structure should exist:

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

Only the hooks that the developer wishes to implement need to be included.

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>,
  // To be extended
};

The ADDON structure may not be protected from being altered by the hook, however the structure will get thrown away after the hook is executed.

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 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

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:

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, though if a means of running them after the first UI windows are displayed is found then that would be a better choice.

Disable

The disable hook will run during early startup as the add-on is disabled/uninstalled. This hook 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 disable 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.