Bug 1443964: Part 2 - Remove most add-on compatibility shims. r?mconley draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 07 Mar 2018 12:16:37 -0800
changeset 764701 b7d420ea167474f574a2a790a792754474ae3126
parent 764654 001266824b28a4323bafcd548dd74e1b73895ddb
child 764702 3ce5cfda782db70e80f0530a48ce54f343bd42ba
child 764722 2695a235be9118b48223dc26720964ceb69ff9af
push id101827
push usermaglione.k@gmail.com
push dateThu, 08 Mar 2018 02:14:42 +0000
reviewersmconley
bugs1443964
milestone60.0a1
Bug 1443964: Part 2 - Remove most add-on compatibility shims. r?mconley The TabBrowser.addProgressListener shim is the only remaining exception, since the browser_google_behavior.js non-trivially relies on it. MozReview-Commit-ID: Cc2ARwLkjTA
js/xpconnect/src/Sandbox.cpp
toolkit/components/addoncompat/CompatWarning.jsm
toolkit/components/addoncompat/RemoteAddonsChild.jsm
toolkit/components/addoncompat/RemoteAddonsParent.jsm
toolkit/components/addoncompat/moz.build
toolkit/components/addoncompat/multiprocessShims.js
toolkit/components/addoncompat/tests/addon/bootstrap.js
toolkit/components/addoncompat/tests/addon/chrome.manifest
toolkit/components/addoncompat/tests/addon/content/page.html
toolkit/components/addoncompat/tests/addon/install.rdf
toolkit/components/addoncompat/tests/browser/.eslintrc.js
toolkit/components/addoncompat/tests/browser/addon.xpi
toolkit/components/addoncompat/tests/browser/browser.ini
toolkit/components/addoncompat/tests/browser/browser_addonShims.js
toolkit/components/addoncompat/tests/browser/browser_addonShims_testpage.html
toolkit/components/addoncompat/tests/browser/browser_addonShims_testpage2.html
toolkit/components/addoncompat/tests/browser/compat-addon.xpi
toolkit/components/addoncompat/tests/compat-addon/bootstrap.js
toolkit/components/addoncompat/tests/compat-addon/install.rdf
toolkit/components/addoncompat/tests/moz.build
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -1139,19 +1139,21 @@ xpc::CreateSandboxObject(JSContext* cx, 
 
     // Try to figure out any addon this sandbox should be associated with.
     // The addon could have been passed in directly, as part of the metadata,
     // or by being constructed from an addon's code.
     JSAddonId* addonId = nullptr;
     if (options.addonId) {
         addonId = JS::NewAddonId(cx, options.addonId);
         NS_ENSURE_TRUE(addonId, NS_ERROR_FAILURE);
-    } else if (JSObject* obj = JS::CurrentGlobalOrNull(cx)) {
-        if (JSAddonId* id = JS::AddonIdOfObject(obj))
-            addonId = id;
+    } else if (principal == nsXPConnect::SystemPrincipal()) {
+        if (JSObject* obj = JS::CurrentGlobalOrNull(cx)) {
+            if (JSAddonId* id = JS::AddonIdOfObject(obj))
+                addonId = id;
+        }
     }
 
     creationOptions.setAddonId(addonId);
 
     compartmentOptions.behaviors().setDiscardSource(options.discardSource);
 
     const js::Class* clasp = options.writeToGlobalPrototype
                              ? &SandboxWriteToProtoClass
deleted file mode 100644
--- a/toolkit/components/addoncompat/CompatWarning.jsm
+++ /dev/null
@@ -1,99 +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/.
-
-var EXPORTED_SYMBOLS = ["CompatWarning"];
-
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/Preferences.jsm");
-
-function section(number, url) {
-  const baseURL = "https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Limitations_of_chrome_scripts";
-  return { number, url: baseURL + url };
-}
-
-var CompatWarning = {
-  // Sometimes we want to generate a warning, but put off issuing it
-  // until later. For example, if someone registers a listener, we
-  // might only want to warn about it if the listener actually
-  // fires. However, we want the warning to show a stack for the
-  // registration site.
-  delayedWarning(msg, addon, warning) {
-    function isShimLayer(filename) {
-      return filename.includes("CompatWarning.jsm") ||
-        filename.includes("RemoteAddonsParent.jsm") ||
-        filename.includes("RemoteAddonsChild.jsm") ||
-        filename.includes("multiprocessShims.js");
-    }
-
-    let stack = Components.stack;
-    while (stack && isShimLayer(stack.filename))
-      stack = stack.caller;
-
-    let alreadyWarned = false;
-
-    return function() {
-      if (alreadyWarned) {
-        return;
-      }
-      alreadyWarned = true;
-
-      if (addon) {
-        let histogram = Services.telemetry.getKeyedHistogramById("ADDON_SHIM_USAGE");
-        histogram.add(addon, warning ? warning.number : 0);
-      }
-
-      if (!Preferences.get("dom.ipc.shims.enabledWarnings", false))
-        return;
-
-      let error = Cc["@mozilla.org/scripterror;1"].createInstance(Ci.nsIScriptError);
-      if (!error || !Services.console) {
-        // Too late during shutdown to use the nsIConsole
-        return;
-      }
-
-      let message = `Warning: ${msg}`;
-      if (warning)
-        message += `\nMore info at: ${warning.url}`;
-
-      error.init(
-                 /* message*/ message,
-                 /* sourceName*/ stack ? stack.filename : "",
-                 /* sourceLine*/ stack ? stack.sourceLine : "",
-                 /* lineNumber*/ stack ? stack.lineNumber : 0,
-                 /* columnNumber*/ 0,
-                 /* flags*/ Ci.nsIScriptError.warningFlag,
-                 /* category*/ "chrome javascript");
-      Services.console.logMessage(error);
-
-      if (Preferences.get("dom.ipc.shims.dumpWarnings", false)) {
-        dump(message + "\n");
-        while (stack) {
-          dump(stack + "\n");
-          stack = stack.caller;
-        }
-        dump("\n");
-      }
-    };
-  },
-
-  warn(msg, addon, warning) {
-    let delayed = this.delayedWarning(msg, addon, warning);
-    delayed();
-  },
-
-  warnings: {
-    content: section(1, "#gBrowser.contentWindow.2C_window.content..."),
-    limitations_of_CPOWs: section(2, "#Limitations_of_CPOWs"),
-    nsIContentPolicy: section(3, "#nsIContentPolicy"),
-    nsIWebProgressListener: section(4, "#nsIWebProgressListener"),
-    observers: section(5, "#Observers_in_the_chrome_process"),
-    DOM_events: section(6, "#DOM_Events"),
-    sandboxes: section(7, "#Sandboxes"),
-    JSMs: section(8, "#JavaScript_code_modules_(JSMs)"),
-    nsIAboutModule: section(9, "#nsIAboutModule"),
-    // If more than 14 values appear here, you need to change the
-    // ADDON_SHIM_USAGE histogram definition in Histograms.json.
-  },
-};
--- a/toolkit/components/addoncompat/RemoteAddonsChild.jsm
+++ b/toolkit/components/addoncompat/RemoteAddonsChild.jsm
@@ -1,32 +1,16 @@
 // 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/.
 
 var EXPORTED_SYMBOLS = ["RemoteAddonsChild"];
 
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-ChromeUtils.defineModuleGetter(this, "BrowserUtils",
-                               "resource://gre/modules/BrowserUtils.jsm");
-ChromeUtils.defineModuleGetter(this, "Prefetcher",
-                               "resource://gre/modules/Prefetcher.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "SystemPrincipal",
-                                   "@mozilla.org/systemprincipal;1", "nsIPrincipal");
-
-XPCOMUtils.defineLazyServiceGetter(this, "contentSecManager",
-                                   "@mozilla.org/contentsecuritymanager;1",
-                                   "nsIContentSecurityManager");
-
-const TELEMETRY_SHOULD_LOAD_LOADING_KEY = "ADDON_CONTENT_POLICY_SHIM_BLOCKING_LOADING_MS";
-const TELEMETRY_SHOULD_LOAD_LOADED_KEY = "ADDON_CONTENT_POLICY_SHIM_BLOCKING_LOADED_MS";
-
 // Similar to Python. Returns dict[key] if it exists. Otherwise,
 // sets dict[key] to default_ and returns default_.
 function setDefault(dict, key, default_) {
   if (key in dict) {
     return dict[key];
   }
   dict[key] = default_;
   return default_;
@@ -139,502 +123,37 @@ var NotificationTracker = {
     this._registered.delete(watcher);
   },
 
   getCount(component1) {
     return this.findPaths([component1]).length;
   },
 };
 
-// This code registers an nsIContentPolicy in the child process. When
-// it runs, it notifies the parent that it needs to run its own
-// nsIContentPolicy list. If any policy in the parent rejects a
-// resource load, that answer is returned to the child.
-var ContentPolicyChild = {
-  _classDescription: "Addon shim content policy",
-  _classID: Components.ID("6e869130-635c-11e2-bcfd-0800200c9a66"),
-  _contractID: "@mozilla.org/addon-child/policy;1",
-
-  // A weak map of time spent blocked in hooks for a given document.
-  // WeakMap[document -> Map[addonId -> timeInMS]]
-  timings: new WeakMap(),
-
-  init() {
-    let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-    registrar.registerFactory(this._classID, this._classDescription, this._contractID, this);
-
-    this.loadingHistogram = Services.telemetry.getKeyedHistogramById(TELEMETRY_SHOULD_LOAD_LOADING_KEY);
-    this.loadedHistogram = Services.telemetry.getKeyedHistogramById(TELEMETRY_SHOULD_LOAD_LOADED_KEY);
-
-    NotificationTracker.watch("content-policy", this);
-  },
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver,
-                                         Ci.nsIChannelEventSink, Ci.nsIFactory,
-                                         Ci.nsISupportsWeakReference]),
-
-  track(path, register) {
-    let catMan = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
-    if (register) {
-      catMan.addCategoryEntry("content-policy", this._contractID, this._contractID, false, true);
-    } else {
-      catMan.deleteCategoryEntry("content-policy", this._contractID, false);
-    }
-  },
-
-  // Returns a map of cumulative time spent in shouldLoad hooks for a
-  // given add-on in the given node's document. May return null if
-  // telemetry recording is disabled, or the given context does not
-  // point to a document.
-  getTimings(context) {
-    if (!Services.telemetry.canRecordExtended) {
-      return null;
-    }
-
-    let doc;
-    if (context instanceof Ci.nsIDOMNode) {
-      doc = context.ownerDocument;
-    } else if (context instanceof Ci.nsIDOMDocument) {
-      doc = context;
-    } else if (context instanceof Ci.nsIDOMWindow) {
-      doc = context.document;
-    }
-
-    if (!doc) {
-      return null;
-    }
-
-    let map = this.timings.get(doc);
-    if (!map) {
-      // No timing object exists for this document yet. Create one, and
-      // set up a listener to record the final values at the right time.
-      map = new Map();
-      this.timings.set(doc, map);
-
-      // If the document is still loading, record aggregate pre-load
-      // timings when the load event fires. If it's already loaded,
-      // record aggregate post-load timings when the page is hidden.
-      let eventName = doc.readyState == "complete" ? "pagehide" : "load";
-
-      let listener = event => {
-        if (event.target == doc) {
-          event.currentTarget.removeEventListener(eventName, listener, true);
-          this.logTelemetry(doc, eventName);
-        }
-      };
-      doc.defaultView.addEventListener(eventName, listener, true);
-    }
-    return map;
-  },
-
-  // Logs the accumulated telemetry for the given document, into the
-  // appropriate telemetry histogram based on the DOM event name that
-  // triggered it.
-  logTelemetry(doc, eventName) {
-    let map = this.timings.get(doc);
-    this.timings.delete(doc);
-
-    let histogram = eventName == "load" ? this.loadingHistogram : this.loadedHistogram;
-
-    for (let [addon, time] of map.entries()) {
-      histogram.add(addon, time);
-    }
-  },
-
-  shouldLoad(contentType, contentLocation, requestOrigin,
-                       node, mimeTypeGuess, extra, requestPrincipal) {
-    let startTime = Cu.now();
-
-    let addons = NotificationTracker.findSuffixes(["content-policy"]);
-    let [prefetched, cpows] = Prefetcher.prefetch("ContentPolicy.shouldLoad",
-                                                  addons, {InitNode: node});
-    cpows.node = node;
-
-    let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-               .getService(Ci.nsISyncMessageSender);
-    let rval = cpmm.sendRpcMessage("Addons:ContentPolicy:Run", {
-      contentType,
-      contentLocation: contentLocation.spec,
-      requestOrigin: requestOrigin ? requestOrigin.spec : null,
-      mimeTypeGuess,
-      requestPrincipal,
-      prefetched,
-    }, cpows);
-
-    let timings = this.getTimings(node);
-    if (timings) {
-      let delta = Cu.now() - startTime;
-
-      for (let addon of addons) {
-        let old = timings.get(addon) || 0;
-        timings.set(addon, old + delta);
-      }
-    }
-
-    if (rval.length != 1) {
-      return Ci.nsIContentPolicy.ACCEPT;
-    }
-
-    return rval[0];
-  },
-
-  shouldProcess(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra) {
-    return Ci.nsIContentPolicy.ACCEPT;
-  },
-
-  createInstance(outer, iid) {
-    if (outer) {
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    }
-    return this.QueryInterface(iid);
-  },
-};
-
-// This is a shim channel whose only purpose is to return some string
-// data from an about: protocol handler.
-function AboutProtocolChannel(uri, contractID, loadInfo) {
-  this.URI = uri;
-  this.originalURI = uri;
-  this._contractID = contractID;
-  this._loadingPrincipal = loadInfo.loadingPrincipal;
-  this._securityFlags = loadInfo.securityFlags;
-  this._contentPolicyType = loadInfo.externalContentPolicyType;
-}
-
-AboutProtocolChannel.prototype = {
-  contentCharset: "utf-8",
-  contentLength: 0,
-  owner: SystemPrincipal,
-  securityInfo: null,
-  notificationCallbacks: null,
-  loadFlags: 0,
-  loadGroup: null,
-  name: null,
-  status: Cr.NS_OK,
-
-  asyncOpen(listener, context) {
-    // Ask the parent to synchronously read all the data from the channel.
-    let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-               .getService(Ci.nsISyncMessageSender);
-    let rval = cpmm.sendRpcMessage("Addons:AboutProtocol:OpenChannel", {
-      uri: this.URI.spec,
-      contractID: this._contractID,
-      loadingPrincipal: this._loadingPrincipal,
-      securityFlags: this._securityFlags,
-      contentPolicyType: this._contentPolicyType
-    }, {
-      notificationCallbacks: this.notificationCallbacks,
-      loadGroupNotificationCallbacks: this.loadGroup ? this.loadGroup.notificationCallbacks : null,
-    });
-
-    if (rval.length != 1) {
-      throw Cr.NS_ERROR_FAILURE;
-    }
-
-    let {data, contentType} = rval[0];
-    this.contentType = contentType;
-
-    // Return the data via an nsIStringInputStream.
-    let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
-    stream.setData(data, data.length);
-
-    let runnable = {
-      run: () => {
-        try {
-          listener.onStartRequest(this, context);
-        } catch (e) {}
-        try {
-          listener.onDataAvailable(this, context, stream, 0, stream.available());
-        } catch (e) {}
-        try {
-          listener.onStopRequest(this, context, Cr.NS_OK);
-        } catch (e) {}
-      }
-    };
-    Services.tm.dispatchToMainThread(runnable);
-  },
-
-  asyncOpen2(listener) {
-    // throws an error if security checks fail
-    var outListener = contentSecManager.performSecurityCheck(this, listener);
-    this.asyncOpen(outListener, null);
-  },
-
-  open() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  open2() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  isPending() {
-    return false;
-  },
-
-  cancel() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  suspend() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  resume() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
-};
-
-// This shim protocol handler is used when content fetches an about: URL.
-function AboutProtocolInstance(contractID) {
-  this._contractID = contractID;
-  this._uriFlags = undefined;
-}
-
-AboutProtocolInstance.prototype = {
-  createInstance(outer, iid) {
-    if (outer != null) {
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    }
-
-    return this.QueryInterface(iid);
-  },
-
-  getURIFlags(uri) {
-    // Cache the result to avoid the extra IPC.
-    if (this._uriFlags !== undefined) {
-      return this._uriFlags;
-    }
-
-    let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-               .getService(Ci.nsISyncMessageSender);
-
-    let rval = cpmm.sendRpcMessage("Addons:AboutProtocol:GetURIFlags", {
-      uri: uri.spec,
-      contractID: this._contractID
-    });
-
-    if (rval.length != 1) {
-      throw Cr.NS_ERROR_FAILURE;
-    }
-
-    this._uriFlags = rval[0];
-    return this._uriFlags;
-  },
-
-  // We take some shortcuts here. Ideally, we would return a CPOW that
-  // wraps the add-on's nsIChannel. However, many of the methods
-  // related to nsIChannel are marked [noscript], so they're not
-  // available to CPOWs. Consequently, we return a shim channel that,
-  // when opened, asks the parent to open the channel and read out all
-  // the data.
-  newChannel(uri, loadInfo) {
-    return new AboutProtocolChannel(uri, this._contractID, loadInfo);
-  },
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule])
-};
-
-var AboutProtocolChild = {
-  _classDescription: "Addon shim about: protocol handler",
-
-  init() {
-    // Maps contractIDs to instances
-    this._instances = new Map();
-    // Maps contractIDs to classIDs
-    this._classIDs = new Map();
-    NotificationTracker.watch("about-protocol", this);
-  },
-
-  track(path, register) {
-    let contractID = path[1];
-    let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-    if (register) {
-      let instance = new AboutProtocolInstance(contractID);
-      let classID = Cc["@mozilla.org/uuid-generator;1"]
-                      .getService(Ci.nsIUUIDGenerator)
-                      .generateUUID();
-
-      this._instances.set(contractID, instance);
-      this._classIDs.set(contractID, classID);
-      registrar.registerFactory(classID, this._classDescription, contractID, instance);
-    } else {
-      let instance = this._instances.get(contractID);
-      let classID = this._classIDs.get(contractID);
-      registrar.unregisterFactory(classID, instance);
-      this._instances.delete(contractID);
-      this._classIDs.delete(contractID);
-    }
-  },
-};
-
-// This code registers observers in the child whenever an add-on in
-// the parent asks for notifications on the given topic.
-var ObserverChild = {
-  init() {
-    NotificationTracker.watch("observer", this);
-  },
-
-  track(path, register) {
-    let topic = path[1];
-    if (register) {
-      Services.obs.addObserver(this, topic);
-    } else {
-      Services.obs.removeObserver(this, topic);
-    }
-  },
-
-  observe(subject, topic, data) {
-    let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-               .getService(Ci.nsISyncMessageSender);
-    cpmm.sendRpcMessage("Addons:Observer:Run", {}, {
-      topic,
-      subject,
-      data
-    });
-  }
-};
-
-// There is one of these objects per browser tab in the child. When an
-// add-on in the parent listens for an event, this child object
-// listens for that event in the child.
-function EventTargetChild(childGlobal) {
-  this._childGlobal = childGlobal;
-  this.capturingHandler = (event) => this.handleEvent(true, event);
-  this.nonCapturingHandler = (event) => this.handleEvent(false, event);
-  NotificationTracker.watch("event", this);
-}
-
-EventTargetChild.prototype = {
-  uninit() {
-    NotificationTracker.unwatch("event", this);
-  },
-
-  track(path, register) {
-    let eventType = path[1];
-    let useCapture = path[2];
-    let listener = useCapture ? this.capturingHandler : this.nonCapturingHandler;
-    if (register) {
-      this._childGlobal.addEventListener(eventType, listener, useCapture, true);
-    } else {
-      this._childGlobal.removeEventListener(eventType, listener, useCapture);
-    }
-  },
-
-  handleEvent(capturing, event) {
-    let addons = NotificationTracker.findSuffixes(["event", event.type, capturing]);
-    let [prefetched, cpows] = Prefetcher.prefetch("EventTarget.handleEvent",
-                                                  addons,
-                                                  {Event: event,
-                                                   Window: this._childGlobal.content});
-    cpows.event = event;
-    cpows.eventTarget = event.target;
-
-    this._childGlobal.sendRpcMessage("Addons:Event:Run",
-                                     {type: event.type,
-                                      capturing,
-                                      isTrusted: event.isTrusted,
-                                      prefetched},
-                                     cpows);
-  }
-};
-
-// The parent can create a sandbox to run code in the child
-// process. We actually create the sandbox in the child so that the
-// code runs there. However, managing the lifetime of these sandboxes
-// can be tricky. The parent references these sandboxes using CPOWs,
-// which only keep weak references. So we need to create a strong
-// reference in the child. For simplicity, we kill off these strong
-// references whenever we navigate away from the page for which the
-// sandbox was created.
-function SandboxChild(chromeGlobal) {
-  this.chromeGlobal = chromeGlobal;
-  this.sandboxes = [];
-}
-
-SandboxChild.prototype = {
-  uninit() {
-    this.clearSandboxes();
-  },
-
-  addListener() {
-    let webProgress = this.chromeGlobal.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIWebProgress);
-    webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_LOCATION);
-  },
-
-  removeListener() {
-    let webProgress = this.chromeGlobal.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIWebProgress);
-    webProgress.removeProgressListener(this);
-  },
-
-  onLocationChange(webProgress, request, location, flags) {
-    this.clearSandboxes();
-  },
-
-  addSandbox(sandbox) {
-    if (this.sandboxes.length == 0) {
-      this.addListener();
-    }
-    this.sandboxes.push(sandbox);
-  },
-
-  clearSandboxes() {
-    if (this.sandboxes.length) {
-      this.removeListener();
-    }
-    this.sandboxes = [];
-  },
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
-                                         Ci.nsISupportsWeakReference])
-};
 
 var RemoteAddonsChild = {
   _ready: false,
 
   makeReady() {
-    let shims = [
-      Prefetcher,
-      NotificationTracker,
-      ContentPolicyChild,
-      AboutProtocolChild,
-      ObserverChild,
-    ];
-
-    for (let shim of shims) {
-      try {
-        shim.init();
-      } catch (e) {
-        Cu.reportError(e);
-      }
-    }
   },
 
   init(global) {
 
     if (!this._ready) {
       if (!Services.cpmm.initialProcessData.remoteAddonsParentInitted) {
         return null;
       }
 
       this.makeReady();
       this._ready = true;
     }
 
     global.sendAsyncMessage("Addons:RegisterGlobal", {}, {global});
 
-    let sandboxChild = new SandboxChild(global);
-    global.addSandbox = sandboxChild.addSandbox.bind(sandboxChild);
-
-    // Return this so it gets rooted in the content script.
-    return [new EventTargetChild(global), sandboxChild];
+    return [];
   },
 
   uninit(perTabShims) {
     for (let shim of perTabShims) {
       try {
         shim.uninit();
       } catch (e) {
         Cu.reportError(e);
--- a/toolkit/components/addoncompat/RemoteAddonsParent.jsm
+++ b/toolkit/components/addoncompat/RemoteAddonsParent.jsm
@@ -1,25 +1,17 @@
 // 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/.
 
 var EXPORTED_SYMBOLS = ["RemoteAddonsParent"];
 
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/RemoteWebProgress.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-ChromeUtils.defineModuleGetter(this, "NetUtil",
-                               "resource://gre/modules/NetUtil.jsm");
-ChromeUtils.defineModuleGetter(this, "Prefetcher",
-                               "resource://gre/modules/Prefetcher.jsm");
-ChromeUtils.defineModuleGetter(this, "CompatWarning",
-                               "resource://gre/modules/CompatWarning.jsm");
-
 Cu.permitCPOWsInScope(this);
 
 // Similar to Python. Returns dict[key] if it exists. Otherwise,
 // sets dict[key] to default_ and returns default_.
 function setDefault(dict, key, default_) {
   if (key in dict) {
     return dict[key];
   }
@@ -88,878 +80,17 @@ function Interposition(name, base) {
     this.setters = Object.create(base.setters);
   } else {
     this.methods = Object.create(null);
     this.getters = Object.create(null);
     this.setters = Object.create(null);
   }
 }
 
-// This object is responsible for notifying the child when a new
-// content policy is added or removed. It also runs all the registered
-// add-on content policies when the child asks it to do so.
-var ContentPolicyParent = {
-  init() {
-    let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
-               .getService(Ci.nsIMessageBroadcaster);
-    ppmm.addMessageListener("Addons:ContentPolicy:Run", this);
-
-    this._policies = new Map();
-  },
-
-  addContentPolicy(addon, name, cid) {
-    this._policies.set(name, cid);
-    NotificationTracker.add(["content-policy", addon]);
-  },
-
-  removeContentPolicy(addon, name) {
-    this._policies.delete(name);
-    NotificationTracker.remove(["content-policy", addon]);
-  },
-
-  receiveMessage(aMessage) {
-    switch (aMessage.name) {
-      case "Addons:ContentPolicy:Run":
-        return this.shouldLoad(aMessage.data, aMessage.objects);
-    }
-    return undefined;
-  },
-
-  shouldLoad(aData, aObjects) {
-    for (let policyCID of this._policies.values()) {
-      let policy;
-      try {
-        policy = Cc[policyCID].getService(Ci.nsIContentPolicy);
-      } catch (e) {
-        // Current Gecko behavior is to ignore entries that don't QI.
-        continue;
-      }
-      try {
-        let contentLocation = Services.io.newURI(aData.contentLocation);
-        let requestOrigin = aData.requestOrigin ? Services.io.newURI(aData.requestOrigin) : null;
-
-        let result = Prefetcher.withPrefetching(aData.prefetched, aObjects, () => {
-          return policy.shouldLoad(aData.contentType,
-                                   contentLocation,
-                                   requestOrigin,
-                                   aObjects.node,
-                                   aData.mimeTypeGuess,
-                                   null,
-                                   aData.requestPrincipal);
-        });
-        if (result != Ci.nsIContentPolicy.ACCEPT && result != 0)
-          return result;
-      } catch (e) {
-        Cu.reportError(e);
-      }
-    }
-
-    return Ci.nsIContentPolicy.ACCEPT;
-  },
-};
-ContentPolicyParent.init();
-
-// This interposition intercepts calls to add or remove new content
-// policies and forwards these requests to ContentPolicyParent.
-var CategoryManagerInterposition = new Interposition("CategoryManagerInterposition");
-
-CategoryManagerInterposition.methods.addCategoryEntry =
-  function(addon, target, category, entry, value, persist, replace) {
-    if (category == "content-policy") {
-      CompatWarning.warn("content-policy should be added from the child process only.",
-                         addon, CompatWarning.warnings.nsIContentPolicy);
-      ContentPolicyParent.addContentPolicy(addon, entry, value);
-    }
-
-    target.addCategoryEntry(category, entry, value, persist, replace);
-  };
-
-CategoryManagerInterposition.methods.deleteCategoryEntry =
-  function(addon, target, category, entry, persist) {
-    if (category == "content-policy") {
-      CompatWarning.warn("content-policy should be removed from the child process only.",
-                         addon, CompatWarning.warnings.nsIContentPolicy);
-      ContentPolicyParent.removeContentPolicy(addon, entry);
-    }
-
-    target.deleteCategoryEntry(category, entry, persist);
-  };
-
-// This shim handles the case where an add-on registers an about:
-// protocol handler in the parent and we want the child to be able to
-// use it. This code is pretty specific to Adblock's usage.
-var AboutProtocolParent = {
-  init() {
-    let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
-               .getService(Ci.nsIMessageBroadcaster);
-    ppmm.addMessageListener("Addons:AboutProtocol:GetURIFlags", this);
-    ppmm.addMessageListener("Addons:AboutProtocol:OpenChannel", this);
-    this._protocols = [];
-  },
-
-  registerFactory(addon, class_, className, contractID, factory) {
-    this._protocols.push({contractID, factory});
-    NotificationTracker.add(["about-protocol", contractID, addon]);
-  },
-
-  unregisterFactory(addon, class_, factory) {
-    for (let i = 0; i < this._protocols.length; i++) {
-      if (this._protocols[i].factory == factory) {
-        NotificationTracker.remove(["about-protocol", this._protocols[i].contractID, addon]);
-        this._protocols.splice(i, 1);
-        break;
-      }
-    }
-  },
-
-  receiveMessage(msg) {
-    switch (msg.name) {
-      case "Addons:AboutProtocol:GetURIFlags":
-        return this.getURIFlags(msg);
-      case "Addons:AboutProtocol:OpenChannel":
-        return this.openChannel(msg);
-    }
-    return undefined;
-  },
-
-  getURIFlags(msg) {
-    let uri = Services.io.newURI(msg.data.uri);
-    let contractID = msg.data.contractID;
-    let module = Cc[contractID].getService(Ci.nsIAboutModule);
-    try {
-      return module.getURIFlags(uri);
-    } catch (e) {
-      Cu.reportError(e);
-      return undefined;
-    }
-  },
-
-  // We immediately read all the data out of the channel here and
-  // return it to the child.
-  openChannel(msg) {
-    function wrapGetInterface(cpow) {
-      return {
-        getInterface(intf) { return cpow.getInterface(intf); }
-      };
-    }
-
-    let uri = Services.io.newURI(msg.data.uri);
-    let channelParams;
-    if (msg.data.contentPolicyType === Ci.nsIContentPolicy.TYPE_DOCUMENT) {
-      // For TYPE_DOCUMENT loads, we cannot recreate the loadinfo here in the
-      // parent. In that case, treat this as a chrome (addon)-requested
-      // subload. When we use the data in the child, we'll load it into the
-      // correctly-principaled document.
-      channelParams = {
-        uri,
-        contractID: msg.data.contractID,
-        loadingPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
-        securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
-        contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER
-      };
-    } else {
-      // We can recreate the loadinfo here in the parent for non TYPE_DOCUMENT
-      // loads.
-      channelParams = {
-        uri,
-        contractID: msg.data.contractID,
-        loadingPrincipal: msg.data.loadingPrincipal,
-        securityFlags: msg.data.securityFlags,
-        contentPolicyType: msg.data.contentPolicyType
-      };
-    }
-
-    try {
-      let channel = NetUtil.newChannel(channelParams);
-
-      // We're not allowed to set channel.notificationCallbacks to a
-      // CPOW, since the setter for notificationCallbacks is in C++,
-      // which can't tolerate CPOWs. Instead we just use a JS object
-      // that wraps the CPOW.
-      channel.notificationCallbacks = wrapGetInterface(msg.objects.notificationCallbacks);
-      if (msg.objects.loadGroupNotificationCallbacks) {
-        channel.loadGroup = {notificationCallbacks: msg.objects.loadGroupNotificationCallbacks};
-      } else {
-        channel.loadGroup = null;
-      }
-      let stream = channel.open2();
-      let data = NetUtil.readInputStreamToString(stream, stream.available(), {});
-      return {
-        data,
-        contentType: channel.contentType
-      };
-    } catch (e) {
-      Cu.reportError(e);
-      return undefined;
-    }
-  },
-};
-AboutProtocolParent.init();
-
-var ComponentRegistrarInterposition = new Interposition("ComponentRegistrarInterposition");
-
-ComponentRegistrarInterposition.methods.registerFactory =
-  function(addon, target, class_, className, contractID, factory) {
-    if (contractID && contractID.startsWith("@mozilla.org/network/protocol/about;1?")) {
-      CompatWarning.warn("nsIAboutModule should be registered in the content process" +
-                         " as well as the chrome process. (If you do that already, ignore" +
-                         " this warning.)",
-                         addon, CompatWarning.warnings.nsIAboutModule);
-      AboutProtocolParent.registerFactory(addon, class_, className, contractID, factory);
-    }
-
-    target.registerFactory(class_, className, contractID, factory);
-  };
-
-ComponentRegistrarInterposition.methods.unregisterFactory =
-  function(addon, target, class_, factory) {
-    AboutProtocolParent.unregisterFactory(addon, class_, factory);
-    target.unregisterFactory(class_, factory);
-  };
-
-// This object manages add-on observers that might fire in the child
-// process. Rather than managing the observers itself, it uses the
-// parent's observer service. When an add-on listens on topic T,
-// ObserverParent asks the child process to listen on T. It also adds
-// an observer in the parent for the topic e10s-T. When the T observer
-// fires in the child, the parent fires all the e10s-T observers,
-// passing them CPOWs for the subject and data. We don't want to use T
-// in the parent because there might be non-add-on T observers that
-// won't expect to get notified in this case.
-var ObserverParent = {
-  init() {
-    let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
-               .getService(Ci.nsIMessageBroadcaster);
-    ppmm.addMessageListener("Addons:Observer:Run", this);
-  },
-
-  addObserver(addon, observer, topic, ownsWeak) {
-    Services.obs.addObserver(observer, "e10s-" + topic, ownsWeak);
-    NotificationTracker.add(["observer", topic, addon]);
-  },
-
-  removeObserver(addon, observer, topic) {
-    Services.obs.removeObserver(observer, "e10s-" + topic);
-    NotificationTracker.remove(["observer", topic, addon]);
-  },
-
-  receiveMessage(msg) {
-    switch (msg.name) {
-      case "Addons:Observer:Run":
-        this.notify(msg.objects.subject, msg.objects.topic, msg.objects.data);
-        break;
-    }
-  },
-
-  notify(subject, topic, data) {
-    let e = Services.obs.enumerateObservers("e10s-" + topic);
-    while (e.hasMoreElements()) {
-      let obs = e.getNext().QueryInterface(Ci.nsIObserver);
-      try {
-        obs.observe(subject, topic, data);
-      } catch (e) {
-        Cu.reportError(e);
-      }
-    }
-  }
-};
-ObserverParent.init();
-
-// We only forward observers for these topics.
-var TOPIC_WHITELIST = [
-  "content-document-global-created",
-  "document-element-inserted",
-  "dom-window-destroyed",
-  "inner-window-destroyed",
-  "outer-window-destroyed",
-  "csp-on-violate-policy",
-];
-
-// This interposition listens for
-// nsIObserverService.{add,remove}Observer.
-var ObserverInterposition = new Interposition("ObserverInterposition");
-
-ObserverInterposition.methods.addObserver =
-  function(addon, target, observer, topic, ownsWeak) {
-    if (TOPIC_WHITELIST.includes(topic)) {
-      CompatWarning.warn(`${topic} observer should be added from the child process only.`,
-                         addon, CompatWarning.warnings.observers);
-
-      ObserverParent.addObserver(addon, observer, topic);
-    }
-
-    target.addObserver(observer, topic, ownsWeak);
-  };
-
-ObserverInterposition.methods.removeObserver =
-  function(addon, target, observer, topic) {
-    if (TOPIC_WHITELIST.includes(topic)) {
-      ObserverParent.removeObserver(addon, observer, topic);
-    }
-
-    target.removeObserver(observer, topic);
-  };
-
-// This object is responsible for forwarding events from the child to
-// the parent.
-var EventTargetParent = {
-  init() {
-    // The _listeners map goes from targets (either <browser> elements
-    // or windows) to a dictionary from event types to listeners.
-    this._listeners = new WeakMap();
-
-    let mm = Cc["@mozilla.org/globalmessagemanager;1"].
-      getService(Ci.nsIMessageListenerManager);
-    mm.addMessageListener("Addons:Event:Run", this);
-  },
-
-  // If target is not on the path from a <browser> element to the
-  // window root, then we return null here to ignore the
-  // target. Otherwise, if the target is a browser-specific element
-  // (the <browser> or <tab> elements), then we return the
-  // <browser>. If it's some generic element, then we return the
-  // window itself.
-  redirectEventTarget(target) {
-    if (Cu.isCrossProcessWrapper(target)) {
-      return null;
-    }
-
-    if (target instanceof Ci.nsIDOMChromeWindow) {
-      return target;
-    }
-
-    if (target instanceof Ci.nsIDOMXULElement) {
-      if (target.localName == "browser") {
-        return target;
-      } else if (target.localName == "tab") {
-        return target.linkedBrowser;
-      }
-
-      // Check if |target| is somewhere on the path from the
-      // tabbrowser tabbox.
-      let window = target.ownerGlobal;
-
-      // Some non-browser windows define gBrowser globals which are not elements
-      // and can't be passed to target.contains().
-      if (window &&
-          window.gBrowser &&
-          window.gBrowser.tabbox &&
-          target.contains(window.gBrowser.tabbox)) {
-        return window;
-      }
-    }
-
-    if (target.ownerGlobal && target === target.ownerGlobal.gBrowser) {
-      return target.ownerGlobal;
-    }
-
-    return null;
-  },
-
-  // When a given event fires in the child, we fire it on the
-  // <browser> element and the window since those are the two possible
-  // results of redirectEventTarget.
-  getTargets(browser) {
-    let window = browser.ownerGlobal;
-    return [browser, window];
-  },
-
-  addEventListener(addon, target, type, listener, useCapture, wantsUntrusted, delayedWarning) {
-    let newTarget = this.redirectEventTarget(target);
-    if (!newTarget) {
-      return;
-    }
-
-    useCapture = useCapture || false;
-    wantsUntrusted = wantsUntrusted || false;
-
-    NotificationTracker.add(["event", type, useCapture, addon]);
-
-    let listeners = this._listeners.get(newTarget);
-    if (!listeners) {
-      listeners = {};
-      this._listeners.set(newTarget, listeners);
-    }
-    let forType = setDefault(listeners, type, []);
-
-    // If there's already an identical listener, don't do anything.
-    for (let i = 0; i < forType.length; i++) {
-      if (forType[i].listener === listener &&
-          forType[i].target === target &&
-          forType[i].useCapture === useCapture &&
-          forType[i].wantsUntrusted === wantsUntrusted) {
-        return;
-      }
-    }
-
-    forType.push({listener,
-                  target,
-                  wantsUntrusted,
-                  useCapture,
-                  delayedWarning});
-  },
-
-  removeEventListener(addon, target, type, listener, useCapture) {
-    let newTarget = this.redirectEventTarget(target);
-    if (!newTarget) {
-      return;
-    }
-
-    useCapture = useCapture || false;
-
-    let listeners = this._listeners.get(newTarget);
-    if (!listeners) {
-      return;
-    }
-    let forType = setDefault(listeners, type, []);
-
-    for (let i = 0; i < forType.length; i++) {
-      if (forType[i].listener === listener &&
-          forType[i].target === target &&
-          forType[i].useCapture === useCapture) {
-        forType.splice(i, 1);
-        NotificationTracker.remove(["event", type, useCapture, addon]);
-        break;
-      }
-    }
-  },
-
-  receiveMessage(msg) {
-    switch (msg.name) {
-      case "Addons:Event:Run":
-        this.dispatch(msg.target, msg.data.type, msg.data.capturing,
-                      msg.data.isTrusted, msg.data.prefetched, msg.objects);
-        break;
-    }
-  },
-
-  dispatch(browser, type, capturing, isTrusted, prefetched, cpows) {
-    let event = cpows.event;
-    let eventTarget = cpows.eventTarget;
-    let targets = this.getTargets(browser);
-    for (let target of targets) {
-      let listeners = this._listeners.get(target);
-      if (!listeners) {
-        continue;
-      }
-      let forType = setDefault(listeners, type, []);
-
-      // Make a copy in case they call removeEventListener in the listener.
-      let handlers = [];
-      for (let {listener, target, wantsUntrusted, useCapture, delayedWarning} of forType) {
-        if ((wantsUntrusted || isTrusted) && useCapture == capturing) {
-          // Issue a warning for this listener.
-          delayedWarning();
-
-          handlers.push([listener, target]);
-        }
-      }
-
-      for (let [handler, target] of handlers) {
-        let EventProxy = {
-          get(knownProps, name) {
-            if (knownProps.hasOwnProperty(name))
-              return knownProps[name];
-            return event[name];
-          }
-        };
-        let proxyEvent = new Proxy({
-          currentTarget: target,
-          target: eventTarget,
-          type,
-          QueryInterface(iid) {
-            if (iid.equals(Ci.nsISupports) ||
-                iid.equals(Ci.nsIDOMEventTarget))
-              return proxyEvent;
-            // If event deson't support the interface this will throw. If it
-            // does we want to return the proxy
-            event.QueryInterface(iid);
-            return proxyEvent;
-          }
-        }, EventProxy);
-
-        try {
-          Prefetcher.withPrefetching(prefetched, cpows, () => {
-            if ("handleEvent" in handler) {
-              handler.handleEvent(proxyEvent);
-            } else {
-              handler.call(eventTarget, proxyEvent);
-            }
-          });
-        } catch (e) {
-          Cu.reportError(e);
-        }
-      }
-    }
-  }
-};
-EventTargetParent.init();
-
-// This function returns a listener that will remove itself the first time
-// it is fired.
-var selfRemovingListeners = new WeakMap();
-function makeSelfRemovingListener(addon, target, type, listener, useCapture) {
-  if (selfRemovingListeners.has(listener)) {
-    return selfRemovingListeners.get(listener);
-  }
-
-  function selfRemovingListener(event) {
-    EventTargetInterposition.methods.removeEventListener(addon, target, type,
-                                                         listener, useCapture);
-    if ("handleEvent" in listener) {
-      listener.handleEvent(event);
-    } else {
-      listener.call(event.target, event);
-    }
-  }
-  selfRemovingListeners.set(listener, selfRemovingListener);
-
-  return selfRemovingListener;
-}
-
-// This function returns a listener that will not fire on events where
-// the target is a remote xul:browser element itself. We'd rather let
-// the child process handle the event and pass it up via
-// EventTargetParent.
-var filteringListeners = new WeakMap();
-function makeFilteringListener(eventType, listener) {
-  // Some events are actually targeted at the <browser> element
-  // itself, so we only handle the ones where know that won't happen.
-  let eventTypes = ["mousedown", "mouseup", "click"];
-  if (!eventTypes.includes(eventType) || !listener ||
-      (typeof listener != "object" && typeof listener != "function")) {
-    return listener;
-  }
-
-  if (filteringListeners.has(listener)) {
-    return filteringListeners.get(listener);
-  }
-
-  function filter(event) {
-    let target = event.originalTarget;
-    if (target instanceof Ci.nsIDOMXULElement &&
-        target.localName == "browser" &&
-        target.isRemoteBrowser) {
-      return;
-    }
-
-    if ("handleEvent" in listener) {
-      listener.handleEvent(event);
-    } else {
-      listener.call(event.target, event);
-    }
-  }
-  filteringListeners.set(listener, filter);
-  return filter;
-}
-
-// This interposition redirects addEventListener and
-// removeEventListener to EventTargetParent.
-var EventTargetInterposition = new Interposition("EventTargetInterposition");
-
-EventTargetInterposition.methods.addEventListener =
-  function(addon, target, type, listener, options, wantsUntrusted) {
-    let delayed = CompatWarning.delayedWarning(
-      `Registering a ${type} event listener on content DOM nodes` +
-        " needs to happen in the content process.",
-      addon, CompatWarning.warnings.DOM_events);
-
-    let useCapture =
-      options === true || (typeof options == "object" && options.capture) || false;
-    if (typeof options == "object" && options.once) {
-      listener = makeSelfRemovingListener(addon, target, type, listener, useCapture);
-    }
-
-    EventTargetParent.addEventListener(addon, target, type, listener,
-                                       useCapture, wantsUntrusted, delayed);
-    target.addEventListener(type, makeFilteringListener(type, listener),
-                            useCapture, wantsUntrusted);
-  };
-
-EventTargetInterposition.methods.removeEventListener =
-  function(addon, target, type, listener, options) {
-    let useCapture =
-      options === true || (typeof options == "object" && options.capture) || false;
-
-    if (selfRemovingListeners.has(listener)) {
-      listener = selfRemovingListeners.get(listener);
-    }
-
-    EventTargetParent.removeEventListener(addon, target, type, listener, useCapture);
-    target.removeEventListener(type, makeFilteringListener(type, listener), useCapture);
-  };
-
-// This interposition intercepts accesses to |rootTreeItem| on a child
-// process docshell. In the child, each docshell is its own
-// root. However, add-ons expect the root to be the chrome docshell,
-// so we make that happen here.
-var ContentDocShellTreeItemInterposition = new Interposition("ContentDocShellTreeItemInterposition");
-
-ContentDocShellTreeItemInterposition.getters.rootTreeItem =
-  function(addon, target) {
-    // The chrome global in the child.
-    let chromeGlobal = target.rootTreeItem
-      .QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIContentFrameMessageManager);
-
-    // Map it to a <browser> element and window.
-    let browser = RemoteAddonsParent.globalToBrowser.get(chromeGlobal);
-    if (!browser) {
-      // Somehow we have a CPOW from the child, but it hasn't sent us
-      // its global yet. That shouldn't happen, but return null just
-      // in case.
-      return null;
-    }
-
-    let chromeWin = browser.ownerGlobal;
-
-    // Return that window's docshell.
-    return chromeWin.QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIWebNavigation)
-      .QueryInterface(Ci.nsIDocShellTreeItem);
-  };
-
-function chromeGlobalForContentWindow(window) {
-    return window
-      .QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIWebNavigation)
-      .QueryInterface(Ci.nsIDocShellTreeItem)
-      .rootTreeItem
-      .QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIContentFrameMessageManager);
-}
-
-// This object manages sandboxes created with content principals in
-// the parent. We actually create these sandboxes in the child process
-// so that the code loaded into them runs there. The resulting sandbox
-// object is a CPOW. This is primarly useful for Greasemonkey.
-var SandboxParent = {
-  componentsMap: new WeakMap(),
-
-  makeContentSandbox(addon, chromeGlobal, principals, ...rest) {
-    CompatWarning.warn("This sandbox should be created from the child process.",
-                       addon, CompatWarning.warnings.sandboxes);
-    if (rest.length) {
-      // Do a shallow copy of the options object into the child
-      // process. This way we don't have to access it through a Chrome
-      // object wrapper, which would not let us access any properties.
-      //
-      // The only object property here is sandboxPrototype. We assume
-      // it's a child process object (since that's what Greasemonkey
-      // does) and leave it alone.
-      let options = rest[0];
-      let optionsCopy = new chromeGlobal.Object();
-      for (let prop in options) {
-        optionsCopy[prop] = options[prop];
-      }
-      rest[0] = optionsCopy;
-    }
-
-    // Make a sandbox in the child.
-    let cu = chromeGlobal.Components.utils;
-    let sandbox = cu.Sandbox(principals, ...rest);
-
-    // We need to save the sandbox in the child so it won't get
-    // GCed. The child will drop this reference at the next
-    // navigation.
-    chromeGlobal.addSandbox(sandbox);
-
-    // The sandbox CPOW will be kept alive by whomever we return it
-    // to. Its lifetime is unrelated to that of the sandbox object in
-    // the child.
-    this.componentsMap.set(sandbox, cu);
-    return sandbox;
-  },
-
-  evalInSandbox(code, sandbox, ...rest) {
-    let cu = this.componentsMap.get(sandbox);
-    return cu.evalInSandbox(code, sandbox, ...rest);
-  }
-};
-
-// This interposition redirects calls to Cu.Sandbox and
-// Cu.evalInSandbox to SandboxParent if the principals are content
-// principals.
-var ComponentsUtilsInterposition = new Interposition("ComponentsUtilsInterposition");
-
-ComponentsUtilsInterposition.methods.Sandbox =
-  function(addon, target, principals, ...rest) {
-    // principals can be a window object, a list of window objects, or
-    // something else (a string, for example).
-    if (principals &&
-        typeof(principals) == "object" &&
-        Cu.isCrossProcessWrapper(principals) &&
-        principals instanceof Ci.nsIDOMWindow) {
-      let chromeGlobal = chromeGlobalForContentWindow(principals);
-      return SandboxParent.makeContentSandbox(addon, chromeGlobal, principals, ...rest);
-    } else if (principals &&
-               typeof(principals) == "object" &&
-               "every" in principals &&
-               principals.length &&
-               principals.every(e => e instanceof Ci.nsIDOMWindow && Cu.isCrossProcessWrapper(e))) {
-      let chromeGlobal = chromeGlobalForContentWindow(principals[0]);
-
-      // The principals we pass to the content process must use an
-      // Array object from the content process.
-      let array = new chromeGlobal.Array();
-      for (let i = 0; i < principals.length; i++) {
-        array[i] = principals[i];
-      }
-      return SandboxParent.makeContentSandbox(addon, chromeGlobal, array, ...rest);
-    }
-    return Cu.Sandbox(principals, ...rest);
-  };
-
-ComponentsUtilsInterposition.methods.evalInSandbox =
-  function(addon, target, code, sandbox, ...rest) {
-    if (sandbox && Cu.isCrossProcessWrapper(sandbox)) {
-      return SandboxParent.evalInSandbox(code, sandbox, ...rest);
-    }
-    return Cu.evalInSandbox(code, sandbox, ...rest);
-  };
-
-// This interposition handles cases where an add-on tries to import a
-// chrome XUL node into a content document. It doesn't actually do the
-// import, which we can't support. It just avoids throwing an
-// exception.
-var ContentDocumentInterposition = new Interposition("ContentDocumentInterposition");
-
-ContentDocumentInterposition.methods.importNode =
-  function(addon, target, node, deep) {
-    if (!Cu.isCrossProcessWrapper(node)) {
-      // Trying to import a node from the parent process into the
-      // child process. We don't support this now. Video Download
-      // Helper does this in domhook-service.js to add a XUL
-      // popupmenu to content.
-      Cu.reportError("Calling contentDocument.importNode on a XUL node is not allowed.");
-      return node;
-    }
-
-    return target.importNode(node, deep);
-  };
-
-// This interposition ensures that calling browser.docShell from an
-// add-on returns a CPOW around the docshell.
-var RemoteBrowserElementInterposition = new Interposition("RemoteBrowserElementInterposition",
-                                                          EventTargetInterposition);
-
-RemoteBrowserElementInterposition.getters.docShell = function(addon, target) {
-  CompatWarning.warn("Direct access to content docshell will no longer work in the chrome process.",
-                     addon, CompatWarning.warnings.content);
-  let remoteChromeGlobal = RemoteAddonsParent.browserToGlobal.get(target);
-  if (!remoteChromeGlobal) {
-    // We may not have any messages from this tab yet.
-    return null;
-  }
-  return remoteChromeGlobal.docShell;
-};
-
-RemoteBrowserElementInterposition.getters.sessionHistory = function(addon, target) {
-  CompatWarning.warn("Direct access to browser.sessionHistory will no longer " +
-                     "work in the chrome process.",
-                     addon, CompatWarning.warnings.content);
-
-  return getSessionHistory(target);
-};
-
-// We use this in place of the real browser.contentWindow if we
-// haven't yet received a CPOW for the child process's window. This
-// happens if the tab has just started loading.
-function makeDummyContentWindow(browser) {
-  let dummyContentWindow = {
-    set location(url) {
-      browser.loadURI(url, null, null);
-    },
-    document: {
-      readyState: "loading",
-      location: { href: "about:blank" }
-    },
-    frames: [],
-  };
-  dummyContentWindow.top = dummyContentWindow;
-  dummyContentWindow.document.defaultView = dummyContentWindow;
-  browser._contentWindow = dummyContentWindow;
-  return dummyContentWindow;
-}
-
-RemoteBrowserElementInterposition.getters.contentWindow = function(addon, target) {
-  CompatWarning.warn("Direct access to browser.contentWindow will no longer work in the chrome process.",
-                     addon, CompatWarning.warnings.content);
-
-  // If we don't have a CPOW yet, just return something we can use for
-  // setting the location. This is useful for tests that create a tab
-  // and immediately set contentWindow.location.
-  if (!target.contentWindowAsCPOW) {
-    CompatWarning.warn("CPOW to the content window does not exist yet, dummy content window is created.");
-    return makeDummyContentWindow(target);
-  }
-  return target.contentWindowAsCPOW;
-};
-
-function getContentDocument(addon, browser) {
-  if (!browser.contentWindowAsCPOW) {
-    return makeDummyContentWindow(browser).document;
-  }
-
-  let doc = Prefetcher.lookupInCache(addon, browser.contentWindowAsCPOW, "document");
-  if (doc) {
-    return doc;
-  }
-
-  return browser.contentWindowAsCPOW.document;
-}
-
-function getSessionHistory(browser) {
-  let remoteChromeGlobal = RemoteAddonsParent.browserToGlobal.get(browser);
-  if (!remoteChromeGlobal) {
-    CompatWarning.warn("CPOW for the remote browser docShell hasn't been received yet.");
-    // We may not have any messages from this tab yet.
-    return null;
-  }
-  return remoteChromeGlobal.docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
-}
-
-RemoteBrowserElementInterposition.getters.contentDocument = function(addon, target) {
-  CompatWarning.warn("Direct access to browser.contentDocument will no longer work in the chrome process.",
-                     addon, CompatWarning.warnings.content);
-
-  return getContentDocument(addon, target);
-};
-
-var TabBrowserElementInterposition = new Interposition("TabBrowserElementInterposition",
-                                                       EventTargetInterposition);
-
-TabBrowserElementInterposition.getters.contentWindow = function(addon, target) {
-  CompatWarning.warn("Direct access to gBrowser.contentWindow will no longer work in the chrome process.",
-                     addon, CompatWarning.warnings.content);
-
-  if (!target.selectedBrowser.contentWindowAsCPOW) {
-    return makeDummyContentWindow(target.selectedBrowser);
-  }
-  return target.selectedBrowser.contentWindowAsCPOW;
-};
-
-TabBrowserElementInterposition.getters.contentDocument = function(addon, target) {
-  CompatWarning.warn("Direct access to gBrowser.contentDocument will no longer work in the chrome process.",
-                     addon, CompatWarning.warnings.content);
-
-  let browser = target.selectedBrowser;
-  return getContentDocument(addon, browser);
-};
-
-TabBrowserElementInterposition.getters.sessionHistory = function(addon, target) {
-  CompatWarning.warn("Direct access to gBrowser.sessionHistory will no " +
-                     "longer work in the chrome process.",
-                     addon, CompatWarning.warnings.content);
-  let browser = target.selectedBrowser;
-  if (!browser.isRemoteBrowser) {
-    return browser.sessionHistory;
-  }
-  return getSessionHistory(browser);
-};
+var TabBrowserElementInterposition = new Interposition("TabBrowserElementInterposition");
 
 // This function returns a wrapper around an
 // nsIWebProgressListener. When the wrapper is invoked, it calls the
 // real listener but passes CPOWs for the nsIWebProgress and
 // nsIRequest arguments.
 var progressListeners = {global: new WeakMap(), tabs: new WeakMap()};
 function wrapProgressListener(kind, listener) {
   if (progressListeners[kind].has(listener)) {
@@ -996,117 +127,39 @@ TabBrowserElementInterposition.methods.r
   if (!target.ownerGlobal.gMultiProcessBrowser) {
     return target.removeProgressListener(listener);
   }
 
   NotificationTracker.remove(["web-progress", addon]);
   return target.removeProgressListener(wrapProgressListener("global", listener));
 };
 
-TabBrowserElementInterposition.methods.addTabsProgressListener = function(addon, target, listener) {
-  if (!target.ownerGlobal.gMultiProcessBrowser) {
-    return target.addTabsProgressListener(listener);
-  }
-
-  NotificationTracker.add(["web-progress", addon]);
-  return target.addTabsProgressListener(wrapProgressListener("tabs", listener));
-};
-
-TabBrowserElementInterposition.methods.removeTabsProgressListener = function(addon, target, listener) {
-  if (!target.ownerGlobal.gMultiProcessBrowser) {
-    return target.removeTabsProgressListener(listener);
-  }
-
-  NotificationTracker.remove(["web-progress", addon]);
-  return target.removeTabsProgressListener(wrapProgressListener("tabs", listener));
-};
-
-var ChromeWindowInterposition = new Interposition("ChromeWindowInterposition",
-                                                  EventTargetInterposition);
-
-ChromeWindowInterposition.getters.content = function(addon, target) {
-  CompatWarning.warn("Direct access to chromeWindow.content will no longer work in the chrome process.",
-                     addon, CompatWarning.warnings.content);
-
-  let browser = target.gBrowser.selectedBrowser;
-  if (!browser.contentWindowAsCPOW) {
-    return makeDummyContentWindow(browser);
-  }
-  return browser.contentWindowAsCPOW;
-};
-
-var RemoteWebNavigationInterposition = new Interposition("RemoteWebNavigation");
-
-RemoteWebNavigationInterposition.getters.sessionHistory = function(addon, target) {
-  CompatWarning.warn("Direct access to webNavigation.sessionHistory will no longer " +
-                     "work in the chrome process.",
-                     addon, CompatWarning.warnings.content);
-
-  if (target instanceof Ci.nsIDocShell) {
-    // We must have a non-remote browser, so we can go ahead
-    // and just return the real sessionHistory.
-    return target.sessionHistory;
-  }
-
-  let impl = target.wrappedJSObject;
-  if (!impl) {
-    return null;
-  }
-
-  let browser = impl._browser;
-
-  return getSessionHistory(browser);
-};
-
 var RemoteAddonsParent = {
   init() {
     let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
     mm.addMessageListener("Addons:RegisterGlobal", this);
 
     Services.ppmm.initialProcessData.remoteAddonsParentInitted = true;
 
     Services.ppmm.loadProcessScript("data:,new " + function() {
       ChromeUtils.import("resource://gre/modules/RemoteAddonsChild.jsm");
     }, true);
 
     this.globalToBrowser = new WeakMap();
     this.browserToGlobal = new WeakMap();
   },
 
   getInterfaceInterpositions() {
-    let result = {};
-
-    function register(intf, interp) {
-      result[intf.number] = interp;
-    }
-
-    register(Ci.nsICategoryManager, CategoryManagerInterposition);
-    register(Ci.nsIComponentRegistrar, ComponentRegistrarInterposition);
-    register(Ci.nsIObserverService, ObserverInterposition);
-    register(Ci.nsIXPCComponents_Utils, ComponentsUtilsInterposition);
-    register(Ci.nsIWebNavigation, RemoteWebNavigationInterposition);
-
-    return result;
+    return {};
   },
 
   getTaggedInterpositions() {
-    let result = {};
-
-    function register(tag, interp) {
-      result[tag] = interp;
-    }
-
-    register("EventTarget", EventTargetInterposition);
-    register("ContentDocShellTreeItem", ContentDocShellTreeItemInterposition);
-    register("ContentDocument", ContentDocumentInterposition);
-    register("RemoteBrowserElement", RemoteBrowserElementInterposition);
-    register("TabBrowserElement", TabBrowserElementInterposition);
-    register("ChromeWindow", ChromeWindowInterposition);
-
-    return result;
+    return {
+      TabBrowserElement: TabBrowserElementInterposition,
+    };
   },
 
   receiveMessage(msg) {
     switch (msg.name) {
     case "Addons:RegisterGlobal":
       this.browserToGlobal.set(msg.target, msg.objects.global);
       this.globalToBrowser.set(msg.objects.global, msg.target);
       break;
--- a/toolkit/components/addoncompat/moz.build
+++ b/toolkit/components/addoncompat/moz.build
@@ -2,22 +2,19 @@
 # vim: set filetype=python:
 # 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/.
 
 with Files('**'):
     BUG_COMPONENT = ('Firefox', 'Extension Compatibility')
 
-TEST_DIRS += ['tests']
-
 EXTRA_COMPONENTS += [
     'addoncompat.manifest',
     'defaultShims.js',
     'multiprocessShims.js',
 ]
 
 EXTRA_JS_MODULES += [
-    'CompatWarning.jsm',
     'Prefetcher.jsm',
     'RemoteAddonsChild.jsm',
     'RemoteAddonsParent.jsm',
 ]
--- a/toolkit/components/addoncompat/multiprocessShims.js
+++ b/toolkit/components/addoncompat/multiprocessShims.js
@@ -104,34 +104,20 @@ AddonInterpositionService.prototype = {
 
   // When the interface is not known for a method call, this code
   // determines the type of the target object.
   getObjectTag(target) {
     if (Cu.isCrossProcessWrapper(target)) {
       return Cu.getCrossProcessWrapperTag(target);
     }
 
-    if (target instanceof Ci.nsIDOMXULElement) {
-      if (target.localName == "browser" && target.isRemoteBrowser) {
-        return "RemoteBrowserElement";
-      }
-    }
-
     if (target.ownerGlobal && target === target.ownerGlobal.gBrowser) {
       return "TabBrowserElement";
     }
 
-    if (target instanceof Ci.nsIDOMChromeWindow && target.gMultiProcessBrowser) {
-      return "ChromeWindow";
-    }
-
-    if (target instanceof Ci.nsIDOMEventTarget) {
-      return "EventTarget";
-    }
-
     return "generic";
   },
 
   interposeProperty(addon, target, iid, prop) {
     let interp;
     if (iid) {
       interp = this._interfaceInterpositions[iid];
     } else {
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/addon/bootstrap.js
+++ /dev/null
@@ -1,628 +0,0 @@
-// This file also defines a frame script.
-/* eslint-env mozilla/frame-script */
-
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const baseURL = "http://mochi.test:8888/browser/" +
-  "toolkit/components/addoncompat/tests/browser/";
-
-var contentSecManager = Cc["@mozilla.org/contentsecuritymanager;1"]
-                          .getService(Ci.nsIContentSecurityManager);
-
-function forEachWindow(f) {
-  let wins = Services.wm.getEnumerator("navigator:browser");
-  while (wins.hasMoreElements()) {
-    let win = wins.getNext();
-    f(win);
-  }
-}
-
-function addLoadListener(target, listener) {
-  target.addEventListener("load", function(event) {
-    return listener(event);
-  }, {capture: true, once: true});
-}
-
-var gWin;
-var gBrowser;
-var ok, is, info;
-
-function removeTab(tab, done) {
-  // Remove the tab in a different turn of the event loop. This way
-  // the nested event loop in removeTab doesn't conflict with the
-  // event listener shims.
-  gWin.setTimeout(() => {
-    gBrowser.removeTab(tab);
-    done();
-  }, 0);
-}
-
-// Make sure that the shims for window.content, browser.contentWindow,
-// and browser.contentDocument are working.
-function testContentWindow() {
-  return new Promise(function(resolve, reject) {
-    const url = baseURL + "browser_addonShims_testpage.html";
-    let tab = BrowserTestUtils.addTab(gBrowser, url); // eslint-disable-line no-undef
-    gBrowser.selectedTab = tab;
-    let browser = tab.linkedBrowser;
-    addLoadListener(browser, function handler() {
-      ok(gWin.content, "content is defined on chrome window");
-      ok(browser.contentWindow, "contentWindow is defined");
-      ok(browser.contentDocument, "contentWindow is defined");
-      is(gWin.content, browser.contentWindow, "content === contentWindow");
-      ok(browser.webNavigation.sessionHistory, "sessionHistory is defined");
-
-      ok(browser.contentDocument.getElementById("link"), "link present in document");
-
-      // FIXME: Waiting on bug 1073631.
-      // is(browser.contentWindow.wrappedJSObject.global, 3, "global available on document");
-
-      removeTab(tab, resolve);
-    });
-  });
-}
-
-// Test for bug 1060046 and bug 1072607. We want to make sure that
-// adding and removing listeners works as expected.
-function testListeners() {
-  return new Promise(function(resolve, reject) {
-    const url1 = baseURL + "browser_addonShims_testpage.html";
-    const url2 = baseURL + "browser_addonShims_testpage2.html";
-
-    let tab = BrowserTestUtils.addTab(gBrowser, url2); // eslint-disable-line no-undef
-    let browser = tab.linkedBrowser;
-    addLoadListener(browser, function handler() {
-      function dummyHandler() {}
-
-      // Test that a removed listener stays removed (bug
-      // 1072607). We're looking to make sure that adding and removing
-      // a listener here doesn't cause later listeners to fire more
-      // than once.
-      for (let i = 0; i < 5; i++) {
-        gBrowser.addEventListener("load", dummyHandler, true);
-        gBrowser.removeEventListener("load", dummyHandler, true);
-      }
-
-      // We also want to make sure that this listener doesn't fire
-      // after it's removed.
-      let loadWithRemoveCount = 0;
-      addLoadListener(browser, function handler1(event) {
-        loadWithRemoveCount++;
-        is(event.target.documentURI, url1, "only fire for first url");
-      });
-
-      // Load url1 and then url2. We want to check that:
-      // 1. handler1 only fires for url1.
-      // 2. handler2 only fires once for url1 (so the second time it
-      //    fires should be for url2).
-      let loadCount = 0;
-      browser.addEventListener("load", function handler2(event) {
-        loadCount++;
-        if (loadCount == 1) {
-          is(event.target.documentURI, url1, "first load is for first page loaded");
-          browser.loadURI(url2);
-        } else {
-          gBrowser.removeEventListener("load", handler2, true);
-
-          is(event.target.documentURI, url2, "second load is for second page loaded");
-          is(loadWithRemoveCount, 1, "load handler is only called once");
-
-          removeTab(tab, resolve);
-        }
-      }, true);
-
-      browser.loadURI(url1);
-    });
-  });
-}
-
-// Test for bug 1059207. We want to make sure that adding a capturing
-// listener and a non-capturing listener to the same element works as
-// expected.
-function testCapturing() {
-  return new Promise(function(resolve, reject) {
-    let capturingCount = 0;
-    let nonCapturingCount = 0;
-
-    function capturingHandler(event) {
-      is(capturingCount, 0, "capturing handler called once");
-      is(nonCapturingCount, 0, "capturing handler called before bubbling handler");
-      capturingCount++;
-    }
-
-    function nonCapturingHandler(event) {
-      is(capturingCount, 1, "bubbling handler called after capturing handler");
-      is(nonCapturingCount, 0, "bubbling handler called once");
-      nonCapturingCount++;
-    }
-
-    gBrowser.addEventListener("mousedown", capturingHandler, true);
-    gBrowser.addEventListener("mousedown", nonCapturingHandler);
-
-    const url = baseURL + "browser_addonShims_testpage.html";
-    let tab = BrowserTestUtils.addTab(gBrowser, url); // eslint-disable-line no-undef
-    let browser = tab.linkedBrowser;
-    addLoadListener(browser, function handler() {
-      let win = browser.contentWindow;
-      let event = win.document.createEvent("MouseEvents");
-      event.initMouseEvent("mousedown", true, false, win, 1,
-                           1, 0, 0, 0, // screenX, screenY, clientX, clientY
-                           false, false, false, false, // ctrlKey, altKey, shiftKey, metaKey
-                           0, null); // buttonCode, relatedTarget
-
-      let element = win.document.getElementById("output");
-      element.dispatchEvent(event);
-
-      is(capturingCount, 1, "capturing handler fired");
-      is(nonCapturingCount, 1, "bubbling handler fired");
-
-      gBrowser.removeEventListener("mousedown", capturingHandler, true);
-      gBrowser.removeEventListener("mousedown", nonCapturingHandler);
-
-      removeTab(tab, resolve);
-    });
-  });
-}
-
-// Make sure we get observer notifications that normally fire in the
-// child.
-function testObserver() {
-  return new Promise(function(resolve, reject) {
-    let observerFired = 0;
-
-    function observer(subject, topic, data) {
-      Services.obs.removeObserver(observer, "document-element-inserted");
-      observerFired++;
-    }
-    Services.obs.addObserver(observer, "document-element-inserted");
-
-    let count = 0;
-    const url = baseURL + "browser_addonShims_testpage.html";
-    let tab = BrowserTestUtils.addTab(gBrowser, url); // eslint-disable-line no-undef
-    let browser = tab.linkedBrowser;
-    browser.addEventListener("load", function handler() {
-      count++;
-      if (count == 1) {
-        browser.reload();
-      } else {
-        browser.removeEventListener("load", handler);
-
-        is(observerFired, 1, "got observer notification");
-
-        removeTab(tab, resolve);
-      }
-    }, true);
-  });
-}
-
-// Test for bug 1072472. Make sure that creating a sandbox to run code
-// in the content window works. This is essentially a test for
-// Greasemonkey.
-function testSandbox() {
-  return new Promise(function(resolve, reject) {
-    const url = baseURL + "browser_addonShims_testpage.html";
-    let tab = BrowserTestUtils.addTab(gBrowser, url); // eslint-disable-line no-undef
-    let browser = tab.linkedBrowser;
-    browser.addEventListener("load", function() {
-      let sandbox = Cu.Sandbox(browser.contentWindow,
-                               {sandboxPrototype: browser.contentWindow,
-                                wantXrays: false});
-      Cu.evalInSandbox("const unsafeWindow = window;", sandbox);
-      Cu.evalInSandbox("document.getElementById('output').innerHTML = 'hello';", sandbox);
-
-      is(browser.contentDocument.getElementById("output").innerHTML, "hello",
-         "sandbox code ran successfully");
-
-      // Now try a sandbox with expanded principals.
-      sandbox = Cu.Sandbox([browser.contentWindow],
-                           {sandboxPrototype: browser.contentWindow,
-                            wantXrays: false});
-      Cu.evalInSandbox("const unsafeWindow = window;", sandbox);
-      Cu.evalInSandbox("document.getElementById('output').innerHTML = 'hello2';", sandbox);
-
-      is(browser.contentDocument.getElementById("output").innerHTML, "hello2",
-         "EP sandbox code ran successfully");
-
-      removeTab(tab, resolve);
-    }, {capture: true, once: true});
-  });
-}
-
-// Test for bug 1095305. We just want to make sure that loading some
-// unprivileged content from an add-on package doesn't crash.
-function testAddonContent() {
-  let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"]
-    .getService(Ci.nsIChromeRegistry);
-  let base = chromeRegistry.convertChromeURL(Services.io.newURI("chrome://addonshim1/content/"));
-
-  let res = Services.io.getProtocolHandler("resource")
-    .QueryInterface(Ci.nsIResProtocolHandler);
-  res.setSubstitution("addonshim1", base);
-
-  return new Promise(function(resolve, reject) {
-    const url = "resource://addonshim1/page.html";
-    let tab = BrowserTestUtils.addTab(gBrowser, url); // eslint-disable-line no-undef
-    let browser = tab.linkedBrowser;
-    addLoadListener(browser, function handler() {
-      res.setSubstitution("addonshim1", null);
-      removeTab(tab, resolve);
-    });
-  });
-}
-
-
-// Test for bug 1102410. We check that multiple nsIAboutModule's can be
-// registered in the parent, and that the child can browse to each of
-// the registered about: pages.
-function testAboutModuleRegistration() {
-  let Registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-
-  let modulesToUnregister = new Map();
-
-  function TestChannel(uri, aLoadInfo, aboutName) {
-    this.aboutName = aboutName;
-    this.loadInfo = aLoadInfo;
-    this.URI = this.originalURI = uri;
-  }
-
-  TestChannel.prototype = {
-    asyncOpen(listener, context) {
-      let stream = this.open();
-      let runnable = {
-        run: () => {
-          try {
-            listener.onStartRequest(this, context);
-          } catch (e) {}
-          try {
-            listener.onDataAvailable(this, context, stream, 0, stream.available());
-          } catch (e) {}
-          try {
-            listener.onStopRequest(this, context, Cr.NS_OK);
-          } catch (e) {}
-        }
-      };
-      Services.tm.dispatchToMainThread(runnable);
-    },
-
-    asyncOpen2(listener) {
-      // throws an error if security checks fail
-      var outListener = contentSecManager.performSecurityCheck(this, listener);
-      return this.asyncOpen(outListener, null);
-    },
-
-    open() {
-      function getWindow(channel) {
-        try {
-          if (channel.notificationCallbacks)
-            return channel.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
-        } catch (e) {}
-
-        try {
-          if (channel.loadGroup && channel.loadGroup.notificationCallbacks)
-            return channel.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
-        } catch (e) {}
-
-        return null;
-      }
-
-      let data = `<html><h1>${this.aboutName}</h1></html>`;
-      let wnd = getWindow(this);
-      if (!wnd)
-        throw Cr.NS_ERROR_UNEXPECTED;
-
-      let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
-      stream.setData(data, data.length);
-      return stream;
-    },
-
-    open2() {
-      // throws an error if security checks fail
-      contentSecManager.performSecurityCheck(this, null);
-      return this.open();
-    },
-
-    isPending() {
-      return false;
-    },
-    cancel() {
-      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-    },
-    suspend() {
-      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-    },
-    resume() {
-      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-    },
-
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
-  };
-
-  /**
-   * This function creates a new nsIAboutModule and registers it. Callers
-   * should also call unregisterModules after using this function to clean
-   * up the nsIAboutModules at the end of this test.
-   *
-   * @param aboutName
-   *        This will be the string after about: used to refer to this module.
-   *        For example, if aboutName is foo, you can refer to this module by
-   *        browsing to about:foo.
-   *
-   * @param uuid
-   *        A unique identifer string for this module. For example,
-   *        "5f3a921b-250f-4ac5-a61c-8f79372e6063"
-   */
-  let createAndRegisterAboutModule = function(aboutName, uuid) {
-
-    let AboutModule = function() {};
-
-    AboutModule.prototype = {
-      classID: Components.ID(uuid),
-      classDescription: `Testing About Module for about:${aboutName}`,
-      contractID: `@mozilla.org/network/protocol/about;1?what=${aboutName}`,
-      QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
-
-      newChannel: (aURI, aLoadInfo) => {
-        return new TestChannel(aURI, aLoadInfo, aboutName);
-      },
-
-      getURIFlags: (aURI) => {
-        return Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT |
-               Ci.nsIAboutModule.ALLOW_SCRIPT;
-      },
-    };
-
-    let factory = {
-      createInstance(outer, iid) {
-        if (outer) {
-          throw Cr.NS_ERROR_NO_AGGREGATION;
-        }
-        return new AboutModule();
-      },
-    };
-
-    Registrar.registerFactory(AboutModule.prototype.classID,
-                              AboutModule.prototype.classDescription,
-                              AboutModule.prototype.contractID,
-                              factory);
-
-    modulesToUnregister.set(AboutModule.prototype.classID,
-                            factory);
-  };
-
-  /**
-   * Unregisters any nsIAboutModules registered with
-   * createAndRegisterAboutModule.
-   */
-  let unregisterModules = () => {
-    for (let [classID, factory] of modulesToUnregister) {
-      Registrar.unregisterFactory(classID, factory);
-    }
-  };
-
-  /**
-   * Takes a browser, and sends it a framescript to attempt to
-   * load some about: pages. The frame script will send a test:result
-   * message on completion, passing back a data object with:
-   *
-   * {
-   *   pass: true
-   * }
-   *
-   * on success, and:
-   *
-   * {
-   *   pass: false,
-   *   errorMsg: message,
-   * }
-   *
-   * on failure.
-   *
-   * @param browser
-   *        The browser to send the framescript to.
-   */
-  let testAboutModulesWork = (browser) => {
-    let testConnection = () => {
-      // This section is loaded into a frame script.
-      /* global content:false */
-      let request = new content.XMLHttpRequest();
-      try {
-        request.open("GET", "about:test1", false);
-        request.send(null);
-        if (request.status != 200) {
-          throw (`about:test1 response had status ${request.status} - expected 200`);
-        }
-        if (!request.responseText.includes("test1")) {
-          throw (`about:test1 response had result ${request.responseText}`);
-        }
-
-        request = new content.XMLHttpRequest();
-        request.open("GET", "about:test2", false);
-        request.send(null);
-
-        if (request.status != 200) {
-          throw (`about:test2 response had status ${request.status} - expected 200`);
-        }
-        if (!request.responseText.includes("test2")) {
-          throw (`about:test2 response had result ${request.responseText}`);
-        }
-
-        sendAsyncMessage("test:result", {
-          pass: true,
-        });
-      } catch (e) {
-        sendAsyncMessage("test:result", {
-          pass: false,
-          errorMsg: e.toString(),
-        });
-      }
-    };
-
-    return new Promise((resolve, reject) => {
-      let mm = browser.messageManager;
-      mm.addMessageListener("test:result", function onTestResult(message) {
-        mm.removeMessageListener("test:result", onTestResult);
-        if (message.data.pass) {
-          ok(true, "Connections to about: pages were successful");
-        } else {
-          ok(false, message.data.errorMsg);
-        }
-        resolve();
-      });
-      mm.loadFrameScript("data:,(" + testConnection.toString() + ")();", false);
-    });
-  };
-
-  // Here's where the actual test is performed.
-  return new Promise((resolve, reject) => {
-    createAndRegisterAboutModule("test1", "5f3a921b-250f-4ac5-a61c-8f79372e6063");
-    createAndRegisterAboutModule("test2", "d7ec0389-1d49-40fa-b55c-a1fc3a6dbf6f");
-
-    // This needs to be a chrome-privileged page that loads in the
-    // content process. It needs chrome privs because otherwise the
-    // XHRs for about:test[12] will fail with a privilege error
-    // despite the presence of URI_SAFE_FOR_UNTRUSTED_CONTENT.
-    let newTab = BrowserTestUtils.addTab(gBrowser, "chrome://addonshim1/content/page.html"); // eslint-disable-line no-undef
-    gBrowser.selectedTab = newTab;
-    let browser = newTab.linkedBrowser;
-
-    addLoadListener(browser, function() {
-      testAboutModulesWork(browser).then(() => {
-        unregisterModules();
-        removeTab(newTab, resolve);
-      });
-    });
-  });
-}
-
-function testProgressListener() {
-  const url = baseURL + "browser_addonShims_testpage.html";
-
-  let sawGlobalLocChange = false;
-  let sawTabsLocChange = false;
-
-  let globalListener = {
-    onLocationChange(webProgress, request, uri) {
-      if (uri.spec == url) {
-        sawGlobalLocChange = true;
-        ok(request instanceof Ci.nsIHttpChannel, "Global listener channel is an HTTP channel");
-      }
-    },
-  };
-
-  let tabsListener = {
-    onLocationChange(browser, webProgress, request, uri) {
-      if (uri.spec == url) {
-        sawTabsLocChange = true;
-        ok(request instanceof Ci.nsIHttpChannel, "Tab listener channel is an HTTP channel");
-      }
-    },
-  };
-
-  gBrowser.addProgressListener(globalListener);
-  gBrowser.addTabsProgressListener(tabsListener);
-  info("Added progress listeners");
-
-  return new Promise(function(resolve, reject) {
-    let tab = BrowserTestUtils.addTab(gBrowser, url); // eslint-disable-line no-undef
-    gBrowser.selectedTab = tab;
-    addLoadListener(tab.linkedBrowser, function handler() {
-      ok(sawGlobalLocChange, "Saw global onLocationChange");
-      ok(sawTabsLocChange, "Saw tabs onLocationChange");
-
-      gBrowser.removeProgressListener(globalListener);
-      gBrowser.removeTabsProgressListener(tabsListener);
-      removeTab(tab, resolve);
-    });
-  });
-}
-
-function testRootTreeItem() {
-  return new Promise(function(resolve, reject) {
-    const url = baseURL + "browser_addonShims_testpage.html";
-    let tab = BrowserTestUtils.addTab(gBrowser, url); // eslint-disable-line no-undef
-    gBrowser.selectedTab = tab;
-    let browser = tab.linkedBrowser;
-    addLoadListener(browser, function handler() {
-      let win = browser.contentWindow;
-
-      // Add-ons love this crap.
-      let root = win.QueryInterface(Ci.nsIInterfaceRequestor)
-                    .getInterface(Ci.nsIWebNavigation)
-                    .QueryInterface(Ci.nsIDocShellTreeItem)
-                    .rootTreeItem
-                    .QueryInterface(Ci.nsIInterfaceRequestor)
-                    .getInterface(Ci.nsIDOMWindow);
-      is(root, gWin, "got correct chrome window");
-
-      removeTab(tab, resolve);
-    });
-  });
-}
-
-function testImportNode() {
-  return new Promise(function(resolve, reject) {
-    const url = baseURL + "browser_addonShims_testpage.html";
-    let tab = BrowserTestUtils.addTab(gBrowser, url); // eslint-disable-line no-undef
-    gBrowser.selectedTab = tab;
-    let browser = tab.linkedBrowser;
-    addLoadListener(browser, function handler() {
-      let node = gWin.document.createElement("div");
-      let doc = browser.contentDocument;
-      let result;
-      try {
-        result = doc.importNode(node, false);
-      } catch (e) {
-        ok(false, "importing threw an exception");
-      }
-      if (browser.isRemoteBrowser) {
-        is(result, node, "got expected import result");
-      }
-
-      removeTab(tab, resolve);
-    });
-  });
-}
-
-function runTests(win, funcs) {
-  ok = funcs.ok;
-  is = funcs.is;
-  info = funcs.info;
-
-  gWin = win;
-  gBrowser = win.gBrowser;
-
-  return testContentWindow().
-    then(testListeners).
-    then(testCapturing).
-    then(testObserver).
-    then(testSandbox).
-    then(testAddonContent).
-    then(testAboutModuleRegistration).
-    then(testProgressListener).
-    then(testRootTreeItem).
-    then(testImportNode).
-    then(Promise.resolve());
-}
-
-/*
- bootstrap.js API
-*/
-
-function startup(aData, aReason) {
-  forEachWindow(win => {
-    win.runAddonShimTests = (funcs) => runTests(win, funcs);
-  });
-}
-
-function shutdown(aData, aReason) {
-  forEachWindow(win => {
-    delete win.runAddonShimTests;
-  });
-}
-
-function install(aData, aReason) {
-}
-
-function uninstall(aData, aReason) {
-}
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/addon/chrome.manifest
+++ /dev/null
@@ -1,1 +0,0 @@
-content addonshim1 content/
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/addon/content/page.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<html>
-</html>
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/addon/install.rdf
+++ /dev/null
@@ -1,37 +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-addon-shim-1@tests.mozilla.org</em:id>
-    <em:version>1</em:version>
-    <em:type>2</em:type>
-    <em:bootstrap>true</em:bootstrap>
-
-    <!-- Front End MetaData -->
-    <em:name>Test addon shim 1</em:name>
-    <em:description>Test an add-on that needs multiprocess shims.</em:description>
-    <em:multiprocessCompatible>false</em:multiprocessCompatible>
-
-    <em:iconURL>chrome://foo/skin/icon.png</em:iconURL>
-    <em:aboutURL>chrome://foo/content/about.xul</em:aboutURL>
-    <em:optionsURL>chrome://foo/content/options.xul</em:optionsURL>
-
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>0.3</em:minVersion>
-        <em:maxVersion>*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <em:targetApplication>
-      <Description>
-        <em:id>toolkit@mozilla.org</em:id>
-        <em:minVersion>10.0</em:minVersion>
-        <em:maxVersion>*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-  </Description>
-</RDF>
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
-  "extends": [
-    "plugin:mozilla/browser-test"
-  ]
-};
deleted file mode 100644
index e6392fb40a1c917dcd967cd426555613a11e1bd9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/browser/browser.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[DEFAULT]
-tags = addons
-support-files =
-  addon.xpi
-  browser_addonShims_testpage.html
-  browser_addonShims_testpage2.html
-  compat-addon.xpi
-
-[browser_addonShims.js]
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/browser/browser_addonShims.js
+++ /dev/null
@@ -1,62 +0,0 @@
-var {AddonManager} = ChromeUtils.import("resource://gre/modules/AddonManager.jsm", {});
-var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
-
-const ADDON_URL = "http://example.com/browser/toolkit/components/addoncompat/tests/browser/addon.xpi";
-const COMPAT_ADDON_URL = "http://example.com/browser/toolkit/components/addoncompat/tests/browser/compat-addon.xpi";
-
-// Install a test add-on that will exercise e10s shims.
-//   url: Location of the add-on.
-function addAddon(url) {
-  info("Installing add-on: " + url);
-
-  return new Promise(function(resolve, reject) {
-    AddonManager.getInstallForURL(url, installer => {
-      installer.install();
-      let listener = {
-        onInstallEnded(addon, addonInstall) {
-          installer.removeListener(listener);
-
-          // Wait for add-on's startup scripts to execute. See bug 997408
-          executeSoon(function() {
-            resolve(addonInstall);
-          });
-        }
-      };
-      installer.addListener(listener);
-    }, "application/x-xpinstall");
-  });
-}
-
-// Uninstall a test add-on.
-//   addon: The addon reference returned from addAddon.
-function removeAddon(addon) {
-  info("Removing addon.");
-
-  return new Promise(function(resolve, reject) {
-    let listener = {
-      onUninstalled(uninstalledAddon) {
-        if (uninstalledAddon != addon) {
-          return;
-        }
-        AddonManager.removeAddonListener(listener);
-        resolve();
-      }
-    };
-    AddonManager.addAddonListener(listener);
-    addon.uninstall();
-  });
-}
-
-add_task(async function test_addon_shims() {
-  await SpecialPowers.pushPrefEnv({set: [["dom.ipc.shims.enabledWarnings", true]]});
-
-  let addon = await addAddon(ADDON_URL);
-  await window.runAddonShimTests({ok, is, info});
-  await removeAddon(addon);
-
-  if (Services.appinfo.browserTabsRemoteAutostart) {
-    addon = await addAddon(COMPAT_ADDON_URL);
-    await window.runAddonTests({ok, is, info});
-    await removeAddon(addon);
-  }
-});
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/browser/browser_addonShims_testpage.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>shim test</title>
-</head>
-
-<body>
-Hello!
-
-<a href="browser_addonShims_testpage2.html" id="link">Link</a>
-<div id="output"></div>
-
-<script type="text/javascript">
-var global = 3;
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/browser/browser_addonShims_testpage2.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>shim test</title>
-</head>
-
-<body>
-Hello!
-
-<a href="browser_addonShims_testpage.html" id="link">Link</a>
-
-<script type="text/javascript">
-var global = 5;
-</script>
-</body>
-</html>
deleted file mode 100644
index c7ca32cdc69a519c9258931b6ad982d911b657e6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/compat-addon/bootstrap.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// This file defines a frame script.
-/* eslint-env mozilla/frame-script */
-
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/BrowserUtils.jsm");
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const baseURL = "http://mochi.test:8888/browser/" +
-  "toolkit/components/addoncompat/tests/browser/";
-
-function forEachWindow(f) {
-  let wins = Services.wm.getEnumerator("navigator:browser");
-  while (wins.hasMoreElements()) {
-    let win = wins.getNext();
-    f(win);
-  }
-}
-
-function addLoadListener(target, listener) {
-  function frameScript() {
-    addEventListener("load", function handler(event) {
-      removeEventListener("load", handler, true);
-      sendAsyncMessage("compat-test:loaded");
-    }, true);
-  }
-  target.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false);
-  target.messageManager.addMessageListener("compat-test:loaded", function handler() {
-    target.messageManager.removeMessageListener("compat-test:loaded", handler);
-    listener();
-  });
-}
-
-var gWin;
-var gBrowser;
-var ok, is, info;
-
-// Make sure that the shims for window.content, browser.contentWindow,
-// and browser.contentDocument are working.
-function testContentWindow() {
-  return new Promise(function(resolve, reject) {
-    const url = baseURL + "browser_addonShims_testpage.html";
-    let tab = BrowserTestUtils.addTab(gBrowser, "about:blank"); // eslint-disable-line no-undef
-    gBrowser.selectedTab = tab;
-    let browser = tab.linkedBrowser;
-    addLoadListener(browser, function handler() {
-      ok(!gWin.content, "content is defined on chrome window");
-      ok(!browser.contentWindow, "contentWindow is defined");
-      ok(!browser.contentDocument, "contentWindow is defined");
-
-      gBrowser.removeTab(tab);
-      resolve();
-    });
-    browser.loadURI(url);
-  });
-}
-
-function runTests(win, funcs) {
-  ok = funcs.ok;
-  is = funcs.is;
-  info = funcs.info;
-
-  gWin = win;
-  gBrowser = win.gBrowser;
-
-  return testContentWindow();
-}
-
-/*
- bootstrap.js API
-*/
-
-function startup(aData, aReason) {
-  forEachWindow(win => {
-    win.runAddonTests = (funcs) => runTests(win, funcs);
-  });
-}
-
-function shutdown(aData, aReason) {
-  forEachWindow(win => {
-    delete win.runAddonTests;
-  });
-}
-
-function install(aData, aReason) {
-}
-
-function uninstall(aData, aReason) {
-}
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/compat-addon/install.rdf
+++ /dev/null
@@ -1,37 +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-addon-shim-2@tests.mozilla.org</em:id>
-    <em:version>1</em:version>
-    <em:type>2</em:type>
-    <em:bootstrap>true</em:bootstrap>
-
-    <!-- Front End MetaData -->
-    <em:name>Test addon shims 2</em:name>
-    <em:description>Test an add-on that doesn't need multiprocess shims.</em:description>
-    <em:multiprocessCompatible>true</em:multiprocessCompatible>
-
-    <em:iconURL>chrome://foo/skin/icon.png</em:iconURL>
-    <em:aboutURL>chrome://foo/content/about.xul</em:aboutURL>
-    <em:optionsURL>chrome://foo/content/options.xul</em:optionsURL>
-
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>0.3</em:minVersion>
-        <em:maxVersion>*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <em:targetApplication>
-      <Description>
-        <em:id>toolkit@mozilla.org</em:id>
-        <em:minVersion>10.0</em:minVersion>
-        <em:maxVersion>*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-  </Description>
-</RDF>
deleted file mode 100644
--- a/toolkit/components/addoncompat/tests/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-BROWSER_CHROME_MANIFESTS += ['browser/browser.ini']