addon.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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 file,
  3. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. const {interfaces: Ci, utils: Cu} = Components;
  6. Cu.import("resource://gre/modules/AddonManager.jsm");
  7. Cu.import("resource://gre/modules/FileUtils.jsm");
  8. Cu.import("chrome://marionette/content/error.js");
  9. this.EXPORTED_SYMBOLS = ["addon"];
  10. this.addon = {};
  11. // from https://developer.mozilla.org/en-US/Add-ons/Add-on_Manager/AddonManager#AddonInstall_errors
  12. addon.Errors = {
  13. [-1]: "ERROR_NETWORK_FAILURE: A network error occured.",
  14. [-2]: "ERROR_INCORECT_HASH: The downloaded file did not match the expected hash.",
  15. [-3]: "ERROR_CORRUPT_FILE: The file appears to be corrupt.",
  16. [-4]: "ERROR_FILE_ACCESS: There was an error accessing the filesystem.",
  17. [-5]: "ERROR_SIGNEDSTATE_REQUIRED: The addon must be signed and isn't.",
  18. };
  19. function lookupError(code) {
  20. let msg = addon.Errors[code];
  21. return new UnknownError(msg);
  22. }
  23. /**
  24. * Install a Firefox addon.
  25. *
  26. * If the addon is restartless, it can be used right away. Otherwise a
  27. * restart is required.
  28. *
  29. * Temporary addons will automatically be uninstalled on shutdown and
  30. * do not need to be signed, though they must be restartless.
  31. *
  32. * @param {string} path
  33. * Full path to the extension package archive.
  34. * @param {boolean=} temporary
  35. * True to install the addon temporarily, false (default) otherwise.
  36. *
  37. * @return {Promise: string}
  38. * Addon ID.
  39. *
  40. * @throws {UnknownError}
  41. * If there is a problem installing the addon.
  42. */
  43. addon.install = function (path, temporary = false) {
  44. return new Promise((resolve, reject) => {
  45. let file = new FileUtils.File(path);
  46. let listener = {
  47. onInstallEnded: function (install, addon) {
  48. resolve(addon.id);
  49. },
  50. onInstallFailed: function (install) {
  51. reject(lookupError(install.error));
  52. },
  53. onInstalled: function (addon) {
  54. AddonManager.removeAddonListener(listener);
  55. resolve(addon.id);
  56. }
  57. };
  58. if (!temporary) {
  59. AddonManager.getInstallForFile(file, function (aInstall) {
  60. if (aInstall.error !== 0) {
  61. reject(lookupError(aInstall.error));
  62. }
  63. aInstall.addListener(listener);
  64. aInstall.install();
  65. });
  66. } else {
  67. AddonManager.addAddonListener(listener);
  68. AddonManager.installTemporaryAddon(file);
  69. }
  70. });
  71. };
  72. /**
  73. * Uninstall a Firefox addon.
  74. *
  75. * If the addon is restartless it will be uninstalled right away.
  76. * Otherwise, Firefox must be restarted for the change to take effect.
  77. *
  78. * @param {string} id
  79. * ID of the addon to uninstall.
  80. *
  81. * @return {Promise}
  82. */
  83. addon.uninstall = function (id) {
  84. return new Promise(resolve => {
  85. AddonManager.getAddonByID(id, function (addon) {
  86. addon.uninstall();
  87. resolve();
  88. });
  89. });
  90. };