1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/wm/core/capture_controller.h" 6 7#include "base/logging.h" 8#include "base/path_service.h" 9#include "ui/aura/env.h" 10#include "ui/aura/test/test_window_delegate.h" 11#include "ui/aura/window_event_dispatcher.h" 12#include "ui/aura/window_tree_host.h" 13#include "ui/base/resource/resource_bundle.h" 14#include "ui/base/ui_base_paths.h" 15#include "ui/events/event.h" 16#include "ui/events/test/event_generator.h" 17#include "ui/gl/gl_surface.h" 18#include "ui/views/test/views_test_base.h" 19#include "ui/views/view.h" 20#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" 21#include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" 22#include "ui/views/widget/root_view.h" 23#include "ui/views/widget/widget.h" 24 25// NOTE: these tests do native capture, so they have to be in 26// interactive_ui_tests. 27 28namespace views { 29 30class DesktopCaptureControllerTest : public ViewsTestBase { 31 public: 32 DesktopCaptureControllerTest() {} 33 virtual ~DesktopCaptureControllerTest() {} 34 35 virtual void SetUp() OVERRIDE { 36 gfx::GLSurface::InitializeOneOffForTests(); 37 ui::RegisterPathProvider(); 38 base::FilePath ui_test_pak_path; 39 ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path)); 40 ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path); 41 42 ViewsTestBase::SetUp(); 43 } 44}; 45 46// This class provides functionality to verify whether the View instance 47// received the gesture event. 48class DesktopViewInputTest : public View { 49 public: 50 DesktopViewInputTest() 51 : received_gesture_event_(false) {} 52 53 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { 54 received_gesture_event_ = true; 55 return View::OnGestureEvent(event); 56 } 57 58 // Resets state maintained by this class. 59 void Reset() { 60 received_gesture_event_ = false; 61 } 62 63 bool received_gesture_event() const { return received_gesture_event_; } 64 65 private: 66 bool received_gesture_event_; 67 68 DISALLOW_COPY_AND_ASSIGN(DesktopViewInputTest); 69}; 70 71views::Widget* CreateWidget() { 72 views::Widget* widget = new views::Widget; 73 views::Widget::InitParams params; 74 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; 75 params.accept_events = true; 76 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 77 params.native_widget = new DesktopNativeWidgetAura(widget); 78 params.bounds = gfx::Rect(0, 0, 200, 100); 79 widget->Init(params); 80 widget->Show(); 81 return widget; 82} 83 84// Verifies mouse handlers are reset when a window gains capture. Specifically 85// creates two widgets, does a mouse press in one, sets capture in the other and 86// verifies state is reset in the first. 87TEST_F(DesktopCaptureControllerTest, ResetMouseHandlers) { 88 scoped_ptr<Widget> w1(CreateWidget()); 89 scoped_ptr<Widget> w2(CreateWidget()); 90 ui::test::EventGenerator generator1(w1->GetNativeView()->GetRootWindow()); 91 generator1.MoveMouseToCenterOf(w1->GetNativeView()); 92 generator1.PressLeftButton(); 93 EXPECT_FALSE(w1->HasCapture()); 94 aura::WindowEventDispatcher* w1_dispatcher = 95 w1->GetNativeView()->GetHost()->dispatcher(); 96 EXPECT_TRUE(w1_dispatcher->mouse_pressed_handler() != NULL); 97 EXPECT_TRUE(w1_dispatcher->mouse_moved_handler() != NULL); 98 w2->SetCapture(w2->GetRootView()); 99 EXPECT_TRUE(w2->HasCapture()); 100 EXPECT_TRUE(w1_dispatcher->mouse_pressed_handler() == NULL); 101 EXPECT_TRUE(w1_dispatcher->mouse_moved_handler() == NULL); 102 w2->ReleaseCapture(); 103 RunPendingMessages(); 104} 105 106// Tests aura::Window capture and whether gesture events are sent to the window 107// which has capture. 108// The test case creates two visible widgets and sets capture to the underlying 109// aura::Windows one by one. It then sends a gesture event and validates whether 110// the window which had capture receives the gesture. 111// TODO(sky): move this test, it should be part of ScopedCaptureClient tests. 112TEST_F(DesktopCaptureControllerTest, CaptureWindowInputEventTest) { 113 scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client1; 114 scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client2; 115 116 scoped_ptr<Widget> widget1(new Widget()); 117 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 118 scoped_ptr<wm::ScopedCaptureClient> scoped_capture_client( 119 new wm::ScopedCaptureClient(params.context->GetRootWindow())); 120 aura::client::CaptureClient* capture_client = 121 scoped_capture_client->capture_client(); 122 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 123 params.bounds = gfx::Rect(50, 50, 650, 650); 124 widget1->Init(params); 125 internal::RootView* root1 = 126 static_cast<internal::RootView*>(widget1->GetRootView()); 127 128 desktop_position_client1.reset( 129 new DesktopScreenPositionClient(params.context->GetRootWindow())); 130 aura::client::SetScreenPositionClient( 131 widget1->GetNativeView()->GetRootWindow(), 132 desktop_position_client1.get()); 133 134 DesktopViewInputTest* v1 = new DesktopViewInputTest(); 135 v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300)); 136 root1->AddChildView(v1); 137 widget1->Show(); 138 139 scoped_ptr<Widget> widget2(new Widget()); 140 141 params = CreateParams(Widget::InitParams::TYPE_POPUP); 142 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 143 params.bounds = gfx::Rect(50, 50, 650, 650); 144 widget2->Init(params); 145 146 internal::RootView* root2 = 147 static_cast<internal::RootView*>(widget2->GetRootView()); 148 desktop_position_client2.reset( 149 new DesktopScreenPositionClient(params.context->GetRootWindow())); 150 aura::client::SetScreenPositionClient( 151 widget2->GetNativeView()->GetRootWindow(), 152 desktop_position_client2.get()); 153 ui::EventDispatchDetails details; 154 155 DesktopViewInputTest* v2 = new DesktopViewInputTest(); 156 v2->SetBoundsRect(gfx::Rect(0, 0, 300, 300)); 157 root2->AddChildView(v2); 158 widget2->Show(); 159 160 EXPECT_FALSE(widget1->GetNativeView()->HasCapture()); 161 EXPECT_FALSE(widget2->GetNativeView()->HasCapture()); 162 EXPECT_EQ(reinterpret_cast<aura::Window*>(0), 163 capture_client->GetCaptureWindow()); 164 165 widget1->GetNativeView()->SetCapture(); 166 EXPECT_TRUE(widget1->GetNativeView()->HasCapture()); 167 EXPECT_FALSE(widget2->GetNativeView()->HasCapture()); 168 EXPECT_EQ(capture_client->GetCaptureWindow(), widget1->GetNativeView()); 169 170 ui::GestureEvent g1(80, 171 80, 172 0, 173 base::TimeDelta(), 174 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS)); 175 details = root1->OnEventFromSource(&g1); 176 EXPECT_FALSE(details.dispatcher_destroyed); 177 EXPECT_FALSE(details.target_destroyed); 178 179 EXPECT_TRUE(v1->received_gesture_event()); 180 EXPECT_FALSE(v2->received_gesture_event()); 181 v1->Reset(); 182 v2->Reset(); 183 184 widget2->GetNativeView()->SetCapture(); 185 186 EXPECT_FALSE(widget1->GetNativeView()->HasCapture()); 187 EXPECT_TRUE(widget2->GetNativeView()->HasCapture()); 188 EXPECT_EQ(capture_client->GetCaptureWindow(), widget2->GetNativeView()); 189 190 details = root2->OnEventFromSource(&g1); 191 EXPECT_FALSE(details.dispatcher_destroyed); 192 EXPECT_FALSE(details.target_destroyed); 193 194 EXPECT_TRUE(v2->received_gesture_event()); 195 EXPECT_FALSE(v1->received_gesture_event()); 196 197 widget1->CloseNow(); 198 widget2->CloseNow(); 199 RunPendingMessages(); 200} 201 202} // namespace views 203