Backed out changeset f99621542727 (bug 1038068) for test failures in test_corrupt.js etc on a CLOSED TREE
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 23 Apr 2015 09:09:30 +0200
changeset 240624 cac8a0359113ff642052bbac834b23264ddc76b6
parent 240623 04406a15fbb7a1ddc4a5f5bc42a242282f468e46
child 240625 6d160cfb8bbf95ef601190fd7508ea83a5b63cd3
child 240695 10a237997b8dcfb74e1507d368c76819219ca268
push id12531
push usercbook@mozilla.com
push dateThu, 23 Apr 2015 07:09:44 +0000
treeherderfx-team@cac8a0359113 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1038068
milestone40.0a1
backs outf996215427273ee9a9a7c7c36230a4c6b2777e87
Backed out changeset f99621542727 (bug 1038068) for test failures in test_corrupt.js etc on a CLOSED TREE
CLOBBER
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/CLOBBER
+++ b/CLOBBER
@@ -17,12 +17,13 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1038068: Check add-on signatures and refuse to install unsigned or broken add-ons
+Bug 1155718: Merge Bluetooth v1/v2 files for all simple cases
 
-Not sure why this needs a clobber but tests perma-failed when they don't on
-try.
+This patch set renames source files. This requires updating the
+build system's dependency information from scratch. The issue has
+been reported in bug 1154232.
--- 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
@@ -4103,18 +4103,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..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 73e48cadfe2da5373a20a88a54148dac695da7d4..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
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
@@ -34,17 +34,17 @@ interface nsIVerifySignedManifestCallbac
   void verifySignedManifestFinished(in nsresult rv,
                                     in nsIX509Cert aSignerCert);
 };
 
 /**
  * This represents a service to access and manipulate
  * X.509 certificates stored in a database.
  */
-[scriptable, uuid(560bc9ac-3e71-472e-9b08-2270d0c71878)]
+[scriptable, uuid(8b01c2af-3a44-44d3-8ea5-51c2455e6c4b)]
 interface nsIX509CertDB : nsISupports {
 
   /**
    *  Constants that define which usages a certificate
    *  is trusted for.
    */
   const unsigned long UNTRUSTED       =      0;
   const unsigned long TRUSTED_SSL     = 1 << 0;
@@ -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..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 5444b951a48a7b9114d69cf44fbe7eb45e7280ab..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 122c4d56b3d37bb98458ae9055630ca1f9aed670..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 150918a8c157f6855b4d9ea6796965153af4fe17..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 3c6cd647031e61ea5d9c2f60419956a629185451..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index cdf4325acde44b9ef829471ea730ba3c3ab90c72..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 9d50f0825046db67b679ca8c62b95200b111b73b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 6ba1efd727a26604778641ad78abbb0027c0bb5d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
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]