drag_drop_unittest.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. #include "ash/drag_drop/drag_drop_controller.h"
  5. #include <memory>
  6. #include "ash/shell.h"
  7. #include "ash/test/ash_test_base.h"
  8. #include "ash/test/ui_controls_factory_ash.h"
  9. #include "base/bind.h"
  10. #include "base/run_loop.h"
  11. #include "base/strings/utf_string_conversions.h"
  12. #include "ui/aura/window_event_dispatcher.h"
  13. #include "ui/base/dragdrop/drag_drop_types.h"
  14. #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
  15. #include "ui/base/test/ui_controls.h"
  16. #include "ui/base/test/ui_controls_aura.h"
  17. #include "ui/views/view.h"
  18. #include "ui/views/widget/widget.h"
  19. namespace ash {
  20. namespace {
  21. class DraggableView : public views::View {
  22. public:
  23. DraggableView() = default;
  24. DraggableView(const DraggableView&) = delete;
  25. DraggableView& operator=(const DraggableView&) = delete;
  26. ~DraggableView() override = default;
  27. // views::View overrides:
  28. int GetDragOperations(const gfx::Point& press_pt) override {
  29. return ui::DragDropTypes::DRAG_MOVE;
  30. }
  31. void WriteDragData(const gfx::Point& press_pt,
  32. OSExchangeData* data) override {
  33. data->SetString(u"test");
  34. }
  35. };
  36. class TargetView : public views::View {
  37. public:
  38. TargetView() : dropped_(false) {}
  39. TargetView(const TargetView&) = delete;
  40. TargetView& operator=(const TargetView&) = delete;
  41. ~TargetView() override = default;
  42. // views::View overrides:
  43. bool GetDropFormats(
  44. int* formats,
  45. std::set<ui::ClipboardFormatType>* format_types) override {
  46. *formats = ui::OSExchangeData::STRING;
  47. return true;
  48. }
  49. bool AreDropTypesRequired() override { return false; }
  50. bool CanDrop(const OSExchangeData& data) override { return true; }
  51. int OnDragUpdated(const ui::DropTargetEvent& event) override {
  52. return ui::DragDropTypes::DRAG_MOVE;
  53. }
  54. DropCallback GetDropCallback(const ui::DropTargetEvent& event) override {
  55. return base::BindOnce(&TargetView::PerformDrop, base::Unretained(this));
  56. }
  57. bool dropped() const { return dropped_; }
  58. private:
  59. void PerformDrop(const ui::DropTargetEvent& event,
  60. ui::mojom::DragOperation& output_drag_op) {
  61. dropped_ = true;
  62. output_drag_op = ui::mojom::DragOperation::kMove;
  63. }
  64. bool dropped_;
  65. };
  66. views::Widget* CreateWidget(std::unique_ptr<views::View> contents_view,
  67. const gfx::Rect& bounds,
  68. aura::Window* context) {
  69. views::Widget* widget = new views::Widget;
  70. views::Widget::InitParams params;
  71. params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
  72. params.accept_events = true;
  73. params.bounds = bounds;
  74. params.context = context;
  75. widget->Init(std::move(params));
  76. widget->SetContentsView(std::move(contents_view));
  77. widget->Show();
  78. return widget;
  79. }
  80. void QuitLoop() {
  81. base::RunLoop::QuitCurrentWhenIdleDeprecated();
  82. }
  83. void DragDropAcrossMultiDisplay_Step4() {
  84. ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT, ui_controls::UP,
  85. base::BindOnce(&QuitLoop));
  86. }
  87. void DragDropAcrossMultiDisplay_Step3() {
  88. // Move to the edge of the 1st display so that the mouse
  89. // is moved to 2nd display by ash.
  90. ui_controls::SendMouseMoveNotifyWhenDone(
  91. 399, 10, base::BindOnce(&DragDropAcrossMultiDisplay_Step4));
  92. }
  93. void DragDropAcrossMultiDisplay_Step2() {
  94. ui_controls::SendMouseMoveNotifyWhenDone(
  95. 20, 10, base::BindOnce(&DragDropAcrossMultiDisplay_Step3));
  96. }
  97. void DragDropAcrossMultiDisplay_Step1() {
  98. ui_controls::SendMouseEventsNotifyWhenDone(
  99. ui_controls::LEFT, ui_controls::DOWN,
  100. base::BindOnce(&DragDropAcrossMultiDisplay_Step2));
  101. }
  102. } // namespace
  103. using DragDropTest = AshTestBase;
  104. // Test if the mouse gets moved properly to another display
  105. // during drag & drop operation.
  106. // Test flaky on ChromeOS: crbug.com/1312727
  107. TEST_F(DragDropTest, DISABLED_DragDropAcrossMultiDisplay) {
  108. ui_controls::InstallUIControlsAura(test::CreateAshUIControls());
  109. UpdateDisplay("400x300,400x300");
  110. aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
  111. auto draggable_view = std::make_unique<DraggableView>();
  112. draggable_view->set_drag_controller(NULL);
  113. draggable_view->SetBounds(0, 0, 100, 100);
  114. views::Widget* source = CreateWidget(std::move(draggable_view),
  115. gfx::Rect(0, 0, 100, 100), GetContext());
  116. auto target_view = std::make_unique<TargetView>();
  117. target_view->SetBounds(0, 0, 100, 100);
  118. TargetView* target_view_ptr = target_view.get();
  119. views::Widget* target = CreateWidget(
  120. std::move(target_view), gfx::Rect(400, 0, 100, 100), GetContext());
  121. // Make sure they're on the different root windows.
  122. EXPECT_EQ(root_windows[0], source->GetNativeView()->GetRootWindow());
  123. EXPECT_EQ(root_windows[1], target->GetNativeView()->GetRootWindow());
  124. ui_controls::SendMouseMoveNotifyWhenDone(
  125. 10, 10, base::BindOnce(&DragDropAcrossMultiDisplay_Step1));
  126. base::RunLoop().Run();
  127. EXPECT_TRUE(target_view_ptr->dropped());
  128. source->Close();
  129. target->Close();
  130. ui_controls::InstallUIControlsAura(nullptr);
  131. }
  132. } // namespace ash