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 4ff3491de482542efe4781d46d153e896df8eef4..e92a2369f371f27226e4191b2cf8564b4f4860cd 100644 |
--- a/content/browser/media/session/audio_focus_manager.cc |
+++ b/content/browser/media/session/audio_focus_manager.cc |
@@ -4,6 +4,7 @@ |
#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" |
@@ -14,7 +15,8 @@ AudioFocusManager::AudioFocusEntry::AudioFocusEntry( |
AudioFocusManager* audio_focus_manager, |
AudioFocusType type) |
: WebContentsObserver(web_contents), |
- audio_focus_manager_(audio_focus_manager) {} |
+ audio_focus_manager_(audio_focus_manager), |
+ type_(type) {} |
AudioFocusManager::AudioFocusType |
AudioFocusManager::AudioFocusEntry::type() const { |
@@ -35,80 +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) |
whywhat
2016/09/07 20:09:54
nit: use {} as the condition statement doesn't fit
Zhiqiang Zhang (Slow)
2016/09/08 14:18:26
Done.
|
return; |
whywhat
2016/09/07 20:09:54
don't you need to check that the AudioFocusType is
Zhiqiang Zhang (Slow)
2016/09/08 14:18:26
Done.
|
- } |
- |
- 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())->StartDucking(); |
+ } |
+ } else { |
+ for (const auto& focus_entry : audio_focus_stack_) { |
+ MediaSession* session = MediaSession::Get(focus_entry->web_contents()); |
+ if (session->IsActive()) |
+ session->Suspend(MediaSession::SuspendType::SYSTEM); |
+ } |
+ } |
+ if (!audio_focus_stack_.empty()) { |
+ MediaSession::Get(audio_focus_stack_.back()->web_contents()) |
whywhat
2016/09/07 20:09:54
shouldn't Suspend or StartDucking do that? I feel
Zhiqiang Zhang (Slow)
2016/09/08 14:18:26
I'm renaming the flag `is_on_top_` to `allow_peppe
|
+ ->SetOnTop(false); |
} |
- focus_entry_.reset( |
- new AudioFocusEntry(web_contents, this, AudioFocusType::Gain)); |
- MaybeStartDucking(); |
-} |
- |
-void AudioFocusManager::OnWebContentsDestroyed(WebContents* web_contents) { |
- AbandonAudioFocusInternal(web_contents); |
+ audio_focus_stack_.push_back(base::MakeUnique<AudioFocusEntry>( |
+ web_contents, this, type)); |
+ MediaSession::Get(audio_focus_stack_.back()->web_contents())->StopDucking(); |
whywhat
2016/09/07 20:09:54
How do we know it's not suspended but ducking?
Zhiqiang Zhang (Slow)
2016/09/08 14:18:26
If it's suspended, then this will be no-op, since
|
+ MediaSession::Get(audio_focus_stack_.back()->web_contents())->SetOnTop(true); |
} |
-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; |
+ } |
- MediaSession::Get(focus_entry_->web_contents())->StartDucking(); |
-} |
- |
-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; |
- MediaSession::Get(focus_entry_->web_contents())->StopDucking(); |
+ 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())->StopDucking(); |
} |
-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())->StopDucking(); |
- 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); |
+ return; |
+ } |
} |
} |