Commit 88c43d22 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Media Session] Add metadata changed to observer

Add the MediaSessionMetadataChanged event to the
observer that will be fired if the metadata
associated with the media session changes.

This will be used for the notification to display
metadata of the currently playing media.

BUG=875004

Change-Id: I17d4e2af8b1d3b5b6213ec2eaaf0c29eb58c5937
Reviewed-on: https://chromium-review.googlesource.com/c/1316659
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612749}
parent 06d647ed
...@@ -122,6 +122,11 @@ void MediaNotificationController::MediaSessionInfoChanged( ...@@ -122,6 +122,11 @@ void MediaNotificationController::MediaSessionInfoChanged(
view_->UpdateWithMediaSessionInfo(session_info_); view_->UpdateWithMediaSessionInfo(session_info_);
} }
void MediaNotificationController::MediaSessionMetadataChanged(
const base::Optional<media_session::MediaMetadata>& metadata) {
NOTIMPLEMENTED();
}
void MediaNotificationController::FlushForTesting() { void MediaNotificationController::FlushForTesting() {
media_controller_ptr_.FlushForTesting(); media_controller_ptr_.FlushForTesting();
} }
......
...@@ -43,6 +43,8 @@ class ASH_EXPORT MediaNotificationController ...@@ -43,6 +43,8 @@ class ASH_EXPORT MediaNotificationController
// media_session::mojom::MediaSessionObserver: // media_session::mojom::MediaSessionObserver:
void MediaSessionInfoChanged( void MediaSessionInfoChanged(
media_session::mojom::MediaSessionInfoPtr session_info) override; media_session::mojom::MediaSessionInfoPtr session_info) override;
void MediaSessionMetadataChanged(
const base::Optional<media_session::MediaMetadata>& metadata) override;
void FlushForTesting(); void FlushForTesting();
void SetMediaControllerForTesting( void SetMediaControllerForTesting(
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "media/base/media_content_type.h" #include "media/base/media_content_type.h"
#include "services/media_session/public/cpp/switches.h" #include "services/media_session/public/cpp/switches.h"
#include "services/media_session/public/cpp/test/audio_focus_test_util.h" #include "services/media_session/public/cpp/test/audio_focus_test_util.h"
#include "services/media_session/public/cpp/test/mock_media_session.h"
#include "services/media_session/public/mojom/audio_focus.mojom.h" #include "services/media_session/public/mojom/audio_focus.mojom.h"
#include "services/media_session/public/mojom/constants.mojom.h" #include "services/media_session/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
...@@ -26,50 +27,6 @@ const char kExpectedSourceName[] = "web"; ...@@ -26,50 +27,6 @@ const char kExpectedSourceName[] = "web";
} // namespace } // namespace
class MediaSessionStateObserver
: public media_session::mojom::MediaSessionObserver {
public:
explicit MediaSessionStateObserver(
media_session::mojom::MediaSession* media_session)
: binding_(this) {
media_session::mojom::MediaSessionObserverPtr observer;
binding_.Bind(mojo::MakeRequest(&observer));
media_session->AddObserver(std::move(observer));
}
~MediaSessionStateObserver() override = default;
// media_session::mojom::MediaSessionObserver
void MediaSessionInfoChanged(
media_session::mojom::MediaSessionInfoPtr session_info) override {
if (desired_state_.has_value() &&
desired_state_.value() == session_info->state) {
run_loop_.Quit();
return;
}
session_info_ = std::move(session_info);
}
void WaitForState(
media_session::mojom::MediaSessionInfo::SessionState state) {
if (session_info_ && state == session_info_->state)
return;
desired_state_ = state;
run_loop_.Run();
}
protected:
base::RunLoop run_loop_;
mojo::Binding<media_session::mojom::MediaSessionObserver> binding_;
base::Optional<media_session::mojom::MediaSessionInfo::SessionState>
desired_state_;
media_session::mojom::MediaSessionInfoPtr session_info_;
DISALLOW_COPY_AND_ASSIGN(MediaSessionStateObserver);
};
class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest { class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest {
protected: protected:
void SetUpOnMainThread() override { void SetUpOnMainThread() override {
...@@ -121,14 +78,16 @@ class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest { ...@@ -121,14 +78,16 @@ class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest {
} }
{ {
MediaSessionStateObserver state_observer(media_session); media_session::test::MockMediaSessionMojoObserver observer(
state_observer.WaitForState( *media_session);
observer.WaitForState(
media_session::mojom::MediaSessionInfo::SessionState::kActive); media_session::mojom::MediaSessionInfo::SessionState::kActive);
} }
{ {
MediaSessionStateObserver state_observer(other_media_session); media_session::test::MockMediaSessionMojoObserver observer(
state_observer.WaitForState( *other_media_session);
observer.WaitForState(
media_session::mojom::MediaSessionInfo::SessionState::kInactive); media_session::mojom::MediaSessionInfo::SessionState::kInactive);
} }
...@@ -144,16 +103,18 @@ class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest { ...@@ -144,16 +103,18 @@ class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest {
} }
{ {
MediaSessionStateObserver state_observer(media_session); media_session::test::MockMediaSessionMojoObserver observer(
state_observer.WaitForState( *media_session);
observer.WaitForState(
use_separate_group_id use_separate_group_id
? media_session::mojom::MediaSessionInfo::SessionState::kSuspended ? media_session::mojom::MediaSessionInfo::SessionState::kSuspended
: media_session::mojom::MediaSessionInfo::SessionState::kActive); : media_session::mojom::MediaSessionInfo::SessionState::kActive);
} }
{ {
MediaSessionStateObserver state_observer(other_media_session); media_session::test::MockMediaSessionMojoObserver observer(
state_observer.WaitForState( *other_media_session);
observer.WaitForState(
media_session::mojom::MediaSessionInfo::SessionState::kActive); media_session::mojom::MediaSessionInfo::SessionState::kActive);
} }
...@@ -167,14 +128,16 @@ class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest { ...@@ -167,14 +128,16 @@ class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest {
} }
{ {
MediaSessionStateObserver state_observer(media_session); media_session::test::MockMediaSessionMojoObserver observer(
state_observer.WaitForState( *media_session);
observer.WaitForState(
media_session::mojom::MediaSessionInfo::SessionState::kInactive); media_session::mojom::MediaSessionInfo::SessionState::kInactive);
} }
{ {
MediaSessionStateObserver state_observer(other_media_session); media_session::test::MockMediaSessionMojoObserver observer(
state_observer.WaitForState( *other_media_session);
observer.WaitForState(
media_session::mojom::MediaSessionInfo::SessionState::kInactive); media_session::mojom::MediaSessionInfo::SessionState::kInactive);
} }
} }
......
...@@ -211,6 +211,11 @@ void MediaSessionImpl::NotifyMediaSessionMetadataChange( ...@@ -211,6 +211,11 @@ void MediaSessionImpl::NotifyMediaSessionMetadataChange(
const base::Optional<media_session::MediaMetadata>& metadata) { const base::Optional<media_session::MediaMetadata>& metadata) {
for (auto& observer : observers_) for (auto& observer : observers_)
observer.MediaSessionMetadataChanged(metadata); observer.MediaSessionMetadataChanged(metadata);
mojo_observers_.ForAllPtrs(
[&metadata](media_session::mojom::MediaSessionObserver* observer) {
observer->MediaSessionMetadataChanged(metadata);
});
} }
void MediaSessionImpl::NotifyMediaSessionActionsChange( void MediaSessionImpl::NotifyMediaSessionActionsChange(
...@@ -742,6 +747,9 @@ void MediaSessionImpl::GetMediaSessionInfo( ...@@ -742,6 +747,9 @@ void MediaSessionImpl::GetMediaSessionInfo(
void MediaSessionImpl::AddObserver( void MediaSessionImpl::AddObserver(
media_session::mojom::MediaSessionObserverPtr observer) { media_session::mojom::MediaSessionObserverPtr observer) {
observer->MediaSessionInfoChanged(GetMediaSessionInfoSync()); observer->MediaSessionInfoChanged(GetMediaSessionInfoSync());
observer->MediaSessionMetadataChanged(
routed_service_ ? routed_service_->metadata() : base::nullopt);
mojo_observers_.AddPtr(std::move(observer)); mojo_observers_.AddPtr(std::move(observer));
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test.h"
#include "content/shell/browser/shell.h" #include "content/shell/browser/shell.h"
#include "media/base/media_content_type.h" #include "media/base/media_content_type.h"
#include "services/media_session/public/cpp/test/mock_media_session.h"
#include "services/media_session/public/mojom/audio_focus.mojom.h" #include "services/media_session/public/mojom/audio_focus.mojom.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
...@@ -1742,6 +1743,35 @@ IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, ...@@ -1742,6 +1743,35 @@ IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
media_session_->AddObserver(mock_media_session_observer()); media_session_->AddObserver(mock_media_session_observer());
} }
IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
AddingMojoObserverNotifiesCurrentInformation_EmptyInfo) {
media_session::test::MockMediaSessionMojoObserver observer(*media_session_);
EXPECT_FALSE(observer.WaitForMetadata());
}
IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
AddingMojoObserverNotifiesCurrentInformation_WithInfo) {
// Set up the service and information.
EnsureMediaSessionService();
media_session::MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("title");
metadata.artist = base::ASCIIToUTF16("artist");
metadata.album = base::ASCIIToUTF16("album");
mock_media_session_service_->SetMetadata(metadata);
// Make sure the service is routed,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
shell()->web_contents()->GetMainFrame());
{
media_session::test::MockMediaSessionMojoObserver observer(*media_session_);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
ResolveAudioFocusSuccess();
EXPECT_EQ(metadata, *observer.WaitForMetadata());
}
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_RequestFailure_Gain) { IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_RequestFailure_Gain) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(); auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "content/test/test_web_contents.h" #include "content/test/test_web_contents.h"
#include "media/base/media_content_type.h" #include "media/base/media_content_type.h"
#include "services/media_session/public/cpp/media_metadata.h" #include "services/media_session/public/cpp/media_metadata.h"
#include "services/media_session/public/cpp/test/mock_media_session.h"
#include "services/media_session/public/mojom/constants.mojom.h" #include "services/media_session/public/mojom/constants.mojom.h"
#include "third_party/blink/public/platform/modules/mediasession/media_session.mojom.h" #include "third_party/blink/public/platform/modules/mediasession/media_session.mojom.h"
...@@ -157,6 +158,10 @@ class MediaSessionImplServiceRoutingTest ...@@ -157,6 +158,10 @@ class MediaSessionImplServiceRoutingTest
return MediaSessionImpl::Get(contents())->ComputeServiceForRouting(); return MediaSessionImpl::Get(contents())->ComputeServiceForRouting();
} }
MediaSessionImpl* GetMediaSession() {
return MediaSessionImpl::Get(contents());
}
TestRenderFrameHost* main_frame_; TestRenderFrameHost* main_frame_;
TestRenderFrameHost* sub_frame_; TestRenderFrameHost* sub_frame_;
...@@ -546,4 +551,35 @@ TEST_F(MediaSessionImplServiceRoutingTest, ...@@ -546,4 +551,35 @@ TEST_F(MediaSessionImplServiceRoutingTest,
run_loop.Run(); run_loop.Run();
} }
TEST_F(MediaSessionImplServiceRoutingTest,
NotifyMojoObserverMetadataWhenControllable) {
media_session::MediaMetadata expected_metadata;
expected_metadata.title = base::ASCIIToUTF16("title");
expected_metadata.artist = base::ASCIIToUTF16("artist");
expected_metadata.album = base::ASCIIToUTF16("album");
CreateServiceForFrame(main_frame_);
StartPlayerForFrame(main_frame_);
{
media_session::test::MockMediaSessionMojoObserver observer(
*GetMediaSession());
services_[main_frame_]->SetMetadata(expected_metadata);
EXPECT_EQ(expected_metadata, *observer.WaitForMetadata());
}
}
TEST_F(MediaSessionImplServiceRoutingTest,
NotifyMojoObserverMetadataEmptyWhenControllable) {
CreateServiceForFrame(main_frame_);
StartPlayerForFrame(main_frame_);
{
media_session::test::MockMediaSessionMojoObserver observer(
*GetMediaSession());
services_[main_frame_]->SetMetadata(base::nullopt);
EXPECT_FALSE(observer.WaitForMetadata());
}
}
} // namespace content } // namespace content
...@@ -45,10 +45,11 @@ void MediaController::ToggleSuspendResume() { ...@@ -45,10 +45,11 @@ void MediaController::ToggleSuspendResume() {
void MediaController::AddObserver(mojom::MediaSessionObserverPtr observer) { void MediaController::AddObserver(mojom::MediaSessionObserverPtr observer) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Flush the new observer with the latest session info. If there is no info // Flush the new observer with the state. We always flush the metadata as that
// then we will update |observer| when |MediaSessionInfoChanged| is called. // is optional so null is a valid value whereas the session info is required.
if (!session_info_.is_null()) if (!session_info_.is_null())
observer->MediaSessionInfoChanged(session_info_.Clone()); observer->MediaSessionInfoChanged(session_info_.Clone());
observer->MediaSessionMetadataChanged(session_metadata_);
observers_.AddPtr(std::move(observer)); observers_.AddPtr(std::move(observer));
} }
...@@ -63,6 +64,17 @@ void MediaController::MediaSessionInfoChanged(mojom::MediaSessionInfoPtr info) { ...@@ -63,6 +64,17 @@ void MediaController::MediaSessionInfoChanged(mojom::MediaSessionInfoPtr info) {
session_info_ = std::move(info); session_info_ = std::move(info);
} }
void MediaController::MediaSessionMetadataChanged(
const base::Optional<MediaMetadata>& metadata) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
observers_.ForAllPtrs([&metadata](mojom::MediaSessionObserver* observer) {
observer->MediaSessionMetadataChanged(metadata);
});
session_metadata_ = metadata;
}
void MediaController::PreviousTrack() { void MediaController::PreviousTrack() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
...@@ -91,6 +103,8 @@ bool MediaController::SetMediaSession(mojom::MediaSession* session) { ...@@ -91,6 +103,8 @@ bool MediaController::SetMediaSession(mojom::MediaSession* session) {
if (changed) { if (changed) {
session_binding_.Close(); session_binding_.Close();
session_info_.reset();
session_metadata_.reset();
if (session) { if (session) {
// Add |this| as an observer for |session|. // Add |this| as an observer for |session|.
......
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
#include <memory> #include <memory>
#include "base/optional.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "services/media_session/public/cpp/media_metadata.h"
#include "services/media_session/public/mojom/media_controller.mojom.h" #include "services/media_session/public/mojom/media_controller.mojom.h"
#include "services/media_session/public/mojom/media_session.mojom.h" #include "services/media_session/public/mojom/media_session.mojom.h"
...@@ -38,6 +40,8 @@ class MediaController : public mojom::MediaController, ...@@ -38,6 +40,8 @@ class MediaController : public mojom::MediaController,
// mojom::MediaSessionObserver overrides. // mojom::MediaSessionObserver overrides.
void MediaSessionInfoChanged( void MediaSessionInfoChanged(
mojom::MediaSessionInfoPtr session_info) override; mojom::MediaSessionInfoPtr session_info) override;
void MediaSessionMetadataChanged(
const base::Optional<MediaMetadata>&) override;
// Sets the media session that the controller should be bound to. If the // Sets the media session that the controller should be bound to. If the
// session is already bound to the same session then we will return false. // session is already bound to the same session then we will return false.
...@@ -53,6 +57,9 @@ class MediaController : public mojom::MediaController, ...@@ -53,6 +57,9 @@ class MediaController : public mojom::MediaController,
// The current info for the |session_|. // The current info for the |session_|.
mojom::MediaSessionInfoPtr session_info_; mojom::MediaSessionInfoPtr session_info_;
// The current metadata for |session_|.
base::Optional<MediaMetadata> session_metadata_;
// Raw pointer to the local proxy. This is used for sending control events to // Raw pointer to the local proxy. This is used for sending control events to
// the underlying MediaSession. // the underlying MediaSession.
mojom::MediaSession* session_ = nullptr; mojom::MediaSession* session_ = nullptr;
......
...@@ -9,9 +9,11 @@ ...@@ -9,9 +9,11 @@
#include <vector> #include <vector>
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h" #include "base/test/scoped_task_environment.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "services/media_session/media_session_service.h" #include "services/media_session/media_session_service.h"
#include "services/media_session/public/cpp/media_metadata.h"
#include "services/media_session/public/cpp/test/mock_media_session.h" #include "services/media_session/public/cpp/test/mock_media_session.h"
#include "services/media_session/public/mojom/constants.mojom.h" #include "services/media_session/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/test/test_connector_factory.h" #include "services/service_manager/public/cpp/test/test_connector_factory.h"
...@@ -459,4 +461,108 @@ TEST_F(MediaControllerTest, ActiveController_Seek) { ...@@ -459,4 +461,108 @@ TEST_F(MediaControllerTest, ActiveController_Seek) {
EXPECT_EQ(1, media_session.seek_count()); EXPECT_EQ(1, media_session.seek_count());
} }
TEST_F(MediaControllerTest, ActiveController_Metadata_Observer_Abandoned) {
MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("title");
metadata.artist = base::ASCIIToUTF16("artist");
metadata.album = base::ASCIIToUTF16("album");
test::MockMediaSession media_session;
base::Optional<MediaMetadata> test_metadata(metadata);
{
test::MockMediaSessionMojoObserver observer(media_session);
RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
}
media_session.SimulateMetadataChanged(test_metadata);
media_session.AbandonAudioFocusFromClient();
{
test::MockMediaSessionMojoObserver observer(controller());
EXPECT_FALSE(observer.WaitForMetadata());
}
}
TEST_F(MediaControllerTest, ActiveController_Metadata_Observer_Empty) {
test::MockMediaSession media_session;
base::Optional<MediaMetadata> test_metadata;
{
test::MockMediaSessionMojoObserver observer(media_session);
RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
}
{
test::MockMediaSessionMojoObserver observer(controller());
media_session.SimulateMetadataChanged(test_metadata);
EXPECT_EQ(test_metadata, observer.WaitForMetadata());
}
}
TEST_F(MediaControllerTest, ActiveController_Metadata_Observer_WithInfo) {
MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("title");
metadata.artist = base::ASCIIToUTF16("artist");
metadata.album = base::ASCIIToUTF16("album");
test::MockMediaSession media_session;
base::Optional<MediaMetadata> test_metadata(metadata);
{
test::MockMediaSessionMojoObserver observer(media_session);
RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
}
{
test::MockMediaSessionMojoObserver observer(controller());
media_session.SimulateMetadataChanged(test_metadata);
EXPECT_EQ(metadata, *observer.WaitForMetadata());
}
}
TEST_F(MediaControllerTest, ActiveController_Metadata_AddObserver_Empty) {
test::MockMediaSession media_session;
base::Optional<MediaMetadata> test_metadata;
{
test::MockMediaSessionMojoObserver observer(media_session);
RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
}
media_session.SimulateMetadataChanged(test_metadata);
{
test::MockMediaSessionMojoObserver observer(controller());
EXPECT_EQ(test_metadata, observer.WaitForMetadata());
}
}
TEST_F(MediaControllerTest, ActiveController_Metadata_AddObserver_WithInfo) {
MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("title");
metadata.artist = base::ASCIIToUTF16("artist");
metadata.album = base::ASCIIToUTF16("album");
test::MockMediaSession media_session;
base::Optional<MediaMetadata> test_metadata(metadata);
{
test::MockMediaSessionMojoObserver observer(media_session);
RequestAudioFocus(media_session, mojom::AudioFocusType::kGain);
observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive);
}
media_session.SimulateMetadataChanged(test_metadata);
{
test::MockMediaSessionMojoObserver observer(controller());
EXPECT_EQ(metadata, *observer.WaitForMetadata());
}
}
} // namespace media_session } // namespace media_session
...@@ -39,6 +39,16 @@ void MockMediaSessionMojoObserver::MediaSessionInfoChanged( ...@@ -39,6 +39,16 @@ void MockMediaSessionMojoObserver::MediaSessionInfoChanged(
} }
} }
void MockMediaSessionMojoObserver::MediaSessionMetadataChanged(
const base::Optional<MediaMetadata>& metadata) {
session_metadata_ = metadata;
if (waiting_for_metadata_) {
run_loop_.Quit();
waiting_for_metadata_ = false;
}
}
void MockMediaSessionMojoObserver::WaitForState( void MockMediaSessionMojoObserver::WaitForState(
mojom::MediaSessionInfo::SessionState wanted_state) { mojom::MediaSessionInfo::SessionState wanted_state) {
if (session_info_ && session_info_->state == wanted_state) if (session_info_ && session_info_->state == wanted_state)
...@@ -57,6 +67,16 @@ void MockMediaSessionMojoObserver::WaitForPlaybackState( ...@@ -57,6 +67,16 @@ void MockMediaSessionMojoObserver::WaitForPlaybackState(
run_loop_.Run(); run_loop_.Run();
} }
const base::Optional<MediaMetadata>&
MockMediaSessionMojoObserver::WaitForMetadata() {
if (!session_metadata_.has_value()) {
waiting_for_metadata_ = true;
run_loop_.Run();
}
return session_metadata_.value();
}
MockMediaSession::MockMediaSession() = default; MockMediaSession::MockMediaSession() = default;
MockMediaSession::MockMediaSession(bool force_duck) : force_duck_(force_duck) {} MockMediaSession::MockMediaSession(bool force_duck) : force_duck_(force_duck) {}
...@@ -217,6 +237,13 @@ void MockMediaSession::FlushForTesting() { ...@@ -217,6 +237,13 @@ void MockMediaSession::FlushForTesting() {
afr_client_.FlushForTesting(); afr_client_.FlushForTesting();
} }
void MockMediaSession::SimulateMetadataChanged(
const base::Optional<MediaMetadata>& metadata) {
observers_.ForAllPtrs([&metadata](mojom::MediaSessionObserver* observer) {
observer->MediaSessionMetadataChanged(metadata);
});
}
void MockMediaSession::SetState(mojom::MediaSessionInfo::SessionState state) { void MockMediaSession::SetState(mojom::MediaSessionInfo::SessionState state) {
state_ = state; state_ = state;
NotifyObservers(); NotifyObservers();
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "services/media_session/public/cpp/media_metadata.h"
#include "services/media_session/public/mojom/audio_focus.mojom.h" #include "services/media_session/public/mojom/audio_focus.mojom.h"
#include "services/media_session/public/mojom/media_controller.mojom.h" #include "services/media_session/public/mojom/media_controller.mojom.h"
#include "services/media_session/public/mojom/media_session.mojom.h" #include "services/media_session/public/mojom/media_session.mojom.h"
...@@ -35,9 +36,12 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) ...@@ -35,9 +36,12 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP)
// mojom::MediaSessionObserver overrides. // mojom::MediaSessionObserver overrides.
void MediaSessionInfoChanged(mojom::MediaSessionInfoPtr session) override; void MediaSessionInfoChanged(mojom::MediaSessionInfoPtr session) override;
void MediaSessionMetadataChanged(
const base::Optional<MediaMetadata>& metadata) override;
void WaitForState(mojom::MediaSessionInfo::SessionState wanted_state); void WaitForState(mojom::MediaSessionInfo::SessionState wanted_state);
void WaitForPlaybackState(mojom::MediaPlaybackState wanted_state); void WaitForPlaybackState(mojom::MediaPlaybackState wanted_state);
const base::Optional<MediaMetadata>& WaitForMetadata();
const mojom::MediaSessionInfoPtr& session_info() const { const mojom::MediaSessionInfoPtr& session_info() const {
return session_info_; return session_info_;
...@@ -45,6 +49,9 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) ...@@ -45,6 +49,9 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP)
private: private:
mojom::MediaSessionInfoPtr session_info_; mojom::MediaSessionInfoPtr session_info_;
base::Optional<base::Optional<MediaMetadata>> session_metadata_;
bool waiting_for_metadata_ = false;
base::Optional<mojom::MediaSessionInfo::SessionState> wanted_state_; base::Optional<mojom::MediaSessionInfo::SessionState> wanted_state_;
base::Optional<mojom::MediaPlaybackState> wanted_playback_state_; base::Optional<mojom::MediaPlaybackState> wanted_playback_state_;
base::RunLoop run_loop_; base::RunLoop run_loop_;
...@@ -63,13 +70,13 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession ...@@ -63,13 +70,13 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession
~MockMediaSession() override; ~MockMediaSession() override;
// mojom::MediaSession overrides. // mojom::MediaSession overrides.
void Suspend(SuspendType) override; void Suspend(SuspendType type) override;
void Resume(SuspendType) override; void Resume(SuspendType type) override;
void StartDucking() override; void StartDucking() override;
void StopDucking() override; void StopDucking() override;
void GetMediaSessionInfo(GetMediaSessionInfoCallback) override; void GetMediaSessionInfo(GetMediaSessionInfoCallback callback) override;
void AddObserver(mojom::MediaSessionObserverPtr) override; void AddObserver(mojom::MediaSessionObserverPtr observer) override;
void GetDebugInfo(GetDebugInfoCallback) override; void GetDebugInfo(GetDebugInfoCallback callback) override;
void PreviousTrack() override; void PreviousTrack() override;
void NextTrack() override; void NextTrack() override;
void Seek(base::TimeDelta seek_time) override; void Seek(base::TimeDelta seek_time) override;
...@@ -80,8 +87,8 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession ...@@ -80,8 +87,8 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession
base::UnguessableToken GetRequestIdFromClient(); base::UnguessableToken GetRequestIdFromClient();
base::UnguessableToken RequestAudioFocusFromService( base::UnguessableToken RequestAudioFocusFromService(
mojom::AudioFocusManagerPtr&, mojom::AudioFocusManagerPtr& service,
mojom::AudioFocusType); mojom::AudioFocusType audio_foucs_type);
base::UnguessableToken RequestGroupedAudioFocusFromService( base::UnguessableToken RequestGroupedAudioFocusFromService(
mojom::AudioFocusManagerPtr& service, mojom::AudioFocusManagerPtr& service,
...@@ -95,6 +102,8 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession ...@@ -95,6 +102,8 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession
} }
void FlushForTesting(); void FlushForTesting();
void SimulateMetadataChanged(const base::Optional<MediaMetadata>& metadata);
int prev_track_count() const { return prev_track_count_; } int prev_track_count() const { return prev_track_count_; }
int next_track_count() const { return next_track_count_; } int next_track_count() const { return next_track_count_; }
int add_observer_count() const { return add_observer_count_; } int add_observer_count() const { return add_observer_count_; }
......
...@@ -90,8 +90,13 @@ struct MediaSessionDebugInfo { ...@@ -90,8 +90,13 @@ struct MediaSessionDebugInfo {
// The observer for observing media session events. // The observer for observing media session events.
// Next Method ID: 1 // Next Method ID: 1
interface MediaSessionObserver { interface MediaSessionObserver {
// The info associated with the session changed. // Call when the info associated with the session changed.
MediaSessionInfoChanged@0(MediaSessionInfo info); MediaSessionInfoChanged@0(MediaSessionInfo info);
// Called when the observed MediaSession has changed metadata. The metadata
// can be null to be reset, e.g. the media that was being played has been
// stopped.
MediaSessionMetadataChanged@1(MediaMetadata? metadata);
}; };
// A MediaSession manages the media session and audio focus for a given // A MediaSession manages the media session and audio focus for a given
......
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