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 {
virtual ~AudioFocusDelegate() = default;
virtual bool RequestAudioFocus(
enum class AudioFocusResult {
kSuccess,
kFailed,
kDelayed,
};
virtual AudioFocusResult RequestAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type) = 0;
virtual void AbandonAudioFocus() = 0;
// 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
......
......@@ -30,14 +30,17 @@ void AudioFocusDelegateAndroid::Initialize() {
Java_AudioFocusDelegate_create(env, reinterpret_cast<intptr_t>(this)));
}
bool AudioFocusDelegateAndroid::RequestAudioFocus(
AudioFocusDelegate::AudioFocusResult
AudioFocusDelegateAndroid::RequestAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type) {
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
return Java_AudioFocusDelegate_requestAudioFocus(
bool success = Java_AudioFocusDelegate_requestAudioFocus(
env, j_media_session_delegate_,
audio_focus_type ==
media_session::mojom::AudioFocusType::kGainTransientMayDuck);
return success ? AudioFocusDelegate::AudioFocusResult::kSuccess
: AudioFocusDelegate::AudioFocusResult::kFailed;
}
void AudioFocusDelegateAndroid::AbandonAudioFocus() {
......@@ -46,7 +49,7 @@ void AudioFocusDelegateAndroid::AbandonAudioFocus() {
Java_AudioFocusDelegate_abandonAudioFocus(env, j_media_session_delegate_);
}
media_session::mojom::AudioFocusType
base::Optional<media_session::mojom::AudioFocusType>
AudioFocusDelegateAndroid::GetCurrentFocusType() const {
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
......
......@@ -27,10 +27,11 @@ class AudioFocusDelegateAndroid : public AudioFocusDelegate {
void Initialize();
bool RequestAudioFocus(
AudioFocusResult RequestAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type) 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 by Java through JNI.
......
......@@ -23,9 +23,9 @@ class AudioFocusDelegateDefault : public AudioFocusDelegate {
~AudioFocusDelegateDefault() override;
// AudioFocusDelegate implementation.
bool RequestAudioFocus(AudioFocusType audio_focus_type) override;
AudioFocusResult RequestAudioFocus(AudioFocusType audio_focus_type) override;
void AbandonAudioFocus() override;
AudioFocusType GetCurrentFocusType() const override;
base::Optional<AudioFocusType> GetCurrentFocusType() const override;
private:
// Holds the current audio focus request id for |media_session_|.
......@@ -35,7 +35,7 @@ class AudioFocusDelegateDefault : public AudioFocusDelegate {
MediaSessionImpl* 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
......@@ -46,12 +46,12 @@ AudioFocusDelegateDefault::AudioFocusDelegateDefault(
AudioFocusDelegateDefault::~AudioFocusDelegateDefault() = default;
bool AudioFocusDelegateDefault::RequestAudioFocus(
AudioFocusType audio_focus_type) {
AudioFocusDelegate::AudioFocusResult
AudioFocusDelegateDefault::RequestAudioFocus(AudioFocusType audio_focus_type) {
audio_focus_type_if_disabled_ = audio_focus_type;
if (!media_session::IsAudioFocusEnabled())
return true;
return AudioFocusDelegate::AudioFocusResult::kSuccess;
media_session::mojom::MediaSessionInfoPtr session_info =
media_session_->GetMediaSessionInfoSync();
......@@ -67,10 +67,14 @@ bool AudioFocusDelegateDefault::RequestAudioFocus(
request_id_);
request_id_ = response.first;
return response.second;
return response.second ? AudioFocusDelegate::AudioFocusResult::kSuccess
: AudioFocusDelegate::AudioFocusResult::kFailed;
}
void AudioFocusDelegateDefault::AbandonAudioFocus() {
audio_focus_type_if_disabled_.reset();
if (!request_id_.has_value())
return;
......@@ -78,13 +82,16 @@ void AudioFocusDelegateDefault::AbandonAudioFocus() {
request_id_.reset();
}
AudioFocusType AudioFocusDelegateDefault::GetCurrentFocusType() const {
if (media_session::IsAudioFocusEnabled()) {
return AudioFocusManager::GetInstance()->GetFocusTypeForSession(
request_id_.value());
}
base::Optional<AudioFocusType> AudioFocusDelegateDefault::GetCurrentFocusType()
const {
if (!media_session::IsAudioFocusEnabled())
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
......
......@@ -15,6 +15,7 @@
#include "base/macros.h"
#include "base/observer_list.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/media_session_uma_helper.h"
#include "content/common/content_export.h"
......@@ -40,7 +41,6 @@ enum class MediaContentType;
namespace content {
class AudioFocusDelegate;
class AudioFocusManagerTest;
class MediaSessionImplServiceRoutingTest;
class MediaSessionImplStateObserver;
......@@ -158,7 +158,7 @@ class MediaSessionImpl : public MediaSession,
// Requests audio focus to the AudioFocusDelegate.
// Returns whether the request was granted.
CONTENT_EXPORT bool RequestSystemAudioFocus(
CONTENT_EXPORT AudioFocusDelegate::AudioFocusResult RequestSystemAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type);
// Creates a binding between |this| and |request|.
......@@ -222,6 +222,12 @@ class MediaSessionImpl : public MediaSession,
void AddObserver(
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:
friend class content::WebContentsUserData<MediaSessionImpl>;
friend class ::MediaSessionImplBrowserTest;
......@@ -245,6 +251,7 @@ class MediaSessionImpl : public MediaSession,
void operator=(const PlayerIdentifier&) = delete;
bool operator==(const PlayerIdentifier& player_identifier) const;
bool operator<(const PlayerIdentifier&) const;
// Hash operator for base::hash_map<>.
struct Hash {
......@@ -261,6 +268,10 @@ class MediaSessionImpl : public MediaSession,
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,
State new_state);
CONTENT_EXPORT void OnResumeInternal(MediaSession::SuspendType suspend_type);
......@@ -316,7 +327,8 @@ class MediaSessionImpl : public MediaSession,
CONTENT_EXPORT MediaSessionServiceImpl* ComputeServiceForRouting();
std::unique_ptr<AudioFocusDelegate> delegate_;
PlayersMap normal_players_;
std::map<PlayerIdentifier, media_session::mojom::AudioFocusType>
normal_players_;
PlayersMap pepper_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