addon-sdk/source/lib/sdk/addon/installer.js

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:94022e2db477
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 module.metadata = {
6 "stability": "experimental"
7 };
8
9 const { Cc, Ci, Cu } = require("chrome");
10 const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm");
11 const { defer } = require("../core/promise");
12 const { setTimeout } = require("../timers");
13
14 /**
15 * `install` method error codes:
16 *
17 * https://developer.mozilla.org/en/Addons/Add-on_Manager/AddonManager#AddonInstall_errors
18 */
19 exports.ERROR_NETWORK_FAILURE = AddonManager.ERROR_NETWORK_FAILURE;
20 exports.ERROR_INCORRECT_HASH = AddonManager.ERROR_INCORRECT_HASH;
21 exports.ERROR_CORRUPT_FILE = AddonManager.ERROR_CORRUPT_FILE;
22 exports.ERROR_FILE_ACCESS = AddonManager.ERROR_FILE_ACCESS;
23
24 /**
25 * Immediatly install an addon.
26 *
27 * @param {String} xpiPath
28 * file path to an xpi file to install
29 * @return {Promise}
30 * A promise resolved when the addon is finally installed.
31 * Resolved with addon id as value or rejected with an error code.
32 */
33 exports.install = function install(xpiPath) {
34 let { promise, resolve, reject } = defer();
35
36 // Create nsIFile for the xpi file
37 let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
38 try {
39 file.initWithPath(xpiPath);
40 }
41 catch(e) {
42 reject(exports.ERROR_FILE_ACCESS);
43 return promise;
44 }
45
46 // Listen for installation end
47 let listener = {
48 onInstallEnded: function(aInstall, aAddon) {
49 aInstall.removeListener(listener);
50 // Bug 749745: on FF14+, onInstallEnded is called just before `startup()`
51 // is called, but we expect to resolve the promise only after it.
52 // As startup is called synchronously just after onInstallEnded,
53 // a simple setTimeout(0) is enough
54 setTimeout(resolve, 0, aAddon.id);
55 },
56 onInstallFailed: function (aInstall) {
57 console.log("failed");
58 aInstall.removeListener(listener);
59 reject(aInstall.error);
60 },
61 onDownloadFailed: function(aInstall) {
62 this.onInstallFailed(aInstall);
63 }
64 };
65
66 // Order AddonManager to install the addon
67 AddonManager.getInstallForFile(file, function(install) {
68 if (install.error != null) {
69 install.addListener(listener);
70 install.install();
71 } else {
72 reject(install.error);
73 }
74 });
75
76 return promise;
77 };
78
79 exports.uninstall = function uninstall(addonId) {
80 let { promise, resolve, reject } = defer();
81
82 // Listen for uninstallation end
83 let listener = {
84 onUninstalled: function onUninstalled(aAddon) {
85 if (aAddon.id != addonId)
86 return;
87 AddonManager.removeAddonListener(listener);
88 resolve();
89 }
90 };
91 AddonManager.addAddonListener(listener);
92
93 // Order Addonmanager to uninstall the addon
94 getAddon(addonId).then(addon => addon.uninstall(), reject);
95
96 return promise;
97 };
98
99 exports.disable = function disable(addonId) {
100 return getAddon(addonId).then(addon => {
101 addon.userDisabled = true;
102 return addonId;
103 });
104 };
105
106 exports.enable = function enabled(addonId) {
107 return getAddon(addonId).then(addon => {
108 addon.userDisabled = false;
109 return addonId;
110 });
111 };
112
113 exports.isActive = function isActive(addonId) {
114 return getAddon(addonId).then(addon => addon.isActive && !addon.appDisabled);
115 };
116
117 function getAddon (id) {
118 let { promise, resolve, reject } = defer();
119 AddonManager.getAddonByID(id, addon => addon ? resolve(addon) : reject());
120 return promise;
121 }

mercurial