OLD | NEW |
---|---|
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.h" | 5 #include "content/browser/media/session/media_session.h" |
6 | 6 |
7 #include "content/browser/media/session/media_session_delegate.h" | 7 #include "content/browser/media/session/media_session_delegate.h" |
8 #include "content/browser/media/session/media_session_observer.h" | 8 #include "content/browser/media/session/media_session_observer.h" |
9 #include "content/browser/web_contents/web_contents_impl.h" | 9 #include "content/browser/web_contents/web_contents_impl.h" |
10 #include "content/public/browser/web_contents.h" | 10 #include "content/public/browser/web_contents.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 session->Initialize(); | 53 session->Initialize(); |
54 } | 54 } |
55 return session; | 55 return session; |
56 } | 56 } |
57 | 57 |
58 MediaSession::~MediaSession() { | 58 MediaSession::~MediaSession() { |
59 DCHECK(players_.empty()); | 59 DCHECK(players_.empty()); |
60 DCHECK(audio_focus_state_ == State::INACTIVE); | 60 DCHECK(audio_focus_state_ == State::INACTIVE); |
61 } | 61 } |
62 | 62 |
63 void MediaSession::WasShown() { | |
64 if (IsSuspended()) | |
65 RequestSystemAudioFocus(audio_focus_type_); | |
66 } | |
67 | |
63 void MediaSession::SetMetadata(const base::Optional<MediaMetadata>& metadata) { | 68 void MediaSession::SetMetadata(const base::Optional<MediaMetadata>& metadata) { |
64 metadata_ = metadata; | 69 metadata_ = metadata; |
65 // TODO(zqzhang): On Android, the metadata is sent though JNI everytime the | 70 // TODO(zqzhang): On Android, the metadata is sent though JNI everytime the |
66 // media session play/pause state changes. Need to find a way to seprate the | 71 // media session play/pause state changes. Need to find a way to seprate the |
67 // state change and Metadata update. See https://crbug.com/621855. | 72 // state change and Metadata update. See https://crbug.com/621855. |
68 static_cast<WebContentsImpl*>(web_contents())->OnMediaSessionStateChanged(); | 73 static_cast<WebContentsImpl*>(web_contents())->OnMediaSessionStateChanged(); |
69 } | 74 } |
70 | 75 |
71 bool MediaSession::AddPlayer(MediaSessionObserver* observer, | 76 bool MediaSession::AddPlayer(MediaSessionObserver* observer, |
72 int player_id, | 77 int player_id, |
73 media::MediaContentType media_content_type) { | 78 media::MediaContentType media_content_type) { |
79 if (media_content_type == media::MediaContentType::Pepper) | |
80 return AddPepperPlayer(observer, player_id); | |
81 | |
74 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier()); | 82 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier()); |
75 | 83 |
76 // Determine the audio focus type required for playing the new player. | 84 // Determine the audio focus type required for playing the new player. |
77 // TODO(zqzhang): handle duckable and uncontrollable. | 85 // TODO(zqzhang): handle duckable and uncontrollable. |
78 // See https://crbug.com/639277. | 86 // See https://crbug.com/639277. |
79 AudioFocusManager::AudioFocusType required_audio_focus_type; | 87 AudioFocusManager::AudioFocusType required_audio_focus_type; |
80 if (media_content_type == media::MediaContentType::Persistent) { | 88 if (media_content_type == media::MediaContentType::Persistent) { |
81 required_audio_focus_type = AudioFocusManager::AudioFocusType::Gain; | 89 required_audio_focus_type = AudioFocusManager::AudioFocusType::Gain; |
82 } else { | 90 } else { |
83 required_audio_focus_type = | 91 required_audio_focus_type = |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 | 123 |
116 return true; | 124 return true; |
117 } | 125 } |
118 | 126 |
119 void MediaSession::RemovePlayer(MediaSessionObserver* observer, | 127 void MediaSession::RemovePlayer(MediaSessionObserver* observer, |
120 int player_id) { | 128 int player_id) { |
121 auto it = players_.find(PlayerIdentifier(observer, player_id)); | 129 auto it = players_.find(PlayerIdentifier(observer, player_id)); |
122 if (it != players_.end()) | 130 if (it != players_.end()) |
123 players_.erase(it); | 131 players_.erase(it); |
124 | 132 |
133 it = pepper_players_.find(PlayerIdentifier(observer, player_id)); | |
134 if (it != pepper_players_.end()) | |
135 pepper_players_.erase(it); | |
136 | |
125 AbandonSystemAudioFocusIfNeeded(); | 137 AbandonSystemAudioFocusIfNeeded(); |
126 } | 138 } |
127 | 139 |
128 void MediaSession::RemovePlayers(MediaSessionObserver* observer) { | 140 void MediaSession::RemovePlayers(MediaSessionObserver* observer) { |
129 for (auto it = players_.begin(); it != players_.end();) { | 141 for (auto it = players_.begin(); it != players_.end(); ) { |
130 if (it->observer == observer) | 142 if (it->observer == observer) |
131 players_.erase(it++); | 143 players_.erase(it++); |
132 else | 144 else |
133 ++it; | 145 ++it; |
134 } | 146 } |
135 | 147 |
148 for (auto it = pepper_players_.begin(); it != pepper_players_.end(); ) { | |
149 if (it->observer == observer) | |
150 pepper_players_.erase(it++); | |
151 else | |
152 ++it; | |
153 } | |
154 | |
136 AbandonSystemAudioFocusIfNeeded(); | 155 AbandonSystemAudioFocusIfNeeded(); |
137 } | 156 } |
138 | 157 |
139 void MediaSession::RecordSessionDuck() { | 158 void MediaSession::RecordSessionDuck() { |
140 uma_helper_.RecordSessionSuspended( | 159 uma_helper_.RecordSessionSuspended( |
141 MediaSessionSuspendedSource::SystemTransientDuck); | 160 MediaSessionSuspendedSource::SystemTransientDuck); |
142 } | 161 } |
143 | 162 |
144 void MediaSession::OnPlayerPaused(MediaSessionObserver* observer, | 163 void MediaSession::OnPlayerPaused(MediaSessionObserver* observer, |
145 int player_id) { | 164 int player_id) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 if (suspend_type == SuspendType::SYSTEM) { | 216 if (suspend_type == SuspendType::SYSTEM) { |
198 OnSuspendInternal(suspend_type, State::INACTIVE); | 217 OnSuspendInternal(suspend_type, State::INACTIVE); |
199 return; | 218 return; |
200 } | 219 } |
201 | 220 |
202 if (audio_focus_state_ != State::SUSPENDED) | 221 if (audio_focus_state_ != State::SUSPENDED) |
203 OnSuspendInternal(suspend_type, State::SUSPENDED); | 222 OnSuspendInternal(suspend_type, State::SUSPENDED); |
204 | 223 |
205 DCHECK(audio_focus_state_ == State::SUSPENDED); | 224 DCHECK(audio_focus_state_ == State::SUSPENDED); |
206 players_.clear(); | 225 players_.clear(); |
226 | |
227 for (const auto& it : pepper_players_) { | |
228 it.observer->OnSetVolumeMultiplier( | |
229 it.player_id, GetPepperVolumeMultiplier()); | |
230 } | |
231 | |
207 AbandonSystemAudioFocusIfNeeded(); | 232 AbandonSystemAudioFocusIfNeeded(); |
208 } | 233 } |
209 | 234 |
210 void MediaSession::StartDucking() { | 235 void MediaSession::StartDucking() { |
211 if (is_ducking_) | 236 if (is_ducking_) |
212 return; | 237 return; |
213 is_ducking_ = true; | 238 is_ducking_ = true; |
214 UpdateVolumeMultiplier(); | 239 UpdateVolumeMultiplier(); |
215 } | 240 } |
216 | 241 |
217 void MediaSession::StopDucking() { | 242 void MediaSession::StopDucking() { |
218 if (!is_ducking_) | 243 if (!is_ducking_) |
219 return; | 244 return; |
220 is_ducking_ = false; | 245 is_ducking_ = false; |
221 UpdateVolumeMultiplier(); | 246 UpdateVolumeMultiplier(); |
222 } | 247 } |
223 | 248 |
224 void MediaSession::UpdateVolumeMultiplier() { | 249 void MediaSession::UpdateVolumeMultiplier() { |
225 for (const auto& it : players_) | 250 for (const auto& it : players_) |
226 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); | 251 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); |
227 } | 252 } |
228 | 253 |
229 double MediaSession::GetVolumeMultiplier() const { | 254 double MediaSession::GetVolumeMultiplier() const { |
230 return is_ducking_ ? kDuckingVolumeMultiplier : kDefaultVolumeMultiplier; | 255 return is_ducking_ ? kDuckingVolumeMultiplier : kDefaultVolumeMultiplier; |
231 } | 256 } |
232 | 257 |
258 double MediaSession::GetPepperVolumeMultiplier() const { | |
259 if (is_ducking_) | |
260 return kDuckingVolumeMultiplier; | |
261 if (!IsActive() && !allow_pepper_override_ducking_) | |
262 return kDuckingVolumeMultiplier; | |
263 return kDefaultVolumeMultiplier; | |
264 } | |
265 | |
233 bool MediaSession::IsActive() const { | 266 bool MediaSession::IsActive() const { |
234 return audio_focus_state_ == State::ACTIVE; | 267 return audio_focus_state_ == State::ACTIVE; |
235 } | 268 } |
236 | 269 |
237 bool MediaSession::IsReallySuspended() const { | 270 bool MediaSession::IsReallySuspended() const { |
238 return audio_focus_state_ == State::SUSPENDED; | 271 return audio_focus_state_ == State::SUSPENDED; |
239 } | 272 } |
240 | 273 |
241 bool MediaSession::IsSuspended() const { | 274 bool MediaSession::IsSuspended() const { |
242 // TODO(mlamouri): should be == State::SUSPENDED. | 275 // TODO(mlamouri): should be == State::SUSPENDED. |
243 return audio_focus_state_ != State::ACTIVE; | 276 return audio_focus_state_ != State::ACTIVE; |
244 } | 277 } |
245 | 278 |
246 bool MediaSession::IsControllable() const { | 279 bool MediaSession::IsControllable() const { |
247 // Only media session having focus Gain can be controllable unless it is | 280 // Only media session having focus Gain can be controllable unless it is |
248 // inactive. | 281 // inactive. |
249 return audio_focus_state_ != State::INACTIVE && | 282 return audio_focus_state_ != State::INACTIVE && |
250 audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain; | 283 audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain; |
251 } | 284 } |
252 | 285 |
286 bool MediaSession::HasPepper() const { | |
287 return !pepper_players_.empty(); | |
288 } | |
289 | |
253 std::unique_ptr<base::CallbackList<void(MediaSession::State)>::Subscription> | 290 std::unique_ptr<base::CallbackList<void(MediaSession::State)>::Subscription> |
254 MediaSession::RegisterMediaSessionStateChangedCallbackForTest( | 291 MediaSession::RegisterMediaSessionStateChangedCallbackForTest( |
255 const StateChangedCallback& cb) { | 292 const StateChangedCallback& cb) { |
256 return media_session_state_listeners_.Add(cb); | 293 return media_session_state_listeners_.Add(cb); |
257 } | 294 } |
258 | 295 |
259 void MediaSession::SetDelegateForTests( | 296 void MediaSession::SetDelegateForTests( |
260 std::unique_ptr<MediaSessionDelegate> delegate) { | 297 std::unique_ptr<MediaSessionDelegate> delegate) { |
261 delegate_ = std::move(delegate); | 298 delegate_ = std::move(delegate); |
262 } | 299 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 suspend_type_ = suspend_type; | 353 suspend_type_ = suspend_type; |
317 | 354 |
318 if (suspend_type != SuspendType::CONTENT) { | 355 if (suspend_type != SuspendType::CONTENT) { |
319 // SuspendType::CONTENT happens when the suspend action came from | 356 // SuspendType::CONTENT happens when the suspend action came from |
320 // the page in which case the player is already paused. | 357 // the page in which case the player is already paused. |
321 // Otherwise, the players need to be paused. | 358 // Otherwise, the players need to be paused. |
322 for (const auto& it : players_) | 359 for (const auto& it : players_) |
323 it.observer->OnSuspend(it.player_id); | 360 it.observer->OnSuspend(it.player_id); |
324 } | 361 } |
325 | 362 |
363 for (const auto& it : pepper_players_) | |
364 it.observer->OnSetVolumeMultiplier(it.player_id, kDuckingVolumeMultiplier); | |
365 | |
326 UpdateWebContents(); | 366 UpdateWebContents(); |
327 } | 367 } |
328 | 368 |
329 void MediaSession::OnResumeInternal(SuspendType suspend_type) { | 369 void MediaSession::OnResumeInternal(SuspendType suspend_type) { |
330 if (suspend_type == SuspendType::SYSTEM && suspend_type_ != suspend_type) | 370 if (suspend_type == SuspendType::SYSTEM && suspend_type_ != suspend_type) |
331 return; | 371 return; |
332 | 372 |
333 SetAudioFocusState(State::ACTIVE); | 373 SetAudioFocusState(State::ACTIVE); |
334 | 374 |
335 for (const auto& it : players_) | 375 for (const auto& it : players_) |
336 it.observer->OnResume(it.player_id); | 376 it.observer->OnResume(it.player_id); |
337 | 377 |
378 for (const auto& it : pepper_players_) | |
379 it.observer->OnSetVolumeMultiplier( | |
380 it.player_id, GetPepperVolumeMultiplier()); | |
381 | |
338 UpdateWebContents(); | 382 UpdateWebContents(); |
339 } | 383 } |
340 | 384 |
341 MediaSession::MediaSession(WebContents* web_contents) | 385 MediaSession::MediaSession(WebContents* web_contents) |
342 : WebContentsObserver(web_contents), | 386 : WebContentsObserver(web_contents), |
343 audio_focus_state_(State::INACTIVE), | 387 audio_focus_state_(State::INACTIVE), |
344 audio_focus_type_( | 388 audio_focus_type_( |
345 AudioFocusManager::AudioFocusType::GainTransientMayDuck), | 389 AudioFocusManager::AudioFocusType::GainTransientMayDuck), |
346 is_ducking_(false) {} | 390 is_ducking_(false), |
391 allow_pepper_override_ducking_(false) {} | |
347 | 392 |
348 void MediaSession::Initialize() { | 393 void MediaSession::Initialize() { |
349 delegate_ = MediaSessionDelegate::Create(this); | 394 delegate_ = MediaSessionDelegate::Create(this); |
350 } | 395 } |
351 | 396 |
352 bool MediaSession::RequestSystemAudioFocus( | 397 bool MediaSession::RequestSystemAudioFocus( |
353 AudioFocusManager::AudioFocusType audio_focus_type) { | 398 AudioFocusManager::AudioFocusType audio_focus_type) { |
354 bool result = delegate_->RequestAudioFocus(audio_focus_type); | 399 bool result = delegate_->RequestAudioFocus(audio_focus_type); |
355 uma_helper_.RecordRequestAudioFocusResult(result); | 400 uma_helper_.RecordRequestAudioFocusResult(result); |
356 return result; | 401 return result; |
357 } | 402 } |
358 | 403 |
359 void MediaSession::AbandonSystemAudioFocusIfNeeded() { | 404 void MediaSession::AbandonSystemAudioFocusIfNeeded() { |
360 if (audio_focus_state_ == State::INACTIVE || !players_.empty()) | 405 if (audio_focus_state_ == State::INACTIVE || !players_.empty() || |
406 !pepper_players_.empty()) | |
361 return; | 407 return; |
362 | 408 |
363 delegate_->AbandonAudioFocus(); | 409 delegate_->AbandonAudioFocus(); |
364 | 410 |
365 SetAudioFocusState(State::INACTIVE); | 411 SetAudioFocusState(State::INACTIVE); |
366 UpdateWebContents(); | 412 UpdateWebContents(); |
367 } | 413 } |
368 | 414 |
369 void MediaSession::UpdateWebContents() { | 415 void MediaSession::UpdateWebContents() { |
370 media_session_state_listeners_.Notify(audio_focus_state_); | 416 media_session_state_listeners_.Notify(audio_focus_state_); |
(...skipping 11 matching lines...) Expand all Loading... | |
382 break; | 428 break; |
383 case State::SUSPENDED: | 429 case State::SUSPENDED: |
384 uma_helper_.OnSessionSuspended(); | 430 uma_helper_.OnSessionSuspended(); |
385 break; | 431 break; |
386 case State::INACTIVE: | 432 case State::INACTIVE: |
387 uma_helper_.OnSessionInactive(); | 433 uma_helper_.OnSessionInactive(); |
388 break; | 434 break; |
389 } | 435 } |
390 } | 436 } |
391 | 437 |
438 bool MediaSession::AddPepperPlayer(MediaSessionObserver* observer, | |
439 int player_id) { | |
440 AudioFocusManager::AudioFocusType focus_type = | |
441 AudioFocusManager::AudioFocusType::Gain; | |
442 State audio_focus_state = | |
443 RequestSystemAudioFocus(focus_type) ? State::ACTIVE : State::INACTIVE; | |
444 SetAudioFocusState(audio_focus_state); | |
445 audio_focus_type_ = focus_type; | |
446 pepper_players_.insert(PlayerIdentifier(observer, player_id)); | |
447 | |
448 observer->OnSetVolumeMultiplier(player_id, GetPepperVolumeMultiplier()); | |
449 | |
450 return true; | |
451 } | |
452 | |
453 void MediaSession::AllowPepperOverrideDucking() { | |
whywhat
2016/09/13 00:16:17
nit: clear candidate to unification as AllowDisall
Zhiqiang Zhang (Slow)
2016/09/22 12:30:33
This method is removed since there's no longer com
| |
454 if (allow_pepper_override_ducking_) | |
455 return; | |
456 | |
457 allow_pepper_override_ducking_ = true; | |
458 for (const auto& it : pepper_players_) { | |
459 it.observer->OnSetVolumeMultiplier( | |
460 it.player_id, GetPepperVolumeMultiplier()); | |
461 } | |
462 } | |
463 | |
464 void MediaSession::DisallowPepperOverrideDucking() { | |
465 if (!allow_pepper_override_ducking_) | |
466 return; | |
467 | |
468 allow_pepper_override_ducking_ = false; | |
469 for (const auto& it : pepper_players_) { | |
470 it.observer->OnSetVolumeMultiplier( | |
471 it.player_id, GetPepperVolumeMultiplier()); | |
472 } | |
473 } | |
474 | |
392 } // namespace content | 475 } // namespace content |
OLD | NEW |