blob: 2516aa323e5b7f83b44744fa39f4f6febbb2ec0a [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/mediasession/media_session.h"
#include "base/macros.h"
#include "base/test/simple_test_tick_clock.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_position_state.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
using testing::_;
namespace {
class MockMediaSessionService : public mojom::blink::MediaSessionService {
public:
MockMediaSessionService() = default;
mojo::Remote<mojom::blink::MediaSessionService> CreateRemoteAndBind() {
return mojo::Remote<mojom::blink::MediaSessionService>(
receiver_.BindNewPipeAndPassRemote());
}
void SetClient(
mojo::PendingRemote<mojom::blink::MediaSessionClient> client) override {}
void SetPlaybackState(
mojom::blink::MediaSessionPlaybackState state) override {}
MOCK_METHOD1(SetPositionState,
void(media_session::mojom::blink::MediaPositionPtr));
void SetMetadata(mojom::blink::SpecMediaMetadataPtr metadata) override {}
void EnableAction(
media_session::mojom::blink::MediaSessionAction action) override {}
void DisableAction(
media_session::mojom::blink::MediaSessionAction action) override {}
private:
mojo::Receiver<mojom::blink::MediaSessionService> receiver_{this};
};
} // namespace
class MediaSessionTest : public PageTestBase {
public:
MediaSessionTest() = default;
void SetUp() override {
PageTestBase::SetUp();
mock_service_ = std::make_unique<MockMediaSessionService>();
media_session_ =
MediaSession::mediaSession(*GetFrame().DomWindow()->navigator());
media_session_->service_ = mock_service_->CreateRemoteAndBind();
media_session_->clock_ = &test_clock_;
}
void SetPositionState(double duration,
double position,
double playback_rate) {
auto* position_state = MediaPositionState::Create();
position_state->setDuration(duration);
position_state->setPosition(position);
position_state->setPlaybackRate(playback_rate);
NonThrowableExceptionState exception_state;
media_session_->setPositionState(position_state, exception_state);
}
void ClearPositionState() {
NonThrowableExceptionState exception_state;
media_session_->setPositionState(MediaPositionState::Create(),
exception_state);
}
void SetPlaybackState(const String& state) {
media_session_->setPlaybackState(state);
}
MockMediaSessionService& service() { return *mock_service_.get(); }
base::SimpleTestTickClock& clock() { return test_clock_; }
private:
base::SimpleTestTickClock test_clock_;
std::unique_ptr<MockMediaSessionService> mock_service_;
Persistent<MediaSession> media_session_;
DISALLOW_COPY_AND_ASSIGN(MediaSessionTest);
};
TEST_F(MediaSessionTest, PlaybackPositionState_None) {
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPlaybackState("none");
SetPositionState(10, 5, 1.0);
loop.Run();
}
TEST_F(MediaSessionTest, PlaybackPositionState_Paused) {
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(0.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPlaybackState("paused");
SetPositionState(10, 5, 1.0);
loop.Run();
}
TEST_F(MediaSessionTest, PlaybackPositionState_Playing) {
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPlaybackState("playing");
SetPositionState(10, 5, 1.0);
loop.Run();
}
TEST_F(MediaSessionTest, PlaybackPositionState_Paused_Clear) {
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(0.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPlaybackState("paused");
SetPositionState(10, 5, 1.0);
loop.Run();
}
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_FALSE(position_state);
loop.Quit();
}));
ClearPositionState();
loop.Run();
}
}
TEST_F(MediaSessionTest, PositionPlaybackState_None) {
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPositionState(10, 5, 1.0);
SetPlaybackState("none");
loop.Run();
}
TEST_F(MediaSessionTest, PositionPlaybackState_Paused_None) {
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromMinutes(1), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPositionState(600, 60, 1.0);
loop.Run();
}
clock().Advance(base::TimeDelta::FromMinutes(1));
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromMinutes(2), position_state->position);
EXPECT_EQ(0.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPlaybackState("paused");
loop.Run();
}
clock().Advance(base::TimeDelta::FromMinutes(1));
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromMinutes(2), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPlaybackState("none");
loop.Run();
}
}
TEST_F(MediaSessionTest, PositionPlaybackState_Paused_Playing) {
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromMinutes(1), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPositionState(600, 60, 1.0);
loop.Run();
}
clock().Advance(base::TimeDelta::FromMinutes(1));
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromMinutes(2), position_state->position);
EXPECT_EQ(0.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPlaybackState("paused");
loop.Run();
}
clock().Advance(base::TimeDelta::FromMinutes(1));
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromMinutes(2), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPlaybackState("playing");
loop.Run();
}
}
TEST_F(MediaSessionTest, PositionPlaybackState_Playing) {
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
SetPositionState(10, 5, 1.0);
SetPlaybackState("playing");
loop.Run();
}
} // namespace blink