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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 metadata_ = metadata; | 64 metadata_ = metadata; |
65 // TODO(zqzhang): On Android, the metadata is sent though JNI everytime the | 65 // 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 | 66 // 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. | 67 // state change and Metadata update. See https://crbug.com/621855. |
68 static_cast<WebContentsImpl*>(web_contents())->OnMediaSessionStateChanged(); | 68 static_cast<WebContentsImpl*>(web_contents())->OnMediaSessionStateChanged(); |
69 } | 69 } |
70 | 70 |
71 bool MediaSession::AddPlayer(MediaSessionObserver* observer, | 71 bool MediaSession::AddPlayer(MediaSessionObserver* observer, |
72 int player_id, | 72 int player_id, |
73 media::MediaContentType media_content_type) { | 73 media::MediaContentType media_content_type) { |
| 74 if (media_content_type == media::MediaContentType::Pepper) |
| 75 return AddPepperPlayer(observer, player_id); |
| 76 |
74 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier()); | 77 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier()); |
75 | 78 |
76 // Determine the audio focus type required for playing the new player. | 79 // Determine the audio focus type required for playing the new player. |
77 // TODO(zqzhang): handle duckable and uncontrollable. | 80 // TODO(zqzhang): handle duckable and uncontrollable. |
78 // See https://crbug.com/639277. | 81 // See https://crbug.com/639277. |
79 AudioFocusManager::AudioFocusType required_audio_focus_type; | 82 AudioFocusManager::AudioFocusType required_audio_focus_type; |
80 if (media_content_type == media::MediaContentType::Persistent) { | 83 if (media_content_type == media::MediaContentType::Persistent) { |
81 required_audio_focus_type = AudioFocusManager::AudioFocusType::Gain; | 84 required_audio_focus_type = AudioFocusManager::AudioFocusType::Gain; |
82 } else { | 85 } else { |
83 required_audio_focus_type = | 86 required_audio_focus_type = |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 | 118 |
116 return true; | 119 return true; |
117 } | 120 } |
118 | 121 |
119 void MediaSession::RemovePlayer(MediaSessionObserver* observer, | 122 void MediaSession::RemovePlayer(MediaSessionObserver* observer, |
120 int player_id) { | 123 int player_id) { |
121 auto it = players_.find(PlayerIdentifier(observer, player_id)); | 124 auto it = players_.find(PlayerIdentifier(observer, player_id)); |
122 if (it != players_.end()) | 125 if (it != players_.end()) |
123 players_.erase(it); | 126 players_.erase(it); |
124 | 127 |
| 128 it = pepper_players_.find(PlayerIdentifier(observer, player_id)); |
| 129 if (it != pepper_players_.end()) |
| 130 pepper_players_.erase(it); |
| 131 |
125 AbandonSystemAudioFocusIfNeeded(); | 132 AbandonSystemAudioFocusIfNeeded(); |
126 } | 133 } |
127 | 134 |
128 void MediaSession::RemovePlayers(MediaSessionObserver* observer) { | 135 void MediaSession::RemovePlayers(MediaSessionObserver* observer) { |
129 for (auto it = players_.begin(); it != players_.end();) { | 136 for (auto it = players_.begin(); it != players_.end(); ) { |
130 if (it->observer == observer) | 137 if (it->observer == observer) |
131 players_.erase(it++); | 138 players_.erase(it++); |
132 else | 139 else |
133 ++it; | 140 ++it; |
134 } | 141 } |
135 | 142 |
| 143 for (auto it = pepper_players_.begin(); it != pepper_players_.end(); ) { |
| 144 if (it->observer == observer) |
| 145 pepper_players_.erase(it++); |
| 146 else |
| 147 ++it; |
| 148 } |
| 149 |
136 AbandonSystemAudioFocusIfNeeded(); | 150 AbandonSystemAudioFocusIfNeeded(); |
137 } | 151 } |
138 | 152 |
139 void MediaSession::RecordSessionDuck() { | 153 void MediaSession::RecordSessionDuck() { |
140 uma_helper_.RecordSessionSuspended( | 154 uma_helper_.RecordSessionSuspended( |
141 MediaSessionSuspendedSource::SystemTransientDuck); | 155 MediaSessionSuspendedSource::SystemTransientDuck); |
142 } | 156 } |
143 | 157 |
144 void MediaSession::OnPlayerPaused(MediaSessionObserver* observer, | 158 void MediaSession::OnPlayerPaused(MediaSessionObserver* observer, |
145 int player_id) { | 159 int player_id) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 } | 197 } |
184 | 198 |
185 void MediaSession::Suspend(SuspendType suspend_type) { | 199 void MediaSession::Suspend(SuspendType suspend_type) { |
186 DCHECK(!IsSuspended()); | 200 DCHECK(!IsSuspended()); |
187 | 201 |
188 OnSuspendInternal(suspend_type, State::SUSPENDED); | 202 OnSuspendInternal(suspend_type, State::SUSPENDED); |
189 } | 203 } |
190 | 204 |
191 void MediaSession::Stop(SuspendType suspend_type) { | 205 void MediaSession::Stop(SuspendType suspend_type) { |
192 DCHECK(audio_focus_state_ != State::INACTIVE); | 206 DCHECK(audio_focus_state_ != State::INACTIVE); |
193 | |
194 DCHECK(suspend_type != SuspendType::CONTENT); | 207 DCHECK(suspend_type != SuspendType::CONTENT); |
| 208 DCHECK(!HasPepper()); |
195 | 209 |
196 // TODO(mlamouri): merge the logic between UI and SYSTEM. | 210 // TODO(mlamouri): merge the logic between UI and SYSTEM. |
197 if (suspend_type == SuspendType::SYSTEM) { | 211 if (suspend_type == SuspendType::SYSTEM) { |
198 OnSuspendInternal(suspend_type, State::INACTIVE); | 212 OnSuspendInternal(suspend_type, State::INACTIVE); |
199 return; | 213 return; |
200 } | 214 } |
201 | 215 |
202 if (audio_focus_state_ != State::SUSPENDED) | 216 if (audio_focus_state_ != State::SUSPENDED) |
203 OnSuspendInternal(suspend_type, State::SUSPENDED); | 217 OnSuspendInternal(suspend_type, State::SUSPENDED); |
204 | 218 |
205 DCHECK(audio_focus_state_ == State::SUSPENDED); | 219 DCHECK(audio_focus_state_ == State::SUSPENDED); |
206 players_.clear(); | 220 players_.clear(); |
| 221 |
207 AbandonSystemAudioFocusIfNeeded(); | 222 AbandonSystemAudioFocusIfNeeded(); |
208 } | 223 } |
209 | 224 |
210 void MediaSession::StartDucking() { | 225 void MediaSession::StartDucking() { |
211 if (is_ducking_) | 226 if (is_ducking_) |
212 return; | 227 return; |
213 is_ducking_ = true; | 228 is_ducking_ = true; |
214 UpdateVolumeMultiplier(); | 229 UpdateVolumeMultiplier(); |
215 } | 230 } |
216 | 231 |
(...skipping 26 matching lines...) Expand all Loading... |
243 return audio_focus_state_ != State::ACTIVE; | 258 return audio_focus_state_ != State::ACTIVE; |
244 } | 259 } |
245 | 260 |
246 bool MediaSession::IsControllable() const { | 261 bool MediaSession::IsControllable() const { |
247 // Only media session having focus Gain can be controllable unless it is | 262 // Only media session having focus Gain can be controllable unless it is |
248 // inactive. | 263 // inactive. |
249 return audio_focus_state_ != State::INACTIVE && | 264 return audio_focus_state_ != State::INACTIVE && |
250 audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain; | 265 audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain; |
251 } | 266 } |
252 | 267 |
| 268 bool MediaSession::HasPepper() const { |
| 269 return !pepper_players_.empty(); |
| 270 } |
| 271 |
253 std::unique_ptr<base::CallbackList<void(MediaSession::State)>::Subscription> | 272 std::unique_ptr<base::CallbackList<void(MediaSession::State)>::Subscription> |
254 MediaSession::RegisterMediaSessionStateChangedCallbackForTest( | 273 MediaSession::RegisterMediaSessionStateChangedCallbackForTest( |
255 const StateChangedCallback& cb) { | 274 const StateChangedCallback& cb) { |
256 return media_session_state_listeners_.Add(cb); | 275 return media_session_state_listeners_.Add(cb); |
257 } | 276 } |
258 | 277 |
259 void MediaSession::SetDelegateForTests( | 278 void MediaSession::SetDelegateForTests( |
260 std::unique_ptr<MediaSessionDelegate> delegate) { | 279 std::unique_ptr<MediaSessionDelegate> delegate) { |
261 delegate_ = std::move(delegate); | 280 delegate_ = std::move(delegate); |
262 } | 281 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 suspend_type_ = suspend_type; | 335 suspend_type_ = suspend_type; |
317 | 336 |
318 if (suspend_type != SuspendType::CONTENT) { | 337 if (suspend_type != SuspendType::CONTENT) { |
319 // SuspendType::CONTENT happens when the suspend action came from | 338 // SuspendType::CONTENT happens when the suspend action came from |
320 // the page in which case the player is already paused. | 339 // the page in which case the player is already paused. |
321 // Otherwise, the players need to be paused. | 340 // Otherwise, the players need to be paused. |
322 for (const auto& it : players_) | 341 for (const auto& it : players_) |
323 it.observer->OnSuspend(it.player_id); | 342 it.observer->OnSuspend(it.player_id); |
324 } | 343 } |
325 | 344 |
| 345 for (const auto& it : pepper_players_) |
| 346 it.observer->OnSetVolumeMultiplier(it.player_id, kDuckingVolumeMultiplier); |
| 347 |
326 UpdateWebContents(); | 348 UpdateWebContents(); |
327 } | 349 } |
328 | 350 |
329 void MediaSession::OnResumeInternal(SuspendType suspend_type) { | 351 void MediaSession::OnResumeInternal(SuspendType suspend_type) { |
330 if (suspend_type == SuspendType::SYSTEM && suspend_type_ != suspend_type) | 352 if (suspend_type == SuspendType::SYSTEM && suspend_type_ != suspend_type) |
331 return; | 353 return; |
332 | 354 |
333 SetAudioFocusState(State::ACTIVE); | 355 SetAudioFocusState(State::ACTIVE); |
334 | 356 |
335 for (const auto& it : players_) | 357 for (const auto& it : players_) |
336 it.observer->OnResume(it.player_id); | 358 it.observer->OnResume(it.player_id); |
337 | 359 |
| 360 for (const auto& it : pepper_players_) |
| 361 it.observer->OnSetVolumeMultiplier( |
| 362 it.player_id, GetVolumeMultiplier()); |
| 363 |
338 UpdateWebContents(); | 364 UpdateWebContents(); |
339 } | 365 } |
340 | 366 |
341 MediaSession::MediaSession(WebContents* web_contents) | 367 MediaSession::MediaSession(WebContents* web_contents) |
342 : WebContentsObserver(web_contents), | 368 : WebContentsObserver(web_contents), |
343 audio_focus_state_(State::INACTIVE), | 369 audio_focus_state_(State::INACTIVE), |
344 audio_focus_type_( | 370 audio_focus_type_( |
345 AudioFocusManager::AudioFocusType::GainTransientMayDuck), | 371 AudioFocusManager::AudioFocusType::GainTransientMayDuck), |
346 is_ducking_(false) {} | 372 is_ducking_(false) {} |
347 | 373 |
348 void MediaSession::Initialize() { | 374 void MediaSession::Initialize() { |
349 delegate_ = MediaSessionDelegate::Create(this); | 375 delegate_ = MediaSessionDelegate::Create(this); |
350 } | 376 } |
351 | 377 |
352 bool MediaSession::RequestSystemAudioFocus( | 378 bool MediaSession::RequestSystemAudioFocus( |
353 AudioFocusManager::AudioFocusType audio_focus_type) { | 379 AudioFocusManager::AudioFocusType audio_focus_type) { |
354 bool result = delegate_->RequestAudioFocus(audio_focus_type); | 380 bool result = delegate_->RequestAudioFocus(audio_focus_type); |
355 uma_helper_.RecordRequestAudioFocusResult(result); | 381 uma_helper_.RecordRequestAudioFocusResult(result); |
356 return result; | 382 return result; |
357 } | 383 } |
358 | 384 |
359 void MediaSession::AbandonSystemAudioFocusIfNeeded() { | 385 void MediaSession::AbandonSystemAudioFocusIfNeeded() { |
360 if (audio_focus_state_ == State::INACTIVE || !players_.empty()) | 386 if (audio_focus_state_ == State::INACTIVE || !players_.empty() || |
| 387 !pepper_players_.empty()) |
361 return; | 388 return; |
362 | 389 |
363 delegate_->AbandonAudioFocus(); | 390 delegate_->AbandonAudioFocus(); |
364 | 391 |
365 SetAudioFocusState(State::INACTIVE); | 392 SetAudioFocusState(State::INACTIVE); |
366 UpdateWebContents(); | 393 UpdateWebContents(); |
367 } | 394 } |
368 | 395 |
369 void MediaSession::UpdateWebContents() { | 396 void MediaSession::UpdateWebContents() { |
370 media_session_state_listeners_.Notify(audio_focus_state_); | 397 media_session_state_listeners_.Notify(audio_focus_state_); |
(...skipping 11 matching lines...) Expand all Loading... |
382 break; | 409 break; |
383 case State::SUSPENDED: | 410 case State::SUSPENDED: |
384 uma_helper_.OnSessionSuspended(); | 411 uma_helper_.OnSessionSuspended(); |
385 break; | 412 break; |
386 case State::INACTIVE: | 413 case State::INACTIVE: |
387 uma_helper_.OnSessionInactive(); | 414 uma_helper_.OnSessionInactive(); |
388 break; | 415 break; |
389 } | 416 } |
390 } | 417 } |
391 | 418 |
| 419 bool MediaSession::AddPepperPlayer(MediaSessionObserver* observer, |
| 420 int player_id) { |
| 421 AudioFocusManager::AudioFocusType focus_type = |
| 422 AudioFocusManager::AudioFocusType::Gain; |
| 423 State audio_focus_state = |
| 424 RequestSystemAudioFocus(focus_type) ? State::ACTIVE : State::INACTIVE; |
| 425 SetAudioFocusState(audio_focus_state); |
| 426 audio_focus_type_ = focus_type; |
| 427 pepper_players_.insert(PlayerIdentifier(observer, player_id)); |
| 428 |
| 429 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier()); |
| 430 |
| 431 return true; |
| 432 } |
| 433 |
392 } // namespace content | 434 } // namespace content |
OLD | NEW |