Bug 1472491: Part 5n - Add AudioPlaybackChild actor. r=felipe draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 29 Jul 2018 21:27:32 -0700
changeset 828449 c8e8dfb04bac2360f2832dc6aa7957acfe731f84
parent 828448 3ceb1eaaa69c249da3f2e82befe96db77156a7c1
child 828450 4db52dd9d2b219a12b45eb974ae5bb25e1d7b6f1
push id118680
push usermaglione.k@gmail.com
push dateFri, 10 Aug 2018 23:04:22 +0000
reviewersfelipe
bugs1472491
milestone63.0a1
Bug 1472491: Part 5n - Add AudioPlaybackChild actor. r=felipe MozReview-Commit-ID: DtGNW4riHQX
toolkit/actors/AudioPlaybackChild.jsm
toolkit/actors/moz.build
toolkit/content/browser-content.js
toolkit/modules/ActorManagerParent.jsm
toolkit/moz.build
copy from toolkit/content/browser-content.js
copy to toolkit/actors/AudioPlaybackChild.jsm
--- a/toolkit/content/browser-content.js
+++ b/toolkit/actors/AudioPlaybackChild.jsm
@@ -1,221 +1,21 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 sw=2 sts=2 et tw=80: */
 /* 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/. */
-
-/* eslint-env mozilla/frame-script */
-/* eslint no-unused-vars: ["error", {args: "none"}] */
-/* global sendAsyncMessage */
-
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/ActorManagerChild.jsm");
-
-ActorManagerChild.attach(this);
-
-ChromeUtils.defineModuleGetter(this, "AutoCompletePopup",
-  "resource://gre/modules/AutoCompletePopupContent.jsm");
-ChromeUtils.defineModuleGetter(this, "AutoScrollController",
-  "resource://gre/modules/AutoScrollController.jsm");
-ChromeUtils.defineModuleGetter(this, "BrowserUtils",
-  "resource://gre/modules/BrowserUtils.jsm");
-ChromeUtils.defineModuleGetter(this, "SelectContentHelper",
-  "resource://gre/modules/SelectContentHelper.jsm");
-ChromeUtils.defineModuleGetter(this, "FindContent",
-  "resource://gre/modules/FindContent.jsm");
-ChromeUtils.defineModuleGetter(this, "PrintingContent",
-  "resource://gre/modules/PrintingContent.jsm");
-ChromeUtils.defineModuleGetter(this, "RemoteFinder",
-  "resource://gre/modules/RemoteFinder.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "formFill",
-                                   "@mozilla.org/satchel/form-fill-controller;1",
-                                   "nsIFormFillController");
-
-var global = this;
-
-XPCOMUtils.defineLazyProxy(this, "PopupBlocking", () => {
-  let tmp = {};
-  ChromeUtils.import("resource://gre/modules/PopupBlocking.jsm", tmp);
-  return new tmp.PopupBlocking(global);
-});
-
-XPCOMUtils.defineLazyProxy(this, "ShieldFrameListener", () => {
-  let tmp = {};
-  ChromeUtils.import("resource://normandy-content/ShieldFrameListener.jsm", tmp);
-  return new tmp.ShieldFrameListener(global);
-});
-
-XPCOMUtils.defineLazyProxy(this, "UITourListener", () => {
-  let tmp = {};
-  ChromeUtils.import("resource:///modules/ContentUITour.jsm", tmp);
-  return new tmp.UITourListener(global);
-});
+"use strict";
 
-XPCOMUtils.defineLazyProxy(this, "SelectionSourceContent",
-  "resource://gre/modules/SelectionSourceContent.jsm");
-
-XPCOMUtils.defineLazyProxy(this, "WebChannelContent",
-  "resource://gre/modules/WebChannelContent.jsm");
-
-XPCOMUtils.defineLazyProxy(this, "DateTimePickerContent", () => {
-  let tmp = {};
-  ChromeUtils.import("resource://gre/modules/DateTimePickerContent.jsm", tmp);
-  return new tmp.DateTimePickerContent(this);
-});
-
-XPCOMUtils.defineLazyProxy(this, "FindBarChild", () => {
-  let tmp = {};
-  ChromeUtils.import("resource://gre/modules/FindBarChild.jsm", tmp);
-  return new tmp.FindBarChild(this);
-}, {inQuickFind: false, inPassThrough: false});
-
-
-// Lazily load the finder code
-addMessageListener("Finder:Initialize", function() {
-  let {RemoteFinderListener} = ChromeUtils.import("resource://gre/modules/RemoteFinder.jsm", {});
-  new RemoteFinderListener(global);
-});
-
-var AutoScrollListener = {
-  handleEvent(event) {
-    if (event.isTrusted &
-        !event.defaultPrevented &&
-        event.button == 1) {
-      if (!this._controller) {
-        this._controller = new AutoScrollController(global);
-      }
-      this._controller.handleEvent(event);
-    }
-  }
-};
-Services.els.addSystemEventListener(global, "mousedown", AutoScrollListener, true);
-
-addEventListener("MozOpenDateTimePicker", DateTimePickerContent);
-
-addEventListener("DOMPopupBlocked", PopupBlocking, true);
-
-var Printing = {
-  MESSAGES: [
-    "Printing:Preview:Enter",
-    "Printing:Preview:Exit",
-    "Printing:Preview:Navigate",
-    "Printing:Preview:ParseDocument",
-    "Printing:Print",
-  ],
+var EXPORTED_SYMBOLS = ["AudioPlaybackChild"];
 
-  init() {
-    this.MESSAGES.forEach(msgName => addMessageListener(msgName, this));
-    addEventListener("PrintingError", this, true);
-    addEventListener("printPreviewUpdate", this, true);
-    this.init = null;
-  },
-
-  handleEvent(event) {
-    return PrintingContent.handleEvent(global, event);
-  },
-
-  receiveMessage(message) {
-    return PrintingContent.receiveMessage(global, message);
-  },
-};
-Printing.init();
-
-var FindBar = {
-  /**
-   * _findKey and _findModifiers are used to determine whether a keypress
-   * is a user attempting to use the find shortcut, after which we'll
-   * route keypresses to the parent until we know the findbar has focus
-   * there. To do this, we need shortcut data from the parent.
-   */
-  _findKey: null,
-
-  init() {
-    Services.els.addSystemEventListener(global, "keypress",
-                                        this.onKeypress.bind(this), false);
-    this.init = null;
-  },
-
-  /**
-   * Check whether this key event will start the findbar in the parent,
-   * in which case we should pass any further key events to the parent to avoid
-   * them being lost.
-   * @param aEvent the key event to check.
-   */
-  eventMatchesFindShortcut(aEvent) {
-    if (!this._findKey) {
-      this._findKey = Services.cpmm.sharedData.get("Findbar:Shortcut");
-      if (!this._findKey) {
-          return false;
-      }
-    }
-    for (let k in this._findKey) {
-      if (this._findKey[k] != aEvent[k]) {
-        return false;
-      }
-    }
-    return true;
-  },
+ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
 
-  onKeypress(event) {
-    if (!FindBarChild.inPassThrough &&
-        this.eventMatchesFindShortcut(event)) {
-      return FindBarChild.start(event);
-    }
-
-    if (event.ctrlKey || event.altKey || event.metaKey || event.defaultPrevented ||
-        !BrowserUtils.canFastFind(content)) {
-      return null;
-    }
-
-    if (FindBarChild.inPassThrough || FindBarChild.inQuickFind) {
-      return FindBarChild.onKeypress(event);
-    }
-
-    if (event.charCode && BrowserUtils.shouldFastFind(event.target)) {
-      let key = String.fromCharCode(event.charCode);
-      if ((key == "/" || key == "'") && RemoteFinder._manualFAYT) {
-        return FindBarChild.startQuickFind(event);
-      }
-      if (key != " " && RemoteFinder._findAsYouType) {
-        return FindBarChild.startQuickFind(event, true);
-      }
-    }
-    return null;
-  },
-};
-FindBar.init();
-
-addEventListener("WebChannelMessageToChrome", WebChannelContent,
-                 true, true);
-addMessageListener("WebChannelMessageToContent", WebChannelContent);
-
-var AudioPlaybackListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
-
-  init() {
-    Services.obs.addObserver(this, "audio-playback");
-
-    addMessageListener("AudioPlayback", this);
-    addEventListener("unload", () => {
-      AudioPlaybackListener.uninit();
-    });
-    this.init = null;
-  },
-
-  uninit() {
-    Services.obs.removeObserver(this, "audio-playback");
-
-    removeMessageListener("AudioPlayback", this);
-  },
-
+class AudioPlaybackChild extends ActorChild {
   handleMediaControlMessage(msg) {
-    let utils = global.content.windowUtils;
+    let utils = this.content.windowUtils;
     let suspendTypes = Ci.nsISuspendedTypes;
     switch (msg) {
       case "mute":
         utils.audioMuted = true;
         break;
       case "unmute":
         utils.audioMuted = false;
         break;
@@ -234,194 +34,39 @@ var AudioPlaybackListener = {
       case "mediaControlStopped":
         utils.mediaSuspend = suspendTypes.SUSPENDED_STOP_DISPOSABLE;
         break;
       case "resumeMedia":
         // User has clicked the tab audio indicator to play a delayed
         // media. That's clear user intent to play, so gesture activate
         // the content document tree so that the block-autoplay logic
         // allows the media to autoplay.
-        content.document.notifyUserGestureActivation();
+        this.content.document.notifyUserGestureActivation();
         utils.mediaSuspend = suspendTypes.NONE_SUSPENDED;
         break;
       default:
         dump("Error : wrong media control msg!\n");
         break;
     }
-  },
+  }
 
   observe(subject, topic, data) {
     if (topic === "audio-playback") {
-      if (subject && subject.top == global.content) {
+      if (subject && subject.top == this.content) {
         let name = "AudioPlayback:";
         if (data === "activeMediaBlockStart") {
           name += "ActiveMediaBlockStart";
         } else if (data === "activeMediaBlockStop") {
           name += "ActiveMediaBlockStop";
         } else {
           name += (data === "active") ? "Start" : "Stop";
         }
-        sendAsyncMessage(name);
+        this.mm.sendAsyncMessage(name);
       }
     }
-  },
+  }
 
   receiveMessage(msg) {
     if (msg.name == "AudioPlayback") {
       this.handleMediaControlMessage(msg.data.type);
     }
-  },
-};
-AudioPlaybackListener.init();
-
-var UnselectedTabHoverObserver = {
-  init() {
-    addMessageListener("Browser:UnselectedTabHover", this);
-    addEventListener("UnselectedTabHover:Enable", this);
-    addEventListener("UnselectedTabHover:Disable", this);
-    this.init = null;
-  },
-  receiveMessage(message) {
-    Services.obs.notifyObservers(content.window, "unselected-tab-hover",
-                                 message.data.hovered);
-  },
-  handleEvent(event) {
-    sendAsyncMessage("UnselectedTabHover:Toggle",
-                     { enable: event.type == "UnselectedTabHover:Enable" });
   }
-};
-UnselectedTabHoverObserver.init();
-
-
-var AudibleAutoplayObserver = {
-  init() {
-    addEventListener("AudibleAutoplayMediaOccurred", this);
-  },
-  handleEvent(event) {
-    sendAsyncMessage("AudibleAutoplayMediaOccurred");
-  }
-};
-AudibleAutoplayObserver.init();
-
-addMessageListener("Browser:PurgeSessionHistory", function BrowserPurgeHistory() {
-  let sessionHistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
-  if (!sessionHistory) {
-    return;
-  }
-
-  // place the entry at current index at the end of the history list, so it won't get removed
-  if (sessionHistory.index < sessionHistory.count - 1) {
-    let legacy = sessionHistory.legacySHistory;
-    legacy.QueryInterface(Ci.nsISHistoryInternal);
-    let indexEntry = legacy.getEntryAtIndex(sessionHistory.index, false);
-    indexEntry.QueryInterface(Ci.nsISHEntry);
-    legacy.addEntry(indexEntry, true);
-  }
-
-  let purge = sessionHistory.count;
-  if (global.content.location.href != "about:blank") {
-    --purge; // Don't remove the page the user's staring at from shistory
-  }
-
-  if (purge > 0) {
-    sessionHistory.legacySHistory.PurgeHistory(purge);
-  }
-});
-
-addMessageListener("ViewSource:GetSelection", SelectionSourceContent);
-
-let AutoComplete = {
-  _connected: false,
-
-  init() {
-    addEventListener("unload", this, {once: true});
-    addEventListener("DOMContentLoaded", this, {once: true});
-    // WebExtension browserAction is preloaded and does not receive DCL, wait
-    // on pageshow so we can hookup the formfill controller.
-    addEventListener("pageshow", this, {capture: true, once: true});
-
-    XPCOMUtils.defineLazyProxy(this, "popup", () => new AutoCompletePopup(global),
-                               {QueryInterface: null});
-    this.init = null;
-  },
-
-  handleEvent(event) {
-    switch (event.type) {
-    case "DOMContentLoaded":
-    case "pageshow":
-      // We need to wait for a content viewer to be available
-      // before we can attach our AutoCompletePopup handler,
-      // since nsFormFillController assumes one will exist
-      // when we call attachToBrowser.
-      if (!this._connected) {
-        formFill.attachToBrowser(docShell, this.popup);
-        this._connected = true;
-      }
-      break;
-
-    case "unload":
-      if (this._connected) {
-        formFill.detachFromBrowser(docShell);
-        this._connected = false;
-      }
-      break;
-    }
-  },
-};
-
-AutoComplete.init();
-
-addEventListener("mozshowdropdown", event => {
-  if (!event.isTrusted)
-    return;
-
-  if (!SelectContentHelper.open) {
-    new SelectContentHelper(event.target, {isOpenedViaTouch: false}, this);
-  }
-});
-
-addEventListener("mozshowdropdown-sourcetouch", event => {
-  if (!event.isTrusted)
-    return;
-
-  if (!SelectContentHelper.open) {
-    new SelectContentHelper(event.target, {isOpenedViaTouch: true}, this);
-  }
-});
-
-let ExtFind = {
-  init() {
-    addMessageListener("ext-Finder:CollectResults", this);
-    addMessageListener("ext-Finder:HighlightResults", this);
-    addMessageListener("ext-Finder:clearHighlighting", this);
-    this.init = null;
-  },
-
-  _findContent: null,
-
-  async receiveMessage(message) {
-    if (!this._findContent) {
-      this._findContent = new FindContent(docShell);
-    }
-
-    let data;
-    switch (message.name) {
-      case "ext-Finder:CollectResults":
-        this.finderInited = true;
-        data = await this._findContent.findRanges(message.data);
-        sendAsyncMessage("ext-Finder:CollectResultsFinished", data);
-        break;
-      case "ext-Finder:HighlightResults":
-        data = this._findContent.highlightResults(message.data);
-        sendAsyncMessage("ext-Finder:HighlightResultsFinished", data);
-        break;
-      case "ext-Finder:clearHighlighting":
-        this._findContent.highlighter.highlight(false);
-        break;
-    }
-  },
-};
-
-ExtFind.init();
-
-addEventListener("ShieldPageEvent", ShieldFrameListener, false, true);
-
-addEventListener("mozUITour", UITourListener, false, true);
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/actors/moz.build
@@ -0,0 +1,9 @@
+# -*- 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/.
+
+FINAL_TARGET_FILES.actors += [
+    'AudioPlaybackChild.jsm',
+]
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -185,98 +185,16 @@ var FindBar = {
   },
 };
 FindBar.init();
 
 addEventListener("WebChannelMessageToChrome", WebChannelContent,
                  true, true);
 addMessageListener("WebChannelMessageToContent", WebChannelContent);
 
-var AudioPlaybackListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
-
-  init() {
-    Services.obs.addObserver(this, "audio-playback");
-
-    addMessageListener("AudioPlayback", this);
-    addEventListener("unload", () => {
-      AudioPlaybackListener.uninit();
-    });
-    this.init = null;
-  },
-
-  uninit() {
-    Services.obs.removeObserver(this, "audio-playback");
-
-    removeMessageListener("AudioPlayback", this);
-  },
-
-  handleMediaControlMessage(msg) {
-    let utils = global.content.windowUtils;
-    let suspendTypes = Ci.nsISuspendedTypes;
-    switch (msg) {
-      case "mute":
-        utils.audioMuted = true;
-        break;
-      case "unmute":
-        utils.audioMuted = false;
-        break;
-      case "lostAudioFocus":
-        utils.mediaSuspend = suspendTypes.SUSPENDED_PAUSE_DISPOSABLE;
-        break;
-      case "lostAudioFocusTransiently":
-        utils.mediaSuspend = suspendTypes.SUSPENDED_PAUSE;
-        break;
-      case "gainAudioFocus":
-        utils.mediaSuspend = suspendTypes.NONE_SUSPENDED;
-        break;
-      case "mediaControlPaused":
-        utils.mediaSuspend = suspendTypes.SUSPENDED_PAUSE_DISPOSABLE;
-        break;
-      case "mediaControlStopped":
-        utils.mediaSuspend = suspendTypes.SUSPENDED_STOP_DISPOSABLE;
-        break;
-      case "resumeMedia":
-        // User has clicked the tab audio indicator to play a delayed
-        // media. That's clear user intent to play, so gesture activate
-        // the content document tree so that the block-autoplay logic
-        // allows the media to autoplay.
-        content.document.notifyUserGestureActivation();
-        utils.mediaSuspend = suspendTypes.NONE_SUSPENDED;
-        break;
-      default:
-        dump("Error : wrong media control msg!\n");
-        break;
-    }
-  },
-
-  observe(subject, topic, data) {
-    if (topic === "audio-playback") {
-      if (subject && subject.top == global.content) {
-        let name = "AudioPlayback:";
-        if (data === "activeMediaBlockStart") {
-          name += "ActiveMediaBlockStart";
-        } else if (data === "activeMediaBlockStop") {
-          name += "ActiveMediaBlockStop";
-        } else {
-          name += (data === "active") ? "Start" : "Stop";
-        }
-        sendAsyncMessage(name);
-      }
-    }
-  },
-
-  receiveMessage(msg) {
-    if (msg.name == "AudioPlayback") {
-      this.handleMediaControlMessage(msg.data.type);
-    }
-  },
-};
-AudioPlaybackListener.init();
-
 var UnselectedTabHoverObserver = {
   init() {
     addMessageListener("Browser:UnselectedTabHover", this);
     addEventListener("UnselectedTabHover:Enable", this);
     addEventListener("UnselectedTabHover:Disable", this);
     this.init = null;
   },
   receiveMessage(message) {
--- a/toolkit/modules/ActorManagerParent.jsm
+++ b/toolkit/modules/ActorManagerParent.jsm
@@ -94,16 +94,27 @@
 var EXPORTED_SYMBOLS = ["ActorManagerParent"];
 
 ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 const {DefaultMap} = ExtensionUtils;
 
 let ACTORS = {
+  AudioPlayback: {
+    child: {
+      module: "resource://gre/actors/AudioPlaybackChild.jsm",
+      messages: [
+        "AudioPlayback",
+      ],
+      observers: [
+        "audio-playback",
+      ],
+    },
+  },
 };
 
 class ActorSet {
   constructor(group, actorSide) {
     this.group = group;
     this.actorSide = actorSide;
 
     this.actors = new Map();
--- a/toolkit/moz.build
+++ b/toolkit/moz.build
@@ -1,15 +1,16 @@
 # -*- 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/.
 
 DIRS += [
+    'actors',
     'components',
     'content',
     'crashreporter',
     'forgetaboutsite',
     'locales',
     'modules',
     'mozapps/downloads',
     'mozapps/extensions',