|
|
| Line 1: |
Line 1: |
| =Overview= | | =Overview= |
| The current extension manager API is focussed on managing XPI style add-ons and is currently very limited forcing the UI and other callers to rely on direct access to the RDF datastore to glean certain required information about add-ons. | | The current extension manager API is focussed on managing XPI style add-ons and is currently very limited forcing the UI and other callers to rely on direct access to the RDF datastore to glean required information about add-ons. |
|
| |
|
| The main goals of this rewrite are: | | The main goals of this rewrite are: |
| Line 9: |
Line 9: |
| * Remove direct access to the datastore | | * Remove direct access to the datastore |
|
| |
|
| =Add-on states= | | =High Level View= |
| The new APIs represent add-ons in a number of states but these can broadly be split into two types, Local add-ons and Available add-ons. The API objects representing these add-ons are considered live views of the add-on. As operations are performed (disabling, downloading etc.) the properties of the object will update to reflect the new state. The objects represent add-on instances however. If I have an object representing the installed add-on "foo", then the user uninstalls and then reinstalls "foo" then the object still represents the old uninstalled instance of "foo". It is undefined whether retrieving the same add-on from the API twice will give two references to the same object or two separate objects that have the same properties. | | The new API is accessed through a global [[Extension Manager:API Rewrite:API#AddonManager|AddonManager]] object that is included in a JavaScript module. There will also be a limited amount of access provided through an XPCOM component but this is intended for the XRE to use during startup. The API makes no assumptions about what types of add-ons do and how they are used, it does make some basic assumptions about the information available about them and the install process. |
|
| |
|
| ==Local add-ons==
| | Users of the API can register to receive events about all add-ons. The API also gives access to two main types of objects: |
| Local add-ons are add-ons that have been installed, or are installed but pending an application restart to be activated.
| |
| <center>[[File:ExtIAddon.png]]</center>
| |
| The majority of the fields available are expected to be self explanatory however a couple deserve special mention:
| |
| ; isActive : This indicates whether the add-on is currently active in the application. For XPI style add-ons this cannot change without a restart, for other add-ons it may change instantly as the add-on is enabled/disabled.
| |
| ; availableUpdate : When an update to the add-on has been detected this is set to the information about the updated verson.
| |
| ; pendingUpdate : When an updated version of the add-on has been downloaded and installed, but the install requires a restart, this will give a reference to the new version.
| |
| ; pending* : Whenever an operation is waiting for an application restart to complete one of these flags may be set.
| |
| ; checkCompatibility : This method is similar to isCompatible however it allows checking compatibility with a particular version of the application. This is necessary for the application update system to determine whether new versions of add-ons are necessary before an application update.
| |
|
| |
|
| It is expected that certain types of add-ons will implement an additional interface to provide specific methods/attributes. For example XPI add-ons will need to expose a method to get access to the installation files as we currently do through the <code>nsIInstallLocation</code> interface.
| | ==Addon== |
| | The [[Extension Manager:API Rewrite:API#Addon|Addon]] object represents an add-on that is installed on the local system. This is a loose term since it also includes add-ons that have been downloaded and will be installed when the application is restarted. There are a set of properties that will be available for all types of add-ons and then each type of add-on may have additional properties. The same goes for operations that can be performed on the add-on. |
|
| |
|
| ==Available add-ons==
| | Certain add-ons may have restrictions over what operations can be performed. These restrictions could be just down to the nature of the add-on (themes cannot be disabled normally) or down to system policies (user's may not have access to uninstall some add-ons f.e.). Each Addon has a permissions property that indicates what operations can currently be performed. |
| Available add-ons are add-ons that are known to be available somewhere. This may include:
| |
|
| |
|
| * Add-ons offered for install by a website
| | Some types of add-ons may require restarts for certain operations. XPI style extensions for example require restarts for almost all operations. The API exposes the operations that are pending in the pendingOperations property. It is also possible that this property may be used to indicate operations that have been deferred for any reason, maybe timing issues, maybe a dependency is pending install. Pending operations can make it hard to tell what state an actual add-on is in. To help solve this the isActive property indicates whether the add-on is currently active. This is separate to and may be different to the various userDisabled, isCompatible and other properties that indicate whether an add-on can be active or not. |
| * Updated versions of add-ons detected by the update system
| |
| * Add-ons on the local filesystem the user is trying to install
| |
|
| |
|
| Available add-ons also go through a number of states between simply being known as available, through downloading and on to installing.
| | ===Liveness=== |
| <center>[[File:ExtIInstall.png]]</center>
| | It is currently undecided whether Addon objects are truly live views or not. There are a few options with pros and cons: |
| The fields of the <code>extIInstall</code> interface are filled out depending on the available information. Some install methods for example do not give any information about the name or version of the add-on being installed.
| |
| ; addon : This is an overloaded field. If the <code>extIInstall</code> represents an update to an existing add-on then the <code>addon</code> field references the old version of that add-on. After the available add-on has been downloaded and installed however the <code>addon</code> field references the installed add-on.
| |
| ; certificate : If the available add-on's code has been signed then this will hold the certificate. This may not be available until after downloading has begun/ended.
| |
|
| |
|
| ''Consider splitting the <code>addon</code> field into two separate fields'' | | ;Totally live :Here the Addon object's properties are always guaranteed to be up to date. There are really only two ways to do this, either a property access ends up as a database query or we cache every Addon object retrieved through the API and make sure that is up to date. The former is a problem since we want to avoid synchronous database queries and making all property accesses asynch would be wrong. The latter is a potential memory concern perhaps mitigated if we could get some weak reference support into JS. |
|
| |
|
| =Management=
| | ;Single instance live :Here if you perform an operation on an instance of Addon then that instance will have its properties updated. Any other cached instances of Addon that are representing the same add-on would not get updated though. This is potentially confusing for obvious reasons, but maybe not terrible. A general rule of recommending people not keep instances cached anywhere would seem to solve it. |
| The global management interface is a lot simpler in this API. Essentially it only contains methods to start installs, list local add-ons and available add-ons, and adding various listeners to be notification about important events.
| |
| <center>[[File:ExtIManager.png]]</center>
| |
|
| |
|
| ''Need to decide whether pending installs and/or pending upgrades appear in <code>getAddons</code>. They have to be reachable somehow but presumably they are through <code>getInstalls</code> although indirectly.'' | | ;Never live :Here the Addon's properties are fixed at time of retrieval and never update. It is perhaps less confusing that the previous option but ultimately less useful too I think. |
|
| |
|
| Additionally there is a need for a private interface to the manager. This is only to be used by the platform and other internal components in order to facilitate add-on loading and blocklisting. The actual content of this is likely not as it stands here, this is just a copy of the existing internal methods from <code>nsIExtensionManager</code>
| | ==AddonInstall== |
| <center>[[File:ExtIManagerInternal.png]]</center>
| | The [[Extension Manager:API Rewrite:API#AddonInstall|AddonInstall]] object represents an add-on that is not yet installed. Again this is a loose definition, technically an AddonInstall object exists for add-ons that have just been installed. Essentially this object begins representing an add-on that can be installed (and may come from an update check to an existing add-on, a request to install a new add-on or a search for new add-ons). It tracks the high level progress of any necessary downloads and installation of the add-on. |
|
| |
|
| =Listeners= | | ==Add-on Providers== |
| In order for the UI to be kept up to date with the state of add-ons and installs there are a number of listeners that can be registered for. These are split into three types.
| | Underneath the manager (and essentially invisible through the API) are a set of add-on providers. Each one manages a specific type of add-on, for example there can be a provider for XPI style add-ons (perhaps multiple providers for each type of XPI add-on but that's unlikely), a provider for plugins, a provider for lightweight themes, etc. There will probably be a hardcoded set of providers for the application and then some means for add-ons to register their own providers. It is up to the providers to maintain their lists of installed add-ons, perform installation and uninstallation and send appropriate notifications out to registered listeners. |
|
| |
|
| ==Local add-on events==
| | The new APIs represent add-ons in a number of states but these can broadly be split into two types, Local add-ons and Available add-ons. The API objects representing these add-ons are considered live views of the add-on. As operations are performed (disabling, downloading etc.) the properties of the object will update to reflect the new state. The objects represent add-on instances however. If I have an object representing the installed add-on "foo", then the user uninstalls and then reinstalls "foo" then the object still represents the old uninstalled instance of "foo". It is undefined whether retrieving the same add-on from the API twice will give two references to the same object or two separate objects that have the same properties. |
| These events are focused on local add-ons and allows the UI to change state as the add-ons are enabled/disabled/etc.
| |
| <center>[[File:ExtIAddonListener.png]]</center>
| |
| | |
| ''I think there are additional events we are going to need here.''
| |
| | |
| ==Available add-on events==
| |
| These events cover the progress of detecting, downloading and installing available add-ons.
| |
| <center>[[File:ExtIInstallListener.png]]</center>
| |
| | |
| ==Update check events==
| |
| When performing an update check the following listener will receive events about the progress of the check.
| |
| <center>[[File:ExtIUpdateCheckListener.png]]</center>
| |
| | |
| ; onUpdateAvailable : This will indicate an available add-on that is compatible with the application version that the update check was performed for.
| |
| ; onCompatibilityUpdates : This indicates that the local add-on that an update check was performed for received a compatibility update during the check.
| |
| ; onUpdateFinished: This is always called at the end of the check and indicates whether there was a success or failure.
| |
| | |
| ''We might consider having onUpdateAvailable be called for every available add-on, callers could then decide which of the available new versions to install.''
| |
| | |
| =Implementation=
| |
| It is expected that the extension manager code will be split into multiple parts consisting of a central manager that doesn't have very much functionality and then a number of separate components to manage different types of add-ons. It's not defined how the manager will interact with the separate components but presumably we will either make them separate xpcom components with a well defined interface, or use jsm modules. Presumably the separate components will need their own datastores for their own specific needs, however we might consider having them all share a single sqlite database. | |
| | |
| The central management code will have to be written, likely mostly from scratch but this is just a thin wrapper around the separate components. The existing XPI management code can be reused to make up the separate component handling XPI add-ons. The UI will also have to be rewritten to use the new API rather than the RDF datastore.
| |