blob: 02e1042398ac4e00f28a5807ba2df72c0c51477b [file] [log] [blame]
// Copyright 2018 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 "content/browser/renderer_host/input/fling_scheduler.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/agent_scheduling_group_host.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/test/mock_render_widget_host_delegate.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_render_widget_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_WIN)
#include "ui/display/win/test/scoped_screen_win.h"
#endif
namespace content {
class FakeFlingScheduler : public FlingScheduler {
public:
FakeFlingScheduler(RenderWidgetHostImpl* host) : FlingScheduler(host) {}
void ScheduleFlingProgress(
base::WeakPtr<FlingController> fling_controller) override {
FlingScheduler::ScheduleFlingProgress(fling_controller);
fling_in_progress_ = true;
}
void DidStopFlingingOnBrowser(
base::WeakPtr<FlingController> fling_controller) override {
FlingScheduler::DidStopFlingingOnBrowser(fling_controller);
fling_in_progress_ = false;
}
bool fling_in_progress() const { return fling_in_progress_; }
ui::Compositor* compositor() { return GetCompositor(); }
ui::Compositor* observed_compositor() { return observed_compositor_; }
base::WeakPtr<FlingController> fling_controller() const {
return fling_controller_;
}
private:
bool fling_in_progress_ = false;
DISALLOW_COPY_AND_ASSIGN(FakeFlingScheduler);
};
class FlingSchedulerTest : public testing::Test,
public FlingControllerEventSenderClient {
public:
FlingSchedulerTest() {}
void SetUp() override {
view_ = CreateView();
widget_host_->SetView(view_.get());
fling_scheduler_ = std::make_unique<FakeFlingScheduler>(widget_host_.get());
fling_controller_ = std::make_unique<FlingController>(
this, fling_scheduler_.get(), FlingController::Config());
}
void TearDown() override {
view_.release()->Destroy(); // 'delete this' is called internally.
widget_host_->ShutdownAndDestroyWidget(false);
widget_host_.reset();
process_host_->Cleanup();
agent_scheduling_group_host_.reset();
process_host_.reset();
browser_context_.reset();
base::RunLoop().RunUntilIdle();
}
std::unique_ptr<TestRenderWidgetHostView> CreateView() {
browser_context_ = std::make_unique<TestBrowserContext>();
process_host_ =
std::make_unique<MockRenderProcessHost>(browser_context_.get());
process_host_->Init();
agent_scheduling_group_host_ =
std::make_unique<AgentSchedulingGroupHost>(*process_host_);
int32_t routing_id = process_host_->GetNextRoutingID();
delegate_ = std::make_unique<MockRenderWidgetHostDelegate>();
widget_host_ = TestRenderWidgetHost::Create(
/* frame_tree= */ nullptr, delegate_.get(),
*agent_scheduling_group_host_, routing_id, false);
delegate_->set_widget_host(widget_host_.get());
return std::make_unique<TestRenderWidgetHostView>(widget_host_.get());
}
void SimulateFlingStart(const gfx::Vector2dF& velocity) {
blink::WebGestureEvent fling_start(
blink::WebInputEvent::Type::kGestureFlingStart, 0,
base::TimeTicks::Now(), blink::WebGestureDevice::kTouchscreen);
fling_start.data.fling_start.velocity_x = velocity.x();
fling_start.data.fling_start.velocity_y = velocity.y();
GestureEventWithLatencyInfo fling_start_with_latency(fling_start);
fling_controller_->ObserveAndMaybeConsumeGestureEvent(
fling_start_with_latency);
}
void SimulateFlingCancel() {
blink::WebGestureEvent fling_cancel(
blink::WebInputEvent::Type::kGestureFlingCancel, 0,
base::TimeTicks::Now(), blink::WebGestureDevice::kTouchscreen);
fling_cancel.data.fling_cancel.prevent_boosting = true;
GestureEventWithLatencyInfo fling_cancel_with_latency(fling_cancel);
fling_controller_->ObserveAndMaybeConsumeGestureEvent(
fling_cancel_with_latency);
}
// FlingControllerEventSenderClient
void SendGeneratedWheelEvent(
const MouseWheelEventWithLatencyInfo& wheel_event) override {}
void SendGeneratedGestureScrollEvents(
const GestureEventWithLatencyInfo& gesture_event) override {}
gfx::Size GetRootWidgetViewportSize() override {
return gfx::Size(1920, 1080);
}
std::unique_ptr<FlingController> fling_controller_;
std::unique_ptr<FakeFlingScheduler> fling_scheduler_;
private:
BrowserTaskEnvironment task_environment_;
std::unique_ptr<TestBrowserContext> browser_context_;
std::unique_ptr<RenderWidgetHostImpl> widget_host_;
std::unique_ptr<MockRenderProcessHost> process_host_;
std::unique_ptr<AgentSchedulingGroupHost> agent_scheduling_group_host_;
std::unique_ptr<TestRenderWidgetHostView> view_;
std::unique_ptr<MockRenderWidgetHostDelegate> delegate_;
#if defined(OS_WIN)
display::win::test::ScopedScreenWin scoped_screen_win_;
#endif
DISALLOW_COPY_AND_ASSIGN(FlingSchedulerTest);
};
TEST_F(FlingSchedulerTest, ScheduleNextFlingProgress) {
base::TimeTicks progress_time = base::TimeTicks::Now();
SimulateFlingStart(gfx::Vector2dF(1000, 0));
EXPECT_TRUE(fling_scheduler_->fling_in_progress());
EXPECT_EQ(fling_controller_.get(),
fling_scheduler_->fling_controller().get());
EXPECT_EQ(fling_scheduler_->compositor(),
fling_scheduler_->observed_compositor());
progress_time += base::Milliseconds(17);
fling_controller_->ProgressFling(progress_time);
EXPECT_TRUE(fling_scheduler_->fling_in_progress());
}
TEST_F(FlingSchedulerTest, FlingCancelled) {
SimulateFlingStart(gfx::Vector2dF(1000, 0));
EXPECT_TRUE(fling_scheduler_->fling_in_progress());
EXPECT_EQ(fling_controller_.get(),
fling_scheduler_->fling_controller().get());
EXPECT_EQ(fling_scheduler_->compositor(),
fling_scheduler_->observed_compositor());
SimulateFlingCancel();
EXPECT_FALSE(fling_scheduler_->fling_in_progress());
EXPECT_EQ(nullptr, fling_scheduler_->fling_controller());
EXPECT_EQ(nullptr, fling_scheduler_->observed_compositor());
}
} // namespace content