Commit e331af1b authored by Noah Rose Ledesma's avatar Noah Rose Ledesma Committed by Commit Bot

GMC: Add OnSetAudioSinkId to MediaSessionPlayerObserver

Changing audio sinks on pepper players is not supported. The mock media
session player observer needs to have OnSetSinkId implemented.

Bug: 1096246
Change-Id: Ie08b36cff98f4beb2a4148e0bd05e27e993308f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2295748
Commit-Queue: Noah Rose Ledesma <noahrose@google.com>
Reviewed-by: default avatarBecca Hughes <beccahughes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#794772}
parent 67a9b3fb
...@@ -4,10 +4,14 @@ ...@@ -4,10 +4,14 @@
#include "content/browser/media/session/media_session_controller.h" #include "content/browser/media/session/media_session_controller.h"
#include "content/browser/media/media_devices_util.h"
#include "content/browser/media/media_web_contents_observer.h"
#include "content/browser/media/session/media_session_impl.h" #include "content/browser/media/session/media_session_impl.h"
#include "content/common/media/media_player_delegate_messages.h" #include "content/common/media/media_player_delegate_messages.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/media_device_id.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "media/base/media_content_type.h" #include "media/base/media_content_type.h"
...@@ -87,6 +91,10 @@ void MediaSessionController::OnExitPictureInPicture(int player_id) { ...@@ -87,6 +91,10 @@ void MediaSessionController::OnExitPictureInPicture(int player_id) {
id_.render_frame_host->GetRoutingID(), id_.delegate_id)); id_.render_frame_host->GetRoutingID(), id_.delegate_id));
} }
void MediaSessionController::OnSetAudioSinkId(
int player_id,
const std::string& raw_device_id) {}
RenderFrameHost* MediaSessionController::render_frame_host() const { RenderFrameHost* MediaSessionController::render_frame_host() const {
return id_.render_frame_host; return id_.render_frame_host;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_MEDIA_SESSION_MEDIA_SESSION_CONTROLLER_H_ #define CONTENT_BROWSER_MEDIA_SESSION_MEDIA_SESSION_CONTROLLER_H_
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "content/browser/media/session/media_session_player_observer.h" #include "content/browser/media/session/media_session_player_observer.h"
...@@ -50,6 +51,8 @@ class CONTENT_EXPORT MediaSessionController ...@@ -50,6 +51,8 @@ class CONTENT_EXPORT MediaSessionController
void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override; void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override;
void OnEnterPictureInPicture(int player_id) override; void OnEnterPictureInPicture(int player_id) override;
void OnExitPictureInPicture(int player_id) override; void OnExitPictureInPicture(int player_id) override;
void OnSetAudioSinkId(int player_id,
const std::string& raw_device_id) override;
RenderFrameHost* render_frame_host() const override; RenderFrameHost* render_frame_host() const override;
base::Optional<media_session::MediaPosition> GetPosition( base::Optional<media_session::MediaPosition> GetPosition(
int player_id) const override; int player_id) const override;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h" #include "content/public/common/content_client.h"
#include "media/audio/audio_device_description.h"
#include "media/base/media_content_type.h" #include "media/base/media_content_type.h"
#include "media/base/media_switches.h" #include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/callback_helpers.h" #include "mojo/public/cpp/bindings/callback_helpers.h"
...@@ -1071,7 +1072,13 @@ void MediaSessionImpl::ExitPictureInPicture() { ...@@ -1071,7 +1072,13 @@ void MediaSessionImpl::ExitPictureInPicture() {
normal_players_.begin()->first.player_id); normal_players_.begin()->first.player_id);
} }
void MediaSessionImpl::SetAudioSinkId(const base::Optional<std::string>& id) {} void MediaSessionImpl::SetAudioSinkId(const base::Optional<std::string>& id) {
for (const auto& it : normal_players_) {
it.first.observer->OnSetAudioSinkId(
it.first.player_id,
id.value_or(media::AudioDeviceDescription::kDefaultDeviceId));
}
}
void MediaSessionImpl::GetMediaImageBitmap( void MediaSessionImpl::GetMediaImageBitmap(
const media_session::MediaImage& image, const media_session::MediaImage& image,
......
...@@ -40,10 +40,10 @@ using media_session::mojom::AudioFocusType; ...@@ -40,10 +40,10 @@ using media_session::mojom::AudioFocusType;
using media_session::mojom::MediaPlaybackState; using media_session::mojom::MediaPlaybackState;
using media_session::mojom::MediaSessionInfo; using media_session::mojom::MediaSessionInfo;
using ::testing::_;
using ::testing::Eq; using ::testing::Eq;
using ::testing::Expectation; using ::testing::Expectation;
using ::testing::NiceMock; using ::testing::NiceMock;
using ::testing::_;
namespace { namespace {
...@@ -56,6 +56,8 @@ const base::string16 kExpectedSourceTitlePrefix = ...@@ -56,6 +56,8 @@ const base::string16 kExpectedSourceTitlePrefix =
constexpr gfx::Size kDefaultFaviconSize = gfx::Size(16, 16); constexpr gfx::Size kDefaultFaviconSize = gfx::Size(16, 16);
const std::string kExampleSinkId = "example_device_id";
class MockAudioFocusDelegate : public content::AudioFocusDelegate { class MockAudioFocusDelegate : public content::AudioFocusDelegate {
public: public:
MockAudioFocusDelegate(content::MediaSessionImpl* media_session, MockAudioFocusDelegate(content::MediaSessionImpl* media_session,
...@@ -213,6 +215,10 @@ class MediaSessionImplBrowserTest : public ContentBrowserTest { ...@@ -213,6 +215,10 @@ class MediaSessionImplBrowserTest : public ContentBrowserTest {
media_session_->Seek(base::TimeDelta::FromSeconds(-1)); media_session_->Seek(base::TimeDelta::FromSeconds(-1));
} }
void UISetAudioSink(const std::string& sink_id) {
media_session_->SetAudioSinkId(sink_id);
}
void SystemStartDucking() { media_session_->StartDucking(); } void SystemStartDucking() { media_session_->StartDucking(); }
void SystemStopDucking() { media_session_->StopDucking(); } void SystemStopDucking() { media_session_->StopDucking(); }
...@@ -2592,6 +2598,17 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ...@@ -2592,6 +2598,17 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
} }
} }
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
SinkIdChangeNotifiesObservers) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
UISetAudioSink(kExampleSinkId);
EXPECT_EQ(player_observer->received_set_audio_sink_id_calls(), 1);
EXPECT_EQ(player_observer->GetAudioSinkId(0), kExampleSinkId);
}
class MediaSessionFaviconBrowserTest : public ContentBrowserTest { class MediaSessionFaviconBrowserTest : public ContentBrowserTest {
protected: protected:
MediaSessionFaviconBrowserTest() = default; MediaSessionFaviconBrowserTest() = default;
......
...@@ -53,6 +53,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { ...@@ -53,6 +53,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
void(int player_id, double volume_multiplier)); void(int player_id, double volume_multiplier));
MOCK_METHOD1(OnEnterPictureInPicture, void(int player_id)); MOCK_METHOD1(OnEnterPictureInPicture, void(int player_id));
MOCK_METHOD1(OnExitPictureInPicture, void(int player_id)); MOCK_METHOD1(OnExitPictureInPicture, void(int player_id));
MOCK_METHOD2(OnSetAudioSinkId,
void(int player_id, const std::string& raw_device_id));
base::Optional<media_session::MediaPosition> GetPosition( base::Optional<media_session::MediaPosition> GetPosition(
int player_id) const override { int player_id) const override {
......
...@@ -41,6 +41,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { ...@@ -41,6 +41,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
} }
void OnEnterPictureInPicture(int player_id) override {} void OnEnterPictureInPicture(int player_id) override {}
void OnExitPictureInPicture(int player_id) override {} void OnExitPictureInPicture(int player_id) override {}
void OnSetAudioSinkId(int player_id,
const std::string& raw_device_id) override {}
base::Optional<media_session::MediaPosition> GetPosition( base::Optional<media_session::MediaPosition> GetPosition(
int player_id) const override { int player_id) const override {
......
...@@ -44,6 +44,11 @@ class MediaSessionPlayerObserver { ...@@ -44,6 +44,11 @@ class MediaSessionPlayerObserver {
// The given |player_id| has been requested to exit picture-in-picture. // The given |player_id| has been requested to exit picture-in-picture.
virtual void OnExitPictureInPicture(int player_id) = 0; virtual void OnExitPictureInPicture(int player_id) = 0;
// The given |player_id| has been requested to route audio output to the
// specified audio device.
virtual void OnSetAudioSinkId(int player_id,
const std::string& raw_device_id) = 0;
// Returns the position for |player_id|. // Returns the position for |player_id|.
virtual base::Optional<media_session::MediaPosition> GetPosition( virtual base::Optional<media_session::MediaPosition> GetPosition(
int player_id) const = 0; int player_id) const = 0;
......
...@@ -54,6 +54,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { ...@@ -54,6 +54,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
} }
void OnEnterPictureInPicture(int player_id) override {} void OnEnterPictureInPicture(int player_id) override {}
void OnExitPictureInPicture(int player_id) override {} void OnExitPictureInPicture(int player_id) override {}
void OnSetAudioSinkId(int player_id,
const std::string& raw_device_id) override {}
base::Optional<media_session::MediaPosition> GetPosition( base::Optional<media_session::MediaPosition> GetPosition(
int player_id) const override { int player_id) const override {
......
...@@ -72,6 +72,16 @@ void MockMediaSessionPlayerObserver::OnExitPictureInPicture(int player_id) { ...@@ -72,6 +72,16 @@ void MockMediaSessionPlayerObserver::OnExitPictureInPicture(int player_id) {
players_[player_id].is_in_picture_in_picture_ = false; players_[player_id].is_in_picture_in_picture_ = false;
} }
void MockMediaSessionPlayerObserver::OnSetAudioSinkId(
int player_id,
const std::string& raw_device_id) {
EXPECT_GE(player_id, 0);
EXPECT_EQ(players_.size(), 1u);
++received_set_audio_sink_id_calls_;
players_[player_id].audio_sink_id_ = raw_device_id;
}
base::Optional<media_session::MediaPosition> base::Optional<media_session::MediaPosition>
MockMediaSessionPlayerObserver::GetPosition(int player_id) const { MockMediaSessionPlayerObserver::GetPosition(int player_id) const {
EXPECT_GE(player_id, 0); EXPECT_GE(player_id, 0);
...@@ -105,6 +115,12 @@ double MockMediaSessionPlayerObserver::GetVolumeMultiplier(size_t player_id) { ...@@ -105,6 +115,12 @@ double MockMediaSessionPlayerObserver::GetVolumeMultiplier(size_t player_id) {
return players_[player_id].volume_multiplier_; return players_[player_id].volume_multiplier_;
} }
const std::string& MockMediaSessionPlayerObserver::GetAudioSinkId(
size_t player_id) {
EXPECT_GT(players_.size(), player_id);
return players_[player_id].audio_sink_id_;
}
void MockMediaSessionPlayerObserver::SetPlaying(size_t player_id, void MockMediaSessionPlayerObserver::SetPlaying(size_t player_id,
bool playing) { bool playing) {
EXPECT_GT(players_.size(), player_id); EXPECT_GT(players_.size(), player_id);
...@@ -144,15 +160,23 @@ int MockMediaSessionPlayerObserver::received_exit_picture_in_picture_calls() ...@@ -144,15 +160,23 @@ int MockMediaSessionPlayerObserver::received_exit_picture_in_picture_calls()
return received_exit_picture_in_picture_calls_; return received_exit_picture_in_picture_calls_;
} }
int MockMediaSessionPlayerObserver::received_set_audio_sink_id_calls() const {
return received_set_audio_sink_id_calls_;
}
bool MockMediaSessionPlayerObserver::HasVideo(int player_id) const { bool MockMediaSessionPlayerObserver::HasVideo(int player_id) const {
EXPECT_GE(player_id, 0); EXPECT_GE(player_id, 0);
EXPECT_GT(players_.size(), static_cast<size_t>(player_id)); EXPECT_GT(players_.size(), static_cast<size_t>(player_id));
return false; return false;
} }
MockMediaSessionPlayerObserver::MockPlayer::MockPlayer(bool is_playing, MockMediaSessionPlayerObserver::MockPlayer::MockPlayer(
double volume_multiplier) bool is_playing,
: is_playing_(is_playing), volume_multiplier_(volume_multiplier) {} double volume_multiplier,
const std::string& audio_sink_id)
: is_playing_(is_playing),
volume_multiplier_(volume_multiplier),
audio_sink_id_(audio_sink_id) {}
MockMediaSessionPlayerObserver::MockPlayer::~MockPlayer() = default; MockMediaSessionPlayerObserver::MockPlayer::~MockPlayer() = default;
......
...@@ -30,6 +30,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { ...@@ -30,6 +30,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override; void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override;
void OnEnterPictureInPicture(int player_id) override; void OnEnterPictureInPicture(int player_id) override;
void OnExitPictureInPicture(int player_id) override; void OnExitPictureInPicture(int player_id) override;
void OnSetAudioSinkId(int player_id,
const std::string& raw_device_id) override;
base::Optional<media_session::MediaPosition> GetPosition( base::Optional<media_session::MediaPosition> GetPosition(
int player_id) const override; int player_id) const override;
bool IsPictureInPictureAvailable(int player_id) const override; bool IsPictureInPictureAvailable(int player_id) const override;
...@@ -46,6 +48,9 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { ...@@ -46,6 +48,9 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
// Returns the volume multiplier of |player_id|. // Returns the volume multiplier of |player_id|.
double GetVolumeMultiplier(size_t player_id); double GetVolumeMultiplier(size_t player_id);
// Returns the sink id being used for the audio output of |player_id|
const std::string& GetAudioSinkId(size_t player_id);
// Simulate a play state change for |player_id|. // Simulate a play state change for |player_id|.
void SetPlaying(size_t player_id, bool playing); void SetPlaying(size_t player_id, bool playing);
...@@ -58,12 +63,15 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { ...@@ -58,12 +63,15 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
int received_seek_backward_calls() const; int received_seek_backward_calls() const;
int received_enter_picture_in_picture_calls() const; int received_enter_picture_in_picture_calls() const;
int received_exit_picture_in_picture_calls() const; int received_exit_picture_in_picture_calls() const;
int received_set_audio_sink_id_calls() const;
private: private:
// Internal representation of the players to keep track of their statuses. // Internal representation of the players to keep track of their statuses.
struct MockPlayer { struct MockPlayer {
public: public:
MockPlayer(bool is_playing = true, double volume_multiplier = 1.0f); explicit MockPlayer(bool is_playing = true,
double volume_multiplier = 1.0f,
const std::string& audio_sink_id = "");
~MockPlayer(); ~MockPlayer();
MockPlayer(const MockPlayer&); MockPlayer(const MockPlayer&);
...@@ -71,6 +79,7 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { ...@@ -71,6 +79,7 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
double volume_multiplier_; double volume_multiplier_;
base::Optional<media_session::MediaPosition> position_; base::Optional<media_session::MediaPosition> position_;
bool is_in_picture_in_picture_; bool is_in_picture_in_picture_;
std::string audio_sink_id_;
}; };
// Basic representation of the players. The position in the vector is the // Basic representation of the players. The position in the vector is the
...@@ -85,6 +94,7 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { ...@@ -85,6 +94,7 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
int received_seek_backward_calls_ = 0; int received_seek_backward_calls_ = 0;
int received_enter_picture_in_picture_calls_ = 0; int received_enter_picture_in_picture_calls_ = 0;
int received_exit_picture_in_picture_calls_ = 0; int received_exit_picture_in_picture_calls_ = 0;
int received_set_audio_sink_id_calls_ = 0;
}; };
} // namespace content } // namespace content
......
...@@ -72,6 +72,12 @@ void PepperPlayerDelegate::OnExitPictureInPicture(int player_id) { ...@@ -72,6 +72,12 @@ void PepperPlayerDelegate::OnExitPictureInPicture(int player_id) {
// Pepper player cannot exit picture-in-picture. Do nothing. // Pepper player cannot exit picture-in-picture. Do nothing.
} }
void PepperPlayerDelegate::OnSetAudioSinkId(int player_id,
const std::string& raw_device_id) {
// Pepper player cannot change audio sinks. Do nothing.
NOTREACHED();
}
base::Optional<media_session::MediaPosition> PepperPlayerDelegate::GetPosition( base::Optional<media_session::MediaPosition> PepperPlayerDelegate::GetPosition(
int player_id) const { int player_id) const {
// Pepper does not support position data. // Pepper does not support position data.
......
...@@ -32,6 +32,8 @@ class PepperPlayerDelegate : public MediaSessionPlayerObserver { ...@@ -32,6 +32,8 @@ class PepperPlayerDelegate : public MediaSessionPlayerObserver {
double volume_multiplier) override; double volume_multiplier) override;
void OnEnterPictureInPicture(int player_id) override; void OnEnterPictureInPicture(int player_id) override;
void OnExitPictureInPicture(int player_id) override; void OnExitPictureInPicture(int player_id) override;
void OnSetAudioSinkId(int player_id,
const std::string& raw_device_id) override;
base::Optional<media_session::MediaPosition> GetPosition( base::Optional<media_session::MediaPosition> GetPosition(
int player_id) const override; int player_id) const override;
bool IsPictureInPictureAvailable(int player_id) const override; bool IsPictureInPictureAvailable(int player_id) const override;
......
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