mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 823273 - Part 1: Music volume should be faded when notification sound is on going - AudioChannel changes. r=baku
This commit is contained in:
parent
74b1d0c3d5
commit
1375174442
@ -95,7 +95,7 @@ AudioChannelAgent::InitInternal(int32_t aChannelType,
|
||||
}
|
||||
|
||||
/* boolean startPlaying (); */
|
||||
NS_IMETHODIMP AudioChannelAgent::StartPlaying(bool *_retval)
|
||||
NS_IMETHODIMP AudioChannelAgent::StartPlaying(int32_t *_retval)
|
||||
{
|
||||
AudioChannelService *service = AudioChannelService::GetAudioChannelService();
|
||||
if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR ||
|
||||
@ -105,7 +105,7 @@ NS_IMETHODIMP AudioChannelAgent::StartPlaying(bool *_retval)
|
||||
|
||||
service->RegisterAudioChannelAgent(this,
|
||||
static_cast<AudioChannelType>(mAudioChannelType));
|
||||
*_retval = !service->GetMuted(this, !mVisible);
|
||||
*_retval = service->GetState(this, !mVisible);
|
||||
mIsRegToService = true;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -134,7 +134,7 @@ NS_IMETHODIMP AudioChannelAgent::SetVisibilityState(bool visible)
|
||||
mVisible = visible;
|
||||
if (mIsRegToService && oldVisibility != mVisible && callback) {
|
||||
AudioChannelService *service = AudioChannelService::GetAudioChannelService();
|
||||
callback->CanPlayChanged(!service->GetMuted(this, !mVisible));
|
||||
callback->CanPlayChanged(service->GetState(this, !mVisible));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -144,7 +144,7 @@ void AudioChannelAgent::NotifyAudioChannelStateChanged()
|
||||
nsCOMPtr<nsIAudioChannelAgentCallback> callback = GetCallback();
|
||||
if (callback) {
|
||||
AudioChannelService *service = AudioChannelService::GetAudioChannelService();
|
||||
callback->CanPlayChanged(!service->GetMuted(this, !mVisible));
|
||||
callback->CanPlayChanged(service->GetState(this, !mVisible));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,12 @@ enum AudioChannelType {
|
||||
AUDIO_CHANNEL_LAST
|
||||
};
|
||||
|
||||
enum AudioChannelState {
|
||||
AUDIO_CHANNEL_STATE_NORMAL = 0,
|
||||
AUDIO_CHANNEL_STATE_MUTED,
|
||||
AUDIO_CHANNEL_STATE_FADED,
|
||||
AUDIO_CHANNEL_STATE_LAST
|
||||
};
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -98,8 +98,8 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
|
||||
MOZ_ASSERT(aType != AUDIO_CHANNEL_DEFAULT);
|
||||
|
||||
AudioChannelAgentData* data = new AudioChannelAgentData(aType,
|
||||
true /* mElementHidden */,
|
||||
true /* mMuted */);
|
||||
true /* aElementHidden */,
|
||||
AUDIO_CHANNEL_STATE_MUTED /* aState */);
|
||||
mAgents.Put(aAgent, data);
|
||||
RegisterType(aType, CONTENT_PROCESS_ID_MAIN);
|
||||
}
|
||||
@ -203,27 +203,25 @@ AudioChannelService::UpdateChannelType(AudioChannelType aType,
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelService::GetMuted(AudioChannelAgent* aAgent, bool aElementHidden)
|
||||
AudioChannelState
|
||||
AudioChannelService::GetState(AudioChannelAgent* aAgent, bool aElementHidden)
|
||||
{
|
||||
AudioChannelAgentData* data;
|
||||
if (!mAgents.Get(aAgent, &data)) {
|
||||
return true;
|
||||
return AUDIO_CHANNEL_STATE_MUTED;
|
||||
}
|
||||
|
||||
bool oldElementHidden = data->mElementHidden;
|
||||
// Update visibility.
|
||||
data->mElementHidden = aElementHidden;
|
||||
|
||||
bool muted = GetMutedInternal(data->mType, CONTENT_PROCESS_ID_MAIN,
|
||||
data->mState = GetStateInternal(data->mType, CONTENT_PROCESS_ID_MAIN,
|
||||
aElementHidden, oldElementHidden);
|
||||
data->mMuted = muted;
|
||||
|
||||
return muted;
|
||||
return data->mState;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelService::GetMutedInternal(AudioChannelType aType, uint64_t aChildID,
|
||||
AudioChannelState
|
||||
AudioChannelService::GetStateInternal(AudioChannelType aType, uint64_t aChildID,
|
||||
bool aElementHidden, bool aElementWasHidden)
|
||||
{
|
||||
UpdateChannelType(aType, aChildID, aElementHidden, aElementWasHidden);
|
||||
@ -269,24 +267,64 @@ AudioChannelService::GetMutedInternal(AudioChannelType aType, uint64_t aChildID,
|
||||
|
||||
// Let play any visible audio channel.
|
||||
if (!aElementHidden) {
|
||||
return false;
|
||||
if (CheckVolumeFadedCondition(newType, aElementHidden)) {
|
||||
return AUDIO_CHANNEL_STATE_FADED;
|
||||
}
|
||||
return AUDIO_CHANNEL_STATE_NORMAL;
|
||||
}
|
||||
|
||||
bool muted = false;
|
||||
|
||||
// We are not visible, maybe we have to mute.
|
||||
if (newType == AUDIO_CHANNEL_INT_NORMAL_HIDDEN ||
|
||||
(newType == AUDIO_CHANNEL_INT_CONTENT_HIDDEN &&
|
||||
!mActiveContentChildIDs.Contains(aChildID))) {
|
||||
muted = true;
|
||||
return AUDIO_CHANNEL_STATE_MUTED;
|
||||
}
|
||||
|
||||
if (!muted) {
|
||||
// After checking the condition on normal & content channel, if the state
|
||||
// is not on muted then checking other higher channels type here.
|
||||
if (ChannelsActiveWithHigherPriorityThan(newType)) {
|
||||
MOZ_ASSERT(newType != AUDIO_CHANNEL_INT_NORMAL_HIDDEN);
|
||||
muted = ChannelsActiveWithHigherPriorityThan(newType);
|
||||
if (CheckVolumeFadedCondition(newType, aElementHidden)) {
|
||||
return AUDIO_CHANNEL_STATE_FADED;
|
||||
}
|
||||
return AUDIO_CHANNEL_STATE_MUTED;
|
||||
}
|
||||
|
||||
return muted;
|
||||
return AUDIO_CHANNEL_STATE_NORMAL;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelService::CheckVolumeFadedCondition(AudioChannelInternalType aType,
|
||||
bool aElementHidden)
|
||||
{
|
||||
// Only normal & content channels are considered
|
||||
if (aType > AUDIO_CHANNEL_INT_CONTENT_HIDDEN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Consider that audio from notification is with short duration
|
||||
// so just fade the volume not pause it
|
||||
if (mChannelCounters[AUDIO_CHANNEL_INT_NOTIFICATION].IsEmpty() &&
|
||||
mChannelCounters[AUDIO_CHANNEL_INT_NOTIFICATION_HIDDEN].IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Since this element is on the foreground, it can be allowed to play always.
|
||||
// So return true directly when there is any notification channel alive.
|
||||
if (aElementHidden == false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If element is on the background, it is possible paused by channels higher
|
||||
// then notification.
|
||||
for (int i = AUDIO_CHANNEL_INT_LAST - 1;
|
||||
i != AUDIO_CHANNEL_INT_NOTIFICATION_HIDDEN; --i) {
|
||||
if (!mChannelCounters[i].IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -476,7 +514,8 @@ AudioChannelService::Notify(nsITimer* aTimer)
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelService::ChannelsActiveWithHigherPriorityThan(AudioChannelInternalType aType)
|
||||
AudioChannelService::ChannelsActiveWithHigherPriorityThan(
|
||||
AudioChannelInternalType aType)
|
||||
{
|
||||
for (int i = AUDIO_CHANNEL_INT_LAST - 1;
|
||||
i != AUDIO_CHANNEL_INT_CONTENT_HIDDEN; --i) {
|
||||
|
@ -29,11 +29,12 @@ public:
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
/**
|
||||
* Returns the AudioChannelServce singleton. Only to be called from main thread.
|
||||
* Returns the AudioChannelServce singleton. Only to be called from main
|
||||
* thread.
|
||||
*
|
||||
* @return NS_OK on proper assignment, NS_ERROR_FAILURE otherwise.
|
||||
*/
|
||||
static AudioChannelService*
|
||||
GetAudioChannelService();
|
||||
static AudioChannelService* GetAudioChannelService();
|
||||
|
||||
/**
|
||||
* Shutdown the singleton.
|
||||
@ -54,9 +55,11 @@ public:
|
||||
virtual void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent);
|
||||
|
||||
/**
|
||||
* Return true if this type should be muted.
|
||||
* Return the state to indicate this agent should keep playing/
|
||||
* fading volume/muted.
|
||||
*/
|
||||
virtual bool GetMuted(AudioChannelAgent* aAgent, bool aElementHidden);
|
||||
virtual AudioChannelState GetState(AudioChannelAgent* aAgent,
|
||||
bool aElementHidden);
|
||||
|
||||
/**
|
||||
* Return true if there is a content channel active in this process
|
||||
@ -65,8 +68,8 @@ public:
|
||||
virtual bool ContentOrNormalChannelIsActive();
|
||||
|
||||
/**
|
||||
* Return true iff a normal or content channel is active for the given process
|
||||
* ID.
|
||||
* Return true if a normal or content channel is active for the given
|
||||
* process ID.
|
||||
*/
|
||||
virtual bool ProcessContentOrNormalChannelIsActive(uint64_t aChildID);
|
||||
|
||||
@ -93,8 +96,9 @@ protected:
|
||||
void UnregisterTypeInternal(AudioChannelType aType, bool aElementHidden,
|
||||
uint64_t aChildID);
|
||||
|
||||
bool GetMutedInternal(AudioChannelType aType, uint64_t aChildID,
|
||||
bool aElementHidden, bool aElementWasHidden);
|
||||
AudioChannelState GetStateInternal(AudioChannelType aType, uint64_t aChildID,
|
||||
bool aElementHidden,
|
||||
bool aElementWasHidden);
|
||||
|
||||
/* Update the internal type value following the visibility changes */
|
||||
void UpdateChannelType(AudioChannelType aType, uint64_t aChildID,
|
||||
@ -127,6 +131,9 @@ protected:
|
||||
|
||||
bool ChannelsActiveWithHigherPriorityThan(AudioChannelInternalType aType);
|
||||
|
||||
bool CheckVolumeFadedCondition(AudioChannelInternalType aType,
|
||||
bool aElementHidden);
|
||||
|
||||
const char* ChannelName(AudioChannelType aType);
|
||||
|
||||
AudioChannelInternalType GetInternalType(AudioChannelType aType,
|
||||
@ -136,15 +143,15 @@ protected:
|
||||
public:
|
||||
AudioChannelAgentData(AudioChannelType aType,
|
||||
bool aElementHidden,
|
||||
bool aMuted)
|
||||
AudioChannelState aState)
|
||||
: mType(aType)
|
||||
, mElementHidden(aElementHidden)
|
||||
, mMuted(aMuted)
|
||||
, mState(aState)
|
||||
{}
|
||||
|
||||
AudioChannelType mType;
|
||||
bool mElementHidden;
|
||||
bool mMuted;
|
||||
AudioChannelState mState;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
|
@ -58,16 +58,16 @@ AudioChannelServiceChild::~AudioChannelServiceChild()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChannelServiceChild::GetMuted(AudioChannelAgent* aAgent, bool aElementHidden)
|
||||
AudioChannelState
|
||||
AudioChannelServiceChild::GetState(AudioChannelAgent* aAgent, bool aElementHidden)
|
||||
{
|
||||
AudioChannelAgentData* data;
|
||||
if (!mAgents.Get(aAgent, &data)) {
|
||||
return true;
|
||||
return AUDIO_CHANNEL_STATE_MUTED;
|
||||
}
|
||||
|
||||
ContentChild *cc = ContentChild::GetSingleton();
|
||||
bool muted = true;
|
||||
AudioChannelState state = AUDIO_CHANNEL_STATE_MUTED;
|
||||
bool oldElementHidden = data->mElementHidden;
|
||||
|
||||
UpdateChannelType(data->mType, CONTENT_PROCESS_ID_MAIN, aElementHidden, oldElementHidden);
|
||||
@ -76,15 +76,15 @@ AudioChannelServiceChild::GetMuted(AudioChannelAgent* aAgent, bool aElementHidde
|
||||
data->mElementHidden = aElementHidden;
|
||||
|
||||
if (cc) {
|
||||
cc->SendAudioChannelGetMuted(data->mType, aElementHidden, oldElementHidden, &muted);
|
||||
cc->SendAudioChannelGetState(data->mType, aElementHidden, oldElementHidden, &state);
|
||||
}
|
||||
data->mMuted = muted;
|
||||
data->mState = state;
|
||||
|
||||
if (cc) {
|
||||
cc->SendAudioChannelChangedNotification();
|
||||
}
|
||||
|
||||
return muted;
|
||||
return state;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -21,11 +21,12 @@ class AudioChannelServiceChild : public AudioChannelService
|
||||
public:
|
||||
|
||||
/**
|
||||
* Returns the AudioChannelServce singleton. Only to be called from main thread.
|
||||
* Returns the AudioChannelServce singleton. Only to be called from main
|
||||
* thread.
|
||||
*
|
||||
* @return NS_OK on proper assignment, NS_ERROR_FAILURE otherwise.
|
||||
*/
|
||||
static AudioChannelService*
|
||||
GetAudioChannelService();
|
||||
static AudioChannelService* GetAudioChannelService();
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
@ -34,9 +35,11 @@ public:
|
||||
virtual void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent);
|
||||
|
||||
/**
|
||||
* Return true if this type + this mozHidden should be muted.
|
||||
* Return the state to indicate this agent should keep playing/
|
||||
* fading volume/muted.
|
||||
*/
|
||||
virtual bool GetMuted(AudioChannelAgent* aAgent, bool aMozHidden);
|
||||
virtual AudioChannelState GetState(AudioChannelAgent* aAgent,
|
||||
bool aElementHidden);
|
||||
|
||||
virtual void SetDefaultVolumeControlChannel(AudioChannelType aType, bool aHidden);
|
||||
|
||||
|
@ -12,10 +12,11 @@ interface nsIAudioChannelAgentCallback : nsISupports
|
||||
*
|
||||
* @param canPlay
|
||||
* Callback from agent to notify component of the playable status
|
||||
* of the channel. If canPlay is false, component SHOULD stop playing
|
||||
* media associated with this channel as soon as possible.
|
||||
* of the channel. If canPlay is muted state, component SHOULD stop
|
||||
* playing media associated with this channel as soon as possible. if
|
||||
* it is faded state then the volume of media should be reduced.
|
||||
*/
|
||||
void canPlayChanged(in boolean canPlay);
|
||||
void canPlayChanged(in long canPlay);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -31,7 +32,7 @@ interface nsIAudioChannelAgentCallback : nsISupports
|
||||
* 1. Changes to the playable status of this channel.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(f012a9b7-6431-4915-a4ac-4ba7d833e28e)]
|
||||
[scriptable, uuid(7a4c0b06-63a4-11e2-8c1b-10bf48d64bd4)]
|
||||
interface nsIAudioChannelAgent : nsISupports
|
||||
{
|
||||
const long AUDIO_AGENT_CHANNEL_NORMAL = 0;
|
||||
@ -44,6 +45,10 @@ interface nsIAudioChannelAgent : nsISupports
|
||||
|
||||
const long AUDIO_AGENT_CHANNEL_ERROR = 1000;
|
||||
|
||||
const long AUDIO_AGENT_STATE_NORMAL = 0;
|
||||
const long AUDIO_AGENT_STATE_MUTED = 1;
|
||||
const long AUDIO_AGENT_STATE_FADED = 2;
|
||||
|
||||
/**
|
||||
* Before init() is called, this returns AUDIO_AGENT_CHANNEL_ERROR.
|
||||
*/
|
||||
@ -80,12 +85,14 @@ interface nsIAudioChannelAgent : nsISupports
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* true: the agent has registered with audio channel service and the
|
||||
* component should start playback.
|
||||
* false: the agent has registered with audio channel service but the
|
||||
* component should not start playback.
|
||||
* normal state: the agent has registered with audio channel service and
|
||||
* the component should start playback.
|
||||
* muted state: the agent has registered with audio channel service but
|
||||
* the component should not start playback.
|
||||
* faded state: the agent has registered with audio channel service the
|
||||
* component should start playback as well as reducing the volume.
|
||||
*/
|
||||
boolean startPlaying();
|
||||
long startPlaying();
|
||||
|
||||
/**
|
||||
* Notify the agent we no longer want to play.
|
||||
|
Loading…
Reference in New Issue
Block a user