mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1113086 - AudioChannel policy in Browser API - patch 2 - IPC communication between AudioChannelServices, r=ehsan
This commit is contained in:
parent
16db4ace47
commit
8361c16bda
@ -85,6 +85,12 @@ GetTopWindow(nsIDOMWindow* aWindow)
|
||||
return window.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
IsParentProcess()
|
||||
{
|
||||
return XRE_GetProcessType() == GeckoProcessType_Default;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
StaticRefPtr<AudioChannelService> gAudioChannelService;
|
||||
@ -118,7 +124,7 @@ void
|
||||
AudioChannelService::Shutdown()
|
||||
{
|
||||
if (gAudioChannelService) {
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
if (IsParentProcess()) {
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(gAudioChannelService, "ipc:content-shutdown");
|
||||
@ -147,8 +153,11 @@ NS_IMPL_RELEASE(AudioChannelService)
|
||||
AudioChannelService::AudioChannelService()
|
||||
: mDisabled(false)
|
||||
, mDefChannelChildID(CONTENT_PROCESS_ID_UNKNOWN)
|
||||
, mTelephonyChannel(false)
|
||||
, mContentOrNormalChannel(false)
|
||||
, mAnyChannel(false)
|
||||
{
|
||||
if (XRE_IsParentProcess()) {
|
||||
if (IsParentProcess()) {
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(this, "ipc:content-shutdown", false);
|
||||
@ -199,6 +208,8 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
|
||||
NS_LITERAL_STRING("active").get());
|
||||
}
|
||||
}
|
||||
|
||||
MaybeSendStatusUpdate();
|
||||
}
|
||||
|
||||
void
|
||||
@ -244,6 +255,8 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
|
||||
NS_LITERAL_STRING("inactive").get());
|
||||
}
|
||||
}
|
||||
|
||||
MaybeSendStatusUpdate();
|
||||
}
|
||||
|
||||
void
|
||||
@ -296,33 +309,68 @@ AudioChannelService::TelephonyChannelIsActiveEnumerator(
|
||||
bool* isActive = static_cast<bool*>(aPtr);
|
||||
*isActive =
|
||||
aWinData->mChannels[(uint32_t)AudioChannel::Telephony].mNumberOfAgents != 0 &&
|
||||
!aWinData->mChannels[(uint32_t)AudioChannel::Telephony].mMuted;
|
||||
!aWinData->mChannels[(uint32_t)AudioChannel::Telephony].mMuted;
|
||||
return *isActive ? PL_DHASH_STOP : PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
AudioChannelService::TelephonyChannelIsActiveInChildrenEnumerator(
|
||||
const uint64_t& aChildID,
|
||||
nsAutoPtr<AudioChannelChildStatus>& aData,
|
||||
void* aPtr)
|
||||
{
|
||||
bool* isActive = static_cast<bool*>(aPtr);
|
||||
*isActive = aData->mActiveTelephonyChannel;
|
||||
return *isActive ? PL_DHASH_STOP : PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelService::TelephonyChannelIsActive()
|
||||
{
|
||||
// TODO: no child process check.
|
||||
|
||||
bool active = false;
|
||||
mWindows.Enumerate(TelephonyChannelIsActiveEnumerator, &active);
|
||||
|
||||
if (!active && IsParentProcess()) {
|
||||
mPlayingChildren.Enumerate(TelephonyChannelIsActiveInChildrenEnumerator,
|
||||
&active);
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
AudioChannelService::ContentOrNormalChannelIsActiveEnumerator(
|
||||
const uint64_t& aWindowID,
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
void* aPtr)
|
||||
{
|
||||
bool* isActive = static_cast<bool*>(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
|
||||
AudioChannelService::ContentOrNormalChannelIsActive()
|
||||
{
|
||||
// This method is meant to be used just by the child to send status update.
|
||||
MOZ_ASSERT(!IsParentProcess());
|
||||
|
||||
bool active = false;
|
||||
mWindows.Enumerate(ContentOrNormalChannelIsActiveEnumerator, &active);
|
||||
return active;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelService::ProcessContentOrNormalChannelIsActive(uint64_t aChildID)
|
||||
{
|
||||
/* TODO
|
||||
AudioChannelChildData* data;
|
||||
if (!mData.Get(aChildID, &data)) {
|
||||
AudioChannelChildStatus* status = mPlayingChildren.Get(aChildID);
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return data->mChannels[(uint32_t)AudioChannel::Content].mNumberOfAgents != 0 ||
|
||||
data->mChannels[(uint32_t)AudioChannel::Normal].mNumberOfAgents != 0;
|
||||
*/
|
||||
return true;
|
||||
return status->mActiveContentOrNormalChannel;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
@ -346,9 +394,13 @@ AudioChannelService::AnyAudioChannelIsActiveEnumerator(
|
||||
bool
|
||||
AudioChannelService::AnyAudioChannelIsActive()
|
||||
{
|
||||
// TODO: no child process check.
|
||||
bool active = false;
|
||||
mWindows.Enumerate(AnyAudioChannelIsActiveEnumerator, &active);
|
||||
|
||||
if (!active && IsParentProcess()) {
|
||||
active = !!mPlayingChildren.Count();
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
@ -441,6 +493,8 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
SetDefaultVolumeControlChannelInternal(-1, false, childID);
|
||||
mDefChannelChildID = CONTENT_PROCESS_ID_UNKNOWN;
|
||||
}
|
||||
|
||||
mPlayingChildren.Remove(childID);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -680,7 +734,7 @@ AudioChannelService::SetDefaultVolumeControlChannelInternal(int32_t aChannel,
|
||||
bool aVisible,
|
||||
uint64_t aChildID)
|
||||
{
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
if (!IsParentProcess()) {
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
if (cc) {
|
||||
cc->SendAudioChannelChangeDefVolChannel(aChannel, aVisible);
|
||||
@ -727,6 +781,50 @@ AudioChannelService::SetDefaultVolumeControlChannelInternal(int32_t aChannel,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioChannelService::MaybeSendStatusUpdate()
|
||||
{
|
||||
if (IsParentProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool telephonyChannel = TelephonyChannelIsActive();
|
||||
bool contentOrNormalChannel = ContentOrNormalChannelIsActive();
|
||||
bool anyChannel = AnyAudioChannelIsActive();
|
||||
|
||||
if (telephonyChannel == mTelephonyChannel &&
|
||||
contentOrNormalChannel == mContentOrNormalChannel &&
|
||||
anyChannel == mAnyChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTelephonyChannel = telephonyChannel;
|
||||
mContentOrNormalChannel = contentOrNormalChannel;
|
||||
mAnyChannel = anyChannel;
|
||||
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
if (cc) {
|
||||
cc->SendAudioChannelServiceStatus(telephonyChannel, contentOrNormalChannel,
|
||||
anyChannel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioChannelService::ChildStatusReceived(uint64_t aChildID,
|
||||
bool aTelephonyChannel,
|
||||
bool aContentOrNormalChannel,
|
||||
bool aAnyChannel)
|
||||
{
|
||||
if (!aAnyChannel) {
|
||||
mPlayingChildren.Remove(aChildID);
|
||||
return;
|
||||
}
|
||||
|
||||
AudioChannelChildStatus* data = mPlayingChildren.LookupOrAdd(aChildID);
|
||||
data->mActiveTelephonyChannel = aTelephonyChannel;
|
||||
data->mActiveContentOrNormalChannel = aContentOrNormalChannel;
|
||||
}
|
||||
|
||||
/* static */ PLDHashOperator
|
||||
AudioChannelService::NotifyEnumerator(AudioChannelAgent* aAgent,
|
||||
AudioChannel* aAudioChannel,
|
||||
|
@ -127,10 +127,17 @@ public:
|
||||
|
||||
void Notify(uint64_t aWindowID);
|
||||
|
||||
void ChildStatusReceived(uint64_t aChildID, bool aTelephonyChannel,
|
||||
bool aContentOrNormalChannel, bool aAnyChannel);
|
||||
|
||||
private:
|
||||
AudioChannelService();
|
||||
~AudioChannelService();
|
||||
|
||||
void MaybeSendStatusUpdate();
|
||||
|
||||
bool ContentOrNormalChannelIsActive();
|
||||
|
||||
/* Send the default-volume-channel-changed notification */
|
||||
void SetDefaultVolumeControlChannelInternal(int32_t aChannel,
|
||||
bool aVisible, uint64_t aChildID);
|
||||
@ -163,6 +170,12 @@ private:
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
void *aPtr);
|
||||
|
||||
static PLDHashOperator
|
||||
ContentOrNormalChannelIsActiveEnumerator(
|
||||
const uint64_t& aWindowID,
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
void *aPtr);
|
||||
|
||||
static PLDHashOperator
|
||||
AnyAudioChannelIsActiveEnumerator(const uint64_t& aWindowID,
|
||||
nsAutoPtr<AudioChannelWindow>& aWinData,
|
||||
@ -180,6 +193,24 @@ private:
|
||||
|
||||
nsClassHashtable<nsUint64HashKey, AudioChannelWindow> mWindows;
|
||||
|
||||
struct AudioChannelChildStatus final {
|
||||
AudioChannelChildStatus()
|
||||
: mActiveTelephonyChannel(false)
|
||||
, mActiveContentOrNormalChannel(false)
|
||||
{}
|
||||
|
||||
bool mActiveTelephonyChannel;
|
||||
bool mActiveContentOrNormalChannel;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
TelephonyChannelIsActiveInChildrenEnumerator(
|
||||
const uint64_t& aChildID,
|
||||
nsAutoPtr<AudioChannelChildStatus>& aData,
|
||||
void *aPtr);
|
||||
|
||||
nsClassHashtable<nsUint64HashKey, AudioChannelChildStatus> mPlayingChildren;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsTArray<SpeakerManagerService*> mSpeakerManager;
|
||||
#endif
|
||||
@ -190,6 +221,12 @@ private:
|
||||
|
||||
uint64_t mDefChannelChildID;
|
||||
|
||||
// These boolean are used to know if we have to send an status update to the
|
||||
// service running in the main process.
|
||||
bool mTelephonyChannel;
|
||||
bool mContentOrNormalChannel;
|
||||
bool mAnyChannel;
|
||||
|
||||
// This is needed for IPC comunication between
|
||||
// AudioChannelServiceChild and this class.
|
||||
friend class ContentParent;
|
||||
|
@ -2802,6 +2802,20 @@ ContentParent::RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvAudioChannelServiceStatus(
|
||||
const bool& aTelephonyChannel,
|
||||
const bool& aContentOrNormalChannel,
|
||||
const bool& aAnyChannel)
|
||||
{
|
||||
nsRefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
|
||||
MOZ_ASSERT(service);
|
||||
|
||||
service->ChildStatusReceived(mChildID, aTelephonyChannel,
|
||||
aContentOrNormalChannel, aAnyChannel);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvDataStoreGetStores(
|
||||
const nsString& aName,
|
||||
|
@ -754,6 +754,11 @@ private:
|
||||
|
||||
virtual bool RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
|
||||
const bool& aHidden) override;
|
||||
|
||||
virtual bool RecvAudioChannelServiceStatus(const bool& aTelephonyChannel,
|
||||
const bool& aContentOrNormalChannel,
|
||||
const bool& aAnyChannel) override;
|
||||
|
||||
virtual bool RecvGetSystemMemory(const uint64_t& getterId) override;
|
||||
|
||||
virtual bool RecvGetLookAndFeelCache(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override;
|
||||
|
@ -863,6 +863,10 @@ parent:
|
||||
// Tell the parent that the child has gone idle for the first time
|
||||
async FirstIdle();
|
||||
|
||||
async AudioChannelServiceStatus(bool aActiveTelephonyChannel,
|
||||
bool aContentOrNormalChannel,
|
||||
bool aAnyActiveChannel);
|
||||
|
||||
async AudioChannelChangeDefVolChannel(int32_t aChannel, bool aHidden);
|
||||
|
||||
sync DataStoreGetStores(nsString aName, nsString aOwner, Principal aPrincipal)
|
||||
|
Loading…
Reference in New Issue
Block a user