forked from Floorp-Projects/Floorp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug 805333 part 1 - AudioChannelService, r=kinetik, a=blocking-basecamp
- Loading branch information
Showing
6 changed files
with
282 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ | ||
/* vim: set ts=2 et sw=2 tw=80: */ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
* You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
#include "AudioChannelService.h" | ||
|
||
#include "base/basictypes.h" | ||
|
||
#include "mozilla/Services.h" | ||
#include "mozilla/StaticPtr.h" | ||
#include "mozilla/unused.h" | ||
#include "mozilla/Util.h" | ||
|
||
#include "mozilla/dom/ContentParent.h" | ||
|
||
#include "base/basictypes.h" | ||
|
||
#include "nsThreadUtils.h" | ||
|
||
using namespace mozilla; | ||
using namespace mozilla::dom; | ||
|
||
StaticRefPtr<AudioChannelService> gAudioChannelService; | ||
|
||
// static | ||
AudioChannelService* | ||
AudioChannelService::GetAudioChannelService() | ||
{ | ||
MOZ_ASSERT(NS_IsMainThread()); | ||
|
||
// If we already exist, exit early | ||
if (gAudioChannelService) { | ||
return gAudioChannelService; | ||
} | ||
|
||
// Create new instance, register, return | ||
nsRefPtr<AudioChannelService> service = new AudioChannelService(); | ||
NS_ENSURE_TRUE(service, nullptr); | ||
|
||
gAudioChannelService = service; | ||
return gAudioChannelService; | ||
} | ||
|
||
void | ||
AudioChannelService::Shutdown() | ||
{ | ||
if (gAudioChannelService) { | ||
delete gAudioChannelService; | ||
gAudioChannelService = nullptr; | ||
} | ||
} | ||
|
||
NS_IMPL_ISUPPORTS0(AudioChannelService) | ||
|
||
AudioChannelService::AudioChannelService() | ||
{ | ||
mChannelCounters = new int32_t[AUDIO_CHANNEL_PUBLICNOTIFICATION+1]; | ||
|
||
for (int i = AUDIO_CHANNEL_NORMAL; | ||
i <= AUDIO_CHANNEL_PUBLICNOTIFICATION; | ||
++i) { | ||
mChannelCounters[i] = 0; | ||
} | ||
|
||
// Creation of the hash table. | ||
mMediaElements.Init(); | ||
} | ||
|
||
AudioChannelService::~AudioChannelService() | ||
{ | ||
delete [] mChannelCounters; | ||
} | ||
|
||
void | ||
AudioChannelService::RegisterMediaElement(nsHTMLMediaElement* aMediaElement, | ||
AudioChannelType aType) | ||
{ | ||
mMediaElements.Put(aMediaElement, aType); | ||
mChannelCounters[aType]++; | ||
|
||
// In order to avoid race conditions, it's safer to notify any existing | ||
// media element any time a new one is registered. | ||
Notify(); | ||
} | ||
|
||
void | ||
AudioChannelService::UnregisterMediaElement(nsHTMLMediaElement* aMediaElement) | ||
{ | ||
AudioChannelType type; | ||
if (!mMediaElements.Get(aMediaElement, &type)) { | ||
return; | ||
} | ||
|
||
mMediaElements.Remove(aMediaElement); | ||
|
||
mChannelCounters[type]--; | ||
MOZ_ASSERT(mChannelCounters[type] >= 0); | ||
|
||
// In order to avoid race conditions, it's safer to notify any existing | ||
// media element any time a new one is registered. | ||
Notify(); | ||
} | ||
|
||
bool | ||
AudioChannelService::GetMuted(AudioChannelType aType, bool aElementHidden) | ||
{ | ||
// We are not visible, maybe we have to mute: | ||
if (aElementHidden) { | ||
switch (aType) { | ||
case AUDIO_CHANNEL_NORMAL: | ||
return true; | ||
|
||
case AUDIO_CHANNEL_CONTENT: | ||
// TODO: this should work per apps | ||
if (mChannelCounters[AUDIO_CHANNEL_CONTENT] > 1) | ||
return true; | ||
break; | ||
|
||
case AUDIO_CHANNEL_NOTIFICATION: | ||
case AUDIO_CHANNEL_ALARM: | ||
case AUDIO_CHANNEL_TELEPHONY: | ||
case AUDIO_CHANNEL_PUBLICNOTIFICATION: | ||
// Nothing to do | ||
break; | ||
} | ||
} | ||
|
||
// Priorities: | ||
switch (aType) { | ||
case AUDIO_CHANNEL_NORMAL: | ||
case AUDIO_CHANNEL_CONTENT: | ||
return !!mChannelCounters[AUDIO_CHANNEL_NOTIFICATION] || | ||
!!mChannelCounters[AUDIO_CHANNEL_ALARM] || | ||
!!mChannelCounters[AUDIO_CHANNEL_TELEPHONY] || | ||
!!mChannelCounters[AUDIO_CHANNEL_PUBLICNOTIFICATION]; | ||
|
||
case AUDIO_CHANNEL_NOTIFICATION: | ||
case AUDIO_CHANNEL_ALARM: | ||
case AUDIO_CHANNEL_TELEPHONY: | ||
return ChannelsActiveWithHigherPriorityThan(aType); | ||
|
||
case AUDIO_CHANNEL_PUBLICNOTIFICATION: | ||
return false; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
|
||
static PLDHashOperator | ||
NotifyEnumerator(nsHTMLMediaElement* aElement, | ||
AudioChannelType aType, void* aData) | ||
{ | ||
if (aElement) { | ||
// TODO: this part will be cover by a different patch. | ||
// aElement->NotifyAudioChannelStateChanged(); | ||
} | ||
return PL_DHASH_NEXT; | ||
} | ||
|
||
void | ||
AudioChannelService::Notify() | ||
{ | ||
MOZ_ASSERT(NS_IsMainThread()); | ||
|
||
// Notify any media element for the main process. | ||
mMediaElements.EnumerateRead(NotifyEnumerator, nullptr); | ||
} | ||
|
||
bool | ||
AudioChannelService::ChannelsActiveWithHigherPriorityThan(AudioChannelType aType) | ||
{ | ||
for (int i = AUDIO_CHANNEL_PUBLICNOTIFICATION; | ||
i != AUDIO_CHANNEL_CONTENT; --i) { | ||
if (i == aType) { | ||
return false; | ||
} | ||
|
||
if (mChannelCounters[i]) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ | ||
/* vim: set ts=2 et sw=2 tw=80: */ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
* You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
#ifndef mozilla_dom_audiochannelservice_h__ | ||
#define mozilla_dom_audiochannelservice_h__ | ||
|
||
#include "nsAutoPtr.h" | ||
#include "nsISupports.h" | ||
|
||
#include "AudioChannelCommon.h" | ||
#include "nsHTMLMediaElement.h" | ||
|
||
namespace mozilla { | ||
namespace dom { | ||
|
||
class AudioChannelService : public nsISupports | ||
{ | ||
public: | ||
NS_DECL_ISUPPORTS | ||
|
||
/** | ||
* Returns the AudioChannelServce singleton. Only to be called from main thread. | ||
* @return NS_OK on proper assignment, NS_ERROR_FAILURE otherwise. | ||
*/ | ||
static AudioChannelService* | ||
GetAudioChannelService(); | ||
|
||
/** | ||
* Shutdown the singleton. | ||
*/ | ||
static void Shutdown(); | ||
|
||
/** | ||
* Any MediaElement that starts playing should register itself to | ||
* this service, sharing the AudioChannelType. | ||
*/ | ||
void RegisterMediaElement(nsHTMLMediaElement* aMediaElement, | ||
AudioChannelType aType); | ||
|
||
/** | ||
* Any MediaElement that stops playing should unregister itself to | ||
* this service. | ||
*/ | ||
void UnregisterMediaElement(nsHTMLMediaElement* aMediaElement); | ||
|
||
/** | ||
* Return true if this type should be muted. | ||
*/ | ||
virtual bool GetMuted(AudioChannelType aType, bool aElementHidden); | ||
|
||
void Notify(); | ||
|
||
protected: | ||
AudioChannelService(); | ||
virtual ~AudioChannelService(); | ||
|
||
bool ChannelsActiveWithHigherPriorityThan(AudioChannelType aType); | ||
|
||
nsDataHashtable< nsPtrHashKey<nsHTMLMediaElement>, AudioChannelType > mMediaElements; | ||
|
||
int32_t* mChannelCounters; | ||
}; | ||
|
||
} // namespace dom | ||
} // namespace mozilla | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters