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;
}
// static
@ -136,11 +135,12 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
return;
}
AudioChannelAgentData* data = new AudioChannelAgentData(aChannel,
true /* aElementHidden */,
AUDIO_CHANNEL_STATE_MUTED /* aState */,
aWithVideo);
mAgents.Put(aAgent, data);
AudioChannelAgentData* data =
new AudioChannelAgentData(aAgent, aChannel,
true /* aElementHidden */,
AUDIO_CHANNEL_STATE_MUTED /* aState */,
aWithVideo);
mAgents.AppendElement(data);
RegisterType(aChannel, CONTENT_PROCESS_ID_MAIN, aWithVideo);
// 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;
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) {
UnregisterType(data->mChannel, data->mElementHidden,
@ -349,17 +358,18 @@ AudioChannelService::UpdateChannelType(AudioChannel aChannel,
AudioChannelState
AudioChannelService::GetState(AudioChannelAgent* aAgent, bool aElementHidden)
{
AudioChannelAgentData* data;
if (!mAgents.Get(aAgent, &data)) {
AudioChannelAgentData* agentData = Find(aAgent);
if (!agentData) {
return AUDIO_CHANNEL_STATE_MUTED;
}
bool oldElementHidden = data->mElementHidden;
bool oldElementHidden = agentData->mElementHidden;
// Update visibility.
data->mElementHidden = aElementHidden;
agentData->mElementHidden = aElementHidden;
data->mState = GetStateInternal(data->mChannel, CONTENT_PROCESS_ID_MAIN,
aElementHidden, oldElementHidden);
agentData->mState = GetStateInternal(agentData->mChannel,
CONTENT_PROCESS_ID_MAIN,
aElementHidden, oldElementHidden);
#ifdef MOZ_WIDGET_GONK
/** Only modify the speaker status when
* (1) apps in the foreground.
@ -376,7 +386,7 @@ AudioChannelService::GetState(AudioChannelAgent* aAgent, bool aElementHidden)
}
#endif
return data->mState;
return agentData->mState;
}
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
{
public:
@ -716,7 +717,11 @@ AudioChannelService::Notify()
mRunnable = nullptr;
// 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.
nsTArray<ContentParent*> children;
@ -766,28 +771,6 @@ AudioChannelService::ChannelsActiveWithHigherPriorityThan(
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
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;
}
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
bool active = AnyAudioChannelIsActive();
@ -949,79 +953,37 @@ AudioChannelService::GetInternalType(AudioChannel aChannel,
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
AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow)
{
RefreshAgentsVolumeData data(aWindow);
mAgents.EnumerateRead(RefreshAgentsVolumeEnumerator, &data);
nsTObserverArray<nsAutoPtr<AudioChannelAgentData>>::ForwardIterator iter(mAgents);
while (iter.HasMore()) {
AudioChannelAgentData* data = iter.GetNext();
for (uint32_t i = 0; i < data.mAgents.Length(); ++i) {
data.mAgents[i]->WindowVolumeChanged();
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(data->mAgent->Window());
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
AudioChannelService::CountWindow(nsIDOMWindow* aWindow)
{
CountWindowData data(aWindow);
mAgents.EnumerateRead(CountWindowEnumerator, &data);
return data.mCount;
uint32_t count = 0;
nsTObserverArray<nsAutoPtr<AudioChannelAgentData>>::ForwardIterator iter(mAgents);
while (iter.HasMore()) {
AudioChannelAgentData* data = iter.GetNext();
if (data->mAgent->Window() == aWindow) {
++count;
}
}
return count;
}
/* static */ const nsAttrValue::EnumTable*
@ -1125,3 +1087,17 @@ AudioChannelService::UnregisterTelephonyChild(uint64_t aChildID)
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 "AudioChannelAgent.h"
#include "nsAttrValue.h"
#include "nsClassHashtable.h"
#include "nsTObserverArray.h"
#include "mozilla/dom/AudioChannelBinding.h"
class nsIRunnable;
@ -189,47 +189,37 @@ protected:
AudioChannelInternalType GetInternalType(AudioChannel aChannel,
bool aElementHidden);
class AudioChannelAgentData {
class AudioChannelAgentData
{
public:
AudioChannelAgentData(AudioChannel aChannel,
AudioChannelAgentData(AudioChannelAgent* aAgent,
AudioChannel aChannel,
bool aElementHidden,
AudioChannelState aState,
bool aWithVideo)
: mChannel(aChannel)
: mAgent(aAgent)
, mChannel(aChannel)
, mElementHidden(aElementHidden)
, mState(aState)
, mWithVideo(aWithVideo)
{}
{
MOZ_ASSERT(mAgent);
}
nsRefPtr<AudioChannelAgent> mAgent;
AudioChannel mChannel;
bool mElementHidden;
AudioChannelState mState;
const bool mWithVideo;
};
static PLDHashOperator
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);
AudioChannelAgentData* Find(AudioChannelAgent* aAgent);
// This returns the number of agents from this aWindow.
uint32_t CountWindow(nsIDOMWindow* aWindow);
nsClassHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelAgentData > mAgents;
nsTObserverArray<nsAutoPtr<AudioChannelAgentData>> mAgents;
#ifdef MOZ_WIDGET_GONK
nsTArray<SpeakerManagerService*> mSpeakerManager;
#endif

View File

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

View File

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