blob: 5087ce44a082d0612f4abb50fb2658cf710ddbab [file] [log] [blame]
// Copyright 2016 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 "core/paint/VideoPainter.h"
#include "core/frame/FrameView.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLMediaElement.h"
#include "core/loader/EmptyClients.h"
#include "core/paint/StubChromeClientForSPv2.h"
#include "core/testing/DummyPageHolder.h"
#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
#include "platform/testing/UnitTestHelpers.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCompositorSupport.h"
#include "public/platform/WebLayer.h"
#include "public/platform/WebMediaPlayer.h"
#include "public/platform/WebSize.h"
#include "testing/gtest/include/gtest/gtest.h"
// Integration tests of video painting code (in SPv2 mode).
namespace blink {
namespace {
class StubWebMediaPlayer : public WebMediaPlayer {
public:
StubWebMediaPlayer(WebMediaPlayerClient* client) : m_client(client) {}
const WebLayer* getWebLayer() { return m_webLayer.get(); }
// WebMediaPlayer
void load(LoadType, const WebMediaPlayerSource&, CORSMode) {
m_networkState = NetworkStateLoaded;
m_client->networkStateChanged();
m_readyState = ReadyStateHaveEnoughData;
m_client->readyStateChanged();
m_webLayer = Platform::current()->compositorSupport()->createLayer();
m_client->setWebLayer(m_webLayer.get());
}
void play() override {}
void pause() override {}
bool supportsSave() const override { return false; }
void seek(double seconds) override {}
void setRate(double) override {}
void setVolume(double) override {}
WebTimeRanges buffered() const override { return WebTimeRanges(); }
WebTimeRanges seekable() const override { return WebTimeRanges(); }
void setSinkId(const WebString& sinkId,
const WebSecurityOrigin&,
WebSetSinkIdCallbacks*) override {}
bool hasVideo() const override { return false; }
bool hasAudio() const override { return false; }
WebSize naturalSize() const override { return WebSize(0, 0); }
bool paused() const override { return false; }
bool seeking() const override { return false; }
double duration() const override { return 0.0; }
double currentTime() const override { return 0.0; }
NetworkState getNetworkState() const override { return m_networkState; }
ReadyState getReadyState() const override { return m_readyState; }
WebString getErrorMessage() override { return WebString(); }
bool didLoadingProgress() override { return false; }
bool hasSingleSecurityOrigin() const override { return true; }
bool didPassCORSAccessCheck() const override { return true; }
double mediaTimeForTimeValue(double timeValue) const override {
return timeValue;
}
unsigned decodedFrameCount() const override { return 0; }
unsigned droppedFrameCount() const override { return 0; }
size_t audioDecodedByteCount() const override { return 0; }
size_t videoDecodedByteCount() const override { return 0; }
void paint(WebCanvas*, const WebRect&, SkPaint&) override {}
private:
WebMediaPlayerClient* m_client;
std::unique_ptr<WebLayer> m_webLayer;
NetworkState m_networkState = NetworkStateEmpty;
ReadyState m_readyState = ReadyStateHaveNothing;
};
class StubFrameLoaderClient : public EmptyFrameLoaderClient {
public:
// FrameLoaderClient
std::unique_ptr<WebMediaPlayer> createWebMediaPlayer(
HTMLMediaElement&,
const WebMediaPlayerSource&,
WebMediaPlayerClient* client) override {
return WTF::makeUnique<StubWebMediaPlayer>(client);
}
};
class VideoPainterTestForSPv2 : public ::testing::Test,
private ScopedSlimmingPaintV2ForTest {
public:
VideoPainterTestForSPv2() : ScopedSlimmingPaintV2ForTest(true) {}
protected:
void SetUp() override {
m_chromeClient = new StubChromeClientForSPv2();
m_frameLoaderClient = new StubFrameLoaderClient;
Page::PageClients clients;
fillWithEmptyClients(clients);
clients.chromeClient = m_chromeClient.get();
m_pageHolder = DummyPageHolder::create(
IntSize(800, 600), &clients, m_frameLoaderClient.get(),
[](Settings& settings) {
settings.setAcceleratedCompositingEnabled(true);
});
document().view()->setParentVisible(true);
document().view()->setSelfVisible(true);
document().setURL(KURL(KURL(), "https://example.com/"));
}
Document& document() { return m_pageHolder->document(); }
bool hasLayerAttached(const WebLayer& layer) {
return m_chromeClient->hasLayer(layer);
}
private:
Persistent<StubChromeClientForSPv2> m_chromeClient;
Persistent<StubFrameLoaderClient> m_frameLoaderClient;
std::unique_ptr<DummyPageHolder> m_pageHolder;
};
TEST_F(VideoPainterTestForSPv2, VideoLayerAppearsInLayerTree) {
// Insert a <video> and allow it to begin loading.
document().body()->setInnerHTML("<video width=300 height=200 src=test.ogv>");
testing::runPendingTasks();
// Force the page to paint.
document().view()->updateAllLifecyclePhases();
// Fetch the layer associated with the <video>, and check that it was
// correctly configured in the layer tree.
HTMLMediaElement* element =
toHTMLMediaElement(document().body()->firstChild());
StubWebMediaPlayer* player =
static_cast<StubWebMediaPlayer*>(element->webMediaPlayer());
const WebLayer* layer = player->getWebLayer();
ASSERT_TRUE(layer);
EXPECT_TRUE(hasLayerAttached(*layer));
EXPECT_EQ(WebSize(300, 200), layer->bounds());
}
} // namespace
} // namespace blink