Index: content/browser/media/session/audio_focus_manager.cc |
diff --git a/content/browser/media/session/audio_focus_manager.cc b/content/browser/media/session/audio_focus_manager.cc |
index c3589efeea5e5d651d32ecaf8909b409a736f293..5278e89ccb68f424f55944fdd243dfb53602b3a7 100644 |
--- a/content/browser/media/session/audio_focus_manager.cc |
+++ b/content/browser/media/session/audio_focus_manager.cc |
@@ -4,24 +4,19 @@ |
#include "content/browser/media/session/audio_focus_manager.h" |
+#include "base/memory/ptr_util.h" |
#include "content/browser/media/session/media_session.h" |
#include "content/public/browser/web_contents.h" |
namespace content { |
-namespace { |
- |
-const double kDuckingVolumeMultiplier = 0.2; |
-const double kDefaultVolumeMultiplier = 1.0; |
- |
-} // anonymous namespace |
- |
AudioFocusManager::AudioFocusEntry::AudioFocusEntry( |
WebContents* web_contents, |
AudioFocusManager* audio_focus_manager, |
AudioFocusType type) |
: WebContentsObserver(web_contents), |
- audio_focus_manager_(audio_focus_manager) {} |
+ audio_focus_manager_(audio_focus_manager), |
+ type_(type) {} |
whywhat
2016/08/30 21:09:37
nit: this sounds like an initialization bug, shoul
|
AudioFocusManager::AudioFocusType |
AudioFocusManager::AudioFocusEntry::type() const { |
@@ -42,85 +37,68 @@ void AudioFocusManager::RequestAudioFocus(MediaSession* media_session, |
AudioFocusType type) { |
WebContents* web_contents = media_session->web_contents(); |
- if (type == AudioFocusType::GainTransientMayDuck) { |
- MaybeRemoveFocusEntry(web_contents); |
- transient_entries_[web_contents].reset( |
- new AudioFocusEntry(web_contents, this, type)); |
- MaybeStartDucking(); |
+ if (!audio_focus_stack_.empty() && |
+ audio_focus_stack_.back()->web_contents() == web_contents) |
return; |
- } |
- |
- DCHECK(type == AudioFocusType::Gain); |
- RequestAudioFocusGain(web_contents); |
-} |
-void AudioFocusManager::AbandonAudioFocus(MediaSession* media_session) { |
- AbandonAudioFocusInternal(media_session->web_contents()); |
-} |
- |
-AudioFocusManager::AudioFocusManager() = default; |
- |
-AudioFocusManager::~AudioFocusManager() = default; |
- |
-void AudioFocusManager::RequestAudioFocusGain(WebContents* web_contents) { |
- MaybeRemoveTransientEntry(web_contents); |
- |
- if (focus_entry_) { |
- if (focus_entry_->web_contents() == web_contents) |
- return; |
+ MaybeRemoveFocusEntry(web_contents); |
- MediaSession* other_session = |
- MediaSession::Get(focus_entry_->web_contents()); |
- if (other_session->IsActive()) |
- other_session->Suspend(MediaSession::SuspendType::SYSTEM); |
+ if (type == AudioFocusType::GainTransientMayDuck) { |
+ for (const auto& focus_entry : audio_focus_stack_) { |
+ MediaSession::Get(focus_entry->web_contents())->Duck(); |
whywhat
2016/08/30 21:09:37
nit: a one-liner, remove the {}
|
+ } |
+ } else { |
+ for (const auto& focus_entry : audio_focus_stack_) { |
+ MediaSession* session = MediaSession::Get(focus_entry->web_contents()); |
+ if (session->IsActive()) |
whywhat
2016/08/30 21:09:37
can we have more than one active session at the ti
|
+ session->Suspend(MediaSession::SuspendType::SYSTEM); |
+ } |
+ } |
+ if (!audio_focus_stack_.empty()) { |
+ MediaSession::Get(audio_focus_stack_.back()->web_contents()) |
+ ->SetOnTop(false); |
whywhat
2016/08/30 21:09:37
SetOnTop sounds like a dirty hack
|
} |
- focus_entry_.reset( |
- new AudioFocusEntry(web_contents, this, AudioFocusType::Gain)); |
- MaybeStartDucking(); |
+ audio_focus_stack_.push_back(base::MakeUnique<AudioFocusEntry>( |
+ web_contents, this, type)); |
+ MediaSession::Get(audio_focus_stack_.back()->web_contents())->Unduck(); |
whywhat
2016/08/30 21:09:37
replace audio_focus_stack_.back()->web_contents()
|
+ MediaSession::Get(audio_focus_stack_.back()->web_contents())->SetOnTop(true); |
} |
-void AudioFocusManager::OnWebContentsDestroyed(WebContents* web_contents) { |
- AbandonAudioFocusInternal(web_contents); |
-} |
- |
-void AudioFocusManager::AbandonAudioFocusInternal(WebContents* web_contents) { |
- MaybeRemoveTransientEntry(web_contents); |
- MaybeRemoveFocusEntry(web_contents); |
-} |
+void AudioFocusManager::AbandonAudioFocus(MediaSession* media_session) { |
+ WebContents* web_contents = media_session->web_contents(); |
-void AudioFocusManager::MaybeStartDucking() const { |
- if (TransientMayDuckEntriesCount() != 1 || !focus_entry_) |
+ if (audio_focus_stack_.back()->web_contents() != web_contents) { |
+ MaybeRemoveFocusEntry(web_contents); |
return; |
+ } |
- // TODO(mlamouri): add StartDuck to MediaSession. |
- MediaSession::Get(focus_entry_->web_contents()) |
- ->SetVolumeMultiplier(kDuckingVolumeMultiplier); |
-} |
- |
-void AudioFocusManager::MaybeStopDucking() const { |
- if (TransientMayDuckEntriesCount() != 0 || !focus_entry_) |
+ MediaSession::Get(audio_focus_stack_.back()->web_contents())->SetOnTop(false); |
+ audio_focus_stack_.pop_back(); |
+ if (audio_focus_stack_.empty()) |
return; |
- // TODO(mlamouri): add StopDuck to MediaSession. |
- MediaSession::Get(focus_entry_->web_contents()) |
- ->SetVolumeMultiplier(kDefaultVolumeMultiplier); |
+ MediaSession::Get(audio_focus_stack_.back()->web_contents())->SetOnTop(true); |
+ // Only try to unduck the new MediaSession on top. The session might be still |
+ // inactive but it will not be resumed (so it does surprise the user). |
+ MediaSession::Get(audio_focus_stack_.back()->web_contents())->Unduck(); |
} |
-int AudioFocusManager::TransientMayDuckEntriesCount() const { |
- return transient_entries_.size(); |
-} |
+AudioFocusManager::AudioFocusManager() = default; |
-void AudioFocusManager::MaybeRemoveTransientEntry(WebContents* web_contents) { |
- transient_entries_.erase(web_contents); |
- MaybeStopDucking(); |
+AudioFocusManager::~AudioFocusManager() = default; |
+ |
+void AudioFocusManager::OnWebContentsDestroyed(WebContents* web_contents) { |
+ AbandonAudioFocus(MediaSession::Get(web_contents)); |
} |
void AudioFocusManager::MaybeRemoveFocusEntry(WebContents* web_contents) { |
- if (focus_entry_ && focus_entry_->web_contents() == web_contents) { |
- MediaSession::Get(focus_entry_->web_contents()) |
- ->SetVolumeMultiplier(kDefaultVolumeMultiplier); |
- focus_entry_.reset(); |
+ for (auto iter = audio_focus_stack_.begin(); iter != audio_focus_stack_.end(); |
+ ++iter) { |
+ if (web_contents == (*iter)->web_contents()) { |
+ audio_focus_stack_.erase(iter); |
whywhat
2016/08/30 21:09:37
Should you update OnTop in some cases?
|
+ return; |
+ } |
} |
} |