| 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/android/media_session.h" | 5 #include "content/browser/media/android/media_session.h" |
| 6 | 6 |
| 7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
| 8 #include "content/browser/media/android/media_session_observer.h" | 8 #include "content/browser/media/android/media_session_observer.h" |
| 9 #include "content/public/browser/web_contents.h" |
| 10 #include "content/public/browser/web_contents_delegate.h" |
| 9 #include "jni/MediaSession_jni.h" | 11 #include "jni/MediaSession_jni.h" |
| 10 | 12 |
| 11 namespace content { | 13 namespace content { |
| 12 | 14 |
| 13 DEFINE_WEB_CONTENTS_USER_DATA_KEY(MediaSession); | 15 DEFINE_WEB_CONTENTS_USER_DATA_KEY(MediaSession); |
| 14 | 16 |
| 15 MediaSession::PlayerIdentifier::PlayerIdentifier(MediaSessionObserver* observer, | 17 MediaSession::PlayerIdentifier::PlayerIdentifier(MediaSessionObserver* observer, |
| 16 int player_id) | 18 int player_id) |
| 17 : observer(observer), | 19 : observer(observer), |
| 18 player_id(player_id) { | 20 player_id(player_id) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 // to request audio focus again. | 63 // to request audio focus again. |
| 62 if (audio_focus_state_ == State::Active && | 64 if (audio_focus_state_ == State::Active && |
| 63 (audio_focus_type_ == Type::Content || audio_focus_type_ == type)) { | 65 (audio_focus_type_ == Type::Content || audio_focus_type_ == type)) { |
| 64 players_.insert(PlayerIdentifier(observer, player_id)); | 66 players_.insert(PlayerIdentifier(observer, player_id)); |
| 65 return true; | 67 return true; |
| 66 } | 68 } |
| 67 | 69 |
| 68 State old_audio_focus_state = audio_focus_state_; | 70 State old_audio_focus_state = audio_focus_state_; |
| 69 audio_focus_state_ = RequestSystemAudioFocus(type) ? State::Active | 71 audio_focus_state_ = RequestSystemAudioFocus(type) ? State::Active |
| 70 : State::Suspended; | 72 : State::Suspended; |
| 73 Type old_audio_focus_type = audio_focus_type_; |
| 71 audio_focus_type_ = type; | 74 audio_focus_type_ = type; |
| 72 | 75 |
| 73 if (audio_focus_state_ != State::Active) | 76 if (audio_focus_state_ != State::Active) |
| 74 return false; | 77 return false; |
| 75 | 78 |
| 76 // The session should be reset if a player is starting while all players are | 79 // The session should be reset if a player is starting while all players are |
| 77 // suspended. | 80 // suspended. |
| 78 if (old_audio_focus_state != State::Active) | 81 if (old_audio_focus_state != State::Active) { |
| 82 // Hide the controls if the type switched from Content to Transient. |
| 83 if (audio_focus_type_ == Type::Transient) |
| 84 HideMediaControlsIfNeeded(old_audio_focus_type); |
| 79 players_.clear(); | 85 players_.clear(); |
| 86 } |
| 80 | 87 |
| 81 players_.insert(PlayerIdentifier(observer, player_id)); | 88 players_.insert(PlayerIdentifier(observer, player_id)); |
| 89 ShowMediaControlsIfNeeded(audio_focus_type_); |
| 82 | 90 |
| 83 return true; | 91 return true; |
| 84 } | 92 } |
| 85 | 93 |
| 86 void MediaSession::RemovePlayer(MediaSessionObserver* observer, | 94 void MediaSession::RemovePlayer(MediaSessionObserver* observer, |
| 87 int player_id) { | 95 int player_id) { |
| 88 auto it = players_.find(PlayerIdentifier(observer, player_id)); | 96 auto it = players_.find(PlayerIdentifier(observer, player_id)); |
| 89 if (it != players_.end()) | 97 if (it != players_.end()) |
| 90 players_.erase(it); | 98 players_.erase(it); |
| 91 | 99 |
| 92 AbandonSystemAudioFocusIfNeeded(); | 100 AbandonSystemAudioFocusIfNeeded(); |
| 93 } | 101 } |
| 94 | 102 |
| 95 void MediaSession::RemovePlayers(MediaSessionObserver* observer) { | 103 void MediaSession::RemovePlayers(MediaSessionObserver* observer) { |
| 96 for (auto it = players_.begin(); it != players_.end();) { | 104 for (auto it = players_.begin(); it != players_.end();) { |
| 97 if (it->observer == observer) | 105 if (it->observer == observer) |
| 98 players_.erase(it++); | 106 players_.erase(it++); |
| 99 else | 107 else |
| 100 ++it; | 108 ++it; |
| 101 } | 109 } |
| 102 | 110 |
| 103 AbandonSystemAudioFocusIfNeeded(); | 111 AbandonSystemAudioFocusIfNeeded(); |
| 104 } | 112 } |
| 105 | 113 |
| 106 void MediaSession::OnSuspend(JNIEnv* env, jobject obj, jboolean temporary) { | 114 void MediaSession::OnSuspend(JNIEnv* env, jobject obj, jboolean temporary) { |
| 107 OnSuspend(temporary); | 115 OnSuspend(temporary); |
| 116 |
| 117 if (temporary) { |
| 118 // Reflect the paused state on the media controls. |
| 119 ShowMediaControlsIfNeeded(audio_focus_type_); |
| 120 } else { |
| 121 HideMediaControlsIfNeeded(audio_focus_type_); |
| 122 } |
| 108 } | 123 } |
| 109 | 124 |
| 110 void MediaSession::OnResume(JNIEnv* env, jobject obj) { | 125 void MediaSession::OnResume(JNIEnv* env, jobject obj) { |
| 111 OnResume(); | 126 OnResume(); |
| 127 ShowMediaControlsIfNeeded(audio_focus_type_); |
| 128 } |
| 129 |
| 130 void MediaSession::OnControlsPause() { |
| 131 DCHECK(!IsPaused()); |
| 132 |
| 133 // Since the playback can be resumed, it's a transient suspension. |
| 134 OnSuspend(true); |
| 135 } |
| 136 |
| 137 void MediaSession::OnControlsResume() { |
| 138 DCHECK(IsPaused()); |
| 139 |
| 140 OnResume(); |
| 141 } |
| 142 |
| 143 bool MediaSession::IsPaused() { |
| 144 return audio_focus_state_ != State::Active; |
| 112 } | 145 } |
| 113 | 146 |
| 114 void MediaSession::ResetJavaRefForTest() { | 147 void MediaSession::ResetJavaRefForTest() { |
| 115 j_media_session_.Reset(); | 148 j_media_session_.Reset(); |
| 116 } | 149 } |
| 117 | 150 |
| 118 bool MediaSession::IsActiveForTest() const { | 151 bool MediaSession::IsActiveForTest() const { |
| 119 return audio_focus_state_ == State::Active; | 152 return audio_focus_state_ == State::Active; |
| 120 } | 153 } |
| 121 | 154 |
| 122 MediaSession::Type MediaSession::audio_focus_type_for_test() const { | 155 MediaSession::Type MediaSession::audio_focus_type_for_test() const { |
| 123 return audio_focus_type_; | 156 return audio_focus_type_; |
| 124 } | 157 } |
| 125 | 158 |
| 159 void MediaSession::RemoveAllPlayersForTest() { |
| 160 players_.clear(); |
| 161 AbandonSystemAudioFocusIfNeeded(); |
| 162 } |
| 163 |
| 126 void MediaSession::OnSuspend(bool temporary) { | 164 void MediaSession::OnSuspend(bool temporary) { |
| 127 if (temporary) | 165 if (temporary) |
| 128 audio_focus_state_ = State::TemporarilySuspended; | 166 audio_focus_state_ = State::TemporarilySuspended; |
| 129 else | 167 else |
| 130 audio_focus_state_ = State::Suspended; | 168 audio_focus_state_ = State::Suspended; |
| 131 | 169 |
| 132 for (const auto& it : players_) | 170 for (const auto& it : players_) |
| 133 it.observer->OnSuspend(it.player_id); | 171 it.observer->OnSuspend(it.player_id); |
| 134 } | 172 } |
| 135 | 173 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 return; | 209 return; |
| 172 | 210 |
| 173 // During tests, j_media_session_ might be null. | 211 // During tests, j_media_session_ might be null. |
| 174 if (!j_media_session_.is_null()) { | 212 if (!j_media_session_.is_null()) { |
| 175 JNIEnv* env = base::android::AttachCurrentThread(); | 213 JNIEnv* env = base::android::AttachCurrentThread(); |
| 176 DCHECK(env); | 214 DCHECK(env); |
| 177 Java_MediaSession_abandonAudioFocus(env, j_media_session_.obj()); | 215 Java_MediaSession_abandonAudioFocus(env, j_media_session_.obj()); |
| 178 } | 216 } |
| 179 | 217 |
| 180 audio_focus_state_ = State::Suspended; | 218 audio_focus_state_ = State::Suspended; |
| 219 HideMediaControlsIfNeeded(audio_focus_type_); |
| 220 } |
| 221 |
| 222 void MediaSession::ShowMediaControlsIfNeeded(Type audio_focus_type) { |
| 223 if (audio_focus_type == Type::Content && web_contents()->GetDelegate()) |
| 224 web_contents()->GetDelegate()->ShowMediaControls(web_contents()); |
| 225 } |
| 226 |
| 227 void MediaSession::HideMediaControlsIfNeeded(Type audio_focus_type) { |
| 228 if (audio_focus_type == Type::Content && web_contents()->GetDelegate()) |
| 229 web_contents()->GetDelegate()->HideMediaControls(web_contents()); |
| 181 } | 230 } |
| 182 | 231 |
| 183 } // namespace content | 232 } // namespace content |
| OLD | NEW |