blob: d96c445672406cc112e66842bae894c29e638c11 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/widget/desktop_aura/desktop_capture_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/base/events/event.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/view.h"
#include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"
namespace views {
typedef ViewsTestBase ViewTest;
class DesktopCaptureClientTest : public aura::test::AuraTestBase {
public:
virtual void SetUp() OVERRIDE {
AuraTestBase::SetUp();
desktop_capture_client_.reset(new DesktopCaptureClient(root_window()));
second_root_.reset(new aura::RootWindow(
aura::RootWindow::CreateParams(gfx::Rect(0, 0, 800, 600))));
second_root_->Init();
second_root_->Show();
second_root_->SetHostSize(gfx::Size(800, 600));
second_desktop_capture_client_.reset(
new DesktopCaptureClient(second_root_.get()));
desktop_position_client_.reset(new DesktopScreenPositionClient());
aura::client::SetScreenPositionClient(root_window(),
desktop_position_client_.get());
second_desktop_position_client_.reset(new DesktopScreenPositionClient());
aura::client::SetScreenPositionClient(
second_root_.get(),
second_desktop_position_client_.get());
}
virtual void TearDown() OVERRIDE {
RunAllPendingInMessageLoop();
second_desktop_position_client_.reset();
second_desktop_capture_client_.reset();
// Kill any active compositors before we hit the compositor shutdown paths.
second_root_.reset();
desktop_position_client_.reset();
desktop_capture_client_.reset();
AuraTestBase::TearDown();
}
scoped_ptr<DesktopCaptureClient> desktop_capture_client_;
scoped_ptr<aura::RootWindow> second_root_;
scoped_ptr<DesktopCaptureClient> second_desktop_capture_client_;
scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client_;
scoped_ptr<aura::client::ScreenPositionClient>
second_desktop_position_client_;
};
// Makes sure that internal details that are set on mouse down (such as
// mouse_pressed_handler()) are cleared when another root window takes capture.
TEST_F(DesktopCaptureClientTest, ResetMouseEventHandlerOnCapture) {
// Create a window inside the RootWindow.
scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL));
// Make a synthesized mouse down event. Ensure that the RootWindow will
// dispatch further mouse events to |w1|.
ui::MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(5, 5),
gfx::Point(5, 5), 0);
root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(
&mouse_pressed_event);
EXPECT_EQ(w1.get(), root_window()->mouse_pressed_handler());
// Build a window in the second RootWindow.
scoped_ptr<aura::Window> w2(CreateNormalWindow(2, second_root_.get(), NULL));
// The act of having the second window take capture should clear out mouse
// pressed handler in the first RootWindow.
w2->SetCapture();
EXPECT_EQ(NULL, root_window()->mouse_pressed_handler());
}
// Makes sure that when one window gets capture, it forces the release on the
// other. This is needed has to be handled explicitly on Linux, and is a sanity
// check on Windows.
TEST_F(DesktopCaptureClientTest, ResetOtherWindowCaptureOnCapture) {
// Create a window inside the RootWindow.
scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL));
w1->SetCapture();
// Both capture clients should return the same capture window.
EXPECT_EQ(w1.get(), desktop_capture_client_->GetCaptureWindow());
EXPECT_EQ(w1.get(), second_desktop_capture_client_->GetCaptureWindow());
// Build a window in the second RootWindow and give it capture. Both capture
// clients should return the same capture window.
scoped_ptr<aura::Window> w2(CreateNormalWindow(2, second_root_.get(), NULL));
w2->SetCapture();
EXPECT_EQ(w2.get(), desktop_capture_client_->GetCaptureWindow());
EXPECT_EQ(w2.get(), second_desktop_capture_client_->GetCaptureWindow());
}
// This class provides functionality to verify whether the View instance
// received the gesture event.
class DesktopViewInputTest : public View {
public:
DesktopViewInputTest()
: received_gesture_event_(false) {}
virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
received_gesture_event_ = true;
return View::OnGestureEvent(event);
}
// Resets state maintained by this class.
void Reset() {
received_gesture_event_ = false;
}
bool received_gesture_event() const { return received_gesture_event_; }
private:
bool received_gesture_event_;
DISALLOW_COPY_AND_ASSIGN(DesktopViewInputTest);
};
// Tests aura::Window capture and whether gesture events are sent to the window
// which has capture.
// The test case creates two visible widgets and sets capture to the underlying
// aura::Windows one by one. It then sends a gesture event and validates whether
// the window which had capture receives the gesture.
TEST_F(ViewTest, CaptureWindowInputEventTest) {
scoped_ptr<DesktopCaptureClient> desktop_capture_client1;
scoped_ptr<DesktopCaptureClient> desktop_capture_client2;
scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client1;
scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client2;
scoped_ptr<Widget> widget1(new Widget());
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
widget1->Init(params);
internal::RootView* root1 =
static_cast<internal::RootView*>(widget1->GetRootView());
desktop_capture_client1.reset(new DesktopCaptureClient(
widget1->GetNativeView()->GetRootWindow()));
desktop_position_client1.reset(new DesktopScreenPositionClient());
aura::client::SetScreenPositionClient(
widget1->GetNativeView()->GetRootWindow(),
desktop_position_client1.get());
DesktopViewInputTest* v1 = new DesktopViewInputTest();
v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
root1->AddChildView(v1);
widget1->Show();
scoped_ptr<Widget> widget2(new Widget());
params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
widget2->Init(params);
internal::RootView* root2 =
static_cast<internal::RootView*>(widget2->GetRootView());
desktop_capture_client2.reset(new DesktopCaptureClient(
widget2->GetNativeView()->GetRootWindow()));
desktop_position_client2.reset(new DesktopScreenPositionClient());
aura::client::SetScreenPositionClient(
widget2->GetNativeView()->GetRootWindow(),
desktop_position_client2.get());
DesktopViewInputTest* v2 = new DesktopViewInputTest();
v2->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
root2->AddChildView(v2);
widget2->Show();
EXPECT_FALSE(widget1->GetNativeView()->HasCapture());
EXPECT_FALSE(widget2->GetNativeView()->HasCapture());
EXPECT_EQ(desktop_capture_client1->GetCaptureWindow(),
reinterpret_cast<aura::Window*>(0));
EXPECT_EQ(desktop_capture_client2->GetCaptureWindow(),
reinterpret_cast<aura::Window*>(0));
widget1->GetNativeView()->SetCapture();
EXPECT_TRUE(widget1->GetNativeView()->HasCapture());
EXPECT_FALSE(widget2->GetNativeView()->HasCapture());
EXPECT_EQ(desktop_capture_client1->GetCaptureWindow(),
widget1->GetNativeView());
EXPECT_EQ(desktop_capture_client2->GetCaptureWindow(),
widget1->GetNativeView());
ui::GestureEvent g1(ui::ET_GESTURE_LONG_PRESS, 80, 80, 0,
base::TimeDelta(),
ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS,
0.0f, 0.0f), 0);
root1->DispatchGestureEvent(&g1);
EXPECT_TRUE(v1->received_gesture_event());
EXPECT_FALSE(v2->received_gesture_event());
v1->Reset();
v2->Reset();
widget2->GetNativeView()->SetCapture();
EXPECT_FALSE(widget1->GetNativeView()->HasCapture());
EXPECT_TRUE(widget2->GetNativeView()->HasCapture());
EXPECT_EQ(desktop_capture_client1->GetCaptureWindow(),
widget2->GetNativeView());
EXPECT_EQ(desktop_capture_client2->GetCaptureWindow(),
widget2->GetNativeView());
root2->DispatchGestureEvent(&g1);
EXPECT_TRUE(v2->received_gesture_event());
EXPECT_FALSE(v1->received_gesture_event());
widget1->CloseNow();
widget2->CloseNow();
RunPendingMessages();
}
} // namespace views