Chromium Code Reviews

Side by Side Diff: content/browser/media/session/audio_focus_manager.cc

Issue 2382723006: Revert of Letting Flash join MediaSession (stack implementaion) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@media_session_type
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/media/session/audio_focus_manager.h" 5 #include "content/browser/media/session/audio_focus_manager.h"
6 6
7 #include "base/memory/ptr_util.h"
8 #include "content/browser/media/session/media_session.h" 7 #include "content/browser/media/session/media_session.h"
9 #include "content/public/browser/web_contents.h" 8 #include "content/public/browser/web_contents.h"
10 9
11 namespace content { 10 namespace content {
12 11
12 AudioFocusManager::AudioFocusEntry::AudioFocusEntry(
13 WebContents* web_contents,
14 AudioFocusManager* audio_focus_manager,
15 AudioFocusType type)
16 : WebContentsObserver(web_contents),
17 audio_focus_manager_(audio_focus_manager) {}
18
19 AudioFocusManager::AudioFocusType
20 AudioFocusManager::AudioFocusEntry::type() const {
21 return type_;
22 }
23
24 void AudioFocusManager::AudioFocusEntry::WebContentsDestroyed() {
25 audio_focus_manager_->OnWebContentsDestroyed(web_contents());
26 // |this| will be destroyed now.
27 }
28
13 // static 29 // static
14 AudioFocusManager* AudioFocusManager::GetInstance() { 30 AudioFocusManager* AudioFocusManager::GetInstance() {
15 return base::Singleton<AudioFocusManager>::get(); 31 return base::Singleton<AudioFocusManager>::get();
16 } 32 }
17 33
18 void AudioFocusManager::RequestAudioFocus(MediaSession* media_session, 34 void AudioFocusManager::RequestAudioFocus(MediaSession* media_session,
19 AudioFocusType type) { 35 AudioFocusType type) {
20 if (!audio_focus_stack_.empty() && 36 WebContents* web_contents = media_session->web_contents();
21 audio_focus_stack_.back() == media_session && 37
22 audio_focus_stack_.back()->audio_focus_type() == type && 38 if (type == AudioFocusType::GainTransientMayDuck) {
23 audio_focus_stack_.back()->IsActive()) { 39 MaybeRemoveFocusEntry(web_contents);
24 // Early returning if |media_session| is already on top (has focus) and is 40 transient_entries_[web_contents].reset(
25 // active. 41 new AudioFocusEntry(web_contents, this, type));
42 MaybeStartDucking();
26 return; 43 return;
27 } 44 }
28 45
29 MaybeRemoveFocusEntry(media_session); 46 DCHECK(type == AudioFocusType::Gain);
30 47 RequestAudioFocusGain(web_contents);
31 // TODO(zqzhang): It seems like MediaSession is exposed to AudioFocusManager
32 // too much. Maybe it's better to do some abstraction and refactoring to clean
33 // up the relation between AudioFocusManager and MediaSession.
34 // See https://crbug.com/651069
35 if (type == AudioFocusType::GainTransientMayDuck) {
36 for (const auto old_session : audio_focus_stack_) {
37 old_session->StartDucking();
38 }
39 } else {
40 for (const auto old_session : audio_focus_stack_) {
41 if (old_session->IsActive()) {
42 if (old_session->HasPepper())
43 old_session->StartDucking();
44 else
45 old_session->Suspend(MediaSession::SuspendType::SYSTEM);
46 }
47 }
48 }
49
50 audio_focus_stack_.push_back(media_session);
51 audio_focus_stack_.back()->StopDucking();
52 } 48 }
53 49
54 void AudioFocusManager::AbandonAudioFocus(MediaSession* media_session) { 50 void AudioFocusManager::AbandonAudioFocus(MediaSession* media_session) {
55 if (audio_focus_stack_.empty()) 51 AbandonAudioFocusInternal(media_session->web_contents());
56 return;
57
58 if (audio_focus_stack_.back() != media_session) {
59 MaybeRemoveFocusEntry(media_session);
60 return;
61 }
62
63 audio_focus_stack_.pop_back();
64 if (audio_focus_stack_.empty())
65 return;
66
67 // Allow the top-most MediaSession having Pepper to unduck pepper even if it's
68 // not active.
69 for (auto iter = audio_focus_stack_.rbegin();
70 iter != audio_focus_stack_.rend(); ++iter) {
71 if (!(*iter)->HasPepper())
72 continue;
73
74 MediaSession* pepper_session = *iter;
75 pepper_session->StopDucking();
76 MaybeRemoveFocusEntry(pepper_session);
77 audio_focus_stack_.push_back(pepper_session);
78 return;
79 }
80 // Only try to unduck the new MediaSession on top. The session might be still
81 // inactive but it will not be resumed (so it doesn't surprise the user).
82 audio_focus_stack_.back()->StopDucking();
83 } 52 }
84 53
85 AudioFocusManager::AudioFocusManager() = default; 54 AudioFocusManager::AudioFocusManager() = default;
86 55
87 AudioFocusManager::~AudioFocusManager() = default; 56 AudioFocusManager::~AudioFocusManager() = default;
88 57
89 void AudioFocusManager::MaybeRemoveFocusEntry(MediaSession* media_session) { 58 void AudioFocusManager::RequestAudioFocusGain(WebContents* web_contents) {
90 audio_focus_stack_.remove(media_session); 59 MaybeRemoveTransientEntry(web_contents);
60
61 if (focus_entry_) {
62 if (focus_entry_->web_contents() == web_contents)
63 return;
64
65 MediaSession* other_session =
66 MediaSession::Get(focus_entry_->web_contents());
67 if (other_session->IsActive())
68 other_session->Suspend(MediaSession::SuspendType::SYSTEM);
69 }
70
71 focus_entry_.reset(
72 new AudioFocusEntry(web_contents, this, AudioFocusType::Gain));
73 MaybeStartDucking();
74 }
75
76 void AudioFocusManager::OnWebContentsDestroyed(WebContents* web_contents) {
77 AbandonAudioFocusInternal(web_contents);
78 }
79
80 void AudioFocusManager::AbandonAudioFocusInternal(WebContents* web_contents) {
81 MaybeRemoveTransientEntry(web_contents);
82 MaybeRemoveFocusEntry(web_contents);
83 }
84
85 void AudioFocusManager::MaybeStartDucking() const {
86 if (TransientMayDuckEntriesCount() != 1 || !focus_entry_)
87 return;
88
89 MediaSession::Get(focus_entry_->web_contents())->StartDucking();
90 }
91
92 void AudioFocusManager::MaybeStopDucking() const {
93 if (TransientMayDuckEntriesCount() != 0 || !focus_entry_)
94 return;
95
96 MediaSession::Get(focus_entry_->web_contents())->StopDucking();
97 }
98
99 int AudioFocusManager::TransientMayDuckEntriesCount() const {
100 return transient_entries_.size();
101 }
102
103 void AudioFocusManager::MaybeRemoveTransientEntry(WebContents* web_contents) {
104 transient_entries_.erase(web_contents);
105 MaybeStopDucking();
106 }
107
108 void AudioFocusManager::MaybeRemoveFocusEntry(WebContents* web_contents) {
109 if (focus_entry_ && focus_entry_->web_contents() == web_contents) {
110 MediaSession::Get(focus_entry_->web_contents())->StopDucking();
111 focus_entry_.reset();
112 }
91 } 113 }
92 114
93 } // namespace content 115 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/media/session/audio_focus_manager.h ('k') | content/browser/media/session/audio_focus_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine