Bug 1242874 - part4 : wrap the volume/mute/suspend for notifyStartedPlaying.
MozReview-Commit-ID: 2FMfEVuODmu
--- a/dom/audiochannel/AudioChannelAgent.cpp
+++ b/dom/audiochannel/AudioChannelAgent.cpp
@@ -196,27 +196,21 @@ AudioChannelAgent::InitInternal(nsPIDOMW
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelAgent, InitInternal, this = %p, type = %d, "
"owner = %p, hasCallback = %d\n", this, mAudioChannelType,
mWindow.get(), (!!mCallback || !!mWeakCallback)));
return NS_OK;
}
-NS_IMETHODIMP AudioChannelAgent::NotifyStartedPlaying(float *aVolume,
- bool* aMuted)
+NS_IMETHODIMP
+AudioChannelAgent::NotifyStartedPlaying(AudioPlaybackConfig* aConfig)
{
- MOZ_ASSERT(aVolume);
- MOZ_ASSERT(aMuted);
-
- // Window-less AudioChannelAgents are muted by default.
- if (!mWindow) {
- *aVolume = 0;
- *aMuted = true;
- return NS_OK;
+ if (NS_WARN_IF(!aConfig)) {
+ return NS_ERROR_FAILURE;
}
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR ||
service == nullptr || mIsRegToService) {
return NS_ERROR_FAILURE;
}
@@ -226,24 +220,23 @@ NS_IMETHODIMP AudioChannelAgent::NotifyS
AudioPlaybackConfig config = service->GetMediaConfig(mWindow,
mAudioChannelType);
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelAgent, NotifyStartedPlaying, this = %p, "
"mute = %d, volume = %f, suspend = %d\n", this,
config.mMuted, config.mVolume, config.mSuspend));
- *aVolume = config.mVolume;
- *aMuted = config.mMuted;
-
+ aConfig->SetConfig(config.mVolume, config.mMuted, config.mSuspend);
mIsRegToService = true;
return NS_OK;
}
-NS_IMETHODIMP AudioChannelAgent::NotifyStoppedPlaying()
+NS_IMETHODIMP
+AudioChannelAgent::NotifyStoppedPlaying()
{
if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR ||
!mIsRegToService) {
return NS_ERROR_FAILURE;
}
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelAgent, NotifyStoppedPlaying, this = %p\n", this));
--- a/dom/audiochannel/nsIAudioChannelAgent.idl
+++ b/dom/audiochannel/nsIAudioChannelAgent.idl
@@ -50,16 +50,26 @@ interface nsISuspendedTypes : nsISupport
const uint32_t NONE_SUSPENDED = 0;
const uint32_t SUSPENDED_PAUSE = 1;
const uint32_t SUSPENDED_BLOCK = 2;
const uint32_t SUSPENDED_PAUSE_DISPOSABLE = 3;
const uint32_t SUSPENDED_STOP_DISPOSABLE = 4;
};
+%{C++
+namespace mozilla {
+namespace dom {
+// It's defined in dom/audiochannel/AudioChannelService.h.
+class AudioPlaybackConfig;
+}
+}
+%}
+[ptr] native AudioPlaybackConfig(mozilla::dom::AudioPlaybackConfig);
+
[uuid(15c05894-408e-4798-b527-a8c32d9c5f8c)]
interface nsIAudioChannelAgentCallback : nsISupports
{
/**
* Notified when the window volume/mute is changed
*/
void windowVolumeChanged(in float aVolume, in bool aMuted);
@@ -147,25 +157,20 @@ interface nsIAudioChannelAgent : nsISupp
void initWithWeakCallback(in mozIDOMWindow window, in long channelType,
in nsIAudioChannelAgentCallback callback);
/**
* Notify the agent that we want to start playing.
* Note: Gecko component SHOULD call this function first then start to
* play audio stream only when return value is true.
*
- * @return
- * normal state: the agent has registered with audio channel service and
- * the component should start playback.
- * muted state: the agent has registered with audio channel service but
- * the component should not start playback.
- * faded state: the agent has registered with audio channel service the
- * component should start playback as well as reducing the volume.
+ * @param config
+ * It contains the playback related states (volume/mute/suspend)
*/
- void notifyStartedPlaying(out float volume, out bool muted);
+ void notifyStartedPlaying(in AudioPlaybackConfig config);
/**
* Notify the agent we no longer want to play.
*
* Note : even if notifyStartedPlaying() returned false, the agent would
* still be registered with the audio channel service and receive callbacks
* for status changes. So notifyStoppedPlaying must still eventually be
* called to unregister the agent with the channel service.
--- a/dom/fmradio/FMRadio.cpp
+++ b/dom/fmradio/FMRadio.cpp
@@ -447,20 +447,24 @@ FMRadio::DisableRDS()
return r.forget();
}
void
FMRadio::EnableAudioChannelAgent()
{
NS_ENSURE_TRUE_VOID(mAudioChannelAgent);
- float volume = 0.0;
- bool muted = true;
- mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
- WindowVolumeChanged(volume, muted);
+ AudioPlaybackConfig config;
+ nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(&config);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return;
+ }
+
+ WindowVolumeChanged(config.mVolume, config.mMuted);
+ WindowSuspendChanged(config.mSuspend);
mAudioChannelAgentEnabled = true;
}
NS_IMETHODIMP
FMRadio::WindowVolumeChanged(float aVolume, bool aMuted)
{
// TODO : Not support to change volume now, so we just close it.
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -5056,20 +5056,24 @@ void
HTMLMediaElement::NotifyAudioChannelAgent(bool aPlaying)
{
// This is needed to pass nsContentUtils::IsCallerChrome().
// AudioChannel API should not called from content but it can happen that
// this method has some content JS in its stack.
AutoNoJSAPI nojsapi;
if (aPlaying) {
- float volume = 0.0;
- bool muted = true;
- mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
- WindowVolumeChanged(volume, muted);
+ AudioPlaybackConfig config;
+ nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(&config);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return;
+ }
+
+ WindowVolumeChanged(config.mVolume, config.mMuted);
+ WindowSuspendChanged(config.mSuspend);
} else {
mAudioChannelAgent->NotifyStoppedPlaying();
mAudioChannelAgent = nullptr;
}
}
NS_IMETHODIMP
HTMLMediaElement::WindowVolumeChanged(float aVolume, bool aMuted)
--- a/dom/media/webaudio/AudioDestinationNode.cpp
+++ b/dom/media/webaudio/AudioDestinationNode.cpp
@@ -659,20 +659,20 @@ AudioDestinationNode::InputMuted(bool aM
CreateAudioChannelAgent();
}
if (aMuted) {
mAudioChannelAgent->NotifyStoppedPlaying();
return;
}
- float volume = 0.0;
- bool muted = true;
- nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
+ AudioPlaybackConfig config;
+ nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(&config);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
- WindowVolumeChanged(volume, muted);
+ WindowVolumeChanged(config.mVolume, config.mMuted);
+ WindowSuspendChanged(config.mSuspend);
}
} // namespace dom
} // namespace mozilla
--- a/dom/media/webspeech/synth/nsSpeechTask.cpp
+++ b/dom/media/webspeech/synth/nsSpeechTask.cpp
@@ -707,19 +707,25 @@ nsSpeechTask::CreateAudioChannelAgent()
if (mAudioChannelAgent) {
mAudioChannelAgent->NotifyStoppedPlaying();
}
mAudioChannelAgent = new AudioChannelAgent();
mAudioChannelAgent->InitWithWeakCallback(mUtterance->GetOwner(),
static_cast<int32_t>(AudioChannelService::GetDefaultAudioChannel()),
this);
- float volume = 0.0f;
- bool muted = true;
- mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
+
+ AudioPlaybackConfig config;
+ nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(&config);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return;
+ }
+
+ WindowVolumeChanged(config.mVolume, config.mMuted);
+ WindowSuspendChanged(config.mSuspend);
}
void
nsSpeechTask::DestroyAudioChannelAgent()
{
if (mAudioChannelAgent) {
mAudioChannelAgent->NotifyStoppedPlaying();
mAudioChannelAgent = nullptr;
@@ -731,19 +737,21 @@ nsSpeechTask::WindowVolumeChanged(float
{
SetAudioOutputVolume(aMuted ? 0.0 : mVolume * aVolume);
return NS_OK;
}
NS_IMETHODIMP
nsSpeechTask::WindowSuspendChanged(nsSuspendedTypes aSuspend)
{
- if (aSuspend == nsISuspendedTypes::NONE_SUSPENDED) {
+ if (aSuspend == nsISuspendedTypes::NONE_SUSPENDED &&
+ mUtterance->mPaused) {
Resume();
- } else {
+ } else if (aSuspend != nsISuspendedTypes::NONE_SUSPENDED &&
+ !mUtterance->mPaused) {
Pause();
}
return NS_OK;
}
NS_IMETHODIMP
nsSpeechTask::WindowAudioCaptureChanged(bool aCapture)
{
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -102,16 +102,17 @@ using mozilla::plugins::PluginModuleCont
#include "android_npapi.h"
#include "ANPBase.h"
#include "AndroidBridge.h"
#undef LOG
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#endif
#include "nsIAudioChannelAgent.h"
+#include "AudioChannelService.h"
using namespace mozilla;
using namespace mozilla::plugins::parent;
// We should make this const...
static NPNetscapeFuncs sBrowserFuncs = {
sizeof(sBrowserFuncs),
(NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
@@ -2284,24 +2285,29 @@ NPError
MOZ_ASSERT(agent);
if (isMuted) {
rv = agent->NotifyStoppedPlaying();
if (NS_WARN_IF(NS_FAILED(rv))) {
return NPERR_NO_ERROR;
}
} else {
- float volume = 0.0;
- bool muted = true;
- rv = agent->NotifyStartedPlaying(&volume, &muted);
+
+ dom::AudioPlaybackConfig config;
+ rv = agent->NotifyStartedPlaying(&config);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NPERR_NO_ERROR;
}
- rv = inst->WindowVolumeChanged(volume, muted);
+ rv = inst->WindowVolumeChanged(config.mVolume, config.mMuted);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return NPERR_NO_ERROR;
+ }
+
+ rv = inst->WindowSuspendChanged(config.mSuspend);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NPERR_NO_ERROR;
}
}
return NPERR_NO_ERROR;
}
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -556,35 +556,37 @@ Telephony::HandleAudioAgentState()
mIsAudioStartPlaying = false;
rv = mAudioAgent->NotifyStoppedPlaying();
mAudioAgent = nullptr;
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else if (!activeCall.IsNull() && !mIsAudioStartPlaying) {
mIsAudioStartPlaying = true;
- float volume;
- bool muted;
- rv = mAudioAgent->NotifyStartedPlaying(&volume, &muted);
+ AudioPlaybackConfig config;
+ rv = mAudioAgent->NotifyStartedPlaying(&config);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// In B2G, the system app manages audio playback policy. If there is a new
// sound want to be playback, it must wait for the permission from the
// system app. It means that the sound would be muted first, and then be
// unmuted. For telephony, the behaviors are hold() first, then resume().
// However, the telephony service can't handle all these requests within a
// short period. The telephony service would reject our resume request,
// because the modem have not changed the call state yet. It causes that
// the telephony can't be resumed. Therefore, we don't mute the telephony
// at the beginning.
- volume = 1.0;
- muted = false;
- rv = WindowVolumeChanged(volume, muted);
+ rv = WindowVolumeChanged(1.0, false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ rv = WindowSuspendChanged(config.mSuspend);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
bool