2 # ***** BEGIN LICENSE BLOCK *****
3 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 # The contents of this file are subject to the Mozilla Public License Version
6 # 1.1 (the "License"); you may not use this file except in compliance with
7 # the License. You may obtain a copy of the License at
8 # http://www.mozilla.org/MPL/
10 # Software distributed under the License is distributed on an "AS IS" basis,
11 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # for the specific language governing rights and limitations under the
15 # The Original Code is the Extension Manager.
17 # The Initial Developer of the Original Code is
18 # the Mozilla Foundation.
19 # Portions created by the Initial Developer are Copyright (C) 2009
20 # the Initial Developer. All Rights Reserved.
23 # Dave Townsend <dtownsend@oxymoronical.com>
25 # Alternatively, the contents of this file may be used under the terms of
26 # either the GNU General Public License Version 2 or later (the "GPL"), or
27 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 # in which case the provisions of the GPL or the LGPL are applicable instead
29 # of those above. If you wish to allow use of your version of this file only
30 # under the terms of either the GPL or the LGPL, and not to allow others to
31 # use your version of this file under the terms of the MPL, indicate your
32 # decision by deleting the provisions above and replace them with the notice
33 # and other provisions required by the GPL or the LGPL. If you do not delete
34 # the provisions above, a recipient may use your version of this file under
35 # the terms of any one of the MPL, the GPL or the LGPL.
37 # ***** END LICENSE BLOCK *****
40 const Cc = Components.classes;
41 const Ci = Components.interfaces;
42 const Cr = Components.results;
44 const PREF_EM_UPDATE_ENABLED = "extensions.update.enabled";
46 Components.utils.import("resource://gre/modules/Services.jsm");
48 var EXPORTED_SYMBOLS = [ "AddonManager", "AddonManagerPrivate" ];
50 const CATEGORY_PROVIDER_MODULE = "addon-provider-module";
52 // A list of providers to load by default
53 const DEFAULT_PROVIDERS = [
54 "resource://gre/modules/XPIProvider.jsm",
55 "resource://gre/modules/LightweightThemeManager.jsm"
58 ["LOG", "WARN", "ERROR"].forEach(function(aName) {
59 this.__defineGetter__(aName, function() {
60 Components.utils.import("resource://gre/modules/AddonLogging.jsm");
62 LogManager.getLogger("addons.manager", this);
68 * Calls a callback method consuming any thrown exception. Any parameters after
69 * the callback parameter will be passed to the callback.
72 * The callback method to call
74 function safeCall(aCallback) {
75 var args = Array.slice(arguments, 1);
78 aCallback.apply(null, args);
81 WARN("Exception calling callback: " + e);
86 * Calls a method on a provider if it exists and consumes any thrown exception.
87 * Any parameters after the dflt parameter are passed to the provider's method.
90 * The provider to call
92 * The method name to call
94 * A default return value if the provider does not implement the named
95 * method or throws an error.
96 * @return the return value from the provider or dflt if the provider does not
97 * implement method or throws an error
99 function callProvider(aProvider, aMethod, aDefault) {
100 if (!(aMethod in aProvider))
103 var args = Array.slice(arguments, 3);
106 return aProvider[aMethod].apply(aProvider, args);
108 ERROR("Exception calling provider." + aMethod + ": " + e);
114 * A helper class to repeatedly call a listener with each object in an array
115 * optionally checking whether the object has a method in it.
118 * The array of objects to iterate through
120 * An optional method name, if not null any objects without this method
121 * will not be passed to the listener
123 * A listener implementing nextObject and noMoreObjects methods. The
124 * former will be called with the AsyncObjectCaller as the first
125 * parameter and the object as the second. noMoreObjects will be passed
126 * just the AsyncObjectCaller
128 function AsyncObjectCaller(aObjects, aMethod, aListener) {
129 this.objects = aObjects.slice(0);
130 this.method = aMethod;
131 this.listener = aListener;
136 AsyncObjectCaller.prototype = {
142 * Passes the next object to the listener or calls noMoreObjects if there
145 callNext: function AOC_callNext() {
146 if (this.objects.length == 0) {
147 this.listener.noMoreObjects(this);
151 let object = this.objects.shift();
152 if (!this.method || this.method in object)
153 this.listener.nextObject(this, object);
160 * This is the real manager, kept here rather than in AddonManager to keep its
161 * contents hidden from API users.
163 var AddonManagerInternal = {
164 installListeners: null,
165 addonListeners: null,
170 * Initializes the AddonManager, loading any known providers and initializing
173 startup: function AMI_startup() {
177 this.installListeners = [];
178 this.addonListeners = [];
180 let appChanged = true;
183 appChanged = Services.appinfo.version !=
184 Services.prefs.getCharPref("extensions.lastAppVersion");
189 LOG("Application has been upgraded");
190 Services.prefs.setCharPref("extensions.lastAppVersion",
191 Services.appinfo.version);
194 // Ensure all default providers have had a chance to register themselves
195 DEFAULT_PROVIDERS.forEach(function(url) {
197 Components.utils.import(url, {});
200 ERROR("Exception loading default provider \"" + url + "\": " + e);
204 // Load any providers registered in the category manager
205 let catman = Cc["@mozilla.org/categorymanager;1"].
206 getService(Ci.nsICategoryManager);
207 let entries = catman.enumerateCategory(CATEGORY_PROVIDER_MODULE);
208 while (entries.hasMoreElements()) {
209 let entry = entries.getNext().QueryInterface(Ci.nsISupportsCString).data;
210 let url = catman.getCategoryEntry(CATEGORY_PROVIDER_MODULE, entry);
213 Components.utils.import(url, {});
216 ERROR("Exception loading provider " + entry + " from category \"" +
221 let needsRestart = false;
222 this.providers.forEach(function(provider) {
223 callProvider(provider, "startup");
224 if (callProvider(provider, "checkForChanges", false, appChanged))
229 // Flag to the platform that a restart is necessary
231 let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].
232 getService(Ci.nsIAppStartup2);
233 appStartup.needsRestart = needsRestart;
238 * Registers a new AddonProvider.
241 * The provider to register
243 registerProvider: function AMI_registerProvider(aProvider) {
244 this.providers.push(aProvider);
246 // If we're registering after startup call this provider's startup.
248 callProvider(aProvider, "startup");
252 * Unregisters an AddonProvider.
255 * The provider to unregister
257 unregisterProvider: function AMI_unregisterProvider(aProvider) {
258 this.providers = this.providers.filter(function(p) {
259 return p != aProvider;
262 // If we're unregistering after startup call this provider's shutdown.
264 callProvider(aProvider, "shutdown");
268 * Shuts down the addon manager and all registered providers, this must clean
269 * up everything in order for automated tests to fake restarts.
271 shutdown: function AM_shutdown() {
272 this.providers.forEach(function(provider) {
273 callProvider(provider, "shutdown");
276 this.installListeners = null;
277 this.addonListeners = null;
278 this.started = false;
282 * Performs a background update check by starting an update for all add-ons
283 * that can be updated.
285 backgroundUpdateCheck: function AMI_backgroundUpdateCheck() {
286 if (!Services.prefs.getBoolPref(PREF_EM_UPDATE_ENABLED))
290 Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", scope);
291 scope.LightweightThemeManager.updateCurrentTheme();
293 this.getAllAddons(function getAddonsCallback(aAddons) {
294 aAddons.forEach(function BUC_forEachCallback(aAddon) {
295 // Check all add-ons for updates so that any compatibility updates will
298 onUpdateAvailable: function BUC_onUpdateAvailable(aAddon, aInstall) {
299 // Start installing updates when the add-on can be updated and
300 // background updates should be applied.
301 if (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE &&
302 aAddon.applyBackgroundUpdates) {
306 }, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
312 * Calls all registered InstallListeners with an event. Any parameters after
313 * the extraListeners parameter are passed to the listener.
316 * The method on the listeners to call
317 * @param aExtraListeners
318 * An array of extra InstallListeners to also call
319 * @return false if any of the listeners returned false, true otherwise
321 callInstallListeners: function AMI_callInstallListeners(aMethod, aExtraListeners) {
323 let listeners = this.installListeners;
325 listeners = aExtraListeners.concat(listeners);
326 let args = Array.slice(arguments, 2);
328 listeners.forEach(function(listener) {
330 if (aMethod in listener) {
331 if (listener[aMethod].apply(listener, args) === false)
336 WARN("InstallListener threw exception when calling " + aMethod + ": " + e);
343 * Calls all registered AddonListeners with an event. Any parameters after
344 * the method parameter are passed to the listener.
347 * The method on the listeners to call
349 callAddonListeners: function AMI_callAddonListeners(aMethod) {
350 var args = Array.slice(arguments, 1);
351 this.addonListeners.forEach(function(listener) {
353 if (aMethod in listener)
354 listener[aMethod].apply(listener, args);
357 WARN("AddonListener threw exception when calling " + aMethod + ": " + e);
363 * Notifies all providers that an add-on has been enabled when that type of
364 * add-on only supports a single add-on being enabled at a time. This allows
365 * the providers to disable theirs if necessary.
368 * The id of the enabled add-on
370 * The type of the enabled add-on
371 * @param aPendingRestart
372 * A boolean indicating if the change will only take place the next
373 * time the application is restarted
375 notifyAddonChanged: function AMI_notifyAddonChanged(aId, aType, aPendingRestart) {
376 this.providers.forEach(function(provider) {
377 callProvider(provider, "addonChanged", null, aId, aType, aPendingRestart);
382 * Notifies all providers they need to update the appDisabled property for
383 * their add-ons in response to an application change such as a blocklist
386 updateAddonAppDisabledStates: function AMI_updateAddonAppDisabledStates() {
387 this.providers.forEach(function(provider) {
388 callProvider(provider, "updateAddonAppDisabledStates");
393 * Asynchronously gets an AddonInstall for a URL.
396 * The url the add-on is located at
398 * A callback to pass the AddonInstall to
400 * The mimetype of the add-on
402 * An optional hash of the add-on
404 * An optional placeholder name while the add-on is being downloaded
406 * An optional placeholder icon URL while the add-on is being downloaded
408 * An optional placeholder version while the add-on is being downloaded
410 * An optional nsILoadGroup to associate any network requests with
411 * @throws if the aUrl, aCallback or aMimetype arguments are not specified
413 getInstallForURL: function AMI_getInstallForURL(aUrl, aCallback, aMimetype,
414 aHash, aName, aIconURL,
415 aVersion, aLoadGroup) {
416 if (!aUrl || !aMimetype || !aCallback)
417 throw new TypeError("Invalid arguments");
419 for (let i = 0; i < this.providers.length; i++) {
420 if (callProvider(this.providers[i], "supportsMimetype", false, aMimetype)) {
421 callProvider(this.providers[i], "getInstallForURL", null,
422 aUrl, aHash, aName, aIconURL, aVersion, aLoadGroup,
424 safeCall(aCallback, aInstall);
429 safeCall(aCallback, null);
433 * Asynchronously gets an AddonInstall for an nsIFile.
436 * the nsIFile where the add-on is located
438 * A callback to pass the AddonInstall to
440 * An optional mimetype hint for the add-on
441 * @throws if the aFile or aCallback arguments are not specified
443 getInstallForFile: function AMI_getInstallForFile(aFile, aCallback, aMimetype) {
444 if (!aFile || !aCallback)
445 throw Cr.NS_ERROR_INVALID_ARG;
447 new AsyncObjectCaller(this.providers, "getInstallForFile", {
448 nextObject: function(aCaller, aProvider) {
449 callProvider(aProvider, "getInstallForFile", null, aFile,
452 safeCall(aCallback, aInstall);
458 noMoreObjects: function(aCaller) {
459 safeCall(aCallback, null);
465 * Asynchronously gets all current AddonInstalls optionally limiting to a list
469 * An optional array of types to retrieve. Each type is a string name
471 * A callback which will be passed an array of AddonInstalls
472 * @throws if the aCallback argument is not specified
474 getInstallsByTypes: function AMI_getInstallsByTypes(aTypes, aCallback) {
476 throw Cr.NS_ERROR_INVALID_ARG;
480 new AsyncObjectCaller(this.providers, "getInstallsByTypes", {
481 nextObject: function(aCaller, aProvider) {
482 callProvider(aProvider, "getInstallsByTypes", null, aTypes,
483 function(aProviderInstalls) {
484 installs = installs.concat(aProviderInstalls);
489 noMoreObjects: function(aCaller) {
490 safeCall(aCallback, installs);
496 * Asynchronously gets all current AddonInstalls.
499 * A callback which will be passed an array of AddonInstalls
501 getAllInstalls: function AMI_getAllInstalls(aCallback) {
502 this.getInstallsByTypes(null, aCallback);
506 * Checks whether installation is enabled for a particular mimetype.
509 * The mimetype to check
510 * @return true if installation is enabled for the mimetype
512 isInstallEnabled: function AMI_isInstallEnabled(aMimetype) {
513 for (let i = 0; i < this.providers.length; i++) {
514 if (callProvider(this.providers[i], "supportsMimetype", false, aMimetype) &&
515 callProvider(this.providers[i], "isInstallEnabled"))
522 * Checks whether a particular source is allowed to install add-ons of a
526 * The mimetype of the add-on
528 * The uri of the source, may be null
529 * @return true if the source is allowed to install this mimetype
531 isInstallAllowed: function AMI_isInstallAllowed(aMimetype, aURI) {
532 for (let i = 0; i < this.providers.length; i++) {
533 if (callProvider(this.providers[i], "supportsMimetype", false, aMimetype) &&
534 callProvider(this.providers[i], "isInstallAllowed", null, aURI))
541 * Starts installation of an array of AddonInstalls notifying the registered
542 * web install listener of blocked or started installs.
545 * The mimetype of add-ons being installed
547 * The nsIDOMWindowInternal that started the installs
549 * the nsIURI that started the installs
551 * The array of AddonInstalls to be installed
553 installAddonsFromWebpage: function AMI_installAddonsFromWebpage(aMimetype,
557 if (!("@mozilla.org/addons/web-install-listener;1" in Cc)) {
558 WARN("No web installer available, cancelling all installs");
559 aInstalls.forEach(function(aInstall) {
566 let weblistener = Cc["@mozilla.org/addons/web-install-listener;1"].
567 getService(Ci.amIWebInstallListener);
569 if (!this.isInstallAllowed(aMimetype, aURI)) {
570 if (weblistener.onWebInstallBlocked(aSource, aURI, aInstalls,
572 aInstalls.forEach(function(aInstall) {
577 else if (weblistener.onWebInstallRequested(aSource, aURI, aInstalls,
579 aInstalls.forEach(function(aInstall) {
585 // In the event that the weblistener throws during instatiation or when
586 // calling onWebInstallBlocked or onWebInstallRequested all of the
587 // installs should get cancelled.
588 WARN("Failure calling web installer: " + e);
589 aInstalls.forEach(function(aInstall) {
596 * Adds a new InstallListener if the listener is not already registered.
599 * The InstallListener to add
601 addInstallListener: function AMI_addInstallListener(aListener) {
602 if (!this.installListeners.some(function(i) { return i == aListener; }))
603 this.installListeners.push(aListener);
607 * Removes an InstallListener if the listener is registered.
610 * The InstallListener to remove
612 removeInstallListener: function AMI_removeInstallListener(aListener) {
613 this.installListeners = this.installListeners.filter(function(i) {
614 return i != aListener;
619 * Asynchronously gets an add-on with a specific ID.
622 * The ID of the add-on to retrieve
624 * The callback to pass the retrieved add-on to
625 * @throws if the aId or aCallback arguments are not specified
627 getAddonByID: function AMI_getAddonByID(aId, aCallback) {
628 if (!aId || !aCallback)
629 throw Cr.NS_ERROR_INVALID_ARG;
631 new AsyncObjectCaller(this.providers, "getAddonByID", {
632 nextObject: function(aCaller, aProvider) {
633 callProvider(aProvider, "getAddonByID", null, aId, function(aAddon) {
635 safeCall(aCallback, aAddon);
641 noMoreObjects: function(aCaller) {
642 safeCall(aCallback, null);
648 * Asynchronously gets an array of add-ons.
651 * The array of IDs to retrieve
653 * The callback to pass an array of Addons to
654 * @throws if the aId or aCallback arguments are not specified
656 getAddonsByIDs: function AMI_getAddonsByIDs(aIds, aCallback) {
657 if (!aIds || !aCallback)
658 throw Cr.NS_ERROR_INVALID_ARG;
662 new AsyncObjectCaller(aIds, null, {
663 nextObject: function(aCaller, aId) {
664 AddonManagerInternal.getAddonByID(aId, function(aAddon) {
670 noMoreObjects: function(aCaller) {
671 safeCall(aCallback, addons);
677 * Asynchronously gets add-ons of specific types.
680 * An optional array of types to retrieve. Each type is a string name
682 * The callback to pass an array of Addons to.
683 * @throws if the aCallback argument is not specified
685 getAddonsByTypes: function AMI_getAddonsByTypes(aTypes, aCallback) {
687 throw Cr.NS_ERROR_INVALID_ARG;
691 new AsyncObjectCaller(this.providers, "getAddonsByTypes", {
692 nextObject: function(aCaller, aProvider) {
693 callProvider(aProvider, "getAddonsByTypes", null, aTypes,
694 function(aProviderAddons) {
695 addons = addons.concat(aProviderAddons);
700 noMoreObjects: function(aCaller) {
701 safeCall(aCallback, addons);
707 * Asynchronously gets all installed add-ons.
710 * A callback which will be passed an array of Addons
712 getAllAddons: function AMI_getAllAddons(aCallback) {
713 this.getAddonsByTypes(null, aCallback);
717 * Asynchronously gets add-ons that have operations waiting for an application
718 * restart to complete.
721 * An optional array of types to retrieve. Each type is a string name
723 * The callback to pass the array of Addons to
724 * @throws if the aCallback argument is not specified
726 getAddonsWithOperationsByTypes:
727 function AMI_getAddonsWithOperationsByTypes(aTypes, aCallback) {
729 throw Cr.NS_ERROR_INVALID_ARG;
733 new AsyncObjectCaller(this.providers, "getAddonsWithOperationsByTypes", {
734 nextObject: function(aCaller, aProvider) {
735 callProvider(aProvider, "getAddonsWithOperationsByTypes", null, aTypes,
736 function(aProviderAddons) {
737 addons = addons.concat(aProviderAddons);
742 noMoreObjects: function(caller) {
743 safeCall(aCallback, addons);
749 * Adds a new AddonListener if the listener is not already registered.
752 * The listener to add
754 addAddonListener: function AMI_addAddonListener(aListener) {
755 if (!this.addonListeners.some(function(i) { return i == aListener; }))
756 this.addonListeners.push(aListener);
760 * Removes an AddonListener if the listener is registered.
763 * The listener to remove
765 removeAddonListener: function AMI_removeAddonListener(aListener) {
766 this.addonListeners = this.addonListeners.filter(function(i) {
767 return i != aListener;
773 * Should not be used outside of core Mozilla code. This is a private API for
774 * the startup and platform integration code to use. Refer to the methods on
775 * AddonManagerInternal for documentation however note that these methods are
776 * subject to change at any time.
778 var AddonManagerPrivate = {
779 startup: function AMP_startup() {
780 AddonManagerInternal.startup();
783 registerProvider: function AMP_registerProvider(aProvider) {
784 AddonManagerInternal.registerProvider(aProvider);
787 unregisterProvider: function AMP_unregisterProvider(aProvider) {
788 AddonManagerInternal.unregisterProvider(aProvider);
791 shutdown: function AMP_shutdown() {
792 AddonManagerInternal.shutdown();
795 backgroundUpdateCheck: function AMP_backgroundUpdateCheck() {
796 AddonManagerInternal.backgroundUpdateCheck();
799 notifyAddonChanged: function AMP_notifyAddonChanged(aId, aType, aPendingRestart) {
800 AddonManagerInternal.notifyAddonChanged(aId, aType, aPendingRestart);
803 updateAddonAppDisabledStates: function AMP_updateAddonAppDisabledStates() {
804 AddonManagerInternal.updateAddonAppDisabledStates();
807 callInstallListeners: function AMP_callInstallListeners(aMethod) {
808 return AddonManagerInternal.callInstallListeners.apply(AddonManagerInternal,
812 callAddonListeners: function AMP_callAddonListeners(aMethod) {
813 AddonManagerInternal.callAddonListeners.apply(AddonManagerInternal, arguments);
818 * This is the public API that UI and developers should be calling. All methods
819 * just forward to AddonManagerInternal.
822 // Constants for the AddonInstall.state property
823 // The install is available for download.
825 // The install is being downloaded.
826 STATE_DOWNLOADING: 1,
827 // The install is checking for compatibility information.
829 // The install is downloaded and ready to install.
831 // The download failed.
832 STATE_DOWNLOAD_FAILED: 4,
833 // The add-on is being installed.
835 // The add-on has been installed.
837 // The install failed.
838 STATE_INSTALL_FAILED: 7,
839 // The install has been cancelled.
842 // Constants representing different types of errors while downloading an
844 // The download failed due to network problems.
845 ERROR_NETWORK_FAILURE: -1,
846 // The downloaded file did not match the provided hash.
847 ERROR_INCORRECT_HASH: -2,
848 // The downloaded file seems to be corrupted in some way.
849 ERROR_CORRUPT_FILE: -3,
850 // An error occured trying to write to the filesystem.
851 ERROR_FILE_ACCESS: -4,
853 // These must be kept in sync with AddonUpdateChecker.
854 // No error was encountered.
855 UPDATE_STATUS_NO_ERROR: 0,
856 // The update check timed out
857 UPDATE_STATUS_TIMEOUT: -1,
858 // There was an error while downloading the update information.
859 UPDATE_STATUS_DOWNLOAD_ERROR: -2,
860 // The update information was malformed in some way.
861 UPDATE_STATUS_PARSE_ERROR: -3,
862 // The update information was not in any known format.
863 UPDATE_STATUS_UNKNOWN_FORMAT: -4,
864 // The update information was not correctly signed or there was an SSL error.
865 UPDATE_STATUS_SECURITY_ERROR: -5,
867 // Constants to indicate why an update check is being performed
868 // Update check has been requested by the user.
869 UPDATE_WHEN_USER_REQUESTED: 1,
870 // Update check is necessary to see if the Addon is compatibile with a new
871 // version of the application.
872 UPDATE_WHEN_NEW_APP_DETECTED: 2,
873 // Update check is necessary because a new application has been installed.
874 UPDATE_WHEN_NEW_APP_INSTALLED: 3,
875 // Update check is a regular background update check.
876 UPDATE_WHEN_PERIODIC_UPDATE: 16,
877 // Update check is needed to check an Addon that is being installed.
878 UPDATE_WHEN_ADDON_INSTALLED: 17,
880 // Constants for operations in Addon.pendingOperations
881 // Indicates that the Addon has no pending operations.
883 // Indicates that the Addon will be enabled after the application restarts.
885 // Indicates that the Addon will be disabled after the application restarts.
887 // Indicates that the Addon will be uninstalled after the application restarts.
888 PENDING_UNINSTALL: 4,
889 // Indicates that the Addon will be installed after the application restarts.
893 // Constants for permissions in Addon.permissions.
894 // Indicates that the Addon can be uninstalled.
895 PERM_CAN_UNINSTALL: 1,
896 // Indicates that the Addon can be enabled by the user.
898 // Indicates that the Addon can be disabled by the user.
900 // Indicates that the Addon can be upgraded.
903 // General descriptions of where items are installed.
904 // Installed in this profile.
906 // Installed for all of this user's profiles.
908 // Installed and owned by the application.
909 SCOPE_APPLICATION: 4,
910 // Installed for all users of the computer.
912 // The combination of all scopes.
915 getInstallForURL: function AM_getInstallForURL(aUrl, aCallback, aMimetype,
916 aHash, aName, aIconURL,
917 aVersion, aLoadGroup) {
918 AddonManagerInternal.getInstallForURL(aUrl, aCallback, aMimetype, aHash,
919 aName, aIconURL, aVersion, aLoadGroup);
922 getInstallForFile: function AM_getInstallForFile(aFile, aCallback, aMimetype) {
923 AddonManagerInternal.getInstallForFile(aFile, aCallback, aMimetype);
926 getAddonByID: function AM_getAddonByID(aId, aCallback) {
927 AddonManagerInternal.getAddonByID(aId, aCallback);
930 getAddonsByIDs: function AM_getAddonsByIDs(aIds, aCallback) {
931 AddonManagerInternal.getAddonsByIDs(aIds, aCallback);
934 getAddonsWithOperationsByTypes:
935 function AM_getAddonsWithOperationsByTypes(aTypes, aCallback) {
936 AddonManagerInternal.getAddonsWithOperationsByTypes(aTypes, aCallback);
939 getAddonsByTypes: function AM_getAddonsByTypes(aTypes, aCallback) {
940 AddonManagerInternal.getAddonsByTypes(aTypes, aCallback);
943 getAllAddons: function AM_getAllAddons(aCallback) {
944 AddonManagerInternal.getAllAddons(aCallback);
947 getInstallsByTypes: function AM_getInstallsByTypes(aTypes, aCallback) {
948 AddonManagerInternal.getInstallsByTypes(aTypes, aCallback);
951 getAllInstalls: function AM_getAllInstalls(aCallback) {
952 AddonManagerInternal.getAllInstalls(aCallback);
955 isInstallEnabled: function AM_isInstallEnabled(aType) {
956 return AddonManagerInternal.isInstallEnabled(aType);
959 isInstallAllowed: function AM_isInstallAllowed(aType, aUri) {
960 return AddonManagerInternal.isInstallAllowed(aType, aUri);
963 installAddonsFromWebpage: function AM_installAddonsFromWebpage(aType, aSource,
965 AddonManagerInternal.installAddonsFromWebpage(aType, aSource, aUri, aInstalls);
968 addInstallListener: function AM_addInstallListener(aListener) {
969 AddonManagerInternal.addInstallListener(aListener);
972 removeInstallListener: function AM_removeInstallListener(aListener) {
973 AddonManagerInternal.removeInstallListener(aListener);
976 addAddonListener: function AM_addAddonListener(aListener) {
977 AddonManagerInternal.addAddonListener(aListener);
980 removeAddonListener: function AM_removeAddonListener(aListener) {
981 AddonManagerInternal.removeAddonListener(aListener);