Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(547)

Side by Side Diff: services/ui/ws/drag_controller_unittest.cc

Issue 2376583003: mus: Keep track of the drag cursor during DnD operations. (Closed)
Patch Set: style Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "services/ui/ws/drag_controller.h" 5 #include "services/ui/ws/drag_controller.h"
6 6
7 #include <map>
8 #include <memory>
9 #include <queue>
10 #include <utility>
11
12 #include "services/ui/public/interfaces/cursor.mojom.h"
7 #include "services/ui/ws/drag_source.h" 13 #include "services/ui/ws/drag_source.h"
8 #include "services/ui/ws/drag_target_connection.h" 14 #include "services/ui/ws/drag_target_connection.h"
9 #include "services/ui/ws/ids.h" 15 #include "services/ui/ws/ids.h"
10 #include "services/ui/ws/server_window.h" 16 #include "services/ui/ws/server_window.h"
11 #include "services/ui/ws/test_server_window_delegate.h" 17 #include "services/ui/ws/test_server_window_delegate.h"
12 #include "services/ui/ws/test_utils.h" 18 #include "services/ui/ws/test_utils.h"
13 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
14 #include "ui/events/base_event_utils.h" 20 #include "ui/events/base_event_utils.h"
15 21
16 namespace ui { 22 namespace ui {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 private: 127 private:
122 DragControllerTest* parent_; 128 DragControllerTest* parent_;
123 TestServerWindowDelegate window_delegate_; 129 TestServerWindowDelegate window_delegate_;
124 ServerWindow window_; 130 ServerWindow window_;
125 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data_; 131 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data_;
126 uint32_t times_received_drag_drop_start_ = 0; 132 uint32_t times_received_drag_drop_start_ = 0;
127 133
128 std::queue<DragEvent> queued_callbacks_; 134 std::queue<DragEvent> queued_callbacks_;
129 }; 135 };
130 136
131 class DragControllerTest : public testing::Test, public DragSource { 137 class DragControllerTest : public testing::Test,
138 public DragCursorUpdater,
139 public DragSource {
132 public: 140 public:
133 std::unique_ptr<DragTestWindow> BuildWindow() { 141 std::unique_ptr<DragTestWindow> BuildWindow() {
134 WindowId id(1, ++window_id_); 142 WindowId id(1, ++window_id_);
135 std::unique_ptr<DragTestWindow> p = 143 std::unique_ptr<DragTestWindow> p =
136 base::MakeUnique<DragTestWindow>(this, id); 144 base::MakeUnique<DragTestWindow>(this, id);
137 server_window_by_id_[id] = p->window(); 145 server_window_by_id_[id] = p->window();
138 connection_by_window_[p->window()] = p.get(); 146 connection_by_window_[p->window()] = p.get();
139 return p; 147 return p;
140 } 148 }
141 149
142 void StartDragOperation( 150 void StartDragOperation(
143 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data, 151 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data,
144 DragTestWindow* window, 152 DragTestWindow* window,
145 uint32_t drag_operations) { 153 uint32_t drag_operations) {
146 window->PerformOnDragDropStart(mime_data.Clone()); 154 window->PerformOnDragDropStart(mime_data.Clone());
147 drag_operation_ = base::MakeUnique<DragController>( 155 drag_operation_ = base::MakeUnique<DragController>(
148 this, window->window(), window, PointerEvent::kMousePointerId, 156 this, this, window->window(), window, PointerEvent::kMousePointerId,
149 std::move(mime_data), drag_operations); 157 std::move(mime_data), drag_operations);
158
159 // It would be nice if we could just let the observer method fire, but it
160 // fires during the constructor when we haven't assigned the unique_ptr
161 // yet.
162 cursor_ = ui::mojom::Cursor(drag_operation_->current_cursor());
150 } 163 }
151 164
152 void DispatchDrag(DragTestWindow* window, 165 void DispatchDrag(DragTestWindow* window,
153 bool mouse_released, 166 bool mouse_released,
154 uint32_t flags, 167 uint32_t flags,
155 const gfx::Point& position) { 168 const gfx::Point& position) {
156 ui::PointerEvent event( 169 ui::PointerEvent event(
157 ui::MouseEvent(mouse_released ? ET_MOUSE_RELEASED : ET_MOUSE_PRESSED, 170 ui::MouseEvent(mouse_released ? ET_MOUSE_RELEASED : ET_MOUSE_PRESSED,
158 position, position, ui::EventTimeForNow(), flags, 0)); 171 position, position, ui::EventTimeForNow(), flags, 0));
159 drag_operation_->DispatchPointerEvent(event, 172 drag_operation_->DispatchPointerEvent(event,
(...skipping 20 matching lines...) Expand all
180 193
181 DragController* drag_operation() const { return drag_operation_.get(); } 194 DragController* drag_operation() const { return drag_operation_.get(); }
182 195
183 const base::Optional<uint32_t>& drag_completed_action() { 196 const base::Optional<uint32_t>& drag_completed_action() {
184 return drag_completed_action_; 197 return drag_completed_action_;
185 } 198 }
186 const base::Optional<bool>& drag_completed_value() { 199 const base::Optional<bool>& drag_completed_value() {
187 return drag_completed_value_; 200 return drag_completed_value_;
188 } 201 }
189 202
203 ui::mojom::Cursor cursor() { return cursor_; }
204
190 private: 205 private:
191 // Overridden from testing::Test: 206 // Overridden from testing::Test:
192 void SetUp() override { 207 void SetUp() override {
193 testing::Test::SetUp(); 208 testing::Test::SetUp();
194 209
195 window_delegate_ = base::MakeUnique<TestServerWindowDelegate>(); 210 window_delegate_ = base::MakeUnique<TestServerWindowDelegate>();
196 root_window_ = 211 root_window_ =
197 base::MakeUnique<ServerWindow>(window_delegate_.get(), WindowId(1, 2)); 212 base::MakeUnique<ServerWindow>(window_delegate_.get(), WindowId(1, 2));
198 window_delegate_->set_root_window(root_window_.get()); 213 window_delegate_->set_root_window(root_window_.get());
199 root_window_->SetVisible(true); 214 root_window_->SetVisible(true);
200 } 215 }
201 216
202 void TearDown() override { 217 void TearDown() override {
203 drag_operation_.reset(); 218 drag_operation_.reset();
204 root_window_.reset(); 219 root_window_.reset();
205 window_delegate_.reset(); 220 window_delegate_.reset();
206 221
207 DCHECK(server_window_by_id_.empty()); 222 DCHECK(server_window_by_id_.empty());
208 DCHECK(connection_by_window_.empty()); 223 DCHECK(connection_by_window_.empty());
209 224
210 testing::Test::TearDown(); 225 testing::Test::TearDown();
211 } 226 }
212 227
228 // Overridden from DragCursorUpdater:
229 void OnDragCursorUpdated() override {
230 if (drag_operation_)
231 cursor_ = ui::mojom::Cursor(drag_operation_->current_cursor());
232 }
233
213 // Overridden from DragControllerSource: 234 // Overridden from DragControllerSource:
214 void OnDragCompleted(bool success, uint32_t action_taken) override { 235 void OnDragCompleted(bool success, uint32_t action_taken) override {
215 drag_completed_action_ = action_taken; 236 drag_completed_action_ = action_taken;
216 drag_completed_value_ = success; 237 drag_completed_value_ = success;
217 } 238 }
218 239
219 ServerWindow* GetWindowById(const WindowId& id) override { 240 ServerWindow* GetWindowById(const WindowId& id) override {
220 auto it = server_window_by_id_.find(id); 241 auto it = server_window_by_id_.find(id);
221 if (it == server_window_by_id_.end()) 242 if (it == server_window_by_id_.end())
222 return nullptr; 243 return nullptr;
223 return it->second; 244 return it->second;
224 } 245 }
225 246
226 DragTargetConnection* GetDragTargetForWindow( 247 DragTargetConnection* GetDragTargetForWindow(
227 const ServerWindow* window) override { 248 const ServerWindow* window) override {
228 auto it = connection_by_window_.find(const_cast<ServerWindow*>(window)); 249 auto it = connection_by_window_.find(const_cast<ServerWindow*>(window));
229 if (it == connection_by_window_.end()) 250 if (it == connection_by_window_.end())
230 return nullptr; 251 return nullptr;
231 return it->second; 252 return it->second;
232 } 253 }
233 254
234 int window_id_ = 3; 255 int window_id_ = 3;
235 256
257 ui::mojom::Cursor cursor_;
258
236 std::map<WindowId, ServerWindow*> server_window_by_id_; 259 std::map<WindowId, ServerWindow*> server_window_by_id_;
237 std::map<ServerWindow*, DragTargetConnection*> connection_by_window_; 260 std::map<ServerWindow*, DragTargetConnection*> connection_by_window_;
238 261
239 std::unique_ptr<TestServerWindowDelegate> window_delegate_; 262 std::unique_ptr<TestServerWindowDelegate> window_delegate_;
240 std::unique_ptr<ServerWindow> root_window_; 263 std::unique_ptr<ServerWindow> root_window_;
241 264
242 std::unique_ptr<DragController> drag_operation_; 265 std::unique_ptr<DragController> drag_operation_;
243 266
244 base::Optional<uint32_t> drag_completed_action_; 267 base::Optional<uint32_t> drag_completed_action_;
245 base::Optional<bool> drag_completed_value_; 268 base::Optional<bool> drag_completed_value_;
246 }; 269 };
247 270
248 DragTestWindow::~DragTestWindow() { 271 DragTestWindow::~DragTestWindow() {
249 parent_->OnTestWindowDestroyed(this); 272 parent_->OnTestWindowDestroyed(this);
250 } 273 }
251 274
252 TEST_F(DragControllerTest, SimpleDragDrop) { 275 TEST_F(DragControllerTest, SimpleDragDrop) {
253 std::unique_ptr<DragTestWindow> window = BuildWindow(); 276 std::unique_ptr<DragTestWindow> window = BuildWindow();
254 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; 277 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
255 StartDragOperation(std::move(mime_data), window.get(), 278 StartDragOperation(std::move(mime_data), window.get(),
256 ui::mojom::kDropEffectMove); 279 ui::mojom::kDropEffectMove);
257 280
281 EXPECT_EQ(ui::mojom::Cursor::NO_DROP, cursor());
282
258 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); 283 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1));
259 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type()); 284 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type());
260 window->Respond(true); 285 window->Respond(true);
261 286
287 // (Even though we're doing a move, the cursor name is COPY.)
288 EXPECT_EQ(ui::mojom::Cursor::COPY, cursor());
289
262 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2)); 290 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2));
263 EXPECT_EQ(QueuedType::OVER, window->queue_response_type()); 291 EXPECT_EQ(QueuedType::OVER, window->queue_response_type());
264 window->Respond(true); 292 window->Respond(true);
265 293
266 DispatchDrag(window.get(), true, 0, gfx::Point(2, 2)); 294 DispatchDrag(window.get(), true, 0, gfx::Point(2, 2));
267 EXPECT_EQ(QueuedType::DROP, window->queue_response_type()); 295 EXPECT_EQ(QueuedType::DROP, window->queue_response_type());
268 window->Respond(true); 296 window->Respond(true);
269 297
270 EXPECT_EQ(ui::mojom::kDropEffectMove, 298 EXPECT_EQ(ui::mojom::kDropEffectMove,
271 drag_completed_action().value_or(ui::mojom::kDropEffectNone)); 299 drag_completed_action().value_or(ui::mojom::kDropEffectNone));
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 window2.reset(); 543 window2.reset();
516 544
517 // DragController doesn't know anything about the server window now. 545 // DragController doesn't know anything about the server window now.
518 EXPECT_EQ(0u, api.GetSizeOfQueueForWindow(server_window)); 546 EXPECT_EQ(0u, api.GetSizeOfQueueForWindow(server_window));
519 EXPECT_EQ(nullptr, api.GetCurrentTarget()); 547 EXPECT_EQ(nullptr, api.GetCurrentTarget());
520 548
521 // But a target window closing out from under us doesn't fail the drag. 549 // But a target window closing out from under us doesn't fail the drag.
522 EXPECT_FALSE(drag_completed_value().has_value()); 550 EXPECT_FALSE(drag_completed_value().has_value());
523 } 551 }
524 552
553 TEST_F(DragControllerTest, TargetWindowClosedResetsCursor) {
554 std::unique_ptr<DragTestWindow> window1 = BuildWindow();
555 std::unique_ptr<DragTestWindow> window2 = BuildWindow();
556 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
557 StartDragOperation(std::move(mime_data), window1.get(),
558 ui::mojom::kDropEffectMove);
559 EXPECT_EQ(ui::mojom::Cursor::NO_DROP, cursor());
560
561 // Send some events to |window|.
562 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
563 gfx::Point(1, 1));
564 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type());
565 window2->Respond(true);
566 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
567 gfx::Point(1, 1));
568 window2->Respond(true);
569 EXPECT_EQ(ui::mojom::Cursor::COPY, cursor());
570
571 // Force the destruction of |window.window|.
572 window2.reset();
573
574 // The cursor no loner indicates that it can drop on |window2|.
575 EXPECT_EQ(ui::mojom::Cursor::NO_DROP, cursor());
576 }
577
525 TEST_F(DragControllerTest, SourceWindowClosedWhileDrag) { 578 TEST_F(DragControllerTest, SourceWindowClosedWhileDrag) {
526 std::unique_ptr<DragTestWindow> window1 = BuildWindow(); 579 std::unique_ptr<DragTestWindow> window1 = BuildWindow();
527 std::unique_ptr<DragTestWindow> window2 = BuildWindow(); 580 std::unique_ptr<DragTestWindow> window2 = BuildWindow();
528 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; 581 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
529 StartDragOperation(std::move(mime_data), window1.get(), 582 StartDragOperation(std::move(mime_data), window1.get(),
530 ui::mojom::kDropEffectMove); 583 ui::mojom::kDropEffectMove);
531 584
532 test::DragControllerTestApi api(drag_operation()); 585 test::DragControllerTestApi api(drag_operation());
533 586
534 // Send some events to |window|. 587 // Send some events to |windoww|.
535 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, 588 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
536 gfx::Point(1, 1)); 589 gfx::Point(1, 1));
537 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type()); 590 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type());
538 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, 591 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
539 gfx::Point(1, 1)); 592 gfx::Point(1, 1));
540 593
541 ServerWindow* server_window = window2->window(); 594 ServerWindow* server_window = window2->window();
542 595
543 // Ensure that DragController is waiting for a response from |window|. 596 // Ensure that DragController is waiting for a response from |window2|.
544 EXPECT_EQ(2u, api.GetSizeOfQueueForWindow(server_window)); 597 EXPECT_EQ(2u, api.GetSizeOfQueueForWindow(server_window));
545 EXPECT_EQ(server_window, api.GetCurrentTarget()); 598 EXPECT_EQ(server_window, api.GetCurrentTarget());
546 599
547 // Force the destruction of the source window. 600 // Force the destruction of the source window.
548 window1.reset(); 601 window1.reset();
549 602
550 // The source window going away fails the drag. 603 // The source window going away fails the drag.
551 EXPECT_FALSE(drag_completed_value().value_or(true)); 604 EXPECT_FALSE(drag_completed_value().value_or(true));
552 } 605 }
553 606
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 // This starts the operation with PointerEvent::kMousePointerId. 655 // This starts the operation with PointerEvent::kMousePointerId.
603 StartDragOperation(std::move(mime_data), window.get(), 656 StartDragOperation(std::move(mime_data), window.get(),
604 ui::mojom::kDropEffectMove); 657 ui::mojom::kDropEffectMove);
605 658
606 // Ignore events from pointer 5. 659 // Ignore events from pointer 5.
607 DispatchDragWithPointer(window.get(), 5, false, ui::EF_LEFT_MOUSE_BUTTON, 660 DispatchDragWithPointer(window.get(), 5, false, ui::EF_LEFT_MOUSE_BUTTON,
608 gfx::Point(1, 1)); 661 gfx::Point(1, 1));
609 ASSERT_EQ(0u, window->queue_size()); 662 ASSERT_EQ(0u, window->queue_size());
610 } 663 }
611 664
612 // TODO(erg): Add a test to ensure windows that the cursor isn't over 665 TEST_F(DragControllerTest, RejectingWindowHasProperCursor) {
613 // responding to messages don't change the cursor when we have cursor handling 666 std::unique_ptr<DragTestWindow> window = BuildWindow();
614 // code. 667 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
668 StartDragOperation(std::move(mime_data), window.get(),
669 ui::mojom::kDropEffectMove);
670
671 EXPECT_EQ(ui::mojom::Cursor::NO_DROP, cursor());
672
673 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1));
674 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type());
675 window->Respond(true);
676
677 EXPECT_EQ(ui::mojom::Cursor::COPY, cursor());
678
679 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2));
680 EXPECT_EQ(QueuedType::OVER, window->queue_response_type());
681
682 // At this point, we respond with no available drag actions at this pixel.
683 window->Respond(false);
684 EXPECT_EQ(ui::mojom::Cursor::NO_DROP, cursor());
685 }
686
687 TEST_F(DragControllerTest, ResopnseFromOtherWindowDoesntChangeCursor) {
688 std::unique_ptr<DragTestWindow> window1 = BuildWindow();
689 std::unique_ptr<DragTestWindow> window2 = BuildWindow();
690 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
691 StartDragOperation(std::move(mime_data), window1.get(),
692 ui::mojom::kDropEffectMove);
693
694 // Send some events to |window2|.
695 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
696 gfx::Point(1, 1));
697 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type());
698 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
699 gfx::Point(1, 1));
700
701 EXPECT_EQ(ui::mojom::Cursor::NO_DROP, cursor());
702
703 // Now enter |window1|, and respond.
704 DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
705 gfx::Point(5, 5));
706 EXPECT_EQ(QueuedType::ENTER, window1->queue_response_type());
707 window1->Respond(true);
708
709 EXPECT_EQ(ui::mojom::Cursor::COPY, cursor());
710
711 // Window 2 responding negatively to its queued messages shouldn't change the
712 // cursor.
713 window2->Respond(false);
714
715 EXPECT_EQ(ui::mojom::Cursor::COPY, cursor());
716 }
615 717
616 } // namespace ws 718 } // namespace ws
617 } // namespace ui 719 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698