blob: 4ac0309cf33709794ab803681a7a498eb95a775d [file] [log] [blame]
// Copyright 2017 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/dom/Document.h"
#include "core/frame/LocalFrameView.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/loader/EmptyClients.h"
#include "core/offscreencanvas/OffscreenCanvas.h"
#include "core/testing/DummyPageHolder.h"
#include "modules/canvas/HTMLCanvasElementModule.h"
#include "modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h"
#include "platform/testing/TestingPlatformSupport.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::Mock;
namespace blink {
class OffscreenCanvasTest : public ::testing::Test {
protected:
OffscreenCanvasTest();
void SetUp() override;
DummyPageHolder& Page() const { return *dummy_page_holder_; }
Document& GetDocument() const { return *document_; }
HTMLCanvasElement& CanvasElement() const { return *canvas_element_; }
OffscreenCanvas& OSCanvas() const { return *offscreen_canvas_; }
OffscreenCanvasFrameDispatcher* Dispatcher() const {
return offscreen_canvas_->GetOrCreateFrameDispatcher();
}
OffscreenCanvasRenderingContext2D& Context() const { return *context_; }
ScriptState* GetScriptState() const {
return ToScriptStateForMainWorld(GetDocument().GetFrame());
}
ScopedTestingPlatformSupport<TestingPlatformSupport>& platform() {
return platform_;
}
private:
std::unique_ptr<DummyPageHolder> dummy_page_holder_;
Persistent<Document> document_;
Persistent<HTMLCanvasElement> canvas_element_;
Persistent<OffscreenCanvas> offscreen_canvas_;
Persistent<OffscreenCanvasRenderingContext2D> context_;
ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
};
OffscreenCanvasTest::OffscreenCanvasTest() {}
void OffscreenCanvasTest::SetUp() {
Page::PageClients page_clients;
FillWithEmptyClients(page_clients);
dummy_page_holder_ =
DummyPageHolder::Create(IntSize(800, 600), &page_clients);
document_ = &dummy_page_holder_->GetDocument();
document_->documentElement()->setInnerHTML(
"<body><canvas id='c'></canvas></body>");
document_->View()->UpdateAllLifecyclePhases();
canvas_element_ = toHTMLCanvasElement(document_->getElementById("c"));
DummyExceptionStateForTesting exception_state;
offscreen_canvas_ = HTMLCanvasElementModule::transferControlToOffscreen(
*canvas_element_, exception_state);
CanvasContextCreationAttributes attrs;
context_ = static_cast<OffscreenCanvasRenderingContext2D*>(
offscreen_canvas_->GetCanvasRenderingContext(document_, String("2d"),
attrs));
}
TEST_F(OffscreenCanvasTest, AnimationNotInitiallySuspended) {
ScriptState::Scope scope(GetScriptState());
EXPECT_FALSE(Dispatcher()->IsAnimationSuspended());
}
TEST_F(OffscreenCanvasTest, AnimationActiveAfterCommit) {
ScriptState::Scope scope(GetScriptState());
DummyExceptionStateForTesting exception_state;
EXPECT_FALSE(Dispatcher()->NeedsBeginFrame());
Context().commit(GetScriptState(), exception_state);
EXPECT_TRUE(Dispatcher()->NeedsBeginFrame());
}
TEST_F(OffscreenCanvasTest, AnimationSuspendedWhilePlaceholderHidden) {
ScriptState::Scope scope(GetScriptState());
DummyExceptionStateForTesting exception_state;
// Do a commit and run it to completion so that the frame dispatcher
// instance becomes known to OffscreenCanvas (async).
Context().commit(GetScriptState(), exception_state); // necessary
platform()->RunUntilIdle();
EXPECT_FALSE(Dispatcher()->IsAnimationSuspended());
// Change visibility to hidden -> animation should be suspended
Page().GetPage().SetVisibilityState(kPageVisibilityStateHidden, false);
platform()->RunUntilIdle();
EXPECT_TRUE(Dispatcher()->IsAnimationSuspended());
// Change visibility to visible -> animation should resume
Page().GetPage().SetVisibilityState(kPageVisibilityStateVisible, false);
platform()->RunUntilIdle();
EXPECT_FALSE(Dispatcher()->IsAnimationSuspended());
}
} // blink