Extension Manager:Addon Conflict Resolution
This requirement is essentially about uplifting the extension dependencies work (covered at Extension Dependencies) to provide greater control to add-on authors over where their add-ons can and can't be installed. This document covers the current situation, some requirements not currently met and then goes on to propose an implementation.
Contents
Current Situation
Currently three levels of control are given to add-on authors:
- Authors must specify a list of applications with min and max versions (targetApplication) that the add-on can be installed in. One must match the current application.
- Authors can specify a list of platforms (targetPlatform) that the add-on will work on. If any are specified then one must match the current platform.
- Authors can specify a list of add-on dependencies (requires). For every dependency listed the given add-on must already be installed and enabled.
It should be noted that the first two control whether the add-on can be installed, the latter only controls whether the add-on is enabled or not.
New Requirements
There are two main requirements that are not met by the current implementation:
Different add-on dependencies per target application
Add-on authors wish to be able to specify that add-on dependencies are only required for certain applications. The most common example of this is add-ons that require the calendar functionality. They need to be able to say that they can be installed in Sunbird, and installed in Thunderbird if the Lightning extension is installed. The current system does not allow for the Lightning check since adding it would not allow installation into Sunbird.
Conflicting add-ons
Some add-ons simply conflict with each other, particularly if the two add-ons are providing similar enhancements. Currently there is no way to specify that one add-on should not be used in conjunction with another. Providing this would give usability benefits to users who should hopefully see less issues with conflicting add-ons breaking the application.
Proposed Implementation
The proposed implementation adds a new property type to the install manifest and changes the behaviour of an existing property:
RDF construct changes
It is proposed that a new property, "conflicts" be implemented that points to an rdf Description that contains details about an add-on what conflicts with the current add-on (id, minVersion and maxVersion). If the given add-on is installed and enabled then this add-on must not be enabled. Below is an example of this:
<?xml version="1.0"?> <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#"> <Description about="urn:mozilla:install-manifest"> <em:conflicts> <Description> <em:id>{05cab068-ba4d-4fbb-8ee5-b887434647ac}</em:id> <em:minVersion>1.0</em:minVersion> <em:maxVersion>2.0</em:maxVersion> </Description> </em:conflicts> </Description> </RDF>
The id used in a requires declaration currently must be an add-on. It is proposed that this be extended and the id be allowed to be an add-on id, an application id or the toolkit generic id. This essentially makes the existing targetApplication property redundant. It will no longer be used internally, but will be handled as detailed below in the backwards compatibility section.
Currently the requires property points to an rdf Description type which contains properties of the required add-on. It is proposed that this be extended in that it may also point to an rdf Alt or an rdf Seq. In this event the list must contain a number of requires or conflicts properties. If the requires was an Alt, then at least one of the requirements must be met. If it was a Seq then all of the requirements must be met. In this way requirements may be combined using basic boolean expressions, Seq being AND and Alt being OR.
An example below demonstrates an install.rdf that would allow installation into Sunbird or Thunderbird with Lightning. The other normally required properties have been removed for brevity:
<?xml version="1.0"?> <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#"> <Description about="urn:mozilla:install-manifest"> <em:requires> <Alt> <!-- Sunbird requirement --> <em:requires> <Description> <em:id>{718e30fb-e89b-41dd-9da7-e25a45638b28}</em:id> <em:minVersion>0.4</em:minVersion> <em:maxVersion>0.6</em:maxVersion> </Description> </em:requires> <em:requires> <Seq> <!-- Thunderbird requirement --> <em:requires> <Description> <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id> <em:minVersion>1.5</em:minVersion> <em:maxVersion>2.0.0.*</em:maxVersion> </Description> </em:requires> <!-- Lightning requirement --> <em:requires> <Description> <em:id>{e2fda1a4-762b-4020-b5ad-a41df1933103}</em:id> <em:minVersion>0.3</em:minVersion> <em:maxVersion>0.3.*</em:maxVersion> </Description> </em:requires> </Seq> </em:requires> </Alt> </em:requires> </Description> </RDF>
Backwards compatibility
In order to provide backwards compatibility existing install.rdf's must be processed. In the case of requires properties this is simple, old versions will continue to work as is. The main difference is the targetApplication property. When an install.rdf is parsed if any targetApplication properties are present then an implicit requires Alt property will be generated. All the details of the targetApplication properties will then be copied into requires inside this implicit property.
Issues with the implementation
There are some issues with the proposed implementation:
The implementation allows authors to specify very complex sets of requirements. This is not necessarily an issue, in fact it makes the EM very flexible to authors. The one main issue here is that it is possible to make the requirements infinitely recursive, however that would be detectable and make the add-on uninstallable.
Currently an add-on must specify that it is compatible with a given application using a targetApplication marker. That would no longer be the case, in fact an add-on need not specify compatibility with any application at all, for example it culd just claim compatibility with the Lightning extension. This makes informing the user about what is going on very difficult. The best example is on install, identifying that the add-on should not be installed because Lightning isn't there is easy, however the install.rdf doesn't contain the names of the add-ons it requires and if the requirements are complex trying to decide exactly what to tell the user is missing would be difficult. Mike Beltzner has suggested that the detail in the current incompatible dialog could be reduced so it's possible that this is a non-issue.
Currently during a compatibility update any changed maxVersion's for a given targetApplication are remembered in the local datasource. That procedure would no longer be possible. Since a given application may appear multiple times in the requirements list there isn't really any way to be sure which particular point in the graph the update is talking about. The only real option is to update the entire graph during a compatibility update which is somewhat less elegant.
The previous point also requires that the update rdf actually specify the entire requirements set. This would at some point become necessary in order to handle automatic dependency resolution, however it causes an issue with old update rdfs. There are add-ons out there that specify requirements, but do not include those requirements in the update rdf. This can be solved if we assume that all such add-ons also use the regular targetApplication entries in install.rdf (which of course for the time being they have to). In this situation in the local datasource we have an implicitly generated requires Alt. All that we need to is just rebuild that in the situation where the update rdf only contains targetApplication markers.
addons.mozilla.org would have to be updated to be able to handle the more complex requirements. Detecting which applications an add-on can be installed into is fairly easy, however if they also wish to list the other add-on dependencies then it becomes more complex, particularly when the requirements are complex.
It becomes difficult to determine whether or not to reject installation of an add-on. Currently add-ons that support the current application are installed, but are disabled if other add-on dependencies aren't present. That would be difficult if not impossible to determine in the proposed implementation. Take the given install.rdf above and assume we are trying to install that extension into Firefox. There is no longer any information about what an id refers to so we can no longer make the call on whether the add-on would ever be able to work in Firefox. The Sunbird id could be an add-on's id for all Firefox knows.
Related bugs
- bug 382312 - Bug tracking this requirement.
- bug 299716 - The given implementation would fix this bug.
- bug 301236 - The given implementation would fix this bug.