| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/wm/core/capture_controller.h" | 5 #include "ui/wm/core/capture_controller.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 } | 96 } |
| 97 | 97 |
| 98 aura::Window* GetCaptureWindow() { | 98 aura::Window* GetCaptureWindow() { |
| 99 return capture_controller_->capture_client()->GetCaptureWindow(); | 99 return capture_controller_->capture_client()->GetCaptureWindow(); |
| 100 } | 100 } |
| 101 | 101 |
| 102 aura::Window* GetSecondCaptureWindow() { | 102 aura::Window* GetSecondCaptureWindow() { |
| 103 return second_capture_controller_->capture_client()->GetCaptureWindow(); | 103 return second_capture_controller_->capture_client()->GetCaptureWindow(); |
| 104 } | 104 } |
| 105 | 105 |
| 106 scoped_ptr<ScopedCaptureClient> capture_controller_; | 106 std::unique_ptr<ScopedCaptureClient> capture_controller_; |
| 107 scoped_ptr<aura::WindowTreeHost> second_host_; | 107 std::unique_ptr<aura::WindowTreeHost> second_host_; |
| 108 scoped_ptr<ScopedCaptureClient> second_capture_controller_; | 108 std::unique_ptr<ScopedCaptureClient> second_capture_controller_; |
| 109 | 109 |
| 110 DISALLOW_COPY_AND_ASSIGN(CaptureControllerTest); | 110 DISALLOW_COPY_AND_ASSIGN(CaptureControllerTest); |
| 111 }; | 111 }; |
| 112 | 112 |
| 113 // Makes sure that internal details that are set on mouse down (such as | 113 // Makes sure that internal details that are set on mouse down (such as |
| 114 // mouse_pressed_handler()) are cleared when another root window takes capture. | 114 // mouse_pressed_handler()) are cleared when another root window takes capture. |
| 115 TEST_F(CaptureControllerTest, ResetMouseEventHandlerOnCapture) { | 115 TEST_F(CaptureControllerTest, ResetMouseEventHandlerOnCapture) { |
| 116 // Create a window inside the WindowEventDispatcher. | 116 // Create a window inside the WindowEventDispatcher. |
| 117 scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL)); | 117 std::unique_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL)); |
| 118 | 118 |
| 119 // Make a synthesized mouse down event. Ensure that the WindowEventDispatcher | 119 // Make a synthesized mouse down event. Ensure that the WindowEventDispatcher |
| 120 // will dispatch further mouse events to |w1|. | 120 // will dispatch further mouse events to |w1|. |
| 121 ui::MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), | 121 ui::MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), |
| 122 gfx::Point(5, 5), ui::EventTimeForNow(), 0, | 122 gfx::Point(5, 5), ui::EventTimeForNow(), 0, |
| 123 0); | 123 0); |
| 124 DispatchEventUsingWindowDispatcher(&mouse_pressed_event); | 124 DispatchEventUsingWindowDispatcher(&mouse_pressed_event); |
| 125 EXPECT_EQ(w1.get(), host()->dispatcher()->mouse_pressed_handler()); | 125 EXPECT_EQ(w1.get(), host()->dispatcher()->mouse_pressed_handler()); |
| 126 | 126 |
| 127 // Build a window in the second WindowEventDispatcher. | 127 // Build a window in the second WindowEventDispatcher. |
| 128 scoped_ptr<aura::Window> w2( | 128 std::unique_ptr<aura::Window> w2( |
| 129 CreateNormalWindow(2, second_host_->window(), NULL)); | 129 CreateNormalWindow(2, second_host_->window(), NULL)); |
| 130 | 130 |
| 131 // The act of having the second window take capture should clear out mouse | 131 // The act of having the second window take capture should clear out mouse |
| 132 // pressed handler in the first WindowEventDispatcher. | 132 // pressed handler in the first WindowEventDispatcher. |
| 133 w2->SetCapture(); | 133 w2->SetCapture(); |
| 134 EXPECT_EQ(NULL, host()->dispatcher()->mouse_pressed_handler()); | 134 EXPECT_EQ(NULL, host()->dispatcher()->mouse_pressed_handler()); |
| 135 } | 135 } |
| 136 | 136 |
| 137 // Makes sure that when one window gets capture, it forces the release on the | 137 // Makes sure that when one window gets capture, it forces the release on the |
| 138 // other. This is needed has to be handled explicitly on Linux, and is a sanity | 138 // other. This is needed has to be handled explicitly on Linux, and is a sanity |
| 139 // check on Windows. | 139 // check on Windows. |
| 140 TEST_F(CaptureControllerTest, ResetOtherWindowCaptureOnCapture) { | 140 TEST_F(CaptureControllerTest, ResetOtherWindowCaptureOnCapture) { |
| 141 // Create a window inside the WindowEventDispatcher. | 141 // Create a window inside the WindowEventDispatcher. |
| 142 scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL)); | 142 std::unique_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL)); |
| 143 w1->SetCapture(); | 143 w1->SetCapture(); |
| 144 // Both capture clients should return the same capture window. | 144 // Both capture clients should return the same capture window. |
| 145 EXPECT_EQ(w1.get(), GetCaptureWindow()); | 145 EXPECT_EQ(w1.get(), GetCaptureWindow()); |
| 146 EXPECT_EQ(w1.get(), GetSecondCaptureWindow()); | 146 EXPECT_EQ(w1.get(), GetSecondCaptureWindow()); |
| 147 | 147 |
| 148 // Build a window in the second WindowEventDispatcher and give it capture. | 148 // Build a window in the second WindowEventDispatcher and give it capture. |
| 149 // Both capture clients should return the same capture window. | 149 // Both capture clients should return the same capture window. |
| 150 scoped_ptr<aura::Window> w2( | 150 std::unique_ptr<aura::Window> w2( |
| 151 CreateNormalWindow(2, second_host_->window(), NULL)); | 151 CreateNormalWindow(2, second_host_->window(), NULL)); |
| 152 w2->SetCapture(); | 152 w2->SetCapture(); |
| 153 EXPECT_EQ(w2.get(), GetCaptureWindow()); | 153 EXPECT_EQ(w2.get(), GetCaptureWindow()); |
| 154 EXPECT_EQ(w2.get(), GetSecondCaptureWindow()); | 154 EXPECT_EQ(w2.get(), GetSecondCaptureWindow()); |
| 155 } | 155 } |
| 156 | 156 |
| 157 // Verifies the touch target for the WindowEventDispatcher gets reset on | 157 // Verifies the touch target for the WindowEventDispatcher gets reset on |
| 158 // releasing capture. | 158 // releasing capture. |
| 159 TEST_F(CaptureControllerTest, TouchTargetResetOnCaptureChange) { | 159 TEST_F(CaptureControllerTest, TouchTargetResetOnCaptureChange) { |
| 160 // Create a window inside the WindowEventDispatcher. | 160 // Create a window inside the WindowEventDispatcher. |
| 161 scoped_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL)); | 161 std::unique_ptr<aura::Window> w1(CreateNormalWindow(1, root_window(), NULL)); |
| 162 ui::test::EventGenerator event_generator1(root_window()); | 162 ui::test::EventGenerator event_generator1(root_window()); |
| 163 event_generator1.PressTouch(); | 163 event_generator1.PressTouch(); |
| 164 w1->SetCapture(); | 164 w1->SetCapture(); |
| 165 // Both capture clients should return the same capture window. | 165 // Both capture clients should return the same capture window. |
| 166 EXPECT_EQ(w1.get(), GetCaptureWindow()); | 166 EXPECT_EQ(w1.get(), GetCaptureWindow()); |
| 167 EXPECT_EQ(w1.get(), GetSecondCaptureWindow()); | 167 EXPECT_EQ(w1.get(), GetSecondCaptureWindow()); |
| 168 | 168 |
| 169 // Build a window in the second WindowEventDispatcher and give it capture. | 169 // Build a window in the second WindowEventDispatcher and give it capture. |
| 170 // Both capture clients should return the same capture window. | 170 // Both capture clients should return the same capture window. |
| 171 scoped_ptr<aura::Window> w2( | 171 std::unique_ptr<aura::Window> w2( |
| 172 CreateNormalWindow(2, second_host_->window(), NULL)); | 172 CreateNormalWindow(2, second_host_->window(), NULL)); |
| 173 w2->SetCapture(); | 173 w2->SetCapture(); |
| 174 EXPECT_EQ(w2.get(), GetCaptureWindow()); | 174 EXPECT_EQ(w2.get(), GetCaptureWindow()); |
| 175 EXPECT_EQ(w2.get(), GetSecondCaptureWindow()); | 175 EXPECT_EQ(w2.get(), GetSecondCaptureWindow()); |
| 176 | 176 |
| 177 // Release capture on the window. Releasing capture should reset the touch | 177 // Release capture on the window. Releasing capture should reset the touch |
| 178 // target of the first WindowEventDispatcher (as it no longer contains the | 178 // target of the first WindowEventDispatcher (as it no longer contains the |
| 179 // capture target). | 179 // capture target). |
| 180 w2->ReleaseCapture(); | 180 w2->ReleaseCapture(); |
| 181 EXPECT_EQ(static_cast<aura::Window*>(NULL), GetCaptureWindow()); | 181 EXPECT_EQ(static_cast<aura::Window*>(NULL), GetCaptureWindow()); |
| 182 EXPECT_EQ(static_cast<aura::Window*>(NULL), GetSecondCaptureWindow()); | 182 EXPECT_EQ(static_cast<aura::Window*>(NULL), GetSecondCaptureWindow()); |
| 183 } | 183 } |
| 184 | 184 |
| 185 // Test that native capture is released properly when the window with capture | 185 // Test that native capture is released properly when the window with capture |
| 186 // is reparented to a different root window while it has capture. | 186 // is reparented to a different root window while it has capture. |
| 187 TEST_F(CaptureControllerTest, ReparentedWhileCaptured) { | 187 TEST_F(CaptureControllerTest, ReparentedWhileCaptured) { |
| 188 scoped_ptr<TestCaptureDelegate> delegate(new TestCaptureDelegate); | 188 std::unique_ptr<TestCaptureDelegate> delegate(new TestCaptureDelegate); |
| 189 ScopedCaptureClient::TestApi(capture_controller_.get()) | 189 ScopedCaptureClient::TestApi(capture_controller_.get()) |
| 190 .SetDelegate(delegate.get()); | 190 .SetDelegate(delegate.get()); |
| 191 scoped_ptr<TestCaptureDelegate> delegate2(new TestCaptureDelegate); | 191 std::unique_ptr<TestCaptureDelegate> delegate2(new TestCaptureDelegate); |
| 192 ScopedCaptureClient::TestApi(second_capture_controller_.get()) | 192 ScopedCaptureClient::TestApi(second_capture_controller_.get()) |
| 193 .SetDelegate(delegate2.get()); | 193 .SetDelegate(delegate2.get()); |
| 194 | 194 |
| 195 scoped_ptr<aura::Window> w(CreateNormalWindow(1, root_window(), NULL)); | 195 std::unique_ptr<aura::Window> w(CreateNormalWindow(1, root_window(), NULL)); |
| 196 w->SetCapture(); | 196 w->SetCapture(); |
| 197 EXPECT_EQ(w.get(), GetCaptureWindow()); | 197 EXPECT_EQ(w.get(), GetCaptureWindow()); |
| 198 EXPECT_EQ(w.get(), GetSecondCaptureWindow()); | 198 EXPECT_EQ(w.get(), GetSecondCaptureWindow()); |
| 199 EXPECT_TRUE(delegate->HasNativeCapture()); | 199 EXPECT_TRUE(delegate->HasNativeCapture()); |
| 200 EXPECT_FALSE(delegate2->HasNativeCapture()); | 200 EXPECT_FALSE(delegate2->HasNativeCapture()); |
| 201 | 201 |
| 202 second_host_->window()->AddChild(w.get()); | 202 second_host_->window()->AddChild(w.get()); |
| 203 EXPECT_EQ(w.get(), GetCaptureWindow()); | 203 EXPECT_EQ(w.get(), GetCaptureWindow()); |
| 204 EXPECT_EQ(w.get(), GetSecondCaptureWindow()); | 204 EXPECT_EQ(w.get(), GetSecondCaptureWindow()); |
| 205 EXPECT_TRUE(delegate->HasNativeCapture()); | 205 EXPECT_TRUE(delegate->HasNativeCapture()); |
| 206 EXPECT_FALSE(delegate2->HasNativeCapture()); | 206 EXPECT_FALSE(delegate2->HasNativeCapture()); |
| 207 | 207 |
| 208 w->ReleaseCapture(); | 208 w->ReleaseCapture(); |
| 209 EXPECT_EQ(nullptr, GetCaptureWindow()); | 209 EXPECT_EQ(nullptr, GetCaptureWindow()); |
| 210 EXPECT_EQ(nullptr, GetSecondCaptureWindow()); | 210 EXPECT_EQ(nullptr, GetSecondCaptureWindow()); |
| 211 EXPECT_FALSE(delegate->HasNativeCapture()); | 211 EXPECT_FALSE(delegate->HasNativeCapture()); |
| 212 EXPECT_FALSE(delegate2->HasNativeCapture()); | 212 EXPECT_FALSE(delegate2->HasNativeCapture()); |
| 213 } | 213 } |
| 214 | 214 |
| 215 // A delegate that deletes a window on scroll cancel gesture event. | 215 // A delegate that deletes a window on scroll cancel gesture event. |
| 216 class GestureEventDeleteWindowOnScrollEnd | 216 class GestureEventDeleteWindowOnScrollEnd |
| 217 : public aura::test::TestWindowDelegate { | 217 : public aura::test::TestWindowDelegate { |
| 218 public: | 218 public: |
| 219 GestureEventDeleteWindowOnScrollEnd() {} | 219 GestureEventDeleteWindowOnScrollEnd() {} |
| 220 | 220 |
| 221 void SetWindow(scoped_ptr<aura::Window> window) { | 221 void SetWindow(std::unique_ptr<aura::Window> window) { |
| 222 window_ = std::move(window); | 222 window_ = std::move(window); |
| 223 } | 223 } |
| 224 aura::Window* window() { return window_.get(); } | 224 aura::Window* window() { return window_.get(); } |
| 225 | 225 |
| 226 // aura::test::TestWindowDelegate: | 226 // aura::test::TestWindowDelegate: |
| 227 void OnGestureEvent(ui::GestureEvent* gesture) override { | 227 void OnGestureEvent(ui::GestureEvent* gesture) override { |
| 228 TestWindowDelegate::OnGestureEvent(gesture); | 228 TestWindowDelegate::OnGestureEvent(gesture); |
| 229 if (gesture->type() != ui::ET_GESTURE_SCROLL_END) | 229 if (gesture->type() != ui::ET_GESTURE_SCROLL_END) |
| 230 return; | 230 return; |
| 231 window_.reset(); | 231 window_.reset(); |
| 232 } | 232 } |
| 233 | 233 |
| 234 private: | 234 private: |
| 235 scoped_ptr<aura::Window> window_; | 235 std::unique_ptr<aura::Window> window_; |
| 236 DISALLOW_COPY_AND_ASSIGN(GestureEventDeleteWindowOnScrollEnd); | 236 DISALLOW_COPY_AND_ASSIGN(GestureEventDeleteWindowOnScrollEnd); |
| 237 }; | 237 }; |
| 238 | 238 |
| 239 // Tests a scenario when a window gets deleted while a capture is being set on | 239 // Tests a scenario when a window gets deleted while a capture is being set on |
| 240 // it and when that window releases its capture prior to being deleted. | 240 // it and when that window releases its capture prior to being deleted. |
| 241 // This scenario should end safely without capture being set. | 241 // This scenario should end safely without capture being set. |
| 242 TEST_F(CaptureControllerTest, GestureResetWithCapture) { | 242 TEST_F(CaptureControllerTest, GestureResetWithCapture) { |
| 243 scoped_ptr<GestureEventDeleteWindowOnScrollEnd> delegate( | 243 std::unique_ptr<GestureEventDeleteWindowOnScrollEnd> delegate( |
| 244 new GestureEventDeleteWindowOnScrollEnd()); | 244 new GestureEventDeleteWindowOnScrollEnd()); |
| 245 const int kWindowWidth = 123; | 245 const int kWindowWidth = 123; |
| 246 const int kWindowHeight = 45; | 246 const int kWindowHeight = 45; |
| 247 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | 247 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); |
| 248 scoped_ptr<aura::Window> window1( | 248 std::unique_ptr<aura::Window> window1( |
| 249 CreateNormalWindowWithBounds(-1235, root_window(), bounds, nullptr)); | 249 CreateNormalWindowWithBounds(-1235, root_window(), bounds, nullptr)); |
| 250 | 250 |
| 251 bounds.Offset(0, 100); | 251 bounds.Offset(0, 100); |
| 252 scoped_ptr<aura::Window> window2(CreateNormalWindowWithBounds( | 252 std::unique_ptr<aura::Window> window2(CreateNormalWindowWithBounds( |
| 253 -1234, root_window(), bounds, delegate.get())); | 253 -1234, root_window(), bounds, delegate.get())); |
| 254 delegate->SetWindow(std::move(window1)); | 254 delegate->SetWindow(std::move(window1)); |
| 255 | 255 |
| 256 ui::test::EventGenerator event_generator(root_window()); | 256 ui::test::EventGenerator event_generator(root_window()); |
| 257 const int position_x = bounds.x() + 1; | 257 const int position_x = bounds.x() + 1; |
| 258 int position_y = bounds.y() + 1; | 258 int position_y = bounds.y() + 1; |
| 259 event_generator.MoveTouch(gfx::Point(position_x, position_y)); | 259 event_generator.MoveTouch(gfx::Point(position_x, position_y)); |
| 260 event_generator.PressTouch(); | 260 event_generator.PressTouch(); |
| 261 for (int idx = 0 ; idx < 20 ; idx++, position_y++) | 261 for (int idx = 0 ; idx < 20 ; idx++, position_y++) |
| 262 event_generator.MoveTouch(gfx::Point(position_x, position_y)); | 262 event_generator.MoveTouch(gfx::Point(position_x, position_y)); |
| 263 | 263 |
| 264 // Setting capture on |window1| cancels touch gestures that are active on | 264 // Setting capture on |window1| cancels touch gestures that are active on |
| 265 // |window2|. GestureEventDeleteWindowOnScrollEnd will then delete |window1| | 265 // |window2|. GestureEventDeleteWindowOnScrollEnd will then delete |window1| |
| 266 // and should release capture on it. | 266 // and should release capture on it. |
| 267 delegate->window()->SetCapture(); | 267 delegate->window()->SetCapture(); |
| 268 | 268 |
| 269 // capture should not be set upon exit from SetCapture() above. | 269 // capture should not be set upon exit from SetCapture() above. |
| 270 aura::client::CaptureClient* capture_client = | 270 aura::client::CaptureClient* capture_client = |
| 271 aura::client::GetCaptureClient(root_window()); | 271 aura::client::GetCaptureClient(root_window()); |
| 272 ASSERT_NE(nullptr, capture_client); | 272 ASSERT_NE(nullptr, capture_client); |
| 273 EXPECT_EQ(nullptr, capture_client->GetCaptureWindow()); | 273 EXPECT_EQ(nullptr, capture_client->GetCaptureWindow()); |
| 274 | 274 |
| 275 // Send a mouse click. We no longer hold capture so this should not crash. | 275 // Send a mouse click. We no longer hold capture so this should not crash. |
| 276 ui::MouseEvent mouse_press(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), | 276 ui::MouseEvent mouse_press(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), |
| 277 base::TimeDelta(), 0, 0); | 277 base::TimeDelta(), 0, 0); |
| 278 DispatchEventUsingWindowDispatcher(&mouse_press); | 278 DispatchEventUsingWindowDispatcher(&mouse_press); |
| 279 } | 279 } |
| 280 | 280 |
| 281 } // namespace wm | 281 } // namespace wm |
| OLD | NEW |