Backed out changeset 16aa7041c009 (bug 1287107) for causing xpcshell and mac tests
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 22 Jul 2016 11:30:23 +0200
changeset 306222 35921a0c3857a29f4bfb37be6e34e681820af4d9
parent 306221 2868c140a299dfb3f036e1404c3ee2741938a525
child 306244 81539328348ac4b64ec580c45e825353d00e96d8
push id79800
push usercbook@mozilla.com
push dateFri, 22 Jul 2016 10:17:37 +0000
treeherdermozilla-inbound@30745bed2567 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1287107
milestone50.0a1
backs out16aa7041c00965e0ead9e03b5f2ff2d8329c4e7d
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 16aa7041c009 (bug 1287107) for causing xpcshell and mac tests
b2g/chrome/content/shell.js
b2g/components/Bootstraper.jsm
b2g/components/GaiaChrome.cpp
b2g/components/GaiaChrome.h
b2g/components/SafeMode.jsm
b2g/components/moz.build
b2g/components/nsIGaiaChrome.idl
b2g/installer/package-manifest.in
caps/tests/mochitest/chrome.ini
devtools/shared/apps/tests/mochitest.ini
dom/apps/AppsServiceChild.jsm
dom/apps/PermissionsTable.jsm
dom/apps/Webapps.jsm
dom/apps/tests/mochitest.ini
dom/broadcastchannel/tests/mochitest.ini
dom/cache/test/mochitest/mochitest.ini
dom/indexedDB/test/mochitest.ini
dom/ipc/tests/mochitest.ini
dom/security/test/csp/chrome.ini
dom/security/test/csp/mochitest.ini
dom/tests/mochitest/fetch/mochitest.ini
dom/tests/mochitest/localstorage/mochitest.ini
extensions/cookie/test/chrome.ini
js/xpconnect/src/nsXPConnect.cpp
netwerk/test/mochitests/mochitest.ini
testing/mochitest/tests/Harness_sanity/mochitest.ini
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -33,16 +33,18 @@ Cu.import('resource://gre/modules/Presen
 Cu.import('resource://gre/modules/AboutServiceWorkers.jsm');
 
 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
                                   "resource://gre/modules/SystemAppProxy.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Screenshot",
                                   "resource://gre/modules/Screenshot.jsm");
 
+Cu.import('resource://gre/modules/Webapps.jsm');
+
 XPCOMUtils.defineLazyServiceGetter(Services, 'env',
                                    '@mozilla.org/process/environment;1',
                                    'nsIEnvironment');
 
 XPCOMUtils.defineLazyServiceGetter(Services, 'ss',
                                    '@mozilla.org/content/style-sheet-service;1',
                                    'nsIStyleSheetService');
 
@@ -349,17 +351,16 @@ var shell = {
     }
 
     let homeURL = this.homeURL;
     if (!homeURL) {
       let msg = 'Fatal error during startup: No homescreen found: try setting B2G_HOMESCREEN';
       alert(msg);
       return;
     }
-
     let manifestURL = this.manifestURL;
     // <html:iframe id="systemapp"
     //              mozbrowser="true" allowfullscreen="true"
     //              style="overflow: hidden; height: 100%; width: 100%; border: none;"
     //              src="data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;'>"/>
     let systemAppFrame =
       document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
     systemAppFrame.setAttribute('id', 'systemapp');
@@ -416,21 +417,21 @@ var shell = {
     window.addEventListener('MozAfterPaint', this);
     window.addEventListener('sizemodechange', this);
     window.addEventListener('unload', this);
     this.contentBrowser.addEventListener('mozbrowserloadstart', this, true);
     this.contentBrowser.addEventListener('mozbrowserscrollviewchange', this, true);
     this.contentBrowser.addEventListener('mozbrowsercaretstatechanged', this);
 
     CustomEventManager.init();
+    WebappsHelper.init();
     UserAgentOverrides.init();
     CaptivePortalLoginHelper.init();
 
     this.contentBrowser.src = homeURL;
-
     this._isEventListenerReady = false;
 
     window.performance.mark('gecko-shell-system-frame-set');
 
     ppmm.addMessageListener("content-handler", this);
     ppmm.addMessageListener("dial-handler", this);
     ppmm.addMessageListener("sms-handler", this);
     ppmm.addMessageListener("mail-handler", this);
@@ -775,16 +776,25 @@ var shell = {
   }
 };
 
 Services.obs.addObserver(function onFullscreenOriginChange(subject, topic, data) {
   shell.sendChromeEvent({ type: "fullscreenoriginchange",
                           fullscreenorigin: data });
 }, "fullscreen-origin-change", false);
 
+DOMApplicationRegistry.registryReady.then(function () {
+  // This event should be sent before System app returns with
+  // system-message-listener-ready mozContentEvent, because it's on
+  // the critical launch path of the app.
+  SystemAppProxy._sendCustomEvent('mozChromeEvent', {
+    type: 'webapps-registry-ready'
+  }, /* noPending */ true);
+});
+
 Services.obs.addObserver(function onBluetoothVolumeChange(subject, topic, data) {
   shell.sendChromeEvent({
     type: "bluetooth-volumeset",
     value: data
   });
 }, 'bluetooth-volume-change', false);
 
 Services.obs.addObserver(function(subject, topic, data) {
@@ -811,16 +821,22 @@ var CustomEventManager = {
     }).bind(this), false);
   },
 
   handleEvent: function custevt_handleEvent(evt) {
     let detail = evt.detail;
     dump('XXX FIXME : Got a mozContentEvent: ' + detail.type + "\n");
 
     switch(detail.type) {
+      case 'webapps-install-granted':
+      case 'webapps-install-denied':
+      case 'webapps-uninstall-granted':
+      case 'webapps-uninstall-denied':
+        WebappsHelper.handleEvent(detail);
+        break;
       case 'system-message-listener-ready':
         Services.obs.notifyObservers(null, 'system-message-listener-ready', null);
         break;
       case 'captive-portal-login-cancel':
         CaptivePortalLoginHelper.handleEvent(detail);
         break;
       case 'inputmethod-update-layouts':
       case 'inputregistry-add':
@@ -869,16 +885,102 @@ var CustomEventManager = {
         break;
       case 'restart':
         restart();
         break;
     }
   }
 }
 
+var WebappsHelper = {
+  _installers: {},
+  _count: 0,
+
+  init: function webapps_init() {
+    Services.obs.addObserver(this, "webapps-launch", false);
+    Services.obs.addObserver(this, "webapps-ask-install", false);
+    Services.obs.addObserver(this, "webapps-ask-uninstall", false);
+    Services.obs.addObserver(this, "webapps-close", false);
+  },
+
+  registerInstaller: function webapps_registerInstaller(data) {
+    let id = "installer" + this._count++;
+    this._installers[id] = data;
+    return id;
+  },
+
+  handleEvent: function webapps_handleEvent(detail) {
+    if (!detail || !detail.id)
+      return;
+
+    let installer = this._installers[detail.id];
+    delete this._installers[detail.id];
+    switch (detail.type) {
+      case "webapps-install-granted":
+        DOMApplicationRegistry.confirmInstall(installer);
+        break;
+      case "webapps-install-denied":
+        DOMApplicationRegistry.denyInstall(installer);
+        break;
+      case "webapps-uninstall-granted":
+        DOMApplicationRegistry.confirmUninstall(installer);
+        break;
+      case "webapps-uninstall-denied":
+        DOMApplicationRegistry.denyUninstall(installer);
+        break;
+    }
+  },
+
+  observe: function webapps_observe(subject, topic, data) {
+    let json = JSON.parse(data);
+    json.mm = subject;
+
+    let id;
+
+    switch(topic) {
+      case "webapps-launch":
+        DOMApplicationRegistry.getManifestFor(json.manifestURL).then((aManifest) => {
+          if (!aManifest)
+            return;
+
+          let manifest = new ManifestHelper(aManifest, json.origin,
+                                            json.manifestURL);
+          let payload = {
+            timestamp: json.timestamp,
+            url: manifest.fullLaunchPath(json.startPoint),
+            manifestURL: json.manifestURL
+          };
+          shell.sendCustomEvent("webapps-launch", payload);
+        });
+        break;
+      case "webapps-ask-install":
+        id = this.registerInstaller(json);
+        shell.sendChromeEvent({
+          type: "webapps-ask-install",
+          id: id,
+          app: json.app
+        });
+        break;
+      case "webapps-ask-uninstall":
+        id = this.registerInstaller(json);
+        shell.sendChromeEvent({
+          type: "webapps-ask-uninstall",
+          id: id,
+          app: json.app
+        });
+        break;
+      case "webapps-close":
+        shell.sendCustomEvent("webapps-close", {
+          "manifestURL": json.manifestURL
+        });
+        break;
+    }
+  }
+}
+
 var KeyboardHelper = {
   handleEvent: function keyboard_handleEvent(detail) {
     switch (detail.type) {
       case 'inputmethod-update-layouts':
         Keyboard.setLayouts(detail.layouts);
 
         break;
       case 'inputregistry-add':
--- a/b2g/components/Bootstraper.jsm
+++ b/b2g/components/Bootstraper.jsm
@@ -7,16 +7,17 @@
 this.EXPORTED_SYMBOLS = ["Bootstraper"];
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const CC = Components.Constructor;
 
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Webapps.jsm");
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 
 function debug(aMsg) {
   //dump("-*- Bootstraper: " + aMsg + "\n");
 }
 
 /**
   * This module loads the manifest for app from the --start-url enpoint and
@@ -53,17 +54,17 @@ this.Bootstraper = {
           manifestHash: AppsUtils.computeHash(JSON.stringify(aManifest)),
           appStatus: Ci.nsIPrincipal.APP_STATUS_CERTIFIED
         },
         appId: 1,
         isBrowser: false,
         isPackage: false
       };
 
-      //DOMApplicationRegistry.confirmInstall(appData, null, aResolve);
+      DOMApplicationRegistry.confirmInstall(appData, null, aResolve);
     });
   },
 
   /**
     * Resolves to a json manifest.
     */
   loadManifest: function() {
     return new Promise((aResolve, aReject) => {
@@ -96,19 +97,16 @@ this.Bootstraper = {
     return Promise.resolve();
   },
 
   /**
     * If a system app is already installed, uninstall it so that we can
     * cleanly replace it by the current one.
     */
   uninstallPreviousSystemApp: function() {
-    // TODO: FIXME
-    return Promise.resolve();
-
     let oldManifestURL;
     try{
       oldManifestURL = Services.prefs.getCharPref("b2g.system_manifest_url");
     } catch(e) {
       // No preference set, so nothing to uninstall.
       return Promise.resolve();
     }
 
@@ -140,17 +138,18 @@ this.Bootstraper = {
     debug("Installing app from " + this._manifestURL);
 
     if (!this.isInstallRequired(this._manifestURL)) {
       debug("Already configured for " + this._manifestURL);
       return Promise.resolve();
     }
 
     return new Promise((aResolve, aReject) => {
-      this.uninstallPreviousSystemApp.bind(this)
+      DOMApplicationRegistry.registryReady
+          .then(this.uninstallPreviousSystemApp.bind(this))
           .then(this.loadManifest.bind(this))
           .then(this.installSystemApp.bind(this))
           .then(this.configure.bind(this))
           .then(aResolve)
           .catch(aReject);
     });
   }
 };
deleted file mode 100644
--- a/b2g/components/GaiaChrome.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "GaiaChrome.h"
-
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsChromeRegistry.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsLocalFile.h"
-#include "nsXULAppAPI.h"
-
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/ModuleUtils.h"
-#include "mozilla/Services.h"
-#include "mozilla/FileLocation.h"
-
-#define NS_GAIACHROME_CID \
-  { 0x83f8f999, 0x6b87, 0x4dd8, { 0xa0, 0x93, 0x72, 0x0b, 0xfb, 0x67, 0x4d, 0x38 } }
-
-using namespace mozilla;
-
-StaticRefPtr<GaiaChrome> gGaiaChrome;
-
-NS_IMPL_ISUPPORTS(GaiaChrome, nsIGaiaChrome)
-
-GaiaChrome::GaiaChrome()
-  : mPackageName(NS_LITERAL_CSTRING("gaia"))
-  , mAppsDir(NS_LITERAL_STRING("apps"))
-  , mDataRoot(NS_LITERAL_STRING("/data/local"))
-  , mSystemRoot(NS_LITERAL_STRING("/system/b2g"))
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  GetProfileDir();
-  Register();
-}
-
-//virtual
-GaiaChrome::~GaiaChrome()
-{
-}
-
-nsresult
-GaiaChrome::GetProfileDir()
-{
-  nsCOMPtr<nsIFile> profDir;
-  nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                                       getter_AddRefs(profDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = profDir->Clone(getter_AddRefs(mProfDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
-}
-
-nsresult
-GaiaChrome::ComputeAppsPath(nsIFile* aPath)
-{
-#if defined(MOZ_MULET)
-  aPath->InitWithFile(mProfDir);
-#elif defined(MOZ_WIDGET_GONK)
-  nsCOMPtr<nsIFile> locationDetection = new nsLocalFile();
-  locationDetection->InitWithPath(mSystemRoot);
-  locationDetection->Append(mAppsDir);
-  bool appsInSystem = EnsureIsDirectory(locationDetection);
-  locationDetection->InitWithPath(mDataRoot);
-  locationDetection->Append(mAppsDir);
-  bool appsInData = EnsureIsDirectory(locationDetection);
-
-  if (!appsInData && !appsInSystem) {
-    printf_stderr("!!! NO root directory with apps found\n");
-    MOZ_ASSERT(false);
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  aPath->InitWithPath(appsInData ? mDataRoot : mSystemRoot);
-#else
-  return NS_ERROR_UNEXPECTED;
-#endif
-
-  aPath->Append(mAppsDir);
-  aPath->Append(NS_LITERAL_STRING("."));
-
-  nsresult rv = EnsureValidPath(aPath);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
-}
-
-bool
-GaiaChrome::EnsureIsDirectory(nsIFile* aPath)
-{
-  bool isDir = false;
-  aPath->IsDirectory(&isDir);
-  return isDir;
-}
-
-nsresult
-GaiaChrome::EnsureValidPath(nsIFile* appsDir)
-{
-  // Ensure there is a valid "apps/system" directory
-  nsCOMPtr<nsIFile> systemAppDir = new nsLocalFile();
-  systemAppDir->InitWithFile(appsDir);
-  systemAppDir->Append(NS_LITERAL_STRING("system"));
-
-  bool hasSystemAppDir = EnsureIsDirectory(systemAppDir);
-  if (!hasSystemAppDir) {
-    nsCString path; appsDir->GetNativePath(path);
-    // We don't want to continue if the apps path does not exists ...
-    printf_stderr("!!! Gaia chrome package is not a directory: %s\n", path.get());
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-GaiaChrome::Register()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(nsChromeRegistry::gChromeRegistry != nullptr);
-
-  nsCOMPtr<nsIFile> aPath = new nsLocalFile();
-  nsresult rv = ComputeAppsPath(aPath);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  FileLocation appsLocation(aPath);
-  nsCString uri;
-  appsLocation.GetURIString(uri);
-
-  char* argv[2];
-  argv[0] = (char*)mPackageName.get();
-  argv[1] = (char*)uri.get();
-
-  nsChromeRegistry::ManifestProcessingContext cx(NS_APP_LOCATION, appsLocation);
-  nsChromeRegistry::gChromeRegistry->ManifestContent(cx, 0, argv, 0);
-
-  return NS_OK;
-}
-
-already_AddRefed<GaiaChrome>
-GaiaChrome::FactoryCreate()
-{
-  if (!XRE_IsParentProcess()) {
-    return nullptr;
-  }
-
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!gGaiaChrome) {
-    gGaiaChrome = new GaiaChrome();
-    ClearOnShutdown(&gGaiaChrome);
-  }
-
-  RefPtr<GaiaChrome> service = gGaiaChrome.get();
-  return service.forget();
-}
-
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(GaiaChrome,
-                                         GaiaChrome::FactoryCreate)
-
-NS_DEFINE_NAMED_CID(NS_GAIACHROME_CID);
-
-static const mozilla::Module::CIDEntry kGaiaChromeCIDs[] = {
-  { &kNS_GAIACHROME_CID, false, nullptr, GaiaChromeConstructor },
-  { nullptr }
-};
-
-static const mozilla::Module::ContractIDEntry kGaiaChromeContracts[] = {
-  { "@mozilla.org/b2g/gaia-chrome;1", &kNS_GAIACHROME_CID },
-  { nullptr }
-};
-
-static const mozilla::Module::CategoryEntry kGaiaChromeCategories[] = {
-  { "profile-after-change", "Gaia Chrome Registration", GAIACHROME_CONTRACTID },
-  { nullptr }
-};
-
-static const mozilla::Module kGaiaChromeModule = {
-  mozilla::Module::kVersion,
-  kGaiaChromeCIDs,
-  kGaiaChromeContracts,
-  kGaiaChromeCategories
-};
-
-NSMODULE_DEFN(GaiaChromeModule) = &kGaiaChromeModule;
deleted file mode 100644
--- a/b2g/components/GaiaChrome.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __GAIACHROME_H__
-#define __GAIACHROME_H__
-
-#include "nsIGaiaChrome.h"
-
-#include "nsIFile.h"
-
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
-using namespace mozilla;
-
-class GaiaChrome final : public nsIGaiaChrome
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIGAIACHROME
-
-  static already_AddRefed<GaiaChrome>
-  FactoryCreate();
-
-private:
-  nsCString mPackageName;
-
-  nsAutoString mAppsDir;
-  nsAutoString mDataRoot;
-  nsAutoString mSystemRoot;
-
-  nsCOMPtr<nsIFile> mProfDir;
-
-  GaiaChrome();
-  ~GaiaChrome();
-
-  nsresult ComputeAppsPath(nsIFile*);
-  bool EnsureIsDirectory(nsIFile*);
-  nsresult EnsureValidPath(nsIFile*);
-  nsresult GetProfileDir();
-};
-
-#endif  // __GAIACHROME_H__
--- a/b2g/components/SafeMode.jsm
+++ b/b2g/components/SafeMode.jsm
@@ -5,16 +5,17 @@
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["SafeMode"];
 
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/AppConstants.jsm");
+Cu.import("resource://gre/modules/Webapps.jsm");
 
 const kSafeModePref = "b2g.safe_mode";
 const kSafeModePage = "safe_mode.html";
 
 function debug(aStr) {
   //dump("-*- SafeMode: " + aStr + "\n");
 }
 
@@ -62,80 +63,81 @@ this.SafeMode = {
     let isSafeMode = Services.prefs.getCharPref(kSafeModePref) === "yes";
     if (!isSafeMode) {
       return Promise.resolve();
     }
     debug("Starting in Safe Mode!");
 
     // Load $system_app/safe_mode.html as a full screen iframe, and wait for
     // the user to make a choice.
-    let shell = SafeMode.window.shell;
-    let document = SafeMode.window.document;
-    SafeMode.window.screen.mozLockOrientation("portrait");
-
-    let url = Services.io.newURI(shell.homeURL, null, null)
-                         .resolve(kSafeModePage);
-    debug("Registry is ready, loading " + url);
-    let frame = document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
-    frame.setAttribute("mozbrowser", "true");
-    frame.setAttribute("mozapp", shell.manifestURL);
-    frame.setAttribute("id", "systemapp"); // To keep screen.js happy.
-    let contentBrowser = document.body.appendChild(frame);
+    return DOMApplicationRegistry.registryReady.then(() => {
+      let shell = SafeMode.window.shell;
+      let document = SafeMode.window.document;
+      SafeMode.window.screen.mozLockOrientation("portrait");
 
-    return new Promise((aResolve, aReject) => {
-      let content = contentBrowser.contentWindow;
+      let url = Services.io.newURI(shell.homeURL, null, null)
+                           .resolve(kSafeModePage);
+      debug("Registry is ready, loading " + url);
+      let frame = document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
+      frame.setAttribute("mozbrowser", "true");
+      frame.setAttribute("mozapp", shell.manifestURL);
+      frame.setAttribute("id", "systemapp"); // To keep screen.js happy.
+      let contentBrowser = document.body.appendChild(frame);
 
-      // Stripped down version of the system app bootstrap.
-      function handleEvent(e) {
-        switch(e.type) {
-          case "mozbrowserloadstart":
-            if (content.document.location == "about:blank") {
-              contentBrowser.addEventListener("mozbrowserlocationchange", handleEvent, true);
-              contentBrowser.removeEventListener("mozbrowserloadstart", handleEvent, true);
-              return;
-            }
+      return new Promise((aResolve, aReject) => {
+        let content = contentBrowser.contentWindow;
+
+        // Stripped down version of the system app bootstrap.
+        function handleEvent(e) {
+          switch(e.type) {
+            case "mozbrowserloadstart":
+              if (content.document.location == "about:blank") {
+                contentBrowser.addEventListener("mozbrowserlocationchange", handleEvent, true);
+                contentBrowser.removeEventListener("mozbrowserloadstart", handleEvent, true);
+                return;
+              }
 
-            notifyContentStart();
-            break;
-          case "mozbrowserlocationchange":
-            if (content.document.location == "about:blank") {
-              return;
-            }
+              notifyContentStart();
+              break;
+            case "mozbrowserlocationchange":
+              if (content.document.location == "about:blank") {
+                return;
+              }
 
-            contentBrowser.removeEventListener("mozbrowserlocationchange", handleEvent, true);
-            notifyContentStart();
-            break;
-          case "mozContentEvent":
-            content.removeEventListener("mozContentEvent", handleEvent, true);
-            contentBrowser.parentNode.removeChild(contentBrowser);
+              contentBrowser.removeEventListener("mozbrowserlocationchange", handleEvent, true);
+              notifyContentStart();
+              break;
+            case "mozContentEvent":
+              content.removeEventListener("mozContentEvent", handleEvent, true);
+              contentBrowser.parentNode.removeChild(contentBrowser);
 
-            if (e.detail == "safemode-yes")  {
-              // Really starting in safe mode, let's disable add-ons first.
-              // TODO: disable add-ons
-              aResolve();
-            } else {
-              aResolve();
-            }
-            break;
+              if (e.detail == "safemode-yes")  {
+                // Really starting in safe mode, let's disable add-ons first.
+                DOMApplicationRegistry.disableAllAddons().then(aResolve);
+              } else {
+                aResolve();
+              }
+              break;
+          }
         }
-      }
 
-      function notifyContentStart() {
-        let window = SafeMode.window;
-        window.shell.sendEvent(window, "SafeModeStart");
-        contentBrowser.setVisible(true);
+        function notifyContentStart() {
+          let window = SafeMode.window;
+          window.shell.sendEvent(window, "SafeModeStart");
+          contentBrowser.setVisible(true);
 
-        // browser-ui-startup-complete is used by the AppShell to stop the
-        // boot animation and start gecko rendering.
-        Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
-        content.addEventListener("mozContentEvent", handleEvent, true);
-      }
+          // browser-ui-startup-complete is used by the AppShell to stop the
+          // boot animation and start gecko rendering.
+          Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
+          content.addEventListener("mozContentEvent", handleEvent, true);
+        }
 
-      contentBrowser.addEventListener("mozbrowserloadstart", handleEvent, true);
-      contentBrowser.src = url;
+        contentBrowser.addEventListener("mozbrowserloadstart", handleEvent, true);
+        contentBrowser.src = url;
+      });
     });
   },
 
   // Returns a Promise that resolves once we have decided to run in safe mode
   // or not. All the safe mode switching actions happen before resolving the
   // promise.
   check: function(aWindow) {
     debug("check");
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -74,23 +74,12 @@ EXTRA_JS_MODULES += [
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
     EXTRA_JS_MODULES += [
       'GlobalSimulatorScreen.jsm'
     ]
 
 XPIDL_SOURCES += [
-    'nsIGaiaChrome.idl',
     'nsISystemMessagesInternal.idl'
 ]
 
 XPIDL_MODULE = 'gaia_chrome'
-
-UNIFIED_SOURCES += [
-    'GaiaChrome.cpp'
-]
-
-LOCAL_INCLUDES += [
-    '/chrome'
-]
-
-FINAL_LIBRARY = 'xul'
deleted file mode 100644
--- a/b2g/components/nsIGaiaChrome.idl
+++ /dev/null
@@ -1,15 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(92a18a98-ab5d-4d02-a024-bdbb3bc89ce1)]
-interface nsIGaiaChrome : nsISupports
-{
-    void register();
-};
-
-%{ C++
-#define GAIACHROME_CONTRACTID "@mozilla.org/b2g/gaia-chrome;1"
-%}
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -226,17 +226,16 @@
 @RESPATH@/components/exthelper.xpt
 @RESPATH@/components/fastfind.xpt
 @RESPATH@/components/feeds.xpt
 #ifdef MOZ_GTK
 @RESPATH@/components/filepicker.xpt
 #endif
 @RESPATH@/components/find.xpt
 @RESPATH@/components/gfx.xpt
-@RESPATH@/components/gaia_chrome.xpt
 @RESPATH@/components/hal.xpt
 @RESPATH@/components/html5.xpt
 @RESPATH@/components/htmlparser.xpt
 @RESPATH@/components/identity.xpt
 @RESPATH@/components/imglib2.xpt
 @RESPATH@/components/inspector.xpt
 @RESPATH@/components/intl.xpt
 @RESPATH@/components/jar.xpt
--- a/caps/tests/mochitest/chrome.ini
+++ b/caps/tests/mochitest/chrome.ini
@@ -4,9 +4,9 @@ support-files =
   file_disableScript.html
   !/caps/tests/mochitest/file_disableScript.html
 
 [test_bug995943.xul]
 [test_addonMayLoad.html]
 [test_disableScript.xul]
 [test_principal_jarprefix_origin_appid_appstatus.html]
 # jarPrefix test doesn't work on Windows, see bug 776296.
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = os == "win"
--- a/devtools/shared/apps/tests/mochitest.ini
+++ b/devtools/shared/apps/tests/mochitest.ini
@@ -1,7 +1,7 @@
 [DEFAULT]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = (buildapp != 'b2g' && buildapp != 'mulet')
 support-files =
   debugger-protocol-helper.js
   redirect.sjs
 
 [test_webapps_actor.html]
--- a/dom/apps/AppsServiceChild.jsm
+++ b/dom/apps/AppsServiceChild.jsm
@@ -104,17 +104,17 @@ this.DOMApplicationRegistry = {
     }).bind(this));
 
     this.cpmm.sendAsyncMessage("Webapps:RegisterForMessages", {
       messages: APPS_IPC_MSG_NAMES
     });
 
     // We need to prime the cache with the list of apps.
     let list = this.cpmm.sendSyncMessage("Webapps:GetList", { })[0];
-    this.webapps = list ? list.webapps : { };
+    this.webapps = list.webapps;
     // We need a fast mapping from localId -> app, so we add an index.
     // We also add the manifest to the app object.
     this.localIdIndex = { };
     for (let id in this.webapps) {
       let app = this.webapps[id];
       this.localIdIndex[app.localId] = app;
       app.manifest = list.manifests[id];
     }
--- a/dom/apps/PermissionsTable.jsm
+++ b/dom/apps/PermissionsTable.jsm
@@ -497,22 +497,16 @@ this.PermissionsTable =  { geolocation: 
                               trusted: DENY_ACTION,
                               privileged: ALLOW_ACTION,
                               certified: ALLOW_ACTION
                            },
                            "system-app-only-audio-channels-in-app": {
                              app: DENY_ACTION,
                              privileged: DENY_ACTION,
                              certified: ALLOW_ACTION
-                           },
-                           "previously-certified-app": {
-                             app: DENY_ACTION,
-                             trusted: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
                            }
                          };
 
 /**
  * Append access modes to the permission name as suffixes.
  *   e.g. permission name 'contacts' with ['read', 'write'] =
  *   ['contacts-read', contacts-write']
  * @param string aPermName
--- a/dom/apps/Webapps.jsm
+++ b/dom/apps/Webapps.jsm
@@ -4809,10 +4809,9 @@ AppcacheObserver.prototype = {
     }
   },
 
   applicationCacheAvailable: function appObs_CacheAvail(aApplicationCache) {
     // Nothing to do.
   }
 };
 
-// FIXME: Properly remove Cu.import(Webapps.jsm) from every place.
-//DOMApplicationRegistry.init();
+DOMApplicationRegistry.init();
--- a/dom/apps/tests/mochitest.ini
+++ b/dom/apps/tests/mochitest.ini
@@ -1,10 +1,10 @@
 [DEFAULT]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp != 'b2g' && buildapp != 'mulet'
 support-files =
   addons/application.zip
   addons/invalid.webapp
   addons/invalid.webapp^headers^
   addons/update.webapp
   addons/update.webapp^headers^
   addons/index.html
   chromeAddCert.js
--- a/dom/broadcastchannel/tests/mochitest.ini
+++ b/dom/broadcastchannel/tests/mochitest.ini
@@ -16,15 +16,15 @@ support-files =
 [test_broadcastchannel_basic.html]
 [test_broadcastchannel_close.html]
 [test_broadcastchannel_close2.html]
 [test_broadcastchannel_self.html]
 [test_broadcastchannel_sharedWorker.html]
 [test_broadcastchannel_worker.html]
 [test_broadcastchannel_worker_alive.html]
 [test_broadcastchannel_mozbrowser.html]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp != 'mulet'
 [test_broadcastchannel_mozbrowser2.html]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp != 'mulet'
 [test_bfcache.html]
 [test_invalidState.html]
 [test_ordering.html]
 [test_dataCloning.html]
--- a/dom/cache/test/mochitest/mochitest.ini
+++ b/dom/cache/test/mochitest/mochitest.ini
@@ -37,13 +37,13 @@ support-files =
 [test_cache_requestCache.html]
 [test_cache_delete.html]
 [test_cache_put_reorder.html]
 [test_cache_https.html]
   skip-if = buildapp == 'b2g' # bug 1162353
 [test_cache_restart.html]
 [test_cache_shrink.html]
 [test_cache_clear_on_app_uninstall.html]
-  skip-if = true || e10s # bug 1178685 ### Bug 1255339: blacklist because no more mozApps
+  skip-if = buildapp != 'mulet' || e10s # bug 1178685
 [test_cache_orphaned_cache.html]
 [test_cache_orphaned_body.html]
 [test_cache_untrusted.html]
 [test_chrome_constructor.html]
--- a/dom/indexedDB/test/mochitest.ini
+++ b/dom/indexedDB/test/mochitest.ini
@@ -379,19 +379,19 @@ skip-if = (buildapp == 'b2g' && toolkit 
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_transaction_ordering.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_unique_index_update.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_webapp_clearBrowserData_inproc_inproc.html]
 # The clearBrowserData tests are only supposed to run in the main process.
 # They currently time out on android.
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp == 'b2g' || e10s || toolkit == 'android'
 [test_webapp_clearBrowserData_inproc_oop.html]
 # The clearBrowserData tests are only supposed to run in the main process.
 # They currently time out on android.
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp == 'b2g' || e10s || toolkit == 'android'
 [test_webapp_clearBrowserData_oop_inproc.html]
 # The clearBrowserData tests are only supposed to run in the main process.
 # They currently time out on android.
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp == 'b2g' || e10s || toolkit == 'android'
 [test_serviceworker.html]
 skip-if = buildapp == 'b2g'
--- a/dom/ipc/tests/mochitest.ini
+++ b/dom/ipc/tests/mochitest.ini
@@ -17,43 +17,43 @@ skip-if = buildapp == 'b2g' || buildapp 
 skip-if = toolkit != 'gonk'
 [test_NuwaProcessDeadlock.html]
 skip-if = toolkit != 'gonk'
 [test_child_docshell.html]
 skip-if = toolkit == 'cocoa' # disabled due to hangs, see changeset 6852e7c47edf
 [test_CrashService_crash.html]
 skip-if = !(crashreporter && !e10s && (toolkit == 'gtk2' || toolkit == 'gtk3' || toolkit == 'cocoa' || toolkit == 'windows') && (buildapp != 'b2g' || toolkit == 'gonk') && (buildapp != 'mulet')) # TC: Bug 1144079 - Re-enable Mulet mochitests and reftests taskcluster-specific disables.
 [test_permission_for_in_process_app.html]
-skip-if = e10s || true || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app  ### Bug 1255339: blacklist because no more mozApps
+skip-if = e10s || (buildapp != 'b2g' && buildapp != 'mulet') || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
 support-files =
   test_permission_helper.js
 [test_permission_for_oop_app.html]
-skip-if = true || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app  ### Bug 1255339: blacklist because no more mozApps
+skip-if = (buildapp != 'b2g' && buildapp != 'mulet') || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
 support-files =
   file_app.sjs
   file_app.template.webapp
   test_permission_helper.js
   test_permission_embed.html
   test_permission_framescript.js
 [test_permission_for_nested_oop_app.html]
-skip-if = true || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app  ### Bug 1255339: blacklist because no more mozApps
+skip-if = (buildapp != 'b2g' && buildapp != 'mulet') || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
 support-files =
   file_app.sjs
   file_app.template.webapp
   test_permission_helper.js
   test_permission_embed.html
   test_permission_framescript.js
 [test_permission_for_two_oop_apps.html]
-skip-if = true || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app  ### Bug 1255339: blacklist because no more mozApps
+skip-if = (buildapp != 'b2g' && buildapp != 'mulet') || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
 support-files =
   file_app.sjs
   file_app.template.webapp
   test_permission_helper.js
   test_permission_embed.html
   test_permission_framescript.js
 [test_permission_when_oop_app_crashes.html]
-skip-if = true || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app  ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp != 'b2g' || os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
 support-files =
   file_app.sjs
   file_app.template.webapp
   test_permission_helper.js
   test_permission_embed.html
   test_permission_framescript.js
--- a/dom/security/test/csp/chrome.ini
+++ b/dom/security/test/csp/chrome.ini
@@ -1,7 +1,7 @@
 [DEFAULT]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp == 'b2g' || os == 'android'
 support-files =
   !/dom/security/test/csp/file_bug768029.html
 
 [test_bug768029.html]
 [test_bug773891.html]
--- a/dom/security/test/csp/mochitest.ini
+++ b/dom/security/test/csp/mochitest.ini
@@ -215,17 +215,17 @@ skip-if = (buildapp == 'b2g' && (toolkit
 skip-if = buildapp == 'b2g' # http-on-opening-request observers are not available in child processes
 [test_hash_source.html]
 skip-if = buildapp == 'b2g' # can't compute hashes in child process (bug 958702)
 [test_scheme_relative_sources.html]
 skip-if = buildapp == 'b2g' #no ssl support
 [test_ignore_unsafe_inline.html]
 [test_self_none_as_hostname_confusion.html]
 [test_bug949549.html]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp != 'b2g' && buildapp != 'mulet'
 [test_path_matching.html]
 [test_path_matching_redirect.html]
 [test_report_uri_missing_in_report_only_header.html]
 [test_report.html]
 [test_301_redirect.html]
 skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490)
 [test_302_redirect.html]
 skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490)
--- a/dom/tests/mochitest/fetch/mochitest.ini
+++ b/dom/tests/mochitest/fetch/mochitest.ini
@@ -30,17 +30,17 @@ support-files =
   !/dom/html/test/form_submit_server.sjs
   !/dom/security/test/cors/file_CrossSiteXHR_server.sjs
 
 [test_headers.html]
 [test_headers_sw_reroute.html]
 skip-if = buildapp == 'b2g' # Bug 1137683
 [test_headers_mainthread.html]
 [test_fetch_app_protocol.html]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = (buildapp != 'b2g' && buildapp != 'mulet')
 [test_fetch_basic.html]
 [test_fetch_basic_sw_reroute.html]
 skip-if = buildapp == 'b2g' # Bug 1137683
 [test_fetch_basic_sw_empty_reroute.html]
 skip-if = buildapp == 'b2g'
 [test_fetch_basic_http.html]
 [test_fetch_basic_http_sw_reroute.html]
 skip-if = buildapp == 'b2g' # Bug 1137683
--- a/dom/tests/mochitest/localstorage/mochitest.ini
+++ b/dom/tests/mochitest/localstorage/mochitest.ini
@@ -14,17 +14,17 @@ support-files =
   frameSlaveNotEqual.html
   interOriginFrame.js
   interOriginTest.js
   interOriginTest2.js
   localStorageCommon.js
   frameLocalStorageSessionOnly.html
 
 [test_appIsolation.html]
-skip-if = true || buildapp == 'b2g' || buildapp == 'mulet' || toolkit == 'android' || e10s #bug 793211 # b2g(needs https to work) b2g-debug(needs https to work) b2g-desktop(needs https to work) ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #bug 793211 # b2g(needs https to work) b2g-debug(needs https to work) b2g-desktop(needs https to work)
 [test_brokenUTF-16.html]
 [test_bug600307-DBOps.html]
 [test_bug746272-1.html]
 [test_bug746272-2.html]
 skip-if = os == "android" || toolkit == 'gonk' # bug 962029
 [test_cookieBlock.html]
 skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(bug 913706) b2g-desktop(bug 913706)
 [test_cookieSession.html]
--- a/extensions/cookie/test/chrome.ini
+++ b/extensions/cookie/test/chrome.ini
@@ -1,10 +1,10 @@
 [DEFAULT]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp == 'b2g' || os == 'android'
 support-files = channel_utils.js
 
 [test_app_uninstall_cookies.html]
 skip-if = buildapp != 'mulet'
 [test_app_uninstall_permissions.html]
 skip-if = buildapp != 'mulet'
 
 [test_permissionmanager_app_isolation.html]
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -26,18 +26,18 @@
 #include "mozilla/dom/Promise.h"
 
 #include "nsDOMMutationObserver.h"
 #include "nsICycleCollectorListener.h"
 #include "mozilla/XPTInterfaceInfoManager.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsScriptSecurityManager.h"
-#include "nsIPermissionManager.h"
 #include "nsContentUtils.h"
+
 #include "jsfriendapi.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace xpc;
 using namespace JS;
 
 NS_IMPL_ISUPPORTS(nsXPConnect, nsIXPConnect)
@@ -437,23 +437,17 @@ InitGlobalObjectOptions(JS::CompartmentO
     if (isSystem) {
         // Make sure [SecureContext] APIs are visible:
         aOptions.creationOptions().setSecureContext(true);
     }
 
     short status = aPrincipal->GetAppStatus();
 
     // Enable the ECMA-402 experimental formatToParts in certified apps.
-    uint32_t perm = nsIPermissionManager::DENY_ACTION;
-    nsCOMPtr<nsIPermissionManager> permissionManager = services::GetPermissionManager();
-    if (permissionManager) {
-        permissionManager->TestPermissionFromPrincipal(aPrincipal, "previously-certified-app", &perm);
-    }
-
-    if (perm == nsIPermissionManager::ALLOW_ACTION) {
+    if (status == nsIPrincipal::APP_STATUS_CERTIFIED) {
         aOptions.creationOptions()
                 .setExperimentalDateTimeFormatFormatToPartsEnabled(true);
     }
 
     if (shouldDiscardSystemSource) {
         bool discardSource = isSystem ||
                              (status == nsIPrincipal::APP_STATUS_PRIVILEGED ||
                               status == nsIPrincipal::APP_STATUS_CERTIFIED);
--- a/netwerk/test/mochitests/mochitest.ini
+++ b/netwerk/test/mochitests/mochitest.ini
@@ -20,13 +20,13 @@ support-files =
 [test_rel_preconnect.html]
 [test_uri_scheme.html]
 [test_user_agent_overrides.html]
 [test_user_agent_updates.html]
 [test_user_agent_updates_reset.html]
 [test_viewsource_unlinkable.html]
 [test_xhr_method_case.html]
 [test_web_packaged_app.html]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp != 'mulet'
 [test_loadinfo_redirectchain.html]
 skip-if = buildapp == 'b2g' #no ssl support
 [test_idn_redirect.html]
 [test_redirect_ref.html]
--- a/testing/mochitest/tests/Harness_sanity/mochitest.ini
+++ b/testing/mochitest/tests/Harness_sanity/mochitest.ini
@@ -17,30 +17,30 @@ support-files = empty.js
 [test_sanityWindowSnapshot.html]
 [test_SpecialPowersExtension.html]
 [test_SpecialPowersExtension2.html]
 support-files = file_SpecialPowersFrame1.html
 [test_SpecialPowersPushPermissions.html]
 support-files =
     specialPowers_framescript.js
 [test_SpecialPowersPushAppPermissions.html]
-skip-if = true ### Bug 1255339: blacklist because no more mozApps
+skip-if = buildapp != 'mulet'
 support-files =
     file_app.sjs
     file_app.template.webapp
     app.html
 [test_SpecialPowersPushPrefEnv.html]
 [test_SimpletestGetTestFileURL.html]
 [test_SpecialPowersLoadChromeScript.html]
 support-files = SpecialPowersLoadChromeScript.js
 [test_SpecialPowersLoadChromeScript_function.html]
 [test_SpecialPowersLoadPrivilegedScript.html]
 [test_bug649012.html]
 [test_bug816847.html]
-skip-if = true || toolkit == 'android' || buildapp == 'b2g' || buildapp == 'mulet' || e10s #No test app installed ### Bug 1255339: blacklist because no more mozApps
+skip-if = toolkit == 'android' || e10s #No test app installed
 [test_sanity_cleanup.html]
 [test_sanity_cleanup2.html]
 [test_sanityEventUtils.html]
 skip-if = buildapp == 'mulet' || toolkit == 'android' #bug 688052
 [test_sanitySimpletest.html]
 subsuite = clipboard
 skip-if = toolkit == 'android' #bug 688052
 [test_sanity_manifest.html]