Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / test / base / view_event_test_base.cc
blob392a6b94ba1e37f4be0915f18f371487c50f8a57
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/test/base/view_event_test_base.h"
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "chrome/test/base/chrome_unit_test_suite.h"
10 #include "chrome/test/base/interactive_test_utils.h"
11 #include "chrome/test/base/testing_browser_process.h"
12 #include "chrome/test/base/view_event_test_platform_part.h"
13 #include "ui/base/ime/input_method_initializer.h"
14 #include "ui/base/test/ui_controls.h"
15 #include "ui/compositor/test/context_factories_for_test.h"
16 #include "ui/views/view.h"
17 #include "ui/views/widget/widget.h"
19 namespace {
21 // View subclass that allows you to specify the preferred size.
22 class TestView : public views::View {
23 public:
24 TestView() {}
26 void SetPreferredSize(const gfx::Size& size) {
27 preferred_size_ = size;
28 PreferredSizeChanged();
31 virtual gfx::Size GetPreferredSize() const override {
32 if (!preferred_size_.IsEmpty())
33 return preferred_size_;
34 return View::GetPreferredSize();
37 virtual void Layout() override {
38 View* child_view = child_at(0);
39 child_view->SetBounds(0, 0, width(), height());
42 private:
43 gfx::Size preferred_size_;
45 DISALLOW_COPY_AND_ASSIGN(TestView);
48 // Delay in background thread before posting mouse move.
49 const int kMouseMoveDelayMS = 200;
51 } // namespace
53 ViewEventTestBase::ViewEventTestBase()
54 : window_(NULL),
55 content_view_(NULL) {
56 // The TestingBrowserProcess must be created in the constructor because there
57 // are tests that require it before SetUp() is called.
58 TestingBrowserProcess::CreateInstance();
61 void ViewEventTestBase::Done() {
62 base::MessageLoop::current()->Quit();
64 // If we're in a nested message loop, as is the case with menus, we
65 // need to quit twice. The second quit does that for us. Finish all
66 // pending UI events before posting closure because events it may be
67 // executed before UI events are executed.
68 ui_controls::RunClosureAfterAllPendingUIEvents(
69 base::MessageLoop::QuitClosure());
72 void ViewEventTestBase::SetUpTestCase() {
73 ChromeUnitTestSuite::InitializeProviders();
74 ChromeUnitTestSuite::InitializeResourceBundle();
77 void ViewEventTestBase::SetUp() {
78 views::ViewsDelegate::views_delegate = &views_delegate_;
79 ui::InitializeInputMethodForTesting();
81 // The ContextFactory must exist before any Compositors are created.
82 bool enable_pixel_output = false;
83 ui::ContextFactory* context_factory =
84 ui::InitializeContextFactoryForTests(enable_pixel_output);
86 platform_part_.reset(ViewEventTestPlatformPart::Create(context_factory));
87 gfx::NativeWindow context = platform_part_->GetContext();
88 window_ = views::Widget::CreateWindowWithContext(this, context);
91 void ViewEventTestBase::TearDown() {
92 if (window_) {
93 window_->Close();
94 content::RunAllPendingInMessageLoop();
95 window_ = NULL;
98 ui::Clipboard::DestroyClipboardForCurrentThread();
99 platform_part_.reset();
101 ui::TerminateContextFactoryForTests();
103 ui::ShutdownInputMethodForTesting();
104 views::ViewsDelegate::views_delegate = NULL;
107 bool ViewEventTestBase::CanResize() const {
108 return true;
111 views::View* ViewEventTestBase::GetContentsView() {
112 if (!content_view_) {
113 // Wrap the real view (as returned by CreateContentsView) in a View so
114 // that we can customize the preferred size.
115 TestView* test_view = new TestView();
116 test_view->SetPreferredSize(GetPreferredSize());
117 test_view->AddChildView(CreateContentsView());
118 content_view_ = test_view;
120 return content_view_;
123 const views::Widget* ViewEventTestBase::GetWidget() const {
124 return content_view_->GetWidget();
127 views::Widget* ViewEventTestBase::GetWidget() {
128 return content_view_->GetWidget();
131 ViewEventTestBase::~ViewEventTestBase() {
132 TestingBrowserProcess::DeleteInstance();
135 void ViewEventTestBase::StartMessageLoopAndRunTest() {
136 ASSERT_TRUE(
137 ui_test_utils::ShowAndFocusNativeWindow(window_->GetNativeWindow()));
139 // Flush any pending events to make sure we start with a clean slate.
140 content::RunAllPendingInMessageLoop();
142 // Schedule a task that starts the test. Need to do this as we're going to
143 // run the message loop.
144 base::MessageLoop::current()->PostTask(
145 FROM_HERE, base::Bind(&ViewEventTestBase::DoTestOnMessageLoop, this));
147 content::RunMessageLoop();
150 gfx::Size ViewEventTestBase::GetPreferredSize() const {
151 return gfx::Size();
154 void ViewEventTestBase::ScheduleMouseMoveInBackground(int x, int y) {
155 if (!dnd_thread_.get()) {
156 dnd_thread_.reset(new base::Thread("mouse-move-thread"));
157 dnd_thread_->Start();
159 dnd_thread_->message_loop()->PostDelayedTask(
160 FROM_HERE,
161 base::Bind(base::IgnoreResult(&ui_controls::SendMouseMove), x, y),
162 base::TimeDelta::FromMilliseconds(kMouseMoveDelayMS));
165 void ViewEventTestBase::StopBackgroundThread() {
166 dnd_thread_.reset(NULL);
169 void ViewEventTestBase::RunTestMethod(const base::Closure& task) {
170 StopBackgroundThread();
172 task.Run();
173 if (HasFatalFailure())
174 Done();