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

Side by Side Diff: content/browser/media/android/media_session.cc

Issue 1671603002: Mute audio for Spitzer playbacks that haven't received focus yet. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix comment. Created 4 years, 10 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 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/android/media_session.h" 5 #include "content/browser/media/android/media_session.h"
6 6
7 #include "base/android/context_utils.h" 7 #include "base/android/context_utils.h"
8 #include "base/android/jni_android.h" 8 #include "base/android/jni_android.h"
9 #include "content/browser/media/android/media_session_observer.h" 9 #include "content/browser/media/android/media_session_observer.h"
10 #include "content/browser/web_contents/web_contents_impl.h" 10 #include "content/browser/web_contents/web_contents_impl.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 bool MediaSession::AddPlayer(MediaSessionObserver* observer, 63 bool MediaSession::AddPlayer(MediaSessionObserver* observer,
64 int player_id, 64 int player_id,
65 Type type) { 65 Type type) {
66 observer->OnSetVolumeMultiplier(player_id, volume_multiplier_);
67
68 // If the audio focus is already granted and is of type Content, there is 66 // If the audio focus is already granted and is of type Content, there is
69 // nothing to do. If it is granted of type Transient the requested type is 67 // nothing to do. If it is granted of type Transient the requested type is
70 // also transient, there is also nothing to do. Otherwise, the session needs 68 // also transient, there is also nothing to do. Otherwise, the session needs
71 // to request audio focus again. 69 // to request audio focus again.
72 if (audio_focus_state_ == State::ACTIVE && 70 if (audio_focus_state_ == State::ACTIVE &&
73 (audio_focus_type_ == Type::Content || audio_focus_type_ == type)) { 71 (audio_focus_type_ == Type::Content || audio_focus_type_ == type)) {
74 players_.insert(PlayerIdentifier(observer, player_id)); 72 players_.insert(PlayerIdentifier(observer, player_id));
75 return true; 73 } else {
74 State old_audio_focus_state = audio_focus_state_;
75 State audio_focus_state = RequestSystemAudioFocus(type) ? State::ACTIVE
76 : State::INACTIVE;
77 SetAudioFocusState(audio_focus_state);
78 audio_focus_type_ = type;
79
80 if (audio_focus_state_ != State::ACTIVE)
81 return false;
82
83 // The session should be reset if a player is starting while all players are
84 // suspended.
85 if (old_audio_focus_state != State::ACTIVE)
86 players_.clear();
87
88 players_.insert(PlayerIdentifier(observer, player_id));
89 UpdateWebContents();
76 } 90 }
77 91
78 State old_audio_focus_state = audio_focus_state_; 92 // Unmute audio for observers which may have started playing asynchronously in
79 State audio_focus_state = RequestSystemAudioFocus(type) ? State::ACTIVE 93 // a muted state while waiting for the focus approval.
80 : State::INACTIVE; 94 observer->OnSetVolumeMultiplier(player_id, volume_multiplier_);
81 SetAudioFocusState(audio_focus_state);
82 audio_focus_type_ = type;
83
84 if (audio_focus_state_ != State::ACTIVE)
85 return false;
86
87 // The session should be reset if a player is starting while all players are
88 // suspended.
89 if (old_audio_focus_state != State::ACTIVE)
90 players_.clear();
91
92 players_.insert(PlayerIdentifier(observer, player_id));
93 UpdateWebContents();
94
95 return true; 95 return true;
96 } 96 }
97 97
98 void MediaSession::RemovePlayer(MediaSessionObserver* observer, 98 void MediaSession::RemovePlayer(MediaSessionObserver* observer,
99 int player_id) { 99 int player_id) {
100 auto it = players_.find(PlayerIdentifier(observer, player_id)); 100 auto it = players_.find(PlayerIdentifier(observer, player_id));
101 if (it != players_.end()) 101 if (it != players_.end())
102 players_.erase(it); 102 players_.erase(it);
103 103
104 AbandonSystemAudioFocusIfNeeded(); 104 AbandonSystemAudioFocusIfNeeded();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 // TODO(mlamouri): should be == State::SUSPENDED. 198 // TODO(mlamouri): should be == State::SUSPENDED.
199 return audio_focus_state_ != State::ACTIVE; 199 return audio_focus_state_ != State::ACTIVE;
200 } 200 }
201 201
202 bool MediaSession::IsControllable() const { 202 bool MediaSession::IsControllable() const {
203 // Only content type media session can be controllable unless it is inactive. 203 // Only content type media session can be controllable unless it is inactive.
204 return audio_focus_state_ != State::INACTIVE && 204 return audio_focus_state_ != State::INACTIVE &&
205 audio_focus_type_ == Type::Content; 205 audio_focus_type_ == Type::Content;
206 } 206 }
207 207
208 void MediaSession::ResetJavaRefForTest() {
209 j_media_session_.Reset();
210 }
211
212 bool MediaSession::IsActiveForTest() const {
213 return audio_focus_state_ == State::ACTIVE;
214 }
215
216 MediaSession::Type MediaSession::audio_focus_type_for_test() const {
217 return audio_focus_type_;
218 }
219
220 MediaSessionUmaHelper* MediaSession::uma_helper_for_test() {
221 return &uma_helper_;
222 }
223
224 void MediaSession::RemoveAllPlayersForTest() {
225 players_.clear();
226 AbandonSystemAudioFocusIfNeeded();
227 }
228
229 void MediaSession::OnSuspendInternal(SuspendType type, State new_state) { 208 void MediaSession::OnSuspendInternal(SuspendType type, State new_state) {
230 DCHECK(new_state == State::SUSPENDED || new_state == State::INACTIVE); 209 DCHECK(new_state == State::SUSPENDED || new_state == State::INACTIVE);
231 // UI suspend cannot use State::INACTIVE. 210 // UI suspend cannot use State::INACTIVE.
232 DCHECK(type == SuspendType::SYSTEM || new_state == State::SUSPENDED); 211 DCHECK(type == SuspendType::SYSTEM || new_state == State::SUSPENDED);
233 212
234 switch (type) { 213 switch (type) {
235 case SuspendType::UI: 214 case SuspendType::UI:
236 uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::UI); 215 uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::UI);
237 break; 216 break;
238 case SuspendType::SYSTEM: 217 case SuspendType::SYSTEM:
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 } 261 }
283 262
284 void MediaSession::OnSetVolumeMultiplierInternal(double volume_multiplier) { 263 void MediaSession::OnSetVolumeMultiplierInternal(double volume_multiplier) {
285 volume_multiplier_ = volume_multiplier; 264 volume_multiplier_ = volume_multiplier;
286 for (const auto& it : players_) 265 for (const auto& it : players_)
287 it.observer->OnSetVolumeMultiplier(it.player_id, volume_multiplier_); 266 it.observer->OnSetVolumeMultiplier(it.player_id, volume_multiplier_);
288 } 267 }
289 268
290 MediaSession::MediaSession(WebContents* web_contents) 269 MediaSession::MediaSession(WebContents* web_contents)
291 : WebContentsObserver(web_contents), 270 : WebContentsObserver(web_contents),
271 default_system_audio_focus_response_(true),
292 audio_focus_state_(State::INACTIVE), 272 audio_focus_state_(State::INACTIVE),
293 audio_focus_type_(Type::Transient), 273 audio_focus_type_(Type::Transient),
294 volume_multiplier_(media::MediaPlayerAndroid::kDefaultVolumeMultiplier) { 274 volume_multiplier_(media::MediaPlayerAndroid::kDefaultVolumeMultiplier) {
295 } 275 }
296 276
297 void MediaSession::Initialize() { 277 void MediaSession::Initialize() {
298 JNIEnv* env = base::android::AttachCurrentThread(); 278 JNIEnv* env = base::android::AttachCurrentThread();
299 DCHECK(env); 279 DCHECK(env);
300 j_media_session_.Reset(Java_MediaSession_createMediaSession( 280 j_media_session_.Reset(Java_MediaSession_createMediaSession(
301 env, 281 env,
302 base::android::GetApplicationContext(), 282 base::android::GetApplicationContext(),
303 reinterpret_cast<intptr_t>(this))); 283 reinterpret_cast<intptr_t>(this)));
304 } 284 }
305 285
306 bool MediaSession::RequestSystemAudioFocus(Type type) { 286 bool MediaSession::RequestSystemAudioFocus(Type type) {
307 // During tests, j_media_session_ might be null. 287 // During tests, j_media_session_ might be null.
308 if (j_media_session_.is_null()) 288 if (j_media_session_.is_null())
309 return true; 289 return default_system_audio_focus_response_;
310 290
311 JNIEnv* env = base::android::AttachCurrentThread(); 291 JNIEnv* env = base::android::AttachCurrentThread();
312 DCHECK(env); 292 DCHECK(env);
313 bool result = Java_MediaSession_requestAudioFocus(env, j_media_session_.obj(), 293 bool result = Java_MediaSession_requestAudioFocus(env, j_media_session_.obj(),
314 type == Type::Transient); 294 type == Type::Transient);
315 uma_helper_.RecordRequestAudioFocusResult(result); 295 uma_helper_.RecordRequestAudioFocusResult(result);
316 return result; 296 return result;
317 } 297 }
318 298
319 void MediaSession::AbandonSystemAudioFocusIfNeeded() { 299 void MediaSession::AbandonSystemAudioFocusIfNeeded() {
(...skipping 27 matching lines...) Expand all
347 case State::SUSPENDED: 327 case State::SUSPENDED:
348 uma_helper_.OnSessionSuspended(); 328 uma_helper_.OnSessionSuspended();
349 break; 329 break;
350 case State::INACTIVE: 330 case State::INACTIVE:
351 uma_helper_.OnSessionInactive(); 331 uma_helper_.OnSessionInactive();
352 break; 332 break;
353 } 333 }
354 } 334 }
355 335
356 } // namespace content 336 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/media/android/media_session.h ('k') | content/browser/media/android/media_session_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698