Home | History | Annotate | Download | only in corewm
      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 
     28 namespace views {
     29 
     30 class 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.
     48 class 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 
     71 views::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.
     87 TEST_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.
    112 TEST_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