Bug 1214148 - patch 2 - from toplevel iframe to the nested iframe, r=alwu

This commit is contained in:
Andrea Marchesini 2015-12-11 11:17:33 -05:00
Родитель 7271d1d622
Коммит 4f57cd1c8f
7 изменённых файлов: 137 добавлений и 5 удалений

Просмотреть файл

@ -14,6 +14,7 @@
#include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/TabParent.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
@ -219,6 +220,7 @@ AudioChannelService::Shutdown()
gAudioChannelService->mWindows.Clear(); gAudioChannelService->mWindows.Clear();
gAudioChannelService->mPlayingChildren.Clear(); gAudioChannelService->mPlayingChildren.Clear();
gAudioChannelService->mTabParents.Clear();
#ifdef MOZ_WIDGET_GONK #ifdef MOZ_WIDGET_GONK
gAudioChannelService->mSpeakerManager.Clear(); gAudioChannelService->mSpeakerManager.Clear();
#endif #endif
@ -341,6 +343,21 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent,
MaybeSendStatusUpdate(); MaybeSendStatusUpdate();
} }
void
AudioChannelService::RegisterTabParent(TabParent* aTabParent)
{
MOZ_ASSERT(aTabParent);
MOZ_ASSERT(!mTabParents.Contains(aTabParent));
mTabParents.AppendElement(aTabParent);
}
void
AudioChannelService::UnregisterTabParent(TabParent* aTabParent)
{
MOZ_ASSERT(aTabParent);
mTabParents.RemoveElement(aTabParent);
}
void void
AudioChannelService::GetState(nsPIDOMWindow* aWindow, uint32_t aAudioChannel, AudioChannelService::GetState(nsPIDOMWindow* aWindow, uint32_t aAudioChannel,
float* aVolume, bool* aMuted) float* aVolume, bool* aMuted)
@ -560,6 +577,32 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK; return NS_OK;
} }
void
AudioChannelService::RefreshAgentsVolumeAndPropagate(AudioChannel aAudioChannel,
nsPIDOMWindow* aWindow)
{
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aWindow->IsOuterWindow());
nsCOMPtr<nsPIDOMWindow> topWindow = aWindow->GetScriptableTop();
if (!topWindow) {
return;
}
AudioChannelWindow* winData = GetWindowData(topWindow->WindowID());
if (!winData) {
return;
}
for (uint32_t i = 0; i < mTabParents.Length(); ++i) {
mTabParents[i]->AudioChannelChangeNotification(aWindow, aAudioChannel,
winData->mChannels[(uint32_t)aAudioChannel].mVolume,
winData->mChannels[(uint32_t)aAudioChannel].mMuted);
}
RefreshAgentsVolume(aWindow);
}
void void
AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow) AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow)
{ {
@ -751,7 +794,7 @@ AudioChannelService::SetAudioChannelVolume(nsPIDOMWindow* aWindow,
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow); AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
winData->mChannels[(uint32_t)aAudioChannel].mVolume = aVolume; winData->mChannels[(uint32_t)aAudioChannel].mVolume = aVolume;
RefreshAgentsVolume(aWindow); RefreshAgentsVolumeAndPropagate(aAudioChannel, aWindow);
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -814,7 +857,7 @@ AudioChannelService::SetAudioChannelMuted(nsPIDOMWindow* aWindow,
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow); AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
winData->mChannels[(uint32_t)aAudioChannel].mMuted = aMuted; winData->mChannels[(uint32_t)aAudioChannel].mMuted = aMuted;
RefreshAgentsVolume(aWindow); RefreshAgentsVolumeAndPropagate(aAudioChannel, aWindow);
} }
NS_IMETHODIMP NS_IMETHODIMP

Просмотреть файл

@ -23,10 +23,13 @@ struct PRLogModuleInfo;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
#ifdef MOZ_WIDGET_GONK #ifdef MOZ_WIDGET_GONK
class SpeakerManagerService; class SpeakerManagerService;
#endif #endif
class TabParent;
#define NUMBER_OF_AUDIO_CHANNELS (uint32_t)AudioChannel::EndGuard_ #define NUMBER_OF_AUDIO_CHANNELS (uint32_t)AudioChannel::EndGuard_
class AudioChannelService final : public nsIAudioChannelService class AudioChannelService final : public nsIAudioChannelService
@ -63,6 +66,12 @@ public:
void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent, void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent,
uint32_t aNotifyPlayback); uint32_t aNotifyPlayback);
/**
* For nested iframes.
*/
void RegisterTabParent(TabParent* aTabParent);
void UnregisterTabParent(TabParent* aTabParent);
/** /**
* Return the state to indicate this audioChannel for his window should keep * Return the state to indicate this audioChannel for his window should keep
* playing/muted. * playing/muted.
@ -108,6 +117,9 @@ public:
void RefreshAgentsVolume(nsPIDOMWindow* aWindow); void RefreshAgentsVolume(nsPIDOMWindow* aWindow);
void RefreshAgentsVolumeAndPropagate(AudioChannel aAudioChannel,
nsPIDOMWindow* aWindow);
// This method needs to know the inner window that wants to capture audio. We // This method needs to know the inner window that wants to capture audio. We
// group agents per top outer window, but we can have multiple innerWindow per // group agents per top outer window, but we can have multiple innerWindow per
// top outerWindow (subiframes, etc.) and we have to identify all the agents // top outerWindow (subiframes, etc.) and we have to identify all the agents
@ -223,6 +235,9 @@ private:
nsTArray<SpeakerManagerService*> mSpeakerManager; nsTArray<SpeakerManagerService*> mSpeakerManager;
#endif #endif
// Raw pointers because TabParents must unregister themselves.
nsTArray<TabParent*> mTabParents;
nsCOMPtr<nsIRunnable> mRunnable; nsCOMPtr<nsIRunnable> mRunnable;
uint64_t mDefChannelChildID; uint64_t mDefChannelChildID;

Просмотреть файл

@ -760,6 +760,13 @@ child:
*/ */
HandleAccessKey(uint32_t[] charCodes, bool isTrusted, int32_t modifierMask); HandleAccessKey(uint32_t[] charCodes, bool isTrusted, int32_t modifierMask);
/**
* Propagate a refresh to the child process
*/
AudioChannelChangeNotification(uint32_t aAudioChannel,
float aVolume,
bool aMuted);
/* /*
* FIXME: write protocol! * FIXME: write protocol!

Просмотреть файл

@ -2254,6 +2254,27 @@ TabChild::RecvHandleAccessKey(nsTArray<uint32_t>&& aCharCodes,
return true; return true;
} }
bool
TabChild::RecvAudioChannelChangeNotification(const uint32_t& aAudioChannel,
const float& aVolume,
const bool& aMuted)
{
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(WebNavigation());
if (window) {
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
MOZ_ASSERT(service);
service->SetAudioChannelVolume(window,
static_cast<AudioChannel>(aAudioChannel),
aVolume);
service->SetAudioChannelMuted(window,
static_cast<AudioChannel>(aAudioChannel),
aMuted);
}
return true;
}
bool bool
TabChild::RecvDestroy() TabChild::RecvDestroy()
{ {

Просмотреть файл

@ -504,6 +504,10 @@ public:
const bool& aIsTrusted, const bool& aIsTrusted,
const int32_t& aModifierMask) override; const int32_t& aModifierMask) override;
virtual bool RecvAudioChannelChangeNotification(const uint32_t& aAudioChannel,
const float& aVolume,
const bool& aMuted) override;
/** /**
* Native widget remoting protocol for use with windowed plugins with e10s. * Native widget remoting protocol for use with windowed plugins with e10s.
*/ */

Просмотреть файл

@ -184,7 +184,7 @@ private:
// Our TabParent may have been destroyed already. If so, don't send any // Our TabParent may have been destroyed already. If so, don't send any
// fds over, just go back to the IO thread and close them. // fds over, just go back to the IO thread and close them.
if (!tabParent->IsDestroyed()) { if (!tabParent->IsDestroyed()) {
mozilla::Unused << tabParent->SendCacheFileDescriptor(mPath, fd); Unused << tabParent->SendCacheFileDescriptor(mPath, fd);
} }
if (!mFD) { if (!mFD) {
@ -232,7 +232,7 @@ private:
// Intentionally leak the runnable (but not the fd) rather // Intentionally leak the runnable (but not the fd) rather
// than crash when trying to release a main thread object // than crash when trying to release a main thread object
// off the main thread. // off the main thread.
mozilla::Unused << mTabParent.forget(); Unused << mTabParent.forget();
CloseFile(); CloseFile();
} }
} }
@ -387,6 +387,11 @@ TabParent::AddWindowListeners()
mPresShellWithRefreshListener = shell; mPresShellWithRefreshListener = shell;
shell->AddPostRefreshObserver(this); shell->AddPostRefreshObserver(this);
} }
RefPtr<AudioChannelService> acs = AudioChannelService::GetOrCreate();
if (acs) {
acs->RegisterTabParent(this);
}
} }
} }
@ -405,6 +410,11 @@ TabParent::RemoveWindowListeners()
mPresShellWithRefreshListener->RemovePostRefreshObserver(this); mPresShellWithRefreshListener->RemovePostRefreshObserver(this);
mPresShellWithRefreshListener = nullptr; mPresShellWithRefreshListener = nullptr;
} }
RefPtr<AudioChannelService> acs = AudioChannelService::GetOrCreate();
if (acs) {
acs->UnregisterTabParent(this);
}
} }
void void
@ -2636,7 +2646,6 @@ TabParent::RecvAudioChannelActivityNotification(const uint32_t& aAudioChannel,
nsCOMPtr<nsIObserverService> os = services::GetObserverService(); nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) { if (os) {
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
nsAutoCString topic; nsAutoCString topic;
topic.Assign("audiochannel-activity-"); topic.Assign("audiochannel-activity-");
topic.Append(AudioChannelService::GetAudioChannelTable()[aAudioChannel].tag); topic.Append(AudioChannelService::GetAudioChannelTable()[aAudioChannel].tag);
@ -3397,6 +3406,33 @@ TabParent::GetShowInfo()
mDPI, mDefaultScale.scale); mDPI, mDefaultScale.scale);
} }
void
TabParent::AudioChannelChangeNotification(nsPIDOMWindow* aWindow,
AudioChannel aAudioChannel,
float aVolume,
bool aMuted)
{
if (!mFrameElement || !mFrameElement->OwnerDoc()) {
return;
}
nsCOMPtr<nsPIDOMWindow> window = mFrameElement->OwnerDoc()->GetWindow();
while (window) {
if (window == aWindow) {
Unused << SendAudioChannelChangeNotification(static_cast<uint32_t>(aAudioChannel),
aVolume, aMuted);
break;
}
nsCOMPtr<nsPIDOMWindow> win = window->GetScriptableParent();
if (window == win) {
break;
}
window = win;
}
}
NS_IMETHODIMP NS_IMETHODIMP
FakeChannel::OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo) FakeChannel::OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo)
{ {

Просмотреть файл

@ -9,6 +9,7 @@
#include "js/TypeDecls.h" #include "js/TypeDecls.h"
#include "mozilla/ContentCache.h" #include "mozilla/ContentCache.h"
#include "mozilla/dom/AudioChannelBinding.h"
#include "mozilla/dom/ipc/IdType.h" #include "mozilla/dom/ipc/IdType.h"
#include "mozilla/dom/PBrowserParent.h" #include "mozilla/dom/PBrowserParent.h"
#include "mozilla/dom/PContent.h" #include "mozilla/dom/PContent.h"
@ -455,6 +456,11 @@ public:
void OnStartSignedPackageRequest(nsIChannel* aChannel, void OnStartSignedPackageRequest(nsIChannel* aChannel,
const nsACString& aPackageId); const nsACString& aPackageId);
void AudioChannelChangeNotification(nsPIDOMWindow* aWindow,
AudioChannel aAudioChannel,
float aVolume,
bool aMuted);
protected: protected:
bool ReceiveMessage(const nsString& aMessage, bool ReceiveMessage(const nsString& aMessage,
bool aSync, bool aSync,