gecko-dev/dom/media/mediacontrol/AudioFocusManager.cpp
alwu 4e911221c2 Bug 1565689 - part2 : implement AudioFocusManager. r=baku
In order to support audio competing among different tabs, we implement a new class AudioFocusManager.

AudioFocusManager is used to assign the audio focus to different requester and decide which requester can own audio focus when audio competing happens.
When the audio competing happens, the last request would be a winner who can still own the audio focus, and all the other requesters would lose the audio focus.
Now MediaController is the onlt requester, it would request the audio focus when it becomes audible and revoke the audio focus when the controller is no longer active.

Differential Revision: https://phabricator.services.mozilla.com/D38142

--HG--
extra : moz-landing-system : lando
2019-08-07 01:46:08 +00:00

75 lines
2.1 KiB
C++

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AudioFocusManager.h"
#include "MediaControlService.h"
#include "mozilla/Logging.h"
#include "mozilla/StaticPrefs_media.h"
extern mozilla::LazyLogModule gMediaControlLog;
#undef LOG
#define LOG(msg, ...) \
MOZ_LOG(gMediaControlLog, LogLevel::Debug, \
("AudioFocusManager=%p, " msg, this, ##__VA_ARGS__))
namespace mozilla {
namespace dom {
AudioFocusManager::AudioFocusManager(MediaControlService* aService)
: mService(aService) {}
void AudioFocusManager::RequestAudioFocus(uint64_t aId) {
if (mOwningFocusControllers.Contains(aId)) {
return;
}
LOG("Controller %" PRId64 " grants audio focus", aId);
mOwningFocusControllers.AppendElement(aId);
HandleAudioCompetition(aId);
}
void AudioFocusManager::RevokeAudioFocus(uint64_t aId) {
if (!mOwningFocusControllers.Contains(aId)) {
return;
}
LOG("Controller %" PRId64 " loses audio focus", aId);
mOwningFocusControllers.RemoveElement(aId);
}
void AudioFocusManager::HandleAudioCompetition(uint64_t aId) {
// Enable audio focus management will start the audio competition which is
// only allowing one controller playing at a time.
if (!StaticPrefs::media_audioFocus_management()) {
return;
}
for (size_t idx = 0; idx < mOwningFocusControllers.Length(); idx++) {
const uint64_t controllerId = mOwningFocusControllers[idx];
if (controllerId != aId) {
LOG("Controller %" PRId64 " loses audio focus in audio competitition",
controllerId);
RefPtr<MediaController> controller =
mService->GetControllerById(controllerId);
MOZ_ASSERT(controller);
controller->Stop();
}
}
mOwningFocusControllers.Clear();
mOwningFocusControllers.AppendElement(aId);
}
uint32_t AudioFocusManager::GetAudioFocusNums() const {
return mOwningFocusControllers.Length();
}
void AudioFocusManager::Shutdown() { mService = nullptr; }
} // namespace dom
} // namespace mozilla