Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Side by Side Diff: content/renderer/mus/compositor_mus_connection_unittest.cc

Issue 1749323002: Update WindowTree::OnWindowInputEventAck to include handled (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Missing Component Build DEPS Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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.
4
5 #include "content/renderer/mus/compositor_mus_connection.h"
6
7 #include "base/macros.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/test/test_simple_task_runner.h"
11 #include "base/time/time.h"
12 #include "components/mus/public/cpp/tests/test_window.h"
13 #include "components/mus/public/interfaces/input_event_constants.mojom.h"
14 #include "components/mus/public/interfaces/input_events.mojom.h"
15 #include "components/mus/public/interfaces/input_key_codes.mojom.h"
16 #include "content/common/input/did_overscroll_params.h"
17 #include "content/common/input/input_event_ack.h"
18 #include "content/common/input/input_event_ack_state.h"
19 #include "content/public/test/mock_render_thread.h"
20 #include "content/renderer/input/input_handler_manager.h"
21 #include "content/renderer/input/input_handler_manager_client.h"
22 #include "content/renderer/input/render_widget_input_handler.h"
23 #include "content/renderer/mus/render_widget_mus_connection.h"
24 #include "content/renderer/render_widget.h"
25 #include "content/test/fake_compositor_dependencies.h"
26 #include "content/test/fake_renderer_scheduler.h"
27 #include "mojo/public/cpp/bindings/interface_request.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 namespace {
31
32 // Wrapper for the callback provided to
33 // CompositorMusConnection:OnWindowInputEvent. This tracks whether the it was
34 // called, along with the result.
35 class TestCallback : public base::RefCounted<TestCallback> {
36 public:
37 TestCallback() : called_(false), result_(false) {}
38
39 bool called() { return called_; }
40 bool result() { return result_; }
41
42 void BoolCallback(bool result) {
43 called_ = true;
44 result_ = result;
45 }
46
47 private:
48 friend class base::RefCounted<TestCallback>;
49
50 ~TestCallback() {}
51
52 bool called_;
53 bool result_;
54
55 DISALLOW_COPY_AND_ASSIGN(TestCallback);
56 };
57
58 // Allows for overriding the behaviour of HandleInputEvent, to simulate input
59 // handlers which consume events before they are sent to the renderer.
60 class TestInputHandlerManager : public content::InputHandlerManager {
61 public:
62 TestInputHandlerManager(
63 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
64 content::InputHandlerManagerClient* client,
65 scheduler::RendererScheduler* renderer_scheduler)
66 : InputHandlerManager(task_runner, client, renderer_scheduler),
67 override_result_(false),
68 result_(content::InputEventAckState::INPUT_EVENT_ACK_STATE_UNKNOWN) {}
69 ~TestInputHandlerManager() override {}
70
71 // Stops overriding the behaviour of HandleInputEvent
72 void ClearHandleInputEventOverride();
73
74 // Overrides the behaviour of HandleInputEvent, returing |result|.
75 void SetHandleInputEventResult(content::InputEventAckState result);
76
77 // content::InputHandlerManager:
78 content::InputEventAckState HandleInputEvent(
79 int routing_id,
80 const blink::WebInputEvent* input_event,
81 ui::LatencyInfo* latency_info) override;
82
83 private:
84 // If true content::InputHandlerManager::HandleInputEvent is not called.
85 bool override_result_;
86
87 // The result to return in HandleInputEvent if |override_result_|.
88 content::InputEventAckState result_;
89
90 DISALLOW_COPY_AND_ASSIGN(TestInputHandlerManager);
91 };
92
93 void TestInputHandlerManager::ClearHandleInputEventOverride() {
94 override_result_ = false;
95 }
96
97 void TestInputHandlerManager::SetHandleInputEventResult(
98 content::InputEventAckState result) {
99 override_result_ = true;
100 result_ = result;
101 }
102
103 content::InputEventAckState TestInputHandlerManager::HandleInputEvent(
104 int routing_id,
105 const blink::WebInputEvent* input_event,
106 ui::LatencyInfo* latency_info) {
107 if (override_result_)
108 return result_;
109 return content::InputHandlerManager::HandleInputEvent(routing_id, input_event,
110 latency_info);
111 }
112
113 // Empty implementation of InputHandlerManagerClient.
114 class TestInputHandlerManagerClient
115 : public content::InputHandlerManagerClient {
116 public:
117 TestInputHandlerManagerClient() {}
118 ~TestInputHandlerManagerClient() override{};
119
120 // content::InputHandlerManagerClient:
121 void SetBoundHandler(const Handler& handler) override {}
122 void DidAddInputHandler(
123 int routing_id,
124 ui::SynchronousInputHandlerProxy* synchronous_handler) override {}
125 void DidRemoveInputHandler(int routing_id) override {}
126 void DidOverscroll(int routing_id,
127 const content::DidOverscrollParams& params) override {}
128 void DidStopFlinging(int routing_id) override {}
129 void NonBlockingInputEventHandled(int routing_id,
130 blink::WebInputEvent::Type type) override {}
131
132 private:
133 DISALLOW_COPY_AND_ASSIGN(TestInputHandlerManagerClient);
134 };
135
136 // Implementation of RenderWidget for testing, performs no initialization.
137 class TestRenderWidget : public content::RenderWidget {
138 public:
139 explicit TestRenderWidget(content::CompositorDependencies* compositor_deps)
140 : content::RenderWidget(compositor_deps,
141 blink::WebPopupTypeNone,
142 blink::WebScreenInfo(),
143 true,
144 false,
145 false) {}
146
147 protected:
148 ~TestRenderWidget() override {}
149
150 private:
151 DISALLOW_COPY_AND_ASSIGN(TestRenderWidget);
152 };
153
154 // Test override of RenderWidgetInputHandler to allow the control of
155 // HandleInputEvent. This will perform no actions on input until a
156 // RenderWidgetInputHandlerDelegate is set. Once set this will always ack
157 // received events.
158 class TestRenderWidgetInputHandler : public content::RenderWidgetInputHandler {
159 public:
160 TestRenderWidgetInputHandler(content::RenderWidget* render_widget);
161 ~TestRenderWidgetInputHandler() override {}
162
163 void set_delegate(content::RenderWidgetInputHandlerDelegate* delegate) {
164 delegate_ = delegate;
165 }
166 void set_state(content::InputEventAckState state) { state_ = state; }
167
168 // content::RenderWidgetInputHandler:
169 void HandleInputEvent(const blink::WebInputEvent& input_event,
170 const ui::LatencyInfo& latency_info,
171 content::InputEventDispatchType dispatch_type) override;
172
173 private:
174 // The input delegate which receives event acks.
175 content::RenderWidgetInputHandlerDelegate* delegate_;
176
177 // The result of input handling to send to |delegate_| during the ack.
178 content::InputEventAckState state_;
179
180 DISALLOW_COPY_AND_ASSIGN(TestRenderWidgetInputHandler);
181 };
182
183 TestRenderWidgetInputHandler::TestRenderWidgetInputHandler(
184 content::RenderWidget* render_widget)
185 : content::RenderWidgetInputHandler(render_widget, render_widget),
186 delegate_(nullptr),
187 state_(content::InputEventAckState::INPUT_EVENT_ACK_STATE_UNKNOWN) {}
188
189 void TestRenderWidgetInputHandler::HandleInputEvent(
190 const blink::WebInputEvent& input_event,
191 const ui::LatencyInfo& latency_info,
192 content::InputEventDispatchType dispatch_type) {
193 if (delegate_) {
194 scoped_ptr<content::InputEventAck> ack(
195 new content::InputEventAck(input_event.type, state_));
196 delegate_->OnInputEventAck(std::move(ack));
197 }
198 }
199
200 } // namespace
201
202 namespace content {
203
204 // Test suite for CompositorMusConnection, this does not setup a full renderer
205 // environment. This does not establish a connection to a mus server, nor does
206 // it initialize one.
207 class CompositorMusConnectionTest : public testing::Test {
208 public:
209 CompositorMusConnectionTest() {}
210 ~CompositorMusConnectionTest() override {}
211
212 // Initializes |event| with valid parameters for a key event, so that it can
213 // be converted to a web event by CompositorMusConnection.
214 void GenerateKeyEvent(mus::mojom::EventPtr& event);
215
216 // Calls CompositorMusConnection::OnWindowInputEvent.
217 void OnWindowInputEvent(mus::Window* window,
218 mus::mojom::EventPtr event,
219 scoped_ptr<base::Callback<void(bool)>>* ack_callback);
220
221 // Confirms the state of pending tasks enqueued on each task runner, and runs
222 // until idle.
223 void VerifyAndRunQueues(bool main_task_runner_enqueued,
224 bool compositor_task_runner_enqueued);
225
226 CompositorMusConnection* compositor_connection() {
227 return compositor_connection_.get();
228 }
229 RenderWidgetMusConnection* connection() { return connection_; }
230 TestInputHandlerManager* input_handler_manager() {
231 return input_handler_manager_.get();
232 }
233 TestRenderWidgetInputHandler* render_widget_input_handler() {
234 return render_widget_input_handler_.get();
235 }
236
237 // testing::Test:
238 void SetUp() override;
239 void TearDown() override;
240
241 private:
242 // Mocks/Fakes of the testing environment.
243 TestInputHandlerManagerClient input_handler_manager_client_;
244 FakeCompositorDependencies compositor_dependencies_;
245 FakeRendererScheduler renderer_scheduler_;
246 MockRenderThread render_thread_;
247 scoped_refptr<TestRenderWidget> render_widget_;
248 mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request_;
249
250 // Not owned, RenderWidgetMusConnection tracks in static state. Cleared during
251 // TearDown.
252 RenderWidgetMusConnection* connection_;
253
254 // Test versions of task runners, see VerifyAndRunQueues to use in testing.
255 scoped_refptr<base::TestSimpleTaskRunner> main_task_runner_;
256 scoped_refptr<base::TestSimpleTaskRunner> compositor_task_runner_;
257
258 // Actual CompositorMusConnection for testing.
259 scoped_refptr<CompositorMusConnection> compositor_connection_;
260
261 // Test implementations, to control input given to |compositor_connection_|.
262 scoped_ptr<TestInputHandlerManager> input_handler_manager_;
263 scoped_ptr<TestRenderWidgetInputHandler> render_widget_input_handler_;
264
265 DISALLOW_COPY_AND_ASSIGN(CompositorMusConnectionTest);
266 };
267
268 void CompositorMusConnectionTest::GenerateKeyEvent(
269 mus::mojom::EventPtr& event) {
270 event->action = mus::mojom::EventType::KEY_PRESSED;
271 event->time_stamp = base::TimeTicks::Now().ToInternalValue();
272 event->key_data = mus::mojom::KeyData::New();
273 event->key_data->is_char = true;
274 event->key_data->windows_key_code = mus::mojom::KeyboardCode::A;
275 }
276
277 void CompositorMusConnectionTest::OnWindowInputEvent(
278 mus::Window* window,
279 mus::mojom::EventPtr event,
280 scoped_ptr<base::Callback<void(bool)>>* ack_callback) {
281 compositor_connection_->OnWindowInputEvent(window, std::move(event),
282 ack_callback);
283 }
284
285 void CompositorMusConnectionTest::VerifyAndRunQueues(
286 bool main_task_runner_enqueued,
287 bool compositor_task_runner_enqueued) {
288 // Run through the enqueued actions.
289 EXPECT_EQ(main_task_runner_enqueued, main_task_runner_->HasPendingTask());
290 main_task_runner_->RunUntilIdle();
291
292 EXPECT_EQ(compositor_task_runner_enqueued,
293 compositor_task_runner_->HasPendingTask());
294 compositor_task_runner_->RunUntilIdle();
295 }
296
297 void CompositorMusConnectionTest::SetUp() {
298 testing::Test::SetUp();
299
300 main_task_runner_ = new base::TestSimpleTaskRunner();
301 compositor_task_runner_ = new base::TestSimpleTaskRunner();
302
303 input_handler_manager_.reset(new TestInputHandlerManager(
304 compositor_task_runner_, &input_handler_manager_client_,
305 &renderer_scheduler_));
306
307 const int routing_id = 42;
308 compositor_connection_ = new CompositorMusConnection(
309 routing_id, main_task_runner_, compositor_task_runner_,
310 std::move(request_), input_handler_manager_.get());
311
312 // CompositorMusConnection attempts to create connection to the non-existant
313 // server. Clear that.
314 compositor_task_runner_->ClearPendingTasks();
315
316 render_widget_ = new TestRenderWidget(&compositor_dependencies_);
317 render_widget_input_handler_.reset(
318 new TestRenderWidgetInputHandler(render_widget_.get()));
319 connection_ = RenderWidgetMusConnection::GetOrCreate(routing_id);
320 connection_->SetInputHandler(render_widget_input_handler_.get());
321 }
322
323 void CompositorMusConnectionTest::TearDown() {
324 // Clear static state.
325 connection_->OnConnectionLost();
326 testing::Test::TearDown();
327 }
328
329 // Tests that for events which the renderer will ack, yet not consume, that
330 // CompositorMusConnection consumes the ack during OnWindowInputEvent, and calls
331 // it with the correct state once processed.
332 TEST_F(CompositorMusConnectionTest, NotConsumed) {
333 TestRenderWidgetInputHandler* input_handler = render_widget_input_handler();
334 input_handler->set_delegate(connection());
335 input_handler->set_state(
336 InputEventAckState::INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
337
338 mus::TestWindow test_window;
339 mus::mojom::EventPtr event = mus::mojom::Event::New();
340 GenerateKeyEvent(event);
341 scoped_refptr<TestCallback> test_callback(new TestCallback);
342 scoped_ptr<base::Callback<void(bool)>> ack_callback(
343 new base::Callback<void(bool)>(
344 base::Bind(&::TestCallback::BoolCallback, test_callback)));
345
346 OnWindowInputEvent(&test_window, std::move(event), &ack_callback);
347 // OnWindowInputEvent is expected to clear the callback if it plans on
348 // handling the ack.
349 EXPECT_FALSE(ack_callback.get());
350
351 VerifyAndRunQueues(true, true);
352
353 // The ack callback should have been called
354 EXPECT_TRUE(test_callback->called());
355 EXPECT_FALSE(test_callback->result());
356 }
357
358 // Tests that for events which the renderer will ack, and consume, that
359 // CompositorMusConnection consumes the ack during OnWindowInputEvent, and calls
360 // it with the correct state once processed.
361 TEST_F(CompositorMusConnectionTest, Consumed) {
362 TestRenderWidgetInputHandler* input_handler = render_widget_input_handler();
363 input_handler->set_delegate(connection());
364 input_handler->set_state(InputEventAckState::INPUT_EVENT_ACK_STATE_CONSUMED);
365
366 mus::TestWindow test_window;
367 mus::mojom::EventPtr event = mus::mojom::Event::New();
368 GenerateKeyEvent(event);
369 scoped_refptr<TestCallback> test_callback(new TestCallback);
370 scoped_ptr<base::Callback<void(bool)>> ack_callback(
371 new base::Callback<void(bool)>(
372 base::Bind(&::TestCallback::BoolCallback, test_callback)));
373
374 OnWindowInputEvent(&test_window, std::move(event), &ack_callback);
375 // OnWindowInputEvent is expected to clear the callback if it plans on
376 // handling the ack.
377 EXPECT_FALSE(ack_callback.get());
378
379 VerifyAndRunQueues(true, true);
380
381 // The ack callback should have been called
382 EXPECT_TRUE(test_callback->called());
383 EXPECT_TRUE(test_callback->result());
384 }
385
386 // Tests that when the RenderWidgetInputHandler does not ack before a new event
387 // arrives, that only the most recent ack is fired.
388 TEST_F(CompositorMusConnectionTest, LostAck) {
389 mus::TestWindow test_window;
390 mus::mojom::EventPtr event1 = mus::mojom::Event::New();
391 GenerateKeyEvent(event1);
392 scoped_refptr<TestCallback> test_callback1(new TestCallback);
393 scoped_ptr<base::Callback<void(bool)>> ack_callback1(
394 new base::Callback<void(bool)>(
395 base::Bind(&::TestCallback::BoolCallback, test_callback1)));
396
397 OnWindowInputEvent(&test_window, std::move(event1), &ack_callback1);
398 EXPECT_FALSE(ack_callback1.get());
399 // When simulating the timeout the ack is never enqueued
400 VerifyAndRunQueues(true, false);
401
402 // Setting a delegate will lead to the next event being acked. Having a
403 // cleared queue simulates the input handler timing out on an event.
404 TestRenderWidgetInputHandler* input_handler = render_widget_input_handler();
405 input_handler->set_delegate(connection());
406 input_handler->set_state(InputEventAckState::INPUT_EVENT_ACK_STATE_CONSUMED);
407
408 mus::mojom::EventPtr event2 = mus::mojom::Event::New();
409 GenerateKeyEvent(event2);
410 scoped_refptr<TestCallback> test_callback2(new TestCallback);
411 scoped_ptr<base::Callback<void(bool)>> ack_callback2(
412 new base::Callback<void(bool)>(
413 base::Bind(&::TestCallback::BoolCallback, test_callback2)));
414 OnWindowInputEvent(&test_window, std::move(event2), &ack_callback2);
415 EXPECT_FALSE(ack_callback2.get());
416
417 VerifyAndRunQueues(true, true);
418
419 // Only the most recent ack was called.
420 EXPECT_FALSE(test_callback1->called());
421 EXPECT_TRUE(test_callback2->called());
422 EXPECT_TRUE(test_callback2->result());
423 }
424
425 // Tests that when an input handler consumes the event, that
426 // CompositorMusConnection does not consume the ack, nor calls it.
427 TEST_F(CompositorMusConnectionTest, InputHandlerConsumes) {
428 input_handler_manager()->SetHandleInputEventResult(
429 InputEventAckState::INPUT_EVENT_ACK_STATE_CONSUMED);
430 mus::TestWindow test_window;
431 mus::mojom::EventPtr event = mus::mojom::Event::New();
432 GenerateKeyEvent(event);
433 scoped_refptr<TestCallback> test_callback(new TestCallback);
434 scoped_ptr<base::Callback<void(bool)>> ack_callback(
435 new base::Callback<void(bool)>(
436 base::Bind(&::TestCallback::BoolCallback, test_callback)));
437
438 OnWindowInputEvent(&test_window, std::move(event), &ack_callback);
439
440 EXPECT_TRUE(ack_callback.get());
441 VerifyAndRunQueues(false, false);
442 EXPECT_FALSE(test_callback->called());
443 }
444
445 // Tests that when the renderer will not ack an event, that
446 // CompositorMusConnection does not consume the ack, nor calls it.
447 TEST_F(CompositorMusConnectionTest, RendererWillNotSendAck) {
448 mus::TestWindow test_window;
449 mus::mojom::EventPtr event = mus::mojom::Event::New();
450 event->action = mus::mojom::EventType::POINTER_DOWN;
451 event->time_stamp = base::TimeTicks::Now().ToInternalValue();
452 event->pointer_data = mus::mojom::PointerData::New();
453
454 scoped_refptr<TestCallback> test_callback(new TestCallback);
455 scoped_ptr<base::Callback<void(bool)>> ack_callback(
456 new base::Callback<void(bool)>(
457 base::Bind(&::TestCallback::BoolCallback, test_callback)));
458
459 OnWindowInputEvent(&test_window, std::move(event), &ack_callback);
460 EXPECT_TRUE(ack_callback.get());
461
462 VerifyAndRunQueues(true, false);
463 EXPECT_FALSE(test_callback->called());
464 }
465
466 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/mus/compositor_mus_connection.cc ('k') | content/renderer/mus/render_widget_mus_connection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698