Bug 1492700 - Introduce adb singleton to register adb consumers;r=daisuke
authorJulian Descottes <jdescottes@mozilla.com>
Thu, 06 Dec 2018 14:57:03 +0000
changeset 508740 738cae90db60f99317bc2418e36a99a5c703eef3
parent 508739 c804e90f0ce5daec220046b51a387a4edcd59294
child 508741 ec57d6145de761043cb3dadb2a2eac4df951665e
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdaisuke
bugs1492700
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1492700 - Introduce adb singleton to register adb consumers;r=daisuke Depends on D13476 Differential Revision: https://phabricator.services.mozilla.com/D13477
devtools/client/aboutdebugging-new/aboutdebugging.js
devtools/client/aboutdebugging-new/src/modules/usb-runtimes.js
devtools/client/webide/modules/runtimes.js
devtools/shared/adb/adb-devices-registry.js
devtools/shared/adb/adb-scanner.js
devtools/shared/adb/adb.js
devtools/shared/adb/addon-aware-adb-scanner.js
devtools/shared/adb/moz.build
devtools/shared/adb/test/test_addon-aware-adb-scanner.js
devtools/shared/adb/test/xpcshell.ini
--- a/devtools/client/aboutdebugging-new/aboutdebugging.js
+++ b/devtools/client/aboutdebugging-new/aboutdebugging.js
@@ -23,18 +23,16 @@ const { l10n } = require("./src/modules/
 
 const {
   addNetworkLocationsObserver,
   getNetworkLocations,
   removeNetworkLocationsObserver,
 } = require("./src/modules/network-locations");
 const {
   addUSBRuntimesObserver,
-  disableUSBRuntimes,
-  enableUSBRuntimes,
   getUSBRuntimes,
   removeUSBRuntimesObserver,
 } = require("./src/modules/usb-runtimes");
 
 loader.lazyRequireGetter(this, "adbAddon", "devtools/shared/adb/adb-addon", true);
 
 const Router = createFactory(require("devtools/client/shared/vendor/react-router-dom").HashRouter);
 const App = createFactory(require("./src/components/App"));
@@ -71,18 +69,20 @@ const AboutDebugging = {
         )
       ),
       this.mount
     );
 
     this.actions.updateNetworkLocations(getNetworkLocations());
 
     addNetworkLocationsObserver(this.onNetworkLocationsUpdated);
+
+    // Listen to USB runtime updates and retrieve the initial list of runtimes.
     addUSBRuntimesObserver(this.onUSBRuntimesUpdated);
-    await enableUSBRuntimes();
+    getUSBRuntimes();
 
     adbAddon.on("update", this.onAdbAddonUpdated);
     this.onAdbAddonUpdated();
 
     // Remove deprecated remote debugging extensions.
     await adbAddon.uninstallUnsupportedExtensions();
   },
 
@@ -108,17 +108,16 @@ const AboutDebugging = {
       await this.actions.unwatchRuntime(currentRuntimeId);
     }
 
     // Remove all client listeners.
     this.actions.removeRuntimeListeners();
 
     removeNetworkLocationsObserver(this.onNetworkLocationsUpdated);
     removeUSBRuntimesObserver(this.onUSBRuntimesUpdated);
-    disableUSBRuntimes();
     adbAddon.off("update", this.onAdbAddonUpdated);
     setDebugTargetCollapsibilities(state.ui.debugTargetCollapsibilities);
     unmountComponentAtNode(this.mount);
   },
 
   get mount() {
     return document.getElementById("mount");
   },
--- a/devtools/client/aboutdebugging-new/src/modules/usb-runtimes.js
+++ b/devtools/client/aboutdebugging-new/src/modules/usb-runtimes.js
@@ -1,46 +1,33 @@
 /* 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/. */
 
 "use strict";
 
-loader.lazyGetter(this, "adbScanner", () => {
-  const { AddonAwareADBScanner } = require("devtools/shared/adb/addon-aware-adb-scanner");
-  return new AddonAwareADBScanner();
-});
+loader.lazyRequireGetter(this, "adb", "devtools/shared/adb/adb", true);
 
 /**
  * This module provides a collection of helper methods to detect USB runtimes whom Firefox
  * is running on.
  */
 function addUSBRuntimesObserver(listener) {
-  adbScanner.on("runtime-list-updated", listener);
+  adb.registerListener(listener);
 }
 exports.addUSBRuntimesObserver = addUSBRuntimesObserver;
 
-function disableUSBRuntimes() {
-  adbScanner.disable();
-}
-exports.disableUSBRuntimes = disableUSBRuntimes;
-
-async function enableUSBRuntimes() {
-  adbScanner.enable();
-}
-exports.enableUSBRuntimes = enableUSBRuntimes;
-
 function getUSBRuntimes() {
-  return adbScanner.listRuntimes();
+  return adb.getRuntimes();
 }
 exports.getUSBRuntimes = getUSBRuntimes;
 
 function removeUSBRuntimesObserver(listener) {
-  adbScanner.off("runtime-list-updated", listener);
+  adb.unregisterListener(listener);
 }
 exports.removeUSBRuntimesObserver = removeUSBRuntimesObserver;
 
 function refreshUSBRuntimes() {
-  return adbScanner.scan();
+  return adb.updateRuntimes();
 }
 exports.refreshUSBRuntimes = refreshUSBRuntimes;
 
 require("./test-helper").enableMocks(module, "modules/usb-runtimes");
--- a/devtools/client/webide/modules/runtimes.js
+++ b/devtools/client/webide/modules/runtimes.js
@@ -6,20 +6,17 @@
 
 const Services = require("Services");
 const {DebuggerServer} = require("devtools/server/main");
 const discovery = require("devtools/shared/discovery/discovery");
 const EventEmitter = require("devtools/shared/event-emitter");
 const {RuntimeTypes} = require("devtools/client/webide/modules/runtime-types");
 const promise = require("promise");
 
-loader.lazyGetter(this, "adbScanner", () => {
-  const { AddonAwareADBScanner } = require("devtools/shared/adb/addon-aware-adb-scanner");
-  return new AddonAwareADBScanner();
-});
+loader.lazyRequireGetter(this, "adb", "devtools/shared/adb/adb", true);
 
 loader.lazyRequireGetter(this, "AuthenticationResult",
   "devtools/shared/security/auth", true);
 loader.lazyRequireGetter(this, "DevToolsUtils",
   "devtools/shared/DevToolsUtils");
 
 const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties");
 
@@ -193,19 +190,39 @@ var RuntimeScanners = {
 };
 
 EventEmitter.decorate(RuntimeScanners);
 
 exports.RuntimeScanners = RuntimeScanners;
 
 /* SCANNERS */
 
-// The adb-scanner will automatically start and stop when the ADB extension is installed
-// and uninstalled, so the scanner itself can always be used.
-RuntimeScanners.add(adbScanner);
+var UsbScanner = {
+  init() {
+    this._emitUpdated = this._emitUpdated.bind(this);
+  },
+  enable() {
+    adb.registerListener(this._emitUpdated);
+  },
+  disable() {
+    adb.unregisterListener(this._emitUpdated);
+  },
+  scan() {
+    return adb.updateRuntimes();
+  },
+  listRuntimes() {
+    return adb.getRuntimes();
+  },
+  _emitUpdated() {
+    this.emit("runtime-list-updated");
+  },
+};
+EventEmitter.decorate(UsbScanner);
+UsbScanner.init();
+RuntimeScanners.add(UsbScanner);
 
 var WiFiScanner = {
 
   _runtimes: [],
 
   init() {
     this.updateRegistration();
     Services.prefs.addObserver(this.ALLOWED_PREF, this);
deleted file mode 100644
--- a/devtools/shared/adb/adb-devices-registry.js
+++ /dev/null
@@ -1,80 +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/. */
-
-"use strict";
-
-const EventEmitter = require("devtools/shared/event-emitter");
-const { adbAddon, ADB_ADDON_STATES } = require("devtools/shared/adb/adb-addon");
-
-/**
- * Shared registry that will hold all the detected devices from ADB.
- * Extends EventEmitter and emits the following events:
- * - "register": a new device has been registered
- * - "unregister": a device has been unregistered
- */
-class AdbDevicesRegistry extends EventEmitter {
-  constructor() {
-    super();
-
-    // Internal object to store the discovered adb devices.
-    this._devices = {};
-
-    // When the addon is uninstalled, the repository should be emptied.
-    // TODO: This should also be done when ADB is stopped.
-    this._onAdbAddonUpdate = this._onAdbAddonUpdate.bind(this);
-    adbAddon.on("update", this._onAdbAddonUpdate);
-  }
-
-  /**
-   * Register a device (Device class defined in from adb-device.js) for the provided name.
-   *
-   * @param {String} name
-   *        Name of the device.
-   * @param {AdbDevice} device
-   *        The device to register.
-   */
-  register(name, device) {
-    this._devices[name] = device;
-    this.emit("register");
-  }
-
-  /**
-   * Unregister a device previously registered under the provided name.
-   *
-   * @param {String} name
-   *        Name of the device.
-   */
-  unregister(name) {
-    delete this._devices[name];
-    this.emit("unregister");
-  }
-
-  /**
-   * Returns an iterable containing the name of all the available devices, sorted by name.
-   */
-  available() {
-    return Object.keys(this._devices).sort();
-  }
-
-  /**
-   * Returns a device previously registered under the provided name.
-   *
-   * @param {String} name
-   *        Name of the device.
-   */
-  getByName(name) {
-    return this._devices[name];
-  }
-
-  _onAdbAddonUpdate() {
-    const installed = adbAddon.status === ADB_ADDON_STATES.INSTALLED;
-    if (!installed) {
-      for (const name in this._devices) {
-        this.unregister(name);
-      }
-    }
-  }
-}
-
-exports.adbDevicesRegistry = new AdbDevicesRegistry();
deleted file mode 100644
--- a/devtools/shared/adb/adb-scanner.js
+++ /dev/null
@@ -1,100 +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/. */
-
-"use strict";
-
-const EventEmitter = require("devtools/shared/event-emitter");
-const { dumpn } = require("devtools/shared/DevToolsUtils");
-const { adbProcess } = require("devtools/shared/adb/adb-process");
-const { TrackDevicesCommand } = require("devtools/shared/adb/commands/index");
-const { adbDevicesRegistry } = require("devtools/shared/adb/adb-devices-registry");
-const { AdbRuntime } = require("devtools/shared/adb/adb-runtime");
-
-loader.lazyRequireGetter(this, "AdbDevice", "devtools/shared/adb/adb-device");
-
-class ADBScanner extends EventEmitter {
-  constructor() {
-    super();
-    this._runtimes = [];
-    this._trackDevicesCommand = new TrackDevicesCommand();
-
-    this._onDeviceConnected = this._onDeviceConnected.bind(this);
-    this._onDeviceDisconnected = this._onDeviceDisconnected.bind(this);
-    this._updateRuntimes = this._updateRuntimes.bind(this);
-  }
-
-  enable() {
-    this._trackDevicesCommand.on("device-connected", this._onDeviceConnected);
-    this._trackDevicesCommand.on("device-disconnected", this._onDeviceDisconnected);
-
-    adbDevicesRegistry.on("register", this._updateRuntimes);
-    adbDevicesRegistry.on("unregister", this._updateRuntimes);
-
-    adbProcess.start().then(() => {
-      this._trackDevicesCommand.run();
-    });
-    this._updateRuntimes();
-  }
-
-  disable() {
-    this._trackDevicesCommand.off("device-connected", this._onDeviceConnected);
-    this._trackDevicesCommand.off("device-disconnected", this._onDeviceDisconnected);
-    adbDevicesRegistry.off("register", this._updateRuntimes);
-    adbDevicesRegistry.off("unregister", this._updateRuntimes);
-    this._updateRuntimes();
-  }
-
-  _emitUpdated() {
-    this.emit("runtime-list-updated");
-  }
-
-  _onDeviceConnected(deviceId) {
-    const device = new AdbDevice(deviceId);
-    adbDevicesRegistry.register(deviceId, device);
-  }
-
-  _onDeviceDisconnected(deviceId) {
-    adbDevicesRegistry.unregister(deviceId);
-  }
-
-  _updateRuntimes() {
-    if (this._updatingPromise) {
-      return this._updatingPromise;
-    }
-    this._runtimes = [];
-    const promises = [];
-    for (const id of adbDevicesRegistry.available()) {
-      const device = adbDevicesRegistry.getByName(id);
-      promises.push(this._detectRuntimes(device));
-    }
-    this._updatingPromise = Promise.all(promises);
-    this._updatingPromise.then(() => {
-      this._emitUpdated();
-      this._updatingPromise = null;
-    }, () => {
-      this._updatingPromise = null;
-    });
-    return this._updatingPromise;
-  }
-
-  async _detectRuntimes(adbDevice) {
-    const model = await adbDevice.getModel();
-    const socketPaths = await adbDevice.getRuntimeSocketPaths();
-    for (const socketPath of socketPaths) {
-      const runtime = new AdbRuntime(adbDevice, model, socketPath);
-      dumpn("Found " + runtime.name);
-      this._runtimes.push(runtime);
-    }
-  }
-
-  scan() {
-    return this._updateRuntimes();
-  }
-
-  listRuntimes() {
-    return this._runtimes;
-  }
-}
-
-exports.ADBScanner = ADBScanner;
new file mode 100644
--- /dev/null
+++ b/devtools/shared/adb/adb.js
@@ -0,0 +1,111 @@
+/* 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/. */
+
+"use strict";
+
+const EventEmitter = require("devtools/shared/event-emitter");
+const { adbProcess } = require("devtools/shared/adb/adb-process");
+const { adbAddon } = require("devtools/shared/adb/adb-addon");
+const AdbDevice = require("devtools/shared/adb/adb-device");
+const { AdbRuntime } = require("devtools/shared/adb/adb-runtime");
+const { TrackDevicesCommand } = require("devtools/shared/adb/commands/track-devices");
+
+class Adb extends EventEmitter {
+  constructor() {
+    super();
+
+    this._trackDevicesCommand = new TrackDevicesCommand();
+
+    this._isTrackingDevices = false;
+    this._isUpdatingRuntimes = false;
+
+    this._listeners = new Set();
+    this._devices = new Map();
+    this._runtimes = [];
+
+    this._updateAdbProcess = this._updateAdbProcess.bind(this);
+    this._onDeviceConnected = this._onDeviceConnected.bind(this);
+    this._onDeviceDisconnected = this._onDeviceDisconnected.bind(this);
+
+    this._trackDevicesCommand.on("device-connected", this._onDeviceConnected);
+    this._trackDevicesCommand.on("device-disconnected", this._onDeviceDisconnected);
+    adbAddon.on("update", this._updateAdbProcess);
+  }
+
+  registerListener(listener) {
+    this._listeners.add(listener);
+    this.on("runtime-list-updated", listener);
+    this._updateAdbProcess();
+  }
+
+  unregisterListener(listener) {
+    this._listeners.delete(listener);
+    this.off("runtime-list-updated", listener);
+    this._updateAdbProcess();
+  }
+
+  async updateRuntimes() {
+    try {
+      const devices = [...this._devices.values()];
+      const promises = devices.map(d => this._getDeviceRuntimes(d));
+      const allRuntimes = await Promise.all(promises);
+
+      this._runtimes = allRuntimes.flat();
+      this.emit("runtime-list-updated");
+    } catch (e) {
+      console.error(e);
+    }
+  }
+
+  getRuntimes() {
+    return this._runtimes;
+  }
+
+  async _startAdb() {
+    this._isTrackingDevices = true;
+    await adbProcess.start();
+
+    this._trackDevicesCommand.run();
+  }
+
+  async _stopAdb() {
+    this._isTrackingDevices = false;
+    this._trackDevicesCommand.stop();
+    await adbProcess.stop();
+
+    this._devices = new Map();
+    this._runtimes = [];
+    this.updateRuntimes();
+  }
+
+  _shouldTrack() {
+    return adbAddon.status === "installed" && this._listeners.size > 0;
+  }
+
+  _updateAdbProcess() {
+    if (!this._isTrackingDevices && this._shouldTrack()) {
+      this._startAdb();
+    } else if (this._isTrackingDevices && !this._shouldTrack()) {
+      this._stopAdb();
+    }
+  }
+
+  _onDeviceConnected(deviceId) {
+    this._devices.set(deviceId, new AdbDevice(deviceId));
+    this.updateRuntimes();
+  }
+
+  _onDeviceDisconnected(deviceId) {
+    this._devices.delete(deviceId);
+    this.updateRuntimes();
+  }
+
+  async _getDeviceRuntimes(device) {
+    const model = await device.getModel();
+    const socketPaths = await device.getRuntimeSocketPaths();
+    return [...socketPaths].map(socketPath => new AdbRuntime(device, model, socketPath));
+  }
+}
+
+exports.adb = new Adb();
deleted file mode 100644
--- a/devtools/shared/adb/addon-aware-adb-scanner.js
+++ /dev/null
@@ -1,98 +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/. */
-
-"use strict";
-
-const EventEmitter = require("devtools/shared/event-emitter");
-
-loader.lazyRequireGetter(this, "adbAddon", "devtools/shared/adb/adb-addon", true);
-loader.lazyRequireGetter(this, "ADBScanner", "devtools/shared/adb/adb-scanner", true);
-
-/**
- * The AddonAwareADBScanner decorates an instance of ADBScanner. It will wait until the
- * ADB addon is installed to enable() the real scanner, and will automatically disable
- * it if the addon is uninstalled.
- *
- * It implements the following public API of ADBScanner:
- * - enable
- * - disable
- * - scan
- * - listRuntimes
- * - event "runtime-list-updated"
- */
-class AddonAwareADBScanner extends EventEmitter {
-  /**
-   * Parameters are provided only to allow tests to replace actual implementations with
-   * mocks.
-   *
-   * @param {ADBScanner} scanner
-   *        Only provided in tests for mocks
-   * @param {ADBAddon} addon
-   *        Only provided in tests for mocks
-   */
-  constructor(scanner = new ADBScanner(), addon = adbAddon) {
-    super();
-
-    this._onScannerListUpdated = this._onScannerListUpdated.bind(this);
-    this._onAddonUpdate = this._onAddonUpdate.bind(this);
-
-    this._scanner = scanner;
-    this._scanner.on("runtime-list-updated", this._onScannerListUpdated);
-
-    this._addon = addon;
-  }
-
-  /**
-   * Only forward the enable() call if the addon is installed, because ADBScanner::enable
-   * only works if the addon is installed.
-   */
-  enable() {
-    if (this._addon.status === "installed") {
-      this._scanner.enable();
-    }
-
-    // Remove any previous listener, to make sure we only add one listener if enable() is
-    // called several times.
-    this._addon.off("update", this._onAddonUpdate);
-
-    this._addon.on("update", this._onAddonUpdate);
-  }
-
-  disable() {
-    this._scanner.disable();
-
-    this._addon.off("update", this._onAddonUpdate);
-  }
-
-  /**
-   * Scan for USB devices.
-   *
-   * @return {Promise} Promise that will resolve when the scan is completed.
-   */
-  scan() {
-    return this._scanner.scan();
-  }
-
-  /**
-   * Get the list of currently detected runtimes.
-   *
-   * @return {Array} Array of currently detected runtimes.
-   */
-  listRuntimes() {
-    return this._scanner.listRuntimes();
-  }
-
-  _onAddonUpdate() {
-    if (this._addon.status === "installed") {
-      this._scanner.enable();
-    } else {
-      this._scanner.disable();
-    }
-  }
-
-  _onScannerListUpdated() {
-    this.emit("runtime-list-updated");
-  }
-}
-exports.AddonAwareADBScanner = AddonAwareADBScanner;
--- a/devtools/shared/adb/moz.build
+++ b/devtools/shared/adb/moz.build
@@ -6,21 +6,19 @@ DIRS += [
     'commands',
 ]
 
 DevToolsModules(
     'adb-addon.js',
     'adb-binary.js',
     'adb-client.js',
     'adb-device.js',
-    'adb-devices-registry.js',
     'adb-process.js',
     'adb-running-checker.js',
     'adb-runtime.js',
-    'adb-scanner.js',
     'adb-socket.js',
-    'addon-aware-adb-scanner.js',
+    'adb.js',
 )
 
 with Files('**'):
     BUG_COMPONENT = ('DevTools', 'about:debugging')
 
 XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini']
deleted file mode 100644
--- a/devtools/shared/adb/test/test_addon-aware-adb-scanner.js
+++ /dev/null
@@ -1,221 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const EventEmitter = require("devtools/shared/event-emitter");
-const { AddonAwareADBScanner } = require("devtools/shared/adb/addon-aware-adb-scanner");
-
-/**
- * For the scanner mock, we create an object with spies for each of the public methods
- * used by the AddonAwareADBScanner, and the ability to emit events.
- */
-function prepareMockScanner() {
-  const mockScanner = {
-    enable: sinon.spy(),
-    disable: sinon.spy(),
-    scan: sinon.spy(),
-    listRuntimes: sinon.spy(),
-  };
-  EventEmitter.decorate(mockScanner);
-  return mockScanner;
-}
-
-/**
- * For the addon mock, we simply need an object that is able to emit events and has a
- * status.
- */
-function prepareMockAddon() {
-  const mockAddon = {
-    status: "unknown",
-  };
-  EventEmitter.decorate(mockAddon);
-  return mockAddon;
-}
-
-/**
- * Prepare all mocks needed for the scanner tests.
- */
-function prepareMocks() {
-  const mockScanner = prepareMockScanner();
-  const mockAddon = prepareMockAddon();
-  const addonAwareAdbScanner = new AddonAwareADBScanner(mockScanner, mockAddon);
-  return { addonAwareAdbScanner, mockAddon, mockScanner };
-}
-
-/**
- * This test covers basic usage of enable() on the AddonAwareADBScanner, and checks the
- * different behaviors based on the addon status.
- */
-add_task(async function testCallingEnable() {
-  const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
-
-  // Check that enable() is not called if the addon is uninstalled
-  mockAddon.status = "uninstalled";
-  addonAwareAdbScanner.enable();
-  ok(mockScanner.enable.notCalled, "enable() was not called");
-  mockScanner.enable.reset();
-
-  // Check that enable() is called if the addon is installed
-  mockAddon.status = "installed";
-  addonAwareAdbScanner.enable();
-  ok(mockScanner.enable.called, "enable() was called");
-  mockScanner.enable.reset();
-});
-
-/**
- * This test checks that enable()/disable() methods from the internal ADBScanner are
- * called when the addon is installed or uninstalled.
- */
-add_task(async function testUpdatingAddonEnablesDisablesScanner() {
-  const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
-
-  // Enable the addon aware scanner
-  addonAwareAdbScanner.enable();
-  ok(mockScanner.enable.notCalled, "enable() was not called initially");
-
-  // Check that enable() is called automatically when the addon is installed
-  mockAddon.status = "installed";
-  mockAddon.emit("update");
-  ok(mockScanner.enable.called, "enable() was called when installing the addon");
-  ok(mockScanner.disable.notCalled, "disable() was not called when installing the addon");
-  mockScanner.enable.reset();
-  mockScanner.disable.reset();
-
-  // Check that disabled() is called automatically when the addon is uninstalled
-  mockAddon.status = "uninstalled";
-  mockAddon.emit("update");
-  ok(mockScanner.enable.notCalled, "enable() was not called when uninstalling the addon");
-  ok(mockScanner.disable.called, "disable() was called when uninstalling the addon");
-  mockScanner.enable.reset();
-  mockScanner.disable.reset();
-
-  // Check that enable() is called again when the addon is reinstalled
-  mockAddon.status = "installed";
-  mockAddon.emit("update");
-  ok(mockScanner.enable.called, "enable() was called when installing the addon");
-  ok(mockScanner.disable.notCalled, "disable() was not called when installing the addon");
-  mockScanner.enable.reset();
-  mockScanner.disable.reset();
-});
-
-/**
- * This test checks that disable() is forwarded from the AddonAwareADBScanner to the real
- * scanner even if the addon is uninstalled. We might miss the addon uninstall
- * notification, so it is safer to always proceed with disabling.
- */
-add_task(async function testScannerIsDisabledWhenMissingAddonUpdate() {
-  const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
-
-  // Enable the addon aware scanner
-  mockAddon.status = "installed";
-  addonAwareAdbScanner.enable();
-  ok(mockScanner.enable.called, "enable() was called initially");
-  mockScanner.enable.reset();
-
-  // Uninstall the addon without firing any event
-  mockAddon.status = "uninstalled";
-
-  // Programmatically call disable, check that the scanner's disable is called even though
-  // the addon was uninstalled.
-  addonAwareAdbScanner.disable();
-  ok(mockScanner.disable.called, "disable() was called when uninstalling the addon");
-  mockScanner.disable.reset();
-});
-
-/**
- * This test checks that when the AddonAwareADBScanner is disabled, then enable/disable
- * are not called on the inner scanner when the addon status changes.
- */
-add_task(async function testInnerEnableIsNotCalledIfNotStarted() {
-  const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
-
-  // Check that enable() is not called on the inner scanner when the addon is installed
-  // if the AddonAwareADBScanner was not enabled
-  mockAddon.status = "installed";
-  mockAddon.emit("update");
-  ok(mockScanner.enable.notCalled, "enable() was not called");
-
-  // Same for disable() and "uninstall"
-  mockAddon.status = "uninstalled";
-  mockAddon.emit("update");
-  ok(mockScanner.disable.notCalled, "disable() was not called");
-
-  // Enable the addon aware scanner
-  addonAwareAdbScanner.enable();
-  ok(mockScanner.enable.notCalled, "enable() was not called");
-  ok(mockScanner.disable.notCalled, "disable() was not called");
-});
-
-/**
- * This test checks that when the AddonAwareADBScanner is disabled, installing the addon
- * no longer enables the internal ADBScanner.
- */
-add_task(async function testEnableIsNoLongerCalledAfterDisabling() {
-  const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
-
-  // Start with the addon installed
-  mockAddon.status = "installed";
-  addonAwareAdbScanner.enable();
-  ok(mockScanner.enable.called, "enable() was called since addon was already installed");
-  mockScanner.enable.reset();
-
-  // Here we call enable again to check that we will not add too many events.
-  // A single call to disable() should stop all listeners, even if we called enable()
-  // several times.
-  addonAwareAdbScanner.enable();
-  ok(mockScanner.enable.called, "enable() was called again");
-  mockScanner.enable.reset();
-
-  // Disable the scanner
-  addonAwareAdbScanner.disable();
-  ok(mockScanner.disable.called, "disable() was called");
-  mockScanner.disable.reset();
-
-  // Emit an addon update event
-  mockAddon.emit("update");
-  ok(mockScanner.enable.notCalled,
-    "enable() is not called since the main scanner is disabled");
-});
-
-/**
- * Basic check that the "runtime-list-updated" event is forwarded.
- */
-add_task(async function testListUpdatedEventForwarding() {
-  const { mockScanner, addonAwareAdbScanner } = prepareMocks();
-
-  const spy = sinon.spy();
-  addonAwareAdbScanner.on("runtime-list-updated", spy);
-  mockScanner.emit("runtime-list-updated");
-  ok(spy.called, "The runtime-list-updated event was forwarded from ADBScanner");
-  addonAwareAdbScanner.off("runtime-list-updated", spy);
-});
-
-/**
- * Basic check that calls to scan() are forwarded.
- */
-add_task(async function testScanCallForwarding() {
-  const { mockScanner, addonAwareAdbScanner } = prepareMocks();
-
-  ok(mockScanner.scan.notCalled, "ADBScanner scan() is not called initially");
-
-  addonAwareAdbScanner.scan();
-  mockScanner.emit("runtime-list-updated");
-  ok(mockScanner.scan.called, "ADBScanner scan() was called");
-  mockScanner.scan.reset();
-});
-
-/**
- * Basic check that calls to scan() are forwarded.
- */
-add_task(async function testListRuntimesCallForwarding() {
-  const { mockScanner, addonAwareAdbScanner } = prepareMocks();
-
-  ok(mockScanner.listRuntimes.notCalled,
-    "ADBScanner listRuntimes() is not called initially");
-
-  addonAwareAdbScanner.listRuntimes();
-  mockScanner.emit("runtime-list-updated");
-  ok(mockScanner.listRuntimes.called, "ADBScanner listRuntimes() was called");
-  mockScanner.scan.reset();
-});
--- a/devtools/shared/adb/test/xpcshell.ini
+++ b/devtools/shared/adb/test/xpcshell.ini
@@ -3,9 +3,8 @@ tags = devtools
 head = xpcshell-head.js
 firefox-appdir = browser
 skip-if = toolkit == 'android'
 support-files =
   adb.py
 
 [test_adb.js]
 run-sequentially = An extension having the same id is installed/uninstalled in different tests
-[test_addon-aware-adb-scanner.js]