Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_view_aura_unittest.cc
blobf20df74774cade1512892de2987d791cd35e0440
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 "content/browser/renderer_host/render_widget_host_view_aura.h"
7 #include "base/basictypes.h"
8 #include "base/command_line.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/memory/shared_memory.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "cc/output/compositor_frame.h"
15 #include "cc/output/compositor_frame_metadata.h"
16 #include "cc/output/copy_output_request.h"
17 #include "cc/surfaces/surface.h"
18 #include "cc/surfaces/surface_manager.h"
19 #include "content/browser/browser_thread_impl.h"
20 #include "content/browser/compositor/resize_lock.h"
21 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
22 #include "content/browser/frame_host/render_widget_host_view_guest.h"
23 #include "content/browser/renderer_host/input/web_input_event_util.h"
24 #include "content/browser/renderer_host/overscroll_controller.h"
25 #include "content/browser/renderer_host/overscroll_controller_delegate.h"
26 #include "content/browser/renderer_host/render_widget_host_delegate.h"
27 #include "content/browser/renderer_host/render_widget_host_impl.h"
28 #include "content/common/gpu/client/gl_helper.h"
29 #include "content/common/gpu/gpu_messages.h"
30 #include "content/common/host_shared_bitmap_manager.h"
31 #include "content/common/input/synthetic_web_input_event_builders.h"
32 #include "content/common/input_messages.h"
33 #include "content/common/view_messages.h"
34 #include "content/public/browser/render_widget_host_view.h"
35 #include "content/public/browser/render_widget_host_view_frame_subscriber.h"
36 #include "content/public/test/mock_render_process_host.h"
37 #include "content/public/test/test_browser_context.h"
38 #include "ipc/ipc_test_sink.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
41 #include "ui/aura/client/aura_constants.h"
42 #include "ui/aura/client/screen_position_client.h"
43 #include "ui/aura/client/window_tree_client.h"
44 #include "ui/aura/env.h"
45 #include "ui/aura/layout_manager.h"
46 #include "ui/aura/test/aura_test_helper.h"
47 #include "ui/aura/test/aura_test_utils.h"
48 #include "ui/aura/test/test_cursor_client.h"
49 #include "ui/aura/test/test_screen.h"
50 #include "ui/aura/test/test_window_delegate.h"
51 #include "ui/aura/window.h"
52 #include "ui/aura/window_event_dispatcher.h"
53 #include "ui/aura/window_observer.h"
54 #include "ui/base/ui_base_types.h"
55 #include "ui/compositor/compositor.h"
56 #include "ui/compositor/layer_tree_owner.h"
57 #include "ui/compositor/test/draw_waiter_for_test.h"
58 #include "ui/events/blink/blink_event_util.h"
59 #include "ui/events/event.h"
60 #include "ui/events/event_utils.h"
61 #include "ui/events/gesture_detection/gesture_configuration.h"
62 #include "ui/events/keycodes/dom3/dom_code.h"
63 #include "ui/events/keycodes/dom4/keycode_converter.h"
64 #include "ui/events/test/event_generator.h"
65 #include "ui/wm/core/default_activation_client.h"
66 #include "ui/wm/core/default_screen_position_client.h"
67 #include "ui/wm/core/window_util.h"
69 using testing::_;
71 using blink::WebGestureEvent;
72 using blink::WebInputEvent;
73 using blink::WebMouseEvent;
74 using blink::WebMouseWheelEvent;
75 using blink::WebTouchEvent;
76 using blink::WebTouchPoint;
78 namespace content {
79 namespace {
81 class TestOverscrollDelegate : public OverscrollControllerDelegate {
82 public:
83 explicit TestOverscrollDelegate(RenderWidgetHostView* view)
84 : view_(view),
85 current_mode_(OVERSCROLL_NONE),
86 completed_mode_(OVERSCROLL_NONE),
87 delta_x_(0.f),
88 delta_y_(0.f) {}
90 ~TestOverscrollDelegate() override {}
92 OverscrollMode current_mode() const { return current_mode_; }
93 OverscrollMode completed_mode() const { return completed_mode_; }
94 float delta_x() const { return delta_x_; }
95 float delta_y() const { return delta_y_; }
97 void Reset() {
98 current_mode_ = OVERSCROLL_NONE;
99 completed_mode_ = OVERSCROLL_NONE;
100 delta_x_ = delta_y_ = 0.f;
103 private:
104 // Overridden from OverscrollControllerDelegate:
105 gfx::Rect GetVisibleBounds() const override {
106 return view_->IsShowing() ? view_->GetViewBounds() : gfx::Rect();
109 bool OnOverscrollUpdate(float delta_x, float delta_y) override {
110 delta_x_ = delta_x;
111 delta_y_ = delta_y;
112 return true;
115 void OnOverscrollComplete(OverscrollMode overscroll_mode) override {
116 EXPECT_EQ(current_mode_, overscroll_mode);
117 completed_mode_ = overscroll_mode;
118 current_mode_ = OVERSCROLL_NONE;
121 void OnOverscrollModeChange(OverscrollMode old_mode,
122 OverscrollMode new_mode) override {
123 EXPECT_EQ(current_mode_, old_mode);
124 current_mode_ = new_mode;
125 delta_x_ = delta_y_ = 0.f;
128 RenderWidgetHostView* view_;
129 OverscrollMode current_mode_;
130 OverscrollMode completed_mode_;
131 float delta_x_;
132 float delta_y_;
134 DISALLOW_COPY_AND_ASSIGN(TestOverscrollDelegate);
137 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
138 public:
139 MockRenderWidgetHostDelegate() {}
140 ~MockRenderWidgetHostDelegate() override {}
141 const NativeWebKeyboardEvent* last_event() const { return last_event_.get(); }
142 protected:
143 // RenderWidgetHostDelegate:
144 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
145 bool* is_keyboard_shortcut) override {
146 last_event_.reset(new NativeWebKeyboardEvent(event));
147 return true;
149 private:
150 scoped_ptr<NativeWebKeyboardEvent> last_event_;
151 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHostDelegate);
154 // Simple observer that keeps track of changes to a window for tests.
155 class TestWindowObserver : public aura::WindowObserver {
156 public:
157 explicit TestWindowObserver(aura::Window* window_to_observe)
158 : window_(window_to_observe) {
159 window_->AddObserver(this);
161 ~TestWindowObserver() override {
162 if (window_)
163 window_->RemoveObserver(this);
166 bool destroyed() const { return destroyed_; }
168 // aura::WindowObserver overrides:
169 void OnWindowDestroyed(aura::Window* window) override {
170 CHECK_EQ(window, window_);
171 destroyed_ = true;
172 window_ = NULL;
175 private:
176 // Window that we're observing, or NULL if it's been destroyed.
177 aura::Window* window_;
179 // Was |window_| destroyed?
180 bool destroyed_;
182 DISALLOW_COPY_AND_ASSIGN(TestWindowObserver);
185 class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
186 public:
187 FakeFrameSubscriber(gfx::Size size, base::Callback<void(bool)> callback)
188 : size_(size), callback_(callback) {}
190 bool ShouldCaptureFrame(const gfx::Rect& damage_rect,
191 base::TimeTicks present_time,
192 scoped_refptr<media::VideoFrame>* storage,
193 DeliverFrameCallback* callback) override {
194 *storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
195 size_,
196 gfx::Rect(size_),
197 size_,
198 base::TimeDelta());
199 *callback = base::Bind(&FakeFrameSubscriber::CallbackMethod, callback_);
200 return true;
203 static void CallbackMethod(base::Callback<void(bool)> callback,
204 base::TimeTicks timestamp,
205 bool success) {
206 callback.Run(success);
209 private:
210 gfx::Size size_;
211 base::Callback<void(bool)> callback_;
214 class FakeWindowEventDispatcher : public aura::WindowEventDispatcher {
215 public:
216 FakeWindowEventDispatcher(aura::WindowTreeHost* host)
217 : WindowEventDispatcher(host),
218 processed_touch_event_count_(0) {}
220 void ProcessedTouchEvent(aura::Window* window,
221 ui::EventResult result) override {
222 WindowEventDispatcher::ProcessedTouchEvent(window, result);
223 processed_touch_event_count_++;
226 size_t processed_touch_event_count() {
227 return processed_touch_event_count_;
230 private:
231 size_t processed_touch_event_count_;
234 class FakeRenderWidgetHostViewAura : public RenderWidgetHostViewAura {
235 public:
236 FakeRenderWidgetHostViewAura(RenderWidgetHost* widget,
237 bool is_guest_view_hack)
238 : RenderWidgetHostViewAura(widget, is_guest_view_hack),
239 has_resize_lock_(false) {}
241 void UseFakeDispatcher() {
242 dispatcher_ = new FakeWindowEventDispatcher(window()->GetHost());
243 scoped_ptr<aura::WindowEventDispatcher> dispatcher(dispatcher_);
244 aura::test::SetHostDispatcher(window()->GetHost(), dispatcher.Pass());
247 ~FakeRenderWidgetHostViewAura() override {}
249 scoped_ptr<ResizeLock> DelegatedFrameHostCreateResizeLock(
250 bool defer_compositor_lock) override {
251 gfx::Size desired_size = window()->bounds().size();
252 return scoped_ptr<ResizeLock>(
253 new FakeResizeLock(desired_size, defer_compositor_lock));
256 bool DelegatedFrameCanCreateResizeLock() const override { return true; }
258 void RunOnCompositingDidCommit() {
259 GetDelegatedFrameHost()->OnCompositingDidCommitForTesting(
260 window()->GetHost()->compositor());
263 void InterceptCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
264 last_copy_request_ = request.Pass();
265 if (last_copy_request_->has_texture_mailbox()) {
266 // Give the resulting texture a size.
267 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
268 GLuint texture = gl_helper->ConsumeMailboxToTexture(
269 last_copy_request_->texture_mailbox().mailbox(),
270 last_copy_request_->texture_mailbox().sync_point());
271 gl_helper->ResizeTexture(texture, window()->bounds().size());
272 gl_helper->DeleteTexture(texture);
276 cc::DelegatedFrameProvider* frame_provider() const {
277 return GetDelegatedFrameHost()->FrameProviderForTesting();
280 cc::SurfaceId surface_id() const {
281 return GetDelegatedFrameHost()->SurfaceIdForTesting();
284 bool HasFrameData() const {
285 return frame_provider() || !surface_id().is_null();
288 bool released_front_lock_active() const {
289 return GetDelegatedFrameHost()->ReleasedFrontLockActiveForTesting();
292 // A lock that doesn't actually do anything to the compositor, and does not
293 // time out.
294 class FakeResizeLock : public ResizeLock {
295 public:
296 FakeResizeLock(const gfx::Size new_size, bool defer_compositor_lock)
297 : ResizeLock(new_size, defer_compositor_lock) {}
300 void OnTouchEvent(ui::TouchEvent* event) override {
301 RenderWidgetHostViewAura::OnTouchEvent(event);
302 if (pointer_state().GetPointerCount() > 0) {
303 touch_event_.reset(
304 new blink::WebTouchEvent(ui::CreateWebTouchEventFromMotionEvent(
305 pointer_state(), event->may_cause_scrolling())));
306 } else {
307 // Never create a WebTouchEvent with 0 touch points.
308 touch_event_.reset();
312 bool has_resize_lock_;
313 gfx::Size last_frame_size_;
314 scoped_ptr<cc::CopyOutputRequest> last_copy_request_;
315 // null if there are 0 active touch points.
316 scoped_ptr<blink::WebTouchEvent> touch_event_;
317 FakeWindowEventDispatcher* dispatcher_;
320 // A layout manager that always resizes a child to the root window size.
321 class FullscreenLayoutManager : public aura::LayoutManager {
322 public:
323 explicit FullscreenLayoutManager(aura::Window* owner) : owner_(owner) {}
324 ~FullscreenLayoutManager() override {}
326 // Overridden from aura::LayoutManager:
327 void OnWindowResized() override {
328 aura::Window::Windows::const_iterator i;
329 for (i = owner_->children().begin(); i != owner_->children().end(); ++i) {
330 (*i)->SetBounds(gfx::Rect());
333 void OnWindowAddedToLayout(aura::Window* child) override {
334 child->SetBounds(gfx::Rect());
336 void OnWillRemoveWindowFromLayout(aura::Window* child) override {}
337 void OnWindowRemovedFromLayout(aura::Window* child) override {}
338 void OnChildWindowVisibilityChanged(aura::Window* child,
339 bool visible) override {}
340 void SetChildBounds(aura::Window* child,
341 const gfx::Rect& requested_bounds) override {
342 SetChildBoundsDirect(child, gfx::Rect(owner_->bounds().size()));
345 private:
346 aura::Window* owner_;
347 DISALLOW_COPY_AND_ASSIGN(FullscreenLayoutManager);
350 class MockWindowObserver : public aura::WindowObserver {
351 public:
352 MOCK_METHOD2(OnDelegatedFrameDamage, void(aura::Window*, const gfx::Rect&));
355 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
356 PickleIterator iter(message);
357 const char* data;
358 int data_length;
359 if (!iter.ReadData(&data, &data_length))
360 return NULL;
361 return reinterpret_cast<const WebInputEvent*>(data);
364 } // namespace
366 class RenderWidgetHostViewAuraTest : public testing::Test {
367 public:
368 RenderWidgetHostViewAuraTest()
369 : widget_host_uses_shutdown_to_destroy_(false),
370 is_guest_view_hack_(false),
371 browser_thread_for_ui_(BrowserThread::UI, &message_loop_) {}
373 void SetUpEnvironment() {
374 ImageTransportFactory::InitializeForUnitTests(
375 scoped_ptr<ImageTransportFactory>(
376 new NoTransportImageTransportFactory));
377 aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_));
378 aura_test_helper_->SetUp(
379 ImageTransportFactory::GetInstance()->GetContextFactory());
380 new wm::DefaultActivationClient(aura_test_helper_->root_window());
382 browser_context_.reset(new TestBrowserContext);
383 process_host_ = new MockRenderProcessHost(browser_context_.get());
385 sink_ = &process_host_->sink();
387 parent_host_ = new RenderWidgetHostImpl(
388 &delegate_, process_host_, MSG_ROUTING_NONE, false);
389 parent_view_ = new RenderWidgetHostViewAura(parent_host_,
390 is_guest_view_hack_);
391 parent_view_->InitAsChild(NULL);
392 aura::client::ParentWindowWithContext(parent_view_->GetNativeView(),
393 aura_test_helper_->root_window(),
394 gfx::Rect());
396 widget_host_ = new RenderWidgetHostImpl(
397 &delegate_, process_host_, MSG_ROUTING_NONE, false);
398 widget_host_->Init();
399 view_ = new FakeRenderWidgetHostViewAura(widget_host_, is_guest_view_hack_);
402 void TearDownEnvironment() {
403 sink_ = NULL;
404 process_host_ = NULL;
405 if (view_)
406 view_->Destroy();
408 if (widget_host_uses_shutdown_to_destroy_)
409 widget_host_->Shutdown();
410 else
411 delete widget_host_;
413 parent_view_->Destroy();
414 delete parent_host_;
416 browser_context_.reset();
417 aura_test_helper_->TearDown();
419 message_loop_.DeleteSoon(FROM_HERE, browser_context_.release());
420 message_loop_.RunUntilIdle();
421 ImageTransportFactory::Terminate();
424 void SetUp() override { SetUpEnvironment(); }
426 void TearDown() override { TearDownEnvironment(); }
428 void set_widget_host_uses_shutdown_to_destroy(bool use) {
429 widget_host_uses_shutdown_to_destroy_ = use;
432 void SimulateMemoryPressure(
433 base::MemoryPressureListener::MemoryPressureLevel level) {
434 // Here should be base::MemoryPressureListener::NotifyMemoryPressure, but
435 // since the RendererFrameManager is installing a MemoryPressureListener
436 // which uses ObserverListThreadSafe, which furthermore remembers the
437 // message loop for the thread it was created in. Between tests, the
438 // RendererFrameManager singleton survives and and the MessageLoop gets
439 // destroyed. The correct fix would be to have ObserverListThreadSafe look
440 // up the proper message loop every time (see crbug.com/443824.)
441 RendererFrameManager::GetInstance()->OnMemoryPressure(level);
444 void SendInputEventACK(WebInputEvent::Type type,
445 InputEventAckState ack_result) {
446 InputHostMsg_HandleInputEvent_ACK_Params ack;
447 ack.type = type;
448 ack.state = ack_result;
449 InputHostMsg_HandleInputEvent_ACK response(0, ack);
450 widget_host_->OnMessageReceived(response);
453 size_t GetSentMessageCountAndResetSink() {
454 size_t count = sink_->message_count();
455 sink_->ClearMessages();
456 return count;
459 void AckLastSentInputEventIfNecessary(InputEventAckState ack_result) {
460 if (!sink_->message_count())
461 return;
463 InputMsg_HandleInputEvent::Param params;
464 if (!InputMsg_HandleInputEvent::Read(
465 sink_->GetMessageAt(sink_->message_count() - 1), &params)) {
466 return;
469 if (WebInputEventTraits::IgnoresAckDisposition(*get<0>(params)))
470 return;
472 SendInputEventACK(get<0>(params)->type, ack_result);
475 protected:
476 // If true, then calls RWH::Shutdown() instead of deleting RWH.
477 bool widget_host_uses_shutdown_to_destroy_;
479 bool is_guest_view_hack_;
481 base::MessageLoopForUI message_loop_;
482 BrowserThreadImpl browser_thread_for_ui_;
483 scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_;
484 scoped_ptr<BrowserContext> browser_context_;
485 MockRenderWidgetHostDelegate delegate_;
486 MockRenderProcessHost* process_host_;
488 // Tests should set these to NULL if they've already triggered their
489 // destruction.
490 RenderWidgetHostImpl* parent_host_;
491 RenderWidgetHostViewAura* parent_view_;
493 // Tests should set these to NULL if they've already triggered their
494 // destruction.
495 RenderWidgetHostImpl* widget_host_;
496 FakeRenderWidgetHostViewAura* view_;
498 IPC::TestSink* sink_;
500 private:
501 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraTest);
504 // Helper class to instantiate RenderWidgetHostViewGuest which is backed
505 // by an aura platform view.
506 class RenderWidgetHostViewGuestAuraTest : public RenderWidgetHostViewAuraTest {
507 public:
508 RenderWidgetHostViewGuestAuraTest() {
509 // Use RWH::Shutdown to destroy RWH, instead of deleting.
510 // This will ensure that the RenderWidgetHostViewGuest is not leaked and
511 // is deleted properly upon RWH going away.
512 set_widget_host_uses_shutdown_to_destroy(true);
515 // We explicitly invoke SetUp to allow gesture debounce customization.
516 void SetUp() override {
517 is_guest_view_hack_ = true;
519 RenderWidgetHostViewAuraTest::SetUp();
521 guest_view_weak_ = (new RenderWidgetHostViewGuest(
522 widget_host_, NULL, view_->GetWeakPtr()))->GetWeakPtr();
525 void TearDown() override {
526 // Internal override to do nothing, we clean up ourselves in the test body.
527 // This helps us test that |guest_view_weak_| does not leak.
530 protected:
531 base::WeakPtr<RenderWidgetHostViewBase> guest_view_weak_;
533 private:
535 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewGuestAuraTest);
538 class RenderWidgetHostViewAuraOverscrollTest
539 : public RenderWidgetHostViewAuraTest {
540 public:
541 RenderWidgetHostViewAuraOverscrollTest() {}
543 // We explicitly invoke SetUp to allow gesture debounce customization.
544 void SetUp() override {}
546 protected:
547 void SetUpOverscrollEnvironmentWithDebounce(int debounce_interval_in_ms) {
548 SetUpOverscrollEnvironmentImpl(debounce_interval_in_ms);
551 void SetUpOverscrollEnvironment() { SetUpOverscrollEnvironmentImpl(0); }
553 void SetUpOverscrollEnvironmentImpl(int debounce_interval_in_ms) {
554 ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
555 debounce_interval_in_ms);
557 RenderWidgetHostViewAuraTest::SetUp();
559 view_->SetOverscrollControllerEnabled(true);
560 overscroll_delegate_.reset(new TestOverscrollDelegate(view_));
561 view_->overscroll_controller()->set_delegate(overscroll_delegate_.get());
563 view_->InitAsChild(NULL);
564 view_->SetBounds(gfx::Rect(0, 0, 400, 200));
565 view_->Show();
567 sink_->ClearMessages();
570 // TODO(jdduke): Simulate ui::Events, injecting through the view.
571 void SimulateMouseEvent(WebInputEvent::Type type) {
572 widget_host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
575 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
576 const ui::LatencyInfo& ui_latency) {
577 widget_host_->ForwardMouseEventWithLatencyInfo(
578 SyntheticWebMouseEventBuilder::Build(type), ui_latency);
581 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
582 widget_host_->ForwardWheelEvent(
583 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
586 void SimulateWheelEventWithLatencyInfo(float dX,
587 float dY,
588 int modifiers,
589 bool precise,
590 const ui::LatencyInfo& ui_latency) {
591 widget_host_->ForwardWheelEventWithLatencyInfo(
592 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
593 ui_latency);
596 void SimulateMouseMove(int x, int y, int modifiers) {
597 SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
600 void SimulateMouseEvent(WebInputEvent::Type type,
601 int x,
602 int y,
603 int modifiers,
604 bool pressed) {
605 WebMouseEvent event =
606 SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
607 if (pressed)
608 event.button = WebMouseEvent::ButtonLeft;
609 widget_host_->ForwardMouseEvent(event);
612 void SimulateWheelEventWithPhase(WebMouseWheelEvent::Phase phase) {
613 widget_host_->ForwardWheelEvent(
614 SyntheticWebMouseWheelEventBuilder::Build(phase));
617 // Inject provided synthetic WebGestureEvent instance.
618 void SimulateGestureEventCore(const WebGestureEvent& gesture_event) {
619 widget_host_->ForwardGestureEvent(gesture_event);
622 void SimulateGestureEventCoreWithLatencyInfo(
623 const WebGestureEvent& gesture_event,
624 const ui::LatencyInfo& ui_latency) {
625 widget_host_->ForwardGestureEventWithLatencyInfo(gesture_event, ui_latency);
628 // Inject simple synthetic WebGestureEvent instances.
629 void SimulateGestureEvent(WebInputEvent::Type type,
630 blink::WebGestureDevice sourceDevice) {
631 SimulateGestureEventCore(
632 SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
635 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type,
636 blink::WebGestureDevice sourceDevice,
637 const ui::LatencyInfo& ui_latency) {
638 SimulateGestureEventCoreWithLatencyInfo(
639 SyntheticWebGestureEventBuilder::Build(type, sourceDevice), ui_latency);
642 void SimulateGestureScrollUpdateEvent(float dX, float dY, int modifiers) {
643 SimulateGestureEventCore(SyntheticWebGestureEventBuilder::BuildScrollUpdate(
644 dX, dY, modifiers, blink::WebGestureDeviceTouchscreen));
647 void SimulateGesturePinchUpdateEvent(float scale,
648 float anchorX,
649 float anchorY,
650 int modifiers) {
651 SimulateGestureEventCore(SyntheticWebGestureEventBuilder::BuildPinchUpdate(
652 scale,
653 anchorX,
654 anchorY,
655 modifiers,
656 blink::WebGestureDeviceTouchscreen));
659 // Inject synthetic GestureFlingStart events.
660 void SimulateGestureFlingStartEvent(float velocityX,
661 float velocityY,
662 blink::WebGestureDevice sourceDevice) {
663 SimulateGestureEventCore(SyntheticWebGestureEventBuilder::BuildFling(
664 velocityX, velocityY, sourceDevice));
667 bool ScrollStateIsContentScrolling() const {
668 return scroll_state() == OverscrollController::STATE_CONTENT_SCROLLING;
671 bool ScrollStateIsOverscrolling() const {
672 return scroll_state() == OverscrollController::STATE_OVERSCROLLING;
675 bool ScrollStateIsUnknown() const {
676 return scroll_state() == OverscrollController::STATE_UNKNOWN;
679 OverscrollController::ScrollState scroll_state() const {
680 return view_->overscroll_controller()->scroll_state_;
683 OverscrollMode overscroll_mode() const {
684 return view_->overscroll_controller()->overscroll_mode_;
687 float overscroll_delta_x() const {
688 return view_->overscroll_controller()->overscroll_delta_x_;
691 float overscroll_delta_y() const {
692 return view_->overscroll_controller()->overscroll_delta_y_;
695 TestOverscrollDelegate* overscroll_delegate() {
696 return overscroll_delegate_.get();
699 void SendTouchEvent() {
700 widget_host_->ForwardTouchEventWithLatencyInfo(touch_event_,
701 ui::LatencyInfo());
702 touch_event_.ResetPoints();
705 void PressTouchPoint(int x, int y) {
706 touch_event_.PressPoint(x, y);
707 SendTouchEvent();
710 void MoveTouchPoint(int index, int x, int y) {
711 touch_event_.MovePoint(index, x, y);
712 SendTouchEvent();
715 void ReleaseTouchPoint(int index) {
716 touch_event_.ReleasePoint(index);
717 SendTouchEvent();
720 SyntheticWebTouchEvent touch_event_;
722 scoped_ptr<TestOverscrollDelegate> overscroll_delegate_;
724 private:
725 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraOverscrollTest);
728 class RenderWidgetHostViewAuraShutdownTest
729 : public RenderWidgetHostViewAuraTest {
730 public:
731 RenderWidgetHostViewAuraShutdownTest() {}
733 void TearDown() override {
734 // No TearDownEnvironment here, we do this explicitly during the test.
737 private:
738 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraShutdownTest);
741 // Checks that a fullscreen view has the correct show-state and receives the
742 // focus.
743 TEST_F(RenderWidgetHostViewAuraTest, FocusFullscreen) {
744 view_->InitAsFullscreen(parent_view_);
745 aura::Window* window = view_->GetNativeView();
746 ASSERT_TRUE(window != NULL);
747 EXPECT_EQ(ui::SHOW_STATE_FULLSCREEN,
748 window->GetProperty(aura::client::kShowStateKey));
750 // Check that we requested and received the focus.
751 EXPECT_TRUE(window->HasFocus());
753 // Check that we'll also say it's okay to activate the window when there's an
754 // ActivationClient defined.
755 EXPECT_TRUE(view_->ShouldActivate());
758 // Checks that a popup is positioned correctly relative to its parent using
759 // screen coordinates.
760 TEST_F(RenderWidgetHostViewAuraTest, PositionChildPopup) {
761 wm::DefaultScreenPositionClient screen_position_client;
763 aura::Window* window = parent_view_->GetNativeView();
764 aura::Window* root = window->GetRootWindow();
765 aura::client::SetScreenPositionClient(root, &screen_position_client);
767 parent_view_->SetBounds(gfx::Rect(10, 10, 800, 600));
768 gfx::Rect bounds_in_screen = parent_view_->GetViewBounds();
769 int horiz = bounds_in_screen.width() / 4;
770 int vert = bounds_in_screen.height() / 4;
771 bounds_in_screen.Inset(horiz, vert);
773 // Verify that when the popup is initialized for the first time, it correctly
774 // treats the input bounds as screen coordinates.
775 view_->InitAsPopup(parent_view_, bounds_in_screen);
777 gfx::Rect final_bounds_in_screen = view_->GetViewBounds();
778 EXPECT_EQ(final_bounds_in_screen.ToString(), bounds_in_screen.ToString());
780 // Verify that directly setting the bounds via SetBounds() treats the input
781 // as screen coordinates.
782 bounds_in_screen = gfx::Rect(60, 60, 100, 100);
783 view_->SetBounds(bounds_in_screen);
784 final_bounds_in_screen = view_->GetViewBounds();
785 EXPECT_EQ(final_bounds_in_screen.ToString(), bounds_in_screen.ToString());
787 // Verify that setting the size does not alter the origin.
788 gfx::Point original_origin = window->bounds().origin();
789 view_->SetSize(gfx::Size(120, 120));
790 gfx::Point new_origin = window->bounds().origin();
791 EXPECT_EQ(original_origin.ToString(), new_origin.ToString());
793 aura::client::SetScreenPositionClient(root, NULL);
796 // Checks that a fullscreen view is destroyed when it loses the focus.
797 TEST_F(RenderWidgetHostViewAuraTest, DestroyFullscreenOnBlur) {
798 view_->InitAsFullscreen(parent_view_);
799 aura::Window* window = view_->GetNativeView();
800 ASSERT_TRUE(window != NULL);
801 ASSERT_TRUE(window->HasFocus());
803 // After we create and focus another window, the RWHVA's window should be
804 // destroyed.
805 TestWindowObserver observer(window);
806 aura::test::TestWindowDelegate delegate;
807 scoped_ptr<aura::Window> sibling(new aura::Window(&delegate));
808 sibling->Init(ui::LAYER_TEXTURED);
809 sibling->Show();
810 window->parent()->AddChild(sibling.get());
811 sibling->Focus();
812 ASSERT_TRUE(sibling->HasFocus());
813 ASSERT_TRUE(observer.destroyed());
815 widget_host_ = NULL;
816 view_ = NULL;
819 // Checks that a popup view is destroyed when a user clicks outside of the popup
820 // view and focus does not change. This is the case when the user clicks on the
821 // desktop background on Chrome OS.
822 TEST_F(RenderWidgetHostViewAuraTest, DestroyPopupClickOutsidePopup) {
823 parent_view_->SetBounds(gfx::Rect(10, 10, 400, 400));
824 parent_view_->Focus();
825 EXPECT_TRUE(parent_view_->HasFocus());
827 view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
828 aura::Window* window = view_->GetNativeView();
829 ASSERT_TRUE(window != NULL);
831 gfx::Point click_point;
832 EXPECT_FALSE(window->GetBoundsInRootWindow().Contains(click_point));
833 aura::Window* parent_window = parent_view_->GetNativeView();
834 EXPECT_FALSE(parent_window->GetBoundsInRootWindow().Contains(click_point));
836 TestWindowObserver observer(window);
837 ui::test::EventGenerator generator(window->GetRootWindow(), click_point);
838 generator.ClickLeftButton();
839 ASSERT_TRUE(parent_view_->HasFocus());
840 ASSERT_TRUE(observer.destroyed());
842 widget_host_ = NULL;
843 view_ = NULL;
846 // Checks that a popup view is destroyed when a user taps outside of the popup
847 // view and focus does not change. This is the case when the user taps the
848 // desktop background on Chrome OS.
849 TEST_F(RenderWidgetHostViewAuraTest, DestroyPopupTapOutsidePopup) {
850 parent_view_->SetBounds(gfx::Rect(10, 10, 400, 400));
851 parent_view_->Focus();
852 EXPECT_TRUE(parent_view_->HasFocus());
854 view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
855 aura::Window* window = view_->GetNativeView();
856 ASSERT_TRUE(window != NULL);
858 gfx::Point tap_point;
859 EXPECT_FALSE(window->GetBoundsInRootWindow().Contains(tap_point));
860 aura::Window* parent_window = parent_view_->GetNativeView();
861 EXPECT_FALSE(parent_window->GetBoundsInRootWindow().Contains(tap_point));
863 TestWindowObserver observer(window);
864 ui::test::EventGenerator generator(window->GetRootWindow(), tap_point);
865 generator.GestureTapAt(tap_point);
866 ASSERT_TRUE(parent_view_->HasFocus());
867 ASSERT_TRUE(observer.destroyed());
869 widget_host_ = NULL;
870 view_ = NULL;
873 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
875 // On Desktop Linux, select boxes need mouse capture in order to work. Test that
876 // when a select box is opened via a mouse press that it retains mouse capture
877 // after the mouse is released.
878 TEST_F(RenderWidgetHostViewAuraTest, PopupRetainsCaptureAfterMouseRelease) {
879 parent_view_->SetBounds(gfx::Rect(10, 10, 400, 400));
880 parent_view_->Focus();
881 EXPECT_TRUE(parent_view_->HasFocus());
883 ui::test::EventGenerator generator(
884 parent_view_->GetNativeView()->GetRootWindow(), gfx::Point(300, 300));
885 generator.PressLeftButton();
887 view_->SetPopupType(blink::WebPopupTypeSelect);
888 view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
889 ASSERT_TRUE(view_->NeedsMouseCapture());
890 aura::Window* window = view_->GetNativeView();
891 EXPECT_TRUE(window->HasCapture());
893 generator.ReleaseLeftButton();
894 EXPECT_TRUE(window->HasCapture());
896 #endif
898 // Test that select boxes close when their parent window loses focus (e.g. due
899 // to an alert or system modal dialog).
900 TEST_F(RenderWidgetHostViewAuraTest, PopupClosesWhenParentLosesFocus) {
901 parent_view_->SetBounds(gfx::Rect(10, 10, 400, 400));
902 parent_view_->Focus();
903 EXPECT_TRUE(parent_view_->HasFocus());
905 view_->SetPopupType(blink::WebPopupTypeSelect);
906 view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
908 aura::Window* popup_window = view_->GetNativeView();
909 TestWindowObserver observer(popup_window);
911 aura::test::TestWindowDelegate delegate;
912 scoped_ptr<aura::Window> dialog_window(new aura::Window(&delegate));
913 dialog_window->Init(ui::LAYER_TEXTURED);
914 aura::client::ParentWindowWithContext(
915 dialog_window.get(), popup_window, gfx::Rect());
916 dialog_window->Show();
917 wm::ActivateWindow(dialog_window.get());
918 dialog_window->Focus();
920 ASSERT_TRUE(wm::IsActiveWindow(dialog_window.get()));
921 EXPECT_TRUE(observer.destroyed());
923 widget_host_ = NULL;
924 view_ = NULL;
927 // Checks that IME-composition-event state is maintained correctly.
928 TEST_F(RenderWidgetHostViewAuraTest, SetCompositionText) {
929 view_->InitAsChild(NULL);
930 view_->Show();
932 ui::CompositionText composition_text;
933 composition_text.text = base::ASCIIToUTF16("|a|b");
935 // Focused segment
936 composition_text.underlines.push_back(
937 ui::CompositionUnderline(0, 3, 0xff000000, true, 0x78563412));
939 // Non-focused segment, with different background color.
940 composition_text.underlines.push_back(
941 ui::CompositionUnderline(3, 4, 0xff000000, false, 0xefcdab90));
943 const ui::CompositionUnderlines& underlines = composition_text.underlines;
945 // Caret is at the end. (This emulates Japanese MSIME 2007 and later)
946 composition_text.selection = gfx::Range(4);
948 sink_->ClearMessages();
949 view_->SetCompositionText(composition_text);
950 EXPECT_TRUE(view_->has_composition_text_);
952 const IPC::Message* msg =
953 sink_->GetFirstMessageMatching(InputMsg_ImeSetComposition::ID);
954 ASSERT_TRUE(msg != NULL);
956 InputMsg_ImeSetComposition::Param params;
957 InputMsg_ImeSetComposition::Read(msg, &params);
958 // composition text
959 EXPECT_EQ(composition_text.text, get<0>(params));
960 // underlines
961 ASSERT_EQ(underlines.size(), get<1>(params).size());
962 for (size_t i = 0; i < underlines.size(); ++i) {
963 EXPECT_EQ(underlines[i].start_offset, get<1>(params)[i].startOffset);
964 EXPECT_EQ(underlines[i].end_offset, get<1>(params)[i].endOffset);
965 EXPECT_EQ(underlines[i].color, get<1>(params)[i].color);
966 EXPECT_EQ(underlines[i].thick, get<1>(params)[i].thick);
967 EXPECT_EQ(underlines[i].background_color,
968 get<1>(params)[i].backgroundColor);
970 // highlighted range
971 EXPECT_EQ(4, get<2>(params)) << "Should be the same to the caret pos";
972 EXPECT_EQ(4, get<3>(params)) << "Should be the same to the caret pos";
975 view_->ImeCancelComposition();
976 EXPECT_FALSE(view_->has_composition_text_);
979 // Checks that sequence of IME-composition-event and mouse-event when mouse
980 // clicking to cancel the composition.
981 TEST_F(RenderWidgetHostViewAuraTest, FinishCompositionByMouse) {
982 view_->InitAsChild(NULL);
983 view_->Show();
985 ui::CompositionText composition_text;
986 composition_text.text = base::ASCIIToUTF16("|a|b");
988 // Focused segment
989 composition_text.underlines.push_back(
990 ui::CompositionUnderline(0, 3, 0xff000000, true, 0x78563412));
992 // Non-focused segment, with different background color.
993 composition_text.underlines.push_back(
994 ui::CompositionUnderline(3, 4, 0xff000000, false, 0xefcdab90));
996 // Caret is at the end. (This emulates Japanese MSIME 2007 and later)
997 composition_text.selection = gfx::Range(4);
999 view_->SetCompositionText(composition_text);
1000 EXPECT_TRUE(view_->has_composition_text_);
1001 sink_->ClearMessages();
1003 // Simulates the mouse press.
1004 ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
1005 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
1007 view_->OnMouseEvent(&mouse_event);
1009 EXPECT_FALSE(view_->has_composition_text_);
1011 EXPECT_EQ(2U, sink_->message_count());
1013 if (sink_->message_count() == 2) {
1014 // Verify mouse event happens after the confirm-composition event.
1015 EXPECT_EQ(InputMsg_ImeConfirmComposition::ID,
1016 sink_->GetMessageAt(0)->type());
1017 EXPECT_EQ(InputMsg_HandleInputEvent::ID,
1018 sink_->GetMessageAt(1)->type());
1022 // Checks that touch-event state is maintained correctly.
1023 TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
1024 view_->InitAsChild(NULL);
1025 view_->Show();
1026 GetSentMessageCountAndResetSink();
1028 // Start with no touch-event handler in the renderer.
1029 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1031 ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
1032 gfx::Point(30, 30),
1034 ui::EventTimeForNow());
1035 ui::TouchEvent move(ui::ET_TOUCH_MOVED,
1036 gfx::Point(20, 20),
1038 ui::EventTimeForNow());
1039 ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
1040 gfx::Point(20, 20),
1042 ui::EventTimeForNow());
1044 // The touch events should get forwared from the view, but they should not
1045 // reach the renderer.
1046 view_->OnTouchEvent(&press);
1047 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
1048 EXPECT_TRUE(press.synchronous_handling_disabled());
1049 EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_->type);
1050 EXPECT_TRUE(view_->touch_event_->cancelable);
1051 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
1052 EXPECT_EQ(blink::WebTouchPoint::StatePressed,
1053 view_->touch_event_->touches[0].state);
1055 view_->OnTouchEvent(&move);
1056 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
1057 EXPECT_TRUE(press.synchronous_handling_disabled());
1058 EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
1059 EXPECT_TRUE(view_->touch_event_->cancelable);
1060 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
1061 EXPECT_EQ(blink::WebTouchPoint::StateMoved,
1062 view_->touch_event_->touches[0].state);
1064 view_->OnTouchEvent(&release);
1065 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
1066 EXPECT_TRUE(press.synchronous_handling_disabled());
1067 EXPECT_EQ(nullptr, view_->touch_event_);
1069 // Now install some touch-event handlers and do the same steps. The touch
1070 // events should now be consumed. However, the touch-event state should be
1071 // updated as before.
1072 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1074 view_->OnTouchEvent(&press);
1075 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
1076 EXPECT_TRUE(press.synchronous_handling_disabled());
1077 EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_->type);
1078 EXPECT_TRUE(view_->touch_event_->cancelable);
1079 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
1080 EXPECT_EQ(blink::WebTouchPoint::StatePressed,
1081 view_->touch_event_->touches[0].state);
1083 view_->OnTouchEvent(&move);
1084 EXPECT_TRUE(move.synchronous_handling_disabled());
1085 EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
1086 EXPECT_TRUE(view_->touch_event_->cancelable);
1087 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
1088 EXPECT_EQ(blink::WebTouchPoint::StateMoved,
1089 view_->touch_event_->touches[0].state);
1090 view_->OnTouchEvent(&release);
1091 EXPECT_TRUE(release.synchronous_handling_disabled());
1092 EXPECT_EQ(nullptr, view_->touch_event_);
1094 // Now start a touch event, and remove the event-handlers before the release.
1095 view_->OnTouchEvent(&press);
1096 EXPECT_TRUE(press.synchronous_handling_disabled());
1097 EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_->type);
1098 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
1099 EXPECT_EQ(blink::WebTouchPoint::StatePressed,
1100 view_->touch_event_->touches[0].state);
1102 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1104 // Ack'ing the outstanding event should flush the pending touch queue.
1105 InputHostMsg_HandleInputEvent_ACK_Params ack;
1106 ack.type = blink::WebInputEvent::TouchStart;
1107 ack.state = INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
1108 widget_host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
1109 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
1111 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 0,
1112 base::Time::NowFromSystemTime() - base::Time());
1113 view_->OnTouchEvent(&move2);
1114 EXPECT_TRUE(press.synchronous_handling_disabled());
1115 EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
1116 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
1117 EXPECT_EQ(blink::WebTouchPoint::StateMoved,
1118 view_->touch_event_->touches[0].state);
1120 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 0,
1121 base::Time::NowFromSystemTime() - base::Time());
1122 view_->OnTouchEvent(&release2);
1123 EXPECT_TRUE(press.synchronous_handling_disabled());
1124 EXPECT_EQ(nullptr, view_->touch_event_);
1127 // Checks that touch-events are queued properly when there is a touch-event
1128 // handler on the page.
1129 TEST_F(RenderWidgetHostViewAuraTest, TouchEventSyncAsync) {
1130 view_->InitAsChild(NULL);
1131 view_->Show();
1133 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1135 ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
1136 gfx::Point(30, 30),
1138 ui::EventTimeForNow());
1139 ui::TouchEvent move(ui::ET_TOUCH_MOVED,
1140 gfx::Point(20, 20),
1142 ui::EventTimeForNow());
1143 ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
1144 gfx::Point(20, 20),
1146 ui::EventTimeForNow());
1148 view_->OnTouchEvent(&press);
1149 EXPECT_TRUE(press.synchronous_handling_disabled());
1150 EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_->type);
1151 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
1152 EXPECT_EQ(blink::WebTouchPoint::StatePressed,
1153 view_->touch_event_->touches[0].state);
1155 view_->OnTouchEvent(&move);
1156 EXPECT_TRUE(move.synchronous_handling_disabled());
1157 EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
1158 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
1159 EXPECT_EQ(blink::WebTouchPoint::StateMoved,
1160 view_->touch_event_->touches[0].state);
1162 // Send the same move event. Since the point hasn't moved, it won't affect the
1163 // queue. However, the view should consume the event.
1164 view_->OnTouchEvent(&move);
1165 EXPECT_TRUE(move.synchronous_handling_disabled());
1166 EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
1167 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
1168 EXPECT_EQ(blink::WebTouchPoint::StateMoved,
1169 view_->touch_event_->touches[0].state);
1171 view_->OnTouchEvent(&release);
1172 EXPECT_TRUE(release.synchronous_handling_disabled());
1173 EXPECT_EQ(nullptr, view_->touch_event_);
1176 TEST_F(RenderWidgetHostViewAuraTest, PhysicalBackingSizeWithScale) {
1177 view_->InitAsChild(NULL);
1178 aura::client::ParentWindowWithContext(
1179 view_->GetNativeView(),
1180 parent_view_->GetNativeView()->GetRootWindow(),
1181 gfx::Rect());
1182 sink_->ClearMessages();
1183 view_->SetSize(gfx::Size(100, 100));
1184 EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString());
1185 EXPECT_EQ(1u, sink_->message_count());
1186 EXPECT_EQ(ViewMsg_Resize::ID, sink_->GetMessageAt(0)->type());
1188 const IPC::Message* msg = sink_->GetMessageAt(0);
1189 EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
1190 ViewMsg_Resize::Param params;
1191 ViewMsg_Resize::Read(msg, &params);
1192 EXPECT_EQ("100x100", get<0>(params).new_size.ToString()); // dip size
1193 EXPECT_EQ("100x100",
1194 get<0>(params).physical_backing_size.ToString()); // backing size
1197 widget_host_->ResetSizeAndRepaintPendingFlags();
1198 sink_->ClearMessages();
1200 aura_test_helper_->test_screen()->SetDeviceScaleFactor(2.0f);
1201 EXPECT_EQ("200x200", view_->GetPhysicalBackingSize().ToString());
1202 // Extra ScreenInfoChanged message for |parent_view_|.
1203 EXPECT_EQ(1u, sink_->message_count());
1205 const IPC::Message* msg = sink_->GetMessageAt(0);
1206 EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
1207 ViewMsg_Resize::Param params;
1208 ViewMsg_Resize::Read(msg, &params);
1209 EXPECT_EQ(2.0f, get<0>(params).screen_info.deviceScaleFactor);
1210 EXPECT_EQ("100x100", get<0>(params).new_size.ToString()); // dip size
1211 EXPECT_EQ("200x200",
1212 get<0>(params).physical_backing_size.ToString()); // backing size
1215 widget_host_->ResetSizeAndRepaintPendingFlags();
1216 sink_->ClearMessages();
1218 aura_test_helper_->test_screen()->SetDeviceScaleFactor(1.0f);
1219 // Extra ScreenInfoChanged message for |parent_view_|.
1220 EXPECT_EQ(1u, sink_->message_count());
1221 EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString());
1223 const IPC::Message* msg = sink_->GetMessageAt(0);
1224 EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
1225 ViewMsg_Resize::Param params;
1226 ViewMsg_Resize::Read(msg, &params);
1227 EXPECT_EQ(1.0f, get<0>(params).screen_info.deviceScaleFactor);
1228 EXPECT_EQ("100x100", get<0>(params).new_size.ToString()); // dip size
1229 EXPECT_EQ("100x100",
1230 get<0>(params).physical_backing_size.ToString()); // backing size
1234 // Checks that InputMsg_CursorVisibilityChange IPC messages are dispatched
1235 // to the renderer at the correct times.
1236 TEST_F(RenderWidgetHostViewAuraTest, CursorVisibilityChange) {
1237 view_->InitAsChild(NULL);
1238 aura::client::ParentWindowWithContext(
1239 view_->GetNativeView(),
1240 parent_view_->GetNativeView()->GetRootWindow(),
1241 gfx::Rect());
1242 view_->SetSize(gfx::Size(100, 100));
1244 aura::test::TestCursorClient cursor_client(
1245 parent_view_->GetNativeView()->GetRootWindow());
1247 cursor_client.AddObserver(view_);
1249 // Expect a message the first time the cursor is shown.
1250 view_->Show();
1251 sink_->ClearMessages();
1252 cursor_client.ShowCursor();
1253 EXPECT_EQ(1u, sink_->message_count());
1254 EXPECT_TRUE(sink_->GetUniqueMessageMatching(
1255 InputMsg_CursorVisibilityChange::ID));
1257 // No message expected if the renderer already knows the cursor is visible.
1258 sink_->ClearMessages();
1259 cursor_client.ShowCursor();
1260 EXPECT_EQ(0u, sink_->message_count());
1262 // Hiding the cursor should send a message.
1263 sink_->ClearMessages();
1264 cursor_client.HideCursor();
1265 EXPECT_EQ(1u, sink_->message_count());
1266 EXPECT_TRUE(sink_->GetUniqueMessageMatching(
1267 InputMsg_CursorVisibilityChange::ID));
1269 // No message expected if the renderer already knows the cursor is invisible.
1270 sink_->ClearMessages();
1271 cursor_client.HideCursor();
1272 EXPECT_EQ(0u, sink_->message_count());
1274 // No messages should be sent while the view is invisible.
1275 view_->Hide();
1276 sink_->ClearMessages();
1277 cursor_client.ShowCursor();
1278 EXPECT_EQ(0u, sink_->message_count());
1279 cursor_client.HideCursor();
1280 EXPECT_EQ(0u, sink_->message_count());
1282 // Show the view. Since the cursor was invisible when the view was hidden,
1283 // no message should be sent.
1284 sink_->ClearMessages();
1285 view_->Show();
1286 EXPECT_FALSE(sink_->GetUniqueMessageMatching(
1287 InputMsg_CursorVisibilityChange::ID));
1289 // No message expected if the renderer already knows the cursor is invisible.
1290 sink_->ClearMessages();
1291 cursor_client.HideCursor();
1292 EXPECT_EQ(0u, sink_->message_count());
1294 // Showing the cursor should send a message.
1295 sink_->ClearMessages();
1296 cursor_client.ShowCursor();
1297 EXPECT_EQ(1u, sink_->message_count());
1298 EXPECT_TRUE(sink_->GetUniqueMessageMatching(
1299 InputMsg_CursorVisibilityChange::ID));
1301 // No messages should be sent while the view is invisible.
1302 view_->Hide();
1303 sink_->ClearMessages();
1304 cursor_client.HideCursor();
1305 EXPECT_EQ(0u, sink_->message_count());
1307 // Show the view. Since the cursor was visible when the view was hidden,
1308 // a message is expected to be sent.
1309 sink_->ClearMessages();
1310 view_->Show();
1311 EXPECT_TRUE(sink_->GetUniqueMessageMatching(
1312 InputMsg_CursorVisibilityChange::ID));
1314 cursor_client.RemoveObserver(view_);
1317 TEST_F(RenderWidgetHostViewAuraTest, UpdateCursorIfOverSelf) {
1318 view_->InitAsChild(NULL);
1319 aura::client::ParentWindowWithContext(
1320 view_->GetNativeView(),
1321 parent_view_->GetNativeView()->GetRootWindow(),
1322 gfx::Rect());
1324 // Note that all coordinates in this test are screen coordinates.
1325 view_->SetBounds(gfx::Rect(60, 60, 100, 100));
1326 view_->Show();
1328 aura::test::TestCursorClient cursor_client(
1329 parent_view_->GetNativeView()->GetRootWindow());
1331 // Cursor is in the middle of the window.
1332 cursor_client.reset_calls_to_set_cursor();
1333 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(110, 110));
1334 view_->UpdateCursorIfOverSelf();
1335 EXPECT_EQ(1, cursor_client.calls_to_set_cursor());
1337 // Cursor is near the top of the window.
1338 cursor_client.reset_calls_to_set_cursor();
1339 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(80, 65));
1340 view_->UpdateCursorIfOverSelf();
1341 EXPECT_EQ(1, cursor_client.calls_to_set_cursor());
1343 // Cursor is near the bottom of the window.
1344 cursor_client.reset_calls_to_set_cursor();
1345 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(159, 159));
1346 view_->UpdateCursorIfOverSelf();
1347 EXPECT_EQ(1, cursor_client.calls_to_set_cursor());
1349 // Cursor is above the window.
1350 cursor_client.reset_calls_to_set_cursor();
1351 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(67, 59));
1352 view_->UpdateCursorIfOverSelf();
1353 EXPECT_EQ(0, cursor_client.calls_to_set_cursor());
1355 // Cursor is below the window.
1356 cursor_client.reset_calls_to_set_cursor();
1357 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(161, 161));
1358 view_->UpdateCursorIfOverSelf();
1359 EXPECT_EQ(0, cursor_client.calls_to_set_cursor());
1362 scoped_ptr<cc::CompositorFrame> MakeDelegatedFrame(float scale_factor,
1363 gfx::Size size,
1364 gfx::Rect damage) {
1365 scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
1366 frame->metadata.device_scale_factor = scale_factor;
1367 frame->delegated_frame_data.reset(new cc::DelegatedFrameData);
1369 scoped_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
1370 pass->SetNew(
1371 cc::RenderPassId(1, 1), gfx::Rect(size), damage, gfx::Transform());
1372 frame->delegated_frame_data->render_pass_list.push_back(pass.Pass());
1373 return frame.Pass();
1376 // Resizing in fullscreen mode should send the up-to-date screen info.
1377 // http://crbug.com/324350
1378 TEST_F(RenderWidgetHostViewAuraTest, DISABLED_FullscreenResize) {
1379 aura::Window* root_window = aura_test_helper_->root_window();
1380 root_window->SetLayoutManager(new FullscreenLayoutManager(root_window));
1381 view_->InitAsFullscreen(parent_view_);
1382 view_->Show();
1383 widget_host_->ResetSizeAndRepaintPendingFlags();
1384 sink_->ClearMessages();
1386 // Call WasResized to flush the old screen info.
1387 view_->GetRenderWidgetHost()->WasResized();
1389 // 0 is CreatingNew message.
1390 const IPC::Message* msg = sink_->GetMessageAt(0);
1391 EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
1392 ViewMsg_Resize::Param params;
1393 ViewMsg_Resize::Read(msg, &params);
1394 EXPECT_EQ("0,0 800x600",
1395 gfx::Rect(get<0>(params).screen_info.availableRect).ToString());
1396 EXPECT_EQ("800x600", get<0>(params).new_size.ToString());
1397 // Resizes are blocked until we swapped a frame of the correct size, and
1398 // we've committed it.
1399 view_->OnSwapCompositorFrame(
1401 MakeDelegatedFrame(
1402 1.f, get<0>(params).new_size, gfx::Rect(get<0>(params).new_size)));
1403 ui::DrawWaiterForTest::WaitForCommit(
1404 root_window->GetHost()->compositor());
1407 widget_host_->ResetSizeAndRepaintPendingFlags();
1408 sink_->ClearMessages();
1410 // Make sure the corrent screen size is set along in the resize
1411 // request when the screen size has changed.
1412 aura_test_helper_->test_screen()->SetUIScale(0.5);
1413 EXPECT_EQ(1u, sink_->message_count());
1415 const IPC::Message* msg = sink_->GetMessageAt(0);
1416 EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
1417 ViewMsg_Resize::Param params;
1418 ViewMsg_Resize::Read(msg, &params);
1419 EXPECT_EQ("0,0 1600x1200",
1420 gfx::Rect(get<0>(params).screen_info.availableRect).ToString());
1421 EXPECT_EQ("1600x1200", get<0>(params).new_size.ToString());
1422 view_->OnSwapCompositorFrame(
1424 MakeDelegatedFrame(
1425 1.f, get<0>(params).new_size, gfx::Rect(get<0>(params).new_size)));
1426 ui::DrawWaiterForTest::WaitForCommit(
1427 root_window->GetHost()->compositor());
1431 // Swapping a frame should notify the window.
1432 TEST_F(RenderWidgetHostViewAuraTest, SwapNotifiesWindow) {
1433 gfx::Size view_size(100, 100);
1434 gfx::Rect view_rect(view_size);
1436 view_->InitAsChild(NULL);
1437 aura::client::ParentWindowWithContext(
1438 view_->GetNativeView(),
1439 parent_view_->GetNativeView()->GetRootWindow(),
1440 gfx::Rect());
1441 view_->SetSize(view_size);
1442 view_->Show();
1444 MockWindowObserver observer;
1445 view_->window_->AddObserver(&observer);
1447 // Delegated renderer path
1448 EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
1449 view_->OnSwapCompositorFrame(
1450 0, MakeDelegatedFrame(1.f, view_size, view_rect));
1451 testing::Mock::VerifyAndClearExpectations(&observer);
1453 EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_,
1454 gfx::Rect(5, 5, 5, 5)));
1455 view_->OnSwapCompositorFrame(
1456 0, MakeDelegatedFrame(1.f, view_size, gfx::Rect(5, 5, 5, 5)));
1457 testing::Mock::VerifyAndClearExpectations(&observer);
1459 view_->window_->RemoveObserver(&observer);
1462 // Recreating the layers for a window should cause Surface destruction to
1463 // depend on both layers.
1464 TEST_F(RenderWidgetHostViewAuraTest, RecreateLayers) {
1465 gfx::Size view_size(100, 100);
1466 gfx::Rect view_rect(view_size);
1468 view_->InitAsChild(NULL);
1469 aura::client::ParentWindowWithContext(
1470 view_->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(),
1471 gfx::Rect());
1472 view_->SetSize(view_size);
1473 view_->Show();
1475 view_->OnSwapCompositorFrame(0,
1476 MakeDelegatedFrame(1.f, view_size, view_rect));
1477 scoped_ptr<ui::LayerTreeOwner> cloned_owner(
1478 wm::RecreateLayers(view_->GetNativeView()));
1480 cc::SurfaceId id = view_->GetDelegatedFrameHost()->SurfaceIdForTesting();
1481 if (!id.is_null()) {
1482 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1483 cc::SurfaceManager* manager = factory->GetSurfaceManager();
1484 cc::Surface* surface = manager->GetSurfaceForId(id);
1485 EXPECT_TRUE(surface);
1486 // Should be a SurfaceSequence for both the original and new layers.
1487 EXPECT_EQ(2u, surface->GetDestructionDependencyCount());
1491 TEST_F(RenderWidgetHostViewAuraTest, Resize) {
1492 gfx::Size size1(100, 100);
1493 gfx::Size size2(200, 200);
1494 gfx::Size size3(300, 300);
1496 aura::Window* root_window = parent_view_->GetNativeView()->GetRootWindow();
1497 view_->InitAsChild(NULL);
1498 aura::client::ParentWindowWithContext(
1499 view_->GetNativeView(), root_window, gfx::Rect(size1));
1500 view_->Show();
1501 view_->SetSize(size1);
1502 view_->OnSwapCompositorFrame(
1503 0, MakeDelegatedFrame(1.f, size1, gfx::Rect(size1)));
1504 ui::DrawWaiterForTest::WaitForCommit(
1505 root_window->GetHost()->compositor());
1506 ViewHostMsg_UpdateRect_Params update_params;
1507 update_params.view_size = size1;
1508 update_params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
1509 widget_host_->OnMessageReceived(
1510 ViewHostMsg_UpdateRect(widget_host_->GetRoutingID(), update_params));
1511 sink_->ClearMessages();
1512 // Resize logic is idle (no pending resize, no pending commit).
1513 EXPECT_EQ(size1.ToString(), view_->GetRequestedRendererSize().ToString());
1515 // Resize renderer, should produce a Resize message
1516 view_->SetSize(size2);
1517 EXPECT_EQ(size2.ToString(), view_->GetRequestedRendererSize().ToString());
1518 EXPECT_EQ(1u, sink_->message_count());
1520 const IPC::Message* msg = sink_->GetMessageAt(0);
1521 EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
1522 ViewMsg_Resize::Param params;
1523 ViewMsg_Resize::Read(msg, &params);
1524 EXPECT_EQ(size2.ToString(), get<0>(params).new_size.ToString());
1526 // Send resize ack to observe new Resize messages.
1527 update_params.view_size = size2;
1528 widget_host_->OnMessageReceived(
1529 ViewHostMsg_UpdateRect(widget_host_->GetRoutingID(), update_params));
1530 sink_->ClearMessages();
1532 // Resize renderer again, before receiving a frame. Should not produce a
1533 // Resize message.
1534 view_->SetSize(size3);
1535 EXPECT_EQ(size2.ToString(), view_->GetRequestedRendererSize().ToString());
1536 EXPECT_EQ(0u, sink_->message_count());
1538 // Receive a frame of the new size, should be skipped and not produce a Resize
1539 // message.
1540 view_->OnSwapCompositorFrame(
1541 0, MakeDelegatedFrame(1.f, size3, gfx::Rect(size3)));
1542 // Expect the frame ack;
1543 EXPECT_EQ(1u, sink_->message_count());
1544 EXPECT_EQ(ViewMsg_SwapCompositorFrameAck::ID, sink_->GetMessageAt(0)->type());
1545 sink_->ClearMessages();
1546 EXPECT_EQ(size2.ToString(), view_->GetRequestedRendererSize().ToString());
1548 // Receive a frame of the correct size, should not be skipped and, and should
1549 // produce a Resize message after the commit.
1550 view_->OnSwapCompositorFrame(
1551 0, MakeDelegatedFrame(1.f, size2, gfx::Rect(size2)));
1552 cc::SurfaceId surface_id = view_->surface_id();
1553 if (surface_id.is_null()) {
1554 // No frame ack yet.
1555 EXPECT_EQ(0u, sink_->message_count());
1556 } else {
1557 // Frame isn't desired size, so early ack.
1558 EXPECT_EQ(1u, sink_->message_count());
1560 EXPECT_EQ(size2.ToString(), view_->GetRequestedRendererSize().ToString());
1562 // Wait for commit, then we should unlock the compositor and send a Resize
1563 // message (and a frame ack)
1564 ui::DrawWaiterForTest::WaitForCommit(
1565 root_window->GetHost()->compositor());
1567 bool has_resize = false;
1568 for (uint32 i = 0; i < sink_->message_count(); ++i) {
1569 const IPC::Message* msg = sink_->GetMessageAt(i);
1570 switch (msg->type()) {
1571 case InputMsg_HandleInputEvent::ID: {
1572 // On some platforms, the call to view_->Show() causes a posted task to
1573 // call
1574 // ui::WindowEventDispatcher::SynthesizeMouseMoveAfterChangeToWindow,
1575 // which the above WaitForCommit may cause to be picked up. Be robust
1576 // to this extra IPC coming in.
1577 InputMsg_HandleInputEvent::Param params;
1578 InputMsg_HandleInputEvent::Read(msg, &params);
1579 const blink::WebInputEvent* event = get<0>(params);
1580 EXPECT_EQ(blink::WebInputEvent::MouseMove, event->type);
1581 break;
1583 case ViewMsg_SwapCompositorFrameAck::ID:
1584 break;
1585 case ViewMsg_Resize::ID: {
1586 EXPECT_FALSE(has_resize);
1587 ViewMsg_Resize::Param params;
1588 ViewMsg_Resize::Read(msg, &params);
1589 EXPECT_EQ(size3.ToString(), get<0>(params).new_size.ToString());
1590 has_resize = true;
1591 break;
1593 default:
1594 ADD_FAILURE() << "Unexpected message " << msg->type();
1595 break;
1598 EXPECT_TRUE(has_resize);
1599 update_params.view_size = size3;
1600 widget_host_->OnMessageReceived(
1601 ViewHostMsg_UpdateRect(widget_host_->GetRoutingID(), update_params));
1602 sink_->ClearMessages();
1605 // Skipped frames should not drop their damage.
1606 TEST_F(RenderWidgetHostViewAuraTest, SkippedDelegatedFrames) {
1607 gfx::Rect view_rect(100, 100);
1608 gfx::Size frame_size = view_rect.size();
1610 view_->InitAsChild(NULL);
1611 aura::client::ParentWindowWithContext(
1612 view_->GetNativeView(),
1613 parent_view_->GetNativeView()->GetRootWindow(),
1614 gfx::Rect());
1615 view_->SetSize(view_rect.size());
1617 MockWindowObserver observer;
1618 view_->window_->AddObserver(&observer);
1620 // A full frame of damage.
1621 EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
1622 view_->OnSwapCompositorFrame(
1623 0, MakeDelegatedFrame(1.f, frame_size, view_rect));
1624 testing::Mock::VerifyAndClearExpectations(&observer);
1625 view_->RunOnCompositingDidCommit();
1627 // A partial damage frame.
1628 gfx::Rect partial_view_rect(30, 30, 20, 20);
1629 EXPECT_CALL(observer,
1630 OnDelegatedFrameDamage(view_->window_, partial_view_rect));
1631 view_->OnSwapCompositorFrame(
1632 0, MakeDelegatedFrame(1.f, frame_size, partial_view_rect));
1633 testing::Mock::VerifyAndClearExpectations(&observer);
1634 view_->RunOnCompositingDidCommit();
1636 // Lock the compositor. Now we should drop frames.
1637 view_rect = gfx::Rect(150, 150);
1638 view_->SetSize(view_rect.size());
1640 // This frame is dropped.
1641 gfx::Rect dropped_damage_rect_1(10, 20, 30, 40);
1642 EXPECT_CALL(observer, OnDelegatedFrameDamage(_, _)).Times(0);
1643 view_->OnSwapCompositorFrame(
1644 0, MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_1));
1645 testing::Mock::VerifyAndClearExpectations(&observer);
1646 view_->RunOnCompositingDidCommit();
1648 gfx::Rect dropped_damage_rect_2(40, 50, 10, 20);
1649 EXPECT_CALL(observer, OnDelegatedFrameDamage(_, _)).Times(0);
1650 view_->OnSwapCompositorFrame(
1651 0, MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_2));
1652 testing::Mock::VerifyAndClearExpectations(&observer);
1653 view_->RunOnCompositingDidCommit();
1655 // Unlock the compositor. This frame should damage everything.
1656 frame_size = view_rect.size();
1658 gfx::Rect new_damage_rect(5, 6, 10, 10);
1659 EXPECT_CALL(observer,
1660 OnDelegatedFrameDamage(view_->window_, view_rect));
1661 view_->OnSwapCompositorFrame(
1662 0, MakeDelegatedFrame(1.f, frame_size, new_damage_rect));
1663 testing::Mock::VerifyAndClearExpectations(&observer);
1664 view_->RunOnCompositingDidCommit();
1666 // A partial damage frame, this should not be dropped.
1667 EXPECT_CALL(observer,
1668 OnDelegatedFrameDamage(view_->window_, partial_view_rect));
1669 view_->OnSwapCompositorFrame(
1670 0, MakeDelegatedFrame(1.f, frame_size, partial_view_rect));
1671 testing::Mock::VerifyAndClearExpectations(&observer);
1672 view_->RunOnCompositingDidCommit();
1675 // Resize to something empty.
1676 view_rect = gfx::Rect(100, 0);
1677 view_->SetSize(view_rect.size());
1679 // We're never expecting empty frames, resize to something non-empty.
1680 view_rect = gfx::Rect(100, 100);
1681 view_->SetSize(view_rect.size());
1683 // This frame should not be dropped.
1684 EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
1685 view_->OnSwapCompositorFrame(
1686 0, MakeDelegatedFrame(1.f, view_rect.size(), view_rect));
1687 testing::Mock::VerifyAndClearExpectations(&observer);
1688 view_->RunOnCompositingDidCommit();
1690 view_->window_->RemoveObserver(&observer);
1693 TEST_F(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange) {
1694 gfx::Rect view_rect(100, 100);
1695 gfx::Size frame_size = view_rect.size();
1697 view_->InitAsChild(NULL);
1698 aura::client::ParentWindowWithContext(
1699 view_->GetNativeView(),
1700 parent_view_->GetNativeView()->GetRootWindow(),
1701 gfx::Rect());
1702 view_->SetSize(view_rect.size());
1704 MockWindowObserver observer;
1705 view_->window_->AddObserver(&observer);
1707 // Swap a frame.
1708 EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
1709 view_->OnSwapCompositorFrame(
1710 0, MakeDelegatedFrame(1.f, frame_size, view_rect));
1711 testing::Mock::VerifyAndClearExpectations(&observer);
1712 view_->RunOnCompositingDidCommit();
1714 // Swap a frame with a different surface id.
1715 EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
1716 view_->OnSwapCompositorFrame(
1717 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
1718 testing::Mock::VerifyAndClearExpectations(&observer);
1719 view_->RunOnCompositingDidCommit();
1721 // Swap an empty frame, with a different surface id.
1722 view_->OnSwapCompositorFrame(
1723 2, MakeDelegatedFrame(1.f, gfx::Size(), gfx::Rect()));
1724 testing::Mock::VerifyAndClearExpectations(&observer);
1725 view_->RunOnCompositingDidCommit();
1727 // Swap another frame, with a different surface id.
1728 EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
1729 view_->OnSwapCompositorFrame(3,
1730 MakeDelegatedFrame(1.f, frame_size, view_rect));
1731 testing::Mock::VerifyAndClearExpectations(&observer);
1732 view_->RunOnCompositingDidCommit();
1734 view_->window_->RemoveObserver(&observer);
1737 TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
1738 view_->InitAsChild(NULL);
1740 size_t max_renderer_frames =
1741 RendererFrameManager::GetInstance()->GetMaxNumberOfSavedFrames();
1742 ASSERT_LE(2u, max_renderer_frames);
1743 size_t renderer_count = max_renderer_frames + 1;
1744 gfx::Rect view_rect(100, 100);
1745 gfx::Size frame_size = view_rect.size();
1746 DCHECK_EQ(0u, HostSharedBitmapManager::current()->AllocatedBitmapCount());
1748 scoped_ptr<RenderWidgetHostImpl * []> hosts(
1749 new RenderWidgetHostImpl* [renderer_count]);
1750 scoped_ptr<FakeRenderWidgetHostViewAura * []> views(
1751 new FakeRenderWidgetHostViewAura* [renderer_count]);
1753 // Create a bunch of renderers.
1754 for (size_t i = 0; i < renderer_count; ++i) {
1755 hosts[i] = new RenderWidgetHostImpl(
1756 &delegate_, process_host_, MSG_ROUTING_NONE, false);
1757 hosts[i]->Init();
1758 views[i] = new FakeRenderWidgetHostViewAura(hosts[i], false);
1759 views[i]->InitAsChild(NULL);
1760 aura::client::ParentWindowWithContext(
1761 views[i]->GetNativeView(),
1762 parent_view_->GetNativeView()->GetRootWindow(),
1763 gfx::Rect());
1764 views[i]->SetSize(view_rect.size());
1767 // Make each renderer visible, and swap a frame on it, then make it invisible.
1768 for (size_t i = 0; i < renderer_count; ++i) {
1769 views[i]->Show();
1770 views[i]->OnSwapCompositorFrame(
1771 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
1772 EXPECT_TRUE(views[i]->HasFrameData());
1773 views[i]->Hide();
1776 // There should be max_renderer_frames with a frame in it, and one without it.
1777 // Since the logic is LRU eviction, the first one should be without.
1778 EXPECT_FALSE(views[0]->HasFrameData());
1779 for (size_t i = 1; i < renderer_count; ++i)
1780 EXPECT_TRUE(views[i]->HasFrameData());
1782 // LRU renderer is [0], make it visible, it shouldn't evict anything yet.
1783 views[0]->Show();
1784 EXPECT_FALSE(views[0]->HasFrameData());
1785 EXPECT_TRUE(views[1]->HasFrameData());
1786 // Since [0] doesn't have a frame, it should be waiting for the renderer to
1787 // give it one.
1788 EXPECT_TRUE(views[0]->released_front_lock_active());
1790 // Swap a frame on it, it should evict the next LRU [1].
1791 views[0]->OnSwapCompositorFrame(
1792 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
1793 EXPECT_TRUE(views[0]->HasFrameData());
1794 EXPECT_FALSE(views[1]->HasFrameData());
1795 // Now that [0] got a frame, it shouldn't be waiting any more.
1796 EXPECT_FALSE(views[0]->released_front_lock_active());
1797 views[0]->Hide();
1799 // LRU renderer is [1], still hidden. Swap a frame on it, it should evict
1800 // the next LRU [2].
1801 views[1]->OnSwapCompositorFrame(
1802 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
1803 EXPECT_TRUE(views[0]->HasFrameData());
1804 EXPECT_TRUE(views[1]->HasFrameData());
1805 EXPECT_FALSE(views[2]->HasFrameData());
1806 for (size_t i = 3; i < renderer_count; ++i)
1807 EXPECT_TRUE(views[i]->HasFrameData());
1809 // Make all renderers but [0] visible and swap a frame on them, keep [0]
1810 // hidden, it becomes the LRU.
1811 for (size_t i = 1; i < renderer_count; ++i) {
1812 views[i]->Show();
1813 // The renderers who don't have a frame should be waiting. The ones that
1814 // have a frame should not.
1815 // In practice, [1] has a frame, but anything after has its frame evicted.
1816 EXPECT_EQ(!views[i]->HasFrameData(),
1817 views[i]->released_front_lock_active());
1818 views[i]->OnSwapCompositorFrame(
1819 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
1820 // Now everyone has a frame.
1821 EXPECT_FALSE(views[i]->released_front_lock_active());
1822 EXPECT_TRUE(views[i]->HasFrameData());
1824 EXPECT_FALSE(views[0]->HasFrameData());
1826 // Swap a frame on [0], it should be evicted immediately.
1827 views[0]->OnSwapCompositorFrame(
1828 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
1829 EXPECT_FALSE(views[0]->HasFrameData());
1831 // Make [0] visible, and swap a frame on it. Nothing should be evicted
1832 // although we're above the limit.
1833 views[0]->Show();
1834 // We don't have a frame, wait.
1835 EXPECT_TRUE(views[0]->released_front_lock_active());
1836 views[0]->OnSwapCompositorFrame(
1837 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
1838 EXPECT_FALSE(views[0]->released_front_lock_active());
1839 for (size_t i = 0; i < renderer_count; ++i)
1840 EXPECT_TRUE(views[i]->HasFrameData());
1842 // Make [0] hidden, it should evict its frame.
1843 views[0]->Hide();
1844 EXPECT_FALSE(views[0]->HasFrameData());
1846 // Make [0] visible, don't give it a frame, it should be waiting.
1847 views[0]->Show();
1848 EXPECT_TRUE(views[0]->released_front_lock_active());
1849 // Make [0] hidden, it should stop waiting.
1850 views[0]->Hide();
1851 EXPECT_FALSE(views[0]->released_front_lock_active());
1853 // Make [1] hidden, resize it. It should drop its frame.
1854 views[1]->Hide();
1855 EXPECT_TRUE(views[1]->HasFrameData());
1856 gfx::Size size2(200, 200);
1857 views[1]->SetSize(size2);
1858 EXPECT_FALSE(views[1]->HasFrameData());
1859 // Show it, it should block until we give it a frame.
1860 views[1]->Show();
1861 EXPECT_TRUE(views[1]->released_front_lock_active());
1862 views[1]->OnSwapCompositorFrame(
1863 1, MakeDelegatedFrame(1.f, size2, gfx::Rect(size2)));
1864 EXPECT_FALSE(views[1]->released_front_lock_active());
1866 for (size_t i = 0; i < renderer_count - 1; ++i)
1867 views[i]->Hide();
1869 // Allocate enough bitmaps so that two frames (proportionally) would be
1870 // enough hit the handle limit.
1871 int handles_per_frame = 5;
1872 RendererFrameManager::GetInstance()->set_max_handles(handles_per_frame * 2);
1874 HostSharedBitmapManagerClient bitmap_client(
1875 HostSharedBitmapManager::current());
1877 for (size_t i = 0; i < (renderer_count - 1) * handles_per_frame; i++) {
1878 bitmap_client.ChildAllocatedSharedBitmap(
1879 1, base::SharedMemory::NULLHandle(), base::GetCurrentProcessHandle(),
1880 cc::SharedBitmap::GenerateId());
1883 // Hiding this last bitmap should evict all but two frames.
1884 views[renderer_count - 1]->Hide();
1885 for (size_t i = 0; i < renderer_count; ++i) {
1886 if (i + 2 < renderer_count)
1887 EXPECT_FALSE(views[i]->HasFrameData());
1888 else
1889 EXPECT_TRUE(views[i]->HasFrameData());
1891 RendererFrameManager::GetInstance()->set_max_handles(
1892 base::SharedMemory::GetHandleLimit());
1894 for (size_t i = 0; i < renderer_count; ++i) {
1895 views[i]->Destroy();
1896 delete hosts[i];
1900 TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
1901 view_->InitAsChild(NULL);
1903 size_t max_renderer_frames =
1904 RendererFrameManager::GetInstance()->GetMaxNumberOfSavedFrames();
1905 ASSERT_LE(2u, max_renderer_frames);
1906 size_t renderer_count = max_renderer_frames + 1;
1907 gfx::Rect view_rect(100, 100);
1908 gfx::Size frame_size = view_rect.size();
1909 DCHECK_EQ(0u, HostSharedBitmapManager::current()->AllocatedBitmapCount());
1911 scoped_ptr<RenderWidgetHostImpl * []> hosts(
1912 new RenderWidgetHostImpl* [renderer_count]);
1913 scoped_ptr<FakeRenderWidgetHostViewAura * []> views(
1914 new FakeRenderWidgetHostViewAura* [renderer_count]);
1916 // Create a bunch of renderers.
1917 for (size_t i = 0; i < renderer_count; ++i) {
1918 hosts[i] = new RenderWidgetHostImpl(
1919 &delegate_, process_host_, MSG_ROUTING_NONE, false);
1920 hosts[i]->Init();
1921 views[i] = new FakeRenderWidgetHostViewAura(hosts[i], false);
1922 views[i]->InitAsChild(NULL);
1923 aura::client::ParentWindowWithContext(
1924 views[i]->GetNativeView(),
1925 parent_view_->GetNativeView()->GetRootWindow(),
1926 gfx::Rect());
1927 views[i]->SetSize(view_rect.size());
1930 // Make each renderer visible and swap a frame on it. No eviction should
1931 // occur because all frames are visible.
1932 for (size_t i = 0; i < renderer_count; ++i) {
1933 views[i]->Show();
1934 views[i]->OnSwapCompositorFrame(
1935 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
1936 EXPECT_TRUE(views[i]->HasFrameData());
1939 // If we hide [0], then [0] should be evicted.
1940 views[0]->Hide();
1941 EXPECT_FALSE(views[0]->HasFrameData());
1943 // If we lock [0] before hiding it, then [0] should not be evicted.
1944 views[0]->Show();
1945 views[0]->OnSwapCompositorFrame(
1946 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
1947 EXPECT_TRUE(views[0]->HasFrameData());
1948 views[0]->GetDelegatedFrameHost()->LockResources();
1949 views[0]->Hide();
1950 EXPECT_TRUE(views[0]->HasFrameData());
1952 // If we unlock [0] now, then [0] should be evicted.
1953 views[0]->GetDelegatedFrameHost()->UnlockResources();
1954 EXPECT_FALSE(views[0]->HasFrameData());
1956 for (size_t i = 0; i < renderer_count; ++i) {
1957 views[i]->Destroy();
1958 delete hosts[i];
1962 // Test that changing the memory pressure should delete saved frames. This test
1963 // only applies to ChromeOS.
1964 TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithMemoryPressure) {
1965 view_->InitAsChild(NULL);
1967 size_t max_renderer_frames =
1968 RendererFrameManager::GetInstance()->GetMaxNumberOfSavedFrames();
1969 ASSERT_LE(2u, max_renderer_frames);
1970 size_t renderer_count = max_renderer_frames;
1971 gfx::Rect view_rect(100, 100);
1972 gfx::Size frame_size = view_rect.size();
1973 DCHECK_EQ(0u, HostSharedBitmapManager::current()->AllocatedBitmapCount());
1975 scoped_ptr<RenderWidgetHostImpl * []> hosts(
1976 new RenderWidgetHostImpl* [renderer_count]);
1977 scoped_ptr<FakeRenderWidgetHostViewAura * []> views(
1978 new FakeRenderWidgetHostViewAura* [renderer_count]);
1980 // Create a bunch of renderers.
1981 for (size_t i = 0; i < renderer_count; ++i) {
1982 hosts[i] = new RenderWidgetHostImpl(
1983 &delegate_, process_host_, MSG_ROUTING_NONE, false);
1984 hosts[i]->Init();
1985 views[i] = new FakeRenderWidgetHostViewAura(hosts[i], false);
1986 views[i]->InitAsChild(NULL);
1987 aura::client::ParentWindowWithContext(
1988 views[i]->GetNativeView(),
1989 parent_view_->GetNativeView()->GetRootWindow(),
1990 gfx::Rect());
1991 views[i]->SetSize(view_rect.size());
1994 // Make each renderer visible and swap a frame on it. No eviction should
1995 // occur because all frames are visible.
1996 for (size_t i = 0; i < renderer_count; ++i) {
1997 views[i]->Show();
1998 views[i]->OnSwapCompositorFrame(
1999 1, MakeDelegatedFrame(1.f, frame_size, view_rect));
2000 EXPECT_TRUE(views[i]->HasFrameData());
2003 // If we hide one, it should not get evicted.
2004 views[0]->Hide();
2005 message_loop_.RunUntilIdle();
2006 EXPECT_TRUE(views[0]->HasFrameData());
2007 // Using a lesser memory pressure event however, should evict.
2008 SimulateMemoryPressure(
2009 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
2010 message_loop_.RunUntilIdle();
2011 EXPECT_FALSE(views[0]->HasFrameData());
2013 // Check the same for a higher pressure event.
2014 views[1]->Hide();
2015 message_loop_.RunUntilIdle();
2016 EXPECT_TRUE(views[1]->HasFrameData());
2017 SimulateMemoryPressure(
2018 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
2019 message_loop_.RunUntilIdle();
2020 EXPECT_FALSE(views[1]->HasFrameData());
2022 for (size_t i = 0; i < renderer_count; ++i) {
2023 views[i]->Destroy();
2024 delete hosts[i];
2028 TEST_F(RenderWidgetHostViewAuraTest, SoftwareDPIChange) {
2029 gfx::Rect view_rect(100, 100);
2030 gfx::Size frame_size(100, 100);
2032 view_->InitAsChild(NULL);
2033 aura::client::ParentWindowWithContext(
2034 view_->GetNativeView(),
2035 parent_view_->GetNativeView()->GetRootWindow(),
2036 gfx::Rect());
2037 view_->SetSize(view_rect.size());
2038 view_->Show();
2040 // With a 1x DPI UI and 1x DPI Renderer.
2041 view_->OnSwapCompositorFrame(
2042 1, MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)));
2044 // Save the frame provider.
2045 scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
2046 view_->frame_provider();
2047 cc::SurfaceId surface_id = view_->surface_id();
2049 // This frame will have the same number of physical pixels, but has a new
2050 // scale on it.
2051 view_->OnSwapCompositorFrame(
2052 1, MakeDelegatedFrame(2.f, frame_size, gfx::Rect(frame_size)));
2054 // When we get a new frame with the same frame size in physical pixels, but a
2055 // different scale, we should generate a new frame provider, as the final
2056 // result will need to be scaled differently to the screen.
2057 if (frame_provider.get())
2058 EXPECT_NE(frame_provider.get(), view_->frame_provider());
2059 else
2060 EXPECT_NE(surface_id, view_->surface_id());
2063 class RenderWidgetHostViewAuraCopyRequestTest
2064 : public RenderWidgetHostViewAuraShutdownTest {
2065 public:
2066 RenderWidgetHostViewAuraCopyRequestTest()
2067 : callback_count_(0), result_(false) {}
2069 void CallbackMethod(bool result) {
2070 result_ = result;
2071 callback_count_++;
2072 quit_closure_.Run();
2075 void RunLoopUntilCallback() {
2076 base::RunLoop run_loop;
2077 quit_closure_ = run_loop.QuitClosure();
2078 run_loop.Run();
2081 int callback_count_;
2082 bool result_;
2084 private:
2085 base::Closure quit_closure_;
2087 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraCopyRequestTest);
2090 // Tests that only one copy/readback request will be executed per one browser
2091 // composite operation, even when multiple render frame swaps occur in between
2092 // browser composites, and even if the frame subscriber desires more frames than
2093 // the number of browser composites.
2094 TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DedupeFrameSubscriberRequests) {
2095 gfx::Rect view_rect(100, 100);
2096 scoped_ptr<cc::CopyOutputRequest> request;
2098 view_->InitAsChild(NULL);
2099 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting(
2100 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput,
2101 base::Unretained(view_)));
2102 aura::client::ParentWindowWithContext(
2103 view_->GetNativeView(),
2104 parent_view_->GetNativeView()->GetRootWindow(),
2105 gfx::Rect());
2106 view_->SetSize(view_rect.size());
2107 view_->Show();
2109 view_->BeginFrameSubscription(make_scoped_ptr(new FakeFrameSubscriber(
2110 view_rect.size(),
2111 base::Bind(&RenderWidgetHostViewAuraCopyRequestTest::CallbackMethod,
2112 base::Unretained(this)))).Pass());
2113 int expected_callback_count = 0;
2114 ASSERT_EQ(expected_callback_count, callback_count_);
2115 ASSERT_FALSE(view_->last_copy_request_);
2117 // Normal case: A browser composite executes for each render frame swap.
2118 for (int i = 0; i < 3; ++i) {
2119 // Renderer provides another frame.
2120 view_->OnSwapCompositorFrame(
2121 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect)));
2122 ASSERT_TRUE(view_->last_copy_request_);
2123 request = view_->last_copy_request_.Pass();
2125 // Browser composites with the frame, executing the copy request, and then
2126 // the result is delivered.
2127 view_->RunOnCompositingDidCommit();
2128 request->SendTextureResult(view_rect.size(),
2129 request->texture_mailbox(),
2130 scoped_ptr<cc::SingleReleaseCallback>());
2131 RunLoopUntilCallback();
2133 // The callback should be run with success status.
2134 ++expected_callback_count;
2135 ASSERT_EQ(expected_callback_count, callback_count_);
2136 EXPECT_TRUE(result_);
2139 // De-duping case: One browser composite executes per varied number of render
2140 // frame swaps.
2141 for (int i = 0; i < 3; ++i) {
2142 const int num_swaps = 1 + i % 3;
2144 // The renderer provides |num_swaps| frames.
2145 for (int j = 0; j < num_swaps; ++j) {
2146 view_->OnSwapCompositorFrame(
2147 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect)));
2148 ASSERT_TRUE(view_->last_copy_request_);
2149 // The following statement simulates the layer de-duping the copy request
2150 // coming from the same source (i.e., the DelegatedFrameHost):
2151 request = view_->last_copy_request_.Pass();
2152 if (j > 0) {
2153 ++expected_callback_count;
2154 ASSERT_EQ(expected_callback_count, callback_count_);
2155 EXPECT_FALSE(result_); // The prior copy request was aborted.
2159 // Browser composites with the frame, executing the last copy request that
2160 // was made, and then the result is delivered.
2161 view_->RunOnCompositingDidCommit();
2162 request->SendTextureResult(view_rect.size(),
2163 request->texture_mailbox(),
2164 scoped_ptr<cc::SingleReleaseCallback>());
2165 RunLoopUntilCallback();
2167 // The final callback should be run with success status.
2168 ++expected_callback_count;
2169 ASSERT_EQ(expected_callback_count, callback_count_);
2170 EXPECT_TRUE(result_);
2173 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory.
2174 TearDownEnvironment();
2177 TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DestroyedAfterCopyRequest) {
2178 gfx::Rect view_rect(100, 100);
2179 scoped_ptr<cc::CopyOutputRequest> request;
2181 view_->InitAsChild(NULL);
2182 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting(
2183 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput,
2184 base::Unretained(view_)));
2185 aura::client::ParentWindowWithContext(
2186 view_->GetNativeView(),
2187 parent_view_->GetNativeView()->GetRootWindow(),
2188 gfx::Rect());
2189 view_->SetSize(view_rect.size());
2190 view_->Show();
2192 scoped_ptr<FakeFrameSubscriber> frame_subscriber(new FakeFrameSubscriber(
2193 view_rect.size(),
2194 base::Bind(&RenderWidgetHostViewAuraCopyRequestTest::CallbackMethod,
2195 base::Unretained(this))));
2197 EXPECT_EQ(0, callback_count_);
2198 EXPECT_FALSE(view_->last_copy_request_);
2200 view_->BeginFrameSubscription(frame_subscriber.Pass());
2201 view_->OnSwapCompositorFrame(
2202 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect)));
2204 EXPECT_EQ(0, callback_count_);
2205 EXPECT_TRUE(view_->last_copy_request_);
2206 EXPECT_TRUE(view_->last_copy_request_->has_texture_mailbox());
2207 request = view_->last_copy_request_.Pass();
2209 // Notify DelegatedFrameHost that the copy requests were moved to the
2210 // compositor thread by calling OnCompositingDidCommit().
2211 view_->RunOnCompositingDidCommit();
2212 // Send back the mailbox included in the request. There's no release callback
2213 // since the mailbox came from the RWHVA originally.
2214 request->SendTextureResult(view_rect.size(),
2215 request->texture_mailbox(),
2216 scoped_ptr<cc::SingleReleaseCallback>());
2217 RunLoopUntilCallback();
2219 // The callback should succeed.
2220 EXPECT_EQ(1, callback_count_);
2221 EXPECT_TRUE(result_);
2223 view_->OnSwapCompositorFrame(
2224 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect)));
2226 EXPECT_EQ(1, callback_count_);
2227 request = view_->last_copy_request_.Pass();
2229 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory.
2230 TearDownEnvironment();
2232 // Send the result after-the-fact. It goes nowhere since DelegatedFrameHost
2233 // has been destroyed.
2234 request->SendTextureResult(view_rect.size(),
2235 request->texture_mailbox(),
2236 scoped_ptr<cc::SingleReleaseCallback>());
2238 // Because the copy request callback may be holding state within it, that
2239 // state must handle the RWHVA and ImageTransportFactory going away before the
2240 // callback is called. This test passes if it does not crash as a result of
2241 // these things being destroyed.
2242 EXPECT_EQ(2, callback_count_);
2243 EXPECT_FALSE(result_);
2246 TEST_F(RenderWidgetHostViewAuraTest, VisibleViewportTest) {
2247 gfx::Rect view_rect(100, 100);
2249 view_->InitAsChild(NULL);
2250 aura::client::ParentWindowWithContext(
2251 view_->GetNativeView(),
2252 parent_view_->GetNativeView()->GetRootWindow(),
2253 gfx::Rect());
2254 view_->SetSize(view_rect.size());
2255 view_->Show();
2257 // Defaults to full height of the view.
2258 EXPECT_EQ(100, view_->GetVisibleViewportSize().height());
2260 widget_host_->ResetSizeAndRepaintPendingFlags();
2261 sink_->ClearMessages();
2262 view_->SetInsets(gfx::Insets(0, 0, 40, 0));
2264 EXPECT_EQ(60, view_->GetVisibleViewportSize().height());
2266 const IPC::Message *message = sink_->GetFirstMessageMatching(
2267 ViewMsg_Resize::ID);
2268 ASSERT_TRUE(message != NULL);
2270 ViewMsg_Resize::Param params;
2271 ViewMsg_Resize::Read(message, &params);
2272 EXPECT_EQ(60, get<0>(params).visible_viewport_size.height());
2275 // Ensures that touch event positions are never truncated to integers.
2276 TEST_F(RenderWidgetHostViewAuraTest, TouchEventPositionsArentRounded) {
2277 const float kX = 30.58f;
2278 const float kY = 50.23f;
2280 view_->InitAsChild(NULL);
2281 view_->Show();
2283 ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
2284 gfx::PointF(kX, kY),
2286 ui::EventTimeForNow());
2288 view_->OnTouchEvent(&press);
2289 EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_->type);
2290 EXPECT_TRUE(view_->touch_event_->cancelable);
2291 EXPECT_EQ(1U, view_->touch_event_->touchesLength);
2292 EXPECT_EQ(blink::WebTouchPoint::StatePressed,
2293 view_->touch_event_->touches[0].state);
2294 EXPECT_EQ(kX, view_->touch_event_->touches[0].screenPosition.x);
2295 EXPECT_EQ(kX, view_->touch_event_->touches[0].position.x);
2296 EXPECT_EQ(kY, view_->touch_event_->touches[0].screenPosition.y);
2297 EXPECT_EQ(kY, view_->touch_event_->touches[0].position.y);
2300 // Tests that scroll ACKs are correctly handled by the overscroll-navigation
2301 // controller.
2302 TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollEventOverscrolls) {
2303 SetUpOverscrollEnvironment();
2305 // Simulate wheel events.
2306 SimulateWheelEvent(-5, 0, 0, true); // sent directly
2307 SimulateWheelEvent(-1, 1, 0, true); // enqueued
2308 SimulateWheelEvent(-10, -3, 0, true); // coalesced into previous event
2309 SimulateWheelEvent(-15, -1, 0, true); // coalesced into previous event
2310 SimulateWheelEvent(-30, -3, 0, true); // coalesced into previous event
2311 SimulateWheelEvent(-20, 6, 1, true); // enqueued, different modifiers
2312 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2313 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2315 // Receive ACK the first wheel event as not processed.
2316 SendInputEventACK(WebInputEvent::MouseWheel,
2317 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2318 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2319 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2320 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2322 // Receive ACK for the second (coalesced) event as not processed. This will
2323 // start a back navigation. However, this will also cause the queued next
2324 // event to be sent to the renderer. But since overscroll navigation has
2325 // started, that event will also be included in the overscroll computation
2326 // instead of being sent to the renderer. So the result will be an overscroll
2327 // back navigation, and no event will be sent to the renderer.
2328 SendInputEventACK(WebInputEvent::MouseWheel,
2329 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2330 EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
2331 EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode());
2332 EXPECT_EQ(-81.f, overscroll_delta_x());
2333 EXPECT_EQ(-31.f, overscroll_delegate()->delta_x());
2334 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2335 EXPECT_EQ(0U, sink_->message_count());
2337 // Send a mouse-move event. This should cancel the overscroll navigation.
2338 SimulateMouseMove(5, 10, 0);
2339 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2340 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2341 EXPECT_EQ(1U, sink_->message_count());
2344 // Tests that if some scroll events are consumed towards the start, then
2345 // subsequent scrolls do not horizontal overscroll.
2346 TEST_F(RenderWidgetHostViewAuraOverscrollTest,
2347 WheelScrollConsumedDoNotHorizOverscroll) {
2348 SetUpOverscrollEnvironment();
2350 // Simulate wheel events.
2351 SimulateWheelEvent(-5, 0, 0, true); // sent directly
2352 SimulateWheelEvent(-1, -1, 0, true); // enqueued
2353 SimulateWheelEvent(-10, -3, 0, true); // coalesced into previous event
2354 SimulateWheelEvent(-15, -1, 0, true); // coalesced into previous event
2355 SimulateWheelEvent(-30, -3, 0, true); // coalesced into previous event
2356 SimulateWheelEvent(-20, 6, 1, true); // enqueued, different modifiers
2357 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2358 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2360 // Receive ACK the first wheel event as processed.
2361 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
2362 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2363 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2364 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2366 // Receive ACK for the second (coalesced) event as not processed. This should
2367 // not initiate overscroll, since the beginning of the scroll has been
2368 // consumed. The queued event with different modifiers should be sent to the
2369 // renderer.
2370 SendInputEventACK(WebInputEvent::MouseWheel,
2371 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2372 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2373 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2375 SendInputEventACK(WebInputEvent::MouseWheel,
2376 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2377 EXPECT_EQ(0U, sink_->message_count());
2378 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2380 // Indicate the end of the scrolling from the touchpad.
2381 SimulateGestureFlingStartEvent(-1200.f, 0.f, blink::WebGestureDeviceTouchpad);
2382 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2384 // Start another scroll. This time, do not consume any scroll events.
2385 SimulateWheelEvent(0, -5, 0, true); // sent directly
2386 SimulateWheelEvent(0, -1, 0, true); // enqueued
2387 SimulateWheelEvent(-10, -3, 0, true); // coalesced into previous event
2388 SimulateWheelEvent(-15, -1, 0, true); // coalesced into previous event
2389 SimulateWheelEvent(-30, -3, 0, true); // coalesced into previous event
2390 SimulateWheelEvent(-20, 6, 1, true); // enqueued, different modifiers
2391 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2392 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2394 // Receive ACK for the first wheel and the subsequent coalesced event as not
2395 // processed. This should start a back-overscroll.
2396 SendInputEventACK(WebInputEvent::MouseWheel,
2397 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2398 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2399 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2400 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2401 SendInputEventACK(WebInputEvent::MouseWheel,
2402 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2403 EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
2406 // Tests that wheel-scrolling correctly turns overscroll on and off.
2407 TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollOverscrollToggle) {
2408 SetUpOverscrollEnvironment();
2410 // Send a wheel event. ACK the event as not processed. This should not
2411 // initiate an overscroll gesture since it doesn't cross the threshold yet.
2412 SimulateWheelEvent(10, 0, 0, true);
2413 SendInputEventACK(WebInputEvent::MouseWheel,
2414 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2415 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2416 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2417 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2419 // Scroll some more so as to not overscroll.
2420 SimulateWheelEvent(10, 0, 0, true);
2421 SendInputEventACK(WebInputEvent::MouseWheel,
2422 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2423 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2424 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2425 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2427 // Scroll some more to initiate an overscroll.
2428 SimulateWheelEvent(40, 0, 0, true);
2429 SendInputEventACK(WebInputEvent::MouseWheel,
2430 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2431 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2432 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2433 EXPECT_EQ(60.f, overscroll_delta_x());
2434 EXPECT_EQ(10.f, overscroll_delegate()->delta_x());
2435 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2436 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2438 // Scroll in the reverse direction enough to abort the overscroll.
2439 SimulateWheelEvent(-20, 0, 0, true);
2440 EXPECT_EQ(0U, sink_->message_count());
2441 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2442 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2444 // Continue to scroll in the reverse direction.
2445 SimulateWheelEvent(-20, 0, 0, true);
2446 SendInputEventACK(WebInputEvent::MouseWheel,
2447 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2448 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2449 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2450 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2452 // Continue to scroll in the reverse direction enough to initiate overscroll
2453 // in that direction.
2454 SimulateWheelEvent(-55, 0, 0, true);
2455 EXPECT_EQ(1U, sink_->message_count());
2456 SendInputEventACK(WebInputEvent::MouseWheel,
2457 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2458 EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
2459 EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode());
2460 EXPECT_EQ(-75.f, overscroll_delta_x());
2461 EXPECT_EQ(-25.f, overscroll_delegate()->delta_x());
2462 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2465 TEST_F(RenderWidgetHostViewAuraOverscrollTest,
2466 ScrollEventsOverscrollWithFling) {
2467 SetUpOverscrollEnvironment();
2469 // Send a wheel event. ACK the event as not processed. This should not
2470 // initiate an overscroll gesture since it doesn't cross the threshold yet.
2471 SimulateWheelEvent(10, 0, 0, true);
2472 SendInputEventACK(WebInputEvent::MouseWheel,
2473 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2474 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2475 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2476 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2478 // Scroll some more so as to not overscroll.
2479 SimulateWheelEvent(20, 0, 0, true);
2480 EXPECT_EQ(1U, sink_->message_count());
2481 SendInputEventACK(WebInputEvent::MouseWheel,
2482 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2483 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2484 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2485 sink_->ClearMessages();
2487 // Scroll some more to initiate an overscroll.
2488 SimulateWheelEvent(30, 0, 0, true);
2489 SendInputEventACK(WebInputEvent::MouseWheel,
2490 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2491 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2492 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2493 EXPECT_EQ(60.f, overscroll_delta_x());
2494 EXPECT_EQ(10.f, overscroll_delegate()->delta_x());
2495 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2496 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2498 // Send a fling start, but with a small velocity, so that the overscroll is
2499 // aborted. The fling should proceed to the renderer, through the gesture
2500 // event filter.
2501 SimulateGestureFlingStartEvent(0.f, 0.1f, blink::WebGestureDeviceTouchpad);
2502 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2503 EXPECT_EQ(1U, sink_->message_count());
2506 // Same as ScrollEventsOverscrollWithFling, but with zero velocity. Checks that
2507 // the zero-velocity fling does not reach the renderer.
2508 TEST_F(RenderWidgetHostViewAuraOverscrollTest,
2509 ScrollEventsOverscrollWithZeroFling) {
2510 SetUpOverscrollEnvironment();
2512 // Send a wheel event. ACK the event as not processed. This should not
2513 // initiate an overscroll gesture since it doesn't cross the threshold yet.
2514 SimulateWheelEvent(10, 0, 0, true);
2515 SendInputEventACK(WebInputEvent::MouseWheel,
2516 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2517 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2518 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2519 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2521 // Scroll some more so as to not overscroll.
2522 SimulateWheelEvent(20, 0, 0, true);
2523 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2524 SendInputEventACK(WebInputEvent::MouseWheel,
2525 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2526 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2527 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2529 // Scroll some more to initiate an overscroll.
2530 SimulateWheelEvent(30, 0, 0, true);
2531 SendInputEventACK(WebInputEvent::MouseWheel,
2532 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2533 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2534 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2535 EXPECT_EQ(60.f, overscroll_delta_x());
2536 EXPECT_EQ(10.f, overscroll_delegate()->delta_x());
2537 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2538 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2540 // Send a fling start, but with a small velocity, so that the overscroll is
2541 // aborted. The fling should proceed to the renderer, through the gesture
2542 // event filter.
2543 SimulateGestureFlingStartEvent(10.f, 0.f, blink::WebGestureDeviceTouchpad);
2544 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2545 EXPECT_EQ(1U, sink_->message_count());
2548 // Tests that a fling in the opposite direction of the overscroll cancels the
2549 // overscroll nav instead of completing it.
2550 TEST_F(RenderWidgetHostViewAuraOverscrollTest, ReverseFlingCancelsOverscroll) {
2551 SetUpOverscrollEnvironment();
2554 // Start and end a gesture in the same direction without processing the
2555 // gesture events in the renderer. This should initiate and complete an
2556 // overscroll navigation.
2557 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2558 blink::WebGestureDeviceTouchscreen);
2559 SimulateGestureScrollUpdateEvent(300, -5, 0);
2560 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2561 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2562 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2563 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2564 sink_->ClearMessages();
2566 SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
2567 blink::WebGestureDeviceTouchscreen);
2568 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
2569 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2570 EXPECT_EQ(1U, sink_->message_count());
2574 // Start over, except instead of ending the gesture with ScrollEnd, end it
2575 // with a FlingStart, with velocity in the reverse direction. This should
2576 // initiate an overscroll navigation, but it should be cancelled because of
2577 // the fling in the opposite direction.
2578 overscroll_delegate()->Reset();
2579 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2580 blink::WebGestureDeviceTouchscreen);
2581 SimulateGestureScrollUpdateEvent(-300, -5, 0);
2582 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2583 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2584 EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
2585 EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode());
2586 sink_->ClearMessages();
2588 SimulateGestureFlingStartEvent(100, 0, blink::WebGestureDeviceTouchscreen);
2589 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
2590 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2591 EXPECT_EQ(1U, sink_->message_count());
2595 // Tests that touch-scroll events are handled correctly by the overscroll
2596 // controller. This also tests that the overscroll controller and the
2597 // gesture-event filter play nice with each other.
2598 TEST_F(RenderWidgetHostViewAuraOverscrollTest, GestureScrollOverscrolls) {
2599 SetUpOverscrollEnvironment();
2601 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2602 blink::WebGestureDeviceTouchscreen);
2603 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2604 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2605 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2607 // Send another gesture event and ACK as not being processed. This should
2608 // initiate the navigation gesture.
2609 SimulateGestureScrollUpdateEvent(55, -5, 0);
2610 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2611 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2612 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2613 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2614 EXPECT_EQ(55.f, overscroll_delta_x());
2615 EXPECT_EQ(-5.f, overscroll_delta_y());
2616 EXPECT_EQ(5.f, overscroll_delegate()->delta_x());
2617 EXPECT_EQ(-5.f, overscroll_delegate()->delta_y());
2618 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2620 // Send another gesture update event. This event should be consumed by the
2621 // controller, and not be forwarded to the renderer. The gesture-event filter
2622 // should not also receive this event.
2623 SimulateGestureScrollUpdateEvent(10, -5, 0);
2624 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2625 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2626 EXPECT_EQ(65.f, overscroll_delta_x());
2627 EXPECT_EQ(-10.f, overscroll_delta_y());
2628 EXPECT_EQ(15.f, overscroll_delegate()->delta_x());
2629 EXPECT_EQ(-10.f, overscroll_delegate()->delta_y());
2630 EXPECT_EQ(0U, sink_->message_count());
2632 // Now send a scroll end. This should cancel the overscroll gesture, and send
2633 // the event to the renderer. The gesture-event filter should receive this
2634 // event.
2635 SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
2636 blink::WebGestureDeviceTouchscreen);
2637 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2638 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2639 EXPECT_EQ(1U, sink_->message_count());
2642 // Tests that if the page is scrolled because of a scroll-gesture, then that
2643 // particular scroll sequence never generates overscroll if the scroll direction
2644 // is horizontal.
2645 TEST_F(RenderWidgetHostViewAuraOverscrollTest,
2646 GestureScrollConsumedHorizontal) {
2647 SetUpOverscrollEnvironment();
2649 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2650 blink::WebGestureDeviceTouchscreen);
2651 SimulateGestureScrollUpdateEvent(10, 0, 0);
2653 // Start scrolling on content. ACK both events as being processed.
2654 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2655 INPUT_EVENT_ACK_STATE_CONSUMED);
2656 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2657 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2658 sink_->ClearMessages();
2660 // Send another gesture event and ACK as not being processed. This should
2661 // not initiate overscroll because the beginning of the scroll event did
2662 // scroll some content on the page. Since there was no overscroll, the event
2663 // should reach the renderer.
2664 SimulateGestureScrollUpdateEvent(55, 0, 0);
2665 EXPECT_EQ(1U, sink_->message_count());
2666 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2667 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2668 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2671 // Tests that the overscroll controller plays nice with touch-scrolls and the
2672 // gesture event filter with debounce filtering turned on.
2673 TEST_F(RenderWidgetHostViewAuraOverscrollTest,
2674 GestureScrollDebounceOverscrolls) {
2675 SetUpOverscrollEnvironmentWithDebounce(100);
2677 // Start scrolling. Receive ACK as it being processed.
2678 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2679 blink::WebGestureDeviceTouchscreen);
2680 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2682 // Send update events.
2683 SimulateGestureScrollUpdateEvent(25, 0, 0);
2684 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2686 // Quickly end and restart the scroll gesture. These two events should get
2687 // discarded.
2688 SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
2689 blink::WebGestureDeviceTouchscreen);
2690 EXPECT_EQ(0U, sink_->message_count());
2692 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2693 blink::WebGestureDeviceTouchscreen);
2694 EXPECT_EQ(0U, sink_->message_count());
2696 // Send another update event. This should get into the queue.
2697 SimulateGestureScrollUpdateEvent(30, 0, 0);
2698 EXPECT_EQ(0U, sink_->message_count());
2700 // Receive an ACK for the first scroll-update event as not being processed.
2701 // This will contribute to the overscroll gesture, but not enough for the
2702 // overscroll controller to start consuming gesture events. This also cause
2703 // the queued gesture event to be forwarded to the renderer.
2704 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2705 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2706 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2707 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2708 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2710 // Send another update event. This should get into the queue.
2711 SimulateGestureScrollUpdateEvent(10, 0, 0);
2712 EXPECT_EQ(0U, sink_->message_count());
2714 // Receive an ACK for the second scroll-update event as not being processed.
2715 // This will now initiate an overscroll. This will also cause the queued
2716 // gesture event to be released. But instead of going to the renderer, it will
2717 // be consumed by the overscroll controller.
2718 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2719 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2720 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2721 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2722 EXPECT_EQ(65.f, overscroll_delta_x());
2723 EXPECT_EQ(15.f, overscroll_delegate()->delta_x());
2724 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2725 EXPECT_EQ(0U, sink_->message_count());
2728 // Tests that the gesture debounce timer plays nice with the overscroll
2729 // controller.
2730 TEST_F(RenderWidgetHostViewAuraOverscrollTest,
2731 GestureScrollDebounceTimerOverscroll) {
2732 SetUpOverscrollEnvironmentWithDebounce(10);
2734 // Start scrolling. Receive ACK as it being processed.
2735 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2736 blink::WebGestureDeviceTouchscreen);
2737 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2739 // Send update events.
2740 SimulateGestureScrollUpdateEvent(55, 0, 0);
2741 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2743 // Send an end event. This should get in the debounce queue.
2744 SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
2745 blink::WebGestureDeviceTouchscreen);
2746 EXPECT_EQ(0U, sink_->message_count());
2748 // Receive ACK for the scroll-update event.
2749 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2750 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2751 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2752 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2753 EXPECT_EQ(55.f, overscroll_delta_x());
2754 EXPECT_EQ(5.f, overscroll_delegate()->delta_x());
2755 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2756 EXPECT_EQ(0U, sink_->message_count());
2758 // Let the timer for the debounce queue fire. That should release the queued
2759 // scroll-end event. Since overscroll has started, but there hasn't been
2760 // enough overscroll to complete the gesture, the overscroll controller
2761 // will reset the state. The scroll-end should therefore be dispatched to the
2762 // renderer, and the gesture-event-filter should await an ACK for it.
2763 base::MessageLoop::current()->PostDelayedTask(
2764 FROM_HERE,
2765 base::MessageLoop::QuitClosure(),
2766 base::TimeDelta::FromMilliseconds(15));
2767 base::MessageLoop::current()->Run();
2769 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2770 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2771 EXPECT_EQ(1U, sink_->message_count());
2774 // Tests that when touch-events are dispatched to the renderer, the overscroll
2775 // gesture deals with them correctly.
2776 TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
2777 SetUpOverscrollEnvironmentWithDebounce(10);
2778 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
2779 sink_->ClearMessages();
2781 // The test sends an intermingled sequence of touch and gesture events.
2782 PressTouchPoint(0, 1);
2783 SendInputEventACK(WebInputEvent::TouchStart,
2784 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2785 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2787 MoveTouchPoint(0, 20, 5);
2788 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2789 SendInputEventACK(WebInputEvent::TouchMove,
2790 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2792 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2793 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2795 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2796 blink::WebGestureDeviceTouchscreen);
2797 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2798 SimulateGestureScrollUpdateEvent(20, 0, 0);
2799 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2800 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2801 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2802 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2803 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2805 // Another touch move event should reach the renderer since overscroll hasn't
2806 // started yet. Note that touch events sent during the scroll period may
2807 // not require an ack (having been marked uncancelable).
2808 MoveTouchPoint(0, 65, 10);
2809 AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2810 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2812 SimulateGestureScrollUpdateEvent(45, 0, 0);
2813 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2814 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2815 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2816 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2817 EXPECT_EQ(65.f, overscroll_delta_x());
2818 EXPECT_EQ(15.f, overscroll_delegate()->delta_x());
2819 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2820 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2822 // Send another touch event. The page should get the touch-move event, even
2823 // though overscroll has started.
2824 MoveTouchPoint(0, 55, 5);
2825 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2826 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2827 EXPECT_EQ(65.f, overscroll_delta_x());
2828 EXPECT_EQ(15.f, overscroll_delegate()->delta_x());
2829 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2830 AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2831 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2833 SimulateGestureScrollUpdateEvent(-10, 0, 0);
2834 EXPECT_EQ(0U, sink_->message_count());
2835 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2836 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2837 EXPECT_EQ(55.f, overscroll_delta_x());
2838 EXPECT_EQ(5.f, overscroll_delegate()->delta_x());
2839 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2841 PressTouchPoint(255, 5);
2842 AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2843 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2845 SimulateGestureScrollUpdateEvent(200, 0, 0);
2846 EXPECT_EQ(0U, sink_->message_count());
2847 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2848 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2849 EXPECT_EQ(255.f, overscroll_delta_x());
2850 EXPECT_EQ(205.f, overscroll_delegate()->delta_x());
2851 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
2853 // The touch-end/cancel event should always reach the renderer if the page has
2854 // touch handlers.
2855 ReleaseTouchPoint(1);
2856 AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2857 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2858 ReleaseTouchPoint(0);
2859 AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2860 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2862 SimulateGestureEvent(blink::WebInputEvent::GestureScrollEnd,
2863 blink::WebGestureDeviceTouchscreen);
2864 base::MessageLoop::current()->PostDelayedTask(
2865 FROM_HERE,
2866 base::MessageLoop::QuitClosure(),
2867 base::TimeDelta::FromMilliseconds(10));
2868 base::MessageLoop::current()->Run();
2869 EXPECT_EQ(1U, sink_->message_count());
2870 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2871 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2872 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
2875 // Tests that touch-gesture end is dispatched to the renderer at the end of a
2876 // touch-gesture initiated overscroll.
2877 TEST_F(RenderWidgetHostViewAuraOverscrollTest,
2878 TouchGestureEndDispatchedAfterOverscrollComplete) {
2879 SetUpOverscrollEnvironmentWithDebounce(10);
2880 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
2881 sink_->ClearMessages();
2883 // Start scrolling. Receive ACK as it being processed.
2884 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2885 blink::WebGestureDeviceTouchscreen);
2886 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2887 // The scroll begin event will have received a synthetic ack from the input
2888 // router.
2889 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2890 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2892 // Send update events.
2893 SimulateGestureScrollUpdateEvent(55, -5, 0);
2894 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2895 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2896 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2898 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2899 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2900 EXPECT_EQ(0U, sink_->message_count());
2901 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2902 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2903 EXPECT_EQ(55.f, overscroll_delta_x());
2904 EXPECT_EQ(5.f, overscroll_delegate()->delta_x());
2905 EXPECT_EQ(-5.f, overscroll_delegate()->delta_y());
2907 // Send end event.
2908 SimulateGestureEvent(blink::WebInputEvent::GestureScrollEnd,
2909 blink::WebGestureDeviceTouchscreen);
2910 EXPECT_EQ(0U, sink_->message_count());
2911 base::MessageLoop::current()->PostDelayedTask(
2912 FROM_HERE,
2913 base::MessageLoop::QuitClosure(),
2914 base::TimeDelta::FromMilliseconds(10));
2915 base::MessageLoop::current()->Run();
2916 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2917 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2918 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
2919 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2921 // Start scrolling. Receive ACK as it being processed.
2922 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2923 blink::WebGestureDeviceTouchscreen);
2924 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2925 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2926 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2928 // Send update events.
2929 SimulateGestureScrollUpdateEvent(235, -5, 0);
2930 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2931 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2932 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2934 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2935 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2936 EXPECT_EQ(0U, sink_->message_count());
2937 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2938 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2939 EXPECT_EQ(235.f, overscroll_delta_x());
2940 EXPECT_EQ(185.f, overscroll_delegate()->delta_x());
2941 EXPECT_EQ(-5.f, overscroll_delegate()->delta_y());
2943 // Send end event.
2944 SimulateGestureEvent(blink::WebInputEvent::GestureScrollEnd,
2945 blink::WebGestureDeviceTouchscreen);
2946 EXPECT_EQ(0U, sink_->message_count());
2947 base::MessageLoop::current()->PostDelayedTask(
2948 FROM_HERE,
2949 base::MessageLoop::QuitClosure(),
2950 base::TimeDelta::FromMilliseconds(10));
2951 base::MessageLoop::current()->Run();
2952 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2953 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
2954 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
2955 EXPECT_EQ(1U, sink_->message_count());
2958 TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDirectionChange) {
2959 SetUpOverscrollEnvironmentWithDebounce(100);
2961 // Start scrolling. Receive ACK as it being processed.
2962 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
2963 blink::WebGestureDeviceTouchscreen);
2964 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2966 // Send update events and receive ack as not consumed.
2967 SimulateGestureScrollUpdateEvent(125, -5, 0);
2968 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2970 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
2971 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2972 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
2973 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
2974 EXPECT_EQ(0U, sink_->message_count());
2976 // Send another update event, but in the reverse direction. The overscroll
2977 // controller will not consume the event, because it is not triggering
2978 // gesture-nav.
2979 SimulateGestureScrollUpdateEvent(-260, 0, 0);
2980 EXPECT_EQ(1U, sink_->message_count());
2981 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2983 // Since the overscroll mode has been reset, the next scroll update events
2984 // should reach the renderer.
2985 SimulateGestureScrollUpdateEvent(-20, 0, 0);
2986 EXPECT_EQ(1U, sink_->message_count());
2987 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
2990 TEST_F(RenderWidgetHostViewAuraOverscrollTest,
2991 OverscrollDirectionChangeMouseWheel) {
2992 SetUpOverscrollEnvironment();
2994 // Send wheel event and receive ack as not consumed.
2995 SimulateWheelEvent(125, -5, 0, true);
2996 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
2997 SendInputEventACK(WebInputEvent::MouseWheel,
2998 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
2999 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
3000 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
3001 EXPECT_EQ(0U, sink_->message_count());
3003 // Send another wheel event, but in the reverse direction. The overscroll
3004 // controller will not consume the event, because it is not triggering
3005 // gesture-nav.
3006 SimulateWheelEvent(-260, 0, 0, true);
3007 EXPECT_EQ(1U, sink_->message_count());
3008 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
3010 // Since the overscroll mode has been reset, the next wheel event should reach
3011 // the renderer.
3012 SimulateWheelEvent(-20, 0, 0, true);
3013 EXPECT_EQ(1U, sink_->message_count());
3014 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
3017 // Tests that if a mouse-move event completes the overscroll gesture, future
3018 // move events do reach the renderer.
3019 TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollMouseMoveCompletion) {
3020 SetUpOverscrollEnvironment();
3022 SimulateWheelEvent(5, 0, 0, true); // sent directly
3023 SimulateWheelEvent(-1, 0, 0, true); // enqueued
3024 SimulateWheelEvent(-10, -3, 0, true); // coalesced into previous event
3025 SimulateWheelEvent(-15, -1, 0, true); // coalesced into previous event
3026 SimulateWheelEvent(-30, -3, 0, true); // coalesced into previous event
3027 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
3028 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3030 // Receive ACK the first wheel event as not processed.
3031 SendInputEventACK(WebInputEvent::MouseWheel,
3032 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3033 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
3034 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
3035 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3037 // Receive ACK for the second (coalesced) event as not processed. This will
3038 // start an overcroll gesture.
3039 SendInputEventACK(WebInputEvent::MouseWheel,
3040 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3041 EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
3042 EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode());
3043 EXPECT_EQ(0U, sink_->message_count());
3045 // Send a mouse-move event. This should cancel the overscroll navigation
3046 // (since the amount overscrolled is not above the threshold), and so the
3047 // mouse-move should reach the renderer.
3048 SimulateMouseMove(5, 10, 0);
3049 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
3050 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
3051 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
3052 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3054 SendInputEventACK(WebInputEvent::MouseMove,
3055 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3057 // Moving the mouse more should continue to send the events to the renderer.
3058 SimulateMouseMove(5, 10, 0);
3059 SendInputEventACK(WebInputEvent::MouseMove,
3060 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3061 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3063 // Now try with gestures.
3064 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
3065 blink::WebGestureDeviceTouchscreen);
3066 SimulateGestureScrollUpdateEvent(300, -5, 0);
3067 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
3068 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3069 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
3070 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
3071 sink_->ClearMessages();
3073 // Overscroll gesture is in progress. Send a mouse-move now. This should
3074 // complete the gesture (because the amount overscrolled is above the
3075 // threshold).
3076 SimulateMouseMove(5, 10, 0);
3077 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
3078 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
3079 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
3080 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3081 SendInputEventACK(WebInputEvent::MouseMove,
3082 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3084 SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
3085 blink::WebGestureDeviceTouchscreen);
3086 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
3087 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3089 // Move mouse some more. The mouse-move events should reach the renderer.
3090 SimulateMouseMove(5, 10, 0);
3091 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3093 SendInputEventACK(WebInputEvent::MouseMove,
3094 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3097 // Tests that if a page scrolled, then the overscroll controller's states are
3098 // reset after the end of the scroll.
3099 TEST_F(RenderWidgetHostViewAuraOverscrollTest,
3100 OverscrollStateResetsAfterScroll) {
3101 SetUpOverscrollEnvironment();
3103 SimulateWheelEvent(0, 5, 0, true); // sent directly
3104 SimulateWheelEvent(0, 30, 0, true); // enqueued
3105 SimulateWheelEvent(0, 40, 0, true); // coalesced into previous event
3106 SimulateWheelEvent(0, 10, 0, true); // coalesced into previous event
3107 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
3108 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3110 // The first wheel event is consumed. Dispatches the queued wheel event.
3111 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
3112 EXPECT_TRUE(ScrollStateIsContentScrolling());
3113 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3115 // The second wheel event is consumed.
3116 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
3117 EXPECT_TRUE(ScrollStateIsContentScrolling());
3119 // Touchpad scroll can end with a zero-velocity fling. But it is not
3120 // dispatched, but it should still reset the overscroll controller state.
3121 SimulateGestureFlingStartEvent(0.f, 0.f, blink::WebGestureDeviceTouchpad);
3122 EXPECT_TRUE(ScrollStateIsUnknown());
3123 EXPECT_EQ(0U, sink_->message_count());
3125 SimulateWheelEvent(-5, 0, 0, true); // sent directly
3126 SimulateWheelEvent(-60, 0, 0, true); // enqueued
3127 SimulateWheelEvent(-100, 0, 0, true); // coalesced into previous event
3128 EXPECT_TRUE(ScrollStateIsUnknown());
3129 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3131 // The first wheel scroll did not scroll content. Overscroll should not start
3132 // yet, since enough hasn't been scrolled.
3133 SendInputEventACK(WebInputEvent::MouseWheel,
3134 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3135 EXPECT_TRUE(ScrollStateIsUnknown());
3136 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3138 SendInputEventACK(WebInputEvent::MouseWheel,
3139 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3140 EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
3141 EXPECT_TRUE(ScrollStateIsOverscrolling());
3142 EXPECT_EQ(0U, sink_->message_count());
3144 SimulateGestureFlingStartEvent(0.f, 0.f, blink::WebGestureDeviceTouchpad);
3145 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
3146 EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->completed_mode());
3147 EXPECT_TRUE(ScrollStateIsUnknown());
3148 EXPECT_EQ(0U, sink_->message_count());
3151 TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollResetsOnBlur) {
3152 SetUpOverscrollEnvironment();
3154 // Start an overscroll with gesture scroll. In the middle of the scroll, blur
3155 // the host.
3156 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
3157 blink::WebGestureDeviceTouchscreen);
3158 SimulateGestureScrollUpdateEvent(300, -5, 0);
3159 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
3160 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3161 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
3162 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
3163 EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
3165 view_->OnWindowFocused(NULL, view_->GetAttachedWindow());
3166 EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
3167 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
3168 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
3169 EXPECT_EQ(0.f, overscroll_delegate()->delta_x());
3170 EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
3171 sink_->ClearMessages();
3173 SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
3174 blink::WebGestureDeviceTouchscreen);
3175 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3177 // Start a scroll gesture again. This should correctly start the overscroll
3178 // after the threshold.
3179 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
3180 blink::WebGestureDeviceTouchscreen);
3181 SimulateGestureScrollUpdateEvent(300, -5, 0);
3182 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
3183 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
3184 EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
3185 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
3186 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
3188 SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
3189 blink::WebGestureDeviceTouchscreen);
3190 EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
3191 EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
3192 EXPECT_EQ(3U, sink_->message_count());
3195 // Tests that when view initiated shutdown happens (i.e. RWHView is deleted
3196 // before RWH), we clean up properly and don't leak the RWHVGuest.
3197 TEST_F(RenderWidgetHostViewGuestAuraTest, GuestViewDoesNotLeak) {
3198 view_->InitAsChild(NULL);
3199 TearDownEnvironment();
3200 ASSERT_FALSE(guest_view_weak_.get());
3203 // Tests that invalid touch events are consumed and handled
3204 // synchronously.
3205 TEST_F(RenderWidgetHostViewAuraTest,
3206 InvalidEventsHaveSyncHandlingDisabled) {
3207 view_->InitAsChild(NULL);
3208 view_->Show();
3209 GetSentMessageCountAndResetSink();
3211 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
3213 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), 0,
3214 ui::EventTimeForNow());
3216 // Construct a move with a touch id which doesn't exist.
3217 ui::TouchEvent invalid_move(ui::ET_TOUCH_MOVED, gfx::Point(30, 30), 1,
3218 ui::EventTimeForNow());
3220 // Valid press is handled asynchronously.
3221 view_->OnTouchEvent(&press);
3222 EXPECT_TRUE(press.synchronous_handling_disabled());
3223 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
3224 AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_CONSUMED);
3226 // Invalid move is handled synchronously, but is consumed. It should not
3227 // be forwarded to the renderer.
3228 view_->OnTouchEvent(&invalid_move);
3229 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
3230 EXPECT_FALSE(invalid_move.synchronous_handling_disabled());
3231 EXPECT_TRUE(invalid_move.stopped_propagation());
3234 // Checks key event codes.
3235 TEST_F(RenderWidgetHostViewAuraTest, KeyEvent) {
3236 view_->InitAsChild(NULL);
3237 view_->Show();
3239 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::KEY_A,
3240 ui::EF_NONE);
3241 view_->OnKeyEvent(&key_event);
3243 const NativeWebKeyboardEvent* event = delegate_.last_event();
3244 EXPECT_NE(nullptr, event);
3245 if (event) {
3246 EXPECT_EQ(key_event.key_code(), event->windowsKeyCode);
3247 EXPECT_EQ(ui::KeycodeConverter::DomCodeToNativeKeycode(key_event.code()),
3248 event->nativeKeyCode);
3252 TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) {
3253 view_->InitAsChild(NULL);
3254 view_->Show();
3256 sink_->ClearMessages();
3258 // Simulates the mouse wheel event with ctrl modifier applied.
3259 ui::MouseWheelEvent event(gfx::Vector2d(1, 1), gfx::Point(), gfx::Point(),
3260 ui::EventTimeForNow(), ui::EF_CONTROL_DOWN, 0);
3261 view_->OnMouseEvent(&event);
3263 const WebInputEvent* input_event =
3264 GetInputEventFromMessage(*sink_->GetMessageAt(0));
3265 const WebMouseWheelEvent* wheel_event =
3266 static_cast<const WebMouseWheelEvent*>(input_event);
3267 // Check if the canScroll set to false when ctrl-scroll is generated from
3268 // mouse wheel event.
3269 EXPECT_FALSE(wheel_event->canScroll);
3270 sink_->ClearMessages();
3272 // Ack'ing the outstanding event should flush the pending event queue.
3273 SendInputEventACK(blink::WebInputEvent::MouseWheel,
3274 INPUT_EVENT_ACK_STATE_CONSUMED);
3276 // Simulates the mouse wheel event with no modifier applied.
3277 event = ui::MouseWheelEvent(gfx::Vector2d(1, 1), gfx::Point(), gfx::Point(),
3278 ui::EventTimeForNow(), ui::EF_NONE, 0);
3280 view_->OnMouseEvent(&event);
3282 input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
3283 wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
3284 // Check if the canScroll set to true when no modifier is applied to the
3285 // mouse wheel event.
3286 EXPECT_TRUE(wheel_event->canScroll);
3287 sink_->ClearMessages();
3289 SendInputEventACK(blink::WebInputEvent::MouseWheel,
3290 INPUT_EVENT_ACK_STATE_CONSUMED);
3292 // Simulates the scroll event with ctrl modifier applied.
3293 ui::ScrollEvent scroll(ui::ET_SCROLL, gfx::Point(2, 2), ui::EventTimeForNow(),
3294 ui::EF_CONTROL_DOWN, 0, 5, 0, 5, 2);
3295 view_->OnScrollEvent(&scroll);
3297 input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
3298 wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
3299 // Check if the canScroll set to true when ctrl-touchpad-scroll is generated
3300 // from scroll event.
3301 EXPECT_TRUE(wheel_event->canScroll);
3304 // Ensures that the mapping from ui::TouchEvent to blink::WebTouchEvent doesn't
3305 // lose track of the number of acks required.
3306 TEST_F(RenderWidgetHostViewAuraTest, CorrectNumberOfAcksAreDispatched) {
3307 view_->InitAsFullscreen(parent_view_);
3308 view_->Show();
3309 view_->UseFakeDispatcher();
3311 ui::TouchEvent press1(
3312 ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), 0, ui::EventTimeForNow());
3314 view_->OnTouchEvent(&press1);
3315 SendInputEventACK(blink::WebInputEvent::TouchStart,
3316 INPUT_EVENT_ACK_STATE_CONSUMED);
3318 ui::TouchEvent press2(
3319 ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), 1, ui::EventTimeForNow());
3320 view_->OnTouchEvent(&press2);
3321 SendInputEventACK(blink::WebInputEvent::TouchStart,
3322 INPUT_EVENT_ACK_STATE_CONSUMED);
3324 EXPECT_EQ(2U, view_->dispatcher_->processed_touch_event_count());
3327 } // namespace content