Bug 923247 - patch 1 - window in the AudioChannelAgent, r=mchen

This commit is contained in:
Andrea Marchesini 2014-03-10 16:36:07 +00:00
parent eff50c44d9
commit af673bd5ac
10 changed files with 66 additions and 34 deletions

View File

@ -274,7 +274,8 @@ HTMLAudioElement::UpdateAudioChannelPlayingState()
return;
}
// Use a weak ref so the audio channel agent can't leak |this|.
mAudioChannelAgent->InitWithWeakCallback(mAudioChannelType, this);
mAudioChannelAgent->InitWithWeakCallback(OwnerDoc()->GetWindow(),
mAudioChannelType, this);
mAudioChannelAgent->SetVisibilityState(!OwnerDoc()->Hidden());
}

View File

@ -3879,9 +3879,11 @@ void HTMLMediaElement::UpdateAudioChannelPlayingState()
nsCOMPtr<nsIDOMHTMLVideoElement> video = do_QueryObject(this);
// Use a weak ref so the audio channel agent can't leak |this|.
if (AUDIO_CHANNEL_NORMAL == mAudioChannelType && video) {
mAudioChannelAgent->InitWithVideo(mAudioChannelType, this, true);
mAudioChannelAgent->InitWithVideo(OwnerDoc()->GetWindow(),
mAudioChannelType, this, true);
} else {
mAudioChannelAgent->InitWithWeakCallback(mAudioChannelType, this);
mAudioChannelAgent->InitWithWeakCallback(OwnerDoc()->GetWindow(),
mAudioChannelType, this);
}
mAudioChannelAgent->SetVisibilityState(!OwnerDoc()->Hidden());
}

View File

@ -478,7 +478,7 @@ AudioDestinationNode::CreateAudioChannelAgent()
}
mAudioChannelAgent = new AudioChannelAgent();
mAudioChannelAgent->InitWithWeakCallback(type, this);
mAudioChannelAgent->InitWithWeakCallback(GetOwner(), type, this);
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner());
if (docshell) {

View File

@ -5,10 +5,12 @@
#include "AudioChannelAgent.h"
#include "AudioChannelCommon.h"
#include "AudioChannelService.h"
#include "nsIDOMWindow.h"
#include "nsXULAppAPI.h"
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_1(AudioChannelAgent, mCallback)
NS_IMPL_CYCLE_COLLECTION_2(AudioChannelAgent, mWindow, mCallback)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AudioChannelAgent)
NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgent)
@ -40,34 +42,46 @@ NS_IMETHODIMP AudioChannelAgent::GetAudioChannelType(int32_t *aAudioChannelType)
return NS_OK;
}
/* boolean init (in long channelType, in nsIAudioChannelAgentCallback callback); */
NS_IMETHODIMP AudioChannelAgent::Init(int32_t channelType, nsIAudioChannelAgentCallback *callback)
/* boolean init (in nsIDOMWindow window, in long channelType,
* in nsIAudioChannelAgentCallback callback); */
NS_IMETHODIMP
AudioChannelAgent::Init(nsIDOMWindow* aWindow, int32_t aChannelType,
nsIAudioChannelAgentCallback *aCallback)
{
return InitInternal(channelType, callback, /* useWeakRef = */ false);
return InitInternal(aWindow, aChannelType, aCallback,
/* useWeakRef = */ false);
}
/* boolean initWithWeakCallback (in long channelType,
/* boolean initWithWeakCallback (in nsIDOMWindow window, in long channelType,
* in nsIAudioChannelAgentCallback callback); */
NS_IMETHODIMP
AudioChannelAgent::InitWithWeakCallback(int32_t channelType,
nsIAudioChannelAgentCallback *callback)
AudioChannelAgent::InitWithWeakCallback(nsIDOMWindow* aWindow,
int32_t aChannelType,
nsIAudioChannelAgentCallback *aCallback)
{
return InitInternal(channelType, callback, /* useWeakRef = */ true);
return InitInternal(aWindow, aChannelType, aCallback,
/* useWeakRef = */ true);
}
/* void initWithVideo(in nsIDOMWindow window, in long channelType,
* in nsIAudioChannelAgentCallback callback, in boolean weak); */
NS_IMETHODIMP
AudioChannelAgent::InitWithVideo(int32_t channelType,
nsIAudioChannelAgentCallback *callback,
AudioChannelAgent::InitWithVideo(nsIDOMWindow* aWindow, int32_t aChannelType,
nsIAudioChannelAgentCallback *aCallback,
bool aUseWeakRef)
{
return InitInternal(channelType, callback, aUseWeakRef, true);
return InitInternal(aWindow, aChannelType, aCallback, aUseWeakRef,
/* withVideo = */ true);
}
nsresult
AudioChannelAgent::InitInternal(int32_t aChannelType,
AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
nsIAudioChannelAgentCallback *aCallback,
bool aUseWeakRef, bool aWithVideo)
{
// We need the window only for IPC.
MOZ_ASSERT(aWindow || XRE_GetProcessType() == GeckoProcessType_Default);
// We syncd the enum of channel type between nsIAudioChannelAgent.idl and
// AudioChannelCommon.h the same.
static_assert(static_cast<AudioChannelType>(AUDIO_AGENT_CHANNEL_NORMAL) ==
@ -92,6 +106,7 @@ AudioChannelAgent::InitInternal(int32_t aChannelType,
return NS_ERROR_FAILURE;
}
mWindow = aWindow;
mAudioChannelType = aChannelType;
if (aUseWeakRef) {

View File

@ -17,6 +17,8 @@
#define NS_AUDIOCHANNELAGENT_CID {0xf27688e2, 0x3dd7, 0x11e2, \
{0x90, 0x4e, 0x10, 0xbf, 0x48, 0xd6, 0x4b, 0xd4}}
class nsIDOMWindow;
namespace mozilla {
namespace dom {
@ -39,10 +41,11 @@ private:
// nsIAudioChannelAgentCallback out of mWeakCallback.
already_AddRefed<nsIAudioChannelAgentCallback> GetCallback();
nsresult InitInternal(int32_t aAudioAgentType,
nsresult InitInternal(nsIDOMWindow* aWindow, int32_t aAudioAgentType,
nsIAudioChannelAgentCallback* aCallback,
bool aUseWeakRef, bool aWithVideo=false);
nsCOMPtr<nsIDOMWindow> mWindow;
nsCOMPtr<nsIAudioChannelAgentCallback> mCallback;
nsWeakPtr mWeakCallback;
int32_t mAudioChannelType;

View File

@ -4,7 +4,9 @@
#include "nsISupports.idl"
[function, scriptable, uuid(c7227506-5f8e-11e2-8bb3-10bf48d64bd4)]
interface nsIDOMWindow;
[function, scriptable, uuid(86975108-cd78-4796-8fc8-6cd777cd6eba)]
interface nsIAudioChannelAgentCallback : nsISupports
{
/**
@ -22,11 +24,12 @@ interface nsIAudioChannelAgentCallback : nsISupports
/**
* This interface provides an agent for gecko components to participate
* in the audio channel service. Gecko components are responsible for
* 1. Indicating what channel type they are using (via the init() member function).
* 1. Indicating what channel type they are using (via the init() member
* function).
* 2. Before playing, checking the playable status of the channel.
* 3. Notifying the agent when they start/stop using this channel.
* 4. Notifying the agent of changes to the visibility of the component using
* this channel.
* this channel.
*
* The agent will invoke a callback to notify Gecko components of
* 1. Changes to the playable status of this channel.
@ -58,16 +61,20 @@ interface nsIAudioChannelAgent : nsISupports
* Initialize the agent with a channel type.
* Note: This function should only be called once.
*
* @param window
* The window
* @param channelType
* Audio Channel Type listed as above
* @param callback
* 1. Once the playable status changes, agent uses this callback function to notify
* Gecko component.
* 2. The callback is allowed to be null. Ex: telephony doesn't need to listen change
* of the playable status.
* 3. The AudioChannelAgent keeps a strong reference to the callback object.
* 1. Once the playable status changes, agent uses this callback function
* to notify Gecko component.
* 2. The callback is allowed to be null. Ex: telephony doesn't need to
* listen change of the playable status.
* 3. The AudioChannelAgent keeps a strong reference to the callback
* object.
*/
void init(in long channelType, in nsIAudioChannelAgentCallback callback);
void init(in nsIDOMWindow window, in long channelType,
in nsIAudioChannelAgentCallback callback);
/**
* This method is just like init(), except the audio channel agent keeps a
@ -76,15 +83,18 @@ interface nsIAudioChannelAgent : nsISupports
* In order for this to work, |callback| must implement
* nsISupportsWeakReference.
*/
void initWithWeakCallback(in long channelType, in nsIAudioChannelAgentCallback callback);
void initWithWeakCallback(in nsIDOMWindow window, in long channelType,
in nsIAudioChannelAgentCallback callback);
/**
* This method is just like init(), and specify the channel is associated with video.
* This method is just like init(), and specify the channel is associated
* with video.
*
* @param weak
* true if weak reference should be hold.
*/
void initWithVideo(in long channelType, in nsIAudioChannelAgentCallback callback, in boolean weak);
void initWithVideo(in nsIDOMWindow window, in long channelType,
in nsIAudioChannelAgentCallback callback, in boolean weak);
/**
* Notify the agent that we want to start playing.

View File

@ -51,10 +51,10 @@ public:
{
nsresult rv = NS_OK;
if (video) {
rv = mAgent->InitWithVideo(mType, this, true);
rv = mAgent->InitWithVideo(nullptr, mType, this, true);
}
else {
rv = mAgent->InitWithWeakCallback(mType, this);
rv = mAgent->InitWithWeakCallback(nullptr, mType, this);
}
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -699,7 +699,7 @@ nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
if (mAudioChannelAgent) {
// Camera app will stop recording when it falls to the background, so no callback is necessary.
mAudioChannelAgent->Init(AUDIO_CHANNEL_CONTENT, nullptr);
mAudioChannelAgent->Init(mWindow, AUDIO_CHANNEL_CONTENT, nullptr);
// Video recording doesn't output any sound, so it's not necessary to check canPlay.
int32_t canPlay;
mAudioChannelAgent->StartPlaying(&canPlay);

View File

@ -150,6 +150,7 @@ FMRadio::Init(nsPIDOMWindow *aWindow)
NS_ENSURE_TRUE_VOID(audioChannelAgent);
audioChannelAgent->InitWithWeakCallback(
GetOwner(),
nsIAudioChannelAgent::AUDIO_AGENT_CHANNEL_CONTENT,
this);

View File

@ -531,9 +531,9 @@ AudioManager::SetPhoneState(int32_t aState)
MOZ_ASSERT(mPhoneAudioAgent);
if (aState == PHONE_STATE_IN_CALL) {
// Telephony doesn't be paused by any other channels.
mPhoneAudioAgent->Init(AUDIO_CHANNEL_TELEPHONY, nullptr);
mPhoneAudioAgent->Init(nullptr, AUDIO_CHANNEL_TELEPHONY, nullptr);
} else {
mPhoneAudioAgent->Init(AUDIO_CHANNEL_RINGER, nullptr);
mPhoneAudioAgent->Init(nullptr, AUDIO_CHANNEL_RINGER, nullptr);
}
// Telephony can always play.