Home | History | Annotate | Download | only in desktop_aura
      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/views/widget/desktop_aura/desktop_capture_client.h"
      6 
      7 #include "ui/aura/root_window.h"
      8 #include "ui/aura/test/aura_test_base.h"
      9 #include "ui/aura/test/test_screen.h"
     10 #include "ui/aura/test/test_window_delegate.h"
     11 #include "ui/base/events/event.h"
     12 #include "ui/views/test/views_test_base.h"
     13 #include "ui/views/view.h"
     14 #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
     15 #include "ui/views/widget/root_view.h"
     16 #include "ui/views/widget/widget.h"
     17 
     18 namespace views {
     19 
     20 typedef ViewsTestBase ViewTest;
     21 
     22 class DesktopCaptureClientTest : public aura::test::AuraTestBase {
     23  public:
     24   virtual void SetUp() OVERRIDE {
     25     AuraTestBase::SetUp();
     26     desktop_capture_client_.reset(new DesktopCaptureClient(root_window()));
     27 
     28     second_root_.reset(new aura::RootWindow(
     29         aura::RootWindow::CreateParams(gfx::Rect(0, 0, 800, 600))));
     30     second_root_->Init();
     31     second_root_->Show();
     32     second_root_->SetHostSize(gfx::Size(800, 600));
     33     second_desktop_capture_client_.reset(
     34       new DesktopCaptureClient(second_root_.get()));
     35 
     36     desktop_position_client_.reset(new DesktopScreenPositionClient());
     37     aura::client::SetScreenPositionClient(root_window(),
     38                                           desktop_position_client_.get());
     39 
     40     second_desktop_position_client_.reset(new DesktopScreenPositionClient());
     41     aura::client::SetScreenPositionClient(
     42         second_root_.get(),
     43         second_desktop_position_client_.get());
     44   }
     45 
     46   virtual void TearDown() OVERRIDE {
     47     RunAllPendingInMessageLoop();
     48 
     49     second_desktop_position_client_.reset();
     50     second_desktop_capture_client_.reset();
     51 
     52     // Kill any active compositors before we hit the compositor shutdown paths.
     53     second_root_.reset();
     54 
     55     desktop_position_client_.reset();
     56     desktop_capture_client_.reset();
     57 
     58     AuraTestBase::TearDown();
     59   }
     60 
     61   scoped_ptr<DesktopCaptureClient> desktop_capture_client_;
     62   scoped_ptr<aura::RootWindow> second_root_;
     63   scoped_ptr<DesktopCaptureClient> second_desktop_capture_client_;
     64   scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client_;
     65   scoped_ptr<aura::client::ScreenPositionClient>
     66       second_desktop_position_client_;
     67 };
     68 
     69 // Makes sure that internal details that are set on mouse down (such as
     70 // mouse_pressed_handler()) are cleared when another root window takes capture.
     71 TEST_F(DesktopCaptureClientTest, ResetMouseEventHandlerOnCapture) {
     72   // Create a window inside the RootWindow.
     73   scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL));
     74 
     75   // Make a synthesized mouse down event. Ensure that the RootWindow will
     76   // dispatch further mouse events to |w1|.
     77   ui::MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(5, 5),
     78                                      gfx::Point(5, 5), 0);
     79   root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(
     80       &mouse_pressed_event);
     81   EXPECT_EQ(w1.get(), root_window()->mouse_pressed_handler());
     82 
     83   // Build a window in the second RootWindow.
     84   scoped_ptr<aura::Window> w2(CreateNormalWindow(2, second_root_.get(), NULL));
     85 
     86   // The act of having the second window take capture should clear out mouse
     87   // pressed handler in the first RootWindow.
     88   w2->SetCapture();
     89   EXPECT_EQ(NULL, root_window()->mouse_pressed_handler());
     90 }
     91 
     92 // Makes sure that when one window gets capture, it forces the release on the
     93 // other. This is needed has to be handled explicitly on Linux, and is a sanity
     94 // check on Windows.
     95 TEST_F(DesktopCaptureClientTest, ResetOtherWindowCaptureOnCapture) {
     96   // Create a window inside the RootWindow.
     97   scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL));
     98   w1->SetCapture();
     99   // Both capture clients should return the same capture window.
    100   EXPECT_EQ(w1.get(), desktop_capture_client_->GetCaptureWindow());
    101   EXPECT_EQ(w1.get(), second_desktop_capture_client_->GetCaptureWindow());
    102 
    103   // Build a window in the second RootWindow and give it capture. Both capture
    104   // clients should return the same capture window.
    105   scoped_ptr<aura::Window> w2(CreateNormalWindow(2, second_root_.get(), NULL));
    106   w2->SetCapture();
    107   EXPECT_EQ(w2.get(), desktop_capture_client_->GetCaptureWindow());
    108   EXPECT_EQ(w2.get(), second_desktop_capture_client_->GetCaptureWindow());
    109 }
    110 
    111 // This class provides functionality to verify whether the View instance
    112 // received the gesture event.
    113 class DesktopViewInputTest : public View {
    114  public:
    115   DesktopViewInputTest()
    116       : received_gesture_event_(false) {}
    117 
    118   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
    119     received_gesture_event_ = true;
    120     return View::OnGestureEvent(event);
    121   }
    122 
    123   // Resets state maintained by this class.
    124   void Reset() {
    125     received_gesture_event_ = false;
    126   }
    127 
    128   bool received_gesture_event() const { return received_gesture_event_; }
    129 
    130  private:
    131   bool received_gesture_event_;
    132 
    133   DISALLOW_COPY_AND_ASSIGN(DesktopViewInputTest);
    134 };
    135 
    136 // Tests aura::Window capture and whether gesture events are sent to the window
    137 // which has capture.
    138 // The test case creates two visible widgets and sets capture to the underlying
    139 // aura::Windows one by one. It then sends a gesture event and validates whether
    140 // the window which had capture receives the gesture.
    141 TEST_F(ViewTest, CaptureWindowInputEventTest) {
    142   scoped_ptr<DesktopCaptureClient> desktop_capture_client1;
    143   scoped_ptr<DesktopCaptureClient> desktop_capture_client2;
    144   scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client1;
    145   scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client2;
    146 
    147   scoped_ptr<Widget> widget1(new Widget());
    148   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    149   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    150   params.bounds = gfx::Rect(50, 50, 650, 650);
    151   widget1->Init(params);
    152   internal::RootView* root1 =
    153       static_cast<internal::RootView*>(widget1->GetRootView());
    154 
    155   desktop_capture_client1.reset(new DesktopCaptureClient(
    156       widget1->GetNativeView()->GetRootWindow()));
    157   desktop_position_client1.reset(new DesktopScreenPositionClient());
    158   aura::client::SetScreenPositionClient(
    159       widget1->GetNativeView()->GetRootWindow(),
    160       desktop_position_client1.get());
    161 
    162   DesktopViewInputTest* v1 = new DesktopViewInputTest();
    163   v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
    164   root1->AddChildView(v1);
    165   widget1->Show();
    166 
    167   scoped_ptr<Widget> widget2(new Widget());
    168 
    169   params = CreateParams(Widget::InitParams::TYPE_POPUP);
    170   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    171   params.bounds = gfx::Rect(50, 50, 650, 650);
    172   widget2->Init(params);
    173 
    174   internal::RootView* root2 =
    175       static_cast<internal::RootView*>(widget2->GetRootView());
    176   desktop_capture_client2.reset(new DesktopCaptureClient(
    177       widget2->GetNativeView()->GetRootWindow()));
    178   desktop_position_client2.reset(new DesktopScreenPositionClient());
    179   aura::client::SetScreenPositionClient(
    180       widget2->GetNativeView()->GetRootWindow(),
    181       desktop_position_client2.get());
    182 
    183   DesktopViewInputTest* v2 = new DesktopViewInputTest();
    184   v2->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
    185   root2->AddChildView(v2);
    186   widget2->Show();
    187 
    188   EXPECT_FALSE(widget1->GetNativeView()->HasCapture());
    189   EXPECT_FALSE(widget2->GetNativeView()->HasCapture());
    190   EXPECT_EQ(desktop_capture_client1->GetCaptureWindow(),
    191             reinterpret_cast<aura::Window*>(0));
    192   EXPECT_EQ(desktop_capture_client2->GetCaptureWindow(),
    193             reinterpret_cast<aura::Window*>(0));
    194 
    195   widget1->GetNativeView()->SetCapture();
    196   EXPECT_TRUE(widget1->GetNativeView()->HasCapture());
    197   EXPECT_FALSE(widget2->GetNativeView()->HasCapture());
    198   EXPECT_EQ(desktop_capture_client1->GetCaptureWindow(),
    199             widget1->GetNativeView());
    200   EXPECT_EQ(desktop_capture_client2->GetCaptureWindow(),
    201             widget1->GetNativeView());
    202 
    203   ui::GestureEvent g1(ui::ET_GESTURE_LONG_PRESS, 80, 80, 0,
    204                       base::TimeDelta(),
    205                       ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS,
    206                                               0.0f, 0.0f), 0);
    207   root1->DispatchGestureEvent(&g1);
    208   EXPECT_TRUE(v1->received_gesture_event());
    209   EXPECT_FALSE(v2->received_gesture_event());
    210   v1->Reset();
    211   v2->Reset();
    212 
    213   widget2->GetNativeView()->SetCapture();
    214 
    215   EXPECT_FALSE(widget1->GetNativeView()->HasCapture());
    216   EXPECT_TRUE(widget2->GetNativeView()->HasCapture());
    217   EXPECT_EQ(desktop_capture_client1->GetCaptureWindow(),
    218             widget2->GetNativeView());
    219   EXPECT_EQ(desktop_capture_client2->GetCaptureWindow(),
    220             widget2->GetNativeView());
    221 
    222   root2->DispatchGestureEvent(&g1);
    223   EXPECT_TRUE(v2->received_gesture_event());
    224   EXPECT_FALSE(v1->received_gesture_event());
    225 
    226   widget1->CloseNow();
    227   widget2->CloseNow();
    228   RunPendingMessages();
    229 }
    230 
    231 }  // namespace views
    232