Chromium Code Reviews| Index: content/browser/media/session/media_session.cc |
| diff --git a/content/browser/media/android/media_session.cc b/content/browser/media/session/media_session.cc |
| similarity index 73% |
| rename from content/browser/media/android/media_session.cc |
| rename to content/browser/media/session/media_session.cc |
| index 17321058233891f393d93ea690ec112ea1af0eee..0d4ed1e9efaff784cfbc7ae1d3ed3c8a4866265c 100644 |
| --- a/content/browser/media/android/media_session.cc |
| +++ b/content/browser/media/session/media_session.cc |
| @@ -2,19 +2,22 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#include "content/browser/media/android/media_session.h" |
| +#include "content/browser/media/session/media_session.h" |
| -#include "base/android/context_utils.h" |
| -#include "base/android/jni_android.h" |
| -#include "content/browser/media/android/media_session_observer.h" |
| +#include "content/browser/media/session/media_session_delegate.h" |
| +#include "content/browser/media/session/media_session_observer.h" |
| #include "content/browser/web_contents/web_contents_impl.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_contents_delegate.h" |
| -#include "jni/MediaSession_jni.h" |
| -#include "media/base/android/media_player_android.h" |
| namespace content { |
| +namespace { |
| + |
| +const double kDefaultVolumeMultiplier = 1.0; |
| + |
| +} // anonymous namespace |
| + |
| using MediaSessionSuspendedSource = |
| MediaSessionUmaHelper::MediaSessionSuspendedSource; |
| @@ -40,11 +43,6 @@ size_t MediaSession::PlayerIdentifier::Hash::operator()( |
| } |
| // static |
| -bool content::MediaSession::RegisterMediaSession(JNIEnv* env) { |
| - return RegisterNativesImpl(env); |
| -} |
| - |
| -// static |
| MediaSession* MediaSession::Get(WebContents* web_contents) { |
| MediaSession* session = FromWebContents(web_contents); |
| if (!session) { |
| @@ -115,29 +113,7 @@ void MediaSession::RemovePlayers(MediaSessionObserver* observer) { |
| AbandonSystemAudioFocusIfNeeded(); |
| } |
| -void MediaSession::OnSuspend(JNIEnv* env, |
| - const JavaParamRef<jobject>& obj, |
| - jboolean temporary) { |
| - // TODO(mlamouri): this check makes it so that if a MediaSession is paused and |
| - // then loses audio focus, it will still stay in the Suspended state. |
| - // See https://crbug.com/539998 |
| - if (audio_focus_state_ != State::ACTIVE) |
| - return; |
| - |
| - OnSuspendInternal(SuspendType::SYSTEM, |
| - temporary ? State::SUSPENDED : State::INACTIVE); |
| - |
| -} |
| - |
| -void MediaSession::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| - if (audio_focus_state_ != State::SUSPENDED) |
| - return; |
| - |
| - OnResumeInternal(SuspendType::SYSTEM); |
| -} |
| - |
| -void MediaSession::RecordSessionDuck(JNIEnv* env, |
| - const JavaParamRef<jobject>& obj) { |
| +void MediaSession::RecordSessionDuck() { |
| uma_helper_.RecordSessionSuspended( |
| MediaSessionSuspendedSource::SystemTransientDuck); |
| } |
| @@ -162,44 +138,66 @@ void MediaSession::OnPlayerPaused(MediaSessionObserver* observer, |
| DCHECK(!IsSuspended()); |
| OnSuspendInternal(SuspendType::CONTENT, State::SUSPENDED); |
| } |
| -void MediaSession::OnSetVolumeMultiplier(JNIEnv *env, jobject obj, |
| - jdouble volume_multiplier) { |
| - OnSetVolumeMultiplierInternal(volume_multiplier); |
| -} |
| -void MediaSession::Resume() { |
| - DCHECK(IsSuspended()); |
| +void MediaSession::Resume(SuspendType type) { |
| + DCHECK(IsReallySuspended()); |
| - // Request audio focus again in case we lost it because another app started |
| - // playing while the playback was paused. |
| - State audio_focus_state = RequestSystemAudioFocus(audio_focus_type_) |
| - ? State::ACTIVE |
| - : State::INACTIVE; |
| - SetAudioFocusState(audio_focus_state); |
| + // When the resume requests comes from another source than system, audio focus |
| + // must be requested. |
| + if (type != SuspendType::SYSTEM) { |
| + // Request audio focus again in case we lost it because another app started |
| + // playing while the playback was paused. |
| + State audio_focus_state = RequestSystemAudioFocus(audio_focus_type_) |
| + ? State::ACTIVE |
| + : State::INACTIVE; |
| + SetAudioFocusState(audio_focus_state); |
| - if (audio_focus_state_ != State::ACTIVE) |
| - return; |
| + if (audio_focus_state_ != State::ACTIVE) |
| + return; |
| + } |
| - OnResumeInternal(SuspendType::UI); |
| + OnResumeInternal(type); |
| } |
| -void MediaSession::Suspend() { |
| +void MediaSession::Suspend(SuspendType type) { |
| DCHECK(!IsSuspended()); |
| - OnSuspendInternal(SuspendType::UI, State::SUSPENDED); |
| + OnSuspendInternal(type, State::SUSPENDED); |
| } |
| -void MediaSession::Stop() { |
| +void MediaSession::Stop(SuspendType type) { |
| DCHECK(audio_focus_state_ != State::INACTIVE); |
| + DCHECK(type != SuspendType::CONTENT); |
| + |
| + // TODO(mlamouri): merge the logic between UI and SYSTEM. |
| + if (type == SuspendType::SYSTEM) { |
| + OnSuspendInternal(type, State::INACTIVE); |
| + return; |
| + } |
| + |
| if (audio_focus_state_ != State::SUSPENDED) |
| - OnSuspendInternal(SuspendType::UI, State::SUSPENDED); |
| + OnSuspendInternal(type, State::SUSPENDED); |
| DCHECK(audio_focus_state_ == State::SUSPENDED); |
| players_.clear(); |
| AbandonSystemAudioFocusIfNeeded(); |
| } |
| +void MediaSession::SetVolumeMultiplier(double volume_multiplier) { |
| + volume_multiplier_ = volume_multiplier; |
| + for (const auto& it : players_) |
| + it.observer->OnSetVolumeMultiplier(it.player_id, volume_multiplier_); |
| +} |
| + |
| +bool MediaSession::IsActive() const { |
| + return audio_focus_state_ == State::ACTIVE; |
| +} |
| + |
| +bool MediaSession::IsReallySuspended() const { |
| + return audio_focus_state_ == State::SUSPENDED; |
|
whywhat
2016/03/01 03:12:10
Given there's three states, your comment in the he
mlamouri (slow - plz ping)
2016/03/07 19:28:09
My comment says that ::IsSuspend() (not this metho
|
| +} |
| + |
| bool MediaSession::IsSuspended() const { |
| // TODO(mlamouri): should be == State::SUSPENDED. |
| return audio_focus_state_ != State::ACTIVE; |
| @@ -211,8 +209,9 @@ bool MediaSession::IsControllable() const { |
| audio_focus_type_ == Type::Content; |
| } |
| -void MediaSession::ResetJavaRefForTest() { |
| - j_media_session_.Reset(); |
| +void MediaSession::SetDelegateForTests( |
| + scoped_ptr<MediaSessionDelegate> delegate) { |
| + delegate_ = std::move(delegate); |
| } |
| bool MediaSession::IsActiveForTest() const { |
| @@ -237,6 +236,9 @@ void MediaSession::OnSuspendInternal(SuspendType type, State new_state) { |
| // UI suspend cannot use State::INACTIVE. |
| DCHECK(type == SuspendType::SYSTEM || new_state == State::SUSPENDED); |
| + if (audio_focus_state_ != State::ACTIVE) |
| + return; |
| + |
| switch (type) { |
| case SuspendType::UI: |
| uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::UI); |
| @@ -287,37 +289,19 @@ void MediaSession::OnResumeInternal(SuspendType type) { |
| UpdateWebContents(); |
| } |
| -void MediaSession::OnSetVolumeMultiplierInternal(double volume_multiplier) { |
| - volume_multiplier_ = volume_multiplier; |
| - for (const auto& it : players_) |
| - it.observer->OnSetVolumeMultiplier(it.player_id, volume_multiplier_); |
| -} |
| - |
| MediaSession::MediaSession(WebContents* web_contents) |
| : WebContentsObserver(web_contents), |
| audio_focus_state_(State::INACTIVE), |
| audio_focus_type_(Type::Transient), |
| - volume_multiplier_(media::MediaPlayerAndroid::kDefaultVolumeMultiplier) { |
| + volume_multiplier_(kDefaultVolumeMultiplier) { |
| } |
| void MediaSession::Initialize() { |
| - JNIEnv* env = base::android::AttachCurrentThread(); |
| - DCHECK(env); |
| - j_media_session_.Reset(Java_MediaSession_createMediaSession( |
| - env, |
| - base::android::GetApplicationContext(), |
| - reinterpret_cast<intptr_t>(this))); |
| + delegate_ = MediaSessionDelegate::Create(this); |
| } |
| bool MediaSession::RequestSystemAudioFocus(Type type) { |
| - // During tests, j_media_session_ might be null. |
| - if (j_media_session_.is_null()) |
| - return true; |
| - |
| - JNIEnv* env = base::android::AttachCurrentThread(); |
| - DCHECK(env); |
| - bool result = Java_MediaSession_requestAudioFocus(env, j_media_session_.obj(), |
| - type == Type::Transient); |
| + bool result = delegate_->RequestAudioFocus(type); |
| uma_helper_.RecordRequestAudioFocusResult(result); |
| return result; |
| } |
| @@ -326,12 +310,7 @@ void MediaSession::AbandonSystemAudioFocusIfNeeded() { |
| if (audio_focus_state_ == State::INACTIVE || !players_.empty()) |
| return; |
| - // During tests, j_media_session_ might be null. |
| - if (!j_media_session_.is_null()) { |
| - JNIEnv* env = base::android::AttachCurrentThread(); |
| - DCHECK(env); |
| - Java_MediaSession_abandonAudioFocus(env, j_media_session_.obj()); |
| - } |
| + delegate_->AbandonAudioFocus(); |
| SetAudioFocusState(State::INACTIVE); |
| UpdateWebContents(); |