From 2b56b58946078cc647b669b379f2ca0aa892f01d Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Sat, 11 Jul 2015 14:13:50 +0200 Subject: [PATCH] Backed out changeset d9cc17209f0e (bug 1113086) --- dom/audiochannel/AudioChannelAgent.cpp | 4 - dom/audiochannel/AudioChannelAgent.h | 2 +- dom/audiochannel/AudioChannelService.cpp | 300 ++++++++---------- dom/audiochannel/AudioChannelService.h | 65 ++-- dom/audiochannel/nsIAudioChannelAgent.idl | 9 +- .../mochitest/general/test_interfaces.html | 2 - 6 files changed, 174 insertions(+), 208 deletions(-) diff --git a/dom/audiochannel/AudioChannelAgent.cpp b/dom/audiochannel/AudioChannelAgent.cpp index e5a4f919105..31b3146de12 100644 --- a/dom/audiochannel/AudioChannelAgent.cpp +++ b/dom/audiochannel/AudioChannelAgent.cpp @@ -91,10 +91,6 @@ AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType, MOZ_ASSERT(topWindow); mWindow = do_QueryInterface(topWindow); - if (!mWindow) { - return NS_ERROR_FAILURE; - } - mWindow = mWindow->GetOuterWindow(); } diff --git a/dom/audiochannel/AudioChannelAgent.h b/dom/audiochannel/AudioChannelAgent.h index 3033ed44f83..ed70c7e3b22 100644 --- a/dom/audiochannel/AudioChannelAgent.h +++ b/dom/audiochannel/AudioChannelAgent.h @@ -64,5 +64,5 @@ private: } // namespace dom } // namespace mozilla - #endif + diff --git a/dom/audiochannel/AudioChannelService.cpp b/dom/audiochannel/AudioChannelService.cpp index ae5681ad5bb..30fa3268523 100644 --- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -190,14 +190,12 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent, } uint64_t windowID = aAgent->WindowID(); - AudioChannelWindow* winData = GetWindowData(windowID); - if (!winData) { - winData = new AudioChannelWindow(windowID); - mWindows.AppendElement(winData); - } + AudioChannelWindow* winData = mWindows.LookupOrAdd(windowID); - MOZ_ASSERT(!winData->mAgents.Contains(aAgent)); - winData->mAgents.AppendElement(aAgent); + MOZ_ASSERT(!winData->mAgents.Get(aAgent)); + + AudioChannel* audioChannel = new AudioChannel(aChannel); + winData->mAgents.Put(aAgent, audioChannel); ++winData->mChannels[(uint32_t)aChannel].mNumberOfAgents; @@ -207,7 +205,7 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent, } // If this is the first agent for this window, we must notify the observers. - if (winData->mAgents.Length() == 1) { + if (winData->mAgents.Count() == 1) { nsCOMPtr observerService = services::GetObserverService(); if (observerService) { @@ -227,25 +225,22 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent) return; } - AudioChannelWindow* winData = GetWindowData(aAgent->WindowID()); - if (!winData) { + uint64_t windowID = aAgent->WindowID(); + AudioChannelWindow* winData = nullptr; + if (!mWindows.Get(windowID, &winData)) { return; } - if (winData->mAgents.Contains(aAgent)) { - int32_t channel = aAgent->AudioChannelType(); - uint64_t windowID = aAgent->WindowID(); + nsAutoPtr audioChannel; + winData->mAgents.RemoveAndForget(aAgent, audioChannel); + if (audioChannel) { + MOZ_ASSERT(winData->mChannels[(uint32_t)*audioChannel].mNumberOfAgents > 0); - // aAgent can be freed after this call. - winData->mAgents.RemoveElement(aAgent); - - MOZ_ASSERT(winData->mChannels[channel].mNumberOfAgents > 0); - - --winData->mChannels[channel].mNumberOfAgents; + --winData->mChannels[(uint32_t)*audioChannel].mNumberOfAgents; // The last one, we must inform the BrowserElementAudioChannel. - if (winData->mChannels[channel].mNumberOfAgents == 0) { - NotifyChannelActive(windowID, static_cast(channel), false); + if (winData->mChannels[(uint32_t)*audioChannel].mNumberOfAgents == 0) { + NotifyChannelActive(aAgent->WindowID(), *audioChannel, false); } } @@ -257,7 +252,7 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent) #endif // If this is the last agent for this window, we must notify the observers. - if (winData->mAgents.IsEmpty()) { + if (winData->mAgents.Count() == 0) { nsCOMPtr observerService = services::GetObserverService(); if (observerService) { @@ -291,8 +286,7 @@ 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 { - winData = GetWindowData(window->WindowID()); - if (winData) { + if (mWindows.Get(window->WindowID(), &winData)) { *aVolume *= winData->mChannels[aAudioChannel].mVolume; *aMuted = *aMuted || winData->mChannels[aAudioChannel].mMuted; } @@ -312,30 +306,55 @@ AudioChannelService::GetState(nsPIDOMWindow* aWindow, uint32_t aAudioChannel, } while (window && window != aWindow); } +PLDHashOperator +AudioChannelService::TelephonyChannelIsActiveEnumerator( + const uint64_t& aWindowID, + nsAutoPtr& aWinData, + void* aPtr) +{ + bool* isActive = static_cast(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& aData, + void* aPtr) +{ + bool* isActive = static_cast(aPtr); + *isActive = aData->mActiveTelephonyChannel; + return *isActive ? PL_DHASH_STOP : PL_DHASH_NEXT; +} + bool AudioChannelService::TelephonyChannelIsActive() { - nsTObserverArray>::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; - } + bool active = false; + mWindows.Enumerate(TelephonyChannelIsActiveEnumerator, &active); + + if (!active && IsParentProcess()) { + mPlayingChildren.Enumerate(TelephonyChannelIsActiveInChildrenEnumerator, + &active); } - if (IsParentProcess()) { - nsTObserverArray>::ForwardIterator - iter(mPlayingChildren); - while (iter.HasMore()) { - AudioChannelChildStatus* child = iter.GetNext(); - if (child->mActiveTelephonyChannel) { - return true; - } - } - } + return active; +} - return false; +PLDHashOperator +AudioChannelService::ContentOrNormalChannelIsActiveEnumerator( + const uint64_t& aWindowID, + nsAutoPtr& aWinData, + void* aPtr) +{ + bool* isActive = static_cast(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; } bool @@ -344,76 +363,51 @@ AudioChannelService::ContentOrNormalChannelIsActive() // This method is meant to be used just by the child to send status update. MOZ_ASSERT(!IsParentProcess()); - nsTObserverArray>::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>::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>::ForwardIterator - iter(mPlayingChildren); - while (iter.HasMore()) { - nsAutoPtr& child = iter.GetNext(); - if (child->mChildID == aChildID) { - mPlayingChildren.RemoveElement(child); - break; - } - } + bool active = false; + mWindows.Enumerate(ContentOrNormalChannelIsActiveEnumerator, &active); + return active; } bool AudioChannelService::ProcessContentOrNormalChannelIsActive(uint64_t aChildID) { - AudioChannelChildStatus* child = GetChildStatus(aChildID); - if (!child) { + AudioChannelChildStatus* status = mPlayingChildren.Get(aChildID); + if (!status) { return false; } - return child->mActiveContentOrNormalChannel; + return status->mActiveContentOrNormalChannel; +} + +PLDHashOperator +AudioChannelService::AnyAudioChannelIsActiveEnumerator( + const uint64_t& aWindowID, + nsAutoPtr& aWinData, + void* aPtr) +{ + bool* isActive = static_cast(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; } bool AudioChannelService::AnyAudioChannelIsActive() { - nsTObserverArray>::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; - } - } + bool active = false; + mWindows.Enumerate(AnyAudioChannelIsActiveEnumerator, &active); + + if (!active && IsParentProcess()) { + active = !!mPlayingChildren.Count(); } - if (IsParentProcess()) { - return !mPlayingChildren.IsEmpty(); - } - - return false; + return active; } NS_IMETHODIMP @@ -473,27 +467,10 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic, return rv; } - nsAutoPtr winData; - { - nsTObserverArray>::ForwardIterator - iter(mWindows); - while (iter.HasMore()) { - nsAutoPtr& next = iter.GetNext(); - if (next->mWindowID == innerID) { - uint32_t pos = mWindows.IndexOf(next); - winData = next.forget(); - mWindows.RemoveElementAt(pos); - break; - } - } - } - - if (winData) { - nsTObserverArray::ForwardIterator - iter(winData->mAgents); - while (iter.HasMore()) { - iter.GetNext()->WindowVolumeChanged(); - } + nsAutoPtr window; + mWindows.RemoveAndForget(innerID, window); + if (window) { + window->mAgents.EnumerateRead(NotifyEnumerator, nullptr); } #ifdef MOZ_WIDGET_GONK @@ -523,7 +500,7 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic, mDefChannelChildID = CONTENT_PROCESS_ID_UNKNOWN; } - RemoveChildStatus(childID); + mPlayingChildren.Remove(childID); } return NS_OK; @@ -539,21 +516,25 @@ struct RefreshAgentsVolumeData nsTArray> mAgents; }; +PLDHashOperator +AudioChannelService::RefreshAgentsVolumeEnumerator( + AudioChannelAgent* aAgent, + AudioChannel* aUnused, + void* aPtr) +{ + MOZ_ASSERT(aAgent); + aAgent->WindowVolumeChanged(); + return PL_DHASH_NEXT; +} void AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow) { - MOZ_ASSERT(aWindow); - - AudioChannelWindow* winData = GetWindowData(aWindow->WindowID()); + AudioChannelWindow* winData = mWindows.Get(aWindow->WindowID()); if (!winData) { return; } - nsTObserverArray::ForwardIterator - iter(winData->mAgents); - while (iter.HasMore()) { - iter.GetNext()->WindowVolumeChanged(); - } + winData->mAgents.EnumerateRead(RefreshAgentsVolumeEnumerator, nullptr); } /* static */ const nsAttrValue::EnumTable* @@ -622,35 +603,15 @@ 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 = GetWindowData(aWindow->WindowID()); - if (!winData) { - winData = new AudioChannelWindow(aWindow->WindowID()); - mWindows.AppendElement(winData); - } - - return winData; -} - -AudioChannelService::AudioChannelWindow* -AudioChannelService::GetWindowData(uint64_t aWindowID) const -{ - nsTObserverArray>::ForwardIterator - iter(mWindows); - while (iter.HasMore()) { - AudioChannelWindow* next = iter.GetNext(); - if (next->mWindowID == aWindowID) { - return next; - } - } - - return nullptr; + AudioChannelWindow* winData = mWindows.LookupOrAdd(aWindow->WindowID()); + return *winData; } float @@ -661,8 +622,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 @@ -684,8 +645,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); } @@ -707,8 +668,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 @@ -730,8 +691,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); } @@ -753,8 +714,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 @@ -861,16 +822,11 @@ AudioChannelService::ChildStatusReceived(uint64_t aChildID, bool aAnyChannel) { if (!aAnyChannel) { - RemoveChildStatus(aChildID); + mPlayingChildren.Remove(aChildID); return; } - AudioChannelChildStatus* data = GetChildStatus(aChildID); - if (!data) { - data = new AudioChannelChildStatus(aChildID); - mPlayingChildren.AppendElement(data); - } - + AudioChannelChildStatus* data = mPlayingChildren.LookupOrAdd(aChildID); data->mActiveTelephonyChannel = aTelephonyChannel; data->mActiveContentOrNormalChannel = aContentOrNormalChannel; } @@ -880,3 +836,13 @@ AudioChannelService::IsAudioChannelMutedByDefault() { return sAudioChannelMutedByDefault; } + +/* static */ PLDHashOperator +AudioChannelService::NotifyEnumerator(AudioChannelAgent* aAgent, + AudioChannel* aAudioChannel, + void* aUnused) +{ + aAgent->WindowVolumeChanged(); + return PL_DHASH_NEXT; +} + diff --git a/dom/audiochannel/AudioChannelService.h b/dom/audiochannel/AudioChannelService.h index 65f312d236b..1c8345fe162 100644 --- a/dom/audiochannel/AudioChannelService.h +++ b/dom/audiochannel/AudioChannelService.h @@ -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,45 +160,58 @@ private: struct AudioChannelWindow final { - explicit AudioChannelWindow(uint64_t aWindowID) - : mWindowID(aWindowID) - {} - - uint64_t mWindowID; AudioChannelConfig mChannels[NUMBER_OF_AUDIO_CHANNELS]; - - // Raw pointer because the AudioChannelAgent must unregister itself. - nsTObserverArray mAgents; + nsClassHashtable, AudioChannel> mAgents; }; - AudioChannelWindow* + AudioChannelWindow& GetOrCreateWindowData(nsPIDOMWindow* aWindow); - AudioChannelWindow* - GetWindowData(uint64_t aWindowID) const; + static PLDHashOperator + TelephonyChannelIsActiveEnumerator(const uint64_t& aWindowID, + nsAutoPtr& aWinData, + void *aPtr); - struct AudioChannelChildStatus final - { - explicit AudioChannelChildStatus(uint64_t aChildID) - : mChildID(aChildID) - , mActiveTelephonyChannel(false) + static PLDHashOperator + ContentOrNormalChannelIsActiveEnumerator( + const uint64_t& aWindowID, + nsAutoPtr& aWinData, + void *aPtr); + + static PLDHashOperator + AnyAudioChannelIsActiveEnumerator(const uint64_t& aWindowID, + nsAutoPtr& aWinData, + void *aPtr); + + static PLDHashOperator + RefreshAgentsVolumeEnumerator(AudioChannelAgent* aAgent, + AudioChannel* aUnused, + void *aPtr); + + static PLDHashOperator + NotifyEnumerator(AudioChannelAgent* aAgent, + AudioChannel* aAudioChannel, + void* aUnused); + + nsClassHashtable mWindows; + + struct AudioChannelChildStatus final { + AudioChannelChildStatus() + : mActiveTelephonyChannel(false) , mActiveContentOrNormalChannel(false) {} - uint64_t mChildID; bool mActiveTelephonyChannel; bool mActiveContentOrNormalChannel; }; - AudioChannelChildStatus* - GetChildStatus(uint64_t aChildID) const; + static PLDHashOperator + TelephonyChannelIsActiveInChildrenEnumerator( + const uint64_t& aChildID, + nsAutoPtr& aData, + void *aPtr); - void - RemoveChildStatus(uint64_t aChildID); - - nsTObserverArray> mWindows; - - nsTObserverArray> mPlayingChildren; + nsClassHashtable mPlayingChildren; #ifdef MOZ_WIDGET_GONK nsTArray mSpeakerManager; diff --git a/dom/audiochannel/nsIAudioChannelAgent.idl b/dom/audiochannel/nsIAudioChannelAgent.idl index 599c3e28722..8febf962fbd 100644 --- a/dom/audiochannel/nsIAudioChannelAgent.idl +++ b/dom/audiochannel/nsIAudioChannelAgent.idl @@ -29,7 +29,7 @@ interface nsIAudioChannelAgentCallback : nsISupports * 1. Changes to the playable status of this channel. */ -[uuid(11138a74-ee64-4a91-9457-f60a5f4527c1)] +[uuid(363ff8d3-5bd2-485a-84ac-125062cbdc19)] interface nsIAudioChannelAgent : nsISupports { const long AUDIO_AGENT_CHANNEL_NORMAL = 0; @@ -51,13 +51,6 @@ 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. diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 77dcd4a945f..9bb1b36445e 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -220,8 +220,6 @@ 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!