Bug 1162663 - Convert nsHashtable to nsObserverTArray in AudioChannelService. r=alwu, r=ehsan, a=jocheng

This commit is contained in:
Andrea Marchesini 2015-06-03 03:32:00 -04:00
parent 76faa21e39
commit 1237709a28
4 changed files with 104 additions and 139 deletions

View File

@ -62,7 +62,6 @@ AudioChannelService::GetAudioChannelService()
} }
return gAudioChannelService; return gAudioChannelService;
} }
// static // static
@ -136,11 +135,12 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
return; return;
} }
AudioChannelAgentData* data = new AudioChannelAgentData(aChannel, AudioChannelAgentData* data =
true /* aElementHidden */, new AudioChannelAgentData(aAgent, aChannel,
AUDIO_CHANNEL_STATE_MUTED /* aState */, true /* aElementHidden */,
aWithVideo); AUDIO_CHANNEL_STATE_MUTED /* aState */,
mAgents.Put(aAgent, data); aWithVideo);
mAgents.AppendElement(data);
RegisterType(aChannel, CONTENT_PROCESS_ID_MAIN, aWithVideo); RegisterType(aChannel, CONTENT_PROCESS_ID_MAIN, aWithVideo);
// If this is the first agent for this window, we must notify the observers. // If this is the first agent for this window, we must notify the observers.
@ -219,7 +219,16 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
} }
nsAutoPtr<AudioChannelAgentData> data; nsAutoPtr<AudioChannelAgentData> data;
mAgents.RemoveAndForget(aAgent, data); nsTObserverArray<nsAutoPtr<AudioChannelAgentData>>::ForwardIterator iter(mAgents);
while (iter.HasMore()) {
nsAutoPtr<AudioChannelAgentData>& pData = iter.GetNext();
if (pData->mAgent == aAgent) {
uint32_t pos = mAgents.IndexOf(pData);
data = pData.forget();
mAgents.RemoveElementAt(pos);
break;
}
}
if (data) { if (data) {
UnregisterType(data->mChannel, data->mElementHidden, UnregisterType(data->mChannel, data->mElementHidden,
@ -349,17 +358,18 @@ AudioChannelService::UpdateChannelType(AudioChannel aChannel,
AudioChannelState AudioChannelState
AudioChannelService::GetState(AudioChannelAgent* aAgent, bool aElementHidden) AudioChannelService::GetState(AudioChannelAgent* aAgent, bool aElementHidden)
{ {
AudioChannelAgentData* data; AudioChannelAgentData* agentData = Find(aAgent);
if (!mAgents.Get(aAgent, &data)) { if (!agentData) {
return AUDIO_CHANNEL_STATE_MUTED; return AUDIO_CHANNEL_STATE_MUTED;
} }
bool oldElementHidden = data->mElementHidden; bool oldElementHidden = agentData->mElementHidden;
// Update visibility. // Update visibility.
data->mElementHidden = aElementHidden; agentData->mElementHidden = aElementHidden;
data->mState = GetStateInternal(data->mChannel, CONTENT_PROCESS_ID_MAIN, agentData->mState = GetStateInternal(agentData->mChannel,
aElementHidden, oldElementHidden); CONTENT_PROCESS_ID_MAIN,
aElementHidden, oldElementHidden);
#ifdef MOZ_WIDGET_GONK #ifdef MOZ_WIDGET_GONK
/** Only modify the speaker status when /** Only modify the speaker status when
* (1) apps in the foreground. * (1) apps in the foreground.
@ -376,7 +386,7 @@ AudioChannelService::GetState(AudioChannelAgent* aAgent, bool aElementHidden)
} }
#endif #endif
return data->mState; return agentData->mState;
} }
AudioChannelState AudioChannelState
@ -670,15 +680,6 @@ AudioChannelService::SendAudioChannelChangedNotification(uint64_t aChildID)
} }
} }
PLDHashOperator
AudioChannelService::NotifyEnumerator(AudioChannelAgent* aAgent,
AudioChannelAgentData* aData, void* aUnused)
{
MOZ_ASSERT(aAgent);
aAgent->NotifyAudioChannelStateChanged();
return PL_DHASH_NEXT;
}
class NotifyRunnable : public nsRunnable class NotifyRunnable : public nsRunnable
{ {
public: public:
@ -716,7 +717,11 @@ AudioChannelService::Notify()
mRunnable = nullptr; mRunnable = nullptr;
// Notify any agent for the main process. // Notify any agent for the main process.
mAgents.EnumerateRead(NotifyEnumerator, nullptr); nsTObserverArray<nsAutoPtr<AudioChannelAgentData>>::ForwardIterator iter(mAgents);
while (iter.HasMore()) {
AudioChannelAgentData* data = iter.GetNext();
data->mAgent->NotifyAudioChannelStateChanged();
}
// Notify for the child processes. // Notify for the child processes.
nsTArray<ContentParent*> children; nsTArray<ContentParent*> children;
@ -766,28 +771,6 @@ AudioChannelService::ChannelsActiveWithHigherPriorityThan(
return false; return false;
} }
PLDHashOperator
AudioChannelService::WindowDestroyedEnumerator(AudioChannelAgent* aAgent,
nsAutoPtr<AudioChannelAgentData>& aData,
void* aPtr)
{
uint64_t* innerID = static_cast<uint64_t*>(aPtr);
MOZ_ASSERT(innerID);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aAgent->Window());
if (!window || window->WindowID() != *innerID) {
return PL_DHASH_NEXT;
}
AudioChannelService* service = AudioChannelService::GetAudioChannelService();
MOZ_ASSERT(service);
service->UnregisterType(aData->mChannel, aData->mElementHidden,
CONTENT_PROCESS_ID_MAIN, aData->mWithVideo);
return PL_DHASH_REMOVE;
}
NS_IMETHODIMP NS_IMETHODIMP
AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
{ {
@ -889,7 +872,28 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic, const ch
return rv; return rv;
} }
mAgents.Enumerate(WindowDestroyedEnumerator, &innerID); nsTArray<nsRefPtr<AudioChannelAgent>> agents;
nsTObserverArray<nsAutoPtr<AudioChannelAgentData>>::ForwardIterator iter(mAgents);
while (iter.HasMore()) {
AudioChannelAgentData* data = iter.GetNext();
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(data->mAgent->Window());
if (window && !window->IsInnerWindow()) {
window = window->GetCurrentInnerWindow();
}
if (!window || window->WindowID() != innerID) {
continue;
}
UnregisterType(data->mChannel, data->mElementHidden,
CONTENT_PROCESS_ID_MAIN, data->mWithVideo);
agents.AppendElement(data->mAgent);
}
for (uint32_t i = 0, len = agents.Length(); i < len; ++i) {
agents[i]->NotifyAudioChannelStateChanged();
}
#ifdef MOZ_WIDGET_GONK #ifdef MOZ_WIDGET_GONK
bool active = AnyAudioChannelIsActive(); bool active = AnyAudioChannelIsActive();
@ -949,79 +953,37 @@ AudioChannelService::GetInternalType(AudioChannel aChannel,
MOZ_CRASH("unexpected audio channel"); MOZ_CRASH("unexpected audio channel");
} }
struct RefreshAgentsVolumeData
{
explicit RefreshAgentsVolumeData(nsPIDOMWindow* aWindow)
: mWindow(aWindow)
{}
nsPIDOMWindow* mWindow;
nsTArray<nsRefPtr<AudioChannelAgent>> mAgents;
};
PLDHashOperator
AudioChannelService::RefreshAgentsVolumeEnumerator(AudioChannelAgent* aAgent,
AudioChannelAgentData* aUnused,
void* aPtr)
{
MOZ_ASSERT(aAgent);
RefreshAgentsVolumeData* data = static_cast<RefreshAgentsVolumeData*>(aPtr);
MOZ_ASSERT(data);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aAgent->Window());
if (window && !window->IsInnerWindow()) {
window = window->GetCurrentInnerWindow();
}
if (window == data->mWindow) {
data->mAgents.AppendElement(aAgent);
}
return PL_DHASH_NEXT;
}
void void
AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow) AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow)
{ {
RefreshAgentsVolumeData data(aWindow); nsTObserverArray<nsAutoPtr<AudioChannelAgentData>>::ForwardIterator iter(mAgents);
mAgents.EnumerateRead(RefreshAgentsVolumeEnumerator, &data); while (iter.HasMore()) {
AudioChannelAgentData* data = iter.GetNext();
for (uint32_t i = 0; i < data.mAgents.Length(); ++i) { nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(data->mAgent->Window());
data.mAgents[i]->WindowVolumeChanged(); if (window && !window->IsInnerWindow()) {
window = window->GetCurrentInnerWindow();
}
if (window == aWindow) {
data->mAgent->WindowVolumeChanged();
}
} }
} }
struct CountWindowData
{
explicit CountWindowData(nsIDOMWindow* aWindow)
: mWindow(aWindow)
, mCount(0)
{}
nsIDOMWindow* mWindow;
uint32_t mCount;
};
PLDHashOperator
AudioChannelService::CountWindowEnumerator(AudioChannelAgent* aAgent,
AudioChannelAgentData* aUnused,
void* aPtr)
{
CountWindowData* data = static_cast<CountWindowData*>(aPtr);
MOZ_ASSERT(aAgent);
if (aAgent->Window() == data->mWindow) {
++data->mCount;
}
return PL_DHASH_NEXT;
}
uint32_t uint32_t
AudioChannelService::CountWindow(nsIDOMWindow* aWindow) AudioChannelService::CountWindow(nsIDOMWindow* aWindow)
{ {
CountWindowData data(aWindow); uint32_t count = 0;
mAgents.EnumerateRead(CountWindowEnumerator, &data); nsTObserverArray<nsAutoPtr<AudioChannelAgentData>>::ForwardIterator iter(mAgents);
return data.mCount; while (iter.HasMore()) {
AudioChannelAgentData* data = iter.GetNext();
if (data->mAgent->Window() == aWindow) {
++count;
}
}
return count;
} }
/* static */ const nsAttrValue::EnumTable* /* static */ const nsAttrValue::EnumTable*
@ -1125,3 +1087,17 @@ AudioChannelService::UnregisterTelephonyChild(uint64_t aChildID)
MOZ_ASSERT(false, "This should not happen."); MOZ_ASSERT(false, "This should not happen.");
} }
AudioChannelService::AudioChannelAgentData*
AudioChannelService::Find(AudioChannelAgent* aAgent)
{
nsTObserverArray<nsAutoPtr<AudioChannelAgentData>>::ForwardIterator iter(mAgents);
while (iter.HasMore()) {
AudioChannelAgentData* data = iter.GetNext();
if (data->mAgent == aAgent) {
return data;
}
}
return nullptr;
}

View File

@ -15,7 +15,7 @@
#include "AudioChannelCommon.h" #include "AudioChannelCommon.h"
#include "AudioChannelAgent.h" #include "AudioChannelAgent.h"
#include "nsAttrValue.h" #include "nsAttrValue.h"
#include "nsClassHashtable.h" #include "nsTObserverArray.h"
#include "mozilla/dom/AudioChannelBinding.h" #include "mozilla/dom/AudioChannelBinding.h"
class nsIRunnable; class nsIRunnable;
@ -189,47 +189,37 @@ protected:
AudioChannelInternalType GetInternalType(AudioChannel aChannel, AudioChannelInternalType GetInternalType(AudioChannel aChannel,
bool aElementHidden); bool aElementHidden);
class AudioChannelAgentData { class AudioChannelAgentData
{
public: public:
AudioChannelAgentData(AudioChannel aChannel, AudioChannelAgentData(AudioChannelAgent* aAgent,
AudioChannel aChannel,
bool aElementHidden, bool aElementHidden,
AudioChannelState aState, AudioChannelState aState,
bool aWithVideo) bool aWithVideo)
: mChannel(aChannel) : mAgent(aAgent)
, mChannel(aChannel)
, mElementHidden(aElementHidden) , mElementHidden(aElementHidden)
, mState(aState) , mState(aState)
, mWithVideo(aWithVideo) , mWithVideo(aWithVideo)
{} {
MOZ_ASSERT(mAgent);
}
nsRefPtr<AudioChannelAgent> mAgent;
AudioChannel mChannel; AudioChannel mChannel;
bool mElementHidden; bool mElementHidden;
AudioChannelState mState; AudioChannelState mState;
const bool mWithVideo; const bool mWithVideo;
}; };
static PLDHashOperator AudioChannelAgentData* Find(AudioChannelAgent* aAgent);
NotifyEnumerator(AudioChannelAgent* aAgent,
AudioChannelAgentData* aData, void *aUnused);
static PLDHashOperator
RefreshAgentsVolumeEnumerator(AudioChannelAgent* aAgent,
AudioChannelAgentData* aUnused,
void *aPtr);
static PLDHashOperator
CountWindowEnumerator(AudioChannelAgent* aAgent,
AudioChannelAgentData* aUnused,
void *aPtr);
static PLDHashOperator
WindowDestroyedEnumerator(AudioChannelAgent* aAgent,
nsAutoPtr<AudioChannelAgentData>& aData,
void *aPtr);
// This returns the number of agents from this aWindow. // This returns the number of agents from this aWindow.
uint32_t CountWindow(nsIDOMWindow* aWindow); uint32_t CountWindow(nsIDOMWindow* aWindow);
nsClassHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelAgentData > mAgents; nsTObserverArray<nsAutoPtr<AudioChannelAgentData>> mAgents;
#ifdef MOZ_WIDGET_GONK #ifdef MOZ_WIDGET_GONK
nsTArray<SpeakerManagerService*> mSpeakerManager; nsTArray<SpeakerManagerService*> mSpeakerManager;
#endif #endif

View File

@ -74,8 +74,8 @@ AudioChannelServiceChild::~AudioChannelServiceChild()
AudioChannelState AudioChannelState
AudioChannelServiceChild::GetState(AudioChannelAgent* aAgent, bool aElementHidden) AudioChannelServiceChild::GetState(AudioChannelAgent* aAgent, bool aElementHidden)
{ {
AudioChannelAgentData* data; AudioChannelAgentData* data = Find(aAgent);
if (!mAgents.Get(aAgent, &data)) { if (!data) {
return AUDIO_CHANNEL_STATE_MUTED; return AUDIO_CHANNEL_STATE_MUTED;
} }
@ -131,8 +131,8 @@ AudioChannelServiceChild::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
void void
AudioChannelServiceChild::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent) AudioChannelServiceChild::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
{ {
AudioChannelAgentData *pData; AudioChannelAgentData* pData = Find(aAgent);
if (!mAgents.Get(aAgent, &pData)) { if (!pData) {
return; return;
} }

View File

@ -59,4 +59,3 @@ protected:
} // namespace mozilla } // namespace mozilla
#endif #endif