mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 20:49:27 +00:00
Bug 1041599 - Maintain a single volume control session between browser, content, and plugins on Windows. r=aklotz
MozReview-Commit-ID: 2LuYciKfsWn
This commit is contained in:
parent
9f5f38e8d7
commit
ee3a95d698
@ -147,6 +147,7 @@
|
||||
#ifdef XP_WIN
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
#include "mozilla/widget/AudioSession.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_X11
|
||||
@ -3043,6 +3044,10 @@ ContentChild::RecvShutdown()
|
||||
"content-child-shutdown", nullptr);
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
mozilla::widget::StopAudioSession();
|
||||
#endif
|
||||
|
||||
GetIPCChannel()->SetAbortOnError(false);
|
||||
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
@ -3161,6 +3166,26 @@ ContentChild::RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvSetAudioSessionData(const nsID& aId,
|
||||
const nsString& aDisplayName,
|
||||
const nsString& aIconPath)
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
if (NS_FAILED(mozilla::widget::RecvAudioSessionData(aId, aDisplayName,
|
||||
aIconPath))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ignore failures here; we can't really do anything about them
|
||||
mozilla::widget::StartAudioSession();
|
||||
return true;
|
||||
#else
|
||||
NS_RUNTIMEABORT("Not Reached!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This code goes here rather than nsGlobalWindow.cpp because nsGlobalWindow.cpp
|
||||
// can't include ContentChild.h since it includes windows.h.
|
||||
|
||||
|
@ -610,6 +610,12 @@ public:
|
||||
|
||||
virtual bool RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent) override;
|
||||
|
||||
// Windows specific - set up audio session
|
||||
virtual bool
|
||||
RecvSetAudioSessionData(const nsID& aId,
|
||||
const nsString& aDisplayName,
|
||||
const nsString& aIconPath) override;
|
||||
|
||||
private:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
|
@ -263,6 +263,10 @@ using namespace mozilla::system;
|
||||
#include "mozilla/dom/GamepadMonitoring.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/widget/AudioSession.h"
|
||||
#endif
|
||||
|
||||
#include "VRManagerParent.h" // for VRManagerParent
|
||||
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
@ -2620,6 +2624,16 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
|
||||
KillHard("SandboxInitFailed");
|
||||
}
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
// Send the info needed to join the browser process's audio session.
|
||||
nsID id;
|
||||
nsString sessionName;
|
||||
nsString iconPath;
|
||||
if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName,
|
||||
iconPath))) {
|
||||
Unused << SendSetAudioSessionData(id, sessionName, iconPath);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -742,6 +742,13 @@ child:
|
||||
*/
|
||||
async PushSubscriptionChange(nsCString scope, Principal principal);
|
||||
|
||||
/**
|
||||
* Windows specific: associate this content process with the browsers
|
||||
* audio session.
|
||||
*/
|
||||
async SetAudioSessionData(nsID aID,
|
||||
nsString aDisplayName,
|
||||
nsString aIconPath);
|
||||
parent:
|
||||
/**
|
||||
* Tell the content process some attributes of itself. This is
|
||||
|
@ -2365,8 +2365,8 @@ PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError)
|
||||
SetPluginFuncs(mNPPIface);
|
||||
}
|
||||
|
||||
// Send the info needed to join the chrome process's audio session to the
|
||||
// plugin process
|
||||
// Send the info needed to join the browser process's audio session to the
|
||||
// plugin process.
|
||||
nsID id;
|
||||
nsString sessionName;
|
||||
nsString iconPath;
|
||||
|
@ -104,6 +104,7 @@
|
||||
#include <math.h>
|
||||
#include "cairo/cairo-features.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#include "mozilla/widget/AudioSession.h"
|
||||
|
||||
#ifndef PROCESS_DEP_ENABLE
|
||||
#define PROCESS_DEP_ENABLE 0x1
|
||||
@ -4420,6 +4421,10 @@ XREMain::XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
||||
|
||||
mScopedXPCOM = nullptr;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
mozilla::widget::StopAudioSession();
|
||||
#endif
|
||||
|
||||
// unlock the profile after ScopedXPCOMStartup object (xpcom)
|
||||
// has gone out of scope. see bug #386739 for more details
|
||||
mProfileLock->Unlock();
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
UNINITIALIZED, // Has not been initialized yet
|
||||
STARTED, // Started
|
||||
CLONED, // SetSessionInfoCalled, Start not called
|
||||
FAILED, // The autdio session failed to start
|
||||
FAILED, // The audio session failed to start
|
||||
STOPPED, // Stop called
|
||||
AUDIO_SESSION_DISCONNECTED // Audio session disconnected
|
||||
};
|
||||
@ -185,16 +185,18 @@ AudioSession::Start()
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
// Don't check for errors in case something already initialized COM
|
||||
// on this thread.
|
||||
CoInitialize(nullptr);
|
||||
// There's a matching CoUninit in Stop() for this tied to a state of
|
||||
// UNINITIALIZED.
|
||||
hr = CoInitialize(nullptr);
|
||||
MOZ_ASSERT(SUCCEEDED(hr), "CoInitialize failure in audio session control, unexpected");
|
||||
|
||||
if (mState == UNINITIALIZED) {
|
||||
mState = FAILED;
|
||||
|
||||
// XXXkhuey implement this for content processes
|
||||
if (XRE_IsContentProcess())
|
||||
// Content processes should be CLONED
|
||||
if (XRE_IsContentProcess()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(XRE_IsParentProcess(),
|
||||
"Should only get here in a chrome process!");
|
||||
@ -212,9 +214,6 @@ AudioSession::Start()
|
||||
|
||||
wchar_t *buffer;
|
||||
mIconPath.GetMutableData(&buffer, MAX_PATH);
|
||||
|
||||
// XXXkhuey we should provide a way for a xulrunner app to specify an icon
|
||||
// that's not in the product binary.
|
||||
::GetModuleFileNameW(nullptr, buffer, MAX_PATH);
|
||||
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
||||
@ -252,16 +251,19 @@ AudioSession::Start()
|
||||
CLSCTX_ALL,
|
||||
nullptr,
|
||||
getter_AddRefs(manager));
|
||||
if (FAILED(hr))
|
||||
if (FAILED(hr)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
hr = manager->GetAudioSessionControl(nullptr,
|
||||
FALSE,
|
||||
hr = manager->GetAudioSessionControl(&GUID_NULL,
|
||||
0,
|
||||
getter_AddRefs(mAudioSessionControl));
|
||||
if (FAILED(hr))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
hr = mAudioSessionControl->SetGroupingParam((LPCGUID)&mSessionGroupingParameter,
|
||||
if (FAILED(hr)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
hr = mAudioSessionControl->SetGroupingParam((LPGUID)&mSessionGroupingParameter,
|
||||
nullptr);
|
||||
if (FAILED(hr)) {
|
||||
StopInternal();
|
||||
@ -294,10 +296,7 @@ AudioSession::Start()
|
||||
void
|
||||
AudioSession::StopInternal()
|
||||
{
|
||||
static const nsID blankId = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0} };
|
||||
|
||||
if (mAudioSessionControl) {
|
||||
mAudioSessionControl->SetGroupingParam((LPCGUID)&blankId, nullptr);
|
||||
mAudioSessionControl->UnregisterAudioSessionNotification(this);
|
||||
mAudioSessionControl = nullptr;
|
||||
}
|
||||
@ -310,18 +309,19 @@ AudioSession::Stop()
|
||||
mState == UNINITIALIZED || // XXXremove this
|
||||
mState == FAILED,
|
||||
"State invariants violated");
|
||||
SessionState state = mState;
|
||||
mState = STOPPED;
|
||||
|
||||
RefPtr<AudioSession> kungFuDeathGrip;
|
||||
kungFuDeathGrip.swap(sService);
|
||||
{
|
||||
RefPtr<AudioSession> kungFuDeathGrip;
|
||||
kungFuDeathGrip.swap(sService);
|
||||
|
||||
if (!XRE_IsContentProcess())
|
||||
StopInternal();
|
||||
}
|
||||
|
||||
// At this point kungFuDeathGrip should be the only reference to AudioSession
|
||||
|
||||
::CoUninitialize();
|
||||
|
||||
if (state != UNINITIALIZED) {
|
||||
::CoUninitialize();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -246,9 +246,14 @@ nsAppShell::Init()
|
||||
NS_IMETHODIMP
|
||||
nsAppShell::Run(void)
|
||||
{
|
||||
// Ignore failure; failing to start the application is not exactly an
|
||||
// appropriate response to failing to start an audio session.
|
||||
mozilla::widget::StartAudioSession();
|
||||
// Content processes initialize audio later through PContent using audio
|
||||
// tray id information pulled from the browser process AudioSession. This
|
||||
// way the two share a single volume control.
|
||||
// Note StopAudioSession() is called from nsAppRunner.cpp after xpcom is torn
|
||||
// down to insure the browser shuts down after child processes.
|
||||
if (XRE_IsParentProcess()) {
|
||||
mozilla::widget::StartAudioSession();
|
||||
}
|
||||
|
||||
// Add an observer that disables the screen saver when requested by Gecko.
|
||||
// For example when we're playing video in the foreground tab.
|
||||
@ -258,8 +263,6 @@ nsAppShell::Run(void)
|
||||
|
||||
RemoveScreenWakeLockListener();
|
||||
|
||||
mozilla::widget::StopAudioSession();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user