Bug 862899 - AudioChannelAgent in the FMRadio API. r=mchen, r=khuey

This commit is contained in:
Andrea Marchesini 2013-11-04 17:27:39 -05:00
Родитель 482cf2ff57
Коммит 667c7302c2
9 изменённых файлов: 131 добавлений и 10 удалений

Просмотреть файл

@ -14,6 +14,10 @@
#include "mozilla/dom/PFMRadioChild.h"
#include "mozilla/dom/FMRadioService.h"
#include "DOMRequest.h"
#include "nsDOMClassInfo.h"
#include "nsIDocShell.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIAudioManager.h"
#undef LOG
#define LOG(args...) FM_LOG("FMRadio", args)
@ -110,6 +114,27 @@ FMRadio::Init(nsPIDOMWindow *aWindow)
mHeadphoneState = GetCurrentSwitchState(SWITCH_HEADPHONES);
RegisterSwitchObserver(SWITCH_HEADPHONES, this);
}
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
NS_ENSURE_TRUE_VOID(target);
target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"), this,
/* useCapture = */ true,
/* wantsUntrusted = */ false);
mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
if (!mAudioChannelAgent) {
return;
}
mAudioChannelAgent->InitWithWeakCallback(nsIAudioChannelAgent::AUDIO_AGENT_CHANNEL_CONTENT,
this);
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner());
if (docshell) {
bool isActive = false;
docshell->GetIsActive(&isActive);
mAudioChannelAgent->SetVisibilityState(isActive);
}
}
void
@ -121,6 +146,11 @@ FMRadio::Shutdown()
UnregisterSwitchObserver(SWITCH_HEADPHONES, this);
}
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
NS_ENSURE_TRUE_VOID(target);
target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), this,
/* useCapture = */ true);
mIsShutdown = true;
}
@ -151,8 +181,14 @@ FMRadio::Notify(const FMRadioEventType& aType)
break;
case EnabledChanged:
if (Enabled()) {
int32_t playingState = 0;
mAudioChannelAgent->StartPlaying(&playingState);
SetCanPlay(playingState == AudioChannelState::AUDIO_CHANNEL_STATE_NORMAL);
DispatchTrustedEvent(NS_LITERAL_STRING("enabled"));
} else {
mAudioChannelAgent->StopPlaying();
DispatchTrustedEvent(NS_LITERAL_STRING("disabled"));
}
break;
@ -284,8 +320,43 @@ FMRadio::CancelSeek()
return r.forget();
}
NS_IMETHODIMP
FMRadio::HandleEvent(nsIDOMEvent* aEvent)
{
nsAutoString type;
aEvent->GetType(type);
if (!type.EqualsLiteral("visibilitychange")) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner());
NS_ENSURE_TRUE(docshell, NS_ERROR_FAILURE);
bool isActive = false;
docshell->GetIsActive(&isActive);
mAudioChannelAgent->SetVisibilityState(isActive);
return NS_OK;
}
NS_IMETHODIMP
FMRadio::CanPlayChanged(int32_t aCanPlay)
{
SetCanPlay(aCanPlay == AudioChannelState::AUDIO_CHANNEL_STATE_NORMAL);
return NS_OK;
}
void
FMRadio::SetCanPlay(bool aCanPlay)
{
IFMRadioService::Singleton()->EnableAudio(aCanPlay);
}
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FMRadio)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgentCallback)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(FMRadio, nsDOMEventTargetHelper)

Просмотреть файл

@ -11,6 +11,7 @@
#include "nsCycleCollectionParticipant.h"
#include "mozilla/HalTypes.h"
#include "nsWeakReference.h"
#include "AudioChannelAgent.h"
class nsPIDOMWindow;
class nsIScriptContext;
@ -23,6 +24,9 @@ class FMRadio MOZ_FINAL : public nsDOMEventTargetHelper
, public hal::SwitchObserver
, public FMRadioEventObserver
, public nsSupportsWeakReference
, public nsIAudioChannelAgentCallback
, public nsIDOMEventListener
{
friend class FMRadioRequest;
@ -30,6 +34,7 @@ public:
FMRadio();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
@ -78,12 +83,19 @@ public:
IMPL_EVENT_HANDLER(antennaavailablechange);
IMPL_EVENT_HANDLER(frequencychange);
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
private:
~FMRadio();
void SetCanPlay(bool aCanPlay);
hal::SwitchState mHeadphoneState;
bool mHasInternalAntenna;
bool mIsShutdown;
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
};
END_FMRADIO_NAMESPACE

Просмотреть файл

@ -123,12 +123,8 @@ public:
info.spaceType() = mSpaceType;
EnableFMRadio(info);
IFMRadioService::Singleton()->EnableAudio(true);
nsCOMPtr<nsIAudioManager> audioManager =
do_GetService(NS_AUDIOMANAGER_CONTRACTID);
audioManager->SetFmRadioAudioEnabled(true);
// TODO apply path from bug 862899: AudioChannelAgent per process
return NS_OK;
}
@ -209,11 +205,7 @@ public:
// Fix Bug 796733. DisableFMRadio should be called before
// SetFmRadioAudioEnabled to prevent the annoying beep sound.
DisableFMRadio();
nsCOMPtr<nsIAudioManager> audioManager =
do_GetService(NS_AUDIOMANAGER_CONTRACTID);
audioManager->SetFmRadioAudioEnabled(false);
IFMRadioService::Singleton()->EnableAudio(false);
return NS_OK;
}
@ -299,6 +291,24 @@ FMRadioService::RemoveObserver(FMRadioEventObserver* aObserver)
}
}
void
FMRadioService::EnableAudio(bool aAudioEnabled)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIAudioManager> audioManager =
do_GetService("@mozilla.org/telephony/audiomanager;1");
if (!audioManager) {
return;
}
bool AudioEnabled;
audioManager->GetFmRadioAudioEnabled(&AudioEnabled);
if (AudioEnabled != aAudioEnabled) {
audioManager->SetFmRadioAudioEnabled(aAudioEnabled);
}
}
/**
* Round the frequency to match the range of frequency and the channel width. If
* the given frequency is out of range, return 0. For example:

Просмотреть файл

@ -117,6 +117,9 @@ public:
virtual void AddObserver(FMRadioEventObserver* aObserver) = 0;
virtual void RemoveObserver(FMRadioEventObserver* aObserver) = 0;
// Enable/Disable FMRadio
virtual void EnableAudio(bool aAudioEnabled) = 0;
/**
* Static method to return the singleton instance. If it's in the child
* process, we will get an object of FMRadioChild.
@ -164,6 +167,8 @@ public:
virtual void AddObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE;
virtual void RemoveObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE;
virtual void EnableAudio(bool aAudioEnabled) MOZ_OVERRIDE;
/* FMRadioObserver */
void Notify(const hal::FMRadioOperationInformation& aInfo) MOZ_OVERRIDE;

Просмотреть файл

@ -165,6 +165,12 @@ FMRadioChild::DeallocPFMRadioRequestChild(PFMRadioRequestChild* aActor)
return true;
}
void
FMRadioChild::EnableAudio(bool aAudioEnabled)
{
SendEnableAudio(aAudioEnabled);
}
// static
FMRadioChild*
FMRadioChild::Singleton()

Просмотреть файл

@ -51,6 +51,8 @@ public:
virtual void AddObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE;
virtual void RemoveObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE;
virtual void EnableAudio(bool aAudioEnabled) MOZ_OVERRIDE;
/* PFMRadioChild */
virtual bool
Recv__delete__() MOZ_OVERRIDE;

Просмотреть файл

@ -97,5 +97,12 @@ FMRadioParent::Notify(const FMRadioEventType& aType)
}
}
bool
FMRadioParent::RecvEnableAudio(const bool& aAudioEnabled)
{
IFMRadioService::Singleton()->EnableAudio(aAudioEnabled);
return true;
}
END_FMRADIO_NAMESPACE

Просмотреть файл

@ -33,6 +33,9 @@ public:
/* FMRadioEventObserver */
virtual void Notify(const FMRadioEventType& aType) MOZ_OVERRIDE;
virtual bool
RecvEnableAudio(const bool& aAudioEnabled) MOZ_OVERRIDE;
};
END_FMRADIO_NAMESPACE

Просмотреть файл

@ -86,6 +86,11 @@ parent:
* is more error prone.
*/
PFMRadioRequest(FMRadioRequestArgs requestType);
/**
* Enable/Disable audio
*/
EnableAudio(bool audioEnabled);
};
} // namespace dom