Bug 1188487 - Add API to BrowserElement to mute and set volume. r=fabrice
authorBrian R. Bondy <netzen@gmail.com>
Fri, 31 Jul 2015 13:21:18 -0400
changeset 287333 8e2cceda7b2fa2e3b9323d8f88db0761aaec8ee1
parent 287332 bb6a924f93259aa2fe54c42fc1ced60c1b907c78
child 287334 11cdfe4196641ef4bb9db1ede43a58f81760ce84
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice
bugs1188487
milestone42.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 1188487 - Add API to BrowserElement to mute and set volume. r=fabrice It's already possible to get mute/volume at the audio channel level, but this adds it at the iframe level so that audio channels can be created and destroyed and the setting will be preserved.
dom/browser-element/BrowserElementChildPreload.js
dom/browser-element/BrowserElementParent.js
dom/browser-element/nsIBrowserElementAPI.idl
dom/html/nsBrowserElement.cpp
dom/html/nsBrowserElement.h
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -217,16 +217,21 @@ BrowserElementChild.prototype = {
       "get-screenshot": this._recvGetScreenshot,
       "get-contentdimensions": this._recvGetContentDimensions,
       "set-visible": this._recvSetVisible,
       "get-visible": this._recvVisible,
       "send-mouse-event": this._recvSendMouseEvent,
       "send-touch-event": this._recvSendTouchEvent,
       "get-can-go-back": this._recvCanGoBack,
       "get-can-go-forward": this._recvCanGoForward,
+      "mute": this._recvMute.bind(this),
+      "unmute": this._recvUnmute.bind(this),
+      "get-muted": this._recvGetMuted.bind(this),
+      "set-volume": this._recvSetVolume.bind(this),
+      "get-volume": this._recvGetVolume.bind(this),
       "go-back": this._recvGoBack,
       "go-forward": this._recvGoForward,
       "reload": this._recvReload,
       "stop": this._recvStop,
       "zoom": this._recvZoom,
       "unblock-modal-prompt": this._recvStopWaiting,
       "fire-ctx-callback": this._recvFireCtxCallback,
       "owner-visibility-change": this._recvOwnerVisibilityChange,
@@ -1295,16 +1300,42 @@ BrowserElementChild.prototype = {
   _recvCanGoForward: function(data) {
     var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
     sendAsyncMsg('got-can-go-forward', {
       id: data.json.id,
       successRv: webNav.canGoForward
     });
   },
 
+  _recvMute: function(data) {
+    this._windowUtils.audioMuted = true;
+  },
+
+  _recvUnmute: function(data) {
+    this._windowUtils.audioMuted = false;
+  },
+
+  _recvGetMuted: function(data) {
+    sendAsyncMsg('got-muted', {
+      id: data.json.id,
+      successRv: this._windowUtils.audioMuted
+    });
+  },
+
+  _recvSetVolume: function(data) {
+    this._windowUtils.audioVolume = data.json.volume;
+  },
+
+  _recvGetVolume: function(data) {
+    sendAsyncMsg('got-volume', {
+      id: data.json.id,
+      successRv: this._windowUtils.audioVolume
+    });
+  },
+
   _recvGoBack: function(data) {
     try {
       docShell.QueryInterface(Ci.nsIWebNavigation).goBack();
     } catch(e) {
       // Silently swallow errors; these happen when we can't go back.
     }
   },
 
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -179,16 +179,18 @@ BrowserElementParent.prototype = {
       "firstpaint": this._fireProfiledEventFromMsg,
       "documentfirstpaint": this._fireProfiledEventFromMsg,
       "nextpaint": this._recvNextPaint,
       "got-purge-history": this._gotDOMRequestResult,
       "got-screenshot": this._gotDOMRequestResult,
       "got-contentdimensions": this._gotDOMRequestResult,
       "got-can-go-back": this._gotDOMRequestResult,
       "got-can-go-forward": this._gotDOMRequestResult,
+      "got-muted": this._gotDOMRequestResult,
+      "got-volume": this._gotDOMRequestResult,
       "requested-dom-fullscreen": this._requestedDOMFullscreen,
       "fullscreen-origin-change": this._fullscreenOriginChange,
       "exit-dom-fullscreen": this._exitDomFullscreen,
       "got-visible": this._gotDOMRequestResult,
       "visibilitychange": this._childVisibilityChange,
       "got-set-input-method-active": this._gotDOMRequestResult,
       "selectionstatechanged": this._handleSelectionStateChanged,
       "scrollviewchange": this._handleScrollViewChange,
@@ -659,16 +661,32 @@ BrowserElementParent.prototype = {
       backward: direction == Ci.nsIBrowserElementAPI.FIND_BACKWARD
     });
   }),
 
   clearMatch: defineNoReturnMethod(function() {
     return this._sendAsyncMsg('clear-match');
   }),
 
+  mute: defineNoReturnMethod(function() {
+    this._sendAsyncMsg('mute');
+  }),
+
+  unmute: defineNoReturnMethod(function() {
+    this._sendAsyncMsg('unmute');
+  }),
+
+  getMuted: defineDOMRequestMethod('get-muted'),
+
+  getVolume: defineDOMRequestMethod('get-volume'),
+
+  setVolume: defineNoReturnMethod(function(volume) {
+    this._sendAsyncMsg('set-volume', {volume});
+  }),
+
   goBack: defineNoReturnMethod(function() {
     this._sendAsyncMsg('go-back');
   }),
 
   goForward: defineNoReturnMethod(function() {
     this._sendAsyncMsg('go-forward');
   }),
 
--- a/dom/browser-element/nsIBrowserElementAPI.idl
+++ b/dom/browser-element/nsIBrowserElementAPI.idl
@@ -21,17 +21,17 @@ interface nsIBrowserElementNextPaintList
     { 0x651db7e3, 0x1734, 0x4536,                               \
       { 0xb1, 0x5a, 0x5b, 0x3a, 0xe6, 0x44, 0x13, 0x4c } }
 %}
 
 /**
  * Interface to the BrowserElementParent implementation. All methods
  * but setFrameLoader throw when the remote process is dead.
  */
-[scriptable, uuid(26a832d1-9d71-43ef-9d46-9d7c8ec33f00)]
+[scriptable, uuid(56bd3e12-4a8b-422a-89fc-6dc25aa30aa2)]
 interface nsIBrowserElementAPI : nsISupports
 {
   const long FIND_CASE_SENSITIVE = 0;
   const long FIND_CASE_INSENSITIVE = 1;
 
   const long FIND_FORWARD = 0;
   const long FIND_BACKWARD = 1;
 
@@ -72,16 +72,23 @@ interface nsIBrowserElementAPI : nsISupp
   nsIDOMDOMRequest getCanGoBack();
   nsIDOMDOMRequest getCanGoForward();
   nsIDOMDOMRequest getContentDimensions();
 
   void findAll(in DOMString searchString, in long caseSensitivity);
   void findNext(in long direction);
   void clearMatch();
 
+  void mute();
+  void unmute();
+  nsIDOMDOMRequest getMuted();
+
+  void setVolume(in float volume);
+  nsIDOMDOMRequest getVolume();
+
   void addNextPaintListener(in nsIBrowserElementNextPaintListener listener);
   void removeNextPaintListener(in nsIBrowserElementNextPaintListener listener);
 
   nsIDOMDOMRequest setInputMethodActive(in boolean isActive);
 
   nsIDOMDOMRequest getAudioChannelVolume(in uint32_t audioChannel);
   nsIDOMDOMRequest setAudioChannelVolume(in uint32_t audioChannel, in float volume);
 
--- a/dom/html/nsBrowserElement.cpp
+++ b/dom/html/nsBrowserElement.cpp
@@ -620,16 +620,89 @@ nsBrowserElement::GetAllowedAudioChannel
     }
 
     mBrowserElementAudioChannels.AppendElements(channels);
   }
 
   aAudioChannels.AppendElements(mBrowserElementAudioChannels);
 }
 
+already_AddRefed<DOMRequest>
+nsBrowserElement::GetMuted(ErrorResult& aRv)
+{
+  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
+  NS_ENSURE_TRUE(IsNotWidgetOrThrow(aRv), nullptr);
+
+  nsCOMPtr<nsIDOMDOMRequest> req;
+  nsresult rv = mBrowserElementAPI->GetMuted(getter_AddRefs(req));
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return nullptr;
+  }
+
+  return req.forget().downcast<DOMRequest>();
+}
+
+void
+nsBrowserElement::Mute(ErrorResult& aRv)
+{
+  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
+  NS_ENSURE_TRUE_VOID(IsNotWidgetOrThrow(aRv));
+
+  nsresult rv = mBrowserElementAPI->Mute();
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+  }
+}
+
+void
+nsBrowserElement::Unmute(ErrorResult& aRv)
+{
+  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
+  NS_ENSURE_TRUE_VOID(IsNotWidgetOrThrow(aRv));
+
+  nsresult rv = mBrowserElementAPI->Unmute();
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+  }
+}
+
+already_AddRefed<DOMRequest>
+nsBrowserElement::GetVolume(ErrorResult& aRv)
+{
+  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
+  NS_ENSURE_TRUE(IsNotWidgetOrThrow(aRv), nullptr);
+
+  nsCOMPtr<nsIDOMDOMRequest> req;
+  nsresult rv = mBrowserElementAPI->GetVolume(getter_AddRefs(req));
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return nullptr;
+  }
+
+  return req.forget().downcast<DOMRequest>();
+}
+
+void
+nsBrowserElement::SetVolume(float aVolume, ErrorResult& aRv)
+{
+  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
+  NS_ENSURE_TRUE_VOID(IsNotWidgetOrThrow(aRv));
+
+  nsresult rv = mBrowserElementAPI->SetVolume(aVolume);
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+  }
+}
+
 void
 nsBrowserElement::SetNFCFocus(bool aIsFocus,
                               ErrorResult& aRv)
 {
   NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
 
   nsresult rv = mBrowserElementAPI->SetNFCFocus(aIsFocus);
   if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/dom/html/nsBrowserElement.h
+++ b/dom/html/nsBrowserElement.h
@@ -71,16 +71,23 @@ public:
            ErrorResult& aRv);
 
   already_AddRefed<dom::DOMRequest> PurgeHistory(ErrorResult& aRv);
 
   void GetAllowedAudioChannels(
             nsTArray<nsRefPtr<dom::BrowserElementAudioChannel>>& aAudioChannels,
             ErrorResult& aRv);
 
+  void Mute(ErrorResult& aRv);
+  void Unmute(ErrorResult& aRv);
+  already_AddRefed<dom::DOMRequest> GetMuted(ErrorResult& aRv);
+
+  void SetVolume(float aVolume , ErrorResult& aRv);
+  already_AddRefed<dom::DOMRequest> GetVolume(ErrorResult& aRv);
+
   already_AddRefed<dom::DOMRequest>
   GetScreenshot(uint32_t aWidth,
                 uint32_t aHeight,
                 const nsAString& aMimeType,
                 ErrorResult& aRv);
 
   void Zoom(float aZoom, ErrorResult& aRv);