Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

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

Issue 2274873003: Letting Flash join MediaSession (stack implementaion) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@media_session_type
Patch Set: fixed existing tests (need new tests when behavior is decided) Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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"
7 #include "content/browser/media/session/media_session.h" 8 #include "content/browser/media/session/media_session.h"
8 #include "content/public/browser/web_contents.h" 9 #include "content/public/browser/web_contents.h"
9 10
10 namespace content { 11 namespace content {
11 12
12 AudioFocusManager::AudioFocusEntry::AudioFocusEntry( 13 AudioFocusManager::AudioFocusEntry::AudioFocusEntry(
13 WebContents* web_contents, 14 WebContents* web_contents,
14 AudioFocusManager* audio_focus_manager, 15 AudioFocusManager* audio_focus_manager,
15 AudioFocusType type) 16 AudioFocusType type)
16 : WebContentsObserver(web_contents), 17 : WebContentsObserver(web_contents),
17 audio_focus_manager_(audio_focus_manager) {} 18 audio_focus_manager_(audio_focus_manager),
19 type_(type) {}
18 20
19 AudioFocusManager::AudioFocusType 21 AudioFocusManager::AudioFocusType
20 AudioFocusManager::AudioFocusEntry::type() const { 22 AudioFocusManager::AudioFocusEntry::type() const {
21 return type_; 23 return type_;
22 } 24 }
23 25
26 MediaSession* AudioFocusManager::AudioFocusEntry::ToMediaSession() const {
27 return MediaSession::Get(web_contents());
28 }
29
24 void AudioFocusManager::AudioFocusEntry::WebContentsDestroyed() { 30 void AudioFocusManager::AudioFocusEntry::WebContentsDestroyed() {
25 audio_focus_manager_->OnWebContentsDestroyed(web_contents()); 31 audio_focus_manager_->OnWebContentsDestroyed(web_contents());
26 // |this| will be destroyed now. 32 // |this| will be destroyed now.
27 } 33 }
28 34
29 // static 35 // static
30 AudioFocusManager* AudioFocusManager::GetInstance() { 36 AudioFocusManager* AudioFocusManager::GetInstance() {
31 return base::Singleton<AudioFocusManager>::get(); 37 return base::Singleton<AudioFocusManager>::get();
32 } 38 }
33 39
34 void AudioFocusManager::RequestAudioFocus(MediaSession* media_session, 40 void AudioFocusManager::RequestAudioFocus(MediaSession* media_session,
35 AudioFocusType type) { 41 AudioFocusType type) {
36 WebContents* web_contents = media_session->web_contents(); 42 WebContents* web_contents = media_session->web_contents();
37 43
38 if (type == AudioFocusType::GainTransientMayDuck) { 44 if (!audio_focus_stack_.empty() &&
39 MaybeRemoveFocusEntry(web_contents); 45 audio_focus_stack_.back()->web_contents() == web_contents &&
40 transient_entries_[web_contents].reset( 46 audio_focus_stack_.back()->type() == type &&
41 new AudioFocusEntry(web_contents, this, type)); 47 audio_focus_stack_.back()->ToMediaSession()->IsActive()) {
42 MaybeStartDucking();
43 return; 48 return;
whywhat 2016/09/13 00:16:17 nit: a comment explaining why this is an early ret
Zhiqiang Zhang (Slow) 2016/09/22 12:30:33 Done.
44 } 49 }
45 50
46 DCHECK(type == AudioFocusType::Gain); 51 MaybeRemoveFocusEntry(web_contents);
47 RequestAudioFocusGain(web_contents); 52
53 if (type == AudioFocusType::GainTransientMayDuck) {
whywhat 2016/09/13 00:16:17 I wonder if this logic could be moved into AudioFo
Zhiqiang Zhang (Slow) 2016/09/22 12:30:32 Yeah, no Pepper magic now. AudioFocusManager check
54 for (const auto& focus_entry : audio_focus_stack_) {
55 focus_entry->ToMediaSession()->StartDucking();
56 }
57 } else {
58 for (const auto& focus_entry : audio_focus_stack_) {
59 MediaSession* session = focus_entry->ToMediaSession();
60 if (session->IsActive())
61 session->Suspend(MediaSession::SuspendType::SYSTEM);
62 session->DisallowPepperOverrideDucking();
63 }
64 }
65
66 audio_focus_stack_.push_back(base::MakeUnique<AudioFocusEntry>(
67 web_contents, this, type));
68 audio_focus_stack_.back()->ToMediaSession()->StopDucking();
whywhat 2016/09/13 00:16:16 Seems like this could just be done in MediaSession
Zhiqiang Zhang (Slow) 2016/09/22 12:30:33 Hmm, probably. However, since all the StartDucking
whywhat 2016/09/27 17:54:16 I disagree here. Incapsulation is the power of OOP
69 audio_focus_stack_.back()->ToMediaSession()->AllowPepperOverrideDucking();
48 } 70 }
49 71
50 void AudioFocusManager::AbandonAudioFocus(MediaSession* media_session) { 72 void AudioFocusManager::AbandonAudioFocus(MediaSession* media_session) {
51 AbandonAudioFocusInternal(media_session->web_contents()); 73 WebContents* web_contents = media_session->web_contents();
74
75 if (audio_focus_stack_.empty())
76 return;
77
78 if (audio_focus_stack_.back()->web_contents() != web_contents) {
79 MaybeRemoveFocusEntry(web_contents);
whywhat 2016/09/13 00:16:17 wouldn't session know it doesn't have focus anymor
Zhiqiang Zhang (Slow) 2016/09/22 12:30:33 Yes, the session knows it doesn't have focus anymo
80 return;
81 }
82
83 audio_focus_stack_.back()->ToMediaSession()->DisallowPepperOverrideDucking();
whywhat 2016/09/13 00:16:16 nit: Something the media session itself can do aft
Zhiqiang Zhang (Slow) 2016/09/22 12:30:33 No special magic for Pepper now. AudioFocusManager
84 audio_focus_stack_.pop_back();
85 if (audio_focus_stack_.empty())
86 return;
87
88 // Allow the top-most MediaSession having Pepper to unduck pepper event it's
whywhat 2016/09/13 00:16:16 nit: the sentence is hard to parse, should it be s
Zhiqiang Zhang (Slow) 2016/09/14 19:30:19 OK, I agree with you now, seems like we should con
89 // not active.
90 for (auto iter = audio_focus_stack_.rbegin();
91 iter != audio_focus_stack_.rend(); ++iter) {
92 if ((*iter)->ToMediaSession()->HasPepper()) {
93 (*iter)->ToMediaSession()->AllowPepperOverrideDucking();
94 break;
95 }
96 }
97 // Only try to unduck the new MediaSession on top. The session might be still
98 // inactive but it will not be resumed (so it does surprise the user).
whywhat 2016/09/13 00:16:16 s/does/doesn't?
Zhiqiang Zhang (Slow) 2016/09/22 12:30:32 Done.
99 audio_focus_stack_.back()->ToMediaSession()->StopDucking();
52 } 100 }
53 101
54 AudioFocusManager::AudioFocusManager() = default; 102 AudioFocusManager::AudioFocusManager() = default;
55 103
56 AudioFocusManager::~AudioFocusManager() = default; 104 AudioFocusManager::~AudioFocusManager() = default;
57 105
58 void AudioFocusManager::RequestAudioFocusGain(WebContents* web_contents) {
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) { 106 void AudioFocusManager::OnWebContentsDestroyed(WebContents* web_contents) {
77 AbandonAudioFocusInternal(web_contents); 107 AbandonAudioFocus(MediaSession::Get(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 } 108 }
107 109
108 void AudioFocusManager::MaybeRemoveFocusEntry(WebContents* web_contents) { 110 void AudioFocusManager::MaybeRemoveFocusEntry(WebContents* web_contents) {
109 if (focus_entry_ && focus_entry_->web_contents() == web_contents) { 111 for (auto iter = audio_focus_stack_.begin(); iter != audio_focus_stack_.end();
110 MediaSession::Get(focus_entry_->web_contents())->StopDucking(); 112 ++iter) {
111 focus_entry_.reset(); 113 if (web_contents == (*iter)->web_contents()) {
114 audio_focus_stack_.erase(iter);
115 return;
116 }
112 } 117 }
113 } 118 }
114 119
115 } // namespace content 120 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698