17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/drag_drop/drag_drop_controller.h"
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/shell.h"
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/test/ash_test_base.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/bind.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/message_loop/message_loop.h"
1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/path_service.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/base/dragdrop/drag_drop_types.h"
1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/base/test/ui_controls.h"
1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/base/ui_base_paths.h"
1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/gl/gl_surface.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/views/view.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/views/widget/widget.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace ash {
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace {
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class DraggableView : public views::View {
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DraggableView() {}
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~DraggableView() {}
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // views::View overrides:
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual int GetDragOperations(const gfx::Point& press_pt) OVERRIDE {
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return ui::DragDropTypes::DRAG_MOVE;
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void WriteDragData(const gfx::Point& press_pt,
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             OSExchangeData* data)OVERRIDE {
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    data->SetString(base::UTF8ToUTF16("test"));
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DraggableView);
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class TargetView : public views::View {
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TargetView() : dropped_(false) {}
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~TargetView() {}
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // views::View overrides:
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool GetDropFormats(
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      int* formats,
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      std::set<OSExchangeData::CustomFormat>* custom_formats) OVERRIDE {
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    *formats = ui::OSExchangeData::STRING;
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return true;
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool AreDropTypesRequired() OVERRIDE {
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return false;
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool CanDrop(const OSExchangeData& data) OVERRIDE {
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return true;
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE {
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return ui::DragDropTypes::DRAG_MOVE;
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE {
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    dropped_ = true;
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return ui::DragDropTypes::DRAG_MOVE;
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool dropped() const { return dropped_; }
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool dropped_;
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TargetView);
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)views::Widget* CreateWidget(views::View* contents_view,
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            const gfx::Rect& bounds) {
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  views::Widget* widget = new views::Widget;
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  views::Widget::InitParams params;
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  params.accept_events = true;
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  params.context = Shell::GetPrimaryRootWindow();
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  params.bounds = bounds;
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->Init(params);
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->SetContentsView(contents_view);
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->Show();
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return widget;
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void QuitLoop() {
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::MessageLoop::current()->Quit();
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DragDropAcrossMultiDisplay_Step4() {
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_controls::SendMouseEventsNotifyWhenDone(
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ui_controls::LEFT, ui_controls::UP,
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&QuitLoop));
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DragDropAcrossMultiDisplay_Step3() {
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Move to the edge of the 1st display so that the mouse
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // is moved to 2nd display by ash.
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_controls::SendMouseMoveNotifyWhenDone(
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      399, 10,
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&DragDropAcrossMultiDisplay_Step4));
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DragDropAcrossMultiDisplay_Step2() {
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_controls::SendMouseMoveNotifyWhenDone(
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      20, 10,
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&DragDropAcrossMultiDisplay_Step3));
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DragDropAcrossMultiDisplay_Step1() {
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_controls::SendMouseEventsNotifyWhenDone(
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ui_controls::LEFT, ui_controls::DOWN,
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&DragDropAcrossMultiDisplay_Step2));
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class DragDropTest : public test::AshTestBase {
12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public:
12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DragDropTest() {}
12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual ~DragDropTest() {}
12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::GLSurface::InitializeOneOffForTests();
13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ui::RegisterPathProvider();
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ui::ResourceBundle::InitSharedInstanceWithLocale(
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        "en-US", NULL, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    base::FilePath resources_pack_path;
13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    PathService::Get(base::DIR_MODULE, &resources_pack_path);
13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    resources_pack_path =
13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        resources_pack_path.Append(FILE_PATH_LITERAL("resources.pak"));
13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ResourceBundle::GetSharedInstance().AddDataPackFromPath(
14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        resources_pack_path, ui::SCALE_FACTOR_NONE);
14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    test::AshTestBase::SetUp();
14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
14423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)};
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(OS_CHROMEOS)
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define MAYBE_DragDropAcrossMultiDisplay DISABLED_DragDropAcrossMultiDisplay
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#else
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define MAYBE_DragDropAcrossMultiDisplay DragDropAcrossMultiDisplay
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Test if the mouse gets moved properly to another display
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// during drag & drop operation.
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(DragDropTest, MAYBE_DragDropAcrossMultiDisplay) {
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!SupportsMultipleDisplays())
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UpdateDisplay("400x400,400x400");
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows =
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      Shell::GetInstance()->GetAllRootWindows();
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  views::View* draggable_view = new DraggableView();
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  draggable_view->set_drag_controller(NULL);
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  draggable_view->SetBounds(0, 0, 100, 100);
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  views::Widget* source =
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      CreateWidget(draggable_view, gfx::Rect(0, 0, 100, 100));
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TargetView* target_view = new TargetView();
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  target_view->SetBounds(0, 0, 100, 100);
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  views::Widget* target =
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      CreateWidget(target_view, gfx::Rect(400, 0, 100, 100));
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Make sure they're on the different root windows.
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(root_windows[0], source->GetNativeView()->GetRootWindow());
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(root_windows[1], target->GetNativeView()->GetRootWindow());
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_controls::SendMouseMoveNotifyWhenDone(
1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      10, 10, base::Bind(&DragDropAcrossMultiDisplay_Step1));
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::MessageLoop::current()->Run();
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(target_view->dropped());
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  source->Close();
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  target->Close();
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace ash
188