Bug 1240423 - part2 : introduce audible changing reasons.
MozReview-Commit-ID: 6V69hOCpyG3
--- a/dom/audiochannel/AudioChannelAgent.cpp
+++ b/dom/audiochannel/AudioChannelAgent.cpp
@@ -249,29 +249,31 @@ AudioChannelAgent::NotifyStoppedPlaying(
service->UnregisterAudioChannelAgent(this);
}
mIsRegToService = false;
return NS_OK;
}
NS_IMETHODIMP
-AudioChannelAgent::NotifyStartedAudible(bool aAudible)
+AudioChannelAgent::NotifyStartedAudible(bool aAudible, uint32_t aReason)
{
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelAgent, NotifyStartedAudible, this = %p, "
"audible = %d\n", this, aAudible));
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
if (NS_WARN_IF(!service)) {
return NS_ERROR_FAILURE;
}
service->AudioAudibleChanged(
- this, static_cast<AudioChannelService::AudibleState>(aAudible));
+ this,
+ static_cast<AudioChannelService::AudibleState>(aAudible),
+ static_cast<AudioChannelService::AudibleChangedReasons>(aReason));
return NS_OK;
}
already_AddRefed<nsIAudioChannelAgentCallback>
AudioChannelAgent::GetCallback()
{
nsCOMPtr<nsIAudioChannelAgentCallback> callback = mCallback;
if (!callback) {
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -100,42 +100,60 @@ bool
IsParentProcess()
{
return XRE_GetProcessType() == GeckoProcessType_Default;
}
class AudioPlaybackRunnable final : public Runnable
{
public:
- AudioPlaybackRunnable(nsPIDOMWindowOuter* aWindow, bool aActive)
+ AudioPlaybackRunnable(nsPIDOMWindowOuter* aWindow, bool aActive,
+ AudioChannelService::AudibleChangedReasons aReason)
: mWindow(aWindow)
, mActive(aActive)
+ , mReason(aReason)
{}
NS_IMETHOD Run()
{
nsCOMPtr<nsIObserverService> observerService =
services::GetObserverService();
if (NS_WARN_IF(!observerService)) {
return NS_ERROR_FAILURE;
}
+ nsAutoString state;
+ GetActiveState(state);
+
observerService->NotifyObservers(ToSupports(mWindow),
"audio-playback",
- mActive ? MOZ_UTF16("active")
- : MOZ_UTF16("inactive"));
+ state.get());
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioPlaybackRunnable, active = %d\n", mActive));
return NS_OK;
}
private:
+ void GetActiveState(nsAString& astate)
+ {
+ if (mActive) {
+ CopyASCIItoUTF16("active", astate);
+ } else {
+ if(mReason == AudioChannelService::AudibleChangedReasons::ePauseStateChanged) {
+ CopyASCIItoUTF16("inactive-pause", astate);
+ } else {
+ CopyASCIItoUTF16("inactive-nonaudible", astate);
+ }
+ }
+ }
+
nsCOMPtr<nsPIDOMWindowOuter> mWindow;
bool mActive;
+ AudioChannelService::AudibleChangedReasons mReason;
};
} // anonymous namespace
StaticRefPtr<AudioChannelService> gAudioChannelService;
// Mappings from 'mozaudiochannel' attribute strings to an enumeration.
static const nsAttrValue::EnumTable kMozAudioChannelAttributeTable[] = {
@@ -367,24 +385,25 @@ AudioChannelService::GetMediaConfig(nsPI
// If there is no parent, or we are the toplevel we don't continue.
} while (window && window != aWindow);
return config;
}
void
AudioChannelService::AudioAudibleChanged(AudioChannelAgent* aAgent,
- AudibleState aAudible)
+ AudibleState aAudible,
+ AudibleChangedReasons aReason)
{
MOZ_ASSERT(aAgent);
uint64_t windowID = aAgent->WindowID();
AudioChannelWindow* winData = GetWindowData(windowID);
if (winData) {
- winData->AudioAudibleChanged(aAgent, aAudible);
+ winData->AudioAudibleChanged(aAgent, aAudible, aReason);
}
}
bool
AudioChannelService::TelephonyChannelIsActive()
{
nsTObserverArray<nsAutoPtr<AudioChannelWindow>>::ForwardIterator windowsIter(mWindows);
while (windowsIter.HasMore()) {
@@ -1188,28 +1207,32 @@ AudioChannelService::AudioChannelWindow:
AudibleState aAudible)
{
MOZ_ASSERT(aAgent);
RequestAudioFocus(aAgent);
AppendAgentAndIncreaseAgentsNum(aAgent);
AudioCapturedChanged(aAgent, AudioCaptureState::eCapturing);
if (aAudible) {
- AudioAudibleChanged(aAgent, AudibleState::eAudible);
+ AudioAudibleChanged(aAgent,
+ AudibleState::eAudible,
+ AudibleChangedReasons::eDataAudibleChanged);
}
}
void
AudioChannelService::AudioChannelWindow::RemoveAgent(AudioChannelAgent* aAgent)
{
MOZ_ASSERT(aAgent);
RemoveAgentAndReduceAgentsNum(aAgent);
AudioCapturedChanged(aAgent, AudioCaptureState::eNotCapturing);
- AudioAudibleChanged(aAgent, AudibleState::eNotAudible);
+ AudioAudibleChanged(aAgent,
+ AudibleState::eNotAudible,
+ AudibleChangedReasons::ePauseStateChanged);
}
void
AudioChannelService::AudioChannelWindow::AppendAgentAndIncreaseAgentsNum(AudioChannelAgent* aAgent)
{
MOZ_ASSERT(aAgent);
MOZ_ASSERT(!mAgents.Contains(aAgent));
@@ -1253,52 +1276,55 @@ AudioChannelService::AudioChannelWindow:
if (mIsAudioCaptured) {
aAgent->WindowAudioCaptureChanged(aAgent->InnerWindowID(), aCapture);
}
}
void
AudioChannelService::AudioChannelWindow::AudioAudibleChanged(AudioChannelAgent* aAgent,
- AudibleState aAudible)
+ AudibleState aAudible,
+ AudibleChangedReasons aReason)
{
MOZ_ASSERT(aAgent);
if (aAudible) {
- AppendAudibleAgentIfNotContained(aAgent);
+ AppendAudibleAgentIfNotContained(aAgent, aReason);
} else {
- RemoveAudibleAgentIfContained(aAgent);
+ RemoveAudibleAgentIfContained(aAgent, aReason);
}
NotifyAudioCompetingChanged(aAgent, aAudible);
}
void
-AudioChannelService::AudioChannelWindow::AppendAudibleAgentIfNotContained(AudioChannelAgent* aAgent)
+AudioChannelService::AudioChannelWindow::AppendAudibleAgentIfNotContained(AudioChannelAgent* aAgent,
+ AudibleChangedReasons aReason)
{
MOZ_ASSERT(aAgent);
MOZ_ASSERT(mAgents.Contains(aAgent));
if (!mAudibleAgents.Contains(aAgent)) {
mAudibleAgents.AppendElement(aAgent);
if (IsFirstAudibleAgent()) {
- NotifyAudioAudibleChanged(aAgent->Window(), AudibleState::eAudible);
+ NotifyAudioAudibleChanged(aAgent->Window(), AudibleState::eAudible, aReason);
}
}
}
void
-AudioChannelService::AudioChannelWindow::RemoveAudibleAgentIfContained(AudioChannelAgent* aAgent)
+AudioChannelService::AudioChannelWindow::RemoveAudibleAgentIfContained(AudioChannelAgent* aAgent,
+ AudibleChangedReasons aReason)
{
MOZ_ASSERT(aAgent);
if (mAudibleAgents.Contains(aAgent)) {
mAudibleAgents.RemoveElement(aAgent);
if (IsLastAudibleAgent()) {
- NotifyAudioAudibleChanged(aAgent->Window(), AudibleState::eNotAudible);
+ NotifyAudioAudibleChanged(aAgent->Window(), AudibleState::eNotAudible, aReason);
}
}
}
bool
AudioChannelService::AudioChannelWindow::IsFirstAudibleAgent() const
{
return (mAudibleAgents.Length() == 1);
@@ -1307,20 +1333,21 @@ AudioChannelService::AudioChannelWindow:
bool
AudioChannelService::AudioChannelWindow::IsLastAudibleAgent() const
{
return mAudibleAgents.IsEmpty();
}
void
AudioChannelService::AudioChannelWindow::NotifyAudioAudibleChanged(nsPIDOMWindowOuter* aWindow,
- AudibleState aAudible)
+ AudibleState aAudible,
+ AudibleChangedReasons aReason)
{
RefPtr<AudioPlaybackRunnable> runnable =
- new AudioPlaybackRunnable(aWindow, aAudible);
+ new AudioPlaybackRunnable(aWindow, aAudible, aReason);
nsresult rv = NS_DispatchToCurrentThread(runnable);
NS_WARN_IF(NS_FAILED(rv));
}
void
AudioChannelService::AudioChannelWindow::NotifyChannelActive(uint64_t aWindowID,
AudioChannel aChannel,
bool aActive)
--- a/dom/audiochannel/AudioChannelService.h
+++ b/dom/audiochannel/AudioChannelService.h
@@ -73,16 +73,22 @@ public:
eNotAudible = false
};
enum AudioCaptureState : bool {
eCapturing = true,
eNotCapturing = false
};
+ enum AudibleChangedReasons : uint32_t {
+ eVolumeChanged = 0,
+ eDataAudibleChanged = 1,
+ ePauseStateChanged = 2
+ };
+
/**
* Returns the AudioChannelServce singleton.
* If AudioChannelServce is not exist, create and return new one.
* Only to be called from main thread.
*/
static already_AddRefed<AudioChannelService> GetOrCreate();
static bool IsAudioChannelMutedByDefault();
@@ -117,17 +123,19 @@ public:
AudioPlaybackConfig GetMediaConfig(nsPIDOMWindowOuter* aWindow,
uint32_t aAudioChannel) const;
/**
* Called this method when the audible state of the audio playback changed,
* it would dispatch the playback event to observers which want to know the
* actual audible state of the window.
*/
- void AudioAudibleChanged(AudioChannelAgent* aAgent, AudibleState aAudible);
+ void AudioAudibleChanged(AudioChannelAgent* aAgent,
+ AudibleState aAudible,
+ AudibleChangedReasons aReason);
/* Methods for the BrowserElementAudioChannel */
float GetAudioChannelVolume(nsPIDOMWindowOuter* aWindow, AudioChannel aChannel);
void SetAudioChannelVolume(nsPIDOMWindowOuter* aWindow, AudioChannel aChannel,
float aVolume);
bool GetAudioChannelMuted(nsPIDOMWindowOuter* aWindow, AudioChannel aChannel);
@@ -245,17 +253,19 @@ private:
, mIsAudioCaptured(false)
, mOwningAudioFocus(!AudioChannelService::IsEnableAudioCompeting())
{
// Workaround for bug1183033, system channel type can always playback.
mChannels[(int16_t)AudioChannel::System].mMuted = false;
}
void AudioFocusChanged(AudioChannelAgent* aNewPlayingAgent, bool aActive);
- void AudioAudibleChanged(AudioChannelAgent* aAgent, AudibleState aAudible);
+ void AudioAudibleChanged(AudioChannelAgent* aAgent,
+ AudibleState aAudible,
+ AudibleChangedReasons aReason);
void AppendAgent(AudioChannelAgent* aAgent, AudibleState aAudible);
void RemoveAgent(AudioChannelAgent* aAgent);
uint64_t mWindowID;
bool mIsAudioCaptured;
AudioChannelConfig mChannels[NUMBER_OF_AUDIO_CHANNELS];
@@ -266,27 +276,31 @@ private:
// Owning audio focus when the window starts playing audible sound, and
// lose audio focus when other windows starts playing.
bool mOwningAudioFocus;
private:
void AudioCapturedChanged(AudioChannelAgent* aAgent,
AudioCaptureState aCapture);
- void AppendAudibleAgentIfNotContained(AudioChannelAgent* aAgent);
- void RemoveAudibleAgentIfContained(AudioChannelAgent* aAgent);
+ void AppendAudibleAgentIfNotContained(AudioChannelAgent* aAgent,
+ AudibleChangedReasons aReason);
+ void RemoveAudibleAgentIfContained(AudioChannelAgent* aAgent,
+ AudibleChangedReasons aReason);
void AppendAgentAndIncreaseAgentsNum(AudioChannelAgent* aAgent);
void RemoveAgentAndReduceAgentsNum(AudioChannelAgent* aAgent);
bool IsFirstAudibleAgent() const;
bool IsLastAudibleAgent() const;
void NotifyAudioAudibleChanged(nsPIDOMWindowOuter* aWindow,
- AudibleState aAudible);
+ AudibleState aAudible,
+ AudibleChangedReasons aReason);
+
void NotifyChannelActive(uint64_t aWindowID, AudioChannel aChannel,
bool aActive);
void RequestAudioFocus(AudioChannelAgent* aAgent);
void NotifyAudioCompetingChanged(AudioChannelAgent* aAgent, bool aActive);
uint32_t GetCompetingBehavior(AudioChannelAgent* aAgent,
int32_t aIncomingChannelType,
--- a/dom/audiochannel/nsIAudioChannelAgent.idl
+++ b/dom/audiochannel/nsIAudioChannelAgent.idl
@@ -178,10 +178,10 @@ interface nsIAudioChannelAgent : nsISupp
/**
* Notify agent that we already start producing audible data.
*
* Note : sometime audio might become silent during playing, this method is used to
* notify the actually audible state to other services which want to know
* about that, ex. tab sound indicator.
*/
- void notifyStartedAudible(in bool audible);
+ void notifyStartedAudible(in bool audible, in uint32_t reason);
};