Commit d55bc9fe authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Media Session] Allow async audio focus requests

For cross process audio focus requests we need to support
async audio focus requests in MediaSessionImpl. This adds
support and test coverage but does not yet fully convert
them to async.

BUG=875004

Change-Id: Ie4236b5e78d63593d9ec3bf0968e03bef36ee1fc
Reviewed-on: https://chromium-review.googlesource.com/c/1192105
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#596371}
parent 667592b2
...@@ -27,12 +27,19 @@ class AudioFocusDelegate { ...@@ -27,12 +27,19 @@ class AudioFocusDelegate {
virtual ~AudioFocusDelegate() = default; virtual ~AudioFocusDelegate() = default;
virtual bool RequestAudioFocus( enum class AudioFocusResult {
kSuccess,
kFailed,
kDelayed,
};
virtual AudioFocusResult RequestAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type) = 0; media_session::mojom::AudioFocusType audio_focus_type) = 0;
virtual void AbandonAudioFocus() = 0; virtual void AbandonAudioFocus() = 0;
// Retrieves the current |AudioFocusType| for the associated |MediaSession|. // Retrieves the current |AudioFocusType| for the associated |MediaSession|.
virtual media_session::mojom::AudioFocusType GetCurrentFocusType() const = 0; virtual base::Optional<media_session::mojom::AudioFocusType>
GetCurrentFocusType() const = 0;
}; };
} // namespace content } // namespace content
......
...@@ -30,14 +30,17 @@ void AudioFocusDelegateAndroid::Initialize() { ...@@ -30,14 +30,17 @@ void AudioFocusDelegateAndroid::Initialize() {
Java_AudioFocusDelegate_create(env, reinterpret_cast<intptr_t>(this))); Java_AudioFocusDelegate_create(env, reinterpret_cast<intptr_t>(this)));
} }
bool AudioFocusDelegateAndroid::RequestAudioFocus( AudioFocusDelegate::AudioFocusResult
AudioFocusDelegateAndroid::RequestAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type) { media_session::mojom::AudioFocusType audio_focus_type) {
JNIEnv* env = base::android::AttachCurrentThread(); JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env); DCHECK(env);
return Java_AudioFocusDelegate_requestAudioFocus( bool success = Java_AudioFocusDelegate_requestAudioFocus(
env, j_media_session_delegate_, env, j_media_session_delegate_,
audio_focus_type == audio_focus_type ==
media_session::mojom::AudioFocusType::kGainTransientMayDuck); media_session::mojom::AudioFocusType::kGainTransientMayDuck);
return success ? AudioFocusDelegate::AudioFocusResult::kSuccess
: AudioFocusDelegate::AudioFocusResult::kFailed;
} }
void AudioFocusDelegateAndroid::AbandonAudioFocus() { void AudioFocusDelegateAndroid::AbandonAudioFocus() {
...@@ -46,7 +49,7 @@ void AudioFocusDelegateAndroid::AbandonAudioFocus() { ...@@ -46,7 +49,7 @@ void AudioFocusDelegateAndroid::AbandonAudioFocus() {
Java_AudioFocusDelegate_abandonAudioFocus(env, j_media_session_delegate_); Java_AudioFocusDelegate_abandonAudioFocus(env, j_media_session_delegate_);
} }
media_session::mojom::AudioFocusType base::Optional<media_session::mojom::AudioFocusType>
AudioFocusDelegateAndroid::GetCurrentFocusType() const { AudioFocusDelegateAndroid::GetCurrentFocusType() const {
JNIEnv* env = base::android::AttachCurrentThread(); JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env); DCHECK(env);
......
...@@ -27,10 +27,11 @@ class AudioFocusDelegateAndroid : public AudioFocusDelegate { ...@@ -27,10 +27,11 @@ class AudioFocusDelegateAndroid : public AudioFocusDelegate {
void Initialize(); void Initialize();
bool RequestAudioFocus( AudioFocusResult RequestAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type) override; media_session::mojom::AudioFocusType audio_focus_type) override;
void AbandonAudioFocus() override; void AbandonAudioFocus() override;
media_session::mojom::AudioFocusType GetCurrentFocusType() const override; base::Optional<media_session::mojom::AudioFocusType> GetCurrentFocusType()
const override;
// Called when the Android system requests the MediaSession to be suspended. // Called when the Android system requests the MediaSession to be suspended.
// Called by Java through JNI. // Called by Java through JNI.
......
...@@ -23,9 +23,9 @@ class AudioFocusDelegateDefault : public AudioFocusDelegate { ...@@ -23,9 +23,9 @@ class AudioFocusDelegateDefault : public AudioFocusDelegate {
~AudioFocusDelegateDefault() override; ~AudioFocusDelegateDefault() override;
// AudioFocusDelegate implementation. // AudioFocusDelegate implementation.
bool RequestAudioFocus(AudioFocusType audio_focus_type) override; AudioFocusResult RequestAudioFocus(AudioFocusType audio_focus_type) override;
void AbandonAudioFocus() override; void AbandonAudioFocus() override;
AudioFocusType GetCurrentFocusType() const override; base::Optional<AudioFocusType> GetCurrentFocusType() const override;
private: private:
// Holds the current audio focus request id for |media_session_|. // Holds the current audio focus request id for |media_session_|.
...@@ -35,7 +35,7 @@ class AudioFocusDelegateDefault : public AudioFocusDelegate { ...@@ -35,7 +35,7 @@ class AudioFocusDelegateDefault : public AudioFocusDelegate {
MediaSessionImpl* media_session_; MediaSessionImpl* media_session_;
// The last requested AudioFocusType by the associated |media_session_|. // The last requested AudioFocusType by the associated |media_session_|.
AudioFocusType audio_focus_type_if_disabled_; base::Optional<AudioFocusType> audio_focus_type_if_disabled_;
}; };
} // anonymous namespace } // anonymous namespace
...@@ -46,12 +46,12 @@ AudioFocusDelegateDefault::AudioFocusDelegateDefault( ...@@ -46,12 +46,12 @@ AudioFocusDelegateDefault::AudioFocusDelegateDefault(
AudioFocusDelegateDefault::~AudioFocusDelegateDefault() = default; AudioFocusDelegateDefault::~AudioFocusDelegateDefault() = default;
bool AudioFocusDelegateDefault::RequestAudioFocus( AudioFocusDelegate::AudioFocusResult
AudioFocusType audio_focus_type) { AudioFocusDelegateDefault::RequestAudioFocus(AudioFocusType audio_focus_type) {
audio_focus_type_if_disabled_ = audio_focus_type; audio_focus_type_if_disabled_ = audio_focus_type;
if (!media_session::IsAudioFocusEnabled()) if (!media_session::IsAudioFocusEnabled())
return true; return AudioFocusDelegate::AudioFocusResult::kSuccess;
media_session::mojom::MediaSessionInfoPtr session_info = media_session::mojom::MediaSessionInfoPtr session_info =
media_session_->GetMediaSessionInfoSync(); media_session_->GetMediaSessionInfoSync();
...@@ -67,10 +67,14 @@ bool AudioFocusDelegateDefault::RequestAudioFocus( ...@@ -67,10 +67,14 @@ bool AudioFocusDelegateDefault::RequestAudioFocus(
request_id_); request_id_);
request_id_ = response.first; request_id_ = response.first;
return response.second;
return response.second ? AudioFocusDelegate::AudioFocusResult::kSuccess
: AudioFocusDelegate::AudioFocusResult::kFailed;
} }
void AudioFocusDelegateDefault::AbandonAudioFocus() { void AudioFocusDelegateDefault::AbandonAudioFocus() {
audio_focus_type_if_disabled_.reset();
if (!request_id_.has_value()) if (!request_id_.has_value())
return; return;
...@@ -78,13 +82,16 @@ void AudioFocusDelegateDefault::AbandonAudioFocus() { ...@@ -78,13 +82,16 @@ void AudioFocusDelegateDefault::AbandonAudioFocus() {
request_id_.reset(); request_id_.reset();
} }
AudioFocusType AudioFocusDelegateDefault::GetCurrentFocusType() const { base::Optional<AudioFocusType> AudioFocusDelegateDefault::GetCurrentFocusType()
if (media_session::IsAudioFocusEnabled()) { const {
return AudioFocusManager::GetInstance()->GetFocusTypeForSession( if (!media_session::IsAudioFocusEnabled())
request_id_.value()); return audio_focus_type_if_disabled_;
}
if (!request_id_.has_value())
return base::Optional<AudioFocusType>();
return audio_focus_type_if_disabled_; return AudioFocusManager::GetInstance()->GetFocusTypeForSession(
request_id_.value());
} }
// static // static
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/optional.h" #include "base/optional.h"
#include "content/browser/media/session/audio_focus_delegate.h"
#include "content/browser/media/session/audio_focus_manager.h" #include "content/browser/media/session/audio_focus_manager.h"
#include "content/browser/media/session/media_session_uma_helper.h" #include "content/browser/media/session/media_session_uma_helper.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
...@@ -40,7 +41,6 @@ enum class MediaContentType; ...@@ -40,7 +41,6 @@ enum class MediaContentType;
namespace content { namespace content {
class AudioFocusDelegate;
class AudioFocusManagerTest; class AudioFocusManagerTest;
class MediaSessionImplServiceRoutingTest; class MediaSessionImplServiceRoutingTest;
class MediaSessionImplStateObserver; class MediaSessionImplStateObserver;
...@@ -158,7 +158,7 @@ class MediaSessionImpl : public MediaSession, ...@@ -158,7 +158,7 @@ class MediaSessionImpl : public MediaSession,
// Requests audio focus to the AudioFocusDelegate. // Requests audio focus to the AudioFocusDelegate.
// Returns whether the request was granted. // Returns whether the request was granted.
CONTENT_EXPORT bool RequestSystemAudioFocus( CONTENT_EXPORT AudioFocusDelegate::AudioFocusResult RequestSystemAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type); media_session::mojom::AudioFocusType audio_focus_type);
// Creates a binding between |this| and |request|. // Creates a binding between |this| and |request|.
...@@ -222,6 +222,12 @@ class MediaSessionImpl : public MediaSession, ...@@ -222,6 +222,12 @@ class MediaSessionImpl : public MediaSession,
void AddObserver( void AddObserver(
media_session::mojom::MediaSessionObserverPtr observer) override; media_session::mojom::MediaSessionObserverPtr observer) override;
// Called by |AudioFocusDelegate| when an async audio focus request is
// completed.
CONTENT_EXPORT void FinishSystemAudioFocusRequest(
media_session::mojom::AudioFocusType type,
bool result);
private: private:
friend class content::WebContentsUserData<MediaSessionImpl>; friend class content::WebContentsUserData<MediaSessionImpl>;
friend class ::MediaSessionImplBrowserTest; friend class ::MediaSessionImplBrowserTest;
...@@ -245,6 +251,7 @@ class MediaSessionImpl : public MediaSession, ...@@ -245,6 +251,7 @@ class MediaSessionImpl : public MediaSession,
void operator=(const PlayerIdentifier&) = delete; void operator=(const PlayerIdentifier&) = delete;
bool operator==(const PlayerIdentifier& player_identifier) const; bool operator==(const PlayerIdentifier& player_identifier) const;
bool operator<(const PlayerIdentifier&) const;
// Hash operator for base::hash_map<>. // Hash operator for base::hash_map<>.
struct Hash { struct Hash {
...@@ -261,6 +268,10 @@ class MediaSessionImpl : public MediaSession, ...@@ -261,6 +268,10 @@ class MediaSessionImpl : public MediaSession,
void Initialize(); void Initialize();
// Called when system audio focus has been requested and whether the request
// was granted.
void OnSystemAudioFocusRequested(bool result);
CONTENT_EXPORT void OnSuspendInternal(MediaSession::SuspendType suspend_type, CONTENT_EXPORT void OnSuspendInternal(MediaSession::SuspendType suspend_type,
State new_state); State new_state);
CONTENT_EXPORT void OnResumeInternal(MediaSession::SuspendType suspend_type); CONTENT_EXPORT void OnResumeInternal(MediaSession::SuspendType suspend_type);
...@@ -316,7 +327,8 @@ class MediaSessionImpl : public MediaSession, ...@@ -316,7 +327,8 @@ class MediaSessionImpl : public MediaSession,
CONTENT_EXPORT MediaSessionServiceImpl* ComputeServiceForRouting(); CONTENT_EXPORT MediaSessionServiceImpl* ComputeServiceForRouting();
std::unique_ptr<AudioFocusDelegate> delegate_; std::unique_ptr<AudioFocusDelegate> delegate_;
PlayersMap normal_players_; std::map<PlayerIdentifier, media_session::mojom::AudioFocusType>
normal_players_;
PlayersMap pepper_players_; PlayersMap pepper_players_;
PlayersMap one_shot_players_; PlayersMap one_shot_players_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment