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"
71 using blink::WebGestureEvent
;
72 using blink::WebInputEvent
;
73 using blink::WebMouseEvent
;
74 using blink::WebMouseWheelEvent
;
75 using blink::WebTouchEvent
;
76 using blink::WebTouchPoint
;
81 class TestOverscrollDelegate
: public OverscrollControllerDelegate
{
83 explicit TestOverscrollDelegate(RenderWidgetHostView
* view
)
85 current_mode_(OVERSCROLL_NONE
),
86 completed_mode_(OVERSCROLL_NONE
),
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_
; }
98 current_mode_
= OVERSCROLL_NONE
;
99 completed_mode_
= OVERSCROLL_NONE
;
100 delta_x_
= delta_y_
= 0.f
;
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
{
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_
;
134 DISALLOW_COPY_AND_ASSIGN(TestOverscrollDelegate
);
137 class MockRenderWidgetHostDelegate
: public RenderWidgetHostDelegate
{
139 MockRenderWidgetHostDelegate() {}
140 ~MockRenderWidgetHostDelegate() override
{}
141 const NativeWebKeyboardEvent
* last_event() const { return last_event_
.get(); }
143 // RenderWidgetHostDelegate:
144 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent
& event
,
145 bool* is_keyboard_shortcut
) override
{
146 last_event_
.reset(new NativeWebKeyboardEvent(event
));
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
{
157 explicit TestWindowObserver(aura::Window
* window_to_observe
)
158 : window_(window_to_observe
) {
159 window_
->AddObserver(this);
161 ~TestWindowObserver() override
{
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_
);
176 // Window that we're observing, or NULL if it's been destroyed.
177 aura::Window
* window_
;
179 // Was |window_| destroyed?
182 DISALLOW_COPY_AND_ASSIGN(TestWindowObserver
);
185 class FakeFrameSubscriber
: public RenderWidgetHostViewFrameSubscriber
{
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
,
199 *callback
= base::Bind(&FakeFrameSubscriber::CallbackMethod
, callback_
);
203 static void CallbackMethod(base::Callback
<void(bool)> callback
,
204 base::TimeTicks timestamp
,
206 callback
.Run(success
);
211 base::Callback
<void(bool)> callback_
;
214 class FakeWindowEventDispatcher
: public aura::WindowEventDispatcher
{
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_
;
231 size_t processed_touch_event_count_
;
234 class FakeRenderWidgetHostViewAura
: public RenderWidgetHostViewAura
{
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
294 class FakeResizeLock
: public ResizeLock
{
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) {
304 new blink::WebTouchEvent(ui::CreateWebTouchEventFromMotionEvent(
305 pointer_state(), event
->may_cause_scrolling())));
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
{
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()));
346 aura::Window
* owner_
;
347 DISALLOW_COPY_AND_ASSIGN(FullscreenLayoutManager
);
350 class MockWindowObserver
: public aura::WindowObserver
{
352 MOCK_METHOD2(OnDelegatedFrameDamage
, void(aura::Window
*, const gfx::Rect
&));
355 const WebInputEvent
* GetInputEventFromMessage(const IPC::Message
& message
) {
356 PickleIterator
iter(message
);
359 if (!iter
.ReadData(&data
, &data_length
))
361 return reinterpret_cast<const WebInputEvent
*>(data
);
366 class RenderWidgetHostViewAuraTest
: public testing::Test
{
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(),
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() {
404 process_host_
= NULL
;
408 if (widget_host_uses_shutdown_to_destroy_
)
409 widget_host_
->Shutdown();
413 parent_view_
->Destroy();
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
;
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();
459 void AckLastSentInputEventIfNecessary(InputEventAckState ack_result
) {
460 if (!sink_
->message_count())
463 InputMsg_HandleInputEvent::Param params
;
464 if (!InputMsg_HandleInputEvent::Read(
465 sink_
->GetMessageAt(sink_
->message_count() - 1), ¶ms
)) {
469 if (WebInputEventTraits::IgnoresAckDisposition(*get
<0>(params
)))
472 SendInputEventACK(get
<0>(params
)->type
, ack_result
);
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
490 RenderWidgetHostImpl
* parent_host_
;
491 RenderWidgetHostViewAura
* parent_view_
;
493 // Tests should set these to NULL if they've already triggered their
495 RenderWidgetHostImpl
* widget_host_
;
496 FakeRenderWidgetHostViewAura
* view_
;
498 IPC::TestSink
* sink_
;
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
{
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.
531 base::WeakPtr
<RenderWidgetHostViewBase
> guest_view_weak_
;
535 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewGuestAuraTest
);
538 class RenderWidgetHostViewAuraOverscrollTest
539 : public RenderWidgetHostViewAuraTest
{
541 RenderWidgetHostViewAuraOverscrollTest() {}
543 // We explicitly invoke SetUp to allow gesture debounce customization.
544 void SetUp() override
{}
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));
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
,
590 const ui::LatencyInfo
& ui_latency
) {
591 widget_host_
->ForwardWheelEventWithLatencyInfo(
592 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
),
596 void SimulateMouseMove(int x
, int y
, int modifiers
) {
597 SimulateMouseEvent(WebInputEvent::MouseMove
, x
, y
, modifiers
, false);
600 void SimulateMouseEvent(WebInputEvent::Type type
,
605 WebMouseEvent event
=
606 SyntheticWebMouseEventBuilder::Build(type
, x
, y
, modifiers
);
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
,
651 SimulateGestureEventCore(SyntheticWebGestureEventBuilder::BuildPinchUpdate(
656 blink::WebGestureDeviceTouchscreen
));
659 // Inject synthetic GestureFlingStart events.
660 void SimulateGestureFlingStartEvent(float velocityX
,
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_
,
702 touch_event_
.ResetPoints();
705 void PressTouchPoint(int x
, int y
) {
706 touch_event_
.PressPoint(x
, y
);
710 void MoveTouchPoint(int index
, int x
, int y
) {
711 touch_event_
.MovePoint(index
, x
, y
);
715 void ReleaseTouchPoint(int index
) {
716 touch_event_
.ReleasePoint(index
);
720 SyntheticWebTouchEvent touch_event_
;
722 scoped_ptr
<TestOverscrollDelegate
> overscroll_delegate_
;
725 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraOverscrollTest
);
728 class RenderWidgetHostViewAuraShutdownTest
729 : public RenderWidgetHostViewAuraTest
{
731 RenderWidgetHostViewAuraShutdownTest() {}
733 void TearDown() override
{
734 // No TearDownEnvironment here, we do this explicitly during the test.
738 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraShutdownTest
);
741 // Checks that a fullscreen view has the correct show-state and receives the
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
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
);
810 window
->parent()->AddChild(sibling
.get());
812 ASSERT_TRUE(sibling
->HasFocus());
813 ASSERT_TRUE(observer
.destroyed());
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());
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());
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());
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());
927 // Checks that IME-composition-event state is maintained correctly.
928 TEST_F(RenderWidgetHostViewAuraTest
, SetCompositionText
) {
929 view_
->InitAsChild(NULL
);
932 ui::CompositionText composition_text
;
933 composition_text
.text
= base::ASCIIToUTF16("|a|b");
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
, ¶ms
);
959 EXPECT_EQ(composition_text
.text
, get
<0>(params
));
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
);
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
);
985 ui::CompositionText composition_text
;
986 composition_text
.text
= base::ASCIIToUTF16("|a|b");
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
);
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
,
1034 ui::EventTimeForNow());
1035 ui::TouchEvent
move(ui::ET_TOUCH_MOVED
,
1038 ui::EventTimeForNow());
1039 ui::TouchEvent
release(ui::ET_TOUCH_RELEASED
,
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
);
1133 widget_host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1135 ui::TouchEvent
press(ui::ET_TOUCH_PRESSED
,
1138 ui::EventTimeForNow());
1139 ui::TouchEvent
move(ui::ET_TOUCH_MOVED
,
1142 ui::EventTimeForNow());
1143 ui::TouchEvent
release(ui::ET_TOUCH_RELEASED
,
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(),
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
, ¶ms
);
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
, ¶ms
);
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
, ¶ms
);
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(),
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.
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.
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();
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.
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();
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(),
1324 // Note that all coordinates in this test are screen coordinates.
1325 view_
->SetBounds(gfx::Rect(60, 60, 100, 100));
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
,
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();
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_
);
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
, ¶ms
);
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(
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
, ¶ms
);
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(
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(),
1441 view_
->SetSize(view_size
);
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(),
1472 view_
->SetSize(view_size
);
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
));
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
, ¶ms
);
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
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
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());
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
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
, ¶ms
);
1579 const blink::WebInputEvent
* event
= get
<0>(params
);
1580 EXPECT_EQ(blink::WebInputEvent::MouseMove
, event
->type
);
1583 case ViewMsg_SwapCompositorFrameAck::ID
:
1585 case ViewMsg_Resize::ID
: {
1586 EXPECT_FALSE(has_resize
);
1587 ViewMsg_Resize::Param params
;
1588 ViewMsg_Resize::Read(msg
, ¶ms
);
1589 EXPECT_EQ(size3
.ToString(), get
<0>(params
).new_size
.ToString());
1594 ADD_FAILURE() << "Unexpected message " << msg
->type();
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(),
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(),
1702 view_
->SetSize(view_rect
.size());
1704 MockWindowObserver observer
;
1705 view_
->window_
->AddObserver(&observer
);
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);
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(),
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
) {
1770 views
[i
]->OnSwapCompositorFrame(
1771 1, MakeDelegatedFrame(1.f
, frame_size
, view_rect
));
1772 EXPECT_TRUE(views
[i
]->HasFrameData());
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.
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
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());
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
) {
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.
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.
1844 EXPECT_FALSE(views
[0]->HasFrameData());
1846 // Make [0] visible, don't give it a frame, it should be waiting.
1848 EXPECT_TRUE(views
[0]->released_front_lock_active());
1849 // Make [0] hidden, it should stop waiting.
1851 EXPECT_FALSE(views
[0]->released_front_lock_active());
1853 // Make [1] hidden, resize it. It should drop its frame.
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.
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
)
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());
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();
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);
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(),
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
) {
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.
1941 EXPECT_FALSE(views
[0]->HasFrameData());
1943 // If we lock [0] before hiding it, then [0] should not be evicted.
1945 views
[0]->OnSwapCompositorFrame(
1946 1, MakeDelegatedFrame(1.f
, frame_size
, view_rect
));
1947 EXPECT_TRUE(views
[0]->HasFrameData());
1948 views
[0]->GetDelegatedFrameHost()->LockResources();
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();
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);
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(),
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
) {
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.
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.
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();
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(),
2037 view_
->SetSize(view_rect
.size());
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
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());
2060 EXPECT_NE(surface_id
, view_
->surface_id());
2063 class RenderWidgetHostViewAuraCopyRequestTest
2064 : public RenderWidgetHostViewAuraShutdownTest
{
2066 RenderWidgetHostViewAuraCopyRequestTest()
2067 : callback_count_(0), result_(false) {}
2069 void CallbackMethod(bool result
) {
2072 quit_closure_
.Run();
2075 void RunLoopUntilCallback() {
2076 base::RunLoop run_loop
;
2077 quit_closure_
= run_loop
.QuitClosure();
2081 int callback_count_
;
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(),
2106 view_
->SetSize(view_rect
.size());
2109 view_
->BeginFrameSubscription(make_scoped_ptr(new FakeFrameSubscriber(
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
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();
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(),
2189 view_
->SetSize(view_rect
.size());
2192 scoped_ptr
<FakeFrameSubscriber
> frame_subscriber(new FakeFrameSubscriber(
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(),
2254 view_
->SetSize(view_rect
.size());
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
, ¶ms
);
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
);
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
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
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
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
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
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
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
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
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(
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
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(
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
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());
2908 SimulateGestureEvent(blink::WebInputEvent::GestureScrollEnd
,
2909 blink::WebGestureDeviceTouchscreen
);
2910 EXPECT_EQ(0U, sink_
->message_count());
2911 base::MessageLoop::current()->PostDelayedTask(
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());
2944 SimulateGestureEvent(blink::WebInputEvent::GestureScrollEnd
,
2945 blink::WebGestureDeviceTouchscreen
);
2946 EXPECT_EQ(0U, sink_
->message_count());
2947 base::MessageLoop::current()->PostDelayedTask(
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
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
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
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
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
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
3205 TEST_F(RenderWidgetHostViewAuraTest
,
3206 InvalidEventsHaveSyncHandlingDisabled
) {
3207 view_
->InitAsChild(NULL
);
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
);
3239 ui::KeyEvent
key_event(ui::ET_KEY_PRESSED
, ui::VKEY_A
, ui::DomCode::KEY_A
,
3241 view_
->OnKeyEvent(&key_event
);
3243 const NativeWebKeyboardEvent
* event
= delegate_
.last_event();
3244 EXPECT_NE(nullptr, 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
);
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_
);
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 // Tests that the scroll deltas stored within the overscroll controller get
3328 // reset at the end of the overscroll gesture even if the overscroll threshold
3329 // isn't surpassed and the overscroll mode stays OVERSCROLL_NONE.
3330 TEST_F(RenderWidgetHostViewAuraOverscrollTest
, ScrollDeltasResetOnEnd
) {
3331 SetUpOverscrollEnvironment();
3332 // Wheel event scroll ending with mouse move.
3333 SimulateWheelEvent(-30, -10, 0, true); // sent directly
3334 SendInputEventACK(WebInputEvent::MouseWheel
,
3335 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
3336 EXPECT_EQ(OVERSCROLL_NONE
, overscroll_mode());
3337 EXPECT_EQ(-30.f
, overscroll_delta_x());
3338 EXPECT_EQ(-10.f
, overscroll_delta_y());
3339 SimulateMouseMove(5, 10, 0);
3340 EXPECT_EQ(0.f
, overscroll_delta_x());
3341 EXPECT_EQ(0.f
, overscroll_delta_y());
3344 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
3345 blink::WebGestureDeviceTouchscreen
);
3346 SimulateGestureScrollUpdateEvent(-30, -5, 0);
3347 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
3348 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
3349 EXPECT_EQ(OVERSCROLL_NONE
, overscroll_mode());
3350 EXPECT_EQ(-30.f
, overscroll_delta_x());
3351 EXPECT_EQ(-5.f
, overscroll_delta_y());
3352 SimulateGestureEvent(WebInputEvent::GestureScrollEnd
,
3353 blink::WebGestureDeviceTouchscreen
);
3354 EXPECT_EQ(0.f
, overscroll_delta_x());
3355 EXPECT_EQ(0.f
, overscroll_delta_y());
3357 // Wheel event scroll ending with a fling.
3358 SimulateWheelEvent(5, 0, 0, true);
3359 SendInputEventACK(WebInputEvent::MouseWheel
,
3360 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
3361 SimulateWheelEvent(10, -5, 0, true);
3362 SendInputEventACK(WebInputEvent::MouseWheel
,
3363 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
3364 EXPECT_EQ(OVERSCROLL_NONE
, overscroll_mode());
3365 EXPECT_EQ(15.f
, overscroll_delta_x());
3366 EXPECT_EQ(-5.f
, overscroll_delta_y());
3367 SimulateGestureFlingStartEvent(0.f
, 0.1f
, blink::WebGestureDeviceTouchpad
);
3368 EXPECT_EQ(0.f
, overscroll_delta_x());
3369 EXPECT_EQ(0.f
, overscroll_delta_y());
3372 } // namespace content