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

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

Issue 2475473002: Implement one-shot audio focus inside MediaSession (Closed)
Patch Set: nits Created 4 years, 1 month 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/media_session_impl.h" 5 #include "content/browser/media/session/media_session_impl.h"
6 6
7 #include <algorithm>
7 #include "content/browser/media/session/audio_focus_delegate.h" 8 #include "content/browser/media/session/audio_focus_delegate.h"
8 #include "content/browser/media/session/media_session_player_observer.h" 9 #include "content/browser/media/session/media_session_player_observer.h"
9 #include "content/browser/media/session/media_session_service_impl.h" 10 #include "content/browser/media/session/media_session_service_impl.h"
10 #include "content/browser/web_contents/web_contents_impl.h" 11 #include "content/browser/web_contents/web_contents_impl.h"
11 #include "content/public/browser/media_session.h" 12 #include "content/public/browser/media_session.h"
12 #include "content/public/browser/media_session_observer.h" 13 #include "content/public/browser/media_session_observer.h"
13 #include "content/public/browser/web_contents.h" 14 #include "content/public/browser/web_contents.h"
14 #include "media/base/media_content_type.h" 15 #include "media/base/media_content_type.h"
15 16
16 #if defined(OS_ANDROID) 17 #if defined(OS_ANDROID)
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 MediaSessionImpl* session = FromWebContents(web_contents); 60 MediaSessionImpl* session = FromWebContents(web_contents);
60 if (!session) { 61 if (!session) {
61 CreateForWebContents(web_contents); 62 CreateForWebContents(web_contents);
62 session = FromWebContents(web_contents); 63 session = FromWebContents(web_contents);
63 session->Initialize(); 64 session->Initialize();
64 } 65 }
65 return session; 66 return session;
66 } 67 }
67 68
68 MediaSessionImpl::~MediaSessionImpl() { 69 MediaSessionImpl::~MediaSessionImpl() {
69 DCHECK(players_.empty()); 70 DCHECK(normal_players_.empty());
71 DCHECK(pepper_players_.empty());
72 DCHECK(one_shot_players_.empty());
70 DCHECK(audio_focus_state_ == State::INACTIVE); 73 DCHECK(audio_focus_state_ == State::INACTIVE);
71 for (auto& observer : observers_) 74 for (auto& observer : observers_)
72 observer.MediaSessionDestroyed(); 75 observer.MediaSessionDestroyed();
73 } 76 }
74 77
75 void MediaSessionImpl::WebContentsDestroyed() { 78 void MediaSessionImpl::WebContentsDestroyed() {
76 // This should only work for tests. In production, all the players should have 79 // This should only work for tests. In production, all the players should have
77 // already been removed before WebContents is destroyed. 80 // already been removed before WebContents is destroyed.
78 81
79 // TODO(zqzhang): refactor MediaSessionImpl, maybe move the interface used to 82 // TODO(zqzhang): refactor MediaSessionImpl, maybe move the interface used to
80 // talk with AudioFocusManager out to a seperate class. The AudioFocusManager 83 // talk with AudioFocusManager out to a seperate class. The AudioFocusManager
81 // unit tests then could mock the interface and abandon audio focus when 84 // unit tests then could mock the interface and abandon audio focus when
82 // WebContents is destroyed. See https://crbug.com/651069 85 // WebContents is destroyed. See https://crbug.com/651069
83 players_.clear(); 86 normal_players_.clear();
84 pepper_players_.clear(); 87 pepper_players_.clear();
88 one_shot_players_.clear();
85 AbandonSystemAudioFocusIfNeeded(); 89 AbandonSystemAudioFocusIfNeeded();
86 } 90 }
87 91
88 void MediaSessionImpl::SetMediaSessionService( 92 void MediaSessionImpl::SetMediaSessionService(
89 MediaSessionServiceImpl* service) { 93 MediaSessionServiceImpl* service) {
90 service_ = service; 94 service_ = service;
91 } 95 }
92 96
93 void MediaSessionImpl::AddObserver(MediaSessionObserver* observer) { 97 void MediaSessionImpl::AddObserver(MediaSessionObserver* observer) {
94 observers_.AddObserver(observer); 98 observers_.AddObserver(observer);
95 } 99 }
96 100
97 void MediaSessionImpl::RemoveObserver(MediaSessionObserver* observer) { 101 void MediaSessionImpl::RemoveObserver(MediaSessionObserver* observer) {
98 observers_.RemoveObserver(observer); 102 observers_.RemoveObserver(observer);
99 } 103 }
100 104
101 void MediaSessionImpl::SetMetadata( 105 void MediaSessionImpl::SetMetadata(
102 const base::Optional<MediaMetadata>& metadata) { 106 const base::Optional<MediaMetadata>& metadata) {
103 metadata_ = metadata; 107 metadata_ = metadata;
104 for (auto& observer : observers_) 108 for (auto& observer : observers_)
105 observer.MediaSessionMetadataChanged(metadata); 109 observer.MediaSessionMetadataChanged(metadata);
106 } 110 }
107 111
108 bool MediaSessionImpl::AddPlayer(MediaSessionPlayerObserver* observer, 112 bool MediaSessionImpl::AddPlayer(MediaSessionPlayerObserver* observer,
109 int player_id, 113 int player_id,
110 media::MediaContentType media_content_type) { 114 media::MediaContentType media_content_type) {
111 if (media_content_type == media::MediaContentType::Uncontrollable) 115 if (media_content_type == media::MediaContentType::OneShot)
112 return true; 116 return AddOneShotPlayer(observer, player_id);
113 if (media_content_type == media::MediaContentType::Pepper) 117 if (media_content_type == media::MediaContentType::Pepper)
114 return AddPepperPlayer(observer, player_id); 118 return AddPepperPlayer(observer, player_id);
115 119
116 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier()); 120 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier());
117 121
118 // Determine the audio focus type required for playing the new player.
119 // TODO(zqzhang): handle duckable and uncontrollable.
120 // See https://crbug.com/639277.
121 AudioFocusManager::AudioFocusType required_audio_focus_type; 122 AudioFocusManager::AudioFocusType required_audio_focus_type;
122 if (media_content_type == media::MediaContentType::Persistent) { 123 if (media_content_type == media::MediaContentType::Persistent) {
123 required_audio_focus_type = AudioFocusManager::AudioFocusType::Gain; 124 required_audio_focus_type = AudioFocusManager::AudioFocusType::Gain;
124 } else { 125 } else {
125 required_audio_focus_type = 126 required_audio_focus_type =
126 AudioFocusManager::AudioFocusType::GainTransientMayDuck; 127 AudioFocusManager::AudioFocusType::GainTransientMayDuck;
127 } 128 }
128 129
129 // If the audio focus is already granted and is of type Content, there is 130 // If the audio focus is already granted and is of type Content, there is
130 // nothing to do. If it is granted of type Transient the requested type is 131 // nothing to do. If it is granted of type Transient the requested type is
131 // also transient, there is also nothing to do. Otherwise, the session needs 132 // also transient, there is also nothing to do. Otherwise, the session needs
132 // to request audio focus again. 133 // to request audio focus again.
133 if (audio_focus_state_ == State::ACTIVE && 134 if (audio_focus_state_ == State::ACTIVE &&
134 (audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain || 135 (audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain ||
135 audio_focus_type_ == required_audio_focus_type)) { 136 audio_focus_type_ == required_audio_focus_type)) {
136 players_.insert(PlayerIdentifier(observer, player_id)); 137 normal_players_.insert(PlayerIdentifier(observer, player_id));
137 return true; 138 return true;
138 } 139 }
139 140
140 State old_audio_focus_state = audio_focus_state_; 141 State old_audio_focus_state = audio_focus_state_;
141 RequestSystemAudioFocus(required_audio_focus_type); 142 RequestSystemAudioFocus(required_audio_focus_type);
142 143
143 if (audio_focus_state_ != State::ACTIVE) 144 if (audio_focus_state_ != State::ACTIVE)
144 return false; 145 return false;
145 146
146 // The session should be reset if a player is starting while all players are 147 // The session should be reset if a player is starting while all players are
147 // suspended. 148 // suspended.
148 if (old_audio_focus_state != State::ACTIVE) 149 if (old_audio_focus_state != State::ACTIVE)
149 players_.clear(); 150 normal_players_.clear();
150 151
151 players_.insert(PlayerIdentifier(observer, player_id)); 152 normal_players_.insert(PlayerIdentifier(observer, player_id));
152 UpdateWebContents(); 153 NotifyAboutStateChange();
153 154
154 return true; 155 return true;
155 } 156 }
156 157
157 void MediaSessionImpl::RemovePlayer(MediaSessionPlayerObserver* observer, 158 void MediaSessionImpl::RemovePlayer(MediaSessionPlayerObserver* observer,
158 int player_id) { 159 int player_id) {
159 auto it = players_.find(PlayerIdentifier(observer, player_id)); 160 PlayerIdentifier identifier(observer, player_id);
160 if (it != players_.end())
161 players_.erase(it);
162 161
163 it = pepper_players_.find(PlayerIdentifier(observer, player_id)); 162 auto it = normal_players_.find(identifier);
163 if (it != normal_players_.end())
164 normal_players_.erase(it);
165
166 it = pepper_players_.find(identifier);
164 if (it != pepper_players_.end()) 167 if (it != pepper_players_.end())
165 pepper_players_.erase(it); 168 pepper_players_.erase(it);
166 169
170 it = one_shot_players_.find(identifier);
171 if (it != one_shot_players_.end()) {
172 one_shot_players_.erase(it);
173
174 // The session may become controllable after all one-shot players are
175 // removed.
176 if (one_shot_players_.empty())
177 NotifyAboutStateChange();
178 }
179
167 AbandonSystemAudioFocusIfNeeded(); 180 AbandonSystemAudioFocusIfNeeded();
168 } 181 }
169 182
170 void MediaSessionImpl::RemovePlayers(MediaSessionPlayerObserver* observer) { 183 void MediaSessionImpl::RemovePlayers(MediaSessionPlayerObserver* observer) {
171 for (auto it = players_.begin(); it != players_.end();) { 184 for (auto it = normal_players_.begin(); it != normal_players_.end();) {
172 if (it->observer == observer) 185 if (it->observer == observer)
173 players_.erase(it++); 186 normal_players_.erase(it++);
174 else 187 else
175 ++it; 188 ++it;
176 } 189 }
177 190
178 for (auto it = pepper_players_.begin(); it != pepper_players_.end();) { 191 for (auto it = pepper_players_.begin(); it != pepper_players_.end();) {
179 if (it->observer == observer) 192 if (it->observer == observer)
180 pepper_players_.erase(it++); 193 pepper_players_.erase(it++);
181 else 194 else
182 ++it; 195 ++it;
183 } 196 }
184 197
198 for (auto it = one_shot_players_.begin(); it != one_shot_players_.end();) {
199 if (it->observer == observer)
200 one_shot_players_.erase(it++);
201 else
202 ++it;
203
204 // The session may become controllable after all one-shot players are
205 // removed.
206 if (one_shot_players_.empty())
207 NotifyAboutStateChange();
208 }
209
185 AbandonSystemAudioFocusIfNeeded(); 210 AbandonSystemAudioFocusIfNeeded();
186 } 211 }
187 212
188 void MediaSessionImpl::RecordSessionDuck() { 213 void MediaSessionImpl::RecordSessionDuck() {
189 uma_helper_.RecordSessionSuspended( 214 uma_helper_.RecordSessionSuspended(
190 MediaSessionSuspendedSource::SystemTransientDuck); 215 MediaSessionSuspendedSource::SystemTransientDuck);
191 } 216 }
192 217
193 void MediaSessionImpl::OnPlayerPaused(MediaSessionPlayerObserver* observer, 218 void MediaSessionImpl::OnPlayerPaused(MediaSessionPlayerObserver* observer,
194 int player_id) { 219 int player_id) {
195 // If a playback is completed, BrowserMediaPlayerManager will call 220 // If a playback is completed, BrowserMediaPlayerManager will call
196 // OnPlayerPaused() after RemovePlayer(). This is a workaround. 221 // OnPlayerPaused() after RemovePlayer(). This is a workaround.
197 // Also, this method may be called when a player that is not added 222 // Also, this method may be called when a player that is not added
198 // to this session (e.g. a silent video) is paused. MediaSessionImpl 223 // to this session (e.g. a silent video) is paused. MediaSessionImpl
199 // should ignore the paused player for this case. 224 // should ignore the paused player for this case.
200 if (!players_.count(PlayerIdentifier(observer, player_id)) && 225 PlayerIdentifier identifier(observer, player_id);
201 !pepper_players_.count(PlayerIdentifier(observer, player_id))) { 226 if (!normal_players_.count(identifier) &&
227 !pepper_players_.count(identifier) &&
228 !one_shot_players_.count(identifier)) {
202 return; 229 return;
203 } 230 }
204 231
205 // If the player to be removed is a pepper player, or there is more than one 232 // If the player to be removed is a pepper player, or there is more than one
206 // observer, remove the paused one from the session. 233 // observer, remove the paused one from the session.
207 if (pepper_players_.count(PlayerIdentifier(observer, player_id)) || 234 if (pepper_players_.count(identifier) ||
208 players_.size() != 1) { 235 normal_players_.size() != 1) {
209 RemovePlayer(observer, player_id); 236 RemovePlayer(observer, player_id);
210 return; 237 return;
211 } 238 }
239
240 // If the player is a one-shot player, just remove it since it is not expected
241 // to resume a one-shot player via resuming MediaSession.
242 if (one_shot_players_.count(identifier)) {
243 RemovePlayer(observer, player_id);
244 return;
245 }
212 246
213 // Otherwise, suspend the session. 247 // Otherwise, suspend the session.
214 DCHECK(!IsSuspended()); 248 DCHECK(!IsSuspended());
215 OnSuspendInternal(SuspendType::CONTENT, State::SUSPENDED); 249 OnSuspendInternal(SuspendType::CONTENT, State::SUSPENDED);
216 } 250 }
217 251
218 void MediaSessionImpl::Resume(SuspendType suspend_type) { 252 void MediaSessionImpl::Resume(SuspendType suspend_type) {
219 DCHECK(IsReallySuspended()); 253 DCHECK(IsReallySuspended());
220 254
221 // When the resume requests comes from another source than system, audio focus 255 // When the resume requests comes from another source than system, audio focus
(...skipping 27 matching lines...) Expand all
249 // TODO(mlamouri): merge the logic between UI and SYSTEM. 283 // TODO(mlamouri): merge the logic between UI and SYSTEM.
250 if (suspend_type == SuspendType::SYSTEM) { 284 if (suspend_type == SuspendType::SYSTEM) {
251 OnSuspendInternal(suspend_type, State::INACTIVE); 285 OnSuspendInternal(suspend_type, State::INACTIVE);
252 return; 286 return;
253 } 287 }
254 288
255 if (audio_focus_state_ != State::SUSPENDED) 289 if (audio_focus_state_ != State::SUSPENDED)
256 OnSuspendInternal(suspend_type, State::SUSPENDED); 290 OnSuspendInternal(suspend_type, State::SUSPENDED);
257 291
258 DCHECK(audio_focus_state_ == State::SUSPENDED); 292 DCHECK(audio_focus_state_ == State::SUSPENDED);
259 players_.clear(); 293 normal_players_.clear();
260 294
261 AbandonSystemAudioFocusIfNeeded(); 295 AbandonSystemAudioFocusIfNeeded();
262 } 296 }
263 297
264 void MediaSessionImpl::DidReceiveAction( 298 void MediaSessionImpl::DidReceiveAction(
265 blink::mojom::MediaSessionAction action) { 299 blink::mojom::MediaSessionAction action) {
266 if (service_) 300 if (service_)
267 service_->GetClient()->DidReceiveAction(action); 301 service_->GetClient()->DidReceiveAction(action);
268 } 302 }
269 303
(...skipping 17 matching lines...) Expand all
287 } 321 }
288 322
289 void MediaSessionImpl::StopDucking() { 323 void MediaSessionImpl::StopDucking() {
290 if (!is_ducking_) 324 if (!is_ducking_)
291 return; 325 return;
292 is_ducking_ = false; 326 is_ducking_ = false;
293 UpdateVolumeMultiplier(); 327 UpdateVolumeMultiplier();
294 } 328 }
295 329
296 void MediaSessionImpl::UpdateVolumeMultiplier() { 330 void MediaSessionImpl::UpdateVolumeMultiplier() {
297 for (const auto& it : players_) 331 for (const auto& it : normal_players_)
298 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); 332 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier());
299 for (const auto& it : pepper_players_) 333 for (const auto& it : pepper_players_)
300 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); 334 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier());
301 } 335 }
302 336
303 double MediaSessionImpl::GetVolumeMultiplier() const { 337 double MediaSessionImpl::GetVolumeMultiplier() const {
304 return is_ducking_ ? kDuckingVolumeMultiplier : kDefaultVolumeMultiplier; 338 return is_ducking_ ? kDuckingVolumeMultiplier : kDefaultVolumeMultiplier;
305 } 339 }
306 340
307 bool MediaSessionImpl::IsActive() const { 341 bool MediaSessionImpl::IsActive() const {
308 return audio_focus_state_ == State::ACTIVE; 342 return audio_focus_state_ == State::ACTIVE;
309 } 343 }
310 344
311 bool MediaSessionImpl::IsReallySuspended() const { 345 bool MediaSessionImpl::IsReallySuspended() const {
312 return audio_focus_state_ == State::SUSPENDED; 346 return audio_focus_state_ == State::SUSPENDED;
313 } 347 }
314 348
315 bool MediaSessionImpl::IsSuspended() const { 349 bool MediaSessionImpl::IsSuspended() const {
316 // TODO(mlamouri): should be == State::SUSPENDED. 350 // TODO(mlamouri): should be == State::SUSPENDED.
317 return audio_focus_state_ != State::ACTIVE; 351 return audio_focus_state_ != State::ACTIVE;
318 } 352 }
319 353
320 bool MediaSessionImpl::IsControllable() const { 354 bool MediaSessionImpl::IsControllable() const {
321 // Only media session having focus Gain can be controllable unless it is 355 // Only media session having focus Gain can be controllable unless it is
322 // inactive. 356 // inactive. Also, the session will be uncontrollable if it contains one-shot
357 // players.
323 return audio_focus_state_ != State::INACTIVE && 358 return audio_focus_state_ != State::INACTIVE &&
324 audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain; 359 audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain &&
360 one_shot_players_.empty();
325 } 361 }
326 362
327 bool MediaSessionImpl::HasPepper() const { 363 bool MediaSessionImpl::HasPepper() const {
328 return !pepper_players_.empty(); 364 return !pepper_players_.empty();
329 } 365 }
330 366
331 std::unique_ptr<base::CallbackList<void(MediaSessionImpl::State)>::Subscription> 367 std::unique_ptr<base::CallbackList<void(MediaSessionImpl::State)>::Subscription>
332 MediaSessionImpl::RegisterMediaSessionStateChangedCallbackForTest( 368 MediaSessionImpl::RegisterMediaSessionStateChangedCallbackForTest(
333 const StateChangedCallback& cb) { 369 const StateChangedCallback& cb) {
334 return media_session_state_listeners_.Add(cb); 370 return media_session_state_listeners_.Add(cb);
335 } 371 }
336 372
337 void MediaSessionImpl::SetDelegateForTests( 373 void MediaSessionImpl::SetDelegateForTests(
338 std::unique_ptr<AudioFocusDelegate> delegate) { 374 std::unique_ptr<AudioFocusDelegate> delegate) {
339 delegate_ = std::move(delegate); 375 delegate_ = std::move(delegate);
340 } 376 }
341 377
342 bool MediaSessionImpl::IsActiveForTest() const { 378 bool MediaSessionImpl::IsActiveForTest() const {
343 return audio_focus_state_ == State::ACTIVE; 379 return audio_focus_state_ == State::ACTIVE;
344 } 380 }
345 381
346 MediaSessionUmaHelper* MediaSessionImpl::uma_helper_for_test() { 382 MediaSessionUmaHelper* MediaSessionImpl::uma_helper_for_test() {
347 return &uma_helper_; 383 return &uma_helper_;
348 } 384 }
349 385
350 void MediaSessionImpl::RemoveAllPlayersForTest() { 386 void MediaSessionImpl::RemoveAllPlayersForTest() {
351 players_.clear(); 387 normal_players_.clear();
388 pepper_players_.clear();
389 one_shot_players_.clear();
352 AbandonSystemAudioFocusIfNeeded(); 390 AbandonSystemAudioFocusIfNeeded();
353 } 391 }
354 392
355 void MediaSessionImpl::OnSuspendInternal(SuspendType suspend_type, 393 void MediaSessionImpl::OnSuspendInternal(SuspendType suspend_type,
356 State new_state) { 394 State new_state) {
357 DCHECK(!HasPepper()); 395 DCHECK(!HasPepper());
358 396
359 DCHECK(new_state == State::SUSPENDED || new_state == State::INACTIVE); 397 DCHECK(new_state == State::SUSPENDED || new_state == State::INACTIVE);
360 // UI suspend cannot use State::INACTIVE. 398 // UI suspend cannot use State::INACTIVE.
361 DCHECK(suspend_type == SuspendType::SYSTEM || new_state == State::SUSPENDED); 399 DCHECK(suspend_type == SuspendType::SYSTEM || new_state == State::SUSPENDED);
362 400
401 if (!one_shot_players_.empty())
402 return;
403
363 if (audio_focus_state_ != State::ACTIVE) 404 if (audio_focus_state_ != State::ACTIVE)
364 return; 405 return;
365 406
366 switch (suspend_type) { 407 switch (suspend_type) {
367 case SuspendType::UI: 408 case SuspendType::UI:
368 uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::UI); 409 uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::UI);
369 break; 410 break;
370 case SuspendType::SYSTEM: 411 case SuspendType::SYSTEM:
371 switch (new_state) { 412 switch (new_state) {
372 case State::SUSPENDED: 413 case State::SUSPENDED:
(...skipping 14 matching lines...) Expand all
387 break; 428 break;
388 } 429 }
389 430
390 SetAudioFocusState(new_state); 431 SetAudioFocusState(new_state);
391 suspend_type_ = suspend_type; 432 suspend_type_ = suspend_type;
392 433
393 if (suspend_type != SuspendType::CONTENT) { 434 if (suspend_type != SuspendType::CONTENT) {
394 // SuspendType::CONTENT happens when the suspend action came from 435 // SuspendType::CONTENT happens when the suspend action came from
395 // the page in which case the player is already paused. 436 // the page in which case the player is already paused.
396 // Otherwise, the players need to be paused. 437 // Otherwise, the players need to be paused.
397 for (const auto& it : players_) 438 for (const auto& it : normal_players_)
398 it.observer->OnSuspend(it.player_id); 439 it.observer->OnSuspend(it.player_id);
399 } 440 }
400 441
401 for (const auto& it : pepper_players_) 442 for (const auto& it : pepper_players_)
402 it.observer->OnSetVolumeMultiplier(it.player_id, kDuckingVolumeMultiplier); 443 it.observer->OnSetVolumeMultiplier(it.player_id, kDuckingVolumeMultiplier);
403 444
404 UpdateWebContents(); 445 NotifyAboutStateChange();
405 } 446 }
406 447
407 void MediaSessionImpl::OnResumeInternal(SuspendType suspend_type) { 448 void MediaSessionImpl::OnResumeInternal(SuspendType suspend_type) {
408 if (suspend_type == SuspendType::SYSTEM && suspend_type_ != suspend_type) 449 if (suspend_type == SuspendType::SYSTEM && suspend_type_ != suspend_type)
409 return; 450 return;
410 451
411 SetAudioFocusState(State::ACTIVE); 452 SetAudioFocusState(State::ACTIVE);
412 453
413 for (const auto& it : players_) 454 for (const auto& it : normal_players_)
414 it.observer->OnResume(it.player_id); 455 it.observer->OnResume(it.player_id);
415 456
416 for (const auto& it : pepper_players_) 457 for (const auto& it : pepper_players_)
417 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); 458 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier());
418 459
419 UpdateWebContents(); 460 NotifyAboutStateChange();
420 } 461 }
421 462
422 MediaSessionImpl::MediaSessionImpl(WebContents* web_contents) 463 MediaSessionImpl::MediaSessionImpl(WebContents* web_contents)
423 : WebContentsObserver(web_contents), 464 : WebContentsObserver(web_contents),
424 audio_focus_state_(State::INACTIVE), 465 audio_focus_state_(State::INACTIVE),
425 audio_focus_type_( 466 audio_focus_type_(
426 AudioFocusManager::AudioFocusType::GainTransientMayDuck), 467 AudioFocusManager::AudioFocusType::GainTransientMayDuck),
427 is_ducking_(false), 468 is_ducking_(false),
428 service_(nullptr) { 469 service_(nullptr) {
429 #if defined(OS_ANDROID) 470 #if defined(OS_ANDROID)
(...skipping 11 matching lines...) Expand all
441 uma_helper_.RecordRequestAudioFocusResult(result); 482 uma_helper_.RecordRequestAudioFocusResult(result);
442 483
443 // MediaSessionImpl must change its state & audio focus type AFTER requesting 484 // MediaSessionImpl must change its state & audio focus type AFTER requesting
444 // audio focus. 485 // audio focus.
445 SetAudioFocusState(result ? State::ACTIVE : State::INACTIVE); 486 SetAudioFocusState(result ? State::ACTIVE : State::INACTIVE);
446 audio_focus_type_ = audio_focus_type; 487 audio_focus_type_ = audio_focus_type;
447 return result; 488 return result;
448 } 489 }
449 490
450 void MediaSessionImpl::AbandonSystemAudioFocusIfNeeded() { 491 void MediaSessionImpl::AbandonSystemAudioFocusIfNeeded() {
451 if (audio_focus_state_ == State::INACTIVE || !players_.empty() || 492 if (audio_focus_state_ == State::INACTIVE || !normal_players_.empty() ||
452 !pepper_players_.empty()) { 493 !pepper_players_.empty() || !one_shot_players_.empty()) {
453 return; 494 return;
454 } 495 }
455 delegate_->AbandonAudioFocus(); 496 delegate_->AbandonAudioFocus();
456 497
457 SetAudioFocusState(State::INACTIVE); 498 SetAudioFocusState(State::INACTIVE);
458 UpdateWebContents(); 499 NotifyAboutStateChange();
459 } 500 }
460 501
461 void MediaSessionImpl::UpdateWebContents() { 502 void MediaSessionImpl::NotifyAboutStateChange() {
462 media_session_state_listeners_.Notify(audio_focus_state_); 503 media_session_state_listeners_.Notify(audio_focus_state_);
463 for (auto& observer : observers_) 504 for (auto& observer : observers_)
464 observer.MediaSessionStateChanged(IsControllable(), IsSuspended()); 505 observer.MediaSessionStateChanged(IsControllable(), IsSuspended());
465 } 506 }
466 507
467 void MediaSessionImpl::SetAudioFocusState(State audio_focus_state) { 508 void MediaSessionImpl::SetAudioFocusState(State audio_focus_state) {
468 if (audio_focus_state == audio_focus_state_) 509 if (audio_focus_state == audio_focus_state_)
469 return; 510 return;
470 511
471 audio_focus_state_ = audio_focus_state; 512 audio_focus_state_ = audio_focus_state;
(...skipping 13 matching lines...) Expand all
485 bool MediaSessionImpl::AddPepperPlayer(MediaSessionPlayerObserver* observer, 526 bool MediaSessionImpl::AddPepperPlayer(MediaSessionPlayerObserver* observer,
486 int player_id) { 527 int player_id) {
487 bool success = 528 bool success =
488 RequestSystemAudioFocus(AudioFocusManager::AudioFocusType::Gain); 529 RequestSystemAudioFocus(AudioFocusManager::AudioFocusType::Gain);
489 DCHECK(success); 530 DCHECK(success);
490 531
491 pepper_players_.insert(PlayerIdentifier(observer, player_id)); 532 pepper_players_.insert(PlayerIdentifier(observer, player_id));
492 533
493 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier()); 534 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier());
494 535
536 NotifyAboutStateChange();
537 return success;
538 }
539
540 bool MediaSessionImpl::AddOneShotPlayer(MediaSessionPlayerObserver* observer,
541 int player_id) {
542 if (!RequestSystemAudioFocus(AudioFocusManager::AudioFocusType::Gain))
543 return false;
544
545 one_shot_players_.insert(PlayerIdentifier(observer, player_id));
546 NotifyAboutStateChange();
547
495 return true; 548 return true;
496 } 549 }
497 550
498 } // namespace content 551 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698