author | Andrea Marchesini <amarchesini@mozilla.com> |
Wed, 09 Jan 2013 08:18:16 +0100 | |
changeset 128072 | b3110cc625529cda6db0df508545926929674ca9 |
parent 128071 | f77ccdb45a90188f922d48339b097a807fbd9998 |
child 128073 | 4961e3a15ed34aa8b9e76177725bc8c3f2d19c07 |
push id | 2323 |
push user | bbajaj@mozilla.com |
push date | Mon, 01 Apr 2013 19:47:02 +0000 |
treeherder | mozilla-beta@7712be144d91 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | sicking |
bugs | 825674 |
milestone | 21.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -969,25 +969,16 @@ window.addEventListener('ContentStart', Services.obs.addObserver(function(aSubject, aTopic, aData) { shell.sendChromeEvent({ type: 'audio-channel-changed', channel: aData }); }, "audio-channel-changed", false); })(); -(function audioChannelChangedTracker() { - Services.obs.addObserver(function(aSubject, aTopic, aData) { - shell.sendChromeEvent({ - type: 'audio-channel-changed', - channel: aData - }); -}, "audio-channel-changed", false); -})(); - (function recordingStatusTracker() { let gRecordingActiveCount = 0; Services.obs.addObserver(function(aSubject, aTopic, aData) { let oldCount = gRecordingActiveCount; if (aData == "starting") { gRecordingActiveCount += 1; } else if (aData == "shutdown") {
--- a/dom/audiochannel/AudioChannelAgent.cpp +++ b/dom/audiochannel/AudioChannelAgent.cpp @@ -67,17 +67,17 @@ NS_IMETHODIMP AudioChannelAgent::StartPl AudioChannelService *service = AudioChannelService::GetAudioChannelService(); if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR || service == nullptr) { return NS_ERROR_FAILURE; } service->RegisterAudioChannelAgent(this, static_cast<AudioChannelType>(mAudioChannelType)); - *_retval = !service->GetMuted(static_cast<AudioChannelType>(mAudioChannelType), !mVisible); + *_retval = !service->GetMuted(this, !mVisible); mIsRegToService = true; return NS_OK; } /* void stopPlaying (); */ NS_IMETHODIMP AudioChannelAgent::StopPlaying(void) { if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR || @@ -94,23 +94,21 @@ NS_IMETHODIMP AudioChannelAgent::StopPla /* void setVisibilityState (in boolean visible); */ NS_IMETHODIMP AudioChannelAgent::SetVisibilityState(bool visible) { bool oldVisibility = mVisible; mVisible = visible; if (mIsRegToService && oldVisibility != mVisible && mCallback != nullptr) { AudioChannelService *service = AudioChannelService::GetAudioChannelService(); - mCallback->CanPlayChanged(!service->GetMuted(static_cast<AudioChannelType>(mAudioChannelType), - !mVisible)); + mCallback->CanPlayChanged(!service->GetMuted(this, !mVisible)); } return NS_OK; } void AudioChannelAgent::NotifyAudioChannelStateChanged() { if (mCallback != nullptr) { AudioChannelService *service = AudioChannelService::GetAudioChannelService(); - mCallback->CanPlayChanged(!service->GetMuted(static_cast<AudioChannelType>(mAudioChannelType), - !mVisible)); + mCallback->CanPlayChanged(!service->GetMuted(this, !mVisible)); } }
--- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -61,17 +61,17 @@ AudioChannelService::Shutdown() if (gAudioChannelService) { gAudioChannelService = nullptr; } } NS_IMPL_ISUPPORTS0(AudioChannelService) AudioChannelService::AudioChannelService() -: mCurrentHigherChannel(AUDIO_CHANNEL_NORMAL) +: mCurrentHigherChannel(AUDIO_CHANNEL_LAST) { // Creation of the hash table. mAgents.Init(); if (XRE_GetProcessType() == GeckoProcessType_Default) { nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->AddObserver(this, "ipc:content-shutdown", false); @@ -82,181 +82,210 @@ AudioChannelService::AudioChannelService AudioChannelService::~AudioChannelService() { } void AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent, AudioChannelType aType) { - mAgents.Put(aAgent, aType); + AudioChannelAgentData data = { aType, + true /* mElementHidden */, + true /* mMuted */ }; + mAgents.Put(aAgent, data); RegisterType(aType, CONTENT_PARENT_UNKNOWN_CHILD_ID); } void AudioChannelService::RegisterType(AudioChannelType aType, uint64_t aChildID) { - mChannelCounters[aType].AppendElement(aChildID); + AudioChannelInternalType type = GetInternalType(aType, true); + mChannelCounters[type].AppendElement(aChildID); // In order to avoid race conditions, it's safer to notify any existing // agent any time a new one is registered. - Notify(); + if (XRE_GetProcessType() == GeckoProcessType_Default) { + SendAudioChannelChangedNotification(); + Notify(); + } } void AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent) { - AudioChannelType type; - if (!mAgents.Get(aAgent, &type)) { + AudioChannelAgentData data; + if (!mAgents.Get(aAgent, &data)) { return; } mAgents.Remove(aAgent); - UnregisterType(type, CONTENT_PARENT_UNKNOWN_CHILD_ID); + UnregisterType(data.mType, data.mElementHidden, CONTENT_PARENT_UNKNOWN_CHILD_ID); } void -AudioChannelService::UnregisterType(AudioChannelType aType, uint64_t aChildID) +AudioChannelService::UnregisterType(AudioChannelType aType, + bool aElementHidden, + uint64_t aChildID) { // The array may contain multiple occurrence of this appId but // this should remove only the first one. - mChannelCounters[aType].RemoveElement(aChildID); - - bool isNoChannelUsed = true; - for (int32_t type = AUDIO_CHANNEL_NORMAL; - type <= AUDIO_CHANNEL_PUBLICNOTIFICATION; - ++type) { - if (!mChannelCounters[type].IsEmpty()) { - isNoChannelUsed = false; - break; - } - } - - if (isNoChannelUsed) { - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); - obs->NotifyObservers(nullptr, "audio-channel-changed", NS_LITERAL_STRING("default").get()); - mCurrentHigherChannel = AUDIO_CHANNEL_NORMAL; - return; - } + AudioChannelInternalType type = GetInternalType(aType, aElementHidden); + mChannelCounters[type].RemoveElement(aChildID); // In order to avoid race conditions, it's safer to notify any existing // agent any time a new one is registered. - Notify(); + if (XRE_GetProcessType() == GeckoProcessType_Default) { + SendAudioChannelChangedNotification(); + Notify(); + } } bool -AudioChannelService::GetMuted(AudioChannelType aType, bool aElementHidden) +AudioChannelService::GetMuted(AudioChannelAgent* aAgent, bool aElementHidden) { - // We are not visible, maybe we have to mute: - if (aElementHidden) { - switch (aType) { - case AUDIO_CHANNEL_NORMAL: - return true; + AudioChannelAgentData data; + if (!mAgents.Get(aAgent, &data)) { + return true; + } + + bool muted = GetMutedInternal(data.mType, CONTENT_PARENT_UNKNOWN_CHILD_ID, + aElementHidden, data.mElementHidden); - case AUDIO_CHANNEL_CONTENT: - { - // If we have more than 1 using the content channel, - // this must be muted. - uint32_t childId = CONTENT_PARENT_UNKNOWN_CHILD_ID; - bool empty = true; - for (uint32_t i = 0; - i < mChannelCounters[AUDIO_CHANNEL_CONTENT].Length(); - ++i) { - if (empty) { - childId = mChannelCounters[AUDIO_CHANNEL_CONTENT][i]; - empty = false; - } - else if (childId != mChannelCounters[AUDIO_CHANNEL_CONTENT][i]) - return true; - } - break; - } + // Update visibility. + if (data.mElementHidden != aElementHidden || data.mMuted != muted) { + data.mElementHidden = aElementHidden; + data.mMuted = muted; + mAgents.Put(aAgent, data); + } + + SendAudioChannelChangedNotification(); + return muted; +} - case AUDIO_CHANNEL_NOTIFICATION: - case AUDIO_CHANNEL_ALARM: - case AUDIO_CHANNEL_TELEPHONY: - case AUDIO_CHANNEL_RINGER: - case AUDIO_CHANNEL_PUBLICNOTIFICATION: - // Nothing to do - break; +bool +AudioChannelService::GetMutedInternal(AudioChannelType aType, uint64_t aChildID, + bool aElementHidden, bool aElementWasHidden) +{ + // Calculating the new and old type and update the hashtable if needed. + AudioChannelInternalType newType = GetInternalType(aType, aElementHidden); + AudioChannelInternalType oldType = GetInternalType(aType, aElementWasHidden); - case AUDIO_CHANNEL_LAST: - MOZ_NOT_REACHED(); - return false; - } + if (newType != oldType) { + mChannelCounters[newType].AppendElement(aChildID); + mChannelCounters[oldType].RemoveElement(aChildID); } bool muted = false; - // Priorities: - switch (aType) { - case AUDIO_CHANNEL_NORMAL: - case AUDIO_CHANNEL_CONTENT: - muted = !mChannelCounters[AUDIO_CHANNEL_NOTIFICATION].IsEmpty() || - !mChannelCounters[AUDIO_CHANNEL_ALARM].IsEmpty() || - !mChannelCounters[AUDIO_CHANNEL_TELEPHONY].IsEmpty() || - !mChannelCounters[AUDIO_CHANNEL_RINGER].IsEmpty() || - !mChannelCounters[AUDIO_CHANNEL_PUBLICNOTIFICATION].IsEmpty(); - break; - - case AUDIO_CHANNEL_NOTIFICATION: - case AUDIO_CHANNEL_ALARM: - case AUDIO_CHANNEL_TELEPHONY: - case AUDIO_CHANNEL_RINGER: - muted = ChannelsActiveWithHigherPriorityThan(aType); - break; - - case AUDIO_CHANNEL_PUBLICNOTIFICATION: - break; - - case AUDIO_CHANNEL_LAST: - MOZ_NOT_REACHED(); - return false; + // We are not visible, maybe we have to mute. + if (newType == AUDIO_CHANNEL_INT_NORMAL_HIDDEN || + (newType == AUDIO_CHANNEL_INT_CONTENT_HIDDEN && + (!mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].IsEmpty() || + HasMoreThanOneContentChannelHidden()))) { + muted = true; } - // Notification if needed. if (!muted) { - - // Calculating the most important unmuted channel: - AudioChannelType higher = AUDIO_CHANNEL_NORMAL; - for (int32_t type = AUDIO_CHANNEL_NORMAL; - type <= AUDIO_CHANNEL_PUBLICNOTIFICATION; - ++type) { - if (!mChannelCounters[type].IsEmpty()) { - higher = (AudioChannelType)type; - } - } - - if (higher != mCurrentHigherChannel) { - mCurrentHigherChannel = higher; - - nsString channelName; - channelName.AssignASCII(ChannelName(mCurrentHigherChannel)); - - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); - obs->NotifyObservers(nullptr, "audio-channel-changed", channelName.get()); - } + MOZ_ASSERT(newType != AUDIO_CHANNEL_INT_NORMAL_HIDDEN); + muted = ChannelsActiveWithHigherPriorityThan(newType); } return muted; } bool AudioChannelService::ContentChannelIsActive() { - return mChannelCounters[AUDIO_CHANNEL_CONTENT].Length() > 0; + return !mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].IsEmpty() || + !mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN].IsEmpty(); +} + +bool +AudioChannelService::HasMoreThanOneContentChannelHidden() +{ + uint32_t childId = CONTENT_PARENT_UNKNOWN_CHILD_ID; + bool empty = true; + for (uint32_t i = 0; + i < mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN].Length(); + ++i) { + if (empty) { + childId = mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN][i]; + empty = false; + } else if (childId != mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN][i]) { + return true; + } + } + + return false; } -static PLDHashOperator -NotifyEnumerator(AudioChannelAgent* aAgent, - AudioChannelType aType, void* aData) +void +AudioChannelService::SendAudioChannelChangedNotification() { - if (aAgent) { - aAgent->NotifyAudioChannelStateChanged(); + if (XRE_GetProcessType() != GeckoProcessType_Default) { + return; + } + + // Calculating the most important active channel. + AudioChannelType higher = AUDIO_CHANNEL_LAST; + + // Top-Down in the hierarchy. + if (!mChannelCounters[AUDIO_CHANNEL_INT_PUBLICNOTIFICATION].IsEmpty()) { + higher = AUDIO_CHANNEL_PUBLICNOTIFICATION; + } + + else if (!mChannelCounters[AUDIO_CHANNEL_INT_RINGER].IsEmpty()) { + higher = AUDIO_CHANNEL_RINGER; + } + + else if (!mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY].IsEmpty()) { + higher = AUDIO_CHANNEL_TELEPHONY; + } + + else if (!mChannelCounters[AUDIO_CHANNEL_INT_ALARM].IsEmpty()) { + higher = AUDIO_CHANNEL_ALARM; + } + + else if (!mChannelCounters[AUDIO_CHANNEL_INT_NOTIFICATION].IsEmpty()) { + higher = AUDIO_CHANNEL_NOTIFICATION; } + + // Only 1 content channel hidden or a visible one. + else if ((!mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN].IsEmpty() && + !HasMoreThanOneContentChannelHidden()) || + !mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].IsEmpty()) { + higher = AUDIO_CHANNEL_CONTENT; + } + + // At least 1 visible normal channel. + else if (!mChannelCounters[AUDIO_CHANNEL_INT_NORMAL].IsEmpty()) { + higher = AUDIO_CHANNEL_NORMAL; + } + + if (higher != mCurrentHigherChannel) { + mCurrentHigherChannel = higher; + + nsString channelName; + if (mCurrentHigherChannel != AUDIO_CHANNEL_LAST) { + channelName.AssignASCII(ChannelName(mCurrentHigherChannel)); + } else { + channelName = NS_LITERAL_STRING("default"); + } + + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + obs->NotifyObservers(nullptr, "audio-channel-changed", channelName.get()); + } +} + +PLDHashOperator +AudioChannelService::NotifyEnumerator(AudioChannelAgent* aAgent, + AudioChannelAgentData aData, void* aUnused) +{ + MOZ_ASSERT(aAgent); + aAgent->NotifyAudioChannelStateChanged(); return PL_DHASH_NEXT; } void AudioChannelService::Notify() { MOZ_ASSERT(NS_IsMainThread()); @@ -267,20 +296,20 @@ AudioChannelService::Notify() nsTArray<ContentParent*> children; ContentParent::GetAll(children); for (uint32_t i = 0; i < children.Length(); i++) { unused << children[i]->SendAudioChannelNotify(); } } bool -AudioChannelService::ChannelsActiveWithHigherPriorityThan(AudioChannelType aType) +AudioChannelService::ChannelsActiveWithHigherPriorityThan(AudioChannelInternalType aType) { - for (int i = AUDIO_CHANNEL_PUBLICNOTIFICATION; - i != AUDIO_CHANNEL_CONTENT; --i) { + for (int i = AUDIO_CHANNEL_INT_PUBLICNOTIFICATION; + i != AUDIO_CHANNEL_INT_CONTENT_HIDDEN; --i) { if (i == aType) { return false; } if (!mChannelCounters[i].IsEmpty()) { return true; } } @@ -326,27 +355,65 @@ AudioChannelService::Observe(nsISupports NS_WARNING("ipc:content-shutdown message without property bag as subject"); return NS_OK; } uint64_t childID = 0; nsresult rv = props->GetPropertyAsUint64(NS_LITERAL_STRING("childID"), &childID); if (NS_SUCCEEDED(rv)) { - for (int32_t type = AUDIO_CHANNEL_NORMAL; - type <= AUDIO_CHANNEL_PUBLICNOTIFICATION; + for (int32_t type = AUDIO_CHANNEL_INT_NORMAL; + type < AUDIO_CHANNEL_INT_LAST; ++type) { int32_t index; while ((index = mChannelCounters[type].IndexOf(childID)) != -1) { mChannelCounters[type].RemoveElementAt(index); } } // We don't have to remove the agents from the mAgents hashtable because if // that table contains only agents running on the same process. + SendAudioChannelChangedNotification(); Notify(); } else { NS_WARNING("ipc:content-shutdown message without childID property"); } return NS_OK; } + +AudioChannelService::AudioChannelInternalType +AudioChannelService::GetInternalType(AudioChannelType aType, + bool aElementHidden) +{ + switch (aType) { + case AUDIO_CHANNEL_NORMAL: + return aElementHidden + ? AUDIO_CHANNEL_INT_NORMAL_HIDDEN : AUDIO_CHANNEL_INT_NORMAL; + + case AUDIO_CHANNEL_CONTENT: + return aElementHidden + ? AUDIO_CHANNEL_INT_CONTENT_HIDDEN : AUDIO_CHANNEL_INT_CONTENT; + + case AUDIO_CHANNEL_NOTIFICATION: + return AUDIO_CHANNEL_INT_NOTIFICATION; + + case AUDIO_CHANNEL_ALARM: + return AUDIO_CHANNEL_INT_ALARM; + + case AUDIO_CHANNEL_TELEPHONY: + return AUDIO_CHANNEL_INT_TELEPHONY; + + case AUDIO_CHANNEL_RINGER: + return AUDIO_CHANNEL_INT_RINGER; + + case AUDIO_CHANNEL_PUBLICNOTIFICATION: + return AUDIO_CHANNEL_INT_PUBLICNOTIFICATION; + + case AUDIO_CHANNEL_LAST: + default: + break; + } + + MOZ_NOT_REACHED(); + return AUDIO_CHANNEL_INT_LAST; +}
--- a/dom/audiochannel/AudioChannelService.h +++ b/dom/audiochannel/AudioChannelService.h @@ -46,41 +46,78 @@ public: * Any audio channel agent that stops playing should unregister itself to * this service. */ virtual void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent); /** * Return true if this type should be muted. */ - virtual bool GetMuted(AudioChannelType aType, bool aElementHidden); + virtual bool GetMuted(AudioChannelAgent* aAgent, bool aElementHidden); /** * Return true if there is a content channel active in this process * or one of its subprocesses. */ virtual bool ContentChannelIsActive(); protected: void Notify(); + /** + * Send the audio-channel-changed notification if needed. + */ + void SendAudioChannelChangedNotification(); + /* Register/Unregister IPC types: */ void RegisterType(AudioChannelType aType, uint64_t aChildID); - void UnregisterType(AudioChannelType aType, uint64_t aChildID); + void UnregisterType(AudioChannelType aType, bool aElementHidden, + uint64_t aChildID); + + bool GetMutedInternal(AudioChannelType aType, uint64_t aChildID, + bool aElementHidden, bool aElementWasHidden); AudioChannelService(); virtual ~AudioChannelService(); - bool ChannelsActiveWithHigherPriorityThan(AudioChannelType aType); + enum AudioChannelInternalType { + AUDIO_CHANNEL_INT_NORMAL = 0, + AUDIO_CHANNEL_INT_NORMAL_HIDDEN, + AUDIO_CHANNEL_INT_CONTENT, + AUDIO_CHANNEL_INT_CONTENT_HIDDEN, + AUDIO_CHANNEL_INT_NOTIFICATION, + AUDIO_CHANNEL_INT_ALARM, + AUDIO_CHANNEL_INT_TELEPHONY, + AUDIO_CHANNEL_INT_RINGER, + AUDIO_CHANNEL_INT_PUBLICNOTIFICATION, + AUDIO_CHANNEL_INT_LAST + }; + + bool ChannelsActiveWithHigherPriorityThan(AudioChannelInternalType aType); + + bool HasMoreThanOneContentChannelHidden(); const char* ChannelName(AudioChannelType aType); - nsDataHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelType > mAgents; + AudioChannelInternalType GetInternalType(AudioChannelType aType, + bool aElementHidden); - nsTArray<uint64_t> mChannelCounters[AUDIO_CHANNEL_PUBLICNOTIFICATION+1]; + struct AudioChannelAgentData { + AudioChannelType mType; + bool mElementHidden; + bool mMuted; + }; + + static PLDHashOperator + NotifyEnumerator(AudioChannelAgent* aAgent, + AudioChannelAgentData aData, void *aUnused); + + nsDataHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelAgentData > mAgents; + + nsTArray<uint64_t> mChannelCounters[AUDIO_CHANNEL_INT_LAST]; AudioChannelType mCurrentHigherChannel; // This is needed for IPC comunication between // AudioChannelServiceChild and this class. friend class ContentParent; friend class ContentChild; };
--- a/dom/audiochannel/AudioChannelServiceChild.cpp +++ b/dom/audiochannel/AudioChannelServiceChild.cpp @@ -52,23 +52,39 @@ AudioChannelServiceChild::AudioChannelSe { } AudioChannelServiceChild::~AudioChannelServiceChild() { } bool -AudioChannelServiceChild::GetMuted(AudioChannelType aType, bool aMozHidden) +AudioChannelServiceChild::GetMuted(AudioChannelAgent* aAgent, bool aElementHidden) { + AudioChannelAgentData data; + if (!mAgents.Get(aAgent, &data)) { + return true; + } + ContentChild *cc = ContentChild::GetSingleton(); - bool muted = false; + bool muted = true; if (cc) { - cc->SendAudioChannelGetMuted(aType, aMozHidden, &muted); + cc->SendAudioChannelGetMuted(data.mType, aElementHidden, data.mElementHidden, &muted); + } + + // Update visibility. + if (data.mElementHidden != aElementHidden || data.mMuted != muted) { + data.mElementHidden = aElementHidden; + data.mMuted = muted; + mAgents.Put(aAgent, data); + } + + if (cc) { + cc->SendAudioChannelChangedNotification(); } return muted; } void AudioChannelServiceChild::RegisterAudioChannelAgent(AudioChannelAgent* aAgent, AudioChannelType aType) @@ -84,25 +100,25 @@ AudioChannelServiceChild::RegisterAudioC if (obs) { obs->NotifyObservers(nullptr, "audio-channel-agent-changed", nullptr); } } void AudioChannelServiceChild::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent) { - AudioChannelType type; - if (!mAgents.Get(aAgent, &type)) { + AudioChannelAgentData data; + if (!mAgents.Get(aAgent, &data)) { return; } AudioChannelService::UnregisterAudioChannelAgent(aAgent); ContentChild *cc = ContentChild::GetSingleton(); if (cc) { - cc->SendAudioChannelUnregisterType(type); + cc->SendAudioChannelUnregisterType(data.mType, data.mElementHidden); } nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->NotifyObservers(nullptr, "audio-channel-agent-changed", nullptr); } }
--- a/dom/audiochannel/AudioChannelServiceChild.h +++ b/dom/audiochannel/AudioChannelServiceChild.h @@ -31,17 +31,17 @@ public: virtual void RegisterAudioChannelAgent(AudioChannelAgent* aAgent, AudioChannelType aType); virtual void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent); /** * Return true if this type + this mozHidden should be muted. */ - virtual bool GetMuted(AudioChannelType aType, bool aMozHidden); + virtual bool GetMuted(AudioChannelAgent* aAgent, bool aMozHidden); protected: AudioChannelServiceChild(); virtual ~AudioChannelServiceChild(); }; } // namespace dom } // namespace mozilla
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1094,46 +1094,60 @@ ContentParent::RecvFirstIdle() // prelaunch any sooner than this, then we'll be competing with the // child process and slowing it down. ScheduleDelayedPreallocateAppProcess(); return true; } bool ContentParent::RecvAudioChannelGetMuted(const AudioChannelType& aType, - const bool& aMozHidden, + const bool& aElementHidden, + const bool& aElementWasHidden, bool* aValue) { nsRefPtr<AudioChannelService> service = AudioChannelService::GetAudioChannelService(); *aValue = false; if (service) { - *aValue = service->GetMuted(aType, aMozHidden); + *aValue = service->GetMutedInternal(aType, mChildID, + aElementHidden, aElementWasHidden); } return true; } bool ContentParent::RecvAudioChannelRegisterType(const AudioChannelType& aType) { nsRefPtr<AudioChannelService> service = AudioChannelService::GetAudioChannelService(); if (service) { service->RegisterType(aType, mChildID); } return true; } bool -ContentParent::RecvAudioChannelUnregisterType(const AudioChannelType& aType) +ContentParent::RecvAudioChannelUnregisterType(const AudioChannelType& aType, + const bool& aElementHidden) { nsRefPtr<AudioChannelService> service = AudioChannelService::GetAudioChannelService(); if (service) { - service->UnregisterType(aType, mChildID); + service->UnregisterType(aType, aElementHidden, mChildID); + } + return true; +} + +bool +ContentParent::RecvAudioChannelChangedNotification() +{ + nsRefPtr<AudioChannelService> service = + AudioChannelService::GetAudioChannelService(); + if (service) { + service->SendAudioChannelChangedNotification(); } return true; } NS_IMPL_THREADSAFE_ISUPPORTS3(ContentParent, nsIObserver, nsIThreadObserver, nsIDOMGeoPositionCallback)
--- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -315,21 +315,25 @@ private: const uint32_t& aFlags, const nsCString& aCategory); virtual bool RecvPrivateDocShellsExist(const bool& aExist); virtual bool RecvFirstIdle(); virtual bool RecvAudioChannelGetMuted(const AudioChannelType& aType, - const bool& aMozHidden, + const bool& aElementHidden, + const bool& aElementWasHidden, bool* aValue); virtual bool RecvAudioChannelRegisterType(const AudioChannelType& aType); - virtual bool RecvAudioChannelUnregisterType(const AudioChannelType& aType); + virtual bool RecvAudioChannelUnregisterType(const AudioChannelType& aType, + const bool& aElementHidden); + + virtual bool RecvAudioChannelChangedNotification(); virtual void ProcessingError(Result what) MOZ_OVERRIDE; GeckoChildProcessHost* mSubprocess; ChildOSPrivileges mOSPrivileges; uint64_t mChildID; int32_t mGeolocationWatchID;
--- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -428,20 +428,24 @@ parent: // Notify the parent of the presence or absence of private docshells PrivateDocShellsExist(bool aExist); // Tell the parent that the child has gone idle for the first time async FirstIdle(); // Get Muted from the main AudioChannelService. - sync AudioChannelGetMuted(AudioChannelType aType, bool aMozHidden) + sync AudioChannelGetMuted(AudioChannelType aType, bool aElementHidden, + bool aElementWasHidden) returns (bool value); - async AudioChannelRegisterType(AudioChannelType aType); - async AudioChannelUnregisterType(AudioChannelType aType); + sync AudioChannelRegisterType(AudioChannelType aType); + sync AudioChannelUnregisterType(AudioChannelType aType, + bool aElementHidden); + + async AudioChannelChangedNotification(); both: AsyncMessage(nsString aMessage, ClonedMessageData aData); }; } }