зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1358372: Part 2 - Run Windows AudioSessionControl operations on main thread r=jimm
This plays better with sndvol.exe. It reduces the impact of a bug that shows multiple volume sliders for the content processes.
This commit is contained in:
Родитель
e42b5990ac
Коммит
d2fcfd4724
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/mscom/StructStream.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "HandlerData.h"
|
||||
|
||||
struct NEWEST_IA2_INTERFACE;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
#include <objbase.h>
|
||||
|
||||
|
@ -54,6 +55,8 @@ public:
|
|||
STDMETHODIMP OnSessionDisconnected(AudioSessionDisconnectReason aReason);
|
||||
private:
|
||||
nsresult OnSessionDisconnectedInternal();
|
||||
nsresult CommitAudioSessionData();
|
||||
|
||||
public:
|
||||
STDMETHODIMP OnSimpleVolumeChanged(float aVolume,
|
||||
BOOL aMute,
|
||||
|
@ -86,6 +89,8 @@ protected:
|
|||
nsString mIconPath;
|
||||
nsID mSessionGroupingParameter;
|
||||
SessionState mState;
|
||||
// Guards the IAudioSessionControl
|
||||
mozilla::Mutex mMutex;
|
||||
|
||||
ThreadSafeAutoRefCnt mRefCnt;
|
||||
NS_DECL_OWNINGTHREAD
|
||||
|
@ -127,7 +132,8 @@ RecvAudioSessionData(const nsID& aID,
|
|||
|
||||
AudioSession* AudioSession::sService = nullptr;
|
||||
|
||||
AudioSession::AudioSession()
|
||||
AudioSession::AudioSession() :
|
||||
mMutex("AudioSessionControl")
|
||||
{
|
||||
mState = UNINITIALIZED;
|
||||
}
|
||||
|
@ -254,6 +260,7 @@ AudioSession::Start()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
hr = manager->GetAudioSessionControl(&GUID_NULL,
|
||||
0,
|
||||
getter_AddRefs(mAudioSessionControl));
|
||||
|
@ -262,25 +269,6 @@ AudioSession::Start()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
hr = mAudioSessionControl->SetGroupingParam((LPGUID)&mSessionGroupingParameter,
|
||||
nullptr);
|
||||
if (FAILED(hr)) {
|
||||
StopInternal();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
hr = mAudioSessionControl->SetDisplayName(mDisplayName.get(), nullptr);
|
||||
if (FAILED(hr)) {
|
||||
StopInternal();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
hr = mAudioSessionControl->SetIconPath(mIconPath.get(), nullptr);
|
||||
if (FAILED(hr)) {
|
||||
StopInternal();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Increments refcount of 'this'.
|
||||
hr = mAudioSessionControl->RegisterAudioSessionNotification(this);
|
||||
if (FAILED(hr)) {
|
||||
|
@ -288,6 +276,11 @@ AudioSession::Start()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NewRunnableMethod("AudioSession::CommitAudioSessionData",
|
||||
this, &AudioSession::CommitAudioSessionData);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
|
||||
mState = STARTED;
|
||||
|
||||
return NS_OK;
|
||||
|
@ -296,6 +289,8 @@ AudioSession::Start()
|
|||
void
|
||||
AudioSession::StopInternal()
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
|
||||
if (mAudioSessionControl &&
|
||||
(mState == STARTED || mState == STOPPED)) {
|
||||
// Decrement refcount of 'this'
|
||||
|
@ -318,6 +313,7 @@ AudioSession::Stop()
|
|||
RefPtr<AudioSession> kungFuDeathGrip;
|
||||
kungFuDeathGrip.swap(sService);
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
StopInternal();
|
||||
}
|
||||
|
||||
|
@ -374,6 +370,39 @@ AudioSession::SetSessionData(const nsID& aID,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AudioSession::CommitAudioSessionData()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (!mAudioSessionControl) {
|
||||
// Stop() was called before we had a chance to do this.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
HRESULT hr =
|
||||
mAudioSessionControl->SetGroupingParam((LPGUID)&mSessionGroupingParameter,
|
||||
nullptr);
|
||||
if (FAILED(hr)) {
|
||||
StopInternal();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
hr = mAudioSessionControl->SetDisplayName(mDisplayName.get(), nullptr);
|
||||
if (FAILED(hr)) {
|
||||
StopInternal();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
hr = mAudioSessionControl->SetIconPath(mIconPath.get(), nullptr);
|
||||
if (FAILED(hr)) {
|
||||
StopInternal();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
AudioSession::OnChannelVolumeChanged(DWORD aChannelCount,
|
||||
float aChannelVolumeArray[],
|
||||
|
@ -419,15 +448,20 @@ AudioSession::OnSessionDisconnected(AudioSessionDisconnectReason aReason)
|
|||
nsresult
|
||||
AudioSession::OnSessionDisconnectedInternal()
|
||||
{
|
||||
if (!mAudioSessionControl)
|
||||
return NS_OK;
|
||||
{
|
||||
// We need to release the mutex before we call Start().
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
// When successful, UnregisterAudioSessionNotification will decrement the
|
||||
// refcount of 'this'. Start will re-increment it. In the interim,
|
||||
// we'll need to reference ourselves.
|
||||
RefPtr<AudioSession> kungFuDeathGrip(this);
|
||||
mAudioSessionControl->UnregisterAudioSessionNotification(this);
|
||||
mAudioSessionControl = nullptr;
|
||||
if (!mAudioSessionControl)
|
||||
return NS_OK;
|
||||
|
||||
// When successful, UnregisterAudioSessionNotification will decrement the
|
||||
// refcount of 'this'. Start will re-increment it. In the interim,
|
||||
// we'll need to reference ourselves.
|
||||
RefPtr<AudioSession> kungFuDeathGrip(this);
|
||||
mAudioSessionControl->UnregisterAudioSessionNotification(this);
|
||||
mAudioSessionControl = nullptr;
|
||||
}
|
||||
|
||||
mState = AUDIO_SESSION_DISCONNECTED;
|
||||
CoUninitialize();
|
||||
|
|
Загрузка…
Ссылка в новой задаче