13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/capture_controller.h" 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/logging.h" 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/aura/env.h" 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/aura/test/aura_test_base.h" 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/aura/test/test_screen.h" 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h" 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_utils.h" 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.h" 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/test/views_test_base.h" 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/view.h" 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/widget/root_view.h" 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/widget/widget.h" 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_CHROMEOS) 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace views { 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class CaptureControllerTest : public aura::test::AuraTestBase { 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CaptureControllerTest() {} 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual void SetUp() OVERRIDE { 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AuraTestBase::SetUp(); 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) capture_controller_.reset(new wm::ScopedCaptureClient(root_window())); 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) second_host_.reset(aura::WindowTreeHost::Create(gfx::Rect(0, 0, 800, 600))); 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) second_host_->InitHost(); 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) second_host_->window()->Show(); 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) second_host_->SetBounds(gfx::Rect(800, 600)); 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) second_capture_controller_.reset( 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new wm::ScopedCaptureClient(second_host_->window())); 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_CHROMEOS) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) desktop_position_client_.reset( 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new DesktopScreenPositionClient(root_window())); 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) second_desktop_position_client_.reset( 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new DesktopScreenPositionClient(second_host_->window())); 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual void TearDown() OVERRIDE { 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RunAllPendingInMessageLoop(); 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_CHROMEOS) 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) second_desktop_position_client_.reset(); 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) second_capture_controller_.reset(); 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Kill any active compositors before we hit the compositor shutdown paths. 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) second_host_.reset(); 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_CHROMEOS) 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) desktop_position_client_.reset(); 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) capture_controller_.reset(); 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AuraTestBase::TearDown(); 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) aura::Window* GetCaptureWindow() { 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return capture_controller_->capture_client()->GetCaptureWindow(); 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) aura::Window* GetSecondCaptureWindow() { 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return second_capture_controller_->capture_client()->GetCaptureWindow(); 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<wm::ScopedCaptureClient> capture_controller_; 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::WindowTreeHost> second_host_; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<wm::ScopedCaptureClient> second_capture_controller_; 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_CHROMEOS) 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client_; 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<aura::client::ScreenPositionClient> 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) second_desktop_position_client_; 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CaptureControllerTest); 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Makes sure that internal details that are set on mouse down (such as 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// mouse_pressed_handler()) are cleared when another root window takes capture. 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(CaptureControllerTest, ResetMouseEventHandlerOnCapture) { 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Create a window inside the WindowEventDispatcher. 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL)); 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Make a synthesized mouse down event. Ensure that the WindowEventDispatcher 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // will dispatch further mouse events to |w1|. 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ui::MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Point(5, 5), 0, 0); 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DispatchEventUsingWindowDispatcher(&mouse_pressed_event); 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(w1.get(), host()->dispatcher()->mouse_pressed_handler()); 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Build a window in the second WindowEventDispatcher. 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<aura::Window> w2( 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateNormalWindow(2, second_host_->window(), NULL)); 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The act of having the second window take capture should clear out mouse 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // pressed handler in the first WindowEventDispatcher. 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) w2->SetCapture(); 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(NULL, host()->dispatcher()->mouse_pressed_handler()); 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Makes sure that when one window gets capture, it forces the release on the 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// other. This is needed has to be handled explicitly on Linux, and is a sanity 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// check on Windows. 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(CaptureControllerTest, ResetOtherWindowCaptureOnCapture) { 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Create a window inside the WindowEventDispatcher. 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL)); 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) w1->SetCapture(); 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Both capture clients should return the same capture window. 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(w1.get(), GetCaptureWindow()); 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(w1.get(), GetSecondCaptureWindow()); 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Build a window in the second WindowEventDispatcher and give it capture. 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Both capture clients should return the same capture window. 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<aura::Window> w2( 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateNormalWindow(2, second_host_->window(), NULL)); 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) w2->SetCapture(); 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(w2.get(), GetCaptureWindow()); 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(w2.get(), GetSecondCaptureWindow()); 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Verifies the touch target for the WindowEventDispatcher gets reset on 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// releasing capture. 137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(CaptureControllerTest, TouchTargetResetOnCaptureChange) { 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Create a window inside the WindowEventDispatcher. 139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL)); 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui::test::EventGenerator event_generator1(root_window()); 141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) event_generator1.PressTouch(); 142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) w1->SetCapture(); 143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Both capture clients should return the same capture window. 144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(w1.get(), GetCaptureWindow()); 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(w1.get(), GetSecondCaptureWindow()); 146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Build a window in the second WindowEventDispatcher and give it capture. 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Both capture clients should return the same capture window. 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<aura::Window> w2( 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateNormalWindow(2, second_host_->window(), NULL)); 151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) w2->SetCapture(); 152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(w2.get(), GetCaptureWindow()); 153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(w2.get(), GetSecondCaptureWindow()); 154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Release capture on the window. Releasing capture should reset the touch 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // target of the first WindowEventDispatcher (as it no longer contains the 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // capture target). 158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) w2->ReleaseCapture(); 159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(static_cast<aura::Window*>(NULL), GetCaptureWindow()); 160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(static_cast<aura::Window*>(NULL), GetSecondCaptureWindow()); 161424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ui::TouchEvent touch_event( 162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ui::ET_TOUCH_PRESSED, gfx::Point(), 0, 0, ui::EventTimeForNow(), 1.0f, 163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1.0f, 1.0f, 1.0f); 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) EXPECT_EQ(static_cast<ui::GestureConsumer*>(w2.get()), 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::GestureRecognizer::Get()->GetTouchLockedTarget(touch_event)); 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace views 169