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

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

Issue 2453623003: Decouple MediaSession messages from WebContents (full patch) (Closed)
Patch Set: 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.h" 5 #include "content/browser/media/session/media_session_impl.h"
6 6
7 #include "content/browser/media/session/audio_focus_delegate.h" 7 #include "content/browser/media/session/audio_focus_delegate.h"
8 #include "content/browser/media/session/media_session_player_observer.h" 8 #include "content/browser/media/session/media_session_player_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"
11 #include "content/public/browser/web_contents_delegate.h" 11 #include "content/public/browser/web_contents_delegate.h"
12 #include "media/base/media_content_type.h" 12 #include "media/base/media_content_type.h"
13 13
14 #if defined(OS_ANDROID)
15 #include "content/browser/media/session/media_session_android.h"
16 #include "jni/MediaSession_jni.h"
17 #endif // defined(OS_ANDROID)
18
14 namespace content { 19 namespace content {
15 20
16 namespace { 21 namespace {
17 22
18 const double kDefaultVolumeMultiplier = 1.0; 23 const double kDefaultVolumeMultiplier = 1.0;
19 const double kDuckingVolumeMultiplier = 0.2; 24 const double kDuckingVolumeMultiplier = 0.2;
20 25
21 } // anonymous namespace 26 } // anonymous namespace
22 27
23 using MediaSessionSuspendedSource = 28 using MediaSessionSuspendedSource =
24 MediaSessionUmaHelper::MediaSessionSuspendedSource; 29 MediaSessionUmaHelper::MediaSessionSuspendedSource;
25 30
26 DEFINE_WEB_CONTENTS_USER_DATA_KEY(MediaSession); 31 DEFINE_WEB_CONTENTS_USER_DATA_KEY(MediaSessionImpl);
27 32
28 MediaSession::PlayerIdentifier::PlayerIdentifier( 33 MediaSessionImpl::PlayerIdentifier::PlayerIdentifier(
29 MediaSessionPlayerObserver* observer, 34 MediaSessionPlayerObserver* observer,
30 int player_id) 35 int player_id)
31 : observer(observer), player_id(player_id) {} 36 : observer(observer), player_id(player_id) {}
32 37
33 bool MediaSession::PlayerIdentifier::operator==( 38 bool MediaSessionImpl::PlayerIdentifier::operator==(
34 const PlayerIdentifier& other) const { 39 const PlayerIdentifier& other) const {
35 return this->observer == other.observer && this->player_id == other.player_id; 40 return this->observer == other.observer && this->player_id == other.player_id;
36 } 41 }
37 42
38 size_t MediaSession::PlayerIdentifier::Hash::operator()( 43 size_t MediaSessionImpl::PlayerIdentifier::Hash::operator()(
39 const PlayerIdentifier& player_identifier) const { 44 const PlayerIdentifier& player_identifier) const {
40 size_t hash = BASE_HASH_NAMESPACE::hash<MediaSessionPlayerObserver*>()( 45 size_t hash = BASE_HASH_NAMESPACE::hash<MediaSessionPlayerObserver*>()(
41 player_identifier.observer); 46 player_identifier.observer);
42 hash += BASE_HASH_NAMESPACE::hash<int>()(player_identifier.player_id); 47 hash += BASE_HASH_NAMESPACE::hash<int>()(player_identifier.player_id);
43 return hash; 48 return hash;
44 } 49 }
45 50
46 // static 51 // static
47 MediaSession* MediaSession::Get(WebContents* web_contents) { 52 MediaSession* MediaSession::Get(WebContents* web_contents) {
48 MediaSession* session = FromWebContents(web_contents); 53 return MediaSessionImpl::Get(web_contents);
54 }
55
56 // static
57 MediaSessionImpl* MediaSessionImpl::Get(WebContents* web_contents) {
58 MediaSessionImpl* session = FromWebContents(web_contents);
49 if (!session) { 59 if (!session) {
50 CreateForWebContents(web_contents); 60 CreateForWebContents(web_contents);
51 session = FromWebContents(web_contents); 61 session = FromWebContents(web_contents);
52 session->Initialize(); 62 session->Initialize();
53 } 63 }
54 return session; 64 return session;
55 } 65 }
56 66
57 MediaSession::~MediaSession() { 67 #if defined(OS_ANDROID)
68 bool RegisterMediaSessionNatives(JNIEnv* env) {
69 return RegisterNativesImpl(env);
70 }
71
72 // static
73 base::android::ScopedJavaLocalRef<jobject> GetMediaSessionFromWebContents(
74 JNIEnv* env,
75 const base::android::JavaParamRef<jclass>& clazz,
76 const base::android::JavaParamRef<jobject>& j_contents_android) {
77 WebContents* contents = WebContents::FromJavaWebContents(j_contents_android);
78 DCHECK(contents);
79 MediaSessionImpl* session = MediaSessionImpl::Get(contents);
80 return session->session_android()->GetJavaSession();
81 }
82
83 #endif // defined(OS_ANDROID)
84
85 MediaSessionImpl::~MediaSessionImpl() {
58 DCHECK(players_.empty()); 86 DCHECK(players_.empty());
59 DCHECK(audio_focus_state_ == State::INACTIVE); 87 DCHECK(audio_focus_state_ == State::INACTIVE);
88 for (auto& observer : observers_)
89 observer.MediaSessionDestroyed();
90 for (auto& observer : observers_)
91 observer.StopObserving();
60 } 92 }
61 93
62 void MediaSession::WebContentsDestroyed() { 94 void MediaSessionImpl::WebContentsDestroyed() {
63 // This should only work for tests. In production, all the players should have 95 // This should only work for tests. In production, all the players should have
64 // already been removed before WebContents is destroyed. 96 // already been removed before WebContents is destroyed.
65 97
66 // TODO(zqzhang): refactor MediaSession, maybe move the interface used to talk 98 // TODO(zqzhang): refactor MediaSessionImpl, maybe move the interface used to
99 // talk
67 // with AudioFocusManager out to a seperate class. The AudioFocusManager unit 100 // with AudioFocusManager out to a seperate class. The AudioFocusManager unit
68 // tests then could mock the interface and abandon audio focus when 101 // tests then could mock the interface and abandon audio focus when
69 // WebContents is destroyed. See https://crbug.com/651069 102 // WebContents is destroyed. See https://crbug.com/651069
70 players_.clear(); 103 players_.clear();
71 pepper_players_.clear(); 104 pepper_players_.clear();
72 AbandonSystemAudioFocusIfNeeded(); 105 AbandonSystemAudioFocusIfNeeded();
73 } 106 }
74 107
75 void MediaSession::SetMetadata(const base::Optional<MediaMetadata>& metadata) { 108 void MediaSessionImpl::AddObserver(MediaSessionObserver* observer) {
76 metadata_ = metadata; 109 observers_.AddObserver(observer);
77 static_cast<WebContentsImpl*>(web_contents())
78 ->OnMediaSessionMetadataChanged();
79 } 110 }
80 111
81 bool MediaSession::AddPlayer(MediaSessionPlayerObserver* observer, 112 void MediaSessionImpl::RemoveObserver(MediaSessionObserver* observer) {
82 int player_id, 113 observers_.RemoveObserver(observer);
83 media::MediaContentType media_content_type) { 114 }
115
116 void MediaSessionImpl::SetMetadata(
117 const base::Optional<MediaMetadata>& metadata) {
118 metadata_ = metadata;
119 for (auto& observer : observers_)
120 observer.MediaSessionMetadataChanged(metadata);
121 }
122
123 bool MediaSessionImpl::AddPlayer(MediaSessionPlayerObserver* observer,
124 int player_id,
125 media::MediaContentType media_content_type) {
84 if (media_content_type == media::MediaContentType::Uncontrollable) 126 if (media_content_type == media::MediaContentType::Uncontrollable)
85 return true; 127 return true;
86 if (media_content_type == media::MediaContentType::Pepper) 128 if (media_content_type == media::MediaContentType::Pepper)
87 return AddPepperPlayer(observer, player_id); 129 return AddPepperPlayer(observer, player_id);
88 130
89 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier()); 131 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier());
90 132
91 // Determine the audio focus type required for playing the new player. 133 // Determine the audio focus type required for playing the new player.
92 // TODO(zqzhang): handle duckable and uncontrollable. 134 // TODO(zqzhang): handle duckable and uncontrollable.
93 // See https://crbug.com/639277. 135 // See https://crbug.com/639277.
(...skipping 26 matching lines...) Expand all
120 // suspended. 162 // suspended.
121 if (old_audio_focus_state != State::ACTIVE) 163 if (old_audio_focus_state != State::ACTIVE)
122 players_.clear(); 164 players_.clear();
123 165
124 players_.insert(PlayerIdentifier(observer, player_id)); 166 players_.insert(PlayerIdentifier(observer, player_id));
125 UpdateWebContents(); 167 UpdateWebContents();
126 168
127 return true; 169 return true;
128 } 170 }
129 171
130 void MediaSession::RemovePlayer(MediaSessionPlayerObserver* observer, 172 void MediaSessionImpl::RemovePlayer(MediaSessionPlayerObserver* observer,
131 int player_id) { 173 int player_id) {
132 auto it = players_.find(PlayerIdentifier(observer, player_id)); 174 auto it = players_.find(PlayerIdentifier(observer, player_id));
133 if (it != players_.end()) 175 if (it != players_.end())
134 players_.erase(it); 176 players_.erase(it);
135 177
136 it = pepper_players_.find(PlayerIdentifier(observer, player_id)); 178 it = pepper_players_.find(PlayerIdentifier(observer, player_id));
137 if (it != pepper_players_.end()) 179 if (it != pepper_players_.end())
138 pepper_players_.erase(it); 180 pepper_players_.erase(it);
139 181
140 AbandonSystemAudioFocusIfNeeded(); 182 AbandonSystemAudioFocusIfNeeded();
141 } 183 }
142 184
143 void MediaSession::RemovePlayers(MediaSessionPlayerObserver* observer) { 185 void MediaSessionImpl::RemovePlayers(MediaSessionPlayerObserver* observer) {
144 for (auto it = players_.begin(); it != players_.end(); ) { 186 for (auto it = players_.begin(); it != players_.end();) {
145 if (it->observer == observer) 187 if (it->observer == observer)
146 players_.erase(it++); 188 players_.erase(it++);
147 else 189 else
148 ++it; 190 ++it;
149 } 191 }
150 192
151 for (auto it = pepper_players_.begin(); it != pepper_players_.end(); ) { 193 for (auto it = pepper_players_.begin(); it != pepper_players_.end();) {
152 if (it->observer == observer) 194 if (it->observer == observer)
153 pepper_players_.erase(it++); 195 pepper_players_.erase(it++);
154 else 196 else
155 ++it; 197 ++it;
156 } 198 }
157 199
158 AbandonSystemAudioFocusIfNeeded(); 200 AbandonSystemAudioFocusIfNeeded();
159 } 201 }
160 202
161 void MediaSession::RecordSessionDuck() { 203 void MediaSessionImpl::RecordSessionDuck() {
162 uma_helper_.RecordSessionSuspended( 204 uma_helper_.RecordSessionSuspended(
163 MediaSessionSuspendedSource::SystemTransientDuck); 205 MediaSessionSuspendedSource::SystemTransientDuck);
164 } 206 }
165 207
166 void MediaSession::OnPlayerPaused(MediaSessionPlayerObserver* observer, 208 void MediaSessionImpl::OnPlayerPaused(MediaSessionPlayerObserver* observer,
167 int player_id) { 209 int player_id) {
168 // If a playback is completed, BrowserMediaPlayerManager will call 210 // If a playback is completed, BrowserMediaPlayerManager will call
169 // OnPlayerPaused() after RemovePlayer(). This is a workaround. 211 // OnPlayerPaused() after RemovePlayer(). This is a workaround.
170 // Also, this method may be called when a player that is not added 212 // Also, this method may be called when a player that is not added
171 // to this session (e.g. a silent video) is paused. MediaSession 213 // to this session (e.g. a silent video) is paused. MediaSessionImpl
172 // should ignore the paused player for this case. 214 // should ignore the paused player for this case.
173 if (!players_.count(PlayerIdentifier(observer, player_id)) && 215 if (!players_.count(PlayerIdentifier(observer, player_id)) &&
174 !pepper_players_.count(PlayerIdentifier(observer, player_id))) { 216 !pepper_players_.count(PlayerIdentifier(observer, player_id))) {
175 return; 217 return;
176 } 218 }
177 219
178 // If the player to be removed is a pepper player, or there is more than one 220 // If the player to be removed is a pepper player, or there is more than one
179 // observer, remove the paused one from the session. 221 // observer, remove the paused one from the session.
180 if (pepper_players_.count(PlayerIdentifier(observer, player_id)) || 222 if (pepper_players_.count(PlayerIdentifier(observer, player_id)) ||
181 players_.size() != 1) { 223 players_.size() != 1) {
182 RemovePlayer(observer, player_id); 224 RemovePlayer(observer, player_id);
183 return; 225 return;
184 } 226 }
185 227
186 // Otherwise, suspend the session. 228 // Otherwise, suspend the session.
187 DCHECK(!IsSuspended()); 229 DCHECK(!IsSuspended());
188 OnSuspendInternal(SuspendType::CONTENT, State::SUSPENDED); 230 OnSuspendInternal(SuspendType::CONTENT, State::SUSPENDED);
189 } 231 }
190 232
191 void MediaSession::Resume(SuspendType suspend_type) { 233 void MediaSessionImpl::Resume(SuspendType suspend_type) {
192 DCHECK(IsReallySuspended()); 234 DCHECK(IsReallySuspended());
193 235
194 // When the resume requests comes from another source than system, audio focus 236 // When the resume requests comes from another source than system, audio focus
195 // must be requested. 237 // must be requested.
196 if (suspend_type != SuspendType::SYSTEM) { 238 if (suspend_type != SuspendType::SYSTEM) {
197 // Request audio focus again in case we lost it because another app started 239 // Request audio focus again in case we lost it because another app started
198 // playing while the playback was paused. 240 // playing while the playback was paused.
199 State audio_focus_state = RequestSystemAudioFocus(audio_focus_type_) 241 State audio_focus_state = RequestSystemAudioFocus(audio_focus_type_)
200 ? State::ACTIVE 242 ? State::ACTIVE
201 : State::INACTIVE; 243 : State::INACTIVE;
202 SetAudioFocusState(audio_focus_state); 244 SetAudioFocusState(audio_focus_state);
203 245
204 if (audio_focus_state_ != State::ACTIVE) 246 if (audio_focus_state_ != State::ACTIVE)
205 return; 247 return;
206 } 248 }
207 249
208 OnResumeInternal(suspend_type); 250 OnResumeInternal(suspend_type);
209 } 251 }
210 252
211 void MediaSession::Suspend(SuspendType suspend_type) { 253 void MediaSessionImpl::Suspend(SuspendType suspend_type) {
212 DCHECK(!IsSuspended()); 254 DCHECK(!IsSuspended());
213 255
214 OnSuspendInternal(suspend_type, State::SUSPENDED); 256 OnSuspendInternal(suspend_type, State::SUSPENDED);
215 } 257 }
216 258
217 void MediaSession::Stop(SuspendType suspend_type) { 259 void MediaSessionImpl::Stop(SuspendType suspend_type) {
218 DCHECK(audio_focus_state_ != State::INACTIVE); 260 DCHECK(audio_focus_state_ != State::INACTIVE);
219 DCHECK(suspend_type != SuspendType::CONTENT); 261 DCHECK(suspend_type != SuspendType::CONTENT);
220 DCHECK(!HasPepper()); 262 DCHECK(!HasPepper());
221 263
222 // TODO(mlamouri): merge the logic between UI and SYSTEM. 264 // TODO(mlamouri): merge the logic between UI and SYSTEM.
223 if (suspend_type == SuspendType::SYSTEM) { 265 if (suspend_type == SuspendType::SYSTEM) {
224 OnSuspendInternal(suspend_type, State::INACTIVE); 266 OnSuspendInternal(suspend_type, State::INACTIVE);
225 return; 267 return;
226 } 268 }
227 269
228 if (audio_focus_state_ != State::SUSPENDED) 270 if (audio_focus_state_ != State::SUSPENDED)
229 OnSuspendInternal(suspend_type, State::SUSPENDED); 271 OnSuspendInternal(suspend_type, State::SUSPENDED);
230 272
231 DCHECK(audio_focus_state_ == State::SUSPENDED); 273 DCHECK(audio_focus_state_ == State::SUSPENDED);
232 players_.clear(); 274 players_.clear();
233 275
234 AbandonSystemAudioFocusIfNeeded(); 276 AbandonSystemAudioFocusIfNeeded();
235 } 277 }
236 278
237 void MediaSession::StartDucking() { 279 void MediaSessionImpl::StartDucking() {
238 if (is_ducking_) 280 if (is_ducking_)
239 return; 281 return;
240 is_ducking_ = true; 282 is_ducking_ = true;
241 UpdateVolumeMultiplier(); 283 UpdateVolumeMultiplier();
242 } 284 }
243 285
244 void MediaSession::StopDucking() { 286 void MediaSessionImpl::StopDucking() {
245 if (!is_ducking_) 287 if (!is_ducking_)
246 return; 288 return;
247 is_ducking_ = false; 289 is_ducking_ = false;
248 UpdateVolumeMultiplier(); 290 UpdateVolumeMultiplier();
249 } 291 }
250 292
251 void MediaSession::UpdateVolumeMultiplier() { 293 void MediaSessionImpl::UpdateVolumeMultiplier() {
252 for (const auto& it : players_) 294 for (const auto& it : players_)
253 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); 295 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier());
254 for (const auto& it : pepper_players_) 296 for (const auto& it : pepper_players_)
255 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); 297 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier());
256 } 298 }
257 299
258 double MediaSession::GetVolumeMultiplier() const { 300 double MediaSessionImpl::GetVolumeMultiplier() const {
259 return is_ducking_ ? kDuckingVolumeMultiplier : kDefaultVolumeMultiplier; 301 return is_ducking_ ? kDuckingVolumeMultiplier : kDefaultVolumeMultiplier;
260 } 302 }
261 303
262 bool MediaSession::IsActive() const { 304 bool MediaSessionImpl::IsActive() const {
263 return audio_focus_state_ == State::ACTIVE; 305 return audio_focus_state_ == State::ACTIVE;
264 } 306 }
265 307
266 bool MediaSession::IsReallySuspended() const { 308 bool MediaSessionImpl::IsReallySuspended() const {
267 return audio_focus_state_ == State::SUSPENDED; 309 return audio_focus_state_ == State::SUSPENDED;
268 } 310 }
269 311
270 bool MediaSession::IsSuspended() const { 312 bool MediaSessionImpl::IsSuspended() const {
271 // TODO(mlamouri): should be == State::SUSPENDED. 313 // TODO(mlamouri): should be == State::SUSPENDED.
272 return audio_focus_state_ != State::ACTIVE; 314 return audio_focus_state_ != State::ACTIVE;
273 } 315 }
274 316
275 bool MediaSession::IsControllable() const { 317 bool MediaSessionImpl::IsControllable() const {
276 // Only media session having focus Gain can be controllable unless it is 318 // Only media session having focus Gain can be controllable unless it is
277 // inactive. 319 // inactive.
278 return audio_focus_state_ != State::INACTIVE && 320 return audio_focus_state_ != State::INACTIVE &&
279 audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain; 321 audio_focus_type_ == AudioFocusManager::AudioFocusType::Gain;
280 } 322 }
281 323
282 bool MediaSession::HasPepper() const { 324 bool MediaSessionImpl::HasPepper() const {
283 return !pepper_players_.empty(); 325 return !pepper_players_.empty();
284 } 326 }
285 327
286 std::unique_ptr<base::CallbackList<void(MediaSession::State)>::Subscription> 328 std::unique_ptr<base::CallbackList<void(MediaSessionImpl::State)>::Subscription>
287 MediaSession::RegisterMediaSessionStateChangedCallbackForTest( 329 MediaSessionImpl::RegisterMediaSessionStateChangedCallbackForTest(
288 const StateChangedCallback& cb) { 330 const StateChangedCallback& cb) {
289 return media_session_state_listeners_.Add(cb); 331 return media_session_state_listeners_.Add(cb);
290 } 332 }
291 333
292 void MediaSession::SetDelegateForTests( 334 void MediaSessionImpl::SetDelegateForTests(
293 std::unique_ptr<AudioFocusDelegate> delegate) { 335 std::unique_ptr<AudioFocusDelegate> delegate) {
294 delegate_ = std::move(delegate); 336 delegate_ = std::move(delegate);
295 } 337 }
296 338
297 bool MediaSession::IsActiveForTest() const { 339 bool MediaSessionImpl::IsActiveForTest() const {
298 return audio_focus_state_ == State::ACTIVE; 340 return audio_focus_state_ == State::ACTIVE;
299 } 341 }
300 342
301 MediaSessionUmaHelper* MediaSession::uma_helper_for_test() { 343 MediaSessionUmaHelper* MediaSessionImpl::uma_helper_for_test() {
302 return &uma_helper_; 344 return &uma_helper_;
303 } 345 }
304 346
305 void MediaSession::RemoveAllPlayersForTest() { 347 void MediaSessionImpl::RemoveAllPlayersForTest() {
306 players_.clear(); 348 players_.clear();
307 AbandonSystemAudioFocusIfNeeded(); 349 AbandonSystemAudioFocusIfNeeded();
308 } 350 }
309 351
310 void MediaSession::OnSuspendInternal(SuspendType suspend_type, 352 void MediaSessionImpl::OnSuspendInternal(SuspendType suspend_type,
311 State new_state) { 353 State new_state) {
312 DCHECK(!HasPepper()); 354 DCHECK(!HasPepper());
313 355
314 DCHECK(new_state == State::SUSPENDED || new_state == State::INACTIVE); 356 DCHECK(new_state == State::SUSPENDED || new_state == State::INACTIVE);
315 // UI suspend cannot use State::INACTIVE. 357 // UI suspend cannot use State::INACTIVE.
316 DCHECK(suspend_type == SuspendType::SYSTEM || new_state == State::SUSPENDED); 358 DCHECK(suspend_type == SuspendType::SYSTEM || new_state == State::SUSPENDED);
317 359
318 if (audio_focus_state_ != State::ACTIVE) 360 if (audio_focus_state_ != State::ACTIVE)
319 return; 361 return;
320 362
321 switch (suspend_type) { 363 switch (suspend_type) {
(...skipping 30 matching lines...) Expand all
352 for (const auto& it : players_) 394 for (const auto& it : players_)
353 it.observer->OnSuspend(it.player_id); 395 it.observer->OnSuspend(it.player_id);
354 } 396 }
355 397
356 for (const auto& it : pepper_players_) 398 for (const auto& it : pepper_players_)
357 it.observer->OnSetVolumeMultiplier(it.player_id, kDuckingVolumeMultiplier); 399 it.observer->OnSetVolumeMultiplier(it.player_id, kDuckingVolumeMultiplier);
358 400
359 UpdateWebContents(); 401 UpdateWebContents();
360 } 402 }
361 403
362 void MediaSession::OnResumeInternal(SuspendType suspend_type) { 404 void MediaSessionImpl::OnResumeInternal(SuspendType suspend_type) {
363 if (suspend_type == SuspendType::SYSTEM && suspend_type_ != suspend_type) 405 if (suspend_type == SuspendType::SYSTEM && suspend_type_ != suspend_type)
364 return; 406 return;
365 407
366 SetAudioFocusState(State::ACTIVE); 408 SetAudioFocusState(State::ACTIVE);
367 409
368 for (const auto& it : players_) 410 for (const auto& it : players_)
369 it.observer->OnResume(it.player_id); 411 it.observer->OnResume(it.player_id);
370 412
371 for (const auto& it : pepper_players_) 413 for (const auto& it : pepper_players_)
372 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); 414 it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier());
373 415
374 UpdateWebContents(); 416 UpdateWebContents();
375 } 417 }
376 418
377 MediaSession::MediaSession(WebContents* web_contents) 419 MediaSessionImpl::MediaSessionImpl(WebContents* web_contents)
378 : WebContentsObserver(web_contents), 420 : WebContentsObserver(web_contents),
379 audio_focus_state_(State::INACTIVE), 421 audio_focus_state_(State::INACTIVE),
380 audio_focus_type_( 422 audio_focus_type_(
381 AudioFocusManager::AudioFocusType::GainTransientMayDuck), 423 AudioFocusManager::AudioFocusType::GainTransientMayDuck),
382 is_ducking_(false) {} 424 is_ducking_(false) {
425 #if defined(OS_ANDROID)
426 session_android_.reset(new MediaSessionAndroid(this));
427 #endif // defined(OS_ANDROID)
428 }
383 429
384 void MediaSession::Initialize() { 430 void MediaSessionImpl::Initialize() {
385 delegate_ = AudioFocusDelegate::Create(this); 431 delegate_ = AudioFocusDelegate::Create(this);
386 } 432 }
387 433
388 bool MediaSession::RequestSystemAudioFocus( 434 bool MediaSessionImpl::RequestSystemAudioFocus(
389 AudioFocusManager::AudioFocusType audio_focus_type) { 435 AudioFocusManager::AudioFocusType audio_focus_type) {
390 bool result = delegate_->RequestAudioFocus(audio_focus_type); 436 bool result = delegate_->RequestAudioFocus(audio_focus_type);
391 uma_helper_.RecordRequestAudioFocusResult(result); 437 uma_helper_.RecordRequestAudioFocusResult(result);
392 438
393 // MediaSession must change its state & audio focus type AFTER requesting 439 // MediaSessionImpl must change its state & audio focus type AFTER requesting
394 // audio focus. 440 // audio focus.
395 SetAudioFocusState(result ? State::ACTIVE : State::INACTIVE); 441 SetAudioFocusState(result ? State::ACTIVE : State::INACTIVE);
396 audio_focus_type_ = audio_focus_type; 442 audio_focus_type_ = audio_focus_type;
397 return result; 443 return result;
398 } 444 }
399 445
400 void MediaSession::AbandonSystemAudioFocusIfNeeded() { 446 void MediaSessionImpl::AbandonSystemAudioFocusIfNeeded() {
401 if (audio_focus_state_ == State::INACTIVE || !players_.empty() || 447 if (audio_focus_state_ == State::INACTIVE || !players_.empty() ||
402 !pepper_players_.empty()) { 448 !pepper_players_.empty()) {
403 return; 449 return;
404 } 450 }
405 delegate_->AbandonAudioFocus(); 451 delegate_->AbandonAudioFocus();
406 452
407 SetAudioFocusState(State::INACTIVE); 453 SetAudioFocusState(State::INACTIVE);
408 UpdateWebContents(); 454 UpdateWebContents();
409 } 455 }
410 456
411 void MediaSession::UpdateWebContents() { 457 void MediaSessionImpl::UpdateWebContents() {
412 media_session_state_listeners_.Notify(audio_focus_state_); 458 media_session_state_listeners_.Notify(audio_focus_state_);
413 static_cast<WebContentsImpl*>(web_contents())->OnMediaSessionStateChanged(); 459 for (auto& observer : observers_)
460 observer.MediaSessionStateChanged(IsControllable(), IsSuspended());
414 } 461 }
415 462
416 void MediaSession::SetAudioFocusState(State audio_focus_state) { 463 void MediaSessionImpl::SetAudioFocusState(State audio_focus_state) {
417 if (audio_focus_state == audio_focus_state_) 464 if (audio_focus_state == audio_focus_state_)
418 return; 465 return;
419 466
420 audio_focus_state_ = audio_focus_state; 467 audio_focus_state_ = audio_focus_state;
421 switch (audio_focus_state_) { 468 switch (audio_focus_state_) {
422 case State::ACTIVE: 469 case State::ACTIVE:
423 uma_helper_.OnSessionActive(); 470 uma_helper_.OnSessionActive();
424 break; 471 break;
425 case State::SUSPENDED: 472 case State::SUSPENDED:
426 uma_helper_.OnSessionSuspended(); 473 uma_helper_.OnSessionSuspended();
427 break; 474 break;
428 case State::INACTIVE: 475 case State::INACTIVE:
429 uma_helper_.OnSessionInactive(); 476 uma_helper_.OnSessionInactive();
430 break; 477 break;
431 } 478 }
432 } 479 }
433 480
434 bool MediaSession::AddPepperPlayer(MediaSessionPlayerObserver* observer, 481 bool MediaSessionImpl::AddPepperPlayer(MediaSessionPlayerObserver* observer,
435 int player_id) { 482 int player_id) {
436 bool success = RequestSystemAudioFocus( 483 bool success =
437 AudioFocusManager::AudioFocusType::Gain); 484 RequestSystemAudioFocus(AudioFocusManager::AudioFocusType::Gain);
438 DCHECK(success); 485 DCHECK(success);
439 486
440 pepper_players_.insert(PlayerIdentifier(observer, player_id)); 487 pepper_players_.insert(PlayerIdentifier(observer, player_id));
441 488
442 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier()); 489 observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier());
443 490
444 return true; 491 return true;
445 } 492 }
446 493
447 } // namespace content 494 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698