michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "AudioChannelAgent.h" michael@0: #include "AudioChannelCommon.h" michael@0: #include "AudioChannelService.h" michael@0: #include "nsIDOMWindow.h" michael@0: #include "nsPIDOMWindow.h" michael@0: #include "nsXULAppAPI.h" michael@0: michael@0: using namespace mozilla::dom; michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION(AudioChannelAgent, mWindow, mCallback) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AudioChannelAgent) michael@0: NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgent) michael@0: NS_INTERFACE_MAP_ENTRY(nsISupports) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioChannelAgent) michael@0: NS_IMPL_CYCLE_COLLECTING_RELEASE(AudioChannelAgent) michael@0: michael@0: AudioChannelAgent::AudioChannelAgent() michael@0: : mAudioChannelType(AUDIO_AGENT_CHANNEL_ERROR) michael@0: , mIsRegToService(false) michael@0: , mVisible(true) michael@0: , mWithVideo(false) michael@0: { michael@0: } michael@0: michael@0: AudioChannelAgent::~AudioChannelAgent() michael@0: { michael@0: if (mIsRegToService) { michael@0: StopPlaying(); michael@0: } michael@0: } michael@0: michael@0: /* readonly attribute long audioChannelType; */ michael@0: NS_IMETHODIMP AudioChannelAgent::GetAudioChannelType(int32_t *aAudioChannelType) michael@0: { michael@0: *aAudioChannelType = mAudioChannelType; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* boolean init (in nsIDOMWindow window, in long channelType, michael@0: * in nsIAudioChannelAgentCallback callback); */ michael@0: NS_IMETHODIMP michael@0: AudioChannelAgent::Init(nsIDOMWindow* aWindow, int32_t aChannelType, michael@0: nsIAudioChannelAgentCallback *aCallback) michael@0: { michael@0: return InitInternal(aWindow, aChannelType, aCallback, michael@0: /* useWeakRef = */ false); michael@0: } michael@0: michael@0: /* boolean initWithWeakCallback (in nsIDOMWindow window, in long channelType, michael@0: * in nsIAudioChannelAgentCallback callback); */ michael@0: NS_IMETHODIMP michael@0: AudioChannelAgent::InitWithWeakCallback(nsIDOMWindow* aWindow, michael@0: int32_t aChannelType, michael@0: nsIAudioChannelAgentCallback *aCallback) michael@0: { michael@0: return InitInternal(aWindow, aChannelType, aCallback, michael@0: /* useWeakRef = */ true); michael@0: } michael@0: michael@0: /* void initWithVideo(in nsIDOMWindow window, in long channelType, michael@0: * in nsIAudioChannelAgentCallback callback, in boolean weak); */ michael@0: NS_IMETHODIMP michael@0: AudioChannelAgent::InitWithVideo(nsIDOMWindow* aWindow, int32_t aChannelType, michael@0: nsIAudioChannelAgentCallback *aCallback, michael@0: bool aUseWeakRef) michael@0: { michael@0: return InitInternal(aWindow, aChannelType, aCallback, aUseWeakRef, michael@0: /* withVideo = */ true); michael@0: } michael@0: michael@0: nsresult michael@0: AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType, michael@0: nsIAudioChannelAgentCallback *aCallback, michael@0: bool aUseWeakRef, bool aWithVideo) michael@0: { michael@0: // We need the window only for IPC. michael@0: MOZ_ASSERT(aWindow || XRE_GetProcessType() == GeckoProcessType_Default); michael@0: michael@0: // We syncd the enum of channel type between nsIAudioChannelAgent.idl and michael@0: // AudioChannelBinding.h the same. michael@0: MOZ_ASSERT(int(AUDIO_AGENT_CHANNEL_NORMAL) == int(AudioChannel::Normal) && michael@0: int(AUDIO_AGENT_CHANNEL_CONTENT) == int(AudioChannel::Content) && michael@0: int(AUDIO_AGENT_CHANNEL_NOTIFICATION) == int(AudioChannel::Notification) && michael@0: int(AUDIO_AGENT_CHANNEL_ALARM) == int(AudioChannel::Alarm) && michael@0: int(AUDIO_AGENT_CHANNEL_TELEPHONY) == int(AudioChannel::Telephony) && michael@0: int(AUDIO_AGENT_CHANNEL_RINGER) == int(AudioChannel::Ringer) && michael@0: int(AUDIO_AGENT_CHANNEL_PUBLICNOTIFICATION) == int(AudioChannel::Publicnotification), michael@0: "Enum of channel on nsIAudioChannelAgent.idl should be the same with AudioChannelBinding.h"); michael@0: michael@0: if (mAudioChannelType != AUDIO_AGENT_CHANNEL_ERROR || michael@0: aChannelType > AUDIO_AGENT_CHANNEL_PUBLICNOTIFICATION || michael@0: aChannelType < AUDIO_AGENT_CHANNEL_NORMAL) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: mWindow = aWindow; michael@0: mAudioChannelType = aChannelType; michael@0: michael@0: if (aUseWeakRef) { michael@0: mWeakCallback = do_GetWeakReference(aCallback); michael@0: } else { michael@0: mCallback = aCallback; michael@0: } michael@0: michael@0: mWithVideo = aWithVideo; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* boolean startPlaying (); */ michael@0: NS_IMETHODIMP AudioChannelAgent::StartPlaying(int32_t *_retval) michael@0: { michael@0: AudioChannelService *service = AudioChannelService::GetAudioChannelService(); michael@0: if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR || michael@0: service == nullptr || mIsRegToService) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: service->RegisterAudioChannelAgent(this, michael@0: static_cast(mAudioChannelType), mWithVideo); michael@0: *_retval = service->GetState(this, !mVisible); michael@0: mIsRegToService = true; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void stopPlaying (); */ michael@0: NS_IMETHODIMP AudioChannelAgent::StopPlaying(void) michael@0: { michael@0: if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR || michael@0: !mIsRegToService) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: AudioChannelService *service = AudioChannelService::GetAudioChannelService(); michael@0: service->UnregisterAudioChannelAgent(this); michael@0: mIsRegToService = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void setVisibilityState (in boolean visible); */ michael@0: NS_IMETHODIMP AudioChannelAgent::SetVisibilityState(bool visible) michael@0: { michael@0: bool oldVisibility = mVisible; michael@0: michael@0: nsCOMPtr callback = GetCallback(); michael@0: michael@0: mVisible = visible; michael@0: if (mIsRegToService && oldVisibility != mVisible && callback) { michael@0: AudioChannelService *service = AudioChannelService::GetAudioChannelService(); michael@0: callback->CanPlayChanged(service->GetState(this, !mVisible)); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: void AudioChannelAgent::NotifyAudioChannelStateChanged() michael@0: { michael@0: nsCOMPtr callback = GetCallback(); michael@0: if (callback) { michael@0: AudioChannelService *service = AudioChannelService::GetAudioChannelService(); michael@0: callback->CanPlayChanged(service->GetState(this, !mVisible)); michael@0: } michael@0: } michael@0: michael@0: already_AddRefed michael@0: AudioChannelAgent::GetCallback() michael@0: { michael@0: nsCOMPtr callback = mCallback; michael@0: if (!callback) { michael@0: callback = do_QueryReferent(mWeakCallback); michael@0: } michael@0: return callback.forget(); michael@0: } michael@0: michael@0: void michael@0: AudioChannelAgent::WindowVolumeChanged() michael@0: { michael@0: nsCOMPtr callback = GetCallback(); michael@0: if (!callback) { michael@0: return; michael@0: } michael@0: michael@0: callback->WindowVolumeChanged(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: AudioChannelAgent::GetWindowVolume(float* aVolume) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aVolume); michael@0: michael@0: nsCOMPtr win = do_QueryInterface(mWindow); michael@0: if (!win) { michael@0: *aVolume = 1.0f; michael@0: return NS_OK; michael@0: } michael@0: michael@0: *aVolume = win->GetAudioGlobalVolume(); michael@0: return NS_OK; michael@0: }