Commit 7a85bf2d authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Media Session] Add position state to WMPI

Adds position state to WMPI. This is a combination of
playback rate, duration and current time and is used
to display the playback position in the UI.

The next step is sending this to the browser process.

BUG=985394

Change-Id: I76a3671d6357d5fb620e05857e3519de6707fbc3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1706777Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Reviewed-by: default avatarChrome Cunningham <chcunningham@chromium.org>
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#680458}
parent b493e53f
...@@ -65,6 +65,9 @@ class CONTENT_EXPORT RendererWebMediaPlayerDelegate ...@@ -65,6 +65,9 @@ class CONTENT_EXPORT RendererWebMediaPlayerDelegate
blink::WebFullscreenVideoStatus fullscreen_video_status) override; blink::WebFullscreenVideoStatus fullscreen_video_status) override;
void DidPlayerSizeChange(int delegate_id, const gfx::Size& size) override; void DidPlayerSizeChange(int delegate_id, const gfx::Size& size) override;
void DidPlayerMutedStatusChange(int delegate_id, bool muted) override; void DidPlayerMutedStatusChange(int delegate_id, bool muted) override;
void DidPlayerMediaPositionStateChange(
int delegate_id,
const media_session::MediaPosition& position) override {}
// content::RenderFrameObserver overrides. // content::RenderFrameObserver overrides.
void WasHidden() override; void WasHidden() override;
......
...@@ -13,6 +13,7 @@ include_rules = [ ...@@ -13,6 +13,7 @@ include_rules = [
"+mojo/public/cpp/bindings", "+mojo/public/cpp/bindings",
"+net/base", "+net/base",
"+net/http", "+net/http",
"+services/media_session/public/cpp",
"+services/network/public/cpp", "+services/network/public/cpp",
"+services/network/public/mojom", "+services/network/public/mojom",
"+services/service_manager/public/cpp", "+services/service_manager/public/cpp",
......
...@@ -810,6 +810,9 @@ void WebMediaPlayerImpl::Pause() { ...@@ -810,6 +810,9 @@ void WebMediaPlayerImpl::Pause() {
media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE));
// Paused changed so we should update media position state.
UpdateMediaPositionState();
UpdatePlayState(); UpdatePlayState();
} }
...@@ -872,6 +875,9 @@ void WebMediaPlayerImpl::DoSeek(base::TimeDelta time, bool time_updated) { ...@@ -872,6 +875,9 @@ void WebMediaPlayerImpl::DoSeek(base::TimeDelta time, bool time_updated) {
// This needs to be called after Seek() so that if a resume is triggered, it // This needs to be called after Seek() so that if a resume is triggered, it
// is to the correct time. // is to the correct time.
UpdatePlayState(); UpdatePlayState();
// The seek time has changed so we should update the media position state.
UpdateMediaPositionState();
} }
void WebMediaPlayerImpl::SetRate(double rate) { void WebMediaPlayerImpl::SetRate(double rate) {
...@@ -1564,6 +1570,9 @@ void WebMediaPlayerImpl::OnPipelineSeeked(bool time_updated) { ...@@ -1564,6 +1570,9 @@ void WebMediaPlayerImpl::OnPipelineSeeked(bool time_updated) {
} }
attempting_suspended_start_ = false; attempting_suspended_start_ = false;
// The current time has changed so we should update the media position state.
UpdateMediaPositionState();
} }
void WebMediaPlayerImpl::OnPipelineSuspended() { void WebMediaPlayerImpl::OnPipelineSuspended() {
...@@ -2107,6 +2116,9 @@ void WebMediaPlayerImpl::OnDurationChange() { ...@@ -2107,6 +2116,9 @@ void WebMediaPlayerImpl::OnDurationChange() {
client_->DurationChanged(); client_->DurationChanged();
if (watch_time_reporter_) if (watch_time_reporter_)
watch_time_reporter_->OnDurationChanged(GetPipelineMediaDuration()); watch_time_reporter_->OnDurationChanged(GetPipelineMediaDuration());
// The duration has changed so we should update the media position state.
UpdateMediaPositionState();
} }
void WebMediaPlayerImpl::OnAddTextTrack(const TextTrackConfig& config, void WebMediaPlayerImpl::OnAddTextTrack(const TextTrackConfig& config,
...@@ -2778,6 +2790,28 @@ void WebMediaPlayerImpl::UpdatePlayState() { ...@@ -2778,6 +2790,28 @@ void WebMediaPlayerImpl::UpdatePlayState() {
SetSuspendState(state.is_suspended || pending_suspend_resume_cycle_); SetSuspendState(state.is_suspended || pending_suspend_resume_cycle_);
} }
void WebMediaPlayerImpl::UpdateMediaPositionState() {
DCHECK(delegate_);
// When seeking the current time can go beyond the duration so we should
// cap the current time at the duration.
base::TimeDelta duration = GetPipelineMediaDuration();
base::TimeDelta current_time = GetCurrentTimeInternal();
if (current_time > duration)
current_time = duration;
media_session::MediaPosition new_position(paused_ ? 0.0 : playback_rate_,
duration, current_time);
if (media_position_state_ == new_position)
return;
DVLOG(2) << __func__ << "(" << new_position.ToString() << ")";
media_position_state_ = new_position;
delegate_->DidPlayerMediaPositionStateChange(delegate_id_,
media_position_state_);
}
void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state, void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state,
bool is_idle) { bool is_idle) {
DCHECK(delegate_); DCHECK(delegate_);
...@@ -3552,6 +3586,10 @@ void WebMediaPlayerImpl::MaybeUpdateBufferSizesForPlayback() { ...@@ -3552,6 +3586,10 @@ void WebMediaPlayerImpl::MaybeUpdateBufferSizesForPlayback() {
mb_data_source_->MediaPlaybackRateChanged(playback_rate_); mb_data_source_->MediaPlaybackRateChanged(playback_rate_);
if (!paused_) if (!paused_)
mb_data_source_->MediaIsPlaying(); mb_data_source_->MediaIsPlaying();
// The playback rate has changed so we should rebuild the media position
// state.
UpdateMediaPositionState();
} }
} // namespace media } // namespace media
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "media/blink/webmediaplayer_params.h" #include "media/blink/webmediaplayer_params.h"
#include "media/filters/pipeline_controller.h" #include "media/filters/pipeline_controller.h"
#include "media/renderers/paint_canvas_video_renderer.h" #include "media/renderers/paint_canvas_video_renderer.h"
#include "services/media_session/public/cpp/media_position.h"
#include "third_party/blink/public/platform/media/webmediaplayer_delegate.h" #include "third_party/blink/public/platform/media/webmediaplayer_delegate.h"
#include "third_party/blink/public/platform/web_audio_source_provider.h" #include "third_party/blink/public/platform/web_audio_source_provider.h"
#include "third_party/blink/public/platform/web_content_decryption_module_result.h" #include "third_party/blink/public/platform/web_content_decryption_module_result.h"
...@@ -427,6 +428,21 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl ...@@ -427,6 +428,21 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
// - enter_pip_callback_, // - enter_pip_callback_,
void UpdatePlayState(); void UpdatePlayState();
// Calculates the current position state for the media element and notifies
// |delegate_| if it has changed.
//
// Spec: https://wicg.github.io/mediasession/#position-state
//
// This method should be called any time its dependent values change. These
// are:
// - pipeline_controller_->GetMediaDuration()
// - pipeline_media_duration_for_test_
// - pipeline_controller_->GetMediaTime()
// - playback_rate_
// - Seeking() / seek_time_
// - paused_, paused_time_
void UpdateMediaPositionState();
// Methods internal to UpdatePlayState(). // Methods internal to UpdatePlayState().
PlayState UpdatePlayState_ComputePlayState(bool is_flinging, PlayState UpdatePlayState_ComputePlayState(bool is_flinging,
bool can_auto_suspend, bool can_auto_suspend,
...@@ -826,6 +842,10 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl ...@@ -826,6 +842,10 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
bool allow_media_player_renderer_credentials_ = false; bool allow_media_player_renderer_credentials_ = false;
#endif #endif
// Stores the current position state of the media. See
// |UpdateMediaPositionState| for more details.
media_session::MediaPosition media_position_state_;
// Set whenever the demuxer encounters an HLS file. // Set whenever the demuxer encounters an HLS file.
// This flag is distinct from |using_media_player_renderer_|, because on older // This flag is distinct from |using_media_player_renderer_|, because on older
// devices we might use MediaPlayerRenderer for non HLS playback. // devices we might use MediaPlayerRenderer for non HLS playback.
......
...@@ -84,6 +84,9 @@ constexpr char kAudioOnlyTestFile[] = "sfx-opus-441.webm"; ...@@ -84,6 +84,9 @@ constexpr char kAudioOnlyTestFile[] = "sfx-opus-441.webm";
constexpr char kVideoOnlyTestFile[] = "bear-320x240-video-only.webm"; constexpr char kVideoOnlyTestFile[] = "bear-320x240-video-only.webm";
constexpr char kEncryptedVideoOnlyTestFile[] = "bear-320x240-av_enc-v.webm"; constexpr char kEncryptedVideoOnlyTestFile[] = "bear-320x240-av_enc-v.webm";
constexpr base::TimeDelta kAudioOnlyTestFileDuration =
base::TimeDelta::FromMilliseconds(296);
MATCHER(WmpiDestroyed, "") { MATCHER(WmpiDestroyed, "") {
return CONTAINS_STRING(arg, "WEBMEDIAPLAYER_DESTROYED {}"); return CONTAINS_STRING(arg, "WEBMEDIAPLAYER_DESTROYED {}");
} }
...@@ -256,6 +259,9 @@ class MockWebMediaPlayerDelegate : public blink::WebMediaPlayerDelegate { ...@@ -256,6 +259,9 @@ class MockWebMediaPlayerDelegate : public blink::WebMediaPlayerDelegate {
int player_id() { return player_id_; } int player_id() { return player_id_; }
MOCK_METHOD2(DidPlayerMediaPositionStateChange,
void(int, const media_session::MediaPosition&));
private: private:
Observer* observer_ = nullptr; Observer* observer_ = nullptr;
int player_id_ = 1234; int player_id_ = 1234;
...@@ -423,6 +429,7 @@ class WebMediaPlayerImplTest : public testing::Test { ...@@ -423,6 +429,7 @@ class WebMediaPlayerImplTest : public testing::Test {
void SetDuration(base::TimeDelta value) { void SetDuration(base::TimeDelta value) {
wmpi_->SetPipelineMediaDurationForTest(value); wmpi_->SetPipelineMediaDurationForTest(value);
wmpi_->OnDurationChange();
} }
base::TimeDelta GetCurrentTimeInternal() { base::TimeDelta GetCurrentTimeInternal() {
...@@ -1387,6 +1394,127 @@ TEST_F(WebMediaPlayerImplTest, AutoplayMuted_SetVolume) { ...@@ -1387,6 +1394,127 @@ TEST_F(WebMediaPlayerImplTest, AutoplayMuted_SetVolume) {
wmpi_->SetVolume(1.0); wmpi_->SetVolume(1.0);
} }
TEST_F(WebMediaPlayerImplTest, MediaPositionState_OnDurationChange) {
InitializeWebMediaPlayerImpl();
testing::Sequence s;
EXPECT_CALL(delegate_,
DidPlayerMediaPositionStateChange(
delegate_.player_id(),
media_session::MediaPosition(0.0, kAudioOnlyTestFileDuration,
base::TimeDelta())))
.InSequence(s);
EXPECT_CALL(delegate_, DidPlayerMediaPositionStateChange(
delegate_.player_id(),
media_session::MediaPosition(
0.0, kInfiniteDuration, base::TimeDelta())))
.InSequence(s);
LoadAndWaitForReadyState(kAudioOnlyTestFile,
blink::WebMediaPlayer::kReadyStateHaveCurrentData);
SetDuration(kInfiniteDuration);
}
TEST_F(WebMediaPlayerImplTest, MediaPositionState_PlayPauseSetRate) {
InitializeWebMediaPlayerImpl();
testing::Sequence s;
EXPECT_CALL(delegate_,
DidPlayerMediaPositionStateChange(
delegate_.player_id(),
media_session::MediaPosition(0.0, kAudioOnlyTestFileDuration,
base::TimeDelta())))
.InSequence(s);
EXPECT_CALL(delegate_,
DidPlayerMediaPositionStateChange(delegate_.player_id(), _))
.InSequence(s)
.WillOnce([](auto id, auto position) {
EXPECT_EQ(1.0, position.playback_rate());
EXPECT_EQ(kAudioOnlyTestFileDuration, position.duration());
EXPECT_EQ(base::TimeDelta(),
position.GetPositionAtTime(position.last_updated_time()));
});
EXPECT_CALL(delegate_,
DidPlayerMediaPositionStateChange(
delegate_.player_id(),
media_session::MediaPosition(0.0, kAudioOnlyTestFileDuration,
base::TimeDelta())))
.InSequence(s);
EXPECT_CALL(delegate_,
DidPlayerMediaPositionStateChange(delegate_.player_id(), _))
.InSequence(s)
.WillOnce([](auto id, auto position) {
EXPECT_EQ(2.0, position.playback_rate());
EXPECT_EQ(kAudioOnlyTestFileDuration, position.duration());
EXPECT_EQ(base::TimeDelta(),
position.GetPositionAtTime(position.last_updated_time()));
});
wmpi_->SetRate(1.0);
LoadAndWaitForReadyState(kAudioOnlyTestFile,
blink::WebMediaPlayer::kReadyStateHaveCurrentData);
// Play will set the playback rate to 1.0.
Play();
// Pause will set the playback rate to 0.0.
Pause();
// SetRate will set the playback rate, but it will not affect the position
// state until we have started playing again.
wmpi_->SetRate(2.0);
Play();
}
TEST_F(WebMediaPlayerImplTest, MediaPositionState_Seeking) {
InitializeWebMediaPlayerImpl();
testing::Sequence s;
EXPECT_CALL(delegate_,
DidPlayerMediaPositionStateChange(
delegate_.player_id(),
media_session::MediaPosition(0.0, kAudioOnlyTestFileDuration,
base::TimeDelta())))
.InSequence(s);
EXPECT_CALL(delegate_,
DidPlayerMediaPositionStateChange(delegate_.player_id(), _))
.InSequence(s)
.WillOnce([](auto id, auto position) {
EXPECT_EQ(1.0, position.playback_rate());
EXPECT_EQ(kAudioOnlyTestFileDuration, position.duration());
EXPECT_EQ(base::TimeDelta(),
position.GetPositionAtTime(position.last_updated_time()));
});
EXPECT_CALL(delegate_,
DidPlayerMediaPositionStateChange(delegate_.player_id(), _))
.InSequence(s)
.WillOnce([](auto id, auto position) {
EXPECT_EQ(1.0, position.playback_rate());
EXPECT_EQ(kAudioOnlyTestFileDuration, position.duration());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(100),
position.GetPositionAtTime(position.last_updated_time()));
});
EXPECT_CALL(delegate_, DidPlayerMediaPositionStateChange(
delegate_.player_id(),
media_session::MediaPosition(
0.0, kAudioOnlyTestFileDuration,
base::TimeDelta::FromMilliseconds(100))))
.InSequence(s);
wmpi_->SetRate(1.0);
LoadAndWaitForReadyState(kAudioOnlyTestFile,
blink::WebMediaPlayer::kReadyStateHaveCurrentData);
Play();
// Seek forward 100ms will result in the position to be updated.
wmpi_->Seek(0.1);
// If we trigger another update to the position state the new position should
// be used.
Pause();
}
TEST_F(WebMediaPlayerImplTest, NoStreams) { TEST_F(WebMediaPlayerImplTest, NoStreams) {
InitializeWebMediaPlayerImpl(); InitializeWebMediaPlayerImpl();
PipelineMetadata metadata; PipelineMetadata metadata;
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "services/media_session/public/cpp/media_position.h" #include "services/media_session/public/cpp/media_position.h"
#include "base/strings/stringprintf.h"
namespace media_session { namespace media_session {
MediaPosition::MediaPosition() = default; MediaPosition::MediaPosition() = default;
...@@ -26,6 +28,14 @@ base::TimeDelta MediaPosition::duration() const { ...@@ -26,6 +28,14 @@ base::TimeDelta MediaPosition::duration() const {
return duration_; return duration_;
} }
double MediaPosition::playback_rate() const {
return playback_rate_;
}
base::Time MediaPosition::last_updated_time() const {
return last_updated_time_;
}
base::TimeDelta MediaPosition::GetPosition() const { base::TimeDelta MediaPosition::GetPosition() const {
return GetPositionAtTime(base::Time::Now()); return GetPositionAtTime(base::Time::Now());
} }
...@@ -46,4 +56,22 @@ base::TimeDelta MediaPosition::GetPositionAtTime(base::Time time) const { ...@@ -46,4 +56,22 @@ base::TimeDelta MediaPosition::GetPositionAtTime(base::Time time) const {
return updated_position; return updated_position;
} }
bool MediaPosition::operator==(const MediaPosition& other) const {
if (playback_rate_ != other.playback_rate_ || duration_ != other.duration_)
return false;
base::Time now = base::Time::Now();
return GetPositionAtTime(now) == other.GetPositionAtTime(now);
}
bool MediaPosition::operator!=(const MediaPosition& other) const {
return !(*this == other);
}
std::string MediaPosition::ToString() const {
return base::StringPrintf("playback_rate=%f duration=%f current_time=%f",
playback_rate_, duration_.InSecondsF(),
position_.InSecondsF());
}
} // namespace media_session } // namespace media_session
...@@ -34,6 +34,21 @@ struct COMPONENT_EXPORT(MEDIA_SESSION_BASE_CPP) MediaPosition { ...@@ -34,6 +34,21 @@ struct COMPONENT_EXPORT(MEDIA_SESSION_BASE_CPP) MediaPosition {
// Return the current position of the media. // Return the current position of the media.
base::TimeDelta GetPosition() const; base::TimeDelta GetPosition() const;
// Return the current playback rate of the media.
double playback_rate() const;
// Return the time the position state was last updated.
base::Time last_updated_time() const;
// Return the updated position of the media, assuming current time is
// |time|.
base::TimeDelta GetPositionAtTime(base::Time time) const;
bool operator==(const MediaPosition&) const;
bool operator!=(const MediaPosition&) const;
std::string ToString() const;
private: private:
friend struct mojo::StructTraits<mojom::MediaPositionDataView, MediaPosition>; friend struct mojo::StructTraits<mojom::MediaPositionDataView, MediaPosition>;
friend class MediaPositionTest; friend class MediaPositionTest;
...@@ -45,10 +60,11 @@ struct COMPONENT_EXPORT(MEDIA_SESSION_BASE_CPP) MediaPosition { ...@@ -45,10 +60,11 @@ struct COMPONENT_EXPORT(MEDIA_SESSION_BASE_CPP) MediaPosition {
TestPositionUpdatedFasterPlayback); TestPositionUpdatedFasterPlayback);
FRIEND_TEST_ALL_PREFIXES(MediaPositionTest, FRIEND_TEST_ALL_PREFIXES(MediaPositionTest,
TestPositionUpdatedSlowerPlayback); TestPositionUpdatedSlowerPlayback);
FRIEND_TEST_ALL_PREFIXES(MediaPositionTest, TestEquals_AllSame);
// Return the updated position of the media, assuming current time is FRIEND_TEST_ALL_PREFIXES(MediaPositionTest, TestEquals_SameButDifferentTime);
// |time|. FRIEND_TEST_ALL_PREFIXES(MediaPositionTest, TestNotEquals_DifferentDuration);
base::TimeDelta GetPositionAtTime(base::Time time) const; FRIEND_TEST_ALL_PREFIXES(MediaPositionTest,
TestNotEquals_DifferentPlaybackRate);
// Playback rate of the media. // Playback rate of the media.
double playback_rate_; double playback_rate_;
......
...@@ -104,4 +104,71 @@ TEST_F(MediaPositionTest, TestPositionUpdatedSlowerPlayback) { ...@@ -104,4 +104,71 @@ TEST_F(MediaPositionTest, TestPositionUpdatedSlowerPlayback) {
EXPECT_EQ(updated_position.InSeconds(), 400); EXPECT_EQ(updated_position.InSeconds(), 400);
} }
} // namespace media_session
\ No newline at end of file TEST_F(MediaPositionTest, TestNotEquals_AllDifferent) {
EXPECT_NE(MediaPosition(.5 /* playback_rate */,
base::TimeDelta::FromSeconds(600) /* duration */,
base::TimeDelta::FromSeconds(300) /* position */),
MediaPosition(1.0 /* playback_rate */,
base::TimeDelta::FromSeconds(800) /* duration */,
base::TimeDelta::FromSeconds(100) /* position */));
}
TEST_F(MediaPositionTest, TestNotEquals_DifferentDuration) {
MediaPosition position_1(.5 /* playback_rate */,
base::TimeDelta::FromSeconds(600) /* duration */,
base::TimeDelta::FromSeconds(300) /* position */);
MediaPosition position_2(.5 /* playback_rate */,
base::TimeDelta::FromSeconds(1000) /* duration */,
base::TimeDelta::FromSeconds(300) /* position */);
position_1.last_updated_time_ = position_2.last_updated_time_;
EXPECT_NE(position_1, position_2);
}
TEST_F(MediaPositionTest, TestNotEquals_DifferentPlaybackRate) {
MediaPosition position_1(.5 /* playback_rate */,
base::TimeDelta::FromSeconds(600) /* duration */,
base::TimeDelta::FromSeconds(300) /* position */);
MediaPosition position_2(1.0 /* playback_rate */,
base::TimeDelta::FromSeconds(600) /* duration */,
base::TimeDelta::FromSeconds(300) /* position */);
position_1.last_updated_time_ = position_2.last_updated_time_;
EXPECT_NE(position_1, position_2);
}
TEST_F(MediaPositionTest, TestEquals_AllSame) {
MediaPosition position_1(.5 /* playback_rate */,
base::TimeDelta::FromSeconds(600) /* duration */,
base::TimeDelta::FromSeconds(300) /* position */);
MediaPosition position_2(.5 /* playback_rate */,
base::TimeDelta::FromSeconds(600) /* duration */,
base::TimeDelta::FromSeconds(300) /* position */);
position_1.last_updated_time_ = position_2.last_updated_time_;
EXPECT_EQ(position_1, position_2);
}
TEST_F(MediaPositionTest, TestEquals_SameButDifferentTime) {
MediaPosition position_1(1.0 /* playback_rate */,
base::TimeDelta::FromSeconds(600) /* duration */,
base::TimeDelta::FromSeconds(0) /* position */);
MediaPosition position_2(1.0 /* playback_rate */,
base::TimeDelta::FromSeconds(600) /* duration */,
base::TimeDelta::FromSeconds(10) /* position */);
position_2.last_updated_time_ = position_1.last_updated_time_;
position_1.last_updated_time_ -= base::TimeDelta::FromSeconds(10);
EXPECT_EQ(position_1, position_2);
}
} // namespace media_session
...@@ -16,6 +16,10 @@ namespace media { ...@@ -16,6 +16,10 @@ namespace media {
enum class MediaContentType; enum class MediaContentType;
} // namespace media } // namespace media
namespace media_session {
struct MediaPosition;
} // namespace media_session
namespace blink { namespace blink {
enum class WebFullscreenVideoStatus; enum class WebFullscreenVideoStatus;
...@@ -106,6 +110,11 @@ class BLINK_PLATFORM_EXPORT WebMediaPlayerDelegate { ...@@ -106,6 +110,11 @@ class BLINK_PLATFORM_EXPORT WebMediaPlayerDelegate {
// Notify that the muted status of the media player has changed. // Notify that the muted status of the media player has changed.
virtual void DidPlayerMutedStatusChange(int delegate_id, bool muted) = 0; virtual void DidPlayerMutedStatusChange(int delegate_id, bool muted) = 0;
// Notify that the media position state of the media player has changed.
virtual void DidPlayerMediaPositionStateChange(
int delegate_id,
const media_session::MediaPosition& position) = 0;
// Notify that playback is stopped. This will drop wake locks and remove any // Notify that playback is stopped. This will drop wake locks and remove any
// external controls. // external controls.
// //
......
...@@ -161,6 +161,12 @@ class FakeWebMediaPlayerDelegate ...@@ -161,6 +161,12 @@ class FakeWebMediaPlayerDelegate
int delegate_id() { return delegate_id_; } int delegate_id() { return delegate_id_; }
void DidPlayerMediaPositionStateChange(
int delegate_id,
const media_session::MediaPosition& position) override {
EXPECT_EQ(delegate_id_, delegate_id);
}
private: private:
int delegate_id_ = 1234; int delegate_id_ = 1234;
Observer* observer_ = nullptr; Observer* observer_ = nullptr;
......
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