зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1113086 - AudioChannel policy in Browser API - patch 5 - nsTObserverArray instead hashtables, r=ehsan, r=alwu
This commit is contained in:
Родитель
7fe6a31b4a
Коммит
2ba53b5aab
|
@ -91,6 +91,10 @@ AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
|
|||
MOZ_ASSERT(topWindow);
|
||||
|
||||
mWindow = do_QueryInterface(topWindow);
|
||||
if (!mWindow) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mWindow = mWindow->GetOuterWindow();
|
||||
}
|
||||
|
||||
|
|
|
@ -64,5 +64,5 @@ private:
|
|||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -190,12 +190,14 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
|
|||
}
|
||||
|
||||
uint64_t windowID = aAgent->WindowID();
|
||||
AudioChannelWindow* winData = mWindows.LookupOrAdd(windowID);
|
||||
AudioChannelWindow* winData = GetWindowData(windowID);
|
||||
if (!winData) {
|
||||
winData = new AudioChannelWindow(windowID);
|
||||
mWindows.AppendElement(winData);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!winData->mAgents.Get(aAgent));
|
||||
|
||||
AudioChannel* audioChannel = new AudioChannel(aChannel);
|
||||
winData->mAgents.Put(aAgent, audioChannel);
|
||||
MOZ_ASSERT(!winData->mAgents.Contains(aAgent));
|
||||
winData->mAgents.AppendElement(aAgent);
|
||||
|
||||
++winData->mChannels[(uint32_t)aChannel].mNumberOfAgents;
|
||||
|
||||
|
@ -205,7 +207,7 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
|
|||
}
|
||||
|
||||
// If this is the first agent for this window, we must notify the observers.
|
||||
if (winData->mAgents.Count() == 1) {
|
||||
if (winData->mAgents.Length() == 1) {
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
services::GetObserverService();
|
||||
if (observerService) {
|
||||
|
@ -225,22 +227,25 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
|
|||
return;
|
||||
}
|
||||
|
||||
uint64_t windowID = aAgent->WindowID();
|
||||
AudioChannelWindow* winData = nullptr;
|
||||
if (!mWindows.Get(windowID, &winData)) {
|
||||
AudioChannelWindow* winData = GetWindowData(aAgent->WindowID());
|
||||
if (!winData) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoPtr<AudioChannel> audioChannel;
|
||||
winData->mAgents.RemoveAndForget(aAgent, audioChannel);
|
||||
if (audioChannel) {
|
||||
MOZ_ASSERT(winData->mChannels[(uint32_t)*audioChannel].mNumberOfAgents > 0);
|
||||
if (winData->mAgents.Contains(aAgent)) {
|
||||
int32_t channel = aAgent->AudioChannelType();
|
||||
uint64_t windowID = aAgent->WindowID();
|
||||
|
||||
--winData->mChannels[(uint32_t)*audioChannel].mNumberOfAgents;
|
||||
// aAgent can be freed after this call.
|
||||
winData->mAgents.RemoveElement(aAgent);
|
||||
|
||||
MOZ_ASSERT(winData->mChannels[channel].mNumberOfAgents > 0);
|
||||
|
||||
--winData->mChannels[channel].mNumberOfAgents;
|
||||
|
||||
// The last one, we must inform the BrowserElementAudioChannel.
|
||||
if (winData->mChannels[(uint32_t)*audioChannel].mNumberOfAgents == 0) {
|
||||
NotifyChannelActive(aAgent->WindowID(), *audioChannel, false);
|
||||
if (winData->mChannels[channel].mNumberOfAgents == 0) {
|
||||
NotifyChannelActive(windowID, static_cast<AudioChannel>(channel), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +257,7 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
|
|||
#endif
|
||||
|
||||
// If this is the last agent for this window, we must notify the observers.
|
||||
if (winData->mAgents.Count() == 0) {
|
||||
if (winData->mAgents.IsEmpty()) {
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
services::GetObserverService();
|
||||
if (observerService) {
|
||||
|
@ -286,7 +291,8 @@ AudioChannelService::GetState(nsPIDOMWindow* aWindow, uint32_t aAudioChannel,
|
|||
// The volume must be calculated based on the window hierarchy. Here we go up
|
||||
// to the top window and we calculate the volume and the muted flag.
|
||||
do {
|
||||
if (mWindows.Get(window->WindowID(), &winData)) {
|
||||
winData = GetWindowData(window->WindowID());
|
||||
if (winData) {
|
||||
*aVolume *= winData->mChannels[aAudioChannel].mVolume;
|
||||
*aMuted = *aMuted || winData->mChannels[aAudioChannel].mMuted;
|
||||
}
|
||||
|
@ -306,55 +312,30 @@ AudioChannelService::GetState(nsPIDOMWindow* aWindow, uint32_t aAudioChannel,
|
|||
} while (window && window != aWindow);
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
AudioChannelService::TelephonyChannelIsActiveEnumerator(
|
||||
const uint64_t& aWindowID,
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
void* aPtr)
|
||||
{
|
||||
bool* isActive = static_cast<bool*>(aPtr);
|
||||
*isActive =
|
||||
aWinData->mChannels[(uint32_t)AudioChannel::Telephony].mNumberOfAgents != 0 &&
|
||||
!aWinData->mChannels[(uint32_t)AudioChannel::Telephony].mMuted;
|
||||
return *isActive ? PL_DHASH_STOP : PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
AudioChannelService::TelephonyChannelIsActiveInChildrenEnumerator(
|
||||
const uint64_t& aChildID,
|
||||
nsAutoPtr<AudioChannelChildStatus>& aData,
|
||||
void* aPtr)
|
||||
{
|
||||
bool* isActive = static_cast<bool*>(aPtr);
|
||||
*isActive = aData->mActiveTelephonyChannel;
|
||||
return *isActive ? PL_DHASH_STOP : PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelService::TelephonyChannelIsActive()
|
||||
{
|
||||
bool active = false;
|
||||
mWindows.Enumerate(TelephonyChannelIsActiveEnumerator, &active);
|
||||
|
||||
if (!active && IsParentProcess()) {
|
||||
mPlayingChildren.Enumerate(TelephonyChannelIsActiveInChildrenEnumerator,
|
||||
&active);
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelWindow>>::ForwardIterator iter(mWindows);
|
||||
while (iter.HasMore()) {
|
||||
AudioChannelWindow* next = iter.GetNext();
|
||||
if (next->mChannels[(uint32_t)AudioChannel::Telephony].mNumberOfAgents != 0 &&
|
||||
!next->mChannels[(uint32_t)AudioChannel::Telephony].mMuted) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
if (IsParentProcess()) {
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelChildStatus>>::ForwardIterator
|
||||
iter(mPlayingChildren);
|
||||
while (iter.HasMore()) {
|
||||
AudioChannelChildStatus* child = iter.GetNext();
|
||||
if (child->mActiveTelephonyChannel) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
AudioChannelService::ContentOrNormalChannelIsActiveEnumerator(
|
||||
const uint64_t& aWindowID,
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
void* aPtr)
|
||||
{
|
||||
bool* isActive = static_cast<bool*>(aPtr);
|
||||
*isActive =
|
||||
aWinData->mChannels[(uint32_t)AudioChannel::Content].mNumberOfAgents > 0 ||
|
||||
aWinData->mChannels[(uint32_t)AudioChannel::Normal].mNumberOfAgents > 0;
|
||||
return *isActive ? PL_DHASH_STOP : PL_DHASH_NEXT;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -363,51 +344,76 @@ AudioChannelService::ContentOrNormalChannelIsActive()
|
|||
// This method is meant to be used just by the child to send status update.
|
||||
MOZ_ASSERT(!IsParentProcess());
|
||||
|
||||
bool active = false;
|
||||
mWindows.Enumerate(ContentOrNormalChannelIsActiveEnumerator, &active);
|
||||
return active;
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelWindow>>::ForwardIterator iter(mWindows);
|
||||
while (iter.HasMore()) {
|
||||
AudioChannelWindow* next = iter.GetNext();
|
||||
if (next->mChannels[(uint32_t)AudioChannel::Content].mNumberOfAgents > 0 ||
|
||||
next->mChannels[(uint32_t)AudioChannel::Normal].mNumberOfAgents > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AudioChannelService::AudioChannelChildStatus*
|
||||
AudioChannelService::GetChildStatus(uint64_t aChildID) const
|
||||
{
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelChildStatus>>::ForwardIterator
|
||||
iter(mPlayingChildren);
|
||||
while (iter.HasMore()) {
|
||||
AudioChannelChildStatus* child = iter.GetNext();
|
||||
if (child->mChildID == aChildID) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
AudioChannelService::RemoveChildStatus(uint64_t aChildID)
|
||||
{
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelChildStatus>>::ForwardIterator
|
||||
iter(mPlayingChildren);
|
||||
while (iter.HasMore()) {
|
||||
nsAutoPtr<AudioChannelChildStatus>& child = iter.GetNext();
|
||||
if (child->mChildID == aChildID) {
|
||||
mPlayingChildren.RemoveElement(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelService::ProcessContentOrNormalChannelIsActive(uint64_t aChildID)
|
||||
{
|
||||
AudioChannelChildStatus* status = mPlayingChildren.Get(aChildID);
|
||||
if (!status) {
|
||||
AudioChannelChildStatus* child = GetChildStatus(aChildID);
|
||||
if (!child) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return status->mActiveContentOrNormalChannel;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
AudioChannelService::AnyAudioChannelIsActiveEnumerator(
|
||||
const uint64_t& aWindowID,
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
void* aPtr)
|
||||
{
|
||||
bool* isActive = static_cast<bool*>(aPtr);
|
||||
for (uint32_t i = 0; kMozAudioChannelAttributeTable[i].tag; ++i) {
|
||||
if (aWinData->mChannels[kMozAudioChannelAttributeTable[i].value].mNumberOfAgents
|
||||
!= 0) {
|
||||
*isActive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return *isActive ? PL_DHASH_STOP : PL_DHASH_NEXT;
|
||||
return child->mActiveContentOrNormalChannel;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelService::AnyAudioChannelIsActive()
|
||||
{
|
||||
bool active = false;
|
||||
mWindows.Enumerate(AnyAudioChannelIsActiveEnumerator, &active);
|
||||
|
||||
if (!active && IsParentProcess()) {
|
||||
active = !!mPlayingChildren.Count();
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelWindow>>::ForwardIterator iter(mWindows);
|
||||
while (iter.HasMore()) {
|
||||
AudioChannelWindow* next = iter.GetNext();
|
||||
for (uint32_t i = 0; kMozAudioChannelAttributeTable[i].tag; ++i) {
|
||||
if (next->mChannels[kMozAudioChannelAttributeTable[i].value].mNumberOfAgents
|
||||
!= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return active;
|
||||
if (IsParentProcess()) {
|
||||
return !mPlayingChildren.IsEmpty();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -467,10 +473,27 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsAutoPtr<AudioChannelWindow> window;
|
||||
mWindows.RemoveAndForget(innerID, window);
|
||||
if (window) {
|
||||
window->mAgents.EnumerateRead(NotifyEnumerator, nullptr);
|
||||
nsAutoPtr<AudioChannelWindow> winData;
|
||||
{
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelWindow>>::ForwardIterator
|
||||
iter(mWindows);
|
||||
while (iter.HasMore()) {
|
||||
nsAutoPtr<AudioChannelWindow>& next = iter.GetNext();
|
||||
if (next->mWindowID == innerID) {
|
||||
uint32_t pos = mWindows.IndexOf(next);
|
||||
winData = next.forget();
|
||||
mWindows.RemoveElementAt(pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (winData) {
|
||||
nsTObserverArray<AudioChannelAgent*>::ForwardIterator
|
||||
iter(winData->mAgents);
|
||||
while (iter.HasMore()) {
|
||||
iter.GetNext()->WindowVolumeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
@ -500,7 +523,7 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
mDefChannelChildID = CONTENT_PROCESS_ID_UNKNOWN;
|
||||
}
|
||||
|
||||
mPlayingChildren.Remove(childID);
|
||||
RemoveChildStatus(childID);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -516,25 +539,21 @@ struct RefreshAgentsVolumeData
|
|||
nsTArray<nsRefPtr<AudioChannelAgent>> mAgents;
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
AudioChannelService::RefreshAgentsVolumeEnumerator(
|
||||
AudioChannelAgent* aAgent,
|
||||
AudioChannel* aUnused,
|
||||
void* aPtr)
|
||||
{
|
||||
MOZ_ASSERT(aAgent);
|
||||
aAgent->WindowVolumeChanged();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
void
|
||||
AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
AudioChannelWindow* winData = mWindows.Get(aWindow->WindowID());
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
AudioChannelWindow* winData = GetWindowData(aWindow->WindowID());
|
||||
if (!winData) {
|
||||
return;
|
||||
}
|
||||
|
||||
winData->mAgents.EnumerateRead(RefreshAgentsVolumeEnumerator, nullptr);
|
||||
nsTObserverArray<AudioChannelAgent*>::ForwardIterator
|
||||
iter(winData->mAgents);
|
||||
while (iter.HasMore()) {
|
||||
iter.GetNext()->WindowVolumeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ const nsAttrValue::EnumTable*
|
||||
|
@ -603,15 +622,35 @@ AudioChannelService::GetDefaultAudioChannelString(nsAString& aString)
|
|||
}
|
||||
}
|
||||
|
||||
AudioChannelService::AudioChannelWindow&
|
||||
AudioChannelService::AudioChannelWindow*
|
||||
AudioChannelService::GetOrCreateWindowData(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsOuterWindow());
|
||||
|
||||
AudioChannelWindow* winData = mWindows.LookupOrAdd(aWindow->WindowID());
|
||||
return *winData;
|
||||
AudioChannelWindow* winData = GetWindowData(aWindow->WindowID());
|
||||
if (!winData) {
|
||||
winData = new AudioChannelWindow(aWindow->WindowID());
|
||||
mWindows.AppendElement(winData);
|
||||
}
|
||||
|
||||
return winData;
|
||||
}
|
||||
|
||||
AudioChannelService::AudioChannelWindow*
|
||||
AudioChannelService::GetWindowData(uint64_t aWindowID) const
|
||||
{
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelWindow>>::ForwardIterator
|
||||
iter(mWindows);
|
||||
while (iter.HasMore()) {
|
||||
AudioChannelWindow* next = iter.GetNext();
|
||||
if (next->mWindowID == aWindowID) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
float
|
||||
|
@ -622,8 +661,8 @@ AudioChannelService::GetAudioChannelVolume(nsPIDOMWindow* aWindow,
|
|||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsOuterWindow());
|
||||
|
||||
AudioChannelWindow& winData = GetOrCreateWindowData(aWindow);
|
||||
return winData.mChannels[(uint32_t)aAudioChannel].mVolume;
|
||||
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
|
||||
return winData->mChannels[(uint32_t)aAudioChannel].mVolume;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -645,8 +684,8 @@ AudioChannelService::SetAudioChannelVolume(nsPIDOMWindow* aWindow,
|
|||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsOuterWindow());
|
||||
|
||||
AudioChannelWindow& winData = GetOrCreateWindowData(aWindow);
|
||||
winData.mChannels[(uint32_t)aAudioChannel].mVolume = aVolume;
|
||||
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
|
||||
winData->mChannels[(uint32_t)aAudioChannel].mVolume = aVolume;
|
||||
RefreshAgentsVolume(aWindow);
|
||||
}
|
||||
|
||||
|
@ -668,8 +707,8 @@ AudioChannelService::GetAudioChannelMuted(nsPIDOMWindow* aWindow,
|
|||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsOuterWindow());
|
||||
|
||||
AudioChannelWindow& winData = GetOrCreateWindowData(aWindow);
|
||||
return winData.mChannels[(uint32_t)aAudioChannel].mMuted;
|
||||
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
|
||||
return winData->mChannels[(uint32_t)aAudioChannel].mMuted;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -691,8 +730,8 @@ AudioChannelService::SetAudioChannelMuted(nsPIDOMWindow* aWindow,
|
|||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsOuterWindow());
|
||||
|
||||
AudioChannelWindow& winData = GetOrCreateWindowData(aWindow);
|
||||
winData.mChannels[(uint32_t)aAudioChannel].mMuted = aMuted;
|
||||
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
|
||||
winData->mChannels[(uint32_t)aAudioChannel].mMuted = aMuted;
|
||||
RefreshAgentsVolume(aWindow);
|
||||
}
|
||||
|
||||
|
@ -714,8 +753,8 @@ AudioChannelService::IsAudioChannelActive(nsPIDOMWindow* aWindow,
|
|||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsOuterWindow());
|
||||
|
||||
AudioChannelWindow& winData = GetOrCreateWindowData(aWindow);
|
||||
return !!winData.mChannels[(uint32_t)aAudioChannel].mNumberOfAgents;
|
||||
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
|
||||
return !!winData->mChannels[(uint32_t)aAudioChannel].mNumberOfAgents;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -822,11 +861,16 @@ AudioChannelService::ChildStatusReceived(uint64_t aChildID,
|
|||
bool aAnyChannel)
|
||||
{
|
||||
if (!aAnyChannel) {
|
||||
mPlayingChildren.Remove(aChildID);
|
||||
RemoveChildStatus(aChildID);
|
||||
return;
|
||||
}
|
||||
|
||||
AudioChannelChildStatus* data = mPlayingChildren.LookupOrAdd(aChildID);
|
||||
AudioChannelChildStatus* data = GetChildStatus(aChildID);
|
||||
if (!data) {
|
||||
data = new AudioChannelChildStatus(aChildID);
|
||||
mPlayingChildren.AppendElement(data);
|
||||
}
|
||||
|
||||
data->mActiveTelephonyChannel = aTelephonyChannel;
|
||||
data->mActiveContentOrNormalChannel = aContentOrNormalChannel;
|
||||
}
|
||||
|
@ -836,13 +880,3 @@ AudioChannelService::IsAudioChannelMutedByDefault()
|
|||
{
|
||||
return sAudioChannelMutedByDefault;
|
||||
}
|
||||
|
||||
/* static */ PLDHashOperator
|
||||
AudioChannelService::NotifyEnumerator(AudioChannelAgent* aAgent,
|
||||
AudioChannel* aAudioChannel,
|
||||
void* aUnused)
|
||||
{
|
||||
aAgent->WindowVolumeChanged();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
#include "nsIAudioChannelService.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "AudioChannelAgent.h"
|
||||
#include "nsAttrValue.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "mozilla/dom/AudioChannelBinding.h"
|
||||
|
||||
class nsIRunnable;
|
||||
|
@ -160,58 +160,45 @@ private:
|
|||
|
||||
struct AudioChannelWindow final
|
||||
{
|
||||
explicit AudioChannelWindow(uint64_t aWindowID)
|
||||
: mWindowID(aWindowID)
|
||||
{}
|
||||
|
||||
uint64_t mWindowID;
|
||||
AudioChannelConfig mChannels[NUMBER_OF_AUDIO_CHANNELS];
|
||||
nsClassHashtable<nsPtrHashKey<AudioChannelAgent>, AudioChannel> mAgents;
|
||||
|
||||
// Raw pointer because the AudioChannelAgent must unregister itself.
|
||||
nsTObserverArray<AudioChannelAgent*> mAgents;
|
||||
};
|
||||
|
||||
AudioChannelWindow&
|
||||
AudioChannelWindow*
|
||||
GetOrCreateWindowData(nsPIDOMWindow* aWindow);
|
||||
|
||||
static PLDHashOperator
|
||||
TelephonyChannelIsActiveEnumerator(const uint64_t& aWindowID,
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
void *aPtr);
|
||||
AudioChannelWindow*
|
||||
GetWindowData(uint64_t aWindowID) const;
|
||||
|
||||
static PLDHashOperator
|
||||
ContentOrNormalChannelIsActiveEnumerator(
|
||||
const uint64_t& aWindowID,
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
void *aPtr);
|
||||
|
||||
static PLDHashOperator
|
||||
AnyAudioChannelIsActiveEnumerator(const uint64_t& aWindowID,
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
void *aPtr);
|
||||
|
||||
static PLDHashOperator
|
||||
RefreshAgentsVolumeEnumerator(AudioChannelAgent* aAgent,
|
||||
AudioChannel* aUnused,
|
||||
void *aPtr);
|
||||
|
||||
static PLDHashOperator
|
||||
NotifyEnumerator(AudioChannelAgent* aAgent,
|
||||
AudioChannel* aAudioChannel,
|
||||
void* aUnused);
|
||||
|
||||
nsClassHashtable<nsUint64HashKey, AudioChannelWindow> mWindows;
|
||||
|
||||
struct AudioChannelChildStatus final {
|
||||
AudioChannelChildStatus()
|
||||
: mActiveTelephonyChannel(false)
|
||||
struct AudioChannelChildStatus final
|
||||
{
|
||||
explicit AudioChannelChildStatus(uint64_t aChildID)
|
||||
: mChildID(aChildID)
|
||||
, mActiveTelephonyChannel(false)
|
||||
, mActiveContentOrNormalChannel(false)
|
||||
{}
|
||||
|
||||
uint64_t mChildID;
|
||||
bool mActiveTelephonyChannel;
|
||||
bool mActiveContentOrNormalChannel;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
TelephonyChannelIsActiveInChildrenEnumerator(
|
||||
const uint64_t& aChildID,
|
||||
nsAutoPtr<AudioChannelChildStatus>& aData,
|
||||
void *aPtr);
|
||||
AudioChannelChildStatus*
|
||||
GetChildStatus(uint64_t aChildID) const;
|
||||
|
||||
nsClassHashtable<nsUint64HashKey, AudioChannelChildStatus> mPlayingChildren;
|
||||
void
|
||||
RemoveChildStatus(uint64_t aChildID);
|
||||
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelWindow>> mWindows;
|
||||
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelChildStatus>> mPlayingChildren;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsTArray<SpeakerManagerService*> mSpeakerManager;
|
||||
|
|
|
@ -29,7 +29,7 @@ interface nsIAudioChannelAgentCallback : nsISupports
|
|||
* 1. Changes to the playable status of this channel.
|
||||
*/
|
||||
|
||||
[uuid(363ff8d3-5bd2-485a-84ac-125062cbdc19)]
|
||||
[uuid(11138a74-ee64-4a91-9457-f60a5f4527c1)]
|
||||
interface nsIAudioChannelAgent : nsISupports
|
||||
{
|
||||
const long AUDIO_AGENT_CHANNEL_NORMAL = 0;
|
||||
|
@ -51,6 +51,13 @@ interface nsIAudioChannelAgent : nsISupports
|
|||
*/
|
||||
readonly attribute long audioChannelType;
|
||||
|
||||
%{C++
|
||||
inline int32_t AudioChannelType() {
|
||||
int32_t channel;
|
||||
return NS_SUCCEEDED(GetAudioChannelType(&channel)) ? channel : AUDIO_AGENT_CHANNEL_ERROR;
|
||||
}
|
||||
%}
|
||||
|
||||
/**
|
||||
* Initialize the agent with a channel type.
|
||||
* Note: This function should only be called once.
|
||||
|
|
|
@ -220,6 +220,8 @@ var interfaceNamesInGlobalScope =
|
|||
permission: ["bluetooth"]},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "BoxObject", xbl: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "BrowserElementAudioChannel", b2g: true, permission: ["browser"] },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"BroadcastChannel",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
Загрузка…
Ссылка в новой задаче