mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 815452: Hook up FM radio to the audio manager. r=sicking a=blocking-basecamp
This commit is contained in:
parent
dc892b3d1e
commit
031981ba1b
@ -73,6 +73,19 @@ DOMFMRadioChild.prototype = {
|
||||
"DOMFMRadio:powerStateChange",
|
||||
"DOMFMRadio:antennaChange"];
|
||||
this.initHelper(aWindow, messages);
|
||||
|
||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Ci.nsIEventListenerService);
|
||||
|
||||
els.addSystemEventListener(aWindow, "visibilitychange",
|
||||
this._updateVisibility.bind(this),
|
||||
/* useCapture = */ true);
|
||||
|
||||
this._visibility = aWindow.document.visibilityState;
|
||||
// Unlike the |enabled| getter, this is true if *this* DOM window
|
||||
// has successfully enabled the FM radio more recently than
|
||||
// disabling it.
|
||||
this._haveEnabledRadio = false;
|
||||
},
|
||||
|
||||
// Called from DOMRequestIpcHelper
|
||||
@ -130,6 +143,18 @@ DOMFMRadioChild.prototype = {
|
||||
this.dispatchEvent(e);
|
||||
},
|
||||
|
||||
_updateVisibility: function(evt) {
|
||||
this._visibility = evt.target.visibilityState;
|
||||
// Only notify visibility state when we "own" the radio stream.
|
||||
if (this._haveEnabledRadio) {
|
||||
this._notifyVisibility();
|
||||
}
|
||||
},
|
||||
|
||||
_notifyVisibility: function() {
|
||||
cpmm.sendAsyncMessage("DOMFMRadio:updateVisibility", this._visibility);
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
let msg = aMessage.json;
|
||||
if (msg.mid && msg.mid != this._id) {
|
||||
@ -153,6 +178,7 @@ DOMFMRadioChild.prototype = {
|
||||
Services.DOMRequest.fireError(request, "Failed to turn on the FM radio");
|
||||
break;
|
||||
case "DOMFMRadio:disable:Return:OK":
|
||||
this._haveEnabledRadio = false;
|
||||
request = this.takeRequest(msg.rid);
|
||||
if (!request) {
|
||||
return;
|
||||
@ -160,6 +186,10 @@ DOMFMRadioChild.prototype = {
|
||||
Services.DOMRequest.fireSuccess(request, null);
|
||||
break;
|
||||
case "DOMFMRadio:disable:Return:NO":
|
||||
// If disabling the radio failed, but the hardware is still
|
||||
// on, this DOM window is still responsible for the continued
|
||||
// playback.
|
||||
this._haveEnabledRadio = this.enabled;
|
||||
request = this.takeRequest(msg.rid);
|
||||
if (!request) {
|
||||
return;
|
||||
@ -291,6 +321,10 @@ DOMFMRadioChild.prototype = {
|
||||
},
|
||||
|
||||
enable: function nsIDOMFMRadio_enable(frequency) {
|
||||
// FMRadio::Enable() needs the most recent visibility state
|
||||
// synchronously.
|
||||
this._haveEnabledRadio = true;
|
||||
this._notifyVisibility();
|
||||
return this._call("enable", frequency);
|
||||
},
|
||||
|
||||
|
@ -101,7 +101,8 @@ this.DOMFMRadioParent = {
|
||||
"DOMFMRadio:getPowerState", "DOMFMRadio:getFrequency",
|
||||
"DOMFMRadio:getAntennaState",
|
||||
"DOMFMRadio:seekUp", "DOMFMRadio:seekDown",
|
||||
"DOMFMRadio:cancelSeek"
|
||||
"DOMFMRadio:cancelSeek",
|
||||
"DOMFMRadio:updateVisibility",
|
||||
];
|
||||
this._messages.forEach(function(msgName) {
|
||||
ppmm.addMessageListener(msgName, this);
|
||||
@ -458,6 +459,9 @@ this.DOMFMRadioParent = {
|
||||
self._sendMessage("DOMFMRadio:cancelSeek:Return", true, null, msg);
|
||||
}
|
||||
break;
|
||||
case "DOMFMRadio:updateVisibility":
|
||||
FMRadio.updateVisible(msg == 'visible');
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -38,6 +38,7 @@ using mozilla::Preferences;
|
||||
FMRadio::FMRadio()
|
||||
: mHeadphoneState(SWITCH_STATE_OFF)
|
||||
, mHasInternalAntenna(false)
|
||||
, mHidden(true)
|
||||
{
|
||||
LOG("FMRadio is initialized.");
|
||||
|
||||
@ -114,6 +115,23 @@ NS_IMETHODIMP FMRadio::Enable(nsIFMRadioSettings *settings)
|
||||
|
||||
int32_t upperLimit, lowerLimit, channelWidth;
|
||||
|
||||
if (!mAudioChannelAgent) {
|
||||
nsresult rv;
|
||||
mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1", &rv);
|
||||
if (!mAudioChannelAgent) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mAudioChannelAgent->Init(AUDIO_CHANNEL_CONTENT, this);
|
||||
}
|
||||
|
||||
bool canPlay;
|
||||
mAudioChannelAgent->SetVisibilityState(!mHidden);
|
||||
mAudioChannelAgent->StartPlaying(&canPlay);
|
||||
// We enable the hardware, but mute the audio stream, in order to
|
||||
// simplify state handling. This is simpler but worse for battery
|
||||
// life; followup is bug 820282.
|
||||
CanPlayChanged(canPlay);
|
||||
|
||||
settings->GetUpperLimit(&upperLimit);
|
||||
settings->GetLowerLimit(&lowerLimit);
|
||||
settings->GetChannelWidth(&channelWidth);
|
||||
@ -140,12 +158,17 @@ NS_IMETHODIMP FMRadio::Disable()
|
||||
// DisableFMRadio should be called before SetFmRadioAudioEnabled to prevent
|
||||
// the annoying beep sound.
|
||||
DisableFMRadio();
|
||||
|
||||
|
||||
nsCOMPtr<nsIAudioManager> audioManager =
|
||||
do_GetService(NS_AUDIOMANAGER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(audioManager, NS_OK);
|
||||
|
||||
audioManager->SetFmRadioAudioEnabled(false);
|
||||
|
||||
if (mAudioChannelAgent) {
|
||||
mAudioChannelAgent->StopPlaying();
|
||||
mAudioChannelAgent = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -189,6 +212,15 @@ NS_IMETHODIMP FMRadio::SetFrequency(int32_t frequency)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP FMRadio::UpdateVisible(bool aVisible)
|
||||
{
|
||||
mHidden = !aVisible;
|
||||
if (mAudioChannelAgent) {
|
||||
mAudioChannelAgent->SetVisibilityState(!mHidden);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void FMRadio::Notify(const SwitchEvent& aEvent)
|
||||
{
|
||||
if (mHeadphoneState != aEvent.status()) {
|
||||
@ -211,5 +243,27 @@ void FMRadio::Notify(const FMRadioOperationInformation& info)
|
||||
case FM_RADIO_OPERATION_SEEK:
|
||||
DispatchTrustedEvent(RADIO_SEEK_COMPLETE_EVENT_NAME);
|
||||
break;
|
||||
default:
|
||||
MOZ_NOT_REACHED();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* void canPlayChanged (in boolean canPlay); */
|
||||
NS_IMETHODIMP FMRadio::CanPlayChanged(bool canPlay)
|
||||
{
|
||||
nsCOMPtr<nsIAudioManager> audioManager =
|
||||
do_GetService(NS_AUDIOMANAGER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(audioManager, NS_OK);
|
||||
/* mute fm first, it should be better to stop&resume fm */
|
||||
if (canPlay) {
|
||||
int32_t volIdx = 0;
|
||||
// Restore fm volume, that value is sync as music type
|
||||
audioManager->GetStreamVolumeIndex(nsIAudioManager::STREAM_TYPE_MUSIC, &volIdx);
|
||||
audioManager->SetStreamVolumeIndex(nsIAudioManager::STREAM_TYPE_FM, volIdx);
|
||||
} else {
|
||||
audioManager->SetStreamVolumeIndex(nsIAudioManager::STREAM_TYPE_FM, 0);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/HalTypes.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "nsIFMRadio.h"
|
||||
#include "AudioChannelService.h"
|
||||
|
||||
#define NS_FMRADIO_CONTRACTID "@mozilla.org/fmradio;1"
|
||||
// 9cb91834-78a9-4029-b644-7806173c5e2d
|
||||
@ -26,10 +27,12 @@ class FMRadio : public nsDOMEventTargetHelper
|
||||
, public nsIFMRadio
|
||||
, public hal::FMRadioObserver
|
||||
, public hal::SwitchObserver
|
||||
, public nsIAudioChannelAgentCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFMRADIO
|
||||
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
|
||||
|
||||
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
|
||||
@ -41,8 +44,11 @@ public:
|
||||
|
||||
private:
|
||||
~FMRadio();
|
||||
bool mHasInternalAntenna;
|
||||
|
||||
hal::SwitchState mHeadphoneState;
|
||||
bool mHasInternalAntenna;
|
||||
bool mHidden;
|
||||
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
|
||||
};
|
||||
|
||||
} // namespace fm
|
||||
|
@ -26,7 +26,7 @@ interface nsIFMRadioSettings : nsISupports
|
||||
*
|
||||
* If the WebFM API is re-written in c++ some day, this interface will be useless.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(26288adc-d2c1-4fbc-86b5-ecd8173fbf90)]
|
||||
[scriptable, builtinclass, uuid(9586bc9c-738e-4bcd-907c-ad340a6adc8b)]
|
||||
interface nsIFMRadio : nsIDOMEventTarget {
|
||||
const long SEEK_DIRECTION_UP = 0;
|
||||
const long SEEK_DIRECTION_DOWN = 1;
|
||||
@ -79,6 +79,11 @@ interface nsIFMRadio : nsIDOMEventTarget {
|
||||
*/
|
||||
void setFrequency(in long frequency);
|
||||
|
||||
/**
|
||||
* Update the visibility state of our client.
|
||||
*/
|
||||
void updateVisible(in boolean visible);
|
||||
|
||||
/**
|
||||
* Fired when the antenna state is changed.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user