Backed out changeset 3b48e1a81a17 (bug 1038068) for xpcshell orange even after a clobbering IGNORE IDL
authorWes Kocher <wkocher@mozilla.com>
Tue, 21 Apr 2015 18:21:52 -0700
changeset 240341 19ae213736588a54a0869463fc3605d618510e76
parent 240340 01fbd5debd94fcd4b8c765548f19aa8897d7bdaa
child 240342 fc5fe99decdb1edc4c38543bc85ef657b1eedb2d
push id28631
push usercbook@mozilla.com
push dateWed, 22 Apr 2015 13:28:54 +0000
treeherdermozilla-central@a955d8a44ca4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1038068
milestone40.0a1
backs out3b48e1a81a170634dce964cd462c752d09680805
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 3b48e1a81a17 (bug 1038068) for xpcshell orange even after a clobbering IGNORE IDL
browser/app/profile/firefox.js
browser/locales/en-US/chrome/browser/browser.properties
layout/tools/reftest/runreftest.py
modules/libpref/init/all.js
security/apps/AppTrustDomain.cpp
security/apps/addons-public.crt
security/apps/addons-stage.crt
security/apps/gen_cert_header.py
security/apps/moz.build
security/manager/ssl/public/nsIX509CertDB.idl
testing/profiles/prefs_general.js
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/internal/XPIProviderUtils.js
toolkit/mozapps/extensions/internal/moz.build
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_1/bootstrap.js
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_1/install.rdf
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_1/test.txt
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_2/bootstrap.js
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_2/install.rdf
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_2/test.txt
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/nonbootstrap_1/install.rdf
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/nonbootstrap_1/test.txt
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/nonbootstrap_2/install.rdf
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/nonbootstrap_2/test.txt
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/preliminary_bootstrap_2.xpi
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed_bootstrap_1.xpi
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed_bootstrap_2.xpi
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed_bootstrap_badid_2.xpi
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed_nonbootstrap_2.xpi
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed_nonbootstrap_badid_2.xpi
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/unsigned_bootstrap_2.xpi
toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/unsigned_nonbootstrap_2.xpi
toolkit/mozapps/extensions/test/xpcshell/head_addons.js
toolkit/mozapps/extensions/test/xpcshell/test_migrate1.js
toolkit/mozapps/extensions/test/xpcshell/test_migrate3.js
toolkit/mozapps/extensions/test/xpcshell/test_signed_inject.js
toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js
toolkit/mozapps/extensions/test/xpcshell/test_signed_migrate.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -64,19 +64,16 @@ pref("extensions.update.autoUpdateDefaul
 pref("extensions.hotfix.id", "firefox-hotfix@mozilla.org");
 pref("extensions.hotfix.cert.checkAttributes", true);
 pref("extensions.hotfix.certs.1.sha1Fingerprint", "91:53:98:0C:C1:86:DF:47:8F:35:22:9E:11:C9:A7:31:04:49:A1:AA");
 
 // Disable add-ons that are not installed by the user in all scopes by default.
 // See the SCOPE constants in AddonManager.jsm for values to use here.
 pref("extensions.autoDisableScopes", 15);
 
-// Don't require signed add-ons by default
-pref("xpinstall.signatures.required", false);
-
 // Dictionary download preference
 pref("browser.dictionaries.download.url", "https://addons.mozilla.org/%LOCALE%/firefox/dictionaries/");
 
 // At startup, should we check to see if the installation
 // date is older than some threshold
 pref("app.update.checkInstallTime", true);
 
 // The number of days a binary is permitted to be old without checking is defined in
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -64,32 +64,30 @@ addonwatch.restart.accesskey=R
 # Semicolon-separated list of plural forms. See:
 # http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # #1 first add-on's name, #2 number of add-ons, #3 application name
 addonsInstalled=#1 has been installed successfully.;#2 add-ons have been installed successfully.
 addonsInstalledNeedsRestart=#1 will be installed after you restart #3.;#2 add-ons will be installed after you restart #3.
 addonInstallRestartButton=Restart Now
 addonInstallRestartButton.accesskey=R
 
-# LOCALIZATION NOTE (addonError-1, addonError-2, addonError-3, addonError-4, addonError-5):
+# LOCALIZATION NOTE (addonError-1, addonError-2, addonError-3, addonError-4):
 # #1 is the add-on name, #2 is the host name, #3 is the application name
 # #4 is the application version
 addonError-1=The add-on could not be downloaded because of a connection failure on #2.
 addonError-2=The add-on from #2 could not be installed because it does not match the add-on #3 expected.
 addonError-3=The add-on downloaded from #2 could not be installed because it appears to be corrupt.
 addonError-4=#1 could not be installed because #3 cannot modify the needed file.
-addonError-5=#3 has prevented this site from installing an unverified add-on.
 
-# LOCALIZATION NOTE (addonLocalError-1, addonLocalError-2, addonLocalError-3, addonLocalError-4, addonLocalError-5, addonErrorIncompatible, addonErrorBlocklisted):
+# LOCALIZATION NOTE (addonLocalError-1, addonLocalError-2, addonLocalError-3, addonLocalError-4, addonErrorIncompatible, addonErrorBlocklisted):
 # #1 is the add-on name, #3 is the application name, #4 is the application version
 addonLocalError-1=This add-on could not be installed because of a filesystem error.
 addonLocalError-2=This add-on could not be installed because it does not match the add-on #3 expected.
 addonLocalError-3=This add-on could not be installed because it appears to be corrupt.
 addonLocalError-4=#1 could not be installed because #3 cannot modify the needed file.
-addonLocalError-5=This add-on could not be installed because it has not been verified.
 addonErrorIncompatible=#1 could not be installed because it is not compatible with #3 #4.
 addonErrorBlocklisted=#1 could not be installed because it has a high risk of causing stability or security problems.
 
 # LOCALIZATION NOTE (deveditionTheme.name): This should be nearly the brand name for aurora.
 # See browser/branding/aurora/locales/*/brand.properties
 deveditionTheme.name=Developer Edition
 
 # LOCALIZATION NOTE (lwthemeInstallRequest.message): %S will be replaced with
--- a/layout/tools/reftest/runreftest.py
+++ b/layout/tools/reftest/runreftest.py
@@ -218,18 +218,16 @@ class RefTest(object):
     prefs['browser.snippets.firstrunHomepage.enabled'] = False
     # And for useragent updates.
     prefs['general.useragent.updates.enabled'] = False
     # And for webapp updates.  Yes, it is supposed to be an integer.
     prefs['browser.webapps.checkForUpdates'] = 0
     # And for about:newtab content fetch and pings.
     prefs['browser.newtabpage.directory.source'] = 'data:application/json,{"reftest":1}'
     prefs['browser.newtabpage.directory.ping'] = ''
-    # Allow unsigned add-ons
-    prefs['xpinstall.signatures.required'] = False
 
     #Don't use auto-enabled e10s
     prefs['browser.tabs.remote.autostart.1'] = False
     prefs['browser.tabs.remote.autostart.2'] = False
     if options.e10s:
       prefs['browser.tabs.remote.autostart'] = True
 
     for v in options.extraPrefs:
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4110,18 +4110,16 @@ pref("html5.flushtimer.subsequentdelay",
 // Push/Pop/Replace State prefs
 pref("browser.history.allowPushState", true);
 pref("browser.history.allowReplaceState", true);
 pref("browser.history.allowPopState", true);
 pref("browser.history.maxStateObjectSize", 655360);
 
 // XPInstall prefs
 pref("xpinstall.whitelist.required", true);
-// Only Firefox requires add-on signatures
-pref("xpinstall.signatures.required", false);
 pref("extensions.alwaysUnpack", false);
 pref("extensions.minCompatiblePlatformVersion", "2.0");
 
 pref("network.buffer.cache.count", 24);
 pref("network.buffer.cache.size",  32768);
 
 // Desktop Notification
 pref("notification.feature.enabled", false);
--- a/security/apps/AppTrustDomain.cpp
+++ b/security/apps/AppTrustDomain.cpp
@@ -18,19 +18,16 @@
 #include "marketplace-prod-reviewers.inc"
 #include "marketplace-dev-public.inc"
 #include "marketplace-dev-reviewers.inc"
 #include "marketplace-stage.inc"
 #include "xpcshell.inc"
 // Trusted Hosted Apps Certificates
 #include "manifest-signing-root.inc"
 #include "manifest-signing-test-root.inc"
-// Add-on signing Certificates
-#include "addons-public.inc"
-#include "addons-stage.inc"
 
 using namespace mozilla::pkix;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gPIPNSSLog;
 #endif
 
 static const unsigned int DEFAULT_MIN_RSA_BITS = 2048;
@@ -91,26 +88,16 @@ AppTrustDomain::SetTrustedRoot(AppTruste
       trustedDER.len = mozilla::ArrayLength(trustedAppPublicRoot);
       break;
 
     case nsIX509CertDB::TrustedHostedAppTestRoot:
       trustedDER.data = const_cast<uint8_t*>(trustedAppTestRoot);
       trustedDER.len = mozilla::ArrayLength(trustedAppTestRoot);
       break;
 
-    case nsIX509CertDB::AddonsPublicRoot:
-      trustedDER.data = const_cast<uint8_t*>(addonsPublicRoot);
-      trustedDER.len = mozilla::ArrayLength(addonsPublicRoot);
-      break;
-
-    case nsIX509CertDB::AddonsStageRoot:
-      trustedDER.data = const_cast<uint8_t*>(addonsStageRoot);
-      trustedDER.len = mozilla::ArrayLength(addonsStageRoot);
-      break;
-
     default:
       PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
       return SECFailure;
   }
 
   mTrustedRoot = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                          &trustedDER, nullptr, false, true);
   if (!mTrustedRoot) {
deleted file mode 100644
index 6ab711b996fc25b144995af21726b08bc399996d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 73e48cadfe2da5373a20a88a54148dac695da7d4..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
--- a/security/apps/gen_cert_header.py
+++ b/security/apps/gen_cert_header.py
@@ -30,15 +30,13 @@ array_names = [
   'marketplaceProdPublicRoot',
   'marketplaceProdReviewersRoot',
   'marketplaceDevPublicRoot',
   'marketplaceDevReviewersRoot',
   'marketplaceStageRoot',
   'trustedAppPublicRoot',
   'trustedAppTestRoot',
   'xpcshellRoot',
-  'addonsPublicRoot',
-  'addonsStageRoot',
 ]
 
 for n in array_names:
   # Make sure the lambda captures the right string.
   globals()[n] = lambda header, cert_filename, name=n: header.write(_create_header(name, _file_byte_generator(cert_filename)))
--- a/security/apps/moz.build
+++ b/security/apps/moz.build
@@ -29,17 +29,15 @@ headers_arrays_certs = [
     ('marketplace-prod-public.inc', 'marketplaceProdPublicRoot', 'marketplace-prod-public.crt'),
     ('marketplace-prod-reviewers.inc', 'marketplaceProdReviewersRoot', 'marketplace-prod-reviewers.crt'),
     ('marketplace-dev-public.inc', 'marketplaceDevPublicRoot', 'marketplace-dev-public.crt'),
     ('marketplace-dev-reviewers.inc', 'marketplaceDevReviewersRoot', 'marketplace-dev-reviewers.crt'),
     ('marketplace-stage.inc', 'marketplaceStageRoot', 'marketplace-stage.crt'),
     ('manifest-signing-root.inc', 'trustedAppPublicRoot', 'trusted-app-public.der'),
     ('manifest-signing-test-root.inc', 'trustedAppTestRoot', test_ssl_path + '/test_signed_manifest/trusted_ca1.der'),
     ('xpcshell.inc', 'xpcshellRoot', test_ssl_path + '/test_signed_apps/trusted_ca1.der'),
-    ('addons-public.inc', 'addonsPublicRoot', 'addons-public.crt'),
-    ('addons-stage.inc', 'addonsStageRoot', 'addons-stage.crt'),
 ]
 
 for header, array_name, cert in headers_arrays_certs:
     GENERATED_FILES += [header]
     h = GENERATED_FILES[header]
     h.script = 'gen_cert_header.py:' + array_name
     h.inputs = [cert]
--- a/security/manager/ssl/public/nsIX509CertDB.idl
+++ b/security/manager/ssl/public/nsIX509CertDB.idl
@@ -306,18 +306,16 @@ interface nsIX509CertDB : nsISupports {
   const AppTrustedRoot AppMarketplaceProdPublicRoot = 1;
   const AppTrustedRoot AppMarketplaceProdReviewersRoot = 2;
   const AppTrustedRoot AppMarketplaceDevPublicRoot = 3;
   const AppTrustedRoot AppMarketplaceDevReviewersRoot = 4;
   const AppTrustedRoot AppMarketplaceStageRoot = 5;
   const AppTrustedRoot AppXPCShellRoot = 6;
   const AppTrustedRoot TrustedHostedAppPublicRoot = 7;
   const AppTrustedRoot TrustedHostedAppTestRoot = 8;
-  const AppTrustedRoot AddonsPublicRoot = 9;
-  const AppTrustedRoot AddonsStageRoot = 10;
   void openSignedAppFileAsync(in AppTrustedRoot trustedRoot,
                               in nsIFile aJarFile,
                               in nsIOpenSignedAppFileCallback callback);
 
   /**
    * Given streams containing a signature and a manifest file, verifies
    * that the signature is valid for the manifest. The signature must
    * come from a certificate that is trusted for code signing and that
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -71,18 +71,16 @@ user_pref("experiments.manifest.uri", "h
 // AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
 user_pref("extensions.enabledScopes", 5);
 // Disable metadata caching for installed add-ons by default
 user_pref("extensions.getAddons.cache.enabled", false);
 // Disable intalling any distribution add-ons
 user_pref("extensions.installDistroAddons", false);
 // XPI extensions are required for test harnesses to load
 user_pref("extensions.defaultProviders.enabled", true);
-// Disable signature requirements where possible
-user_pref("xpinstall.signatures.required", false);
 
 user_pref("geo.wifi.uri", "http://%(server)s/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs");
 user_pref("geo.wifi.timeToWaitBeforeSending", 2000);
 user_pref("geo.wifi.scan", false);
 user_pref("geo.wifi.logging.enabled", true);
 
 // Make url-classifier updates so rare that they won't affect tests
 user_pref("urlclassifier.updateinterval", 172800);
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -2667,18 +2667,16 @@ this.AddonManager = {
   // The download failed due to network problems.
   ERROR_NETWORK_FAILURE: -1,
   // The downloaded file did not match the provided hash.
   ERROR_INCORRECT_HASH: -2,
   // The downloaded file seems to be corrupted in some way.
   ERROR_CORRUPT_FILE: -3,
   // An error occured trying to write to the filesystem.
   ERROR_FILE_ACCESS: -4,
-  // The add-on must be signed and isn't.
-  ERROR_SIGNEDSTATE_REQUIRED: -5,
 
   // These must be kept in sync with AddonUpdateChecker.
   // No error was encountered.
   UPDATE_STATUS_NO_ERROR: 0,
   // The update check timed out
   UPDATE_STATUS_TIMEOUT: -1,
   // There was an error while downloading the update information.
   UPDATE_STATUS_DOWNLOAD_ERROR: -2,
@@ -2804,30 +2802,16 @@ this.AddonManager = {
   // an application change making an add-on incompatible. Doesn't include
   // add-ons that were pending being disabled the last time the application ran.
   STARTUP_CHANGE_DISABLED: "disabled",
   // Add-ons that were detected as enabled during startup, normally because of
   // an application change making an add-on compatible. Doesn't include
   // add-ons that were pending being enabled the last time the application ran.
   STARTUP_CHANGE_ENABLED: "enabled",
 
-  // Constants for Addon.signedState. Any states that should cause an add-on
-  // to be unusable in builds that require signing should have negative values.
-  // Add-on is signed but signature verification has failed.
-  SIGNEDSTATE_BROKEN: -2,
-  // Add-on may be signed but by an certificate that doesn't chain to our
-  // our trusted certificate.
-  SIGNEDSTATE_UNKNOWN: -1,
-  // Add-on is unsigned.
-  SIGNEDSTATE_MISSING: 0,
-  // Add-on is preliminarily reviewed.
-  SIGNEDSTATE_PRELIMINARY: 1,
-  // Add-on is fully reviewed.
-  SIGNEDSTATE_SIGNED: 2,
-
   // Constants for the Addon.userDisabled property
   // Indicates that the userDisabled state of this add-on is currently
   // ask-to-activate. That is, it can be conditionally enabled on a
   // case-by-case basis.
   STATE_ASK_TO_ACTIVATE: "askToActivate",
 
 #ifdef MOZ_EM_DEBUG
   get __AddonManagerInternal__() {
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -73,19 +73,16 @@ const PREF_EM_ENABLED_ADDONS          = 
 const PREF_EM_EXTENSION_FORMAT        = "extensions.";
 const PREF_EM_ENABLED_SCOPES          = "extensions.enabledScopes";
 const PREF_EM_AUTO_DISABLED_SCOPES    = "extensions.autoDisableScopes";
 const PREF_EM_SHOW_MISMATCH_UI        = "extensions.showMismatchUI";
 const PREF_XPI_ENABLED                = "xpinstall.enabled";
 const PREF_XPI_WHITELIST_REQUIRED     = "xpinstall.whitelist.required";
 const PREF_XPI_DIRECT_WHITELISTED     = "xpinstall.whitelist.directRequest";
 const PREF_XPI_FILE_WHITELISTED       = "xpinstall.whitelist.fileRequest";
-// xpinstall.signatures.required only supported in dev builds
-const PREF_XPI_SIGNATURES_REQUIRED    = "xpinstall.signatures.required";
-const PREF_XPI_SIGNATURES_DEV_ROOT    = "xpinstall.signatures.dev-root";
 const PREF_XPI_PERMISSIONS_BRANCH     = "xpinstall.";
 const PREF_XPI_UNPACK                 = "extensions.alwaysUnpack";
 const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts";
 const PREF_INSTALL_REQUIRESECUREORIGIN = "extensions.install.requireSecureOrigin";
 const PREF_INSTALL_DISTRO_ADDONS      = "extensions.installDistroAddons";
 const PREF_BRANCH_INSTALLED_ADDON     = "extensions.installedDistroAddon.";
 const PREF_SHOWN_SELECTION_UI         = "extensions.shownSelectionUI";
 const PREF_INTERPOSITION_ENABLED      = "extensions.interposition.enabled";
@@ -98,16 +95,17 @@ const PREF_CHECKCOMAT_THEMEOVERRIDE   = 
 const URI_EXTENSION_SELECT_DIALOG     = "chrome://mozapps/content/extensions/selectAddons.xul";
 const URI_EXTENSION_UPDATE_DIALOG     = "chrome://mozapps/content/extensions/update.xul";
 const URI_EXTENSION_STRINGS           = "chrome://mozapps/locale/extensions/extensions.properties";
 
 const STRING_TYPE_NAME                = "type.%ID%.name";
 
 const DIR_EXTENSIONS                  = "extensions";
 const DIR_STAGE                       = "staged";
+const DIR_XPI_STAGE                   = "staged-xpis";
 const DIR_TRASH                       = "trash";
 
 const FILE_DATABASE                   = "extensions.json";
 const FILE_OLD_CACHE                  = "extensions.cache";
 const FILE_INSTALL_MANIFEST           = "install.rdf";
 const FILE_XPI_ADDONS_LIST            = "extensions.ini";
 
 const KEY_PROFILEDIR                  = "ProfD";
@@ -187,29 +185,16 @@ const TYPES = {
 };
 
 const RESTARTLESS_TYPES = new Set([
   "dictionary",
   "experiment",
   "locale",
 ]);
 
-const SIGNED_TYPES = new Set([
-  "extension",
-  "experiment",
-]);
-
-// Whether add-on signing is required.
-function mustSign(aType) {
-  if (!SIGNED_TYPES.has(aType))
-    return false;
-  return REQUIRE_SIGNING || Preferences.get(PREF_XPI_SIGNATURES_REQUIRED, false);
-}
-
-
 // Keep track of where we are in startup for telemetry
 // event happened during XPIDatabase.startup()
 const XPI_STARTING = "XPIStarting";
 // event happened after startup() but before the final-ui-startup event
 const XPI_BEFORE_UI_STARTUP = "BeforeFinalUIStartup";
 // event happened after final-ui-startup
 const XPI_AFTER_UI_STARTUP = "AfterFinalUIStartup";
 
@@ -640,19 +625,16 @@ function applyBlocklistChanges(aOldAddon
  *         The add-on to check
  * @return true if the add-on should not be appDisabled
  */
 function isUsableAddon(aAddon) {
   // Hack to ensure the default theme is always usable
   if (aAddon.type == "theme" && aAddon.internalName == XPIProvider.defaultSkin)
     return true;
 
-  if (mustSign(aAddon.type) && aAddon.signedState <= AddonManager.SIGNEDSTATE_MISSING)
-    return false;
-
   if (aAddon.blocklistState == Blocklist.STATE_BLOCKED)
     return false;
 
   if (AddonManager.checkUpdateSecurity && !aAddon.providesUpdatesSecurely)
     return false;
 
   if (!aAddon.isPlatformCompatible)
     return false;
@@ -1012,17 +994,17 @@ function loadManifestFromRDF(aUri, aStre
 /**
  * Loads an AddonInternal object from an add-on extracted in a directory.
  *
  * @param  aDir
  *         The nsIFile directory holding the add-on
  * @return an AddonInternal object
  * @throws if the directory does not contain a valid install manifest
  */
-let loadManifestFromDir = Task.async(function* loadManifestFromDir(aDir) {
+function loadManifestFromDir(aDir) {
   function getFileSize(aFile) {
     if (aFile.isSymlink())
       return 0;
 
     if (!aFile.isDirectory())
       return aFile.fileSize;
 
     let size = 0;
@@ -1053,39 +1035,34 @@ let loadManifestFromDir = Task.async(fun
     addon.size = getFileSize(aDir);
 
     file = aDir.clone();
     file.append("chrome.manifest");
     let chromeManifest = ChromeManifestParser.parseSync(Services.io.newFileURI(file));
     addon.hasBinaryComponents = ChromeManifestParser.hasType(chromeManifest,
                                                              "binary-component");
 
-    if (SIGNED_TYPES.has(addon.type))
-      addon.signedState = yield verifyDirSignedState(aDir, addon.id);
-    else
-      addon.signedState = AddonManager.SIGNEDSTATE_MISSING;
-
     addon.appDisabled = !isUsableAddon(addon);
     return addon;
   }
   finally {
     bis.close();
     fis.close();
   }
-});
+}
 
 /**
  * Loads an AddonInternal object from an nsIZipReader for an add-on.
  *
  * @param  aZipReader
  *         An open nsIZipReader for the add-on's files
  * @return an AddonInternal object
  * @throws if the XPI file does not contain a valid install manifest
  */
-let loadManifestFromZipReader = Task.async(function* loadManifestFromZipReader(aZipReader) {
+function loadManifestFromZipReader(aZipReader) {
   let zis = aZipReader.getInputStream(FILE_INSTALL_MANIFEST);
   let bis = Cc["@mozilla.org/network/buffered-input-stream;1"].
             createInstance(Ci.nsIBufferedInputStream);
   bis.init(zis, 4096);
 
   try {
     let uri = buildJarURI(aZipReader.file, FILE_INSTALL_MANIFEST);
     let addon = loadManifestFromRDF(uri, bis);
@@ -1101,89 +1078,54 @@ let loadManifestFromZipReader = Task.asy
       uri = buildJarURI(aZipReader.file, "chrome.manifest");
       let chromeManifest = ChromeManifestParser.parseSync(uri);
       addon.hasBinaryComponents = ChromeManifestParser.hasType(chromeManifest,
                                                                "binary-component");
     } else {
       addon.hasBinaryComponents = false;
     }
 
-    if (SIGNED_TYPES.has(addon.type))
-      addon.signedState = yield verifyZipSignedState(aZipReader.file, addon.id, addon.version);
-    else
-      addon.signedState = AddonManager.SIGNEDSTATE_MISSING;
-
     addon.appDisabled = !isUsableAddon(addon);
     return addon;
   }
   finally {
     bis.close();
     zis.close();
   }
-});
+}
 
 /**
  * Loads an AddonInternal object from an add-on in an XPI file.
  *
  * @param  aXPIFile
  *         An nsIFile pointing to the add-on's XPI file
  * @return an AddonInternal object
  * @throws if the XPI file does not contain a valid install manifest
  */
-let loadManifestFromZipFile = Task.async(function* loadManifestFromZipFile(aXPIFile) {
+function loadManifestFromZipFile(aXPIFile) {
   let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].
                   createInstance(Ci.nsIZipReader);
   try {
     zipReader.open(aXPIFile);
 
-    // Can't return this promise because that will make us close the zip reader
-    // before it has finished loading the manifest. Wait for the result and then
-    // return.
-    let manifest = yield loadManifestFromZipReader(zipReader);
-    return manifest;
+    return loadManifestFromZipReader(zipReader);
   }
   finally {
     zipReader.close();
   }
-});
+}
 
 function loadManifestFromFile(aFile) {
   if (aFile.isFile())
     return loadManifestFromZipFile(aFile);
   else
     return loadManifestFromDir(aFile);
 }
 
 /**
- * A synchronous method for loading an add-on's manifest. This should only ever
- * be used during startup or a sync load of the add-ons DB
- */
-function syncLoadManifestFromFile(aFile) {
-  let success = undefined;
-  let result = null;
-
-  loadManifestFromFile(aFile).then(val => {
-    success = true;
-    result = val;
-  }, val => {
-    success = false;
-    result = val
-  });
-
-  let thread = Services.tm.currentThread;
-
-  while (success === undefined)
-    thread.processNextEvent(true);
-
-  if (!success)
-    throw result;
-  return result;
-}
-
-/**
  * Gets an nsIURI for a file within another file, either a directory or an XPI
  * file. If aFile is a directory then this will return a file: URI, if it is an
  * XPI file then it will return a jar: URI.
  *
  * @param  aFile
  *         The file containing the resources, must be either a directory or an
  *         XPI file
  * @param  aPath
@@ -1280,91 +1222,16 @@ function verifyZipSigning(aZip, aCertifi
     if (!entryCertificate || !aCertificate.equals(entryCertificate)) {
       return false;
     }
   }
   return aZip.manifestEntriesCount == count;
 }
 
 /**
- * Returns the signedState for a given return code and certificate by verifying
- * it against the expected ID.
- */
-function getSignedStatus(aRv, aCert, aExpectedID) {
-  switch (aRv) {
-    case Cr.NS_OK:
-      if (aExpectedID != aCert.commonName)
-        return AddonManager.SIGNEDSTATE_BROKEN;
-
-      return /preliminary/i.test(aCert.organizationalUnit)
-               ? AddonManager.SIGNEDSTATE_PRELIMINARY
-               : AddonManager.SIGNEDSTATE_SIGNED;
-      break;
-    case Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED:
-      return AddonManager.SIGNEDSTATE_MISSING;
-      break;
-    case Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID:
-    case Cr.NS_ERROR_SIGNED_JAR_ENTRY_INVALID:
-    case Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING:
-    case Cr.NS_ERROR_SIGNED_JAR_ENTRY_TOO_LARGE:
-    case Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY:
-    case Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY:
-      return AddonManager.SIGNEDSTATE_BROKEN;
-      break;
-    default:
-      // Any other error indicates that either the add-on isn't signed or it
-      // is signed by a signature that doesn't chain to the trusted root.
-      return AddonManager.SIGNEDSTATE_UNKNOWN;
-      break;
-  }
-}
-
-/**
- * Verifies that a zip file's contents are all correctly signed by an
- * AMO-issued certificate
- *
- * @param  aFile
- *         the xpi file to check
- * @param  aExpectedID
- *         the expected ID of the signature
- * @return a Promise that resolves to an AddonManager.SIGNEDSTATE_* constant.
- */
-function verifyZipSignedState(aFile, aExpectedID, aVersion) {
-  let certDB = Cc["@mozilla.org/security/x509certdb;1"]
-               .getService(Ci.nsIX509CertDB);
-
-  let root = Ci.nsIX509CertDB.AddonsPublicRoot;
-  if (!REQUIRE_SIGNING && Preferences.get(PREF_XPI_SIGNATURES_DEV_ROOT, false))
-    root = Ci.nsIX509CertDB.AddonsStageRoot;
-
-  return new Promise(resolve => {
-    certDB.openSignedAppFileAsync(root, aFile, (aRv, aZipReader, aCert) => {
-      if (aZipReader)
-        aZipReader.close();
-      resolve(getSignedStatus(aRv, aCert, aExpectedID));
-    });
-  });
-}
-
-/**
- * Verifies that a directory's contents are all correctly signed by an
- * AMO-issued certificate
- *
- * @param  aDir
- *         the directory to check
- * @param  aExpectedID
- *         the expected ID of the signature
- * @return a Promise that resolves to an AddonManager.SIGNEDSTATE_* constant.
- */
-function verifyDirSignedState(aDir, aExpectedID) {
-  // TODO: Get the certificate for an unpacked add-on (bug 1038072)
-  return Promise.resolve(AddonManager.SIGNEDSTATE_MISSING);
-}
-
-/**
  * Replaces %...% strings in an addon url (update and updateInfo) with
  * appropriate values.
  *
  * @param  aAddon
  *         The AddonInternal representing the add-on
  * @param  aUri
  *         The uri to escape
  * @param  aUpdateType
@@ -2209,18 +2076,16 @@ this.XPIProvider = {
       this.minCompatibleAppVersion = Preferences.get(PREF_EM_MIN_COMPAT_APP_VERSION,
                                                      null);
       this.minCompatiblePlatformVersion = Preferences.get(PREF_EM_MIN_COMPAT_PLATFORM_VERSION,
                                                           null);
       this.enabledAddons = "";
 
       Services.prefs.addObserver(PREF_EM_MIN_COMPAT_APP_VERSION, this, false);
       Services.prefs.addObserver(PREF_EM_MIN_COMPAT_PLATFORM_VERSION, this, false);
-      if (!REQUIRE_SIGNING)
-        Services.prefs.addObserver(PREF_XPI_SIGNATURES_REQUIRED, this, false);
       Services.obs.addObserver(this, NOTIFICATION_FLUSH_PERMISSIONS, false);
       if (Cu.isModuleLoaded("resource:///modules/devtools/ToolboxProcess.jsm")) {
         // If BrowserToolboxProcess is already loaded, set the boolean to true
         // and do whatever is needed
         this._toolboxProcessLoaded = true;
         BrowserToolboxProcess.on("connectionchange",
                                  this.onDebugConnectionChange.bind(this));
       }
@@ -2554,18 +2419,105 @@ this.XPIProvider = {
   processPendingFileChanges: function XPI_processPendingFileChanges(aManifests) {
     let changed = false;
     this.installLocations.forEach(function(aLocation) {
       aManifests[aLocation.name] = {};
       // We can't install or uninstall anything in locked locations
       if (aLocation.locked)
         return;
 
+      let stagedXPIDir = aLocation.getXPIStagingDir();
       let stagingDir = aLocation.getStagingDir();
 
+      if (stagedXPIDir.exists() && stagedXPIDir.isDirectory()) {
+        let entries = stagedXPIDir.directoryEntries
+                                  .QueryInterface(Ci.nsIDirectoryEnumerator);
+        while (entries.hasMoreElements()) {
+          let stageDirEntry = entries.nextFile;
+
+          if (!stageDirEntry.isDirectory()) {
+            logger.warn("Ignoring file in XPI staging directory: " + stageDirEntry.path);
+            continue;
+          }
+
+          // Find the last added XPI file in the directory
+          let stagedXPI = null;
+          var xpiEntries = stageDirEntry.directoryEntries
+                                        .QueryInterface(Ci.nsIDirectoryEnumerator);
+          while (xpiEntries.hasMoreElements()) {
+            let file = xpiEntries.nextFile;
+            if (file.isDirectory())
+              continue;
+
+            let extension = file.leafName;
+            extension = extension.substring(extension.length - 4);
+
+            if (extension != ".xpi" && extension != ".jar")
+              continue;
+
+            stagedXPI = file;
+          }
+          xpiEntries.close();
+
+          if (!stagedXPI)
+            continue;
+
+          let addon = null;
+          try {
+            addon = loadManifestFromZipFile(stagedXPI);
+          }
+          catch (e) {
+            logger.error("Unable to read add-on manifest from " + stagedXPI.path, e);
+            continue;
+          }
+
+          logger.debug("Migrating staged install of " + addon.id + " in " + aLocation.name);
+
+          if (addon.unpack || Preferences.get(PREF_XPI_UNPACK, false)) {
+            let targetDir = stagingDir.clone();
+            targetDir.append(addon.id);
+            try {
+              targetDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
+            }
+            catch (e) {
+              logger.error("Failed to create staging directory for add-on " + addon.id, e);
+              continue;
+            }
+
+            try {
+              ZipUtils.extractFiles(stagedXPI, targetDir);
+            }
+            catch (e) {
+              logger.error("Failed to extract staged XPI for add-on " + addon.id + " in " +
+                    aLocation.name, e);
+            }
+          }
+          else {
+            try {
+              stagedXPI.moveTo(stagingDir, addon.id + ".xpi");
+            }
+            catch (e) {
+              logger.error("Failed to move staged XPI for add-on " + addon.id + " in " +
+                    aLocation.name, e);
+            }
+          }
+        }
+        entries.close();
+      }
+
+      if (stagedXPIDir.exists()) {
+        try {
+          recursiveRemove(stagedXPIDir);
+        }
+        catch (e) {
+          // Non-critical, just saves some perf on startup if we clean this up.
+          logger.debug("Error removing XPI staging dir " + stagedXPIDir.path, e);
+        }
+      }
+
       try {
         if (!stagingDir || !stagingDir.exists() || !stagingDir.isDirectory())
           return;
       }
       catch (e) {
         logger.warn("Failed to find staging directory", e);
         return;
       }
@@ -2636,75 +2588,66 @@ this.XPIProvider = {
 
         aManifests[aLocation.name][id] = null;
         let existingAddonID = id;
 
         let jsonfile = stagingDir.clone();
         jsonfile.append(id + ".json");
 
         try {
-          aManifests[aLocation.name][id] = syncLoadManifestFromFile(stageDirEntry);
+          aManifests[aLocation.name][id] = loadManifestFromFile(stageDirEntry);
         }
         catch (e) {
           logger.error("Unable to read add-on manifest from " + stageDirEntry.path, e);
           // This add-on can't be installed so just remove it now
           seenFiles.push(stageDirEntry.leafName);
           seenFiles.push(jsonfile.leafName);
           continue;
         }
 
-        let addon = aManifests[aLocation.name][id];
-
-        if ((addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) && mustSign(addon.type)) {
-          logger.warn("Refusing to install staged add-on " + id + " with signed state " + addon.signedState);
-          seenFiles.push(stageDirEntry.leafName);
-          seenFiles.push(jsonfile.leafName);
-          continue;
-        }
-
         // Check for a cached metadata for this add-on, it may contain updated
         // compatibility information
         if (jsonfile.exists()) {
           logger.debug("Found updated metadata for " + id + " in " + aLocation.name);
           let fis = Cc["@mozilla.org/network/file-input-stream;1"].
                        createInstance(Ci.nsIFileInputStream);
           let json = Cc["@mozilla.org/dom/json;1"].
                      createInstance(Ci.nsIJSON);
 
           try {
             fis.init(jsonfile, -1, 0, 0);
             let metadata = json.decodeFromStream(fis, jsonfile.fileSize);
-            addon.importMetadata(metadata);
+            aManifests[aLocation.name][id].importMetadata(metadata);
           }
           catch (e) {
             // If some data can't be recovered from the cached metadata then it
             // is unlikely to be a problem big enough to justify throwing away
             // the install, just log and error and continue
             logger.error("Unable to read metadata from " + jsonfile.path, e);
           }
           finally {
             fis.close();
           }
         }
         seenFiles.push(jsonfile.leafName);
 
-        existingAddonID = addon.existingAddonID || id;
+        existingAddonID = aManifests[aLocation.name][id].existingAddonID || id;
 
         var oldBootstrap = null;
         logger.debug("Processing install of " + id + " in " + aLocation.name);
         if (existingAddonID in this.bootstrappedAddons) {
           try {
             var existingAddon = aLocation.getLocationForID(existingAddonID);
             if (this.bootstrappedAddons[existingAddonID].descriptor ==
                 existingAddon.persistentDescriptor) {
               oldBootstrap = this.bootstrappedAddons[existingAddonID];
 
               // We'll be replacing a currently active bootstrapped add-on so
               // call its uninstall method
-              let newVersion = addon.version;
+              let newVersion = aManifests[aLocation.name][id].version;
               let oldVersion = oldBootstrap.version;
               let uninstallReason = Services.vc.compare(oldVersion, newVersion) < 0 ?
                                     BOOTSTRAP_REASONS.ADDON_UPGRADE :
                                     BOOTSTRAP_REASONS.ADDON_DOWNGRADE;
 
               this.callBootstrapMethod(createAddonDetails(existingAddonID, oldBootstrap),
                                        existingAddon, "uninstall", uninstallReason,
                                        { newVersion: newVersion });
@@ -2712,25 +2655,27 @@ this.XPIProvider = {
               flushStartupCache();
             }
           }
           catch (e) {
           }
         }
 
         try {
-          addon._sourceBundle = aLocation.installAddon(id, stageDirEntry,
-                                                       existingAddonID);
+          var addonInstallLocation = aLocation.installAddon(id, stageDirEntry,
+                                                            existingAddonID);
+          if (aManifests[aLocation.name][id])
+            aManifests[aLocation.name][id]._sourceBundle = addonInstallLocation;
         }
         catch (e) {
           logger.error("Failed to install staged add-on " + id + " in " + aLocation.name,
                 e);
           // Re-create the staged install
           AddonInstall.createStagedInstall(aLocation, stageDirEntry,
-                                           addon);
+                                           aManifests[aLocation.name][id]);
           // Make sure not to delete the cached manifest json file
           seenFiles.pop();
 
           delete aManifests[aLocation.name][id];
 
           if (oldBootstrap) {
             // Re-install the old add-on
             this.callBootstrapMethod(createAddonDetails(existingAddonID, oldBootstrap),
@@ -2806,17 +2751,17 @@ this.XPIProvider = {
       if (!gIDTest.test(id)) {
         logger.debug("Ignoring distribution add-on whose name is not a valid add-on ID: " +
             entry.path);
         continue;
       }
 
       let addon;
       try {
-        addon = syncLoadManifestFromFile(entry);
+        addon = loadManifestFromFile(entry);
       }
       catch (e) {
         logger.warn("File entry " + entry.path + " contains an invalid add-on", e);
         continue;
       }
 
       if (addon.id != id) {
         logger.warn("File entry " + entry.path + " contains an add-on with an " +
@@ -2829,17 +2774,17 @@ this.XPIProvider = {
         existingEntry = profileLocation.getLocationForID(id);
       }
       catch (e) {
       }
 
       if (existingEntry) {
         let existingAddon;
         try {
-          existingAddon = syncLoadManifestFromFile(existingEntry);
+          existingAddon = loadManifestFromFile(existingEntry);
 
           if (Services.vc.compare(addon.version, existingAddon.version) <= 0)
             continue;
         }
         catch (e) {
           // Bad add-on in the profile so just proceed and install over the top
           logger.warn("Profile contains an add-on with a bad or missing install " +
                "manifest at " + existingEntry.path + ", overwriting", e);
@@ -2924,17 +2869,17 @@ this.XPIProvider = {
 
       // Check if there is an updated install manifest for this add-on
       let newAddon = aManifests[aInstallLocation.name][aOldAddon.id];
 
       try {
         // If not load it
         if (!newAddon) {
           let file = aInstallLocation.getLocationForID(aOldAddon.id);
-          newAddon = syncLoadManifestFromFile(file);
+          newAddon = loadManifestFromFile(file);
           applyBlocklistChanges(aOldAddon, newAddon);
 
           // Carry over any pendingUninstall state to add-ons modified directly
           // in the profile. This is important when the attempt to remove the
           // add-on in processPendingFileChanges failed and caused an mtime
           // change to the add-ons files.
           newAddon.pendingUninstall = aOldAddon.pendingUninstall;
         }
@@ -2967,21 +2912,16 @@ this.XPIProvider = {
       // Update the database
       let newDBAddon = XPIDatabase.updateAddonMetadata(aOldAddon, newAddon,
                                                        aAddonState.descriptor);
       if (newDBAddon.visible) {
         visibleAddons[newDBAddon.id] = newDBAddon;
         // Remember add-ons that were changed during startup
         AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED,
                                              newDBAddon.id);
-        if (aOldAddon.active == newDBAddon.disabled) {
-          let change = aOldAddon.active ? AddonManager.STARTUP_CHANGE_DISABLED
-                                        : AddonManager.STARTUP_CHANGE_ENABLED;
-          AddonManagerPrivate.addStartupChange(change, newDBAddon.id);
-        }
 
         // If this was the active theme and it is now disabled then enable the
         // default theme
         if (aOldAddon.active && newDBAddon.disabled)
           XPIProvider.enableDefaultTheme();
 
         // If the new add-on is bootstrapped and active then call its install method
         if (newDBAddon.active && newDBAddon.bootstrap) {
@@ -3096,35 +3036,26 @@ this.XPIProvider = {
       }
 
       // App version changed, we may need to update the appDisabled property.
       if (aUpdateCompatibility) {
         let wasDisabled = aOldAddon.disabled;
         let wasAppDisabled = aOldAddon.appDisabled;
         let wasUserDisabled = aOldAddon.userDisabled;
         let wasSoftDisabled = aOldAddon.softDisabled;
-        let updateDB = false;
-
-        // If updating from a version of the app that didn't support signedState
-        // then fetch that property now
-        if (aOldAddon.signedState === undefined) {
-          let file = aInstallLocation.getLocationForID(aOldAddon.id);
-          let manifest = syncLoadManifestFromFile(file);
-          aOldAddon.signedState = manifest.signedState;
-          updateDB = true;
-        }
+
         // This updates the addon's JSON cached data in place
         applyBlocklistChanges(aOldAddon, aOldAddon, aOldAppVersion,
                               aOldPlatformVersion);
         aOldAddon.appDisabled = !isUsableAddon(aOldAddon);
 
         let isDisabled = aOldAddon.disabled;
 
         // If either property has changed update the database.
-        if (updateDB || wasAppDisabled != aOldAddon.appDisabled ||
+        if (wasAppDisabled != aOldAddon.appDisabled ||
             wasUserDisabled != aOldAddon.userDisabled ||
             wasSoftDisabled != aOldAddon.softDisabled) {
           logger.debug("Add-on " + aOldAddon.id + " changed appDisabled state to " +
               aOldAddon.appDisabled + ", userDisabled state to " +
               aOldAddon.userDisabled + " and softDisabled state to " +
               aOldAddon.softDisabled);
           XPIDatabase.saveChanges();
         }
@@ -3235,17 +3166,17 @@ this.XPIProvider = {
       // must be something dropped directly into the install location
       let isDetectedInstall = isNewInstall && !newAddon;
 
       // Load the manifest if necessary and sanity check the add-on ID
       try {
         if (!newAddon) {
           // Load the manifest from the add-on.
           let file = aInstallLocation.getLocationForID(aId);
-          newAddon = syncLoadManifestFromFile(file);
+          newAddon = loadManifestFromFile(file);
         }
         // The add-on in the manifest should match the add-on ID.
         if (newAddon.id != aId) {
           throw new Error("Invalid addon ID: expected addon ID " + aId +
                           ", found " + newAddon.id + " in manifest");
         }
       }
       catch (e) {
@@ -4158,28 +4089,23 @@ this.XPIProvider = {
       this._toolboxProcessLoaded = true;
       BrowserToolboxProcess.on("connectionchange",
                                this.onDebugConnectionChange.bind(this));
     }
 
     if (aTopic == "nsPref:changed") {
       switch (aData) {
       case PREF_EM_MIN_COMPAT_APP_VERSION:
+      case PREF_EM_MIN_COMPAT_PLATFORM_VERSION:
         this.minCompatibleAppVersion = Preferences.get(PREF_EM_MIN_COMPAT_APP_VERSION,
                                                        null);
-        this.updateAddonAppDisabledStates();
-        break;
-      case PREF_EM_MIN_COMPAT_PLATFORM_VERSION:
         this.minCompatiblePlatformVersion = Preferences.get(PREF_EM_MIN_COMPAT_PLATFORM_VERSION,
                                                             null);
         this.updateAddonAppDisabledStates();
         break;
-      case PREF_XPI_SIGNATURES_REQUIRED:
-        this.updateAddonAppDisabledStates();
-        break;
       }
     }
   },
 
   /**
    * Tests whether enabling an add-on will require a restart.
    *
    * @param  aAddon
@@ -4983,55 +4909,59 @@ AddonInstall.prototype = {
              this.hash.data + ")");
         this.state = AddonManager.STATE_DOWNLOAD_FAILED;
         this.error = AddonManager.ERROR_INCORRECT_HASH;
         aCallback(this);
         return;
       }
     }
 
-    let self = this;
-    this.loadManifest().then(() => {
-      XPIDatabase.getVisibleAddonForID(self.addon.id, function initLocalInstall_getVisibleAddon(aAddon) {
-        self.existingAddon = aAddon;
-        if (aAddon)
-          applyBlocklistChanges(aAddon, self.addon);
-        self.addon.updateDate = Date.now();
-        self.addon.installDate = aAddon ? aAddon.installDate : self.addon.updateDate;
-
-        if (!self.addon.isCompatible) {
-          // TODO Should we send some event here?
-          self.state = AddonManager.STATE_CHECKING;
-          new UpdateChecker(self.addon, {
-            onUpdateFinished: function updateChecker_onUpdateFinished(aAddon) {
-              self.state = AddonManager.STATE_DOWNLOADED;
-              XPIProvider.installs.push(self);
-              AddonManagerPrivate.callInstallListeners("onNewInstall",
-                                                       self.listeners,
-                                                       self.wrapper);
-
-              aCallback(self);
-            }
-          }, AddonManager.UPDATE_WHEN_ADDON_INSTALLED);
-        }
-        else {
-          XPIProvider.installs.push(self);
-          AddonManagerPrivate.callInstallListeners("onNewInstall",
-                                                   self.listeners,
-                                                   self.wrapper);
-
-          aCallback(self);
-        }
+    try {
+      let self = this;
+      this.loadManifest(function  initLocalInstall_loadManifest() {
+        XPIDatabase.getVisibleAddonForID(self.addon.id, function initLocalInstall_getVisibleAddon(aAddon) {
+          self.existingAddon = aAddon;
+          if (aAddon)
+            applyBlocklistChanges(aAddon, self.addon);
+          self.addon.updateDate = Date.now();
+          self.addon.installDate = aAddon ? aAddon.installDate : self.addon.updateDate;
+
+          if (!self.addon.isCompatible) {
+            // TODO Should we send some event here?
+            self.state = AddonManager.STATE_CHECKING;
+            new UpdateChecker(self.addon, {
+              onUpdateFinished: function updateChecker_onUpdateFinished(aAddon) {
+                self.state = AddonManager.STATE_DOWNLOADED;
+                XPIProvider.installs.push(self);
+                AddonManagerPrivate.callInstallListeners("onNewInstall",
+                                                         self.listeners,
+                                                         self.wrapper);
+
+                aCallback(self);
+              }
+            }, AddonManager.UPDATE_WHEN_ADDON_INSTALLED);
+          }
+          else {
+            XPIProvider.installs.push(self);
+            AddonManagerPrivate.callInstallListeners("onNewInstall",
+                                                     self.listeners,
+                                                     self.wrapper);
+
+            aCallback(self);
+          }
+        });
       });
-    }, ([error, message]) => {
-      logger.warn("Invalid XPI", message);
+    }
+    catch (e) {
+      logger.warn("Invalid XPI", e);
       this.state = AddonManager.STATE_DOWNLOAD_FAILED;
-      this.error = error;
+      this.error = AddonManager.ERROR_CORRUPT_FILE;
       aCallback(this);
-    });
+      return;
+    }
   },
 
   /**
    * Initialises this install to be a download from a remote url.
    *
    * @param  aCallback
    *         The callback to pass the initialised AddonInstall to
    * @param  aName
@@ -5210,17 +5140,18 @@ AddonInstall.prototype = {
    * @param  aZipReader
    *         An open nsIZipReader for the multi-package XPI's files. This will
    *         be closed before this method returns.
    * @param  aCallback
    *         A function to call when all of the add-on manifests have been
    *         loaded. Because this loadMultipackageManifests is an internal API
    *         we don't exception-wrap this callback
    */
-  _loadMultipackageManifests: Task.async(function* AI_loadMultipackageManifests(aZipReader) {
+  _loadMultipackageManifests: function AI_loadMultipackageManifests(aZipReader,
+                                                                   aCallback) {
     let files = [];
     let entries = aZipReader.findEntries("(*.[Xx][Pp][Ii]|*.[Jj][Aa][Rr])");
     while (entries.hasMore()) {
       let entryName = entries.getNext();
       var target = getTemporaryFile();
       try {
         aZipReader.extract(entryName, target);
         files.push(target);
@@ -5243,27 +5174,28 @@ AddonInstall.prototype = {
 
     // Find the first file that has a valid install manifest and use it for
     // the add-on that this AddonInstall instance will install.
     while (files.length > 0) {
       this.removeTemporaryFile();
       this.file = files.shift();
       this.ownsTempFile = true;
       try {
-        addon = yield loadManifestFromZipFile(this.file);
+        addon = loadManifestFromZipFile(this.file);
         break;
       }
       catch (e) {
         logger.warn(this.file.leafName + " cannot be installed from multi-package " +
              "XPI", e);
       }
     }
 
     if (!addon) {
       // No valid add-on was found
+      aCallback();
       return;
     }
 
     this.addon = addon;
 
     this.updateAddonURIs();
 
     this.addon._install = this;
@@ -5275,138 +5207,144 @@ AddonInstall.prototype = {
     // makes it impossible to delete on Windows.
     //let newIcon = createWrapper(this.addon).iconURL;
     //if (newIcon)
     //  this.iconURL = newIcon;
 
     // Create new AddonInstall instances for every remaining file
     if (files.length > 0) {
       this.linkedInstalls = [];
+      let count = 0;
       let self = this;
-      for (let file of files) {
-        let install = yield new Promise(resolve => AddonInstall.createInstall(resolve, file));
-
-        // Ignore bad add-ons (createInstall will have logged the error)
-        if (install.state == AddonManager.STATE_DOWNLOAD_FAILED) {
-          // Manually remove the temporary file
-          file.remove(true);
-        }
-        else {
-          // Make the new install own its temporary file
-          install.ownsTempFile = true;
-
-          self.linkedInstalls.push(install)
-
-          install.sourceURI = self.sourceURI;
-          install.releaseNotesURI = self.releaseNotesURI;
-          install.updateAddonURIs();
-        }
-      }
-    }
-  }),
+      files.forEach(function(file) {
+        AddonInstall.createInstall(function loadMultipackageManifests_createInstall(aInstall) {
+          // Ignore bad add-ons (createInstall will have logged the error)
+          if (aInstall.state == AddonManager.STATE_DOWNLOAD_FAILED) {
+            // Manually remove the temporary file
+            file.remove(true);
+          }
+          else {
+            // Make the new install own its temporary file
+            aInstall.ownsTempFile = true;
+
+            self.linkedInstalls.push(aInstall)
+
+            aInstall.sourceURI = self.sourceURI;
+            aInstall.releaseNotesURI = self.releaseNotesURI;
+            aInstall.updateAddonURIs();
+          }
+
+          count++;
+          if (count == files.length)
+            aCallback();
+        }, file);
+      }, this);
+    }
+    else {
+      aCallback();
+    }
+  },
 
   /**
    * Called after the add-on is a local file and the signature and install
    * manifest can be read.
    *
    * @param  aCallback
    *         A function to call when the manifest has been loaded
    * @throws if the add-on does not contain a valid install manifest or the
    *         XPI is incorrectly signed
    */
-  loadManifest: Task.async(function* AI_loadManifest() {
+  loadManifest: function AI_loadManifest(aCallback) {
+    aCallback = makeSafe(aCallback);
+    let self = this;
+    function addRepositoryData(aAddon) {
+      // Try to load from the existing cache first
+      AddonRepository.getCachedAddonByID(aAddon.id, function loadManifest_getCachedAddonByID(aRepoAddon) {
+        if (aRepoAddon) {
+          aAddon._repositoryAddon = aRepoAddon;
+          self.name = self.name || aAddon._repositoryAddon.name;
+          aAddon.compatibilityOverrides = aRepoAddon.compatibilityOverrides;
+          aAddon.appDisabled = !isUsableAddon(aAddon);
+          aCallback();
+          return;
+        }
+
+        // It wasn't there so try to re-download it
+        AddonRepository.cacheAddons([aAddon.id], function loadManifest_cacheAddons() {
+          AddonRepository.getCachedAddonByID(aAddon.id, function loadManifest_getCachedAddonByID(aRepoAddon) {
+            aAddon._repositoryAddon = aRepoAddon;
+            self.name = self.name || aAddon._repositoryAddon.name;
+            aAddon.compatibilityOverrides = aRepoAddon ?
+                                              aRepoAddon.compatibilityOverrides :
+                                              null;
+            aAddon.appDisabled = !isUsableAddon(aAddon);
+            aCallback();
+          });
+        });
+      });
+    }
+
     let zipreader = Cc["@mozilla.org/libjar/zip-reader;1"].
                     createInstance(Ci.nsIZipReader);
     try {
       zipreader.open(this.file);
     }
     catch (e) {
       zipreader.close();
-      return Promise.reject([AddonManager.ERROR_CORRUPT_FILE, e]);
+      throw e;
+    }
+
+    let x509 = zipreader.getSigningCert(null);
+    if (x509) {
+      logger.debug("Verifying XPI signature");
+      if (verifyZipSigning(zipreader, x509)) {
+        this.certificate = x509;
+        if (this.certificate.commonName.length > 0) {
+          this.certName = this.certificate.commonName;
+        } else {
+          this.certName = this.certificate.organization;
+        }
+      } else {
+        zipreader.close();
+        throw new Error("XPI is incorrectly signed");
+      }
     }
 
     try {
-      // loadManifestFromZipReader performs the certificate verification for us
-      this.addon = yield loadManifestFromZipReader(zipreader);
+      this.addon = loadManifestFromZipReader(zipreader);
     }
     catch (e) {
       zipreader.close();
-      return Promise.reject([AddonManager.ERROR_CORRUPT_FILE, e]);
-    }
-
-    if (mustSign(this.addon.type)) {
-      if (this.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) {
-        // This add-on isn't properly signed by a signature that chains to the
-        // trusted root.
-        let state = this.addon.signedState;
-        this.addon = null;
-        zipreader.close();
-
-        if (state == AddonManager.SIGNEDSTATE_MISSING)
-          return Promise.reject([AddonManager.ERROR_SIGNEDSTATE_REQUIRED,
-                                 "signature is required but missing"])
-
-        return Promise.reject([AddonManager.ERROR_CORRUPT_FILE,
-                               "signature verification failed"])
-      }
-    }
-    else if (this.addon.signedState == AddonManager.SIGNEDSTATE_UNKNOWN) {
-      // Check object signing certificate, if any
-      let x509 = zipreader.getSigningCert(null);
-      if (x509) {
-        logger.debug("Verifying XPI signature");
-        if (verifyZipSigning(zipreader, x509)) {
-          this.certificate = x509;
-          if (this.certificate.commonName.length > 0) {
-            this.certName = this.certificate.commonName;
-          } else {
-            this.certName = this.certificate.organization;
-          }
-        } else {
-          zipreader.close();
-          return Promise.reject([AddonManager.ERROR_CORRUPT_FILE,
-                                 "XPI is incorrectly signed"]);
-        }
-      }
-    }
-
-    if (this.addon.type == "multipackage")
-      return this._loadMultipackageManifests(zipreader);
+      throw e;
+    }
+
+    if (this.addon.type == "multipackage") {
+      this._loadMultipackageManifests(zipreader, function loadManifest_loadMultipackageManifests() {
+        addRepositoryData(self.addon);
+      });
+      return;
+    }
 
     zipreader.close();
 
     this.updateAddonURIs();
 
     this.addon._install = this;
     this.name = this.addon.selectedLocale.name;
     this.type = this.addon.type;
     this.version = this.addon.version;
 
     // Setting the iconURL to something inside the XPI locks the XPI and
     // makes it impossible to delete on Windows.
     //let newIcon = createWrapper(this.addon).iconURL;
     //if (newIcon)
     //  this.iconURL = newIcon;
 
-    // Try to load from the existing cache first
-    let repoAddon = yield new Promise(resolve => AddonRepository.getCachedAddonByID(this.addon.id, resolve));
-
-    // It wasn't there so try to re-download it
-    if (!repoAddon) {
-      yield new Promise(resolve => AddonRepository.cacheAddons([this.addon.id], resolve));
-      repoAddon = yield new Promise(resolve => AddonRepository.getCachedAddonByID(this.addon.id, resolve));
-    }
-
-    this.addon._repositoryAddon = repoAddon;
-    this.name = this.name || this.addon._repositoryAddon.name;
-    this.addon.compatibilityOverrides = repoAddon ?
-                                    repoAddon.compatibilityOverrides :
-                                    null;
-    this.addon.appDisabled = !isUsableAddon(this.addon);
-  }),
+    addRepositoryData(this.addon);
+  },
 
   observe: function AI_observe(aSubject, aTopic, aData) {
     // Network is going offline
     this.cancel();
   },
 
   /**
    * Starts downloading the add-on's XPI file.
@@ -5632,34 +5570,36 @@ AddonInstall.prototype = {
         let calculatedHash = getHashStringForCrypto(this.crypto);
         this.crypto = null;
         if (this.hash && calculatedHash != this.hash.data) {
           this.downloadFailed(AddonManager.ERROR_INCORRECT_HASH,
                               "Downloaded file hash (" + calculatedHash +
                               ") did not match provided hash (" + this.hash.data + ")");
           return;
         }
-
-        let self = this;
-        this.loadManifest().then(() => {
-          if (self.addon.isCompatible) {
-            self.downloadCompleted();
-          }
-          else {
-            // TODO Should we send some event here (bug 557716)?
-            self.state = AddonManager.STATE_CHECKING;
-            new UpdateChecker(self.addon, {
-              onUpdateFinished: function onStopRequest_onUpdateFinished(aAddon) {
-                self.downloadCompleted();
-              }
-            }, AddonManager.UPDATE_WHEN_ADDON_INSTALLED);
-          }
-        }, ([error, message]) => {
-          this.downloadFailed(error, message);
-        });
+        try {
+          let self = this;
+          this.loadManifest(function onStopRequest_loadManifest() {
+            if (self.addon.isCompatible) {
+              self.downloadCompleted();
+            }
+            else {
+              // TODO Should we send some event here (bug 557716)?
+              self.state = AddonManager.STATE_CHECKING;
+              new UpdateChecker(self.addon, {
+                onUpdateFinished: function onStopRequest_onUpdateFinished(aAddon) {
+                  self.downloadCompleted();
+                }
+              }, AddonManager.UPDATE_WHEN_ADDON_INSTALLED);
+            }
+          });
+        }
+        catch (e) {
+          this.downloadFailed(AddonManager.ERROR_CORRUPT_FILE, e);
+        }
       }
       else {
         if (aRequest instanceof Ci.nsIHttpChannel)
           this.downloadFailed(AddonManager.ERROR_NETWORK_FAILURE,
                               aRequest.responseStatus + " " +
                               aRequest.responseStatusText);
         else
           this.downloadFailed(AddonManager.ERROR_NETWORK_FAILURE, aStatus);
@@ -6674,17 +6614,17 @@ function AddonWrapper(aAddon) {
 
     return [objValue, false];
   }
 
   ["id", "syncGUID", "version", "type", "isCompatible", "isPlatformCompatible",
    "providesUpdatesSecurely", "blocklistState", "blocklistURL", "appDisabled",
    "softDisabled", "skinnable", "size", "foreignInstall", "hasBinaryComponents",
    "strictCompatibility", "compatibilityOverrides", "updateURL",
-   "getDataDirectory", "multiprocessCompatible", "signedState"].forEach(function(aProp) {
+   "getDataDirectory", "multiprocessCompatible"].forEach(function(aProp) {
      this.__defineGetter__(aProp, function AddonWrapper_propertyGetter() aAddon[aProp]);
   }, this);
 
   ["fullDescription", "developerComments", "eula", "supportURL",
    "contributionURL", "contributionAmount", "averageRating", "reviewCount",
    "reviewURL", "totalDownloads", "weeklyDownloads", "dailyUsers",
    "repositoryStatus"].forEach(function(aProp) {
     this.__defineGetter__(aProp, function AddonWrapper_repoPropertyGetter() {
@@ -7246,17 +7186,17 @@ DirectoryInstallLocation.prototype = {
   _readAddons: function DirInstallLocation__readAddons() {
     // Use a snapshot of the directory contents to avoid possible issues with
     // iterating over a directory while removing files from it (the YAFFS2
     // embedded filesystem has this issue, see bug 772238).
     let entries = getDirectoryEntries(this._directory);
     for (let entry of entries) {
       let id = entry.leafName;
 
-      if (id == DIR_STAGE || id == DIR_TRASH)
+      if (id == DIR_STAGE || id == DIR_XPI_STAGE || id == DIR_TRASH)
         continue;
 
       let directLoad = false;
       if (entry.isFile() &&
           id.substring(id.length - 4).toLowerCase() == ".xpi") {
         directLoad = true;
         id = id.substring(0, id.length - 4);
       }
@@ -7390,16 +7330,28 @@ DirectoryInstallLocation.prototype = {
     }
     catch (e) {
       logger.warn("Failed to remove staging dir", e);
       // Failing to remove the staging directory is ignorable
     }
   },
 
   /**
+   * Gets the directory used by old versions for staging XPI and JAR files ready
+   * to be installed.
+   *
+   * @return an nsIFile
+   */
+  getXPIStagingDir: function DirInstallLocation_getXPIStagingDir() {
+    let dir = this._directory.clone();
+    dir.append(DIR_XPI_STAGE);
+    return dir;
+  },
+
+  /**
    * Returns a directory that is normally on the same filesystem as the rest of
    * the install location and can be used for temporarily storing files during
    * safe move operations. Calling this method will delete the existing trash
    * directory and its contents.
    *
    * @return an nsIFile
    */
   getTrashDir: function DirInstallLocation_getTrashDir() {
@@ -7765,29 +7717,16 @@ WinRegInstallLocation.prototype = {
    * @see DirectoryInstallLocation
    */
   isLinkedAddon: function RegInstallLocation_isLinkedAddon(aId) {
     return true;
   }
 };
 #endif
 
-// Make this a non-changable property so it can't be manipulated from other
-// code in the app.
-Object.defineProperty(this, "REQUIRE_SIGNING", {
-  configurable: false,
-  enumerable: false,
-  writable: false,
-#ifdef MOZ_REQUIRE_SIGNING
-  value: true,
-#else
-  value: false,
-#endif
-});
-
 let addonTypes = [
   new AddonManagerPrivate.AddonType("extension", URI_EXTENSION_STRINGS,
                                     STRING_TYPE_NAME,
                                     AddonManager.VIEW_TYPE_LIST, 4000),
   new AddonManagerPrivate.AddonType("theme", URI_EXTENSION_STRINGS,
                                     STRING_TYPE_NAME,
                                     AddonManager.VIEW_TYPE_LIST, 5000),
   new AddonManagerPrivate.AddonType("dictionary", URI_EXTENSION_STRINGS,
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -65,17 +65,17 @@ const PROP_JSON_FIELDS = ["id", "syncGUI
                           "internalName", "updateURL", "updateKey", "optionsURL",
                           "optionsType", "aboutURL", "iconURL", "icon64URL",
                           "defaultLocale", "visible", "active", "userDisabled",
                           "appDisabled", "pendingUninstall", "descriptor", "installDate",
                           "updateDate", "applyBackgroundUpdates", "bootstrap",
                           "skinnable", "size", "sourceURI", "releaseNotesURI",
                           "softDisabled", "foreignInstall", "hasBinaryComponents",
                           "strictCompatibility", "locales", "targetApplications",
-                          "targetPlatforms", "multiprocessCompatible", "signedState"];
+                          "targetPlatforms", "multiprocessCompatible"];
 
 // Time to wait before async save of XPI JSON database, in milliseconds
 const ASYNC_SAVE_DELAY_MS = 20;
 
 const PREFIX_ITEM_URI                 = "urn:mozilla:item:";
 const RDFURI_ITEM_ROOT                = "urn:mozilla:item:root"
 const PREFIX_NS_EM                    = "http://www.mozilla.org/2004/em-rdf#";
 
--- a/toolkit/mozapps/extensions/internal/moz.build
+++ b/toolkit/mozapps/extensions/internal/moz.build
@@ -23,13 +23,13 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'andr
 
 EXTRA_PP_JS_MODULES.addons += [
     'XPIProvider.jsm',
     'XPIProviderUtils.js',
 ]
 
 # This is used in multiple places, so is defined here to avoid it getting
 # out of sync.
-DEFINES['MOZ_EXTENSIONS_DB_SCHEMA'] = 17
+DEFINES['MOZ_EXTENSIONS_DB_SCHEMA'] = 16
 
 # Additional debugging info is exposed in debug builds
 if CONFIG['MOZ_EM_DEBUG']:
     DEFINES['MOZ_EM_DEBUG'] = 1
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_1/bootstrap.js
+++ /dev/null
@@ -1,29 +0,0 @@
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-const VERSION = 1;
-
-// Test steps chain from pref observers on *_reason,
-// so always set that last
-function install(data, reason) {
-  Services.prefs.setIntPref("bootstraptest.installed_version", VERSION);
-  Services.prefs.setIntPref("bootstraptest.install_oldversion", data.oldVersion);
-  Services.prefs.setIntPref("bootstraptest.install_reason", reason);
-}
-
-function startup(data, reason) {
-  Services.prefs.setIntPref("bootstraptest.active_version", VERSION);
-  Services.prefs.setIntPref("bootstraptest.startup_oldversion", data.oldVersion);
-  Services.prefs.setIntPref("bootstraptest.startup_reason", reason);
-}
-
-function shutdown(data, reason) {
-  Services.prefs.setIntPref("bootstraptest.active_version", 0);
-  Services.prefs.setIntPref("bootstraptest.shutdown_newversion", data.newVersion);
-  Services.prefs.setIntPref("bootstraptest.shutdown_reason", reason);
-}
-
-function uninstall(data, reason) {
-  Services.prefs.setIntPref("bootstraptest.installed_version", 0);
-  Services.prefs.setIntPref("bootstraptest.uninstall_newversion", data.newVersion);
-  Services.prefs.setIntPref("bootstraptest.uninstall_reason", reason);
-}
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_1/install.rdf
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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:id>test@tests.mozilla.org</em:id>
-    <em:version>1.0</em:version>
-    <em:bootstrap>true</em:bootstrap>
-
-    <!-- Front End MetaData -->
-    <em:name>Test Add-on</em:name>
-    <em:updateURL>http://localhost:4444/update.rdf</em:updateURL>
-
-    <em:targetApplication>
-      <Description>
-        <em:id>xpcshell@tests.mozilla.org</em:id>
-        <em:minVersion>2</em:minVersion>
-        <em:maxVersion>5</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-  </Description>
-</RDF>
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_1/test.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-This test file can be altered to break signing checks.
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_2/bootstrap.js
+++ /dev/null
@@ -1,29 +0,0 @@
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-const VERSION = 2;
-
-// Test steps chain from pref observers on *_reason,
-// so always set that last
-function install(data, reason) {
-  Services.prefs.setIntPref("bootstraptest.installed_version", VERSION);
-  Services.prefs.setIntPref("bootstraptest.install_oldversion", data.oldVersion);
-  Services.prefs.setIntPref("bootstraptest.install_reason", reason);
-}
-
-function startup(data, reason) {
-  Services.prefs.setIntPref("bootstraptest.active_version", VERSION);
-  Services.prefs.setIntPref("bootstraptest.startup_oldversion", data.oldVersion);
-  Services.prefs.setIntPref("bootstraptest.startup_reason", reason);
-}
-
-function shutdown(data, reason) {
-  Services.prefs.setIntPref("bootstraptest.active_version", 0);
-  Services.prefs.setIntPref("bootstraptest.shutdown_newversion", data.newVersion);
-  Services.prefs.setIntPref("bootstraptest.shutdown_reason", reason);
-}
-
-function uninstall(data, reason) {
-  Services.prefs.setIntPref("bootstraptest.installed_version", 0);
-  Services.prefs.setIntPref("bootstraptest.uninstall_newversion", data.newVersion);
-  Services.prefs.setIntPref("bootstraptest.uninstall_reason", reason);
-}
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_2/install.rdf
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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:id>test@tests.mozilla.org</em:id>
-    <em:version>2.0</em:version>
-    <em:bootstrap>true</em:bootstrap>
-
-    <!-- Front End MetaData -->
-    <em:name>Test Add-on</em:name>
-    <em:updateURL>http://localhost:4444/update.rdf</em:updateURL>
-
-    <em:targetApplication>
-      <Description>
-        <em:id>xpcshell@tests.mozilla.org</em:id>
-        <em:minVersion>4</em:minVersion>
-        <em:maxVersion>6</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-  </Description>
-</RDF>
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/bootstrap_2/test.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-This test file can be altered to break signing checks.
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/nonbootstrap_1/install.rdf
+++ /dev/null
@@ -1,23 +0,0 @@
-<?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:id>test@tests.mozilla.org</em:id>
-    <em:version>1.0</em:version>
-
-    <!-- Front End MetaData -->
-    <em:name>Test Add-on</em:name>
-    <em:updateURL>http://localhost:4444/update.rdf</em:updateURL>
-
-    <em:targetApplication>
-      <Description>
-        <em:id>xpcshell@tests.mozilla.org</em:id>
-        <em:minVersion>2</em:minVersion>
-        <em:maxVersion>5</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-  </Description>
-</RDF>
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/nonbootstrap_1/test.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-This test file can be altered to break signing checks.
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/nonbootstrap_2/install.rdf
+++ /dev/null
@@ -1,23 +0,0 @@
-<?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:id>test@tests.mozilla.org</em:id>
-    <em:version>2.0</em:version>
-
-    <!-- Front End MetaData -->
-    <em:name>Test Add-on</em:name>
-    <em:updateURL>http://localhost:4444/update.rdf</em:updateURL>
-
-    <em:targetApplication>
-      <Description>
-        <em:id>xpcshell@tests.mozilla.org</em:id>
-        <em:minVersion>4</em:minVersion>
-        <em:maxVersion>6</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-  </Description>
-</RDF>
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/nonbootstrap_2/test.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-This test file can be altered to break signing checks.
deleted file mode 100644
index a62faf1c52b3b5aadb1383d16b4cb5419eaedd1f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 5444b951a48a7b9114d69cf44fbe7eb45e7280ab..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 122c4d56b3d37bb98458ae9055630ca1f9aed670..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 150918a8c157f6855b4d9ea6796965153af4fe17..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 3c6cd647031e61ea5d9c2f60419956a629185451..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index cdf4325acde44b9ef829471ea730ba3c3ab90c72..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 9d50f0825046db67b679ca8c62b95200b111b73b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 6ba1efd727a26604778641ad78abbb0027c0bb5d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
@@ -9,17 +9,16 @@ const XULAPPINFO_CONTRACTID = "@mozilla.
 const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}");
 
 const PREF_EM_CHECK_UPDATE_SECURITY   = "extensions.checkUpdateSecurity";
 const PREF_EM_STRICT_COMPATIBILITY    = "extensions.strictCompatibility";
 const PREF_EM_MIN_COMPAT_APP_VERSION      = "extensions.minCompatibleAppVersion";
 const PREF_EM_MIN_COMPAT_PLATFORM_VERSION = "extensions.minCompatiblePlatformVersion";
 const PREF_GETADDONS_BYIDS               = "extensions.getAddons.get.url";
 const PREF_GETADDONS_BYIDS_PERFORMANCE   = "extensions.getAddons.getWithPerformance.url";
-const PREF_XPI_SIGNATURES_REQUIRED    = "xpinstall.signatures.required";
 
 // Forcibly end the test if it runs longer than 15 minutes
 const TIMEOUT_MS = 900000;
 
 Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/FileUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
@@ -1449,19 +1448,16 @@ Services.prefs.setBoolPref("extensions.s
 
 // By default don't check for hotfixes
 Services.prefs.setCharPref("extensions.hotfix.id", "");
 
 // By default, set min compatible versions to 0
 Services.prefs.setCharPref(PREF_EM_MIN_COMPAT_APP_VERSION, "0");
 Services.prefs.setCharPref(PREF_EM_MIN_COMPAT_PLATFORM_VERSION, "0");
 
-// Disable signature checks for most tests
-Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, false);
-
 // Register a temporary directory for the tests.
 const gTmpD = gProfD.clone();
 gTmpD.append("temp");
 gTmpD.create(AM_Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
 registerDirectory("TmpD", gTmpD);
 
 // Write out an empty blocklist.xml file to the profile to ensure nothing
 // is blocklisted by default
@@ -1529,16 +1525,19 @@ do_register_cleanup(function addon_clean
   var testDir = gProfD.clone();
   testDir.append("extensions");
   testDir.append("trash");
   pathShouldntExist(testDir);
 
   testDir.leafName = "staged";
   pathShouldntExist(testDir);
 
+  testDir.leafName = "staged-xpis";
+  pathShouldntExist(testDir);
+
   shutdownManager();
 
   // Clear commonly set prefs.
   try {
     Services.prefs.clearUserPref(PREF_EM_CHECK_UPDATE_SECURITY);
   } catch (e) {}
   try {
     Services.prefs.clearUserPref(PREF_EM_STRICT_COMPATIBILITY);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate1.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate1.js
@@ -192,21 +192,45 @@ function run_test() {
     // since, it should still be disabled but should be incompatible
     do_check_neq(a5, null);
     do_check_true(a5.userDisabled);
     do_check_true(a5.appDisabled);
     do_check_false(a5.isActive);
     do_check_false(isExtensionInAddonsList(profileDir, a5.id));
     do_check_false(a5.hasBinaryComponents);
 
-    // addon6, addon7 and addon8 will have been lost as they were staged in the
-    // pre-Firefox 4.0 directory
-    do_check_eq(a6, null);
-    do_check_eq(a7, null);
-    do_check_eq(a8, null);
+    // addon6 should be installed and compatible and packed unless unpacking is
+    // forced
+    do_check_neq(a6, null);
+    do_check_false(a6.userDisabled);
+    do_check_false(a6.appDisabled);
+    do_check_true(a6.isActive);
+    do_check_true(isExtensionInAddonsList(profileDir, a6.id));
+    if (Services.prefs.getBoolPref("extensions.alwaysUnpack"))
+      do_check_eq(a6.getResourceURI("install.rdf").scheme, "file");
+    else
+      do_check_eq(a6.getResourceURI("install.rdf").scheme, "jar");
+    do_check_false(a6.hasBinaryComponents);
+
+    // addon7 should be installed and compatible and unpacked
+    do_check_neq(a7, null);
+    do_check_false(a7.userDisabled);
+    do_check_false(a7.appDisabled);
+    do_check_true(a7.isActive);
+    do_check_true(isExtensionInAddonsList(profileDir, a7.id));
+    do_check_eq(a7.getResourceURI("install.rdf").scheme, "file");
+    do_check_false(a7.hasBinaryComponents);
+
+    // addon8 should be installed and compatible and have binary components
+    do_check_neq(a8, null);
+    do_check_false(a8.userDisabled);
+    do_check_false(a8.appDisabled);
+    do_check_true(a8.isActive);
+    do_check_true(isExtensionInAddonsList(profileDir, a8.id));
+    do_check_true(a8.hasBinaryComponents);
 
     // Theme 1 was previously enabled
     do_check_neq(t1, null);
     do_check_false(t1.userDisabled);
     do_check_false(t1.appDisabled);
     do_check_true(t1.isActive);
     do_check_true(isThemeInAddonsList(profileDir, t1.id));
     do_check_false(hasFlag(t1.permissions, AddonManager.PERM_CAN_ENABLE));
@@ -214,11 +238,13 @@ function run_test() {
     // Theme 2 was previously disabled
     do_check_neq(t1, null);
     do_check_true(t2.userDisabled);
     do_check_false(t2.appDisabled);
     do_check_false(t2.isActive);
     do_check_false(isThemeInAddonsList(profileDir, t2.id));
     do_check_true(hasFlag(t2.permissions, AddonManager.PERM_CAN_ENABLE));
 
+    do_check_false(stagedXPIs.exists());
+
     do_execute_soon(do_test_finished);
   });
 }
--- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate3.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate3.js
@@ -191,20 +191,35 @@ function run_test() {
     // addon5 was disabled and compatible but a new version has been installed
     // since, it should still be disabled but should be incompatible
     do_check_neq(a5, null);
     do_check_true(a5.userDisabled);
     do_check_true(a5.appDisabled);
     do_check_false(a5.isActive);
     do_check_false(isExtensionInAddonsList(profileDir, a5.id));
 
-    // addon6 and addon7 will have been lost as they were staged in the
-    // pre-Firefox 4.0 directory
-    do_check_eq(a6, null);
-    do_check_eq(a7, null);
+    // addon6 should be installed and compatible and packed unless unpacking is
+    // forced
+    do_check_neq(a6, null);
+    do_check_false(a6.userDisabled);
+    do_check_false(a6.appDisabled);
+    do_check_true(a6.isActive);
+    do_check_true(isExtensionInAddonsList(profileDir, a6.id));
+    if (Services.prefs.getBoolPref("extensions.alwaysUnpack"))
+      do_check_eq(a6.getResourceURI("install.rdf").scheme, "file");
+    else
+      do_check_eq(a6.getResourceURI("install.rdf").scheme, "jar");
+
+    // addon7 should be installed and compatible and unpacked
+    do_check_neq(a7, null);
+    do_check_false(a7.userDisabled);
+    do_check_false(a7.appDisabled);
+    do_check_true(a7.isActive);
+    do_check_true(isExtensionInAddonsList(profileDir, a7.id));
+    do_check_eq(a7.getResourceURI("install.rdf").scheme, "file");
 
     // Theme 1 was previously disabled
     do_check_neq(t1, null);
     do_check_true(t1.userDisabled);
     do_check_false(t1.appDisabled);
     do_check_false(t1.isActive);
     do_check_true(isThemeInAddonsList(profileDir, t1.id));
     do_check_true(hasFlag(t1.permissions, AddonManager.PERM_CAN_ENABLE));
@@ -212,11 +227,13 @@ function run_test() {
     // Theme 2 was previously disabled
     do_check_neq(t1, null);
     do_check_true(t2.userDisabled);
     do_check_false(t2.appDisabled);
     do_check_false(t2.isActive);
     do_check_false(isThemeInAddonsList(profileDir, t2.id));
     do_check_true(hasFlag(t2.permissions, AddonManager.PERM_CAN_ENABLE));
 
+    do_check_false(stagedXPIs.exists());
+
     do_execute_soon(do_test_finished);
   });
 }
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/test_signed_inject.js
+++ /dev/null
@@ -1,320 +0,0 @@
-// Enable signature checks for these tests
-Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, true);
-// Disable update security
-Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
-
-const DATA = "data/signing_checks/";
-const ADDONS = {
-  bootstrap: {
-    unsigned: "unsigned_bootstrap_2.xpi",
-    badid: "signed_bootstrap_badid_2.xpi",
-    signed: "signed_bootstrap_2.xpi",
-  },
-  nonbootstrap: {
-    unsigned: "unsigned_nonbootstrap_2.xpi",
-    badid: "signed_nonbootstrap_badid_2.xpi",
-    signed: "signed_nonbootstrap_2.xpi",
-  }
-};
-const ID = "test@tests.mozilla.org";
-
-const profileDir = gProfD.clone();
-profileDir.append("extensions");
-
-// Deletes a file from the test add-on in the profile
-function breakAddon(file) {
-  if (TEST_UNPACKED) {
-    file.append("test.txt");
-    file.remove(true);
-  }
-  else {
-    var zipW = AM_Cc["@mozilla.org/zipwriter;1"].
-               createInstance(AM_Ci.nsIZipWriter);
-    zipW.open(file, FileUtils.MODE_RDWR | FileUtils.MODE_APPEND);
-    zipW.removeEntry("test.txt", false);
-    zipW.close();
-  }
-}
-
-function resetPrefs() {
-  Services.prefs.setIntPref("bootstraptest.active_version", -1);
-  Services.prefs.setIntPref("bootstraptest.installed_version", -1);
-  Services.prefs.setIntPref("bootstraptest.startup_reason", -1);
-  Services.prefs.setIntPref("bootstraptest.shutdown_reason", -1);
-  Services.prefs.setIntPref("bootstraptest.install_reason", -1);
-  Services.prefs.setIntPref("bootstraptest.uninstall_reason", -1);
-  Services.prefs.setIntPref("bootstraptest.startup_oldversion", -1);
-  Services.prefs.setIntPref("bootstraptest.shutdown_newversion", -1);
-  Services.prefs.setIntPref("bootstraptest.install_oldversion", -1);
-  Services.prefs.setIntPref("bootstraptest.uninstall_newversion", -1);
-}
-
-function getActiveVersion() {
-  return Services.prefs.getIntPref("bootstraptest.active_version");
-}
-
-function run_test() {
-  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "4", "4");
-
-  // Start and stop the manager to initialise everything in the profile before
-  // actual testing
-  startupManager();
-  shutdownManager();
-  resetPrefs();
-
-  run_next_test();
-}
-
-// Injecting into profile (bootstrap)
-add_task(function*() {
-  manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.unsigned), profileDir, ID);
-
-  startupManager();
-
-  // Currently we leave the sideloaded add-on there but just don't run it
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_true(addon.appDisabled);
-  do_check_false(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_MISSING);
-  do_check_eq(getActiveVersion(), -1);
-
-  addon.uninstall();
-  yield promiseShutdownManager();
-  resetPrefs();
-
-  do_check_false(getFileForAddon(profileDir, ID).exists());
-});
-
-add_task(function*() {
-  manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.signed), profileDir, ID);
-  breakAddon(getFileForAddon(profileDir, ID));
-
-  startupManager();
-
-  // Currently we leave the sideloaded add-on there but just don't run it
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_true(addon.appDisabled);
-  do_check_false(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
-  do_check_eq(getActiveVersion(), -1);
-
-  addon.uninstall();
-  yield promiseShutdownManager();
-  resetPrefs();
-
-  do_check_false(getFileForAddon(profileDir, ID).exists());
-});
-
-add_task(function*() {
-  manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.badid), profileDir, ID);
-
-  startupManager();
-
-  // Currently we leave the sideloaded add-on there but just don't run it
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_true(addon.appDisabled);
-  do_check_false(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
-  do_check_eq(getActiveVersion(), -1);
-
-  addon.uninstall();
-  yield promiseShutdownManager();
-  resetPrefs();
-
-  do_check_false(getFileForAddon(profileDir, ID).exists());
-});
-
-// Installs a signed add-on then modifies it in place breaking its signing
-add_task(function*() {
-  manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.signed), profileDir, ID);
-
-  // Make it appear to come from the past so when we modify it later it is
-  // detected during startup. Obviously malware can bypass this method of
-  // detection but the periodic scan will catch that
-  yield promiseSetExtensionModifiedTime(getFileForAddon(profileDir, ID).path, Date.now() - 600000);
-
-  startupManager();
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_false(addon.appDisabled);
-  do_check_true(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_SIGNED);
-  do_check_eq(getActiveVersion(), 2);
-
-  yield promiseShutdownManager();
-  do_check_eq(getActiveVersion(), 0);
-
-  breakAddon(getFileForAddon(profileDir, ID));
-  resetPrefs();
-
-  startupManager();
-
-  addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_true(addon.appDisabled);
-  do_check_false(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
-  do_check_eq(getActiveVersion(), -1);
-
-  let ids = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_DISABLED);
-  do_check_eq(ids.length, 1);
-  do_check_eq(ids[0], ID);
-
-  addon.uninstall();
-  yield promiseShutdownManager();
-  resetPrefs();
-
-  do_check_false(getFileForAddon(profileDir, ID).exists());
-});
-
-// Injecting into profile (non-bootstrap)
-add_task(function*() {
-  manuallyInstall(do_get_file(DATA + ADDONS.nonbootstrap.unsigned), profileDir, ID);
-
-  startupManager();
-
-  // Currently we leave the sideloaded add-on there but just don't run it
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_true(addon.appDisabled);
-  do_check_false(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_MISSING);
-  do_check_false(isExtensionInAddonsList(profileDir, ID));
-
-  addon.uninstall();
-  yield promiseRestartManager();
-  yield promiseShutdownManager();
-
-  do_check_false(getFileForAddon(profileDir, ID).exists());
-});
-
-add_task(function*() {
-  manuallyInstall(do_get_file(DATA + ADDONS.nonbootstrap.signed), profileDir, ID);
-  breakAddon(getFileForAddon(profileDir, ID));
-
-  startupManager();
-
-  // Currently we leave the sideloaded add-on there but just don't run it
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_true(addon.appDisabled);
-  do_check_false(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
-  do_check_false(isExtensionInAddonsList(profileDir, ID));
-
-  addon.uninstall();
-  yield promiseRestartManager();
-  yield promiseShutdownManager();
-
-  do_check_false(getFileForAddon(profileDir, ID).exists());
-});
-
-add_task(function*() {
-  manuallyInstall(do_get_file(DATA + ADDONS.nonbootstrap.badid), profileDir, ID);
-
-  startupManager();
-
-  // Currently we leave the sideloaded add-on there but just don't run it
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_true(addon.appDisabled);
-  do_check_false(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
-  do_check_false(isExtensionInAddonsList(profileDir, ID));
-
-  addon.uninstall();
-  yield promiseRestartManager();
-  yield promiseShutdownManager();
-
-  do_check_false(getFileForAddon(profileDir, ID).exists());
-});
-
-// Installs a signed add-on then modifies it in place breaking its signing
-add_task(function*() {
-  manuallyInstall(do_get_file(DATA + ADDONS.nonbootstrap.signed), profileDir, ID);
-
-  // Make it appear to come from the past so when we modify it later it is
-  // detected during startup. Obviously malware can bypass this method of
-  // detection but the periodic scan will catch that
-  yield promiseSetExtensionModifiedTime(getFileForAddon(profileDir, ID).path, Date.now() - 60000);
-
-  startupManager();
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_false(addon.appDisabled);
-  do_check_true(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_SIGNED);
-  do_check_true(isExtensionInAddonsList(profileDir, ID));
-
-  yield promiseShutdownManager();
-
-  breakAddon(getFileForAddon(profileDir, ID));
-
-  startupManager();
-
-  addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_true(addon.appDisabled);
-  do_check_false(addon.isActive);
-  do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
-  do_check_false(isExtensionInAddonsList(profileDir, ID));
-
-  let ids = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_DISABLED);
-  do_check_eq(ids.length, 1);
-  do_check_eq(ids[0], ID);
-
-  addon.uninstall();
-  yield promiseRestartManager();
-  yield promiseShutdownManager();
-
-  do_check_false(getFileForAddon(profileDir, ID).exists());
-});
-
-// Stage install then modify before startup (non-bootstrap)
-add_task(function*() {
-  startupManager();
-  yield promiseInstallAllFiles([do_get_file(DATA + ADDONS.nonbootstrap.signed)]);
-  yield promiseShutdownManager();
-
-  let staged = profileDir.clone();
-  staged.append("staged");
-  staged.append(do_get_expected_addon_name(ID));
-  do_check_true(staged.exists());
-
-  breakAddon(staged);
-  startupManager();
-
-  // Should have refused to install the broken staged version
-  let addon = yield promiseAddonByID(ID);
-  do_check_eq(addon, null);
-
-  let install = getFileForAddon(profileDir, ID);
-  do_check_false(install.exists());
-
-  yield promiseShutdownManager();
-});
-
-// Manufacture staged install (bootstrap)
-add_task(function*() {
-  let stage = profileDir.clone();
-  stage.append("staged");
-
-  let file = manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.signed), stage, ID);
-  breakAddon(file);
-
-  startupManager();
-
-  // Should have refused to install the broken staged version
-  let addon = yield promiseAddonByID(ID);
-  do_check_eq(addon, null);
-  do_check_eq(getActiveVersion(), -1);
-
-  let install = getFileForAddon(profileDir, ID);
-  do_check_false(install.exists());
-
-  yield promiseShutdownManager();
-  resetPrefs();
-});
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js
+++ /dev/null
@@ -1,265 +0,0 @@
-// Enable signature checks for these tests
-Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, true);
-// Disable update security
-Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
-
-const DATA = "data/signing_checks/";
-const ADDONS = {
-  bootstrap: {
-    unsigned: "unsigned_bootstrap_2.xpi",
-    badid: "signed_bootstrap_badid_2.xpi",
-    preliminary: "preliminary_bootstrap_2.xpi",
-    signed: "signed_bootstrap_2.xpi",
-  },
-};
-const WORKING = "signed_bootstrap_1.xpi";
-const ID = "test@tests.mozilla.org";
-
-Components.utils.import("resource://testing-common/httpd.js");
-var gServer = new HttpServer();
-gServer.start(4444);
-
-// Creates an add-on with a broken signature by changing an existing file
-function createBrokenAddonModify(file) {
-  let brokenFile = gTmpD.clone();
-  brokenFile.append("broken.xpi");
-  file.copyTo(brokenFile.parent, brokenFile.leafName);
-
-  var stream = AM_Cc["@mozilla.org/io/string-input-stream;1"].
-               createInstance(AM_Ci.nsIStringInputStream);
-  stream.setData("FOOBAR", -1);
-  var zipW = AM_Cc["@mozilla.org/zipwriter;1"].
-             createInstance(AM_Ci.nsIZipWriter);
-  zipW.open(brokenFile, FileUtils.MODE_RDWR | FileUtils.MODE_APPEND);
-  zipW.removeEntry("test.txt", false);
-  zipW.addEntryStream("test.txt", 0, AM_Ci.nsIZipWriter.COMPRESSION_NONE,
-                      stream, false);
-  zipW.close();
-
-  return brokenFile;
-}
-
-// Creates an add-on with a broken signature by adding a new file
-function createBrokenAddonAdd(file) {
-  let brokenFile = gTmpD.clone();
-  brokenFile.append("broken.xpi");
-  file.copyTo(brokenFile.parent, brokenFile.leafName);
-
-  var stream = AM_Cc["@mozilla.org/io/string-input-stream;1"].
-               createInstance(AM_Ci.nsIStringInputStream);
-  stream.setData("FOOBAR", -1);
-  var zipW = AM_Cc["@mozilla.org/zipwriter;1"].
-             createInstance(AM_Ci.nsIZipWriter);
-  zipW.open(brokenFile, FileUtils.MODE_RDWR | FileUtils.MODE_APPEND);
-  zipW.addEntryStream("test2.txt", 0, AM_Ci.nsIZipWriter.COMPRESSION_NONE,
-                      stream, false);
-  zipW.close();
-
-  return brokenFile;
-}
-
-// Creates an add-on with a broken signature by removing an existing file
-function createBrokenAddonRemove(file) {
-  let brokenFile = gTmpD.clone();
-  brokenFile.append("broken.xpi");
-  file.copyTo(brokenFile.parent, brokenFile.leafName);
-
-  var stream = AM_Cc["@mozilla.org/io/string-input-stream;1"].
-               createInstance(AM_Ci.nsIStringInputStream);
-  stream.setData("FOOBAR", -1);
-  var zipW = AM_Cc["@mozilla.org/zipwriter;1"].
-             createInstance(AM_Ci.nsIZipWriter);
-  zipW.open(brokenFile, FileUtils.MODE_RDWR | FileUtils.MODE_APPEND);
-  zipW.removeEntry("test.txt", false);
-  zipW.close();
-
-  return brokenFile;
-}
-
-function createInstall(url) {
-  return new Promise(resolve => {
-    AddonManager.getInstallForURL(url, resolve, "application/x-xpinstall");
-  });
-}
-
-function serveUpdateRDF(leafName) {
-  gServer.registerPathHandler("/update.rdf", function(request, response) {
-    let updateData = {};
-    updateData[ID] = [{
-      version: "2.0",
-      targetApplications: [{
-        id: "xpcshell@tests.mozilla.org",
-        minVersion: "4",
-        maxVersion: "6",
-        updateLink: "http://localhost:4444/" + leafName
-      }]
-    }];
-
-    response.setStatusLine(request.httpVersion, 200, "OK");
-    response.write(createUpdateRDF(updateData));
-  });
-}
-
-
-function* test_install_broken(file, expectedError) {
-  gServer.registerFile("/" + file.leafName, file);
-
-  let install = yield createInstall("http://localhost:4444/" + file.leafName);
-  yield promiseCompleteAllInstalls([install]);
-
-  do_check_eq(install.state, AddonManager.STATE_DOWNLOAD_FAILED);
-  do_check_eq(install.error, expectedError);
-  do_check_eq(install.addon, null);
-
-  gServer.registerFile("/" + file.leafName, null);
-}
-
-function* test_install_working(file, expectedSignedState) {
-  gServer.registerFile("/" + file.leafName, file);
-
-  let install = yield createInstall("http://localhost:4444/" + file.leafName);
-  yield promiseCompleteAllInstalls([install]);
-
-  do_check_eq(install.state, AddonManager.STATE_INSTALLED);
-  do_check_neq(install.addon, null);
-  do_check_eq(install.addon.signedState, expectedSignedState);
-
-  gServer.registerFile("/" + file.leafName, null);
-
-  install.addon.uninstall();
-}
-
-function* test_update_broken(file, expectedError) {
-  // First install the older version
-  yield promiseInstallAllFiles([do_get_file(DATA + WORKING)]);
-
-  gServer.registerFile("/" + file.leafName, file);
-  serveUpdateRDF(file.leafName);
-
-  let addon = yield promiseAddonByID(ID);
-  let install = yield promiseFindAddonUpdates(addon);
-  yield promiseCompleteAllInstalls([install]);
-
-  do_check_eq(install.state, AddonManager.STATE_DOWNLOAD_FAILED);
-  do_check_eq(install.error, expectedError);
-  do_check_eq(install.addon, null);
-
-  gServer.registerFile("/" + file.leafName, null);
-  gServer.registerPathHandler("/update.rdf", null);
-
-  addon.uninstall();
-}
-
-function* test_update_working(file, expectedSignedState) {
-  // First install the older version
-  yield promiseInstallAllFiles([do_get_file(DATA + WORKING)]);
-
-  gServer.registerFile("/" + file.leafName, file);
-  serveUpdateRDF(file.leafName);
-
-  let addon = yield promiseAddonByID(ID);
-  let install = yield promiseFindAddonUpdates(addon);
-  yield promiseCompleteAllInstalls([install]);
-
-  do_check_eq(install.state, AddonManager.STATE_INSTALLED);
-  do_check_neq(install.addon, null);
-  do_check_eq(install.addon.signedState, expectedSignedState);
-
-  gServer.registerFile("/" + file.leafName, null);
-  gServer.registerPathHandler("/update.rdf", null);
-
-  install.addon.uninstall();
-}
-
-function run_test() {
-  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "4", "4");
-  startupManager();
-
-  run_next_test();
-}
-
-// Try to install a broken add-on
-add_task(function*() {
-  let file = createBrokenAddonModify(do_get_file(DATA + ADDONS.bootstrap.signed));
-  yield test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE);
-  file.remove(true);
-});
-
-add_task(function*() {
-  let file = createBrokenAddonAdd(do_get_file(DATA + ADDONS.bootstrap.signed));
-  yield test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE);
-  file.remove(true);
-});
-
-add_task(function*() {
-  let file = createBrokenAddonRemove(do_get_file(DATA + ADDONS.bootstrap.signed));
-  yield test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE);
-  file.remove(true);
-});
-
-// Try to install an add-on with an incorrect ID
-add_task(function*() {
-  let file = do_get_file(DATA + ADDONS.bootstrap.badid);
-  yield test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE);
-});
-
-// Try to install an unsigned add-on
-add_task(function*() {
-  let file = do_get_file(DATA + ADDONS.bootstrap.unsigned);
-  yield test_install_broken(file, AddonManager.ERROR_SIGNEDSTATE_REQUIRED);
-});
-
-// Try to install a preliminarily reviewed add-on
-add_task(function*() {
-  let file = do_get_file(DATA + ADDONS.bootstrap.preliminary);
-  yield test_install_working(file, AddonManager.SIGNEDSTATE_PRELIMINARY);
-});
-
-// Try to install a signed add-on
-add_task(function*() {
-  let file = do_get_file(DATA + ADDONS.bootstrap.signed);
-  yield test_install_working(file, AddonManager.SIGNEDSTATE_SIGNED);
-});
-
-// Try to update to a broken add-on
-add_task(function*() {
-  let file = createBrokenAddonModify(do_get_file(DATA + ADDONS.bootstrap.signed));
-  yield test_update_broken(file, AddonManager.ERROR_CORRUPT_FILE);
-  file.remove(true);
-});
-
-add_task(function*() {
-  let file = createBrokenAddonAdd(do_get_file(DATA + ADDONS.bootstrap.signed));
-  yield test_update_broken(file, AddonManager.ERROR_CORRUPT_FILE);
-  file.remove(true);
-});
-
-add_task(function*() {
-  let file = createBrokenAddonRemove(do_get_file(DATA + ADDONS.bootstrap.signed));
-  yield test_update_broken(file, AddonManager.ERROR_CORRUPT_FILE);
-  file.remove(true);
-});
-
-// Try to update to an add-on with an incorrect ID
-add_task(function*() {
-  let file = do_get_file(DATA + ADDONS.bootstrap.badid);
-  yield test_update_broken(file, AddonManager.ERROR_CORRUPT_FILE);
-});
-
-// Try to update to an unsigned add-on
-add_task(function*() {
-  let file = do_get_file(DATA + ADDONS.bootstrap.unsigned);
-  yield test_update_broken(file, AddonManager.ERROR_SIGNEDSTATE_REQUIRED);
-});
-
-// Try to update to a preliminarily reviewed add-on
-add_task(function*() {
-  let file = do_get_file(DATA + ADDONS.bootstrap.preliminary);
-  yield test_update_working(file, AddonManager.SIGNEDSTATE_PRELIMINARY);
-});
-
-// Try to update to a signed add-on
-add_task(function*() {
-  let file = do_get_file(DATA + ADDONS.bootstrap.signed);
-  yield test_update_working(file, AddonManager.SIGNEDSTATE_SIGNED);
-});
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/test_signed_migrate.js
+++ /dev/null
@@ -1,164 +0,0 @@
-// Enable signature checks for these tests
-Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, true);
-// Disable update security
-Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
-
-const DATA = "data/signing_checks/";
-const ADDONS = {
-  bootstrap: {
-    unsigned: "unsigned_bootstrap_2.xpi",
-    badid: "signed_bootstrap_badid_2.xpi",
-    signed: "signed_bootstrap_2.xpi",
-  },
-  nonbootstrap: {
-    unsigned: "unsigned_nonbootstrap_2.xpi",
-    badid: "signed_nonbootstrap_badid_2.xpi",
-    signed: "signed_nonbootstrap_2.xpi",
-  }
-};
-const ID = "test@tests.mozilla.org";
-
-const profileDir = gProfD.clone();
-profileDir.append("extensions");
-
-function resetPrefs() {
-  Services.prefs.setIntPref("bootstraptest.active_version", -1);
-  Services.prefs.setIntPref("bootstraptest.installed_version", -1);
-  Services.prefs.setIntPref("bootstraptest.startup_reason", -1);
-  Services.prefs.setIntPref("bootstraptest.shutdown_reason", -1);
-  Services.prefs.setIntPref("bootstraptest.install_reason", -1);
-  Services.prefs.setIntPref("bootstraptest.uninstall_reason", -1);
-  Services.prefs.setIntPref("bootstraptest.startup_oldversion", -1);
-  Services.prefs.setIntPref("bootstraptest.shutdown_newversion", -1);
-  Services.prefs.setIntPref("bootstraptest.install_oldversion", -1);
-  Services.prefs.setIntPref("bootstraptest.uninstall_newversion", -1);
-}
-
-function getActiveVersion() {
-  return Services.prefs.getIntPref("bootstraptest.active_version");
-}
-
-function run_test() {
-  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "4", "4");
-
-  // Start and stop the manager to initialise everything in the profile before
-  // actual testing
-  startupManager();
-  shutdownManager();
-  resetPrefs();
-
-  run_next_test();
-}
-
-// Removes the signedState field from add-ons in the json database to make it
-// look like the database was written with an older version of the application
-function stripDB() {
-  let jData = loadJSON(gExtensionsJSON);
-  jData.schemaVersion--;
-
-  for (let addon of jData.addons)
-    delete addon.signedState;
-
-  saveJSON(jData, gExtensionsJSON);
-}
-
-function* test_breaking_migrate(addons, test, expectedSignedState) {
-  // Startup as the old version
-  gAppInfo.version = "4";
-  startupManager(true);
-
-  // Install the signed add-on
-  yield promiseInstallAllFiles([do_get_file(DATA + addons.signed)]);
-  // Restart to let non-restartless add-ons install fully
-  yield promiseRestartManager();
-  yield promiseShutdownManager();
-  resetPrefs();
-  stripDB();
-
-  // Now replace it with the version to test. Doing this so quickly shouldn't
-  // trigger the file modification code to detect the change by itself.
-  manuallyUninstall(profileDir, ID);
-  manuallyInstall(do_get_file(DATA + addons[test]), profileDir, ID);
-
-  // Update the application
-  gAppInfo.version = "5";
-  startupManager(true);
-
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_true(addon.appDisabled);
-  do_check_false(addon.isActive);
-  do_check_eq(addon.signedState, expectedSignedState);
-
-  // Add-on shouldn't be active
-  if (addons == ADDONS.bootstrap)
-    do_check_eq(getActiveVersion(), -1);
-  else
-    do_check_false(isExtensionInAddonsList(profileDir, ID));
-
-  // Should have flagged the change during startup
-  let changes = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_DISABLED);
-  do_check_eq(changes.length, 1);
-  do_check_eq(changes[0], ID);
-
-  addon.uninstall();
-  // Restart to let non-restartless add-ons uninstall fully
-  yield promiseRestartManager();
-  yield shutdownManager();
-  resetPrefs();
-}
-
-function* test_working_migrate(addons, test, expectedSignedState) {
-  // Startup as the old version
-  gAppInfo.version = "4";
-  startupManager(true);
-
-  // Install the signed add-on
-  yield promiseInstallAllFiles([do_get_file(DATA + addons.signed)]);
-  // Restart to let non-restartless add-ons install fully
-  yield promiseRestartManager();
-  yield promiseShutdownManager();
-  resetPrefs();
-  stripDB();
-
-  // Now replace it with the version to test. Doing this so quickly shouldn't
-  // trigger the file modification code to detect the change by itself.
-  manuallyUninstall(profileDir, ID);
-  manuallyInstall(do_get_file(DATA + addons[test]), profileDir, ID);
-
-  // Update the application
-  gAppInfo.version = "5";
-  startupManager(true);
-
-  let addon = yield promiseAddonByID(ID);
-  do_check_neq(addon, null);
-  do_check_false(addon.appDisabled);
-  do_check_true(addon.isActive);
-  do_check_eq(addon.signedState, expectedSignedState);
-
-  if (addons == ADDONS.bootstrap)
-    do_check_eq(getActiveVersion(), 2);
-  else
-    do_check_true(isExtensionInAddonsList(profileDir, ID));
-
-  addon.uninstall();
-  // Restart to let non-restartless add-ons uninstall fully
-  yield promiseRestartManager();
-  yield shutdownManager();
-  resetPrefs();
-}
-
-add_task(function*() {
-  yield test_breaking_migrate(ADDONS.bootstrap, "unsigned", AddonManager.SIGNEDSTATE_MISSING);
-  yield test_breaking_migrate(ADDONS.nonbootstrap, "unsigned", AddonManager.SIGNEDSTATE_MISSING);
-});
-
-add_task(function*() {
-  yield test_breaking_migrate(ADDONS.bootstrap, "badid", AddonManager.SIGNEDSTATE_BROKEN);
-  yield test_breaking_migrate(ADDONS.nonbootstrap, "badid", AddonManager.SIGNEDSTATE_BROKEN);
-});
-
-add_task(function*() {
-  yield test_working_migrate(ADDONS.bootstrap, "signed", AddonManager.SIGNEDSTATE_SIGNED);
-  yield test_working_migrate(ADDONS.nonbootstrap, "signed", AddonManager.SIGNEDSTATE_SIGNED);
-});
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -17,17 +17,12 @@ skip-if = appname != "firefox"
 [test_isReady.js]
 [test_metadata_update.js]
 [test_pluginInfoURL.js]
 [test_provider_markSafe.js]
 [test_provider_shutdown.js]
 [test_provider_unsafe_access_shutdown.js]
 [test_provider_unsafe_access_startup.js]
 [test_shutdown.js]
-[test_signed_inject.js]
-skip-if = true
-[test_signed_install.js]
-run-sequentially = Uses hardcoded ports in xpi files.
-[test_signed_migrate.js]
 [test_XPIcancel.js]
 [test_XPIStates.js]
 
 [include:xpcshell-shared.ini]